From 710904f97514f1f8306065b70ebde9efeec7108b Mon Sep 17 00:00:00 2001 From: ychenfo Date: Sat, 2 Apr 2022 03:26:15 +0800 Subject: [PATCH 1/2] nac3core: fix powi with negative integer power --- nac3core/src/codegen/expr.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/nac3core/src/codegen/expr.rs b/nac3core/src/codegen/expr.rs index 33c0eec4e..63c17b470 100644 --- a/nac3core/src/codegen/expr.rs +++ b/nac3core/src/codegen/expr.rs @@ -948,15 +948,12 @@ pub fn gen_binop_expr<'ctx, 'a, G: CodeGenerator>( } else if ty1 == ctx.primitives.float && ty2 == ctx.primitives.int32 { // Pow is the only operator that would pass typecheck between float and int assert!(*op == Operator::Pow); - // TODO: throw exception when rhs is out of i16 bound - // since llvm intrinsic only support to i16 for f64 - let i16_t = ctx.ctx.i16_type(); - let pow_intr = ctx.module.get_function("llvm.powi.f64.i16").unwrap_or_else(|| { + let i32_t = ctx.ctx.i32_type(); + let pow_intr = ctx.module.get_function("llvm.powi.f64.i32").unwrap_or_else(|| { let f64_t = ctx.ctx.f64_type(); - let ty = f64_t.fn_type(&[f64_t.into(), i16_t.into()], false); - ctx.module.add_function("llvm.powi.f64.i16", ty, None) + let ty = f64_t.fn_type(&[f64_t.into(), i32_t.into()], false); + ctx.module.add_function("llvm.powi.f64.i32", ty, None) }); - let right = ctx.builder.build_int_truncate(right.into_int_value(), i16_t, "r_pow"); ctx.builder .build_call(pow_intr, &[left.into(), right.into()], "f_pow_i") .try_as_basic_value() From 23b7f4ef1828ff62d951585bf2857588fece771f Mon Sep 17 00:00:00 2001 From: ychenfo Date: Sat, 2 Apr 2022 03:29:25 +0800 Subject: [PATCH 2/2] nac3standalone: add tests for power --- nac3standalone/demo/src/pow.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 nac3standalone/demo/src/pow.py diff --git a/nac3standalone/demo/src/pow.py b/nac3standalone/demo/src/pow.py new file mode 100644 index 000000000..d17abd73f --- /dev/null +++ b/nac3standalone/demo/src/pow.py @@ -0,0 +1,26 @@ +@extern +def output_float64(f: float): + ... + + +def run() -> int32: + output_float64(float(3 ** 1)) + output_float64(float(3 ** 0)) + output_float64(float(3 ** 19)) + output_float64(1.0 ** -100) + output_float64(1.0 ** -2) + output_float64(1.0 ** 0) + output_float64(1.0 ** 1) + output_float64(1.0 ** 100) + output_float64(3.0 ** 0) + output_float64(3.0 ** 1) + output_float64(3.0 ** 2) + output_float64(3.0 ** -1) + output_float64(3.0 ** -2) + output_float64(3.0 ** -32767) + output_float64(3.0 ** -3.0) + output_float64(3.0 ** -0.0) + output_float64(3.0 ** 0.0) + output_float64(4.0 ** 0.5) + output_float64(4.0 ** -0.5) + return 0 \ No newline at end of file