diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp @@ -207,6 +207,10 @@ static bool requiresFixups(MCContext &C, const MCExpr *Value, const MCExpr *&LHS, const MCExpr *&RHS) { + auto IsMetadataOrEHFrameSection = [](const MCSection &S) -> bool { + return S.getKind().isMetadata() || S.getName() == ".eh_frame"; + }; + const auto *MBE = dyn_cast(Value); if (MBE == nullptr) return false; @@ -225,10 +229,15 @@ MCConstantExpr::create(E.getConstant(), C), C); RHS = E.getSymB(); - return (A.isInSection() ? A.getSection().hasInstructions() - : !A.getName().empty()) || - (B.isInSection() ? B.getSection().hasInstructions() - : !B.getName().empty()); + // TODO: when available, R_RISCV_n_PCREL should be preferred. + + // Avoid pairwise relocations for symbolic difference in debug and .eh_frame + if (A.isInSection()) + return !IsMetadataOrEHFrameSection(A.getSection()); + if (B.isInSection()) + return !IsMetadataOrEHFrameSection(B.getSection()); + // as well as for absolute symbols. + return !A.getName().empty() || !B.getName().empty(); } void reset() override { diff --git a/llvm/test/MC/RISCV/riscv64-64b-pcrel.s b/llvm/test/MC/RISCV/riscv64-64b-pcrel.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/riscv64-64b-pcrel.s @@ -0,0 +1,37 @@ +# RUN: llvm-mc -triple riscv64-unknown-linux-gnu -filetype obj -o - %s \ +# RUN: | llvm-readobj -r - | FileCheck %s + +# CHECK: Relocations [ +# CHECK: .relasx { +# CHECK-NEXT: 0x0 R_RISCV_ADD64 y 0x0 +# CHECK-NEXT: 0x0 R_RISCV_SUB64 x 0x0 +# CHECK: } +# CHECK: .relasy { +# CHECK-NEXT: 0x0 R_RISCV_ADD64 x 0x0 +# CHECK-NEXT: 0x0 R_RISCV_SUB64 y 0x0 +# CHECK: } +# CHECK: .relasz { +# CHECK-NEXT: 0x0 R_RISCV_ADD64 z 0x0 +# CHECK-NEXT: 0x0 R_RISCV_SUB64 a 0x0 +# CHECK: } +# CHECK: .relasa { +# CHECK-NEXT: 0x0 R_RISCV_ADD64 a 0x0 +# CHECK-NEXT: 0x0 R_RISCV_SUB64 z 0x0 +# CHECK: } +# CHECK: ] + + .section sx,"aw",@progbits +x: + .quad y-x + + .section sy,"aw",@progbits +y: + .quad x-y + + .section sz +z: + .quad z-a + + .section sa +a: + .quad a-z