Skip to content

Commit

Permalink
Fixed fmin and fmax intrinsics.
Browse files Browse the repository at this point in the history
  • Loading branch information
FractalFir committed Aug 12, 2024
1 parent 53a2943 commit aad2cac
Show file tree
Hide file tree
Showing 18 changed files with 336 additions and 47 deletions.
3 changes: 2 additions & 1 deletion cargo_tests/build_std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ edition = "2021"

[dependencies]
mycorrhiza = {path="../../mycorrhiza"}
rand = "0.8.5"
[workspace]
[profile.release.build-override]
codegen-units = 1
codegen-units = 1
123 changes: 113 additions & 10 deletions cargo_tests/build_std/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,119 @@ fn should_pass() {}
fn should_panic() {
panic!();
}
#[test]
#[should_panic]
fn div_by_zero() {
let zero = std::hint::black_box(0);
let res = 64 / zero;
std::hint::black_box(res);
}
fn main() {
println!("Hi!");
for arg in std::env::args() {
println!("arg:{arg:?}");
select_nth_unstable();
}

fn select_nth_unstable() {
use core::cmp::Ordering::{Equal, Greater, Less};

use rand::seq::SliceRandom;
use rand::Rng;
let mut rng = rand::thread_rng();
let mut v = [0; 500];
for pivot in 0..v.len() {
println!("{}:{}", file!(), line!());
v.select_nth_unstable_by(pivot, |_, _| {
*[Less, Equal, Greater].choose(&mut rng).unwrap()
});
v.sort();
for i in 0..v.len() {
println!("{}:{}", file!(), line!());
assert_eq!(v[i], i as i32);
}
}

for len in (2..21).chain(500..501) {
let mut orig = vec![0; len];
println!("{}:{}", file!(), line!());
for &modulus in &[5, 10, 1000] {
for _ in 0..10 {
println!("{}:{}", file!(), line!());
for i in 0..len {
println!("{}:{}", file!(), line!());
orig[i] = rng.gen::<i32>() % modulus;
}

let v_sorted = {
let mut v = orig.clone();
v.sort();
v
};

// Sort in default order.
for pivot in 0..len {
println!("{}:{}", file!(), line!());
let mut v = orig.clone();
v.select_nth_unstable(pivot);

assert_eq!(v_sorted[pivot], v[pivot]);
for i in 0..pivot {
for j in pivot..len {
assert!(v[i] <= v[j]);
}
}
}

// Sort in ascending order.
for pivot in 0..len {
println!("{}:{}", file!(), line!());
let mut v = orig.clone();
let (left, pivot, right) = v.select_nth_unstable_by(pivot, |a, b| a.cmp(b));

assert_eq!(left.len() + right.len(), len - 1);

for l in left {
assert!(l <= pivot);
for r in right.iter_mut() {
assert!(l <= r);
assert!(pivot <= r);
}
}
}

// Sort in descending order.
let sort_descending_comparator = |a: &i32, b: &i32| b.cmp(a);
let v_sorted_descending = {
let mut v = orig.clone();
v.sort_by(sort_descending_comparator);
v
};

for pivot in 0..len {
println!("{}:{}", file!(), line!());
let mut v = orig.clone();
v.select_nth_unstable_by(pivot, sort_descending_comparator);

assert_eq!(v_sorted_descending[pivot], v[pivot]);
for i in 0..pivot {
for j in pivot..len {
assert!(v[j] <= v[i]);
}
}
}
}
}
}

// Sort at index using a completely random comparison function.
// This will reorder the elements *somehow*, but won't panic.
let mut v = [0; 500];
for i in 0..v.len() {
println!("{}:{}", file!(), line!());
v[i] = i as i32;
}

// Should not panic.
[(); 10].select_nth_unstable(0);
[(); 10].select_nth_unstable(5);
[(); 10].select_nth_unstable(9);
[(); 100].select_nth_unstable(0);
[(); 100].select_nth_unstable(50);
[(); 100].select_nth_unstable(99);

let mut v = [0xDEADBEEFu64];
v.select_nth_unstable(0);
assert!(v == [0xDEADBEEF]);
println!("v:{v:?}");
}
27 changes: 26 additions & 1 deletion cilly/src/bin/linker/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ use cilly::{
v2::{
asm::{MissingMethodPatcher, ILASM_FLAVOUR},
cilnode::MethodKind,
BasicBlock, CILNode, CILRoot, ClassRef, IlasmFlavour, Int, MethodImpl, Type,
Assembly, BasicBlock, CILNode, CILRoot, ClassRef, Const, IlasmFlavour, Int, MethodImpl,
Type,
},
DotnetTypeRef, FnSig,
};
Expand Down Expand Up @@ -178,8 +179,24 @@ fn main() {
.iter()
.map(|fn_name| (*fn_name, LIBC.as_ref()))
.collect();

let modifies_errno = LIBC_MODIFIES_ERRNO.iter().copied().collect();
let mut overrides: MissingMethodPatcher = FxHashMap::default();
overrides.insert(
final_assembly.alloc_string("pthread_atfork"),
Box::new(|_, asm: &mut Assembly| {
let ret_val = asm.alloc_node(Const::I32(0));
let blocks = vec![BasicBlock::new(
vec![asm.alloc_root(CILRoot::Ret(ret_val))],
1,
None,
)];
MethodImpl::MethodBody {
blocks,
locals: vec![],
}
}),
);
// Override allocator
{
// Get the marshal class
Expand Down Expand Up @@ -401,6 +418,14 @@ fn main() {
//todo!();
}
fn bootstrap_source(fpath: &Path, output_file_path: &str, jumpstart_cmd: &str) -> String {
if let Err(err) = std::fs::remove_file(output_file_path) {
match err.kind() {
std::io::ErrorKind::NotFound => (),
_ => {
panic!("Could not remove tmp file because {err:?}")
}
}
};
format!(
include_str!("dotnet_jumpstart.rs"),
jumpstart_cmd = jumpstart_cmd,
Expand Down
1 change: 0 additions & 1 deletion cilly/src/libc_fns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,6 @@ pub const LIBC_FNS: &[&str] = &[
"prlimit",
"psiginfo",
"psignal",
"pthread_atfork",
"ptrace",
"ptsname",
"putchar",
Expand Down
2 changes: 1 addition & 1 deletion cilly/src/type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ impl Type {
| Self::USize => true,
Self::Bool => true,
Self::F32 | Self::F64 => true,
Self::Ptr(_) => true,
Self::Ptr(_) | Self::DelegatePtr(_) => true,
// 128 bit ints are NOT primitve CIL types!
Self::I128 | Self::U128 => true,
_ => false,
Expand Down
25 changes: 14 additions & 11 deletions cilly/src/type_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,18 +132,21 @@ impl TypeDef {
name = self.name()
);
let max_offset = offsets.iter().max().unwrap_or(&0);

let explict_size = self
.explict_size()
.unwrap_or_else(|| {
panic!(
"Explict offsets provided without explicit size. Type: {}",
self.name()
)
})
.get();
assert!(
(*max_offset)
< self
.explict_size()
.unwrap_or_else(|| {
panic!(
"Explict offsets provided without explicit size. Type: {}",
self.name()
)
})
.get()
(*max_offset) < explict_size,
"name:{:?} max_offset:{max_offset} explict_size:{explict_size} offsets:{:?} fields:{:?}",
self.name(),
self.explicit_offsets().unwrap(),
self.fields()
);
}
self.field_types()
Expand Down
20 changes: 19 additions & 1 deletion cilly/src/v2/il_exporter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -994,12 +994,30 @@ impl Exporter for ILExporter {
fn export(&self, asm: &super::Assembly, target: &std::path::Path) -> Result<(), Self::Error> {
// The IL file should be next to the target
let il_path = target.with_extension("il");

if let Err(err) = std::fs::remove_file(&il_path) {
match err.kind() {
std::io::ErrorKind::NotFound => (),
_ => {
panic!("Could not remove tmp file because {err:?}")
}
}
};
let mut il_out = std::io::BufWriter::new(std::fs::File::create(&il_path)?);
self.export_to_write(asm, &mut il_out)?;
// Needed to ensure the IL file is valid!
il_out.flush().unwrap();
drop(il_out);
let exe_out = target.with_extension("exe");

if let Err(err) = std::fs::remove_file(&exe_out) {
match err.kind() {
std::io::ErrorKind::NotFound => (),
_ => {
panic!("Could not remove tmp file because {err:?}")
}
}
};
let asm_type = if self.is_lib { "-dll" } else { "-exe" };
let mut cmd = std::process::Command::new(ILASM_PATH.clone());
cmd.arg(il_path)
Expand Down Expand Up @@ -1097,7 +1115,7 @@ fn type_il(tpe: &Type, asm: &Assembly) -> String {
},
Type::ClassRef(cref) => class_ref(*cref, asm),
Type::Float(float) => match float {
super::Float::F16 => todo!(),
super::Float::F16 => "valuetype [System.Runtime]System.Half".into(),
super::Float::F32 => "float32".into(),
super::Float::F64 => "float64".into(),
},
Expand Down
7 changes: 7 additions & 0 deletions src/aggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ pub fn handle_aggregate<'tcx>(
)
}
AggregateKind::Array(element) => {
// Check if this array is made up from uninit values
if crate::operand::is_uninit(&value_index[FieldIdx::from_usize(0)], ctx) {
// This array is created from uninitalized data, so it itsefl is uninitialzed, so we can skip initializing it.
return super::place::place_get(target_location, ctx);
}

let element = ctx.monomorphize(*element);
let element = ctx.type_from_cache(element);
let array_type = DotnetTypeRef::array(&element, value_index.len());
Expand All @@ -81,6 +87,7 @@ pub fn handle_aggregate<'tcx>(
.into(),
});
}

CILNode::SubTrees(Box::new((
sub_trees.into(),
Box::new(super::place::place_get(target_location, ctx)),
Expand Down
11 changes: 6 additions & 5 deletions src/bin/autotest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fn main() {
let stderr = str::from_utf8(&out.stderr).unwrap().to_string();
let stdout = str::from_utf8(&out.stdout).unwrap().to_string();
for line in stdout.lines() {
if !line.contains("test ") {
if !line.contains("test ") || line.contains("finished in") {
continue;
}
let mut split = line.split("...");
Expand All @@ -39,14 +39,15 @@ fn main() {
let name = name["test ".len()..].trim();
let name = name.split("-").next().unwrap().trim();
let status = split.next().unwrap_or("");

if status.contains("ok") {
ok.insert(name.to_owned());
} else if status.contains("FAILED") {
failures.insert(name.to_owned());
} else {
if !broken.iter().any(|exisitng| exisitng == name) {
broken.push(name.to_owned());
}
} else if status.contains("ignored") {
continue;
} else if !broken.iter().any(|exisitng| exisitng == name) {
broken.push(name.to_owned());
}
}
if stderr.contains("failures:")
Expand Down
2 changes: 1 addition & 1 deletion src/binop/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ pub fn lt_unchecked(ty_a: Ty<'_>, operand_a: CILNode, operand_b: CILNode) -> CIL
},
// TODO: are chars considered signed or unsigned?
TyKind::Bool | TyKind::Char | TyKind::Float(_) => lt!(operand_a, operand_b),
TyKind::RawPtr(_, _) => lt_un!(operand_a, operand_b),
TyKind::RawPtr(_, _) | TyKind::FnPtr(_) => lt_un!(operand_a, operand_b),
_ => panic!("Can't eq type {ty_a:?}"),
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ fn load_const_scalar<'tcx>(
}
}
}
TyKind::Adt(_, _subst) => CILNode::LdObj {
TyKind::Adt(_, _) | TyKind::Closure(_, _) => CILNode::LdObj {
ptr: Box::new(
CILNode::PointerToConstValue(Box::new(scalar_u128))
.cast_ptr(ptr!(scalar_type.clone())),
Expand Down
Loading

0 comments on commit aad2cac

Please sign in to comment.