[llvm] IPRA: Fixes an IPRA compilation failure. (PR #196928)

via llvm-commits llvm-commits at lists.llvm.org
Sun Jun 14 19:02:50 PDT 2026


https://github.com/vigbalu updated https://github.com/llvm/llvm-project/pull/196928

>From 5afb769d2c90a2d99c1cd4fe0633bee9f484d10a Mon Sep 17 00:00:00 2001
From: Vignesh Balasubramanian <vigbalas at amd.com>
Date: Mon, 11 May 2026 17:01:38 +0530
Subject: [PATCH] IPRA: Fixes an IPRA compilation failure.

IPRA updates the clobbered registers of a call instruction by limiting them
to the registers used by the corresponding callee functions.

However, for the FP and ST register sets, IPRA previously marked only the
individually used registers rather than the entire register group.

This behavior violates the assumptions of the X86Stackifier pass, which expects
either all or none of the FP or ST registers to be marked as clobbered,
in accordance with the platform ABI conventions.

This patch uses the existing target API to mark all FP registers as clobbered,
if anyone of them are used.

Fixes #196864
---
 llvm/lib/Target/X86/X86RegisterInfo.cpp   | 18 ++++++++++++
 llvm/lib/Target/X86/X86RegisterInfo.h     |  2 ++
 llvm/test/CodeGen/X86/ipra-x87-regmask.ll | 34 +++++++++++++++++++++++
 3 files changed, 54 insertions(+)
 create mode 100644 llvm/test/CodeGen/X86/ipra-x87-regmask.ll

diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp
index c84e0f441a459..2db847a1288f7 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.cpp
+++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp
@@ -396,6 +396,24 @@ const MCPhysReg *X86RegisterInfo::getCalleeSavedRegsViaCopy(
   return nullptr;
 }
 
+ArrayRef<MCPhysReg>
+X86RegisterInfo::getIntraCallClobberedRegs(const MachineFunction *MF) const {
+  static const MCPhysReg X87PhysRegs[] = {
+    X86::FP0, X86::FP1, X86::FP2, X86::FP3, X86::FP4, X86::FP5,
+    X86::FP6, X86::FP7, X86::ST0, X86::ST1, X86::ST2, X86::ST3,
+    X86::ST4, X86::ST5, X86::ST6, X86::ST7
+  };
+
+  const MachineRegisterInfo &MRI = MF->getRegInfo();
+  const BitVector &UsedPhysRegsMask = MRI.getUsedPhysRegsMask();
+
+  for (MCPhysReg Reg : X87PhysRegs)
+    if (!MRI.def_empty(Reg) || UsedPhysRegsMask.test(Reg))
+      return ArrayRef(X87PhysRegs);
+
+  return {};
+}
+
 const uint32_t *
 X86RegisterInfo::getCallPreservedMask(const MachineFunction &MF,
                                       CallingConv::ID CC) const {
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.h b/llvm/lib/Target/X86/X86RegisterInfo.h
index e646591663aca..8efa8dd79798a 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.h
+++ b/llvm/lib/Target/X86/X86RegisterInfo.h
@@ -99,6 +99,8 @@ class X86RegisterInfo final : public X86GenRegisterInfo {
   /// getIPRACSRegs - This API can be removed when rbp is safe to optimized out
   /// when IPRA is on.
   const MCPhysReg *getIPRACSRegs(const MachineFunction *MF) const override;
+  ArrayRef<MCPhysReg>
+  getIntraCallClobberedRegs(const MachineFunction *MF) const override;
   const MCPhysReg *
   getCalleeSavedRegsViaCopy(const MachineFunction *MF) const;
   const uint32_t *getCallPreservedMask(const MachineFunction &MF,
diff --git a/llvm/test/CodeGen/X86/ipra-x87-regmask.ll b/llvm/test/CodeGen/X86/ipra-x87-regmask.ll
new file mode 100644
index 0000000000000..d202fb9404a41
--- /dev/null
+++ b/llvm/test/CodeGen/X86/ipra-x87-regmask.ll
@@ -0,0 +1,34 @@
+; RUN: llc -enable-ipra -print-regusage -o /dev/null 2>&1 < %s | FileCheck %s
+
+; When any x87 register is touched, IPRA must treat the entire x87 FP stack as
+; clobbered (FP0-FP7, ST0-ST7), not just the individually used reg.
+
+
+; CHECK-LABEL: caller Clobbered Registers:
+; CHECK-SAME: $fp0
+; CHECK-SAME: $fp7
+define void @caller() #0 {
+  call void @uses_x87()
+  call void @no_x87()
+  ret void
+}
+
+
+; CHECK-LABEL: no_x87 Clobbered Registers:
+; CHECK-NOT: $fp0
+; CHECK-NOT: $st0
+define void @no_x87() #0 {
+  ret void
+}
+
+; CHECK-LABEL: uses_x87 Clobbered Registers:
+; CHECK-SAME: $fp0
+; CHECK-SAME: $fp7
+define void @uses_x87() #0 {
+  call void asm sideeffect "fld1", "~{fp0}"()
+  ret void
+}
+
+ at llvm.used = appending global [3 x ptr] [ptr @uses_x87, ptr @no_x87, ptr @caller]
+
+attributes #0 = { nounwind }



More information about the llvm-commits mailing list