[llvm] 3966292 - MCObjectStreamer: Refine absoluteSymbolDiff condition

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sat Apr 12 19:02:12 PDT 2025


Author: Fangrui Song
Date: 2025-04-12T19:02:07-07:00
New Revision: 39662922e15c53f54da93b5a1d029589d49caec9

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

LOG: MCObjectStreamer: Refine absoluteSymbolDiff condition

The function is called to test the fast path - when Lo/Hi are within the
same fragment. This is unsafe - Lo/Hi at the begin and end of a
relaxable fragment should not evaluate to a constant. However, we don't
have tests that exercise the code path.

Nevertheless, make the check safer and remove the now unnecessary
isRISCV check (from https://reviews.llvm.org/D103539).

Added: 
    

Modified: 
    llvm/lib/MC/MCObjectStreamer.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index e228418fea987..e9295f0e21dd3 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -94,8 +94,12 @@ void MCObjectStreamer::resolvePendingFixups() {
 static std::optional<uint64_t> absoluteSymbolDiff(const MCSymbol *Hi,
                                                   const MCSymbol *Lo) {
   assert(Hi && Lo);
-  if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
-      Hi->isVariable() || Lo->isVariable())
+  if (Lo == Hi)
+    return 0;
+  if (Hi->isVariable() || Lo->isVariable())
+    return std::nullopt;
+  auto *LoF = dyn_cast_or_null<MCDataFragment>(Lo->getFragment());
+  if (!LoF || Hi->getFragment() != LoF || LoF->isLinkerRelaxable())
     return std::nullopt;
 
   return Hi->getOffset() - Lo->getOffset();
@@ -104,20 +108,18 @@ static std::optional<uint64_t> absoluteSymbolDiff(const MCSymbol *Hi,
 void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
                                               const MCSymbol *Lo,
                                               unsigned Size) {
-  if (!getAssembler().getContext().getTargetTriple().isRISCV())
-    if (std::optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo))
-      return emitIntValue(*Diff, Size);
-  MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
+  if (std::optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo))
+    emitIntValue(*Diff, Size);
+  else
+    MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
 }
 
 void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
                                                        const MCSymbol *Lo) {
-  if (!getAssembler().getContext().getTargetTriple().isRISCV())
-    if (std::optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo)) {
-      emitULEB128IntValue(*Diff);
-      return;
-    }
-  MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
+  if (std::optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo))
+    emitULEB128IntValue(*Diff);
+  else
+    MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
 }
 
 void MCObjectStreamer::reset() {


        


More information about the llvm-commits mailing list