Compare commits
5 Commits
1927035cfc
...
0818f5804e
Author | SHA1 | Date |
---|---|---|
David Mak | 0818f5804e | |
David Mak | 9826c20e4c | |
David Mak | 5c1b2e5090 | |
David Mak | a2e23e52ce | |
David Mak | 7b5cf7d5ba |
|
@ -433,52 +433,36 @@ pub fn list_slice_assignment<'ctx, 'a>(
|
|||
ctx.builder.position_at_end(cont_bb);
|
||||
}
|
||||
|
||||
/// Generates a call to `isinf` in IR. Returns either an `i32` or `i1` representing the result,
|
||||
/// depending on the value of `to_i1`.
|
||||
/// Generates a call to `isinf` in IR. Returns either an `i32` representing the result.
|
||||
pub fn call_isinf<'ctx, 'a>(
|
||||
generator: &dyn CodeGenerator,
|
||||
ctx: &CodeGenContext<'ctx, 'a>,
|
||||
v: FloatValue<'ctx>,
|
||||
to_i1: bool,
|
||||
) -> IntValue<'ctx> {
|
||||
let intrinsic_fn = ctx.module.get_function("__nac3_isinf").unwrap_or_else(|| {
|
||||
let fn_type = ctx.ctx.i32_type().fn_type(&[ctx.ctx.f64_type().into()], false);
|
||||
ctx.module.add_function("__nac3_isinf", fn_type, None)
|
||||
});
|
||||
|
||||
let val = ctx.builder
|
||||
ctx.builder
|
||||
.build_call(intrinsic_fn, &[v.into()], "isinf")
|
||||
.try_as_basic_value()
|
||||
.unwrap_left()
|
||||
.into_int_value();
|
||||
if to_i1 {
|
||||
generator.bool_to_i1(ctx, val)
|
||||
} else {
|
||||
val
|
||||
}
|
||||
.into_int_value()
|
||||
}
|
||||
|
||||
/// Generates a call to `isnan` in IR. Returns either an `i32` or `i1` representing the result,
|
||||
/// depending on the value of `to_i1`.
|
||||
/// Generates a call to `isnan` in IR. Returns either an `i32` representing the result.
|
||||
pub fn call_isnan<'ctx, 'a>(
|
||||
generator: &dyn CodeGenerator,
|
||||
ctx: &CodeGenContext<'ctx, 'a>,
|
||||
v: FloatValue<'ctx>,
|
||||
to_i1: bool,
|
||||
) -> IntValue<'ctx> {
|
||||
let intrinsic_fn = ctx.module.get_function("__nac3_isnan").unwrap_or_else(|| {
|
||||
let fn_type = ctx.ctx.i32_type().fn_type(&[ctx.ctx.f64_type().into()], false);
|
||||
ctx.module.add_function("__nac3_isnan", fn_type, None)
|
||||
});
|
||||
|
||||
let val = ctx.builder
|
||||
ctx.builder
|
||||
.build_call(intrinsic_fn, &[v.into()], "isnan")
|
||||
.try_as_basic_value()
|
||||
.unwrap_left()
|
||||
.into_int_value();
|
||||
if to_i1 {
|
||||
generator.bool_to_i1(ctx, val)
|
||||
} else {
|
||||
val
|
||||
}
|
||||
.into_int_value()
|
||||
}
|
||||
|
|
|
@ -1195,7 +1195,10 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
|
||||
assert!(ctx.unifier.unioned(x_ty, float));
|
||||
|
||||
let val = call_isnan(generator, ctx, x_val.into_float_value(), true);
|
||||
let val = generator.bool_to_i1(
|
||||
ctx,
|
||||
call_isnan(ctx, x_val.into_float_value()).into()
|
||||
);
|
||||
|
||||
Ok(Some(val.into()))
|
||||
}),
|
||||
|
@ -1215,7 +1218,10 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
|
||||
assert!(ctx.unifier.unioned(x_ty, float));
|
||||
|
||||
let val = call_isinf(generator, ctx, x_val.into_float_value(), true);
|
||||
let val = generator.bool_to_i1(
|
||||
ctx,
|
||||
call_isinf(ctx, x_val.into_float_value()).into()
|
||||
);
|
||||
|
||||
Ok(Some(val.into()))
|
||||
}),
|
||||
|
@ -1521,9 +1527,9 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
// v = if isinf(x) || isnan(x) { x } else { v } // Handles (1)-(3)
|
||||
|
||||
// %v.isinf = call i32 @__nac3_isinf(f64 %0)
|
||||
let v_isinf = call_isinf(generator, ctx, call.into(), false);
|
||||
let v_isinf = call_isinf(ctx, call.into());
|
||||
// %v.isnan = call i32 @__nac3_isnan(f64 %0)
|
||||
let v_isnan = call_isnan(generator, ctx, call.into(), false);
|
||||
let v_isnan = call_isnan(ctx, call.into());
|
||||
|
||||
// %or = or i32 %v.isinf, %v.isnan
|
||||
// %or.tobool = icmp ne i32 %or, 0
|
||||
|
@ -1537,9 +1543,9 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
).into_float_value();
|
||||
|
||||
// %z.isinf = call i32 @__nac3_isinf(f64 %z)
|
||||
let z_isinf = call_isinf(generator, ctx, z_val.into_float_value(), false);
|
||||
let z_isinf = call_isinf(ctx, z_val.into_float_value());
|
||||
// %z.isnan = call i32 @__nac3_isnan(f64 %z)
|
||||
let z_isnan = call_isnan(generator, ctx, z_val.into_float_value(), false);
|
||||
let z_isnan = call_isnan(ctx, z_val.into_float_value());
|
||||
|
||||
// %or = or i32 %z.isinf, %z.isnan
|
||||
// %or.tobool = icmp ne i32 %or, 0
|
||||
|
@ -1603,7 +1609,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
// %tobool = icmp ne i32 %isinf, 0
|
||||
// %val = select i1 %tobool, f64 %x, f64 %0
|
||||
let v = ctx.builder.build_select(
|
||||
call_isinf(generator, ctx, x_val.into_float_value(), true),
|
||||
generator.bool_to_i1(ctx, call_isinf(ctx, x_val.into_float_value()).into()),
|
||||
x_val,
|
||||
call.into(),
|
||||
""
|
||||
|
@ -1657,10 +1663,13 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
// v = if isinf(x) { f64::NAN } else { v }
|
||||
|
||||
// %1 = call i32 @__nac3_isinf(f64 %x)
|
||||
// %2 =
|
||||
let arg_isinf = call_isinf(generator, ctx, x_val.into_float_value(), true);
|
||||
// %tobool = icmp ne i32 %isinf, 0
|
||||
let arg_isinf = generator.bool_to_i1(
|
||||
ctx,
|
||||
call_isinf(ctx, x_val.into_float_value()).into()
|
||||
);
|
||||
|
||||
// %val = select i1 %1, f64 nan, f64 %0
|
||||
// %val = select i1 %tobool, f64 nan, f64 %0
|
||||
let val = ctx.builder
|
||||
.build_select(arg_isinf, llvm_f64.const_float(f64::NAN), call, "");
|
||||
|
||||
|
|
Loading…
Reference in New Issue