-
Notifications
You must be signed in to change notification settings - Fork 14.6k
MC: Refine ALIGN relocation conditions #150816
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
MC: Refine ALIGN relocation conditions #150816
Conversation
Created using spr 1.3.5-bogner
@llvm/pr-subscribers-mc @llvm/pr-subscribers-backend-loongarch Author: Fangrui Song (MaskRay) ChangesGeneralize MCSection::LinkerRelaxable to a fragment index to implement
The new test llvm/test/MC/RISCV/Relocations/align-after-relax.s Full diff: https://github.com/llvm/llvm-project/pull/150816.diff 10 Files Affected:
diff --git a/llvm/include/llvm/MC/MCSection.h b/llvm/include/llvm/MC/MCSection.h
index 7989310e5a8f2..f70ed4ade23f2 100644
--- a/llvm/include/llvm/MC/MCSection.h
+++ b/llvm/include/llvm/MC/MCSection.h
@@ -567,6 +567,10 @@ class LLVM_ABI MCSection {
Align Alignment;
/// The section index in the assemblers section list.
unsigned Ordinal = 0;
+ // If not -1u, the first linker-relaxable fragment's order within the
+ // subsection. When present, the offset between two locations crossing this
+ // fragment may not be fully resolved.
+ unsigned FirstLinkerRelaxable = -1u;
/// Whether this section has had instructions emitted into it.
bool HasInstructions : 1;
@@ -576,10 +580,6 @@ class LLVM_ABI MCSection {
bool IsText : 1;
bool IsBss : 1;
- /// Whether the section contains linker-relaxable fragments. If true, the
- /// offset between two locations may not be fully resolved.
- bool LinkerRelaxable : 1;
-
MCFragment DummyFragment;
// Mapping from subsection number to fragment list. At layout time, the
@@ -634,8 +634,9 @@ class LLVM_ABI MCSection {
bool isRegistered() const { return IsRegistered; }
void setIsRegistered(bool Value) { IsRegistered = Value; }
- bool isLinkerRelaxable() const { return LinkerRelaxable; }
- void setLinkerRelaxable() { LinkerRelaxable = true; }
+ unsigned firstLinkerRelaxable() const { return FirstLinkerRelaxable; }
+ bool isLinkerRelaxable() const { return FirstLinkerRelaxable != -1u; }
+ void setFirstLinkerRelaxable(unsigned Order) { FirstLinkerRelaxable = Order; }
MCFragment &getDummyFragment() { return DummyFragment; }
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index f0465521c1433..6c66031e7dfb3 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -361,7 +361,9 @@ void MCObjectStreamer::emitInstToData(const MCInst &Inst,
// instruction cannot be resolved at assemble-time.
if (!MarkedLinkerRelaxable) {
MarkedLinkerRelaxable = true;
- getCurrentSectionOnly()->setLinkerRelaxable();
+ auto *Sec = getCurrentSectionOnly();
+ if (!Sec->isLinkerRelaxable())
+ Sec->setFirstLinkerRelaxable(F->getLayoutOrder());
newFragment();
}
}
diff --git a/llvm/lib/MC/MCSection.cpp b/llvm/lib/MC/MCSection.cpp
index 4f282672afbbf..eafd59a2478e9 100644
--- a/llvm/lib/MC/MCSection.cpp
+++ b/llvm/lib/MC/MCSection.cpp
@@ -20,7 +20,7 @@ using namespace llvm;
MCSection::MCSection(StringRef Name, bool IsText, bool IsBss, MCSymbol *Begin)
: Begin(Begin), HasInstructions(false), IsRegistered(false), IsText(IsText),
- IsBss(IsBss), LinkerRelaxable(false), Name(Name) {
+ IsBss(IsBss), Name(Name) {
DummyFragment.setParent(this);
}
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
index d9ea88cdeaf24..6110920b3760e 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
@@ -255,7 +255,8 @@ bool LoongArchAsmBackend::relaxAlign(MCFragment &F, unsigned &Size) {
MCFixup::create(0, Expr, FirstLiteralRelocationKind + ELF::R_LARCH_ALIGN);
F.setVarFixups({Fixup});
F.setLinkerRelaxable();
- F.getParent()->setLinkerRelaxable();
+ if (!F.getParent()->isLinkerRelaxable())
+ F.getParent()->setFirstLinkerRelaxable(F.getLayoutOrder());
return true;
}
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index 82e3b5ceb4ef6..2d9ffc69ccc2f 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -306,11 +306,19 @@ void RISCVAsmBackend::relaxInstruction(MCInst &Inst,
// If conditions are met, compute the padding size and create a fixup encoding
// the padding size in the addend.
bool RISCVAsmBackend::relaxAlign(MCFragment &F, unsigned &Size) {
- // Use default handling unless linker relaxation is enabled and the alignment
- // is larger than the nop size.
- const MCSubtargetInfo *STI = F.getSubtargetInfo();
- if (!STI->hasFeature(RISCV::FeatureRelax))
+ // Alignments before the first linker-relaxable instruction have fixed sizes
+ // and do not require relocations. Alignments following a linker-relaxable
+ // instruction require a relocation, even if the STI specifies norelax.
+ //
+ // firstLinkerRelaxable represents the layout order within the subsection,
+ // which may be smaller than the section's order. Therefore, alignments in
+ // an earlier subsection may be unnecessarily treated as linker-relaxable.
+ auto *Sec = F.getParent();
+ if (F.getLayoutOrder() <= Sec->firstLinkerRelaxable())
return false;
+
+ // Use default handling unless the alignment is larger than the nop size.
+ const MCSubtargetInfo *STI = F.getSubtargetInfo();
unsigned MinNopLen = STI->hasFeature(RISCV::FeatureStdExtZca) ? 2 : 4;
if (F.getAlignment() <= MinNopLen)
return false;
@@ -321,7 +329,8 @@ bool RISCVAsmBackend::relaxAlign(MCFragment &F, unsigned &Size) {
MCFixup::create(0, Expr, FirstLiteralRelocationKind + ELF::R_RISCV_ALIGN);
F.setVarFixups({Fixup});
F.setLinkerRelaxable();
- F.getParent()->setLinkerRelaxable();
+ if (!Sec->isLinkerRelaxable())
+ Sec->setFirstLinkerRelaxable(F.getLayoutOrder());
return true;
}
diff --git a/llvm/test/MC/RISCV/Relocations/align-after-relax.s b/llvm/test/MC/RISCV/Relocations/align-after-relax.s
new file mode 100644
index 0000000000000..cb22e0245e286
--- /dev/null
+++ b/llvm/test/MC/RISCV/Relocations/align-after-relax.s
@@ -0,0 +1,50 @@
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+c,+relax %s --defsym LATE=1 -o %t1
+# RUN: llvm-objdump -dr --no-show-raw-insn -M no-aliases %t1 | FileCheck %s
+
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+c,+relax %s -o %t0
+# RUN: llvm-objdump -dr --no-show-raw-insn -M no-aliases %t0 | FileCheck %s --check-prefix=CHECK0
+
+# CHECK: 6: c.nop
+# CHECK-EMPTY:
+# CHECK: 10: auipc ra, 0x0
+# CHECK-NEXT: R_RISCV_CALL_PLT foo
+# CHECK-NEXT: R_RISCV_RELAX *ABS*
+# CHECK: 20: c.nop
+# CHECK-NEXT: R_RISCV_ALIGN *ABS*+0x6
+
+## Alignment directives in a smaller-number subsection might be conservatively treated as linker-relaxable.
+# CHECK0: 6: c.nop
+# CHECK0-NEXT: R_RISCV_ALIGN *ABS*+0x6
+# CHECK0: 20: c.nop
+# CHECK0-NEXT: R_RISCV_ALIGN *ABS*+0x6
+
+.text 2
+.option push
+.option norelax
+## R_RISCV_ALIGN is required even if norelax, because there is a preceding linker-relaxable instruction.
+.balign 8
+l2:
+ .word 0x12345678
+.option pop
+
+.text 1
+ .space 4
+.ifdef LATE
+ .space 0
+.endif
+ call foo
+.ifdef LATE
+ .space 8
+.else
+ .space 4
+.endif
+
+.text 0
+_start:
+ .space 6
+.option push
+.option norelax
+.balign 8
+l0:
+ .word 0x12345678
+.option pop
diff --git a/llvm/test/MC/RISCV/align-option-relax.s b/llvm/test/MC/RISCV/align-option-relax.s
index 890e1e72d7706..60cd55f5a8b4d 100644
--- a/llvm/test/MC/RISCV/align-option-relax.s
+++ b/llvm/test/MC/RISCV/align-option-relax.s
@@ -1,8 +1,21 @@
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=-relax < %s \
# RUN: | llvm-readobj -r - | FileCheck %s
-# Check that .option relax overrides -mno-relax and enables R_RISCV_ALIGN
-# relocations.
-# CHECK: R_RISCV_ALIGN
- .option relax
- .align 4
+## .option relax overrides -mno-relax and enables R_RISCV_ALIGN/R_RISCV_RELAX relocations.
+# CHECK: .rela.text
+# CHECK: R_RISCV_CALL_PLT
+# CHECK-NEXT: R_RISCV_RELAX
+# CHECK-NEXT: R_RISCV_ALIGN
+.option relax
+call foo
+.align 4
+
+## Alignments before the first linker-relaxable instruction do not need relocations.
+# CHECK-NOT: .rela.text1
+.section .text1,"ax"
+.align 4
+nop
+
+# CHECK: .rela.text2
+.section .text2,"ax"
+call foo
diff --git a/llvm/test/MC/RISCV/align.s b/llvm/test/MC/RISCV/align.s
index da3b1aa9b637a..ab317f079dbcd 100644
--- a/llvm/test/MC/RISCV/align.s
+++ b/llvm/test/MC/RISCV/align.s
@@ -46,16 +46,17 @@
# type for .align N directive when linker relaxation enabled.
# Linker could satisfy alignment by removing NOPs after linker relaxation.
-# The first R_RISCV_ALIGN come from
-# MCELFStreamer::InitSections() emitCodeAlignment(getTextSectionAligntment()).
-# C-OR-ZCA-EXT-RELAX-RELOC: R_RISCV_ALIGN - 0x2
-# C-OR-ZCA-EXT-RELAX-INST: c.nop
test:
+## Start with a linker-relaxable instruction so that the following alignment can be relaxable.
+ call foo
+# NORELAX-RELOC: R_RISCV_CALL_PLT
+# C-OR-ZCA-EXT-NORELAX-RELOC: R_RISCV_CALL_PLT
+
.p2align 2
# If the +c extension is enabled, the text section will be 2-byte aligned, so
# one c.nop instruction is sufficient.
-# C-OR-ZCA-EXT-RELAX-RELOC-NOT: R_RISCV_ALIGN - 0x2
-# C-OR-ZCA-EXT-RELAX-INST-NOT: c.nop
+# C-OR-ZCA-EXT-RELAX-RELOC: R_RISCV_ALIGN - 0x2
+# C-OR-ZCA-EXT-RELAX-INST: c.nop
bne zero, a0, .LBB0_2
mv a0, zero
.p2align 3
@@ -136,16 +137,8 @@ data2:
add a0, a0, a1
## Branches crossing the linker-relaxable R_RISCV_ALIGN need relocations.
-# RELAX-RELOC: .rela.text3 {
-# RELAX-RELOC-NEXT: 0x4 R_RISCV_BRANCH .Ltmp[[#]] 0x0
-# RELAX-RELOC-NEXT: 0x8 R_RISCV_ALIGN - 0x4
-# RELAX-RELOC-NEXT: 0xC R_RISCV_BRANCH .Ltmp[[#]] 0x0
-# RELAX-RELOC-NEXT: }
-# C-OR-ZCA-EXT-RELAX-RELOC: .rela.text3 {
-# C-OR-ZCA-EXT-RELAX-RELOC-NEXT: 0x4 R_RISCV_BRANCH .Ltmp[[#]] 0x0
-# C-OR-ZCA-EXT-RELAX-RELOC-NEXT: 0x8 R_RISCV_ALIGN - 0x4
-# C-OR-ZCA-EXT-RELAX-RELOC-NEXT: 0xC R_RISCV_BRANCH .Ltmp[[#]] 0x0
-# C-OR-ZCA-EXT-RELAX-RELOC-NEXT: }
+# RELAX-RELOC-NOT: .rela.text3 {
+# C-OR-ZCA-EXT-RELAX-RELOC-NOT: .rela.text3 {
.section .text3, "ax"
bnez t1, 1f
bnez t2, 2f
@@ -157,7 +150,6 @@ data2:
## .text3 with a call at the start
# NORELAX-RELOC: .rela.text3a
-# C-OR-ZCA-EXT-NORELAX-RELOC: .rela.text3a
# RELAX-RELOC: .rela.text3a {
# RELAX-RELOC-NEXT: 0x0 R_RISCV_CALL_PLT foo 0x0
# RELAX-RELOC-NEXT: 0x0 R_RISCV_RELAX - 0x0
@@ -165,6 +157,8 @@ data2:
# RELAX-RELOC-NEXT: 0x10 R_RISCV_ALIGN - 0x4
# RELAX-RELOC-NEXT: 0x14 R_RISCV_BRANCH .Ltmp[[#]] 0x0
# RELAX-RELOC-NEXT: }
+# C-OR-ZCA-EXT-NORELAX-RELOC: .rela.text3a
+# C-OR-ZCA-EXT-RELAX-RELOC: .rela.text3a
.section .text3a, "ax"
call foo
bnez t1, 1f
@@ -177,11 +171,8 @@ bnez t1, 2b
## .text3 with a call at the end
# RELAX-RELOC: .rela.text3b {
-# RELAX-RELOC-NEXT: 0x4 R_RISCV_BRANCH .Ltmp[[#]] 0x0
-# RELAX-RELOC-NEXT: 0x8 R_RISCV_ALIGN - 0x4
-# RELAX-RELOC-NEXT: 0xC R_RISCV_BRANCH .Ltmp[[#]] 0x0
-# RELAX-RELOC-NEXT: 0x14 R_RISCV_CALL_PLT foo 0x0
-# RELAX-RELOC-NEXT: 0x14 R_RISCV_RELAX - 0x0
+# RELAX-RELOC-NEXT: 0x10 R_RISCV_CALL_PLT foo 0x0
+# RELAX-RELOC-NEXT: 0x10 R_RISCV_RELAX - 0x0
# RELAX-RELOC-NEXT: }
.section .text3b, "ax"
bnez t1, 1f
diff --git a/llvm/test/MC/RISCV/cfi-advance.s b/llvm/test/MC/RISCV/cfi-advance.s
index f3f8530c419f0..bad2ef07235e5 100644
--- a/llvm/test/MC/RISCV/cfi-advance.s
+++ b/llvm/test/MC/RISCV/cfi-advance.s
@@ -7,7 +7,7 @@
# NORELAX: Relocation section '.rela.text1' at offset {{.*}} contains 1 entries:
# NORELAX-NEXT: Offset Info Type Sym. Value Symbol's Name + Addend
-# NORELAX-NEXT: 00000000 00000313 R_RISCV_CALL_PLT 00000004 .L0 + 0
+# NORELAX-NEXT: 00000000 00000313 R_RISCV_CALL_PLT 00000008 .L0 + 0
# NORELAX-EMPTY:
# RELAX: Relocation section '.rela.text1' at offset {{.*}} contains 2 entries:
# RELAX: R_RISCV_CALL_PLT
@@ -16,23 +16,25 @@
# NORELAX-NEXT: Relocation section '.rela.eh_frame' at offset {{.*}} contains 1 entries:
# NORELAX: Offset Info Type Sym. Value Symbol's Name + Addend
# NORELAX-NEXT: 0000001c 00000139 R_RISCV_32_PCREL 00000000 .L0 + 0
-# RELAX-NEXT: Relocation section '.rela.eh_frame' at offset {{.*}} contains 5 entries:
+# RELAX-NEXT: Relocation section '.rela.eh_frame' at offset {{.*}} contains 7 entries:
# RELAX: Offset Info Type Sym. Value Symbol's Name + Addend
# RELAX-NEXT: 0000001c 00000139 R_RISCV_32_PCREL 00000000 .L0 + 0
-# RELAX-NEXT: 00000020 00000c23 R_RISCV_ADD32 0001017a .L0 + 0
+# RELAX-NEXT: 00000020 00000d23 R_RISCV_ADD32 0001017a .L0 + 0
# RELAX-NEXT: 00000020 00000127 R_RISCV_SUB32 00000000 .L0 + 0
-# RELAX-NEXT: 00000035 00000b35 R_RISCV_SET6 00010176 .L0 + 0
-# RELAX-NEXT: 00000035 00000934 R_RISCV_SUB6 0001016e .L0 + 0
+# RELAX-NEXT: 00000026 00000536 R_RISCV_SET8 00000068 .L0 + 0
+# RELAX-NEXT: 00000026 00000125 R_RISCV_SUB8 00000000 .L0 + 0
+# RELAX-NEXT: 00000035 00000c35 R_RISCV_SET6 00010176 .L0 + 0
+# RELAX-NEXT: 00000035 00000a34 R_RISCV_SUB6 0001016e .L0 + 0
# CHECK-EMPTY:
-# NORELAX: Symbol table '.symtab' contains 13 entries:
-# RELAX: Symbol table '.symtab' contains 16 entries:
+# NORELAX: Symbol table '.symtab' contains 14 entries:
+# RELAX: Symbol table '.symtab' contains 18 entries:
# RELAX-NEXT: Num: Value Size Type Bind Vis Ndx Name
# RELAX-NEXT: 0: 00000000 0 NOTYPE LOCAL DEFAULT UND
# RELAX-NEXT: 1: 00000000 0 NOTYPE LOCAL DEFAULT 2 .L0 {{$}}
-# RELAX: 3: 00000004 0 NOTYPE LOCAL DEFAULT 2 .L0{{$}}
-# RELAX: 9: 0001016e 0 NOTYPE LOCAL DEFAULT 2 .L0 {{$}}
-# RELAX: 11: 00010176 0 NOTYPE LOCAL DEFAULT 2 .L0 {{$}}
-# RELAX: 12: 0001017a 0 NOTYPE LOCAL DEFAULT 2 .L0 {{$}}
+# RELAX: 3: 00000008 0 NOTYPE LOCAL DEFAULT 2 .L0{{$}}
+# RELAX: 10: 0001016e 0 NOTYPE LOCAL DEFAULT 2 .L0 {{$}}
+# RELAX: 12: 00010176 0 NOTYPE LOCAL DEFAULT 2 .L0 {{$}}
+# RELAX: 13: 0001017a 0 NOTYPE LOCAL DEFAULT 2 .L0 {{$}}
# CHECK-DWARFDUMP: DW_CFA_advance_loc1: 104
# CHECK-DWARFDUMP-NEXT: DW_CFA_def_cfa_offset: +8
@@ -48,11 +50,11 @@
.type test,@function
test:
.cfi_startproc
- nop
+ call foo
## This looks similar to fake label names ".L0 ". Even if this is ".L0 ",
## the assembler will not conflate it with fake labels.
.L0:
- .zero 100, 0x90
+ .zero 96, 0x90
.cfi_def_cfa_offset 8
nop
.zero 255, 0x90
diff --git a/llvm/test/MC/RISCV/nop-slide.s b/llvm/test/MC/RISCV/nop-slide.s
index 4dc888b3ba777..9ce2e59f31b08 100644
--- a/llvm/test/MC/RISCV/nop-slide.s
+++ b/llvm/test/MC/RISCV/nop-slide.s
@@ -1,5 +1,5 @@
-# RUN: llvm-mc -triple riscv64 -mattr +c,-relax -filetype obj -o - %s | llvm-objdump -d - | FileCheck %s -check-prefix CHECK-RVC-NORELAX
-# RUN: llvm-mc -triple riscv64 -mattr +c,+relax -filetype obj -o - %s | llvm-objdump -d - | FileCheck %s -check-prefix CHECK-RVC-RELAX
+# RUN: llvm-mc -triple riscv64 -mattr +c,-relax -filetype obj -o - %s | llvm-objdump -d - | FileCheck %s -check-prefix CHECK-RVC
+# RUN: llvm-mc -triple riscv64 -mattr +c,+relax -filetype obj -o - %s | llvm-objdump -d - | FileCheck %s -check-prefix CHECK-RVC
# RUN: llvm-mc -triple riscv64 -mattr -c,-relax -filetype obj -o - %s | llvm-objdump -d - | FileCheck %s
# RUN: llvm-mc -triple riscv64 -mattr -c,+relax -filetype obj -o - %s | llvm-objdump -d - | FileCheck %s
@@ -9,17 +9,10 @@
.balign 4
auipc a0, 0
-# CHECK-RVC-NORELAX: 0000000000000000 <.text>:
-# CHECK-RVC-NORELAX-NEXT: 0: 0000 unimp
-# CHECK-RVC-NORELAX-NEXT: 2: 0001 nop
-# CHECK-RVC-NORELAX-NEXT: 4: 00000517 auipc a0, 0x0
-
-# CHECK-RVC-RELAX: 0000000000000000 <.text>:
-# CHECK-RVC-RELAX-NEXT: 0: 0001 nop
-# CHECK-RVC-RELAX-NEXT: 2: 0100 addi s0, sp, 0x80
-# CHECK-RVC-RELAX-NEXT: 4: 1700 addi s0, sp, 0x3a0
-# CHECK-RVC-RELAX-NEXT: 6: 0005 c.nop 0x1
-# CHECK-RVC-RELAX-NEXT: 8: 00 <unknown>
+# CHECK-RVC: 0000000000000000 <.text>:
+# CHECK-RVC-NEXT: 0: 0000 unimp
+# CHECK-RVC-NEXT: 2: 0001 nop
+# CHECK-RVC-NEXT: 4: 00000517 auipc a0, 0x0
# CHECK: 0000000000000000 <.text>:
# CHECK-NEXT: 0: 0000 <unknown>
|
@@ -255,7 +255,8 @@ bool LoongArchAsmBackend::relaxAlign(MCFragment &F, unsigned &Size) { | |||
MCFixup::create(0, Expr, FirstLiteralRelocationKind + ELF::R_LARCH_ALIGN); | |||
F.setVarFixups({Fixup}); | |||
F.setLinkerRelaxable(); | |||
F.getParent()->setLinkerRelaxable(); | |||
if (!F.getParent()->isLinkerRelaxable()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: I made minimum changes to keep LoongArch tests passing but I do not intend to apply the ALIGN optimization (first behavior in the description).
Up to a LoongArch contributor to replace if (!F.getSubtargetInfo()->hasFeature(LoongArch::FeatureRelax))
with
if (F.getLayoutOrder() <= Sec->firstLinkerRelaxable())
and a few tests @SixWeining @MQ-mengqing
Note: The RISC-V alignment tests are poorly organized, so please avoid following their example. You can create a more effective structure within the LoongArch/Relocations directory.
Thanks for the optimization (To be precise, it's about fixing). But this seems to only address issues within the same object file. How about different object files merged by the linker with the |
Share you my test scripts, it seems still some corner case isn't handled well. The test script will show all step and why it fail :) Setup $ git clone git@github.com:kito-cheng/riscv-alignment-check.git
$ cd riscv-alignment-check
$ wget https://github.com/riscv-collab/riscv-gnu-toolchain/releases/download/2025.07.16/riscv64-glibc-ubuntu-22.04-gcc-nightly-2025.07.16-nightly.tar.xz
$ tar -xf riscv64-glibc-ubuntu-22.04-gcc-nightly-2025.07.16-nightly.tar.xz How to run: ./test_runner.py --toolchain-base `pwd`/riscv/bin --clang --clang-path <path-to-clang> | tee log Result for this PR:
|
@SixWeining reminded me that we have a large problem when mixing -mrelax and -mno-relax object files in relocatable links (-r). cat > x0.s <<e
.globl _start
_start:
call foo
e
cat > x1.s <<e
.option push
.option norelax
.balign 8
l2:
.word 0x12345678
.option pop
.section .text1,"ax"
.globl foo
foo:
e
clang --target=riscv64 -mrelax -c x0.s x1.s
ld.lld -r x0.o x1.o -o x01.o
ld.lld x01.o -o x01 |
I think "make linker synthesize ALIGN relocations at input section starts" would be my preference, otherwise |
Agreed. I have made a draft to synthesize ALIGN relocations at section start: MaskRay#5 Created https://sourceware.org/bugzilla/show_bug.cgi?id=33236 ("ld riscv: Relocatable linking challenge with R_RISCV_ALIGN") |
Is this repo public?
|
@MaskRay I thought I made it public before...anyway I change the visibility now |
Each section now tracks the index of the first linker-relaxable
fragment, enabling two changes:
instruction in a section. The primary example is the offset 0
R_RISCV_ALIGN relocation for a text section aligned by 4.
linker-relaxable instruction, ALIGN relocations are now generated, even in
norelax regions. This fixes the issue [RISCV] Fix alignment when mixing rvc/norvc relax/norelax code #150159.
The new test llvm/test/MC/RISCV/Relocations/align-after-relax.s
verifies the required ALIGN in a norelax region following
linker-relaxable instructions.
By using a fragment index within the subsection (which is less than or
equal to the section's index), the implementation may generate redundant
ALIGN relocations in lower-numbered subsections before the first
linker-relaxable instruction.
align-option-relax.s demonstrates the ALIGN optimization.
Add an initial
call
to a few tests to prevent the ALIGN optimization.