[llvm] [SPARC] Parse relocation specifiers in expressions (PR #208933)

Kirill A. Korinsky via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 11 11:26:25 PDT 2026


https://github.com/catap created https://github.com/llvm/llvm-project/pull/208933

SPARC code generation emits relocation specifiers such as %r_disp32(...) in data directives, but the integrated assembler only recognizes them while parsing instruction operands. Consequently, LLVM cannot reassemble its own PIC exception table output.

Parse SPARC relocation specifiers through the target primary expression hook. Preserve diagnostics for malformed specifiers, and add MC tests for assembly printing and R_SPARC_DISP32 relocation emission on sparc and sparcv9.

>From 8bd82d25c1447a8e3928f319b58c597c6521fe97 Mon Sep 17 00:00:00 2001
From: "Kirill A. Korinsky" <kirill at korins.ky>
Date: Sat, 11 Jul 2026 20:25:07 +0200
Subject: [PATCH] [SPARC] Parse relocation specifiers in expressions

SPARC code generation emits relocation specifiers such as %r_disp32(...)
in data directives, but the integrated assembler only recognizes them
while parsing instruction operands. Consequently, LLVM cannot reassemble
its own PIC exception table output.

Parse SPARC relocation specifiers through the target primary expression
hook. Preserve diagnostics for malformed specifiers, and add MC tests
for assembly printing and R_SPARC_DISP32 relocation emission on sparc
and sparcv9.
---
 .../Target/Sparc/AsmParser/SparcAsmParser.cpp   | 17 ++++++++++++++++-
 llvm/test/MC/Sparc/sparc-asm-errors.s           |  3 +++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
index f6b8e0af67150..3770798c9ce81 100644
--- a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+++ b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
@@ -81,6 +81,7 @@ class SparcAsmParser : public MCTargetAsmParser {
   bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
                         SMLoc NameLoc, OperandVector &Operands) override;
   ParseStatus parseDirective(AsmToken DirectiveID) override;
+  bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) override;
 
   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
                                       unsigned Kind) override;
@@ -1734,8 +1735,10 @@ bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
   }
 
   Parser.Lex(); // Eat the identifier.
-  if (Parser.getTok().getKind() != AsmToken::LParen)
+  if (Parser.getTok().getKind() != AsmToken::LParen) {
+    Error(getLoc(), "expected '('");
     return false;
+  }
 
   Parser.Lex(); // Eat the LParen token.
   const MCExpr *subExpr;
@@ -1746,6 +1749,18 @@ bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
   return true;
 }
 
+bool SparcAsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
+  if (Parser.getTok().is(AsmToken::Percent)) {
+    Parser.Lex();
+    if (matchSparcAsmModifiers(Res, EndLoc))
+      return false;
+    if (!Parser.hasPendingError())
+      return Error(getLoc(), "invalid relocation specifier");
+    return true;
+  }
+  return Parser.parsePrimaryExpr(Res, EndLoc, nullptr);
+}
+
 bool SparcAsmParser::isPossibleExpression(const AsmToken &Token) {
   switch (Token.getKind()) {
   case AsmToken::LParen:
diff --git a/llvm/test/MC/Sparc/sparc-asm-errors.s b/llvm/test/MC/Sparc/sparc-asm-errors.s
index 655fd15e3962f..7a294482b6c93 100644
--- a/llvm/test/MC/Sparc/sparc-asm-errors.s
+++ b/llvm/test/MC/Sparc/sparc-asm-errors.s
@@ -20,3 +20,6 @@
         sll %g1, 32, %g2
         ! V9: immediate shift value out of range
         slx %g1, 64, %g2
+
+        ! CHECK: expected '('
+        .word %r_disp32 foo



More information about the llvm-commits mailing list