Compare commits
5 Commits
7966535677
...
2e1d6ab644
Author | SHA1 | Date |
---|---|---|
David Mak | 2e1d6ab644 | |
David Mak | 8d85ca3ac1 | |
David Mak | 9d3d5be383 | |
David Mak | df4f5fe9f3 | |
David Mak | 197ffbbe81 |
|
@ -433,8 +433,9 @@ 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 `i32` representing the result.
|
/// Generates a call to `isinf` in IR. Returns an `i1` 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> {
|
||||||
|
@ -443,15 +444,18 @@ pub fn call_isinf<'ctx, 'a>(
|
||||||
ctx.module.add_function("__nac3_isinf", fn_type, None)
|
ctx.module.add_function("__nac3_isinf", fn_type, None)
|
||||||
});
|
});
|
||||||
|
|
||||||
ctx.builder
|
let ret = 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 either an `i32` representing the result.
|
/// Generates a call to `isnan` in IR. Returns an `i1` 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> {
|
||||||
|
@ -460,9 +464,11 @@ pub fn call_isnan<'ctx, 'a>(
|
||||||
ctx.module.add_function("__nac3_isnan", fn_type, None)
|
ctx.module.add_function("__nac3_isnan", fn_type, None)
|
||||||
});
|
});
|
||||||
|
|
||||||
ctx.builder
|
let ret = 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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1195,10 +1195,7 @@ 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 = generator.bool_to_i1(
|
let val = call_isnan(generator, ctx, x_val.into_float_value());
|
||||||
ctx,
|
|
||||||
call_isnan(ctx, x_val.into_float_value()).into()
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(Some(val.into()))
|
Ok(Some(val.into()))
|
||||||
}),
|
}),
|
||||||
|
@ -1218,10 +1215,7 @@ 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 = generator.bool_to_i1(
|
let val = call_isinf(generator, ctx, x_val.into_float_value());
|
||||||
ctx,
|
|
||||||
call_isinf(ctx, x_val.into_float_value()).into()
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(Some(val.into()))
|
Ok(Some(val.into()))
|
||||||
}),
|
}),
|
||||||
|
@ -1527,32 +1521,34 @@ 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)
|
||||||
let v_isinf = call_isinf(ctx, call.into());
|
// %v.isinf.tobool = icmp ne i32 %v.isinf, 0
|
||||||
|
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)
|
||||||
let v_isnan = call_isnan(ctx, call.into());
|
// %v.isnan.tobool = icmp ne i32 %v.isnan, 0
|
||||||
|
let v_isnan = call_isnan(generator, ctx, call.into());
|
||||||
|
|
||||||
// %or = or i32 %v.isinf, %v.isnan
|
// %or = or i1 %v.isinf.tobool, %v.isnan.tobool
|
||||||
// %or.tobool = icmp ne i32 %or, 0
|
// %3 = select i1 %or, f64 inf, f64 %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(
|
||||||
generator.bool_to_i1(ctx, v_is_nonnum),
|
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)
|
||||||
let z_isinf = call_isinf(ctx, z_val.into_float_value());
|
// %z.isinf.tobool = icmp ne i32 %z.isinf, 0
|
||||||
|
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)
|
||||||
let z_isnan = call_isnan(ctx, z_val.into_float_value());
|
// %z.isnan.tobool = icmp ne i32 %z.isnan, 0
|
||||||
|
let z_isnan = call_isnan(generator, ctx, z_val.into_float_value());
|
||||||
|
|
||||||
// %or = or i32 %z.isinf, %z.isnan
|
// %or = or i1 %z.isinf.tobool, %z.isnan.tobool
|
||||||
// %or.tobool = icmp ne i32 %or, 0
|
// %val = select i1 %or, f64 %z, f64 %3
|
||||||
// %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(
|
||||||
generator.bool_to_i1(ctx, z_is_nonnum),
|
z_is_nonnum,
|
||||||
z_val.into_float_value(),
|
z_val.into_float_value(),
|
||||||
val,
|
val,
|
||||||
"",
|
"",
|
||||||
|
@ -1609,7 +1605,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(
|
||||||
generator.bool_to_i1(ctx, call_isinf(ctx, x_val.into_float_value()).into()),
|
call_isinf(generator, ctx, x_val.into_float_value()),
|
||||||
x_val,
|
x_val,
|
||||||
call.into(),
|
call.into(),
|
||||||
""
|
""
|
||||||
|
@ -1664,10 +1660,7 @@ 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 = generator.bool_to_i1(
|
let arg_isinf = call_isinf(generator, ctx, x_val.into_float_value());
|
||||||
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
|
||||||
|
|
Loading…
Reference in New Issue