Compare commits

..

5 Commits

2 changed files with 31 additions and 30 deletions

View File

@ -433,9 +433,8 @@ pub fn list_slice_assignment<'ctx, 'a>(
ctx.builder.position_at_end(cont_bb); ctx.builder.position_at_end(cont_bb);
} }
/// Generates a call to `isinf` in IR. Returns an `i1` representing the result. /// Generates a call to `isinf` in IR. Returns an `i32` representing the result.
pub fn call_isinf<'ctx, 'a>( pub fn call_isinf<'ctx, 'a>(
generator: &mut dyn CodeGenerator,
ctx: &CodeGenContext<'ctx, 'a>, ctx: &CodeGenContext<'ctx, 'a>,
v: FloatValue<'ctx>, v: FloatValue<'ctx>,
) -> IntValue<'ctx> { ) -> IntValue<'ctx> {
@ -444,18 +443,15 @@ pub fn call_isinf<'ctx, 'a>(
ctx.module.add_function("__nac3_isinf", fn_type, None) ctx.module.add_function("__nac3_isinf", fn_type, None)
}); });
let ret = ctx.builder ctx.builder
.build_call(intrinsic_fn, &[v.into()], "isinf") .build_call(intrinsic_fn, &[v.into()], "isinf")
.try_as_basic_value() .try_as_basic_value()
.unwrap_left() .unwrap_left()
.into_int_value(); .into_int_value()
generator.bool_to_i1(ctx, ret)
} }
/// Generates a call to `isnan` in IR. Returns an `i1` representing the result. /// Generates a call to `isnan` in IR. Returns either an `i32` representing the result.
pub fn call_isnan<'ctx, 'a>( pub fn call_isnan<'ctx, 'a>(
generator: &mut dyn CodeGenerator,
ctx: &CodeGenContext<'ctx, 'a>, ctx: &CodeGenContext<'ctx, 'a>,
v: FloatValue<'ctx>, v: FloatValue<'ctx>,
) -> IntValue<'ctx> { ) -> IntValue<'ctx> {
@ -464,11 +460,9 @@ pub fn call_isnan<'ctx, 'a>(
ctx.module.add_function("__nac3_isnan", fn_type, None) ctx.module.add_function("__nac3_isnan", fn_type, None)
}); });
let ret = ctx.builder ctx.builder
.build_call(intrinsic_fn, &[v.into()], "isnan") .build_call(intrinsic_fn, &[v.into()], "isnan")
.try_as_basic_value() .try_as_basic_value()
.unwrap_left() .unwrap_left()
.into_int_value(); .into_int_value()
generator.bool_to_i1(ctx, ret)
} }

View File

@ -1195,7 +1195,10 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
assert!(ctx.unifier.unioned(x_ty, float)); assert!(ctx.unifier.unioned(x_ty, float));
let val = call_isnan(generator, ctx, x_val.into_float_value()); let val = generator.bool_to_i1(
ctx,
call_isnan(ctx, x_val.into_float_value()).into()
);
Ok(Some(val.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)); assert!(ctx.unifier.unioned(x_ty, float));
let val = call_isinf(generator, ctx, x_val.into_float_value()); let val = generator.bool_to_i1(
ctx,
call_isinf(ctx, x_val.into_float_value()).into()
);
Ok(Some(val.into())) Ok(Some(val.into()))
}), }),
@ -1521,34 +1527,32 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
// v = if isinf(x) || isnan(x) { x } else { v } // Handles (1)-(3) // v = if isinf(x) || isnan(x) { x } else { v } // Handles (1)-(3)
// %v.isinf = call i32 @__nac3_isinf(f64 %0) // %v.isinf = call i32 @__nac3_isinf(f64 %0)
// %v.isinf.tobool = icmp ne i32 %v.isinf, 0 let v_isinf = call_isinf(ctx, call.into());
let v_isinf = call_isinf(generator, ctx, call.into());
// %v.isnan = call i32 @__nac3_isnan(f64 %0) // %v.isnan = call i32 @__nac3_isnan(f64 %0)
// %v.isnan.tobool = icmp ne i32 %v.isnan, 0 let v_isnan = call_isnan(ctx, call.into());
let v_isnan = call_isnan(generator, ctx, call.into());
// %or = or i1 %v.isinf.tobool, %v.isnan.tobool // %or = or i32 %v.isinf, %v.isnan
// %3 = select i1 %or, f64 inf, f64 %0 // %or.tobool = icmp ne i32 %or, 0
// %3 = select i1 %or.tobool, f64 inf, f64 %0
let v_is_nonnum = ctx.builder.build_or(v_isinf, v_isnan, ""); let v_is_nonnum = ctx.builder.build_or(v_isinf, v_isnan, "");
let val = ctx.builder.build_select( let val = ctx.builder.build_select(
v_is_nonnum, generator.bool_to_i1(ctx, v_is_nonnum),
llvm_f64.const_float(f64::INFINITY).into(), llvm_f64.const_float(f64::INFINITY).into(),
call, call,
"", "",
).into_float_value(); ).into_float_value();
// %z.isinf = call i32 @__nac3_isinf(f64 %z) // %z.isinf = call i32 @__nac3_isinf(f64 %z)
// %z.isinf.tobool = icmp ne i32 %z.isinf, 0 let z_isinf = call_isinf(ctx, z_val.into_float_value());
let z_isinf = call_isinf(generator, ctx, z_val.into_float_value());
// %z.isnan = call i32 @__nac3_isnan(f64 %z) // %z.isnan = call i32 @__nac3_isnan(f64 %z)
// %z.isnan.tobool = icmp ne i32 %z.isnan, 0 let z_isnan = call_isnan(ctx, z_val.into_float_value());
let z_isnan = call_isnan(generator, ctx, z_val.into_float_value());
// %or = or i1 %z.isinf.tobool, %z.isnan.tobool // %or = or i32 %z.isinf, %z.isnan
// %val = select i1 %or, f64 %z, f64 %3 // %or.tobool = icmp ne i32 %or, 0
// %val = select i1 %or.tobool, f64 %z, f64 %3
let z_is_nonnum = ctx.builder.build_or(z_isinf, z_isnan, ""); let z_is_nonnum = ctx.builder.build_or(z_isinf, z_isnan, "");
let val = ctx.builder.build_select( let val = ctx.builder.build_select(
z_is_nonnum, generator.bool_to_i1(ctx, z_is_nonnum),
z_val.into_float_value(), z_val.into_float_value(),
val, val,
"", "",
@ -1605,7 +1609,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
// %tobool = icmp ne i32 %isinf, 0 // %tobool = icmp ne i32 %isinf, 0
// %val = select i1 %tobool, f64 %x, f64 %0 // %val = select i1 %tobool, f64 %x, f64 %0
let v = ctx.builder.build_select( let v = ctx.builder.build_select(
call_isinf(generator, ctx, x_val.into_float_value()), generator.bool_to_i1(ctx, call_isinf(ctx, x_val.into_float_value()).into()),
x_val, x_val,
call.into(), call.into(),
"" ""
@ -1660,7 +1664,10 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
// %1 = call i32 @__nac3_isinf(f64 %x) // %1 = call i32 @__nac3_isinf(f64 %x)
// %tobool = icmp ne i32 %isinf, 0 // %tobool = icmp ne i32 %isinf, 0
let arg_isinf = call_isinf(generator, ctx, x_val.into_float_value()); let arg_isinf = generator.bool_to_i1(
ctx,
call_isinf(ctx, x_val.into_float_value()).into()
);
// %val = select i1 %tobool, f64 nan, f64 %0 // %val = select i1 %tobool, f64 nan, f64 %0
let val = ctx.builder let val = ctx.builder