[llvm] [LoongArch] Fix MergeBaseOffset for constant pool index operand (PR #159336)

via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 17 04:51:39 PDT 2025


https://github.com/heiher created https://github.com/llvm/llvm-project/pull/159336

Fixes #159200

>From c29bd6ea5741cfefde39b10f57adb0fcb06408c9 Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui at loongson.cn>
Date: Wed, 17 Sep 2025 19:23:44 +0800
Subject: [PATCH] [LoongArch] Fix MergeBaseOffset for constant pool index
 operand

---
 llvm/include/llvm/CodeGen/MachineOperand.h    |  3 ++
 llvm/lib/CodeGen/MachineOperand.cpp           | 13 +++++++
 .../Target/LoongArch/LoongArchAsmPrinter.cpp  |  2 +-
 .../LoongArch/LoongArchMergeBaseOffset.cpp    |  4 ++
 .../LoongArch/inline-asm-constraint-m.ll      | 38 +++++++++++++++++++
 5 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/llvm/include/llvm/CodeGen/MachineOperand.h b/llvm/include/llvm/CodeGen/MachineOperand.h
index 646588a2a92a5..9104e93ed9783 100644
--- a/llvm/include/llvm/CodeGen/MachineOperand.h
+++ b/llvm/include/llvm/CodeGen/MachineOperand.h
@@ -788,6 +788,9 @@ class MachineOperand {
   LLVM_ABI void ChangeToBA(const BlockAddress *BA, int64_t Offset,
                            unsigned TargetFlags = 0);
 
+  /// ChangeToCPI - Replace this operand with a new constant pool index operand.
+  LLVM_ABI void ChangeToCPI(unsigned Idx, int Offset, unsigned TargetFlags = 0);
+
   /// ChangeToMCSymbol - Replace this operand with a new MC symbol operand.
   LLVM_ABI void ChangeToMCSymbol(MCSymbol *Sym, unsigned TargetFlags = 0);
 
diff --git a/llvm/lib/CodeGen/MachineOperand.cpp b/llvm/lib/CodeGen/MachineOperand.cpp
index c612f8de7b50b..bb9c76ff0c729 100644
--- a/llvm/lib/CodeGen/MachineOperand.cpp
+++ b/llvm/lib/CodeGen/MachineOperand.cpp
@@ -218,6 +218,19 @@ void MachineOperand::ChangeToBA(const BlockAddress *BA, int64_t Offset,
   setTargetFlags(TargetFlags);
 }
 
+void MachineOperand::ChangeToCPI(unsigned Idx, int Offset,
+                                 unsigned TargetFlags) {
+  assert((!isReg() || !isTied()) &&
+         "Cannot change a tied operand into a constant pool index");
+
+  removeRegFromUses();
+
+  OpKind = MO_ConstantPoolIndex;
+  setIndex(Idx);
+  setOffset(Offset);
+  setTargetFlags(TargetFlags);
+}
+
 void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym, unsigned TargetFlags) {
   assert((!isReg() || !isTied()) &&
          "Cannot change a tied operand into an MCSymbol");
diff --git a/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp b/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp
index b757d123fa0ff..2ab2a98c9434c 100644
--- a/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp
@@ -162,7 +162,7 @@ bool LoongArchAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
   else if (OffsetMO.isImm())
     OS << ", " << OffsetMO.getImm();
   else if (OffsetMO.isGlobal() || OffsetMO.isBlockAddress() ||
-           OffsetMO.isMCSymbol()) {
+           OffsetMO.isMCSymbol() || OffsetMO.isCPI()) {
     OS << ", ";
     MAI->printExpr(OS, *MCO.getExpr());
   } else
diff --git a/llvm/lib/Target/LoongArch/LoongArchMergeBaseOffset.cpp b/llvm/lib/Target/LoongArch/LoongArchMergeBaseOffset.cpp
index f62753356a4dd..a2292d016efa1 100644
--- a/llvm/lib/Target/LoongArch/LoongArchMergeBaseOffset.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchMergeBaseOffset.cpp
@@ -759,6 +759,10 @@ bool LoongArchMergeBaseOffsetOpt::foldIntoMemoryOps(MachineInstr &Hi20,
           MO.ChangeToBA(ImmOp.getBlockAddress(), ImmOp.getOffset(),
                         LoongArchII::getDirectFlags(ImmOp));
           break;
+        case MachineOperand::MO_ConstantPoolIndex:
+          MO.ChangeToCPI(ImmOp.getIndex(), ImmOp.getOffset(),
+                         LoongArchII::getDirectFlags(ImmOp));
+          break;
         default:
           report_fatal_error("unsupported machine operand type");
           break;
diff --git a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-m.ll b/llvm/test/CodeGen/LoongArch/inline-asm-constraint-m.ll
index 565ccdbe6880f..38e06d15670a8 100644
--- a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-m.ll
+++ b/llvm/test/CodeGen/LoongArch/inline-asm-constraint-m.ll
@@ -142,6 +142,44 @@ define i32 @m_offset_2048(ptr %p) nounwind {
   ret i32 %2
 }
 
+define i32 @m_constant_0() nounwind {
+; LA32-LABEL: m_constant_0:
+; LA32:       # %bb.0:
+; LA32-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI7_0)
+; LA32-NEXT:    #APP
+; LA32-NEXT:    #NO_APP
+; LA32-NEXT:    ret
+;
+; LA64-LABEL: m_constant_0:
+; LA64:       # %bb.0:
+; LA64-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI7_0)
+; LA64-NEXT:    #APP
+; LA64-NEXT:    #NO_APP
+; LA64-NEXT:    ret
+  %1 = call i32 asm sideeffect "", "=r,m"(i64 0)
+  ret i32 %1
+}
+
+define i32 @m_constant_1() nounwind {
+; LA32-LABEL: m_constant_1:
+; LA32:       # %bb.0:
+; LA32-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI8_0)
+; LA32-NEXT:    #APP
+; LA32-NEXT:    ld.w $a0, $a0, %pc_lo12(.LCPI8_0)
+; LA32-NEXT:    #NO_APP
+; LA32-NEXT:    ret
+;
+; LA64-LABEL: m_constant_1:
+; LA64:       # %bb.0:
+; LA64-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI8_0)
+; LA64-NEXT:    #APP
+; LA64-NEXT:    ld.w $a0, $a0, %pc_lo12(.LCPI8_0)
+; LA64-NEXT:    #NO_APP
+; LA64-NEXT:    ret
+  %1 = call i32 asm sideeffect "ld.w $0, $1", "=r,m"(i64 1)
+  ret i32 %1
+}
+
 @g_i32 = dso_local global i32 0
 
 define i32 @m_addr_pcrel() nounwind {



More information about the llvm-commits mailing list