mirror of
				https://github.com/bytecodealliance/wasm-micro-runtime.git
				synced 2025-10-31 13:17:31 +00:00 
			
		
		
		
	Fix missing float cmp for XIP (#1699)
This commit is contained in:
		
							parent
							
								
									cef4e74fee
								
							
						
					
					
						commit
						4b0660cf24
					
				|  | @ -72,6 +72,8 @@ static const aot_intrinsic g_intrinsic_mapping[] = { | |||
|     { "i64.div_u", "aot_intrinsic_i64_div_u", AOT_INTRINSIC_FLAG_I64_DIV_U}, | ||||
|     { "i64.rem_s", "aot_intrinsic_i64_rem_s", AOT_INTRINSIC_FLAG_I64_REM_S}, | ||||
|     { "i64.rem_u", "aot_intrinsic_i64_rem_u", AOT_INTRINSIC_FLAG_I64_REM_U}, | ||||
|     { "i64.or", "aot_intrinsic_i64_bit_or", AOT_INTRINSIC_FLAG_I64_BIT_OR}, | ||||
|     { "i64.and", "aot_intrinsic_i64_bit_and", AOT_INTRINSIC_FLAG_I64_BIT_AND}, | ||||
| }; | ||||
| /* clang-format on */ | ||||
| 
 | ||||
|  | @ -524,6 +526,18 @@ aot_intrinsic_i64_rem_u(uint64 l, uint64 r) | |||
|     return l % r; | ||||
| } | ||||
| 
 | ||||
| uint64 | ||||
| aot_intrinsic_i64_bit_or(uint64 l, uint64 r) | ||||
| { | ||||
|     return l | r; | ||||
| } | ||||
| 
 | ||||
| uint64 | ||||
| aot_intrinsic_i64_bit_and(uint64 l, uint64 r) | ||||
| { | ||||
|     return l & r; | ||||
| } | ||||
| 
 | ||||
| const char * | ||||
| aot_intrinsic_get_symbol(const char *llvm_intrinsic) | ||||
| { | ||||
|  | @ -558,6 +572,8 @@ add_i64_common_intrinsics(AOTCompContext *comp_ctx) | |||
|     add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I64_DIV_U); | ||||
|     add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I64_REM_S); | ||||
|     add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I64_REM_U); | ||||
|     add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I64_BIT_OR); | ||||
|     add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I64_BIT_AND); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
|  |  | |||
|  | @ -93,6 +93,8 @@ extern "C" { | |||
| #define AOT_INTRINSIC_FLAG_I64_DIV_U    AOT_INTRINSIC_FLAG(1, 29) | ||||
| #define AOT_INTRINSIC_FLAG_I64_REM_S    AOT_INTRINSIC_FLAG(1, 30) | ||||
| #define AOT_INTRINSIC_FLAG_I64_REM_U    AOT_INTRINSIC_FLAG(1, 31) | ||||
| #define AOT_INTRINSIC_FLAG_I64_BIT_OR   AOT_INTRINSIC_FLAG(1, 32) | ||||
| #define AOT_INTRINSIC_FLAG_I64_BIT_AND  AOT_INTRINSIC_FLAG(1, 33) | ||||
| 
 | ||||
| /* clang-format on */ | ||||
| 
 | ||||
|  | @ -267,6 +269,12 @@ aot_intrinsic_i64_rem_s(int64 l, int64 r); | |||
| uint64 | ||||
| aot_intrinsic_i64_rem_u(uint64 l, uint64 r); | ||||
| 
 | ||||
| uint64 | ||||
| aot_intrinsic_i64_bit_or(uint64 l, uint64 r); | ||||
| 
 | ||||
| uint64 | ||||
| aot_intrinsic_i64_bit_and(uint64 l, uint64 r); | ||||
| 
 | ||||
| const char * | ||||
| aot_intrinsic_get_symbol(const char *llvm_intrinsic); | ||||
| 
 | ||||
|  |  | |||
|  | @ -112,6 +112,8 @@ typedef struct { | |||
|     REG_SYM(aot_intrinsic_i64_div_u),     \ | ||||
|     REG_SYM(aot_intrinsic_i64_rem_s),     \ | ||||
|     REG_SYM(aot_intrinsic_i64_rem_u),     \ | ||||
|     REG_SYM(aot_intrinsic_i64_bit_or),    \ | ||||
|     REG_SYM(aot_intrinsic_i64_bit_and),   \ | ||||
|     REG_SYM(aot_intrinsic_i32_div_u),     \ | ||||
| 
 | ||||
| #define REG_COMMON_SYMBOLS                \ | ||||
|  |  | |||
|  | @ -234,15 +234,49 @@ compile_op_float_min_max(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, | |||
|         nan = LLVMConstRealOfString(ret_type, "NaN"); | ||||
|     char *intrinsic = is_min ? (is_f32 ? "llvm.minnum.f32" : "llvm.minnum.f64") | ||||
|                              : (is_f32 ? "llvm.maxnum.f32" : "llvm.maxnum.f64"); | ||||
|     bool is_i32 = is_f32; | ||||
| 
 | ||||
|     CHECK_LLVM_CONST(nan); | ||||
| 
 | ||||
|     param_types[0] = param_types[1] = ret_type; | ||||
| 
 | ||||
|     if (!(is_nan = LLVMBuildFCmp(comp_ctx->builder, LLVMRealUNO, left, right, | ||||
|                                  "is_nan")) | ||||
|         || !(is_eq = LLVMBuildFCmp(comp_ctx->builder, LLVMRealOEQ, left, right, | ||||
|                                    "is_eq"))) { | ||||
|     if (comp_ctx->disable_llvm_intrinsics | ||||
|         && aot_intrinsic_check_capability(comp_ctx, | ||||
|                                           is_f32 ? "f32_cmp" : "f64_cmp")) { | ||||
|         LLVMTypeRef param_types[3]; | ||||
|         LLVMValueRef opcond = LLVMConstInt(I32_TYPE, FLOAT_UNO, true); | ||||
|         param_types[0] = I32_TYPE; | ||||
|         param_types[1] = is_f32 ? F32_TYPE : F64_TYPE; | ||||
|         param_types[2] = param_types[1]; | ||||
|         is_nan = aot_call_llvm_intrinsic( | ||||
|             comp_ctx, func_ctx, is_f32 ? "f32_cmp" : "f64_cmp", I32_TYPE, | ||||
|             param_types, 3, opcond, left, right); | ||||
| 
 | ||||
|         opcond = LLVMConstInt(I32_TYPE, FLOAT_EQ, true); | ||||
|         is_eq = aot_call_llvm_intrinsic( | ||||
|             comp_ctx, func_ctx, is_f32 ? "f32_cmp" : "f64_cmp", I32_TYPE, | ||||
|             param_types, 3, opcond, left, right); | ||||
| 
 | ||||
|         if (!is_nan || !is_eq) { | ||||
|             return NULL; | ||||
|         } | ||||
| 
 | ||||
|         if (!(is_nan = LLVMBuildIntCast(comp_ctx->builder, is_nan, INT1_TYPE, | ||||
|                                         "bit_cast_is_nan"))) { | ||||
|             aot_set_last_error("llvm build is_nan bit cast fail."); | ||||
|             return NULL; | ||||
|         } | ||||
| 
 | ||||
|         if (!(is_eq = LLVMBuildIntCast(comp_ctx->builder, is_eq, INT1_TYPE, | ||||
|                                        "bit_cast_is_eq"))) { | ||||
|             aot_set_last_error("llvm build is_eq bit cast fail."); | ||||
|             return NULL; | ||||
|         } | ||||
|     } | ||||
|     else if (!(is_nan = LLVMBuildFCmp(comp_ctx->builder, LLVMRealUNO, left, | ||||
|                                       right, "is_nan")) | ||||
|              || !(is_eq = LLVMBuildFCmp(comp_ctx->builder, LLVMRealOEQ, left, | ||||
|                                         right, "is_eq"))) { | ||||
|         aot_set_last_error("llvm build fcmp fail."); | ||||
|         return NULL; | ||||
|     } | ||||
|  | @ -258,9 +292,11 @@ compile_op_float_min_max(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, | |||
|     } | ||||
| 
 | ||||
|     if (is_min) | ||||
|         LLVM_BUILD_OP(Or, left_int, right_int, tmp, "tmp_int", NULL); | ||||
|         LLVM_BUILD_OP_OR_INTRINSIC(Or, left_int, right_int, tmp, "i64.or", | ||||
|                                    "tmp_int", false); | ||||
|     else | ||||
|         LLVM_BUILD_OP(And, left_int, right_int, tmp, "tmp_int", NULL); | ||||
|         LLVM_BUILD_OP_OR_INTRINSIC(And, left_int, right_int, tmp, "i64.and", | ||||
|                                    "tmp_int", false); | ||||
| 
 | ||||
|     if (!(tmp = LLVMBuildBitCast(comp_ctx->builder, tmp, ret_type, "tmp"))) { | ||||
|         aot_set_last_error("llvm build bitcast fail."); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Huang Qi
						Huang Qi