mirror of
				https://github.com/bytecodealliance/wasm-micro-runtime.git
				synced 2025-10-31 13:17:31 +00:00 
			
		
		
		
	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:
		
							parent
							
								
									e73993709e
								
							
						
					
					
						commit
						72b34eaf30
					
				|  | @ -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); | ||||
|  |  | |||
|  | @ -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 | ||||
|   ) | ||||
| ) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Marcin Kolny
						Marcin Kolny