[llvm-branch-commits] [RISCV] Replace @plt/@gotpcrel in data directives with %plt %gotpcrel (PR #132569)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat Mar 22 15:04:10 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: Fangrui Song (MaskRay)
<details>
<summary>Changes</summary>
clang -fexperimental-relative-c++-abi-vtables might generate @<!-- -->plt and
@<!-- -->gotpcrel specifiers in data directives. The syntax is not used in
humand-written assembly code, and is not supported by GNU assembler.
Note: the `@<!-- -->plt` in `.word foo@<!-- -->plt` is different from
the legacy `call func@<!-- -->plt` (where `@<!-- -->plt` is simply ignored).
The @<!-- -->plt syntax was selected was simply due to a quirk of AsmParser:
the syntax was supported by all targets until I updated it
to be an opt-in feature in a0671758eb6e52a758bd1b096a9b421eec60204c
RISC-V favors the `%specifier(expr)` syntax following MIPS and Sparc,
and we should follow this convention.
This PR adds support for `.word %plt(foo-.)` and
`.word %gotpcreel(foo)` and drops `@<!-- -->plt` `@<!-- -->gotpcrel`.
* MCValue::SymA can no longer have a SymbolVariant. Add an assert
similar to that of AArch64ELFObjectWriter.cpp before
https://reviews.llvm.org/D81446 (see my analysis at
https://maskray.me/blog/2025-03-16-relocation-generation-in-assemblers
if intrigued)
* `jump foo@<!-- -->plt, x31` now has a different diagnostic.
---
Patch is 21.89 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/132569.diff
20 Files Affected:
- (modified) lld/test/ELF/riscv-reloc-plt32.s (+3-3)
- (modified) lld/test/ELF/riscv-undefined-weak.s (+1-1)
- (modified) lld/test/ELF/riscv64-reloc-got32-pcrel.s (+8-8)
- (modified) llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h (+6)
- (modified) llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h (+6)
- (modified) llvm/include/llvm/Target/TargetLoweringObjectFile.h (+1)
- (modified) llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (+6-5)
- (modified) llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (+23-7)
- (modified) llvm/lib/MC/MCAssembler.cpp (+1-1)
- (modified) llvm/lib/MC/MCParser/AsmParser.cpp (+1-1)
- (modified) llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (+24-7)
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp (+11-8)
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp (-7)
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp (+11-4)
- (modified) llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp (+8)
- (modified) llvm/lib/Target/RISCV/RISCVTargetObjectFile.h (+3)
- (modified) llvm/test/CodeGen/RISCV/dso_local_equivalent.ll (+1-1)
- (modified) llvm/test/MC/RISCV/data-directive-specifier.s (+11-11)
- (modified) llvm/test/MC/RISCV/pseudo-jump-invalid.s (+1-1)
- (modified) llvm/test/MC/RISCV/rv32i-invalid.s (+1)
``````````diff
diff --git a/lld/test/ELF/riscv-reloc-plt32.s b/lld/test/ELF/riscv-reloc-plt32.s
index 8cbc2d3f442c0..a50b9fe3f137a 100644
--- a/lld/test/ELF/riscv-reloc-plt32.s
+++ b/lld/test/ELF/riscv-reloc-plt32.s
@@ -18,6 +18,6 @@
.globl _start
_start:
.data
- .word foo at PLT - .
- .word foo at PLT - . + 1
- .word foo at PLT - . - 1
+ .word %plt(foo - .)
+ .word %plt(foo - . + 1)
+ .word %plt(foo - . - 1)
diff --git a/lld/test/ELF/riscv-undefined-weak.s b/lld/test/ELF/riscv-undefined-weak.s
index 8a78e1f838338..d78f55394b619 100644
--- a/lld/test/ELF/riscv-undefined-weak.s
+++ b/lld/test/ELF/riscv-undefined-weak.s
@@ -97,4 +97,4 @@ branch:
# PC-NOT: .plt:
# PLT: .plt:
-.word target at plt - .
+.word %plt(target - .)
diff --git a/lld/test/ELF/riscv64-reloc-got32-pcrel.s b/lld/test/ELF/riscv64-reloc-got32-pcrel.s
index 24bd828235b25..a8f42ae6df2b9 100644
--- a/lld/test/ELF/riscv64-reloc-got32-pcrel.s
+++ b/lld/test/ELF/riscv64-reloc-got32-pcrel.s
@@ -12,16 +12,16 @@ bar:
.globl _start
_start: // PC = 0x33a8
-// bar at GOTPCREL = 0x2398 (got entry for `bar`) - 0x33a8 (.) = 0xf0efffff
-// bar at GOTPCREL+4 = 0x2398 (got entry for `bar`) - 0x33ac (.) + 4 = 0xf0efffff
-// bar at GOTPCREL-4 = 0x2398 (got entry for `bar`) - 0x33b0 (.) - 4 = 0xe4efffff
+// %gotpcrel(bar) = 0x2398 (got entry for `bar`) - 0x33a8 (.) = 0xf0efffff
+// %gotpcrel(bar+4) = 0x2398 (got entry for `bar`) - 0x33ac (.) + 4 = 0xf0efffff
+// %gotpcrel(bar-4) = 0x2398 (got entry for `bar`) - 0x33b0 (.) - 4 = 0xe4efffff
// CHECK: Contents of section .data:
// CHECK-NEXT: {{.*}} f0efffff f0efffff e4efffff
- .word bar at GOTPCREL
- .word bar at GOTPCREL+4
- .word bar at GOTPCREL-4
+ .word %gotpcrel(bar)
+ .word %gotpcrel(bar+4)
+ .word %gotpcrel(bar-4)
// WARN: relocation R_RISCV_GOT32_PCREL out of range: {{.*}} is not in [-2147483648, 2147483647]; references 'baz'
// WARN: relocation R_RISCV_GOT32_PCREL out of range: {{.*}} is not in [-2147483648, 2147483647]; references 'baz'
- .word baz at GOTPCREL+0xffffffff
- .word baz at GOTPCREL-0xffffffff
+ .word %gotpcrel(baz+0xffffffff)
+ .word %gotpcrel(baz-0xffffffff)
diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index 7392963bd341f..f6e875e7ad373 100644
--- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -38,6 +38,7 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
protected:
uint8_t PLTRelativeSpecifier = 0;
+ bool UseTargetMCExprForPLTRelative = true;
public:
TargetLoweringObjectFileELF();
@@ -112,11 +113,16 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
MCSection *getStaticDtorSection(unsigned Priority,
const MCSymbol *KeySym) const override;
+ virtual const MCExpr *createTargetMCExpr(const MCExpr *Expr,
+ uint8_t Specifier) const {
+ return nullptr;
+ }
const MCExpr *lowerRelativeReference(const GlobalValue *LHS,
const GlobalValue *RHS,
const TargetMachine &TM) const override;
const MCExpr *lowerDSOLocalEquivalent(const DSOLocalEquivalent *Equiv,
+ const MCSymbolRefExpr *RHS,
const TargetMachine &TM) const override;
MCSection *getSectionForCommandLines() const override;
diff --git a/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h b/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
index 59cee18bfdf42..c7f098be70945 100644
--- a/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
+++ b/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
@@ -396,6 +396,12 @@ class MCTargetAsmParser : public MCAsmParserExtension {
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
return getParser().parsePrimaryExpr(Res, EndLoc, nullptr);
}
+ // Parse an expression in a data directive, possibly with a relocation
+ // specifier.
+ virtual bool parseDataExpr(const MCExpr *&Res) {
+ SMLoc EndLoc;
+ return getParser().parseExpression(Res, EndLoc);
+ }
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc,
SMLoc &EndLoc) = 0;
diff --git a/llvm/include/llvm/Target/TargetLoweringObjectFile.h b/llvm/include/llvm/Target/TargetLoweringObjectFile.h
index a5ed1b29dc1bc..77148320ccfd5 100644
--- a/llvm/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/llvm/include/llvm/Target/TargetLoweringObjectFile.h
@@ -209,6 +209,7 @@ class TargetLoweringObjectFile : public MCObjectFileInfo {
}
virtual const MCExpr *lowerDSOLocalEquivalent(const DSOLocalEquivalent *Equiv,
+ const MCSymbolRefExpr *RHS,
const TargetMachine &TM) const {
return nullptr;
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 743551822a8fc..c5e8aa39a9115 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -3382,7 +3382,7 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) {
return lowerBlockAddressConstant(*BA);
if (const auto *Equiv = dyn_cast<DSOLocalEquivalent>(CV))
- return getObjFileLowering().lowerDSOLocalEquivalent(Equiv, TM);
+ return getObjFileLowering().lowerDSOLocalEquivalent(Equiv, nullptr, TM);
if (const NoCFIValue *NC = dyn_cast<NoCFIValue>(CV))
return MCSymbolRefExpr::create(getSymbol(NC->getGlobalValue()), Ctx);
@@ -3481,12 +3481,13 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) {
if (!RelocExpr) {
const MCExpr *LHSExpr =
MCSymbolRefExpr::create(getSymbol(LHSGV), Ctx);
+ auto *RHSExpr = MCSymbolRefExpr::create(getSymbol(RHSGV), Ctx);
if (DSOEquiv &&
getObjFileLowering().supportDSOLocalEquivalentLowering())
- LHSExpr =
- getObjFileLowering().lowerDSOLocalEquivalent(DSOEquiv, TM);
- RelocExpr = MCBinaryExpr::createSub(
- LHSExpr, MCSymbolRefExpr::create(getSymbol(RHSGV), Ctx), Ctx);
+ RelocExpr = getObjFileLowering().lowerDSOLocalEquivalent(
+ DSOEquiv, RHSExpr, TM);
+ else
+ RelocExpr = MCBinaryExpr::createSub(LHSExpr, RHSExpr, Ctx);
}
int64_t Addend = (LHSOffset - RHSOffset).getSExtValue();
if (Addend != 0)
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 27a70e6f775b3..ee0db578d55b8 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -1194,18 +1194,34 @@ const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference(
MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext());
}
+// Reference the function or its PLT entry (`Equiv`), optionally with a
+// subtrahend (`RHS`).
const MCExpr *TargetLoweringObjectFileELF::lowerDSOLocalEquivalent(
- const DSOLocalEquivalent *Equiv, const TargetMachine &TM) const {
+ const DSOLocalEquivalent *Equiv, const MCSymbolRefExpr *RHS,
+ const TargetMachine &TM) const {
assert(supportDSOLocalEquivalentLowering());
+ // If GV is dso_local, reference the function itself. Return GV or GV-RHS.
const auto *GV = Equiv->getGlobalValue();
-
- // A PLT entry is not needed for dso_local globals.
+ const MCExpr *Res = MCSymbolRefExpr::create(TM.getSymbol(GV), getContext());
+ if (RHS)
+ Res = MCBinaryExpr::createSub(Res, RHS, getContext());
if (GV->isDSOLocal() || GV->isImplicitDSOLocal())
- return MCSymbolRefExpr::create(TM.getSymbol(GV), getContext());
-
- return MCSymbolRefExpr::create(TM.getSymbol(GV), PLTRelativeSpecifier,
- getContext());
+ return Res;
+
+ // Otherwise, reference the PLT. Return a relocatable expression with the PLT
+ // specifier, %plt(GV) or %plt(GV-RHS).
+ Res = createTargetMCExpr(Res, PLTRelativeSpecifier);
+ if (Res)
+ return Res;
+
+ // If the target only supports the legacy syntax @plt, return GV at plt or
+ // GV at plt - RHS.
+ Res = MCSymbolRefExpr::create(TM.getSymbol(GV), PLTRelativeSpecifier,
+ getContext());
+ if (RHS)
+ Res = MCBinaryExpr::createSub(Res, RHS, getContext());
+ return Res;
}
MCSection *TargetLoweringObjectFileELF::getSectionForCommandLines() const {
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index fb85accf267b4..06f94d5e89198 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -237,7 +237,7 @@ bool MCAssembler::evaluateFixup(const MCFixup &Fixup, const MCFragment *DF,
// 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 &&
+ Target.getRefKind() == 0 &&
getBackend().handleAddSubRelocations(*this, *DF, Fixup, Target, Value))
return true;
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index c11c01e52fc2e..87d9a7b8727df 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -3144,7 +3144,7 @@ bool AsmParser::parseDirectiveValue(StringRef IDVal, unsigned Size) {
auto parseOp = [&]() -> bool {
const MCExpr *Value;
SMLoc ExprLoc = getLexer().getLoc();
- if (checkForValidSection() || parseExpression(Value))
+ if (checkForValidSection() || getTargetParser().parseDataExpr(Value))
return true;
// Special case constant expressions to match code generator.
if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 05997cf78c6b1..5f673574c200d 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -225,6 +225,8 @@ class RISCVAsmParser : public MCTargetAsmParser {
}
bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
+ bool parseExprWithSpecifier(const MCExpr *&Res, SMLoc &E);
+ bool parseDataExpr(const MCExpr *&Res) override;
bool parseDirectiveOption();
bool parseDirectiveAttribute();
@@ -2233,8 +2235,17 @@ ParseStatus RISCVAsmParser::parseOperandWithSpecifier(OperandVector &Operands) {
SMLoc S = getLoc();
SMLoc E;
- if (!parseOptionalToken(AsmToken::Percent) ||
- getLexer().getKind() != AsmToken::Identifier)
+ if (!parseOptionalToken(AsmToken::Percent))
+ return Error(getLoc(), "expected '%' relocation specifier");
+ const MCExpr *Expr = nullptr;
+ bool Failed = parseExprWithSpecifier(Expr, E);
+ if (!Failed)
+ Operands.push_back(RISCVOperand::createImm(Expr, S, E, isRV64()));
+ return Failed;
+}
+
+bool RISCVAsmParser::parseExprWithSpecifier(const MCExpr *&Res, SMLoc &E) {
+ if (getLexer().getKind() != AsmToken::Identifier)
return Error(getLoc(), "expected '%' relocation specifier");
StringRef Identifier = getParser().getTok().getIdentifier();
auto Spec = RISCVMCExpr::getSpecifierForName(Identifier);
@@ -2243,15 +2254,21 @@ ParseStatus RISCVAsmParser::parseOperandWithSpecifier(OperandVector &Operands) {
getParser().Lex(); // Eat the identifier
if (parseToken(AsmToken::LParen, "expected '('"))
- return ParseStatus::Failure;
+ return true;
const MCExpr *SubExpr;
if (getParser().parseParenExpression(SubExpr, E))
- return ParseStatus::Failure;
+ return true;
- const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, *Spec, getContext());
- Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64()));
- return ParseStatus::Success;
+ Res = RISCVMCExpr::create(SubExpr, *Spec, getContext());
+ return false;
+}
+
+bool RISCVAsmParser::parseDataExpr(const MCExpr *&Res) {
+ SMLoc E;
+ if (parseOptionalToken(AsmToken::Percent))
+ return parseExprWithSpecifier(Res, E);
+ return getParser().parseExpression(Res);
}
ParseStatus RISCVAsmParser::parseBareSymbol(OperandVector &Operands) {
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
index f8841dd657568..afd5d3e4893f1 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
@@ -50,6 +50,9 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
const MCValue &Target,
const MCFixup &Fixup,
bool IsPCRel) const {
+ assert((!Target.getSymA() ||
+ Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None) &&
+ "sym at specifier should have been rejected");
const MCExpr *Expr = Fixup.getValue();
// Determine the type of the relocation
unsigned Kind = Fixup.getTargetKind();
@@ -73,9 +76,8 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
return ELF::R_RISCV_NONE;
case FK_Data_4:
case FK_PCRel_4:
- return uint8_t(Target.getAccessVariant()) == RISCVMCExpr::VK_PLT
- ? ELF::R_RISCV_PLT32
- : ELF::R_RISCV_32_PCREL;
+ return Target.getRefKind() == RISCVMCExpr::VK_PLT ? ELF::R_RISCV_PLT32
+ : ELF::R_RISCV_32_PCREL;
case RISCV::fixup_riscv_pcrel_hi20:
return ELF::R_RISCV_PCREL_HI20;
case RISCV::fixup_riscv_pcrel_lo12_i:
@@ -129,11 +131,12 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
Ctx.reportError(Fixup.getLoc(), "2-byte data relocations not supported");
return ELF::R_RISCV_NONE;
case FK_Data_4:
- if (Expr->getKind() == MCExpr::Target &&
- cast<RISCVMCExpr>(Expr)->getSpecifier() == RISCVMCExpr::VK_32_PCREL)
- return ELF::R_RISCV_32_PCREL;
- if (getSpecifier(Target.getSymA()) == RISCVMCExpr::VK_GOTPCREL)
- return ELF::R_RISCV_GOT32_PCREL;
+ if (Expr->getKind() == MCExpr::Target) {
+ if (cast<RISCVMCExpr>(Expr)->getSpecifier() == RISCVMCExpr::VK_32_PCREL)
+ return ELF::R_RISCV_32_PCREL;
+ if (cast<RISCVMCExpr>(Expr)->getSpecifier() == RISCVMCExpr::VK_GOTPCREL)
+ return ELF::R_RISCV_GOT32_PCREL;
+ }
return ELF::R_RISCV_32;
case FK_Data_8:
return ELF::R_RISCV_64;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
index c327f9d5f0f1e..7e9b312d3c25e 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
@@ -18,11 +18,6 @@
#include "llvm/TargetParser/Triple.h"
using namespace llvm;
-const MCAsmInfo::VariantKindDesc variantKindDescs[] = {
- {RISCVMCExpr::VK_GOTPCREL, "GOTPCREL"},
- {RISCVMCExpr::VK_PLT, "PLT"},
-};
-
void RISCVMCAsmInfo::anchor() {}
RISCVMCAsmInfo::RISCVMCAsmInfo(const Triple &TT) {
@@ -33,8 +28,6 @@ RISCVMCAsmInfo::RISCVMCAsmInfo(const Triple &TT) {
ExceptionsType = ExceptionHandling::DwarfCFI;
Data16bitsDirective = "\t.half\t";
Data32bitsDirective = "\t.word\t";
-
- initializeVariantKinds(variantKindDescs);
}
const MCExpr *RISCVMCAsmInfo::getExprForFDESymbol(const MCSymbol *Sym,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp
index 7de53e6d3f479..ce365d0036ce3 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp
@@ -94,8 +94,10 @@ bool RISCVMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
Res = MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(),
getSpecifier());
- // Custom fixup types are not valid with symbol difference expressions.
- return Res.getSymB() ? getSpecifier() == VK_None : true;
+ // When the subtrahend (SymB) is present, the relocatable expression
+ // only allows None and PLT as the specifier.
+ return !Res.getSymB() ||
+ llvm::is_contained({VK_None, VK_PLT}, getSpecifier());
}
void RISCVMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
@@ -119,14 +121,15 @@ RISCVMCExpr::getSpecifierForName(StringRef name) {
.Case("tlsdesc_load_lo", VK_TLSDESC_LOAD_LO)
.Case("tlsdesc_add_lo", VK_TLSDESC_ADD_LO)
.Case("tlsdesc_call", VK_TLSDESC_CALL)
+ // Used in data directives
+ .Case("plt", VK_PLT)
+ .Case("gotpcrel", VK_GOTPCREL)
.Default(std::nullopt);
}
StringRef RISCVMCExpr::getSpecifierName(Specifier S) {
switch (S) {
case VK_None:
- case VK_PLT:
- case VK_GOTPCREL:
llvm_unreachable("not used as %specifier()");
case VK_LO:
return "lo";
@@ -162,6 +165,10 @@ StringRef RISCVMCExpr::getSpecifierName(Specifier S) {
return "call_plt";
case VK_32_PCREL:
return "32_pcrel";
+ case VK_PLT:
+ return "plt";
+ case VK_GOTPCREL:
+ return "gotpcrel";
}
llvm_unreachable("Invalid ELF symbol kind");
}
diff --git a/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp b/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
index e546815b70935..7e98f1124d2e5 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
@@ -28,6 +28,7 @@ void RISCVELFTargetObjectFile::Initialize(MCContext &Ctx,
TargetLoweringObjectFileELF::Initialize(Ctx, TM);
PLTRelativeSpecifier = RISCVMCExpr::VK_PLT;
+ UseTargetMCExprForPLTRelative = true;
SupportIndirectSymViaGOTPCRel = true;
SmallDataSection = getContext().getELFSection(
@@ -180,3 +181,10 @@ MCSection *RISCVELFTargetObjectFile::getSectionForConstant(
return TargetLoweringObjectFileELF::getSectionForConstant(DL, Kind, C,
Alignment);
}
+
+const MCExpr *
+RISCVELFTargetObjectFile::createTargetMCExpr(const MCExpr *Expr,
+ uint8_t Specifier) const {
+ return RISCVMCExpr::create(Expr, RISCVMCExpr::Specifier(Specifier),
+ getContext());
+}
diff --git a/llvm/lib/Target/RISCV/RISCVTargetObjectFile.h b/llvm/lib/Target/RISCV/RISCVTargetObjectFile.h
index ff7e3e4c752c3..b6da3f4721f4b 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetObjectFile.h
+++ b/llvm/lib/Target/RISCV/RISCVTargetObjectFile.h
@@ -48,6 +48,9 @@ class RISCVELFTargetObjectFile : public TargetLoweringObjectFileELF {
bool isInSmallSection(uint64_t Size) const;
+ const MCExpr *createTargetMCExpr(const MCExpr *Expr,
+ uint8_t Specifier) const override;
+
const MCExpr *getIndirectSymViaGOTPCRel(const GlobalValue *GV,
const MCSymbol *Sym,
const MCValue &MV, int64_t Offset,
diff --git a/llvm/test/CodeGen/RISCV/dso_local_equivalent.ll b/llvm/test/CodeGen/RISCV/dso_local_equivalent.ll
index 0979967614b8a..9823e8b33fd9d 100644
--- a/llvm/test/CodeGen/RISCV/dso_local_equivalent.ll
+++ b/llvm/test/CodeGen/RISCV/dso_local_equivalent.ll
@@ -4,7 +4,7 @@
declare void @extern_func()
; CHECK-LABEL: const:
-; CHECK-NEXT: .word extern_func at PLT-const
+; CHECK-NEXT: .word %plt(extern_func-const)
;; Note that for riscv32, the ptrtoint will actually upcast the ptr it to an
;; oversized 64-bit pointer that eventually gets truncated. This isn't needed
diff --git a/llvm/test/MC/RISCV/data-directive-specifier.s b/llvm/test/MC/RISCV/data-directive-specifier.s
index a578f9720eccd..9d0f66ee384d9 100644
--- a/llvm/test/MC/RISCV/data-directive-specifier.s
+++ b/llvm/test/MC/RISCV/data-directive-specifier.s
@@ -15,12 +15,12 @@ l:
# CHECK-NEXT: 0x10 R_RISCV_PLT32 g 0x18
# CHECK-NEXT: }
.data
-.word l at plt - .
-.word l at plt - .data
+.word %plt(l - .)
+.word %plt(l - .data)
-.word extern at plt - . + 4
-.word g at plt - . + 8
-.word g at plt - .data + 8
+.word %plt(extern - . + 4)
+.word %plt(g - . + 8)
+.word %plt(g - .data + 8)
# CHECK: Section ({{.*}}) .rela.data1 {
# CHECK-NEXT: 0x0 R_RISCV_GOT32_PCREL data1 0x0
@@ -30,14 +30,14 @@ l:
# CHE...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/132569
More information about the llvm-branch-commits
mailing list