[llvm] ffa829c - [RISCV] Allow delayed decision for ADD/SUB relocations

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 21 08:38:03 PDT 2023


Author: Fangrui Song
Date: 2023-07-21T08:37:58-07:00
New Revision: ffa829c4c5d1cda6b5df3f70cec82888bfc39af9

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

LOG: [RISCV] Allow delayed decision for ADD/SUB relocations

For a label difference `A-B` in assembly, if A and B are separated by a
linker-relaxable instruction, we should emit a pair of ADD/SUB
relocations (e.g. R_RISCV_ADD32/R_RISCV_SUB32,
R_RISCV_ADD64/R_RISCV_SUB64).

However, the decision is made upfront at parsing time with inadequate
heuristics (`requiresFixup`). As a result, LLVM integrated assembler
incorrectly suppresses R_RISCV_ADD32/R_RISCV_SUB32 for the following
code:
```
// Simplified from a workaround https://android-review.googlesource.com/c/platform/art/+/2619609
// Both end and begin are not defined yet. We decide ADD/SUB relocations upfront and don't know they will be needed.
.4byte end-begin

begin:
  call foo
end:
```

To fix the bug, make two primary changes:

* Delete `requiresFixups` and the overridden emitValueImpl (from D103539).
  This deletion requires accurate evaluateAsAbolute (D153097).
* In MCAssembler::evaluateFixup, call handleAddSubRelocations to emit
  ADD/SUB relocations.

However, there is a remaining issue in
MCExpr.cpp:AttemptToFoldSymbolOffsetDifference. With MCAsmLayout, we may
incorrectly fold A-B even when A and B are separated by a
linker-relaxable instruction. This deficiency is acknowledged (see
D153097), but was previously bypassed by eagerly emitting ADD/SUB using
`requiresFixups`. To address this, we partially reintroduce `canFold` (from
D61584, removed by D103539).

Some expressions (e.g. .size and .fill) need to take the `MCAsmLayout`
code path in AttemptToFoldSymbolOffsetDifference, avoiding relocations
(weird, but matching GNU assembler and needed to match user
expectation). Switch to evaluateKnownAbsolute to leverage the `InSet`
condition.

As a bonus, this change allows for the removal of some relocations for
the FDE `address_range` field in the .eh_frame section.

riscv64-64b-pcrel.s contains the main test.
Add a linker relaxable instruction to dwarf-riscv-relocs.ll to test what
it intends to test.
Merge fixups-relax-diff.ll into fixups-diff.ll.

Reviewed By: kito-cheng

Differential Revision: https://reviews.llvm.org/D155357

Added: 
    

Modified: 
    llvm/include/llvm/MC/MCAsmBackend.h
    llvm/lib/MC/MCAssembler.cpp
    llvm/lib/MC/MCExpr.cpp
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h
    llvm/test/CodeGen/RISCV/fixups-diff.ll
    llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll
    llvm/test/DebugInfo/RISCV/relax-debug-frame.ll
    llvm/test/ExecutionEngine/JITLink/RISCV/anonymous_symbol.s
    llvm/test/MC/ELF/RISCV/gen-dwarf.s
    llvm/test/MC/RISCV/cfi-advance.s
    llvm/test/MC/RISCV/fde-reloc.s
    llvm/test/MC/RISCV/fixups-expr.s
    llvm/test/MC/RISCV/riscv64-64b-pcrel.s

Removed: 
    llvm/test/CodeGen/RISCV/fixups-relax-diff.ll


################################################################################
diff  --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h
index 11bb612c4f30e3..5e08fb41679ba9 100644
--- a/llvm/include/llvm/MC/MCAsmBackend.h
+++ b/llvm/include/llvm/MC/MCAsmBackend.h
@@ -129,6 +129,14 @@ class MCAsmBackend {
     llvm_unreachable("Need to implement hook if target has custom fixups");
   }
 
+  virtual bool handleAddSubRelocations(const MCAsmLayout &Layout,
+                                       const MCFragment &F,
+                                       const MCFixup &Fixup,
+                                       const MCValue &Target,
+                                       uint64_t &FixedValue) const {
+    return false;
+  }
+
   /// Apply the \p Value for given \p Fixup into the provided data fragment, at
   /// the offset specified by the fixup and following the fixup kind as
   /// appropriate. Errors (such as an out of range fixup value) should be

diff  --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index 24172a4575299a..55ed1a285cd735 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -287,6 +287,13 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout,
     WasForced = true;
   }
 
+  // A linker relaxation target may emit ADD/SUB relocations for A-B+C. Let
+  // recordRelocation handle non-VK_None cases like A at plt-B+C.
+  if (!IsResolved && Target.getSymA() && Target.getSymB() &&
+      Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None &&
+      getBackend().handleAddSubRelocations(Layout, *DF, Fixup, Target, Value))
+    return true;
+
   return IsResolved;
 }
 
@@ -303,7 +310,7 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
   case MCFragment::FT_Fill: {
     auto &FF = cast<MCFillFragment>(F);
     int64_t NumValues = 0;
-    if (!FF.getNumValues().evaluateAsAbsolute(NumValues, Layout)) {
+    if (!FF.getNumValues().evaluateKnownAbsolute(NumValues, Layout)) {
       getContext().reportError(FF.getLoc(),
                                "expected assembly-time absolute expression");
       return 0;

diff  --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp
index f2caadd7fbcf98..a7b980553af055 100644
--- a/llvm/lib/MC/MCExpr.cpp
+++ b/llvm/lib/MC/MCExpr.cpp
@@ -628,7 +628,14 @@ static void AttemptToFoldSymbolOffsetDifference(
   if ((&SecA != &SecB) && !Addrs)
     return;
 
-  if (Layout) {
+  // When layout is available, we can generally compute the 
diff erence using the
+  // getSymbolOffset path, which also avoids the possible slow fragment walk.
+  // However, linker relaxation may cause incorrect fold of A-B if A and B are
+  // separated by a linker-relaxable instruction. If the section contains
+  // instructions and InSet is false (not expressions in directive like
+  // .size/.fill), disable the fast path.
+  if (Layout && (InSet || !SecA.hasInstructions() ||
+                 !Asm->getContext().getTargetTriple().isRISCV())) {
     // If both symbols are in the same fragment, return the 
diff erence of their
     // offsets. canGetFragmentOffset(FA) may be false.
     if (FA == FB && !SA.isVariable() && !SB.isVariable()) {

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index 81542b2697d5fe..1b890fbe041a7e 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -281,7 +281,7 @@ bool RISCVAsmBackend::relaxDwarfCFA(MCDwarfCallFrameFragment &DF,
   int64_t Value;
   if (AddrDelta.evaluateAsAbsolute(Value, Layout.getAssembler()))
     return false;
-  bool IsAbsolute = AddrDelta.evaluateAsAbsolute(Value, Layout);
+  bool IsAbsolute = AddrDelta.evaluateKnownAbsolute(Value, Layout);
   assert(IsAbsolute && "CFA with invalid expression");
   (void)IsAbsolute;
 
@@ -572,6 +572,48 @@ bool RISCVAsmBackend::evaluateTargetFixup(
   return true;
 }
 
+bool RISCVAsmBackend::handleAddSubRelocations(const MCAsmLayout &Layout,
+                                              const MCFragment &F,
+                                              const MCFixup &Fixup,
+                                              const MCValue &Target,
+                                              uint64_t &FixedValue) const {
+  uint64_t FixedValueA, FixedValueB;
+  unsigned TA = 0, TB = 0;
+  switch (Fixup.getKind()) {
+  case llvm::FK_Data_1:
+    TA = ELF::R_RISCV_ADD8;
+    TB = ELF::R_RISCV_SUB8;
+    break;
+  case llvm::FK_Data_2:
+    TA = ELF::R_RISCV_ADD16;
+    TB = ELF::R_RISCV_SUB16;
+    break;
+  case llvm::FK_Data_4:
+    TA = ELF::R_RISCV_ADD32;
+    TB = ELF::R_RISCV_SUB32;
+    break;
+  case llvm::FK_Data_8:
+    TA = ELF::R_RISCV_ADD64;
+    TB = ELF::R_RISCV_SUB64;
+    break;
+  default:
+    llvm_unreachable("unsupported fixup size");
+  }
+  MCValue A = MCValue::get(Target.getSymA(), nullptr, Target.getConstant());
+  MCValue B = MCValue::get(Target.getSymB());
+  auto FA = MCFixup::create(
+      Fixup.getOffset(), nullptr,
+      static_cast<MCFixupKind>(FirstLiteralRelocationKind + TA));
+  auto FB = MCFixup::create(
+      Fixup.getOffset(), nullptr,
+      static_cast<MCFixupKind>(FirstLiteralRelocationKind + TB));
+  auto &Asm = Layout.getAssembler();
+  Asm.getWriter().recordRelocation(Asm, Layout, &F, FA, A, FixedValueA);
+  Asm.getWriter().recordRelocation(Asm, Layout, &F, FB, B, FixedValueB);
+  FixedValue = FixedValueA - FixedValueB;
+  return true;
+}
+
 void RISCVAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                                  const MCValue &Target,
                                  MutableArrayRef<char> Data, uint64_t Value,

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
index 7fff5e1060c706..0ea1f32e829631 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
@@ -53,6 +53,10 @@ class RISCVAsmBackend : public MCAsmBackend {
                            const MCValue &Target, uint64_t &Value,
                            bool &WasForced) override;
 
+  bool handleAddSubRelocations(const MCAsmLayout &Layout, const MCFragment &F,
+                               const MCFixup &Fixup, const MCValue &Target,
+                               uint64_t &FixedValue) const override;
+
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                   const MCValue &Target, MutableArrayRef<char> Data,
                   uint64_t Value, bool IsResolved,

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
index 3ec6e2afa23628..e43cb8b40d8377 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
@@ -122,84 +122,11 @@ void RISCVTargetELFStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) {
   cast<MCSymbolELF>(Symbol).setOther(ELF::STO_RISCV_VARIANT_CC);
 }
 
-bool RISCVELFStreamer::requiresFixups(MCContext &C, const MCExpr *Value,
-                                      const MCExpr *&LHS, const MCExpr *&RHS) {
-  const auto *MBE = dyn_cast<MCBinaryExpr>(Value);
-  if (MBE == nullptr)
-    return false;
-
-  MCValue E;
-  if (!Value->evaluateAsRelocatable(E, nullptr, nullptr))
-    return false;
-  if (E.getSymA() == nullptr || E.getSymB() == nullptr)
-    return false;
-
-  const auto &A = E.getSymA()->getSymbol();
-  const auto &B = E.getSymB()->getSymbol();
-
-  LHS = MCBinaryExpr::create(MCBinaryExpr::Add, MCSymbolRefExpr::create(&A, C),
-                             MCConstantExpr::create(E.getConstant(), C), C);
-  RHS = E.getSymB();
-
-  // Avoid ADD/SUB if Kind is not VK_None, e.g. A at plt - B + C.
-  if (E.getSymA()->getKind() != MCSymbolRefExpr::VK_None)
-    return false;
-
-  // If either symbol is in a text section, we need to delay the relocation
-  // evaluation as relaxation may alter the size of the symbol.
-  //
-  // Unfortunately, we cannot identify if the symbol was built with relaxation
-  // as we do not track the state per symbol or section.  However, BFD will
-  // always emit the relocation and so we follow suit which avoids the need to
-  // track that information.
-  if (A.isInSection() && A.getSection().getKind().isText())
-    return true;
-  if (B.isInSection() && B.getSection().getKind().isText())
-    return true;
-
-  // If A is undefined and B is defined, we should emit ADD/SUB for A-B.
-  // Unfortunately, A may be defined later, but this requiresFixups call has to
-  // eagerly make a decision. For now, emit ADD/SUB unless A is .L*. This
-  // heuristic handles many temporary label 
diff erences for .debug_* and
-  // .apple_types sections.
-  //
-  // TODO Implement delayed relocation decision.
-  if (!A.isInSection() && !A.isTemporary() && B.isInSection())
-    return true;
-
-  // Support cross-section symbolic 
diff erences ...
-  return A.isInSection() && B.isInSection() &&
-         A.getSection().getName() != B.getSection().getName();
-}
-
 void RISCVELFStreamer::reset() {
   static_cast<RISCVTargetStreamer *>(getTargetStreamer())->reset();
   MCELFStreamer::reset();
 }
 
-void RISCVELFStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
-                                     SMLoc Loc) {
-  const MCExpr *A, *B;
-  if (!requiresFixups(getContext(), Value, A, B))
-    return MCELFStreamer::emitValueImpl(Value, Size, Loc);
-
-  MCStreamer::emitValueImpl(Value, Size, Loc);
-
-  MCDataFragment *DF = getOrCreateDataFragment();
-  flushPendingLabels(DF, DF->getContents().size());
-  MCDwarfLineEntry::make(this, getCurrentSectionOnly());
-
-  MCFixupKind Add, Sub;
-  std::tie(Add, Sub) = RISCV::getRelocPairForSize(Size);
-
-  DF->getFixups().push_back(
-      MCFixup::create(DF->getContents().size(), A, Add, Loc));
-  DF->getFixups().push_back(
-      MCFixup::create(DF->getContents().size(), B, Sub, Loc));
-
-  DF->getContents().resize(DF->getContents().size() + Size, 0);
-}
-
 namespace llvm {
 MCELFStreamer *createRISCVELFStreamer(MCContext &C,
                                       std::unique_ptr<MCAsmBackend> MAB,

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h
index 3cdb04f9a215d3..e68f70261146f7 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h
@@ -15,8 +15,6 @@
 using namespace llvm;
 
 class RISCVELFStreamer : public MCELFStreamer {
-  static bool requiresFixups(MCContext &C, const MCExpr *Value,
-                             const MCExpr *&LHS, const MCExpr *&RHS);
   void reset() override;
 
 public:
@@ -24,8 +22,6 @@ class RISCVELFStreamer : public MCELFStreamer {
                    std::unique_ptr<MCObjectWriter> MOW,
                    std::unique_ptr<MCCodeEmitter> MCE)
       : MCELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE)) {}
-
-  void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override;
 };
 
 namespace llvm {

diff  --git a/llvm/test/CodeGen/RISCV/fixups-
diff .ll b/llvm/test/CodeGen/RISCV/fixups-
diff .ll
index 69fbed5a45a40d..cc1c87b1fe377f 100644
--- a/llvm/test/CodeGen/RISCV/fixups-
diff .ll
+++ b/llvm/test/CodeGen/RISCV/fixups-
diff .ll
@@ -3,13 +3,12 @@
 ; RUN: llc -filetype=obj -mtriple=riscv32 -mattr=-relax %s -o - \
 ; RUN:     | llvm-readobj -r - | FileCheck %s
 
-; Check that a 
diff erence between two symbols in the same fragment
-; causes relocations to be emitted.
-;
-; This specific test is checking that the size of the function in
-; the debug information is represented by a relocation. This isn't
-; an assembly test as the assembler takes a 
diff erent path through
-; LLVM, which is already covered by the fixups-expr.s test.
+;; b-a in the inline asm is unaffected by linker relaxation, so we don't emit
+;; relocations.
+
+;; b-a in the inline asm and DW_AT_high_pc are unaffected by linker relaxation,
+;; so we don't emit ADD/SUB relocations.
+;; See also MC/RISCV/fixups-expr.s.
 
 source_filename = "tmp.c"
 target datalayout = "e-m:e-p:32:32-i64:64-n32-S128"
@@ -19,21 +18,17 @@ define i32 @main() !dbg !7 {
 entry:
   %retval = alloca i32, align 4
   store i32 0, ptr %retval, align 4
+  call void asm sideeffect "a:\0Ab:\0A.dword b-a", ""()
   ret i32 0
 }
 
 ; CHECK:      Section {{.*}} .rela.debug_info {
-; CHECK:        0x22 R_RISCV_ADD32 <null> 0x0
-; CHECK-NEXT:   0x22 R_RISCV_SUB32 <null> 0x0
-; CHECK:        0x2B R_RISCV_ADD32 <null> 0x0
-; CHECK-NEXT:   0x2B R_RISCV_SUB32 <null> 0x0
+; CHECK-NOT:         R_RISCV_ADD32
 ; CHECK:      }
 
 ; CHECK:      Section {{.*}} .rela.eh_frame {
-; CHECK:        0x1C R_RISCV_32_PCREL <null> 0x0
-; CHECK:        0x20 R_RISCV_ADD32 <null> 0x0
-; CHECK-NEXT:   0x20 R_RISCV_SUB32 <null> 0x0
-; CHECK:      }
+; CHECK-NEXT:   0x1C R_RISCV_32_PCREL <null> 0x0
+; CHECK-NEXT: }
 
 !llvm.dbg.cu = !{!0}
 !llvm.module.flags = !{!3, !4, !5}

diff  --git a/llvm/test/CodeGen/RISCV/fixups-relax-
diff .ll b/llvm/test/CodeGen/RISCV/fixups-relax-
diff .ll
deleted file mode 100644
index fd012ccf640bf3..00000000000000
--- a/llvm/test/CodeGen/RISCV/fixups-relax-
diff .ll
+++ /dev/null
@@ -1,16 +0,0 @@
-; RUN: llc -filetype=obj -mtriple=riscv32 -mattr=+relax %s -o - | llvm-readobj -r - | FileCheck %s
-; RUN: llc -filetype=obj -mtriple=riscv32 -mattr=-relax %s -o - | llvm-readobj -r - | FileCheck %s
-
-; This test checks that a 
diff  inserted via inline assembly always causes
-; relocations. This isn't an assembly test as the assembler takes a 
diff erent
-; path through LLVM, which is already covered by the fixups-expr.s test.
-
-define i32 @main() nounwind {
-entry:
-  %retval = alloca i32, align 4
-  store i32 0, ptr %retval, align 4
-  ; CHECK: R_RISCV_ADD64 b
-  ; CHECK-NEXT: R_RISCV_SUB64 a
-  call void asm sideeffect "a:\0Ab:\0A.dword b-a", ""()
-  ret i32 0
-}

diff  --git a/llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll b/llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll
index b49ca8967a95e2..e5de1713f4e00d 100644
--- a/llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll
+++ b/llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll
@@ -70,9 +70,9 @@
 ; DWARF-DUMP-NEXT: Address            Line   Column File   ISA Discriminator OpIndex Flags
 ; DWARF-DUMP-NEXT: ------------------ ------ ------ ------ --- ------------- ------- -------------
 ; DWARF-DUMP-NEXT: 0x0000000000000000      2      0      0   0             0       0  is_stmt
-; DWARF-DUMP-NEXT: 0x0000000000000014      3      5      0   0             0       0  is_stmt prologue_end
-; DWARF-DUMP-NEXT: 0x0000000000000020      3      5      0   0             0       0  epilogue_begin
-; DWARF-DUMP-NEXT: 0x0000000000000028      3      5      0   0             0       0  end_sequence
+; DWARF-DUMP-NEXT: 0x000000000000001c      3      5      0   0             0       0  is_stmt prologue_end
+; DWARF-DUMP-NEXT: 0x0000000000000028      3      5      0   0             0       0  epilogue_begin
+; DWARF-DUMP-NEXT: 0x0000000000000030      3      5      0   0             0       0  end_sequence
 
 ; ModuleID = 'dwarf-riscv-relocs.c'
 source_filename = "dwarf-riscv-relocs.c"
@@ -82,11 +82,14 @@ target triple = "riscv32"
 ; Function Attrs: noinline nounwind optnone
 define dso_local i32 @main() #0 !dbg !7 {
 entry:
+  call void @ext()
   %retval = alloca i32, align 4
   store i32 0, ptr %retval, align 4
   ret i32 0, !dbg !11
 }
 
+declare void @ext()
+
 attributes #0 = { noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+relax" "unsafe-fp-math"="false" "use-soft-float"="false" }
 
 !llvm.dbg.cu = !{!0}

diff  --git a/llvm/test/DebugInfo/RISCV/relax-debug-frame.ll b/llvm/test/DebugInfo/RISCV/relax-debug-frame.ll
index 928ac98477a3a0..f655a7c0a7ef42 100644
--- a/llvm/test/DebugInfo/RISCV/relax-debug-frame.ll
+++ b/llvm/test/DebugInfo/RISCV/relax-debug-frame.ll
@@ -5,11 +5,7 @@
 ;
 ; RELAX:      Section ({{.*}}) .rela.eh_frame {
 ; RELAX-NEXT:   0x1C R_RISCV_32_PCREL <null> 0x0
-; RELAX-NEXT:   0x20 R_RISCV_ADD32 <null> 0x0
-; RELAX-NEXT:   0x20 R_RISCV_SUB32 <null> 0x0
 ; RELAX-NEXT:   0x30 R_RISCV_32_PCREL <null> 0x0
-; RELAX-NEXT:   0x34 R_RISCV_ADD32 <null> 0x0
-; RELAX-NEXT:   0x34 R_RISCV_SUB32 <null> 0x0
 ; RELAX-NEXT:   0x44 R_RISCV_32_PCREL <null> 0x0
 ; RELAX-NEXT:   0x48 R_RISCV_ADD32 <null> 0x0
 ; RELAX-NEXT:   0x48 R_RISCV_SUB32 <null> 0x0

diff  --git a/llvm/test/ExecutionEngine/JITLink/RISCV/anonymous_symbol.s b/llvm/test/ExecutionEngine/JITLink/RISCV/anonymous_symbol.s
index fc1c006095444a..a5038022dfe0c3 100644
--- a/llvm/test/ExecutionEngine/JITLink/RISCV/anonymous_symbol.s
+++ b/llvm/test/ExecutionEngine/JITLink/RISCV/anonymous_symbol.s
@@ -8,7 +8,7 @@
 # can be calculated.
 #
 # CHECK: Creating defined graph symbol for ELF symbol ""
-# CHECK: Creating defined graph symbol for ELF symbol ""
+# CHECK: Creating defined graph symbol for ELF symbol "main"
         .text
         .globl main
         .p2align 2

diff  --git a/llvm/test/MC/ELF/RISCV/gen-dwarf.s b/llvm/test/MC/ELF/RISCV/gen-dwarf.s
index 9a2bab883ba5c0..2235559d5f3575 100644
--- a/llvm/test/MC/ELF/RISCV/gen-dwarf.s
+++ b/llvm/test/MC/ELF/RISCV/gen-dwarf.s
@@ -11,7 +11,7 @@
 
 # RUN: llvm-mc -filetype=obj -triple=riscv64 -g -dwarf-version=5 -mattr=+relax < %s -o %t
 # RUN: llvm-dwarfdump -eh-frame -debug-line -debug-rnglists -v %t | FileCheck %s
-# RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=RELOC
+# RUN: llvm-readobj -r -x .eh_frame %t | FileCheck %s --check-prefix=RELOC
 
 # CHECK:      FDE
 # CHECK-NEXT: Format:       DWARF32
@@ -46,8 +46,6 @@
 # RELOC-NEXT:   0x25 R_RISCV_SET6 <null> 0x0
 # RELOC-NEXT:   0x25 R_RISCV_SUB6 <null> 0x0
 # RELOC-NEXT:   0x34 R_RISCV_32_PCREL <null> 0x0
-# RELOC-NEXT:   0x38 R_RISCV_ADD32 <null> 0x0
-# RELOC-NEXT:   0x38 R_RISCV_SUB32 <null> 0x0
 # RELOC-NEXT: }
 
 ## TODO A section needs two relocations.
@@ -65,6 +63,13 @@
 # RELOC-NEXT:   R_RISCV_SUB16 <null> 0x0
 # RELOC:      }
 
+# RELOC:      Hex dump of section '.eh_frame':
+# RELOC-NEXT: 0x00000000
+# RELOC-NEXT: 0x00000010
+# RELOC-NEXT: 0x00000020
+# RELOC-NEXT: 0x00000030 30000000 00000000 04000000 00000000
+#                                          ^ address_range
+
 .section .text.foo,"ax"
 .globl foo
 foo:

diff  --git a/llvm/test/MC/RISCV/cfi-advance.s b/llvm/test/MC/RISCV/cfi-advance.s
index accff5a6fb8260..d9224fd2ae1c9f 100644
--- a/llvm/test/MC/RISCV/cfi-advance.s
+++ b/llvm/test/MC/RISCV/cfi-advance.s
@@ -5,15 +5,13 @@
 
 # CHECK:      .rela.eh_frame {
 # CHECK-NEXT:   0x1C R_RISCV_32_PCREL <null> 0x0
-# CHECK-NEXT:   0x20 R_RISCV_ADD32 <null> 0x0
-# CHECK-NEXT:   0x20 R_RISCV_SUB32 <null> 0x0
 # CHECK-NEXT: }
-# CHECK-DWARFDUMP: DW_CFA_advance_loc1
-# CHECK-DWARFDUMP-NEXT: DW_CFA_def_cfa_offset
-# CHECK-DWARFDUMP-NEXT: DW_CFA_advance_loc2
-# CHECK-DWARFDUMP-NEXT: DW_CFA_def_cfa_offset
-# CHECK-DWARFDUMP-NEXT: DW_CFA_advance_loc4
-# CHECK-DWARFDUMP-NEXT: DW_CFA_def_cfa_offset
+# CHECK-DWARFDUMP: DW_CFA_advance_loc1: 104
+# CHECK-DWARFDUMP-NEXT: DW_CFA_def_cfa_offset: +8
+# CHECK-DWARFDUMP-NEXT: DW_CFA_advance_loc2: 259
+# CHECK-DWARFDUMP-NEXT: DW_CFA_def_cfa_offset: +8
+# CHECK-DWARFDUMP-NEXT: DW_CFA_advance_loc4: 65539
+# CHECK-DWARFDUMP-NEXT: DW_CFA_def_cfa_offset: +8
         .text
         .globl  test                            # -- Begin function test
         .p2align        1

diff  --git a/llvm/test/MC/RISCV/fde-reloc.s b/llvm/test/MC/RISCV/fde-reloc.s
index 4a5f3ea712a1c4..1db8929e074703 100644
--- a/llvm/test/MC/RISCV/fde-reloc.s
+++ b/llvm/test/MC/RISCV/fde-reloc.s
@@ -1,7 +1,7 @@
 # RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+relax < %s \
-# RUN:     | llvm-readobj -r - | FileCheck %s
+# RUN:     | llvm-readobj -r -x .eh_frame - | FileCheck %s
 # RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=-relax < %s \
-# RUN:     | llvm-readobj -r - | FileCheck %s
+# RUN:     | llvm-readobj -r -x .eh_frame - | FileCheck %s
 
 # Ensure that the eh_frame records the symbolic 
diff erence with the paired
 # relocations always.
@@ -13,6 +13,9 @@ func:
 
 # CHECK:   Section (4) .rela.eh_frame {
 # CHECK-NEXT:   0x1C R_RISCV_32_PCREL <null> 0x0
-# CHECK-NEXT:   0x20 R_RISCV_ADD32 <null> 0x0
-# CHECK-NEXT:   0x20 R_RISCV_SUB32 <null> 0x0
 # CHECK-NEXT: }
+# CHECK:      Hex dump of section '.eh_frame':
+# CHECK-NEXT: 0x00000000 10000000 00000000 017a5200 017c0101
+# CHECK-NEXT: 0x00000010 1b0c0200 10000000 18000000 00000000
+# CHECK-NEXT: 0x00000020 04000000 00000000
+#                        ^ address_range

diff  --git a/llvm/test/MC/RISCV/fixups-expr.s b/llvm/test/MC/RISCV/fixups-expr.s
index 10db3a3c563b94..20e5aacac61928 100644
--- a/llvm/test/MC/RISCV/fixups-expr.s
+++ b/llvm/test/MC/RISCV/fixups-expr.s
@@ -1,20 +1,24 @@
 # RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+relax %s \
 # RUN:     | llvm-readobj -r - | FileCheck -check-prefix RELAX %s
 # RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=-relax %s \
-# RUN:     | llvm-readobj -r - | FileCheck -check-prefix RELAX %s
+# RUN:     | llvm-readobj -r - | FileCheck -check-prefix NORELAX %s
 
 # RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax %s \
 # RUN:     | llvm-readobj -r - | FileCheck -check-prefix RELAX %s
 # RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=-relax %s \
-# RUN:     | llvm-readobj -r - | FileCheck -check-prefix RELAX %s
+# RUN:     | llvm-readobj -r - | FileCheck -check-prefix NORELAX %s
 
-# Check that subtraction expressions are emitted as two relocations always.
+# NORELAX:      Relocations [
+# NORELAX-NEXT:   .rela.text {
+# NORELAX-NEXT:     R_RISCV_CALL_PLT
+# NORELAX-NEXT:   }
+# NORELAX-NEXT: ]
 
 .globl G1
 .globl G2
 .L1:
 G1:
-addi a0, a0, 0
+  call extern
 .L2:
 G2:
 

diff  --git a/llvm/test/MC/RISCV/riscv64-64b-pcrel.s b/llvm/test/MC/RISCV/riscv64-64b-pcrel.s
index 9dd7879fc80562..865fd559b6a9b4 100644
--- a/llvm/test/MC/RISCV/riscv64-64b-pcrel.s
+++ b/llvm/test/MC/RISCV/riscv64-64b-pcrel.s
@@ -1,7 +1,6 @@
-# RUN: llvm-mc -triple riscv64-unknown-linux-gnu -filetype obj -o - %s \
-# RUN:   | llvm-readobj -r - | FileCheck %s
-# RUN: not llvm-mc -triple riscv64-unknown-linux-gnu -filetype obj --defsym ERR=1 -o /dev/null %s 2>&1 \
-# RUN:   | FileCheck %s --check-prefix=ERROR
+# RUN: llvm-mc -triple riscv64-unknown-linux-gnu -filetype obj %s -o %t
+# RUN: llvm-readobj -r %t | FileCheck %s
+# RUN: llvm-objdump -s %t | FileCheck %s --check-prefix=CONTENT
 
 # CHECK:      Relocations [
 # CHECK-NEXT:   Section ({{.*}}) .rela.note {
@@ -19,8 +18,6 @@
 # CHECK-NEXT:     0x8 R_RISCV_SUB64 extern 0x0
 # CHECK-NEXT:     0x10 R_RISCV_ADD32 x 0x0
 # CHECK-NEXT:     0x10 R_RISCV_SUB32 w 0x0
-# CHECK-NEXT:     0x14 R_RISCV_ADD32 w1 0x0
-# CHECK-NEXT:     0x14 R_RISCV_SUB32 w 0x0
 # CHECK-NEXT:     0x18 R_RISCV_ADD32 .L.str 0x0
 # CHECK-NEXT:     0x18 R_RISCV_SUB32 w 0x0
 # CHECK-NEXT:   }
@@ -35,6 +32,8 @@
 # CHECK-NEXT:   Section ({{.*}}) .rela.nonalloc_w {
 # CHECK-NEXT:     0x0 R_RISCV_ADD64 extern 0x0
 # CHECK-NEXT:     0x0 R_RISCV_SUB64 nw 0x0
+# CHECK-NEXT:     0x8 R_RISCV_ADD64 nw 0x0
+# CHECK-NEXT:     0x8 R_RISCV_SUB64 extern 0x0
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Section ({{.*}}) .rela.nonalloc_x {
 # CHECK-NEXT:     0x0 R_RISCV_ADD64 ny 0x0
@@ -46,6 +45,10 @@
 # CHECK-NEXT:   }
 # CHECK-NEXT: ]
 
+# CONTENT:      Contents of section .alloc_w:
+# CONTENT-NEXT:  0000 00000000 00000000 00000000 00000000
+# CONTENT-NEXT:  0010 00000000 1c000000 00000000
+
 .section .note,"a", at note; note:
 .quad extern-note
 .section .rodata,"a", at progbits; rodata:
@@ -66,10 +69,7 @@ w1:
 
 .section .nonalloc_w; nw:
 .quad extern-nw
-.ifdef ERR
-# ERROR: :[[#@LINE+1]]:7: error: symbol 'extern' can not be undefined in a subtraction expression
 .quad nw-extern
-.endif
 .section .nonalloc_x; nx:
 .quad ny-nx
 .section .nonalloc_y; ny:


        


More information about the llvm-commits mailing list