[llvm] 1582bcd - RISCV: handle 64-bit PCREL data relocations

Saleem Abdulrasool via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 14 14:39:47 PDT 2022


Author: Saleem Abdulrasool
Date: 2022-06-14T21:39:16Z
New Revision: 1582bcd0038dbf0b82f11f105ded0b223a40fcec

URL: https://github.com/llvm/llvm-project/commit/1582bcd0038dbf0b82f11f105ded0b223a40fcec
DIFF: https://github.com/llvm/llvm-project/commit/1582bcd0038dbf0b82f11f105ded0b223a40fcec.diff

LOG: RISCV: handle 64-bit PCREL data relocations

We would previously fail to handle 64-bit PC-relative relocations on
RISCV.  This was exposed by trying to build with
`-fprofile-instr-generate`.

The original changes restricted the relocation handling to the text
segment as the paired relocations are undesirable in at least the debug
and .eh_frame sections.  We now make this explicit to handle the general
case for the data relocations as well.

It would be preferable to use `R_RISCV_n_PCREL` when available to avoid
an extra relocation.

Differential Revision: https://reviews.llvm.org/D127549
Reviewed By: luismarques, MaskRay

Fixes: #55971

Added: 
    llvm/test/MC/RISCV/riscv64-64b-pcrel.s

Modified: 
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
index 7d478a21913cd..294e69f89fe6f 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
@@ -207,6 +207,10 @@ class RISCVELFStreamer : public MCELFStreamer {
 
   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<MCBinaryExpr>(Value);
     if (MBE == nullptr)
       return false;
@@ -225,10 +229,15 @@ class RISCVELFStreamer : public MCELFStreamer {
                              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 
diff erence 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
index 0000000000000..f2b84b17ede7f
--- /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", at progbits
+x:
+	.quad y-x
+
+	.section	sy,"aw", at progbits
+y:
+	.quad x-y
+
+	.section	sz
+z:
+	.quad z-a
+
+	.section	sa
+a:
+	.quad a-z


        


More information about the llvm-commits mailing list