Skip to content

Commit 6b1b4c1

Browse files
authored
[RISCV][clang] Don't enable -mrelax-all for -O0 on RISC-V (llvm#88538)
-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 llvm#87127
1 parent dd79632 commit 6b1b4c1

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -847,6 +847,16 @@ static bool UseRelaxAll(Compilation &C, const ArgList &Args) {
847847
if (Arg *A = Args.getLastArg(options::OPT_O_Group))
848848
RelaxDefault = A->getOption().matches(options::OPT_O0);
849849

850+
// RISC-V requires an indirect jump for offsets larger than 1MiB. This cannot
851+
// be done by assembler branch relaxation as it needs a free temporary
852+
// register. Because of this, branch relaxation is handled by a MachineIR
853+
// pass before the assembler. Forcing assembler branch relaxation for -O0
854+
// makes the MachineIR branch relaxation inaccurate and it will miss cases
855+
// where an indirect branch is necessary. To avoid this issue we are
856+
// sacrificing the compile time improvement of using -mrelax-all for -O0.
857+
if (C.getDefaultToolChain().getTriple().isRISCV())
858+
RelaxDefault = false;
859+
850860
if (RelaxDefault) {
851861
RelaxDefault = false;
852862
for (const auto &Act : C.getActions()) {

clang/test/Driver/integrated-as.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
// XFAIL: target={{.*}}-aix{{.*}}
22

3-
// RUN: %clang -### -c -save-temps -integrated-as %s 2>&1 | FileCheck %s
3+
// RUN: %clang -### -c -save-temps -integrated-as --target=x86_64 %s 2>&1 | FileCheck %s
44

55
// CHECK: cc1as
66
// CHECK: -mrelax-all
77

8+
// RISC-V does not enable -mrelax-all
9+
// RUN: %clang -### -c -save-temps -integrated-as --target=riscv64 %s 2>&1 | FileCheck %s -check-prefix=RISCV-RELAX
10+
11+
// RISCV-RELAX: cc1as
12+
// RISCV-RELAX-NOT: -mrelax-all
13+
814
// RUN: %clang -### -fintegrated-as -c -save-temps %s 2>&1 | FileCheck %s -check-prefix FIAS
915

1016
// FIAS: cc1as

0 commit comments

Comments
 (0)