Fix AOT shift operations for indirect constants (#2627)

When doing more investigations related to this PR:
  https://github.com/bytecodealliance/wasm-micro-runtime/pull/2619
We found that in some scenarios the constant might not be directly
available to the LLVM IR builder, e.g.:
```
  (func $const_ret (result i32)
    i32.const -5
  )
  (func $foo
    (i32.shr_u (i32.const -1) (call $const_ret))
    (i32.const 31)
  )
```
In that case, the right parameter to `i32.shr_u` is not constant, therefore
the `SHIFT_COUNT_MASK` isn't applied. However, when the optimization
is enabled (`--opt-level` is 2 or 3), the optimization passes resolve the
call into constant, and that constant is poisoned, causing the compiler to
resolve the whole function to an exception.
This commit is contained in:
Marcin Kolny 2023-10-11 04:22:34 +01:00 committed by GitHub
parent e73993709e
commit 72b34eaf30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 16 deletions

View File

@ -171,15 +171,6 @@
right = shift_count_mask; \
} while (0)
static bool
is_shift_count_mask_needed(AOTCompContext *comp_ctx, LLVMValueRef left,
LLVMValueRef right)
{
return (strcmp(comp_ctx->target_arch, "x86_64") != 0
&& strcmp(comp_ctx->target_arch, "i386") != 0)
|| (LLVMIsEfficientConstInt(left) && LLVMIsEfficientConstInt(right));
}
/* Call llvm constrained floating-point intrinsic */
static LLVMValueRef
call_llvm_float_experimental_constrained_intrinsic(AOTCompContext *comp_ctx,
@ -737,8 +728,7 @@ compile_int_shl(AOTCompContext *comp_ctx, LLVMValueRef left, LLVMValueRef right,
{
LLVMValueRef res;
if (is_shift_count_mask_needed(comp_ctx, left, right))
SHIFT_COUNT_MASK;
SHIFT_COUNT_MASK;
/* Build shl */
LLVM_BUILD_OP(Shl, left, right, res, "shl", NULL);
@ -752,8 +742,7 @@ compile_int_shr_s(AOTCompContext *comp_ctx, LLVMValueRef left,
{
LLVMValueRef res;
if (is_shift_count_mask_needed(comp_ctx, left, right))
SHIFT_COUNT_MASK;
SHIFT_COUNT_MASK;
/* Build shl */
LLVM_BUILD_OP(AShr, left, right, res, "shr_s", NULL);
@ -767,8 +756,7 @@ compile_int_shr_u(AOTCompContext *comp_ctx, LLVMValueRef left,
{
LLVMValueRef res;
if (is_shift_count_mask_needed(comp_ctx, left, right))
SHIFT_COUNT_MASK;
SHIFT_COUNT_MASK;
/* Build shl */
LLVM_BUILD_OP(LShr, left, right, res, "shr_u", NULL);

View File

@ -7,6 +7,7 @@
;; any problems. See: https://github.com/bytecodealliance/wasm-micro-runtime/pull/2619
(module
(memory (export "memory") 1 1)
(func $assert_eq (param i32 i32)
(i32.ne (local.get 0) (local.get 1))
if
@ -23,7 +24,7 @@
(func $i32_shr_s
(call $assert_eq
(i32.shr_u (i32.const 32) (i32.const -30))
(i32.shr_s (i32.const 32) (i32.const -30))
(i32.const 8)
)
)
@ -35,9 +36,43 @@
)
)
(func $const_ret (result i32)
i32.const -5
)
;; *_func_call tests validate the potential LLVM optimizations
;; where the right parameter of the shift operation is an
;; indirect constant value.
(func $i32_shr_u_func_call
(call $assert_eq
(i32.shr_u (i32.const -1) (call $const_ret))
(i32.const 31)
)
)
(func $i32_shr_s_func_call
(call $assert_eq
(i32.shr_s
(i32.const 1073741824) ;; 2^30
(call $const_ret)
)
(i32.const 8)
)
)
(func $i32_shl_func_call
(call $assert_eq
(i32.shl (i32.const -1) (call $const_ret))
(i32.const -134217728)
)
)
(func (export "_start")
call $i32_shr_u
call $i32_shr_s
call $i32_shl
call $i32_shr_u_func_call
call $i32_shr_s_func_call
call $i32_shl_func_call
)
)