[llvm] 1ec9dd2 - Sparc: Refactor R_SPARC_13/R_SPARC_GOT13 handling and fix a bug referencing absolute symbol

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sat May 3 22:50:33 PDT 2025


Author: Fangrui Song
Date: 2025-05-03T22:50:28-07:00
New Revision: 1ec9dd256ea287796261ba88d7bdfbeaba38343d

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

LOG: Sparc: Refactor R_SPARC_13/R_SPARC_GOT13 handling and fix a bug referencing absolute symbol

https://reviews.llvm.org/D47136 did not correctly handle `ld [%i0 + abs], %o0; abs = 7`

To fix it and make fixup handling less hacky,

* Change TableGen MEMri to use simm13Op instead of i32imm
* Emit a fixup of kind fixup_sparc_13 in SparcMCCodeEmitter::getSImm13OpValue
* Convert fixup_sparc_13 to either R_SPARC_13/R_SPARC_GOT13 in getRelocType

This postpones 13/GOT13 decision to relocation generation, ensuring that
we suppress the relocation when referencing an absolute symbol, matching
gas.

Added: 
    

Modified: 
    llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
    llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
    llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
    llvm/lib/Target/Sparc/SparcInstrInfo.td
    llvm/test/MC/Sparc/sparc-fixups.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
index 8a730932ce9f8..78fc1dad203c3 100644
--- a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+++ b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
@@ -1480,18 +1480,8 @@ SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
     if (getParser().parseExpression(EVal, E))
       break;
 
-    int64_t Res;
-    if (!EVal->evaluateAsAbsolute(Res)) {
-      SparcMCExpr::Specifier Kind = SparcMCExpr::VK_13;
-
-      if (getContext().getObjectFileInfo()->isPositionIndependent()) {
-        if (isCall)
-          Kind = SparcMCExpr::VK_WPLT30;
-        else
-          Kind = SparcMCExpr::VK_GOT13;
-      }
-      EVal = SparcMCExpr::create(Kind, EVal, getContext());
-    }
+    if (isCall && getContext().getObjectFileInfo()->isPositionIndependent())
+      EVal = SparcMCExpr::create(SparcMCExpr::VK_WPLT30, EVal, getContext());
     Op = SparcOperand::CreateImm(EVal, S, E);
     break;
   }

diff  --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
index 0c0f49f11a429..1ed5313703b42 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
@@ -9,8 +9,10 @@
 #include "MCTargetDesc/SparcFixupKinds.h"
 #include "MCTargetDesc/SparcMCExpr.h"
 #include "MCTargetDesc/SparcMCTargetDesc.h"
+#include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCELFObjectWriter.h"
 #include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCObjectFileInfo.h"
 #include "llvm/MC/MCObjectWriter.h"
 #include "llvm/MC/MCValue.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -110,7 +112,11 @@ unsigned SparcELFObjectWriter::getRelocType(MCContext &Ctx,
   case FK_Data_8:                return ((Fixup.getOffset() % 8)
                                          ? ELF::R_SPARC_UA64
                                          : ELF::R_SPARC_64);
-  case Sparc::fixup_sparc_13:    return ELF::R_SPARC_13;
+  case Sparc::fixup_sparc_13:
+    if (Ctx.getObjectFileInfo()->isPositionIndependent())
+      return ELF::R_SPARC_GOT13;
+    return ELF::R_SPARC_13;
+
   case Sparc::fixup_sparc_hi22:  return ELF::R_SPARC_HI22;
   case Sparc::fixup_sparc_lo10:  return ELF::R_SPARC_LO10;
   case Sparc::fixup_sparc_h44:   return ELF::R_SPARC_H44;

diff  --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
index b23cc16b76de4..3aaedef6120d8 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
@@ -163,10 +163,7 @@ SparcMCCodeEmitter::getSImm13OpValue(const MCInst &MI, unsigned OpNo,
     Fixups.push_back(MCFixup::create(0, Expr, SExpr->getFixupKind()));
     return 0;
   }
-  uint16_t Kind = Sparc::fixup_sparc_13;
-  if (Ctx.getObjectFileInfo()->isPositionIndependent())
-    Kind = ELF::R_SPARC_GOT13;
-  Fixups.push_back(MCFixup::create(0, Expr, Kind));
+  Fixups.push_back(MCFixup::create(0, Expr, Sparc::fixup_sparc_13));
   return 0;
 }
 

diff  --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td b/llvm/lib/Target/Sparc/SparcInstrInfo.td
index 0c890721da0f4..5617681821a3f 100644
--- a/llvm/lib/Target/Sparc/SparcInstrInfo.td
+++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td
@@ -145,6 +145,12 @@ def SparcMEMriAsmOperand : AsmOperandClass {
   let ParserMethod = "parseMEMOperand";
 }
 
+def simm13Op : Operand<iPTR> {
+  let OperandType = "OPERAND_IMMEDIATE";
+  let DecoderMethod = "DecodeSIMM13";
+  let EncoderMethod = "getSImm13OpValue";
+}
+
 def MEMrr : Operand<iPTR> {
   let PrintMethod = "printMemOperand";
   let MIOperandInfo = (ops ptr_rc, ptr_rc);
@@ -152,7 +158,7 @@ def MEMrr : Operand<iPTR> {
 }
 def MEMri : Operand<iPTR> {
   let PrintMethod = "printMemOperand";
-  let MIOperandInfo = (ops ptr_rc, i32imm);
+  let MIOperandInfo = (ops ptr_rc, simm13Op);
   let ParserMatchClass = SparcMEMriAsmOperand;
 }
 
@@ -234,12 +240,6 @@ def calltarget : Operand<i32> {
   let ParserMatchClass = SparcCallTargetAsmOperand;
 }
 
-def simm13Op : Operand<iPTR> {
-  let OperandType = "OPERAND_IMMEDIATE";
-  let DecoderMethod = "DecodeSIMM13";
-  let EncoderMethod = "getSImm13OpValue";
-}
-
 // Operand for printing out a condition code.
 let PrintMethod = "printCCOperand" in {
   def CCOp : Operand<i32>;

diff  --git a/llvm/test/MC/Sparc/sparc-fixups.s b/llvm/test/MC/Sparc/sparc-fixups.s
index 18224d699fe28..e77f56e24cad3 100644
--- a/llvm/test/MC/Sparc/sparc-fixups.s
+++ b/llvm/test/MC/Sparc/sparc-fixups.s
@@ -1,34 +1,40 @@
-! RUN: llvm-mc %s -triple=sparcv9 -filetype=obj | llvm-objdump -dr - | FileCheck %s
+# RUN: llvm-mc %s -triple=sparcv9 -filetype=obj | llvm-objdump -dr - | FileCheck %s --check-prefixes=NOPIC,CHECK
+# RUN: llvm-mc %s -triple=sparcv9 -filetype=obj -position-independent | llvm-objdump -dr - | FileCheck %s
 .text
 
-! Check that fixups are correctly applied.
+# Check that fixups are correctly applied.
 
 .set sym, 0xfedcba98
 
-! CHECK:      sethi 0x3fb72e, %o0
-! CHECK-NEXT: xor %o0, 0x298, %o0
-! CHECK-NEXT: sethi 0x3b72ea, %o1
-! CHECK-NEXT: xor %o0, 0x188, %o1
+## FIXME: Don't emit GOT relocations when -position-independent is specified.
+# NOPIC:      sethi 0x3fb72e, %o0
+# NOPIC-NEXT: xor %o0, 0x298, %o0
+# NOPIC-NEXT: sethi 0x3b72ea, %o1
+# NOPIC-NEXT: xor %o0, 0x188, %o1
 sethi %hi(sym), %o0
 xor %o0, %lo(sym), %o0
 sethi %hi(-0x12345678), %o1
 xor %o0, %lo(-0x12345678), %o1
 
-! CHECK:      sethi 0x3fb, %o0
-! CHECK-NEXT: or %o0, 0x1cb, %o0
-! CHECK-NEXT: ld [%o0+0xa98], %o0
+# CHECK:      ld [%i0+0x7], %o0
+ld [%i0 + abs], %o0
+abs = 7
+
+# CHECK-NEXT: sethi 0x3fb, %o0
+# CHECK-NEXT: or %o0, 0x1cb, %o0
+# CHECK-NEXT: ld [%o0+0xa98], %o0
 sethi %h44(sym), %o0
 or %o0, %m44(sym), %o0
 ld [%o0 + %l44(sym)], %o0
 
-! CHECK:      sethi 0x0, %o0
-! CHECK-NEXT: sethi 0x3fb72e, %o0
-! CHECK-NEXT: or %o0, 0x0, %o0
+# CHECK-NEXT: sethi 0x0, %o0
+# CHECK-NEXT: sethi 0x3fb72e, %o0
+# CHECK-NEXT: or %o0, 0x0, %o0
 sethi %hh(sym), %o0
 sethi %lm(sym), %o0
 or %o0, %hm(sym), %o0
 
-! CHECK:      sethi 0x48d1, %o0
-! CHECK-NEXT: xor %o0, -0x168, %o0
+# CHECK-NEXT: sethi 0x48d1, %o0
+# CHECK-NEXT: xor %o0, -0x168, %o0
 sethi %hix(sym), %o0
 xor %o0, %lox(sym), %o0


        


More information about the llvm-commits mailing list