[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