[clang] [RISCV][clang] Don't enable -mrelax-all for -O0 on RISC-V (PR #88538)

via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 12 10:22:22 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-driver

Author: Craig Topper (topperc)

<details>
<summary>Changes</summary>

-O0 implies -mrelax-all as an assembler compile time optimization. -mrelax-all allows the assembler to complete layout in 2 passes instead of doing iterative branch relaxation.

Jump offsets larger than +/-1MiB require an indirect jump on RISC-V. This can't be done by the assembler, so we use a branch relaxation MIR pass and use register scavenging to find a free register.

The conditional branch offsets for RISC-V are also somewhat small so we support MC layer branch relaxation to make life easier for assembly programmers. This may also cover up bugs in our function size estimation in MachineIR.

Enabling -mrelax-all causes the MC layer relaxation to agressively relax branches. This increases code size and can create cases where we need an indirect jump, but we can't create one. This leads to linker failures.

The easiest way to avoid this is to not default to -mrelax-all for -O0 and sacrifice the compile time optimization. That's what this patch does.

Fixes #<!-- -->87127

---
Full diff: https://github.com/llvm/llvm-project/pull/88538.diff


2 Files Affected:

- (modified) clang/lib/Driver/ToolChains/Clang.cpp (+10) 
- (modified) clang/test/Driver/integrated-as.c (+1-1) 


``````````diff
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 766a9b91e3c0ad..856a88bdc3aad4 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -844,6 +844,16 @@ static bool UseRelaxAll(Compilation &C, const ArgList &Args) {
   if (Arg *A = Args.getLastArg(options::OPT_O_Group))
     RelaxDefault = A->getOption().matches(options::OPT_O0);
 
+  // RISC-V requires an indirect jump for offsets larger than 1MiB. This cannot
+  // be done by assembler branch relaxation as it needs a free temporary
+  // register. Because of this, branch relaxation is handled by a MachineIR
+  // pass before the assembler. Forcing assembler branch relaxation for -O0
+  // makes the MachineIR branch relaxation inaccurate and it will miss cases
+  // where an indirect branch is necessary. To avoid this issue we are
+  // sacrificing the compile time improvement of using -mrelax-all for -O0.
+  if (C.getDefaultToolChain().getTriple().isRISCV())
+    RelaxDefault = false;
+
   if (RelaxDefault) {
     RelaxDefault = false;
     for (const auto &Act : C.getActions()) {
diff --git a/clang/test/Driver/integrated-as.c b/clang/test/Driver/integrated-as.c
index d7658fdfd63374..5b79714a2c547e 100644
--- a/clang/test/Driver/integrated-as.c
+++ b/clang/test/Driver/integrated-as.c
@@ -1,4 +1,4 @@
-// XFAIL: target={{.*}}-aix{{.*}}
+// XFAIL: target={{.*}}-aix{{.*}}, target=riscv{{.*}}
 
 // RUN: %clang -### -c -save-temps -integrated-as %s 2>&1 | FileCheck %s
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/88538


More information about the cfe-commits mailing list