[llvm] [Mips] Strip \x01 no-mangle prefix from R_MIPS_JALR symbol name (PR #219427)

via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 8 03:01:12 PDT 2026


https://github.com/yingopq updated https://github.com/llvm/llvm-project/pull/219427

>From fc0bacf8c882fc055f99cb46b10c31a87b7dd2cd Mon Sep 17 00:00:00 2001
From: Ying Huang <ying.huang at oss.cipunited.com>
Date: Fri, 28 Aug 2026 17:38:37 +0800
Subject: [PATCH 1/5] [Mips] Strip \x01 no-mangle prefix from R_MIPS_JALR
 symbol name

R_MIPS_JALR relocation did not strip the \x01 no-mangle prefix,
causing linker to see two different symbols: my_target_sym and
\x01my_target_sym.

Use Mangler::getNameWithPrefix() to process the symbol name.

Fix #207470.
---
 llvm/lib/Target/Mips/MipsAsmPrinter.cpp  | 20 +++++++++-------
 llvm/test/CodeGen/Mips/jalr-no-mangle.ll | 30 ++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 8 deletions(-)
 create mode 100644 llvm/test/CodeGen/Mips/jalr-no-mangle.ll

diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
index 62fd0ef319e1a..e0fdae5dbb911 100644
--- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -43,6 +43,7 @@
 #include "llvm/IR/Function.h"
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/Instructions.h"
+#include "llvm/IR/Mangler.h"
 #include "llvm/IR/Module.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCExpr.h"
@@ -147,21 +148,23 @@ void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer,
 //
 // This is an optimization hint for the linker which may then replace
 // an indirect call with a direct branch.
-static void emitDirectiveRelocJalr(const MachineInstr &MI,
-                                   MCContext &OutContext,
-                                   TargetMachine &TM,
-                                   MCStreamer &OutStreamer,
-                                   const MipsSubtarget &Subtarget) {
+void emitDirectiveRelocJalr(const MachineInstr &MI, MCContext &OutContext,
+                            TargetMachine &TM, MCStreamer &OutStreamer,
+                            const MipsSubtarget &Subtarget,
+                            const DataLayout &DL) {
   for (const MachineOperand &MO :
        llvm::drop_begin(MI.operands(), MI.getDesc().getNumOperands())) {
     if (MO.isMCSymbol() && (MO.getTargetFlags() & MipsII::MO_JALR)) {
       MCSymbol *Callee = MO.getMCSymbol();
       if (Callee && !Callee->getName().empty()) {
+        SmallString<128> Name;
+        MCSymbol *Sym = nullptr;
+        Mangler::getNameWithPrefix(Name, Callee->getName(), DL);
+        Sym = OutContext.getOrCreateSymbol(Name);
         MCSymbol *OffsetLabel = OutContext.createTempSymbol();
         const MCExpr *OffsetExpr =
             MCSymbolRefExpr::create(OffsetLabel, OutContext);
-        const MCExpr *CaleeExpr =
-            MCSymbolRefExpr::create(Callee, OutContext);
+        const MCExpr *CaleeExpr = MCSymbolRefExpr::create(Sym, OutContext);
         OutStreamer.emitRelocDirective(
             *OffsetExpr,
             Subtarget.inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
@@ -238,7 +241,8 @@ void MipsAsmPrinter::emitInstruction(const MachineInstr *MI) {
 
   if (EmitJalrReloc &&
       (MI->isReturn() || MI->isCall() || MI->isIndirectBranch())) {
-    emitDirectiveRelocJalr(*MI, OutContext, TM, *OutStreamer, *Subtarget);
+    emitDirectiveRelocJalr(*MI, OutContext, TM, *OutStreamer, *Subtarget,
+                           MF->getDataLayout());
   }
 
   MachineBasicBlock::const_instr_iterator I = MI->getIterator();
diff --git a/llvm/test/CodeGen/Mips/jalr-no-mangle.ll b/llvm/test/CodeGen/Mips/jalr-no-mangle.ll
new file mode 100644
index 0000000000000..573328dfab368
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/jalr-no-mangle.ll
@@ -0,0 +1,30 @@
+; RUN: llc -mtriple=mipsel-unknown-linux-gnu -relocation-model=pic < %s | FileCheck %s --check-prefix=ASM
+; RUN: llc -mtriple=mipsel-unknown-linux-gnu -relocation-model=pic -filetype=obj -o %t %s
+; RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
+; RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=SYM
+
+declare i32 @"\01my_target_sym"()
+
+define i32 @caller() nounwind {
+; ASM-LABEL: caller:
+; ASM:       # %bb.0: # %entry
+; ASM-NEXT:    lui $2, %hi(_gp_disp)
+; ASM-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; ASM-NEXT:    addiu $sp, $sp, -24
+; ASM-NEXT:    sw $ra, 20($sp)
+; ASM-NEXT:    addu $gp, $2, $25
+; ASM-NEXT:    lw $25, %call16(my_target_sym)($gp)
+; ASM-NEXT:    .reloc $tmp0, R_MIPS_JALR, my_target_sym
+; ASM-NEXT:  $tmp0:
+; ASM-NEXT:    jalr $25
+; ASM-NEXT:    nop
+
+; RELOC: R_MIPS_JALR{{.*}}my_target_sym
+
+; SYM: UND{{.*}}my_target_sym
+; SYM-NOT: UND{{.*}}my_target_sym
+
+entry:
+  %call = call i32 @"\01my_target_sym"()
+  ret i32 %call
+}

>From ad6547738f2fbdea40e57e25e4a976d3a2f1f092 Mon Sep 17 00:00:00 2001
From: Ying Huang <ying.huang at oss.cipunited.com>
Date: Tue, 8 Sep 2026 17:28:07 +0800
Subject: [PATCH 2/5] Reuse GetExternalSymbolSymbol

---
 llvm/lib/Target/Mips/MipsAsmPrinter.cpp | 12 ++++--------
 llvm/lib/Target/Mips/MipsAsmPrinter.h   |  3 +++
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
index e0fdae5dbb911..43ed4f22df89f 100644
--- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -148,19 +148,16 @@ void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer,
 //
 // This is an optimization hint for the linker which may then replace
 // an indirect call with a direct branch.
-void emitDirectiveRelocJalr(const MachineInstr &MI, MCContext &OutContext,
+void MipsAsmPrinter::emitDirectiveRelocJalr(const MachineInstr &MI, MCContext &OutContext,
                             TargetMachine &TM, MCStreamer &OutStreamer,
-                            const MipsSubtarget &Subtarget,
-                            const DataLayout &DL) {
+                            const MipsSubtarget &Subtarget) {
   for (const MachineOperand &MO :
        llvm::drop_begin(MI.operands(), MI.getDesc().getNumOperands())) {
     if (MO.isMCSymbol() && (MO.getTargetFlags() & MipsII::MO_JALR)) {
       MCSymbol *Callee = MO.getMCSymbol();
       if (Callee && !Callee->getName().empty()) {
-        SmallString<128> Name;
         MCSymbol *Sym = nullptr;
-        Mangler::getNameWithPrefix(Name, Callee->getName(), DL);
-        Sym = OutContext.getOrCreateSymbol(Name);
+	Sym = GetExternalSymbolSymbol(Callee->getName());
         MCSymbol *OffsetLabel = OutContext.createTempSymbol();
         const MCExpr *OffsetExpr =
             MCSymbolRefExpr::create(OffsetLabel, OutContext);
@@ -241,8 +238,7 @@ void MipsAsmPrinter::emitInstruction(const MachineInstr *MI) {
 
   if (EmitJalrReloc &&
       (MI->isReturn() || MI->isCall() || MI->isIndirectBranch())) {
-    emitDirectiveRelocJalr(*MI, OutContext, TM, *OutStreamer, *Subtarget,
-                           MF->getDataLayout());
+    emitDirectiveRelocJalr(*MI, OutContext, TM, *OutStreamer, *Subtarget);
   }
 
   MachineBasicBlock::const_instr_iterator I = MI->getIterator();
diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.h b/llvm/lib/Target/Mips/MipsAsmPrinter.h
index 6d45ad551db72..37bb908c05394 100644
--- a/llvm/lib/Target/Mips/MipsAsmPrinter.h
+++ b/llvm/lib/Target/Mips/MipsAsmPrinter.h
@@ -159,6 +159,9 @@ class LLVM_LIBRARY_VISIBILITY MipsAsmPrinter : public AsmPrinter {
   void emitEndOfAsmFile(Module &M) override;
   void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
   void emitDebugValue(const MCExpr *Value, unsigned Size) const override;
+  void emitDirectiveRelocJalr(const MachineInstr &MI, MCContext &OutContext,
+                             TargetMachine &TM, MCStreamer &OutStreamer,
+                             const MipsSubtarget &Subtarget);
 };
 
 } // end namespace llvm

>From cbab914980bbcb4a9a9d29dea2b5994b01363dd1 Mon Sep 17 00:00:00 2001
From: Ying Huang <ying.huang at oss.cipunited.com>
Date: Tue, 8 Sep 2026 17:29:23 +0800
Subject: [PATCH 3/5] Fix clang-format info

---
 llvm/lib/Target/Mips/MipsAsmPrinter.cpp | 10 ++++++----
 llvm/lib/Target/Mips/MipsAsmPrinter.h   |  4 ++--
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
index 43ed4f22df89f..9194d2e1b1ceb 100644
--- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -148,16 +148,18 @@ void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer,
 //
 // This is an optimization hint for the linker which may then replace
 // an indirect call with a direct branch.
-void MipsAsmPrinter::emitDirectiveRelocJalr(const MachineInstr &MI, MCContext &OutContext,
-                            TargetMachine &TM, MCStreamer &OutStreamer,
-                            const MipsSubtarget &Subtarget) {
+void MipsAsmPrinter::emitDirectiveRelocJalr(const MachineInstr &MI,
+                                            MCContext &OutContext,
+                                            TargetMachine &TM,
+                                            MCStreamer &OutStreamer,
+                                            const MipsSubtarget &Subtarget) {
   for (const MachineOperand &MO :
        llvm::drop_begin(MI.operands(), MI.getDesc().getNumOperands())) {
     if (MO.isMCSymbol() && (MO.getTargetFlags() & MipsII::MO_JALR)) {
       MCSymbol *Callee = MO.getMCSymbol();
       if (Callee && !Callee->getName().empty()) {
         MCSymbol *Sym = nullptr;
-	Sym = GetExternalSymbolSymbol(Callee->getName());
+        Sym = GetExternalSymbolSymbol(Callee->getName());
         MCSymbol *OffsetLabel = OutContext.createTempSymbol();
         const MCExpr *OffsetExpr =
             MCSymbolRefExpr::create(OffsetLabel, OutContext);
diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.h b/llvm/lib/Target/Mips/MipsAsmPrinter.h
index 37bb908c05394..ae77c305f9703 100644
--- a/llvm/lib/Target/Mips/MipsAsmPrinter.h
+++ b/llvm/lib/Target/Mips/MipsAsmPrinter.h
@@ -160,8 +160,8 @@ class LLVM_LIBRARY_VISIBILITY MipsAsmPrinter : public AsmPrinter {
   void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
   void emitDebugValue(const MCExpr *Value, unsigned Size) const override;
   void emitDirectiveRelocJalr(const MachineInstr &MI, MCContext &OutContext,
-                             TargetMachine &TM, MCStreamer &OutStreamer,
-                             const MipsSubtarget &Subtarget);
+                              TargetMachine &TM, MCStreamer &OutStreamer,
+                              const MipsSubtarget &Subtarget);
 };
 
 } // end namespace llvm

>From 16aa06c870b46ae889833e0f09c5a2f44bdc0f49 Mon Sep 17 00:00:00 2001
From: Ying Huang <ying.huang at oss.cipunited.com>
Date: Tue, 8 Sep 2026 17:52:37 +0800
Subject: [PATCH 4/5] delete redundant head file

---
 llvm/lib/Target/Mips/MipsAsmPrinter.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
index 9194d2e1b1ceb..1fbf0aff00ec1 100644
--- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -43,7 +43,6 @@
 #include "llvm/IR/Function.h"
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/Instructions.h"
-#include "llvm/IR/Mangler.h"
 #include "llvm/IR/Module.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCExpr.h"

>From c70d775977ea8a03ed849128ae920fd39f8cb59b Mon Sep 17 00:00:00 2001
From: Ying Huang <ying.huang at oss.cipunited.com>
Date: Tue, 8 Sep 2026 18:00:16 +0800
Subject: [PATCH 5/5] Optimize code and remove redundant code

---
 llvm/lib/Target/Mips/MipsAsmPrinter.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
index 1fbf0aff00ec1..adda6154e15a5 100644
--- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -157,8 +157,7 @@ void MipsAsmPrinter::emitDirectiveRelocJalr(const MachineInstr &MI,
     if (MO.isMCSymbol() && (MO.getTargetFlags() & MipsII::MO_JALR)) {
       MCSymbol *Callee = MO.getMCSymbol();
       if (Callee && !Callee->getName().empty()) {
-        MCSymbol *Sym = nullptr;
-        Sym = GetExternalSymbolSymbol(Callee->getName());
+        MCSymbol *Sym = GetExternalSymbolSymbol(Callee->getName());
         MCSymbol *OffsetLabel = OutContext.createTempSymbol();
         const MCExpr *OffsetExpr =
             MCSymbolRefExpr::create(OffsetLabel, OutContext);



More information about the llvm-commits mailing list