forked from M-Labs/nac3
core: Fix handling of float-to-int32 casts
Out-of-bound conversions should be wrapped around.
This commit is contained in:
parent
447eb9c387
commit
7a5a2db842
@ -477,12 +477,16 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
||||||
|ctx, _, fun, args, generator| {
|
|ctx, _, fun, args, generator| {
|
||||||
let int32 = ctx.primitives.int32;
|
let PrimitiveStore {
|
||||||
let int64 = ctx.primitives.int64;
|
int32,
|
||||||
let uint32 = ctx.primitives.uint32;
|
int64,
|
||||||
let uint64 = ctx.primitives.uint64;
|
uint32,
|
||||||
let float = ctx.primitives.float;
|
uint64,
|
||||||
let boolean = ctx.primitives.bool;
|
float,
|
||||||
|
bool: boolean,
|
||||||
|
..
|
||||||
|
} = ctx.primitives;
|
||||||
|
|
||||||
let arg_ty = fun.0.args[0].ty;
|
let arg_ty = fun.0.args[0].ty;
|
||||||
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator, arg_ty)?;
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator, arg_ty)?;
|
||||||
Ok(if ctx.unifier.unioned(arg_ty, boolean) {
|
Ok(if ctx.unifier.unioned(arg_ty, boolean) {
|
||||||
@ -512,15 +516,21 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||||||
.into(),
|
.into(),
|
||||||
)
|
)
|
||||||
} else if ctx.unifier.unioned(arg_ty, float) {
|
} else if ctx.unifier.unioned(arg_ty, float) {
|
||||||
let val = ctx
|
let to_int64 = ctx
|
||||||
.builder
|
.builder
|
||||||
.build_float_to_signed_int(
|
.build_float_to_signed_int(
|
||||||
arg.into_float_value(),
|
arg.into_float_value(),
|
||||||
|
ctx.ctx.i64_type(),
|
||||||
|
"",
|
||||||
|
);
|
||||||
|
let val = ctx.builder
|
||||||
|
.build_int_truncate(
|
||||||
|
to_int64,
|
||||||
ctx.ctx.i32_type(),
|
ctx.ctx.i32_type(),
|
||||||
"fptosi",
|
"conv",
|
||||||
)
|
);
|
||||||
.into();
|
|
||||||
Some(val)
|
Some(val.into())
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
})
|
})
|
||||||
@ -542,12 +552,16 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
||||||
|ctx, _, fun, args, generator| {
|
|ctx, _, fun, args, generator| {
|
||||||
let int32 = ctx.primitives.int32;
|
let PrimitiveStore {
|
||||||
let int64 = ctx.primitives.int64;
|
int32,
|
||||||
let uint32 = ctx.primitives.uint32;
|
int64,
|
||||||
let uint64 = ctx.primitives.uint64;
|
uint32,
|
||||||
let float = ctx.primitives.float;
|
uint64,
|
||||||
let boolean = ctx.primitives.bool;
|
float,
|
||||||
|
bool: boolean,
|
||||||
|
..
|
||||||
|
} = ctx.primitives;
|
||||||
|
|
||||||
let arg_ty = fun.0.args[0].ty;
|
let arg_ty = fun.0.args[0].ty;
|
||||||
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator, arg_ty)?;
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator, arg_ty)?;
|
||||||
Ok(
|
Ok(
|
||||||
@ -609,12 +623,16 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
||||||
|ctx, _, fun, args, generator| {
|
|ctx, _, fun, args, generator| {
|
||||||
let int32 = ctx.primitives.int32;
|
let PrimitiveStore {
|
||||||
let int64 = ctx.primitives.int64;
|
int32,
|
||||||
let uint32 = ctx.primitives.uint32;
|
int64,
|
||||||
let uint64 = ctx.primitives.uint64;
|
uint32,
|
||||||
let float = ctx.primitives.float;
|
uint64,
|
||||||
let boolean = ctx.primitives.bool;
|
float,
|
||||||
|
bool: boolean,
|
||||||
|
..
|
||||||
|
} = ctx.primitives;
|
||||||
|
|
||||||
let arg_ty = fun.0.args[0].ty;
|
let arg_ty = fun.0.args[0].ty;
|
||||||
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator, arg_ty)?;
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator, arg_ty)?;
|
||||||
let res = if ctx.unifier.unioned(arg_ty, boolean) {
|
let res = if ctx.unifier.unioned(arg_ty, boolean) {
|
||||||
@ -661,12 +679,16 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
||||||
|ctx, _, fun, args, generator| {
|
|ctx, _, fun, args, generator| {
|
||||||
let int32 = ctx.primitives.int32;
|
let PrimitiveStore {
|
||||||
let int64 = ctx.primitives.int64;
|
int32,
|
||||||
let uint32 = ctx.primitives.uint32;
|
int64,
|
||||||
let uint64 = ctx.primitives.uint64;
|
uint32,
|
||||||
let float = ctx.primitives.float;
|
uint64,
|
||||||
let boolean = ctx.primitives.bool;
|
float,
|
||||||
|
bool: boolean,
|
||||||
|
..
|
||||||
|
} = ctx.primitives;
|
||||||
|
|
||||||
let arg_ty = fun.0.args[0].ty;
|
let arg_ty = fun.0.args[0].ty;
|
||||||
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator, arg_ty)?;
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator, arg_ty)?;
|
||||||
let res = if ctx.unifier.unioned(arg_ty, int32)
|
let res = if ctx.unifier.unioned(arg_ty, int32)
|
||||||
@ -727,6 +749,13 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||||||
.build_signed_int_to_float(arg, ctx.ctx.f64_type(), "sitofp")
|
.build_signed_int_to_float(arg, ctx.ctx.f64_type(), "sitofp")
|
||||||
.into();
|
.into();
|
||||||
Some(val)
|
Some(val)
|
||||||
|
} else if [uint32, uint64].iter().any(|ty| ctx.unifier.unioned(arg_ty, *ty)) {
|
||||||
|
let arg = arg.into_int_value();
|
||||||
|
let val = ctx
|
||||||
|
.builder
|
||||||
|
.build_unsigned_int_to_float(arg, ctx.ctx.f64_type(), "uitofp")
|
||||||
|
.into();
|
||||||
|
Some(val)
|
||||||
} else if ctx.unifier.unioned(arg_ty, float) {
|
} else if ctx.unifier.unioned(arg_ty, float) {
|
||||||
Some(arg)
|
Some(arg)
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user