| --- a/core/iwasm/compilation/aot_llvm.c |
| +++ b/core/iwasm/compilation/aot_llvm.c |
| @@ -3238,9 +3253,17 @@ |
| else |
| code_model = LLVMCodeModelSmall; |
| |
| - /* Create the target machine */ |
| + /* Create the target machine. The backend level may be pinned below |
| + the IR level: LLVM's optimizing AArch64 codegen miscompiles the |
| + strict (constrained) FP this compiler emits, so a build can keep |
| + IR optimization while selecting instructions conservatively. */ |
| + uint32 tm_opt_level = opt_level; |
| + if (option->codegen_opt_level_plus_one != 0 |
| + && option->codegen_opt_level_plus_one - 1 < tm_opt_level) { |
| + tm_opt_level = option->codegen_opt_level_plus_one - 1; |
| + } |
| if (!(comp_ctx->target_machine = LLVMCreateTargetMachineWithOpts( |
| - target, triple_norm, cpu, features, opt_level, |
| + target, triple_norm, cpu, features, tm_opt_level, |
| LLVMRelocStatic, code_model, false, |
| comp_ctx->stack_usage_file))) { |
| aot_set_last_error("create LLVM target machine failed."); |
| --- a/core/iwasm/include/aot_comp_option.h |
| +++ b/core/iwasm/include/aot_comp_option.h |
| @@ -83,6 +83,10 @@ |
| bool enable_shared_chain; |
| char *use_prof_file; |
| uint32_t opt_level; |
| + /* Backend codegen level override, stored as level + 1 so a zeroed |
| + struct follows opt_level. Lets a build keep IR optimization while |
| + pinning conservative instruction selection. */ |
| + uint32_t codegen_opt_level_plus_one; |
| uint32_t size_level; |
| uint32_t output_format; |
| uint32_t bounds_checks; |
| --- a/wamr-compiler/main.c |
| +++ b/wamr-compiler/main.c |
| @@ -130,6 +130,7 @@ |
| printf(" For example, --cpu-features=+feature1,-feature2\n"); |
| printf(" Use --cpu-features=+help to list all the features supported\n"); |
| printf(" --opt-level=n Set the optimization level (0 to 3, default is 3)\n"); |
| + printf(" --codegen-opt-level=n Cap the backend codegen level below the IR opt level\n"); |
| printf(" --size-level=n Set the code size level (0 to 3, default is 3)\n"); |
| printf(" 0 - Large code model\n"); |
| printf(" 1 - Medium code model\n"); |
| @@ -472,6 +473,15 @@ |
| option.opt_level = (uint32)atoi(argv[0] + 12); |
| if (option.opt_level > 3) |
| option.opt_level = 3; |
| + } |
| + else if (!strncmp(argv[0], "--codegen-opt-level=", 20)) { |
| + uint32 level; |
| + if (argv[0][20] == '\0') |
| + PRINT_HELP_AND_EXIT(); |
| + level = (uint32)atoi(argv[0] + 20); |
| + if (level > 3) |
| + level = 3; |
| + option.codegen_opt_level_plus_one = level + 1; |
| } |
| else if (!strncmp(argv[0], "--size-level=", 13)) { |
| if (argv[0][13] == '\0') |