blob: 89da6e018c022f9d8551a3a80382661e1a18c60e [file]
--- 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')