[llvm] X86: Stop using MachineFunction in getPointerRegClass (PR #156880)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 10 03:09:36 PDT 2025
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/156880
>From 3a082be782d05f6e6c4210793ce5633129d4eff0 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 4 Sep 2025 14:44:56 +0900
Subject: [PATCH 1/6] X86: Stop using MachineFunction in getPointerRegClass
This should be a low level function used to interpret an
MCInstrDesc that only depends on the hwmode. It should not depend
on other dynamic context like the parent function. In general more
ABI properties like this should be expressed directly in the instruction
definitions, so introduce new TCRETURN pseudos to use with the special
case register classes (e.g. in a better future the callee saved registers
would always be encoded directly in a mask on the return instruction).
This will help unify X86 onto a pending replacement mechanism for
getPointerRegClass.
---
llvm/lib/Target/X86/X86AsmPrinter.cpp | 3 ++-
llvm/lib/Target/X86/X86ExpandPseudo.cpp | 7 +++++--
llvm/lib/Target/X86/X86FrameLowering.cpp | 3 ++-
llvm/lib/Target/X86/X86InstrCompiler.td | 10 +++++++++-
llvm/lib/Target/X86/X86InstrControl.td | 6 ++++++
llvm/lib/Target/X86/X86InstrPredicates.td | 6 ++++++
llvm/lib/Target/X86/X86RegisterInfo.cpp | 18 +++---------------
llvm/lib/Target/X86/X86RegisterInfo.h | 5 -----
8 files changed, 33 insertions(+), 25 deletions(-)
diff --git a/llvm/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp
index d406277e440bb..ff22ee8c86fac 100644
--- a/llvm/lib/Target/X86/X86AsmPrinter.cpp
+++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp
@@ -476,7 +476,8 @@ static bool isIndirectBranchOrTailCall(const MachineInstr &MI) {
return MI.getDesc().isIndirectBranch() /*Make below code in a good shape*/ ||
Opc == X86::TAILJMPr || Opc == X86::TAILJMPm ||
Opc == X86::TAILJMPr64 || Opc == X86::TAILJMPm64 ||
- Opc == X86::TCRETURNri || Opc == X86::TCRETURNmi ||
+ Opc == X86::TCRETURNri || Opc == X86::TCRETURN_WIN64ri ||
+ Opc == X86::TCRETURN_HIPE32ri || Opc == X86::TCRETURNmi ||
Opc == X86::TCRETURNri64 || Opc == X86::TCRETURNmi64 ||
Opc == X86::TCRETURNri64_ImpCall || Opc == X86::TAILJMPr64_REX ||
Opc == X86::TAILJMPm64_REX;
diff --git a/llvm/lib/Target/X86/X86ExpandPseudo.cpp b/llvm/lib/Target/X86/X86ExpandPseudo.cpp
index 0e6b4dffec3a6..9457e718de699 100644
--- a/llvm/lib/Target/X86/X86ExpandPseudo.cpp
+++ b/llvm/lib/Target/X86/X86ExpandPseudo.cpp
@@ -269,6 +269,8 @@ bool X86ExpandPseudo::expandMI(MachineBasicBlock &MBB,
case X86::TCRETURNdi:
case X86::TCRETURNdicc:
case X86::TCRETURNri:
+ case X86::TCRETURN_WIN64ri:
+ case X86::TCRETURN_HIPE32ri:
case X86::TCRETURNmi:
case X86::TCRETURNdi64:
case X86::TCRETURNdi64cc:
@@ -346,8 +348,9 @@ bool X86ExpandPseudo::expandMI(MachineBasicBlock &MBB,
MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(Op));
for (unsigned i = 0; i != X86::AddrNumOperands; ++i)
MIB.add(MBBI->getOperand(i));
- } else if ((Opcode == X86::TCRETURNri64) ||
- (Opcode == X86::TCRETURNri64_ImpCall)) {
+ } else if (Opcode == X86::TCRETURNri64 ||
+ Opcode == X86::TCRETURNri64_ImpCall ||
+ Opcode == X86::TCRETURN_WIN64ri) {
JumpTarget.setIsKill();
BuildMI(MBB, MBBI, DL,
TII->get(IsX64 ? X86::TAILJMPr64_REX : X86::TAILJMPr64))
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
index cba7843d53e3f..a293b4c87cfe4 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -2398,7 +2398,8 @@ X86FrameLowering::getWinEHFuncletFrameSize(const MachineFunction &MF) const {
}
static bool isTailCallOpcode(unsigned Opc) {
- return Opc == X86::TCRETURNri || Opc == X86::TCRETURNdi ||
+ return Opc == X86::TCRETURNri || Opc == X86::TCRETURN_WIN64ri ||
+ Opc == X86::TCRETURN_HIPE32ri || Opc == X86::TCRETURNdi ||
Opc == X86::TCRETURNmi || Opc == X86::TCRETURNri64 ||
Opc == X86::TCRETURNri64_ImpCall || Opc == X86::TCRETURNdi64 ||
Opc == X86::TCRETURNmi64;
diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td
index 927b2c8b22f05..734c488fe3159 100644
--- a/llvm/lib/Target/X86/X86InstrCompiler.td
+++ b/llvm/lib/Target/X86/X86InstrCompiler.td
@@ -1326,7 +1326,11 @@ def : Pat<(X86imp_call (i64 tglobaladdr:$dst)),
// Match an X86tcret that uses less than 7 volatile registers.
def : Pat<(X86tcret ptr_rc_tailcall:$dst, timm:$off),
(TCRETURNri ptr_rc_tailcall:$dst, timm:$off)>,
- Requires<[Not64BitMode, NotUseIndirectThunkCalls]>;
+ Requires<[Not64BitMode, IsNotHiPECCFunc, NotUseIndirectThunkCalls]>;
+
+def : Pat<(X86tcret GR32:$dst, timm:$off),
+ (TCRETURN_HIPE32ri GR32:$dst, timm:$off)>,
+ Requires<[Not64BitMode, IsHiPECCFunc, NotUseIndirectThunkCalls]>;
// FIXME: This is disabled for 32-bit PIC mode because the global base
// register which is part of the address mode may be assigned a
@@ -1344,6 +1348,10 @@ def : Pat<(X86tcret (i32 texternalsym:$dst), timm:$off),
(TCRETURNdi texternalsym:$dst, timm:$off)>,
Requires<[NotLP64]>;
+def : Pat<(X86tcret GR64_TCW64:$dst, timm:$off),
+ (TCRETURN_WIN64ri GR64_TCW64:$dst, timm:$off)>,
+ Requires<[In64BitMode, IsWin64CCFunc, NotUseIndirectThunkCalls]>;
+
def : Pat<(X86tcret ptr_rc_tailcall:$dst, timm:$off),
(TCRETURNri64 ptr_rc_tailcall:$dst, timm:$off)>,
Requires<[In64BitMode, NotUseIndirectThunkCalls, ImportCallOptimizationDisabled]>;
diff --git a/llvm/lib/Target/X86/X86InstrControl.td b/llvm/lib/Target/X86/X86InstrControl.td
index 22253bf0413a4..3acffe2a209fb 100644
--- a/llvm/lib/Target/X86/X86InstrControl.td
+++ b/llvm/lib/Target/X86/X86InstrControl.td
@@ -282,6 +282,12 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
[]>, Sched<[WriteJump]>;
def TCRETURNri : PseudoI<(outs), (ins ptr_rc_tailcall:$dst, i32imm:$offset),
[]>, Sched<[WriteJump]>;
+
+ def TCRETURN_WIN64ri : PseudoI<(outs), (ins GR64_TCW64:$dst, i32imm:$offset),
+ []>, Sched<[WriteJump]>;
+ def TCRETURN_HIPE32ri : PseudoI<(outs), (ins GR32:$dst, i32imm:$offset),
+ []>, Sched<[WriteJump]>;
+
let mayLoad = 1 in
def TCRETURNmi : PseudoI<(outs), (ins i32mem_TC:$dst, i32imm:$offset),
[]>, Sched<[WriteJumpLd]>;
diff --git a/llvm/lib/Target/X86/X86InstrPredicates.td b/llvm/lib/Target/X86/X86InstrPredicates.td
index 8a2846bcfdf34..5c82fb5bccb23 100644
--- a/llvm/lib/Target/X86/X86InstrPredicates.td
+++ b/llvm/lib/Target/X86/X86InstrPredicates.td
@@ -230,6 +230,12 @@ let RecomputePerFunction = 1 in {
"!Subtarget->hasSSE41()">;
def ImportCallOptimizationEnabled : Predicate<"MF->getFunction().getParent()->getModuleFlag(\"import-call-optimization\")">;
def ImportCallOptimizationDisabled : Predicate<"!MF->getFunction().getParent()->getModuleFlag(\"import-call-optimization\")">;
+
+ def IsWin64CCFunc : Predicate<"MF->getFunction().getCallingConv() == CallingConv::Win64">;
+ def IsHiPECCFunc : Predicate<"MF->getFunction().getCallingConv() == CallingConv::HiPE">;
+
+ def IsNotHiPECCFunc : Predicate<
+ "MF->getFunction().getCallingConv() != CallingConv::HiPE">;
}
def CallImmAddr : Predicate<"Subtarget->isLegalToCallImmediateAddr()">;
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp
index edba313c25df8..9ec04e740a08b 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.cpp
+++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp
@@ -220,24 +220,10 @@ X86RegisterInfo::getPointerRegClass(const MachineFunction &MF,
// NOSP does not contain RIP, so no special case here.
return &X86::GR32_NOREX_NOSPRegClass;
case 4: // Available for tailcall (not callee-saved GPRs).
- return getGPRsForTailCall(MF);
+ return Is64Bit ? &X86::GR64_TCRegClass : &X86::GR32_TCRegClass;
}
}
-const TargetRegisterClass *
-X86RegisterInfo::getGPRsForTailCall(const MachineFunction &MF) const {
- const Function &F = MF.getFunction();
- if (IsWin64 || IsUEFI64 || (F.getCallingConv() == CallingConv::Win64))
- return &X86::GR64_TCW64RegClass;
- else if (Is64Bit)
- return &X86::GR64_TCRegClass;
-
- bool hasHipeCC = (F.getCallingConv() == CallingConv::HiPE);
- if (hasHipeCC)
- return &X86::GR32RegClass;
- return &X86::GR32_TCRegClass;
-}
-
const TargetRegisterClass *
X86RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const {
if (RC == &X86::CCRRegClass) {
@@ -1017,6 +1003,8 @@ unsigned X86RegisterInfo::findDeadCallerSavedReg(
case X86::RETI64:
case X86::TCRETURNdi:
case X86::TCRETURNri:
+ case X86::TCRETURN_WIN64ri:
+ case X86::TCRETURN_HIPE32ri:
case X86::TCRETURNmi:
case X86::TCRETURNdi64:
case X86::TCRETURNri64:
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.h b/llvm/lib/Target/X86/X86RegisterInfo.h
index 2f4c55cfad6d2..d022e5ab87945 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.h
+++ b/llvm/lib/Target/X86/X86RegisterInfo.h
@@ -87,11 +87,6 @@ class X86RegisterInfo final : public X86GenRegisterInfo {
const TargetRegisterClass *
getCrossCopyRegClass(const TargetRegisterClass *RC) const override;
- /// getGPRsForTailCall - Returns a register class with registers that can be
- /// used in forming tail calls.
- const TargetRegisterClass *
- getGPRsForTailCall(const MachineFunction &MF) const;
-
unsigned getRegPressureLimit(const TargetRegisterClass *RC,
MachineFunction &MF) const override;
>From fac6165459511ba3eabd634b2a78a265826f9de3 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 10 Sep 2025 07:56:46 +0900
Subject: [PATCH 2/6] Adjust win64cc condition
---
llvm/lib/Target/X86/X86InstrPredicates.td | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/X86/X86InstrPredicates.td b/llvm/lib/Target/X86/X86InstrPredicates.td
index 5c82fb5bccb23..472296a226ddb 100644
--- a/llvm/lib/Target/X86/X86InstrPredicates.td
+++ b/llvm/lib/Target/X86/X86InstrPredicates.td
@@ -231,7 +231,7 @@ let RecomputePerFunction = 1 in {
def ImportCallOptimizationEnabled : Predicate<"MF->getFunction().getParent()->getModuleFlag(\"import-call-optimization\")">;
def ImportCallOptimizationDisabled : Predicate<"!MF->getFunction().getParent()->getModuleFlag(\"import-call-optimization\")">;
- def IsWin64CCFunc : Predicate<"MF->getFunction().getCallingConv() == CallingConv::Win64">;
+ def IsWin64CCFunc : Predicate<"Subtarget->isCallingConvWin64(MF->getFunction().getCallingConv())">;
def IsHiPECCFunc : Predicate<"MF->getFunction().getCallingConv() == CallingConv::HiPE">;
def IsNotHiPECCFunc : Predicate<
>From eada1f2be94fc4c28180be14df2970eb6b574a83 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 10 Sep 2025 18:49:05 +0900
Subject: [PATCH 3/6] Fix using esp instead of rsp on TCRETURN_WIN64ri
---
llvm/lib/Target/X86/X86InstrControl.td | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/X86/X86InstrControl.td b/llvm/lib/Target/X86/X86InstrControl.td
index 3acffe2a209fb..139aedd473ebc 100644
--- a/llvm/lib/Target/X86/X86InstrControl.td
+++ b/llvm/lib/Target/X86/X86InstrControl.td
@@ -283,8 +283,6 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
def TCRETURNri : PseudoI<(outs), (ins ptr_rc_tailcall:$dst, i32imm:$offset),
[]>, Sched<[WriteJump]>;
- def TCRETURN_WIN64ri : PseudoI<(outs), (ins GR64_TCW64:$dst, i32imm:$offset),
- []>, Sched<[WriteJump]>;
def TCRETURN_HIPE32ri : PseudoI<(outs), (ins GR32:$dst, i32imm:$offset),
[]>, Sched<[WriteJump]>;
@@ -363,6 +361,9 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
def TCRETURNri64 : PseudoI<(outs),
(ins ptr_rc_tailcall:$dst, i32imm:$offset),
[]>, Sched<[WriteJump]>;
+ def TCRETURN_WIN64ri : PseudoI<(outs), (ins GR64_TCW64:$dst, i32imm:$offset),
+ []>, Sched<[WriteJump]>;
+
def TCRETURNri64_ImpCall : PseudoI<(outs),
(ins GR64_A:$dst, i32imm:$offset),
[]>, Sched<[WriteJump]>;
>From 03995ff699ca6a81cadf513793990a52335b0696 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 10 Sep 2025 19:06:54 +0900
Subject: [PATCH 4/6] Add ImportCallOptimizationDisabled to TCRETURN_WIN64ri
predicates
---
llvm/lib/Target/X86/X86InstrCompiler.td | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td
index 734c488fe3159..c64ea80612b11 100644
--- a/llvm/lib/Target/X86/X86InstrCompiler.td
+++ b/llvm/lib/Target/X86/X86InstrCompiler.td
@@ -1350,7 +1350,7 @@ def : Pat<(X86tcret (i32 texternalsym:$dst), timm:$off),
def : Pat<(X86tcret GR64_TCW64:$dst, timm:$off),
(TCRETURN_WIN64ri GR64_TCW64:$dst, timm:$off)>,
- Requires<[In64BitMode, IsWin64CCFunc, NotUseIndirectThunkCalls]>;
+ Requires<[In64BitMode, IsWin64CCFunc, NotUseIndirectThunkCalls, ImportCallOptimizationDisabled]>;
def : Pat<(X86tcret ptr_rc_tailcall:$dst, timm:$off),
(TCRETURNri64 ptr_rc_tailcall:$dst, timm:$off)>,
>From ab287b3891b1c5e1e8b98ac6fca0cfc837d3b53b Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 10 Sep 2025 19:07:28 +0900
Subject: [PATCH 5/6] Remove redundant In64BitMode predicate
---
llvm/lib/Target/X86/X86InstrCompiler.td | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td
index c64ea80612b11..34610c21d991c 100644
--- a/llvm/lib/Target/X86/X86InstrCompiler.td
+++ b/llvm/lib/Target/X86/X86InstrCompiler.td
@@ -1350,7 +1350,7 @@ def : Pat<(X86tcret (i32 texternalsym:$dst), timm:$off),
def : Pat<(X86tcret GR64_TCW64:$dst, timm:$off),
(TCRETURN_WIN64ri GR64_TCW64:$dst, timm:$off)>,
- Requires<[In64BitMode, IsWin64CCFunc, NotUseIndirectThunkCalls, ImportCallOptimizationDisabled]>;
+ Requires<[IsWin64CCFunc, NotUseIndirectThunkCalls, ImportCallOptimizationDisabled]>;
def : Pat<(X86tcret ptr_rc_tailcall:$dst, timm:$off),
(TCRETURNri64 ptr_rc_tailcall:$dst, timm:$off)>,
>From df38881964356686bb43bfca7afb77eac47793ed Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 10 Sep 2025 19:09:02 +0900
Subject: [PATCH 6/6] Move win64 pattern after base case
---
llvm/lib/Target/X86/X86InstrCompiler.td | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td
index 34610c21d991c..e22c9956c34c2 100644
--- a/llvm/lib/Target/X86/X86InstrCompiler.td
+++ b/llvm/lib/Target/X86/X86InstrCompiler.td
@@ -1348,14 +1348,14 @@ def : Pat<(X86tcret (i32 texternalsym:$dst), timm:$off),
(TCRETURNdi texternalsym:$dst, timm:$off)>,
Requires<[NotLP64]>;
-def : Pat<(X86tcret GR64_TCW64:$dst, timm:$off),
- (TCRETURN_WIN64ri GR64_TCW64:$dst, timm:$off)>,
- Requires<[IsWin64CCFunc, NotUseIndirectThunkCalls, ImportCallOptimizationDisabled]>;
-
def : Pat<(X86tcret ptr_rc_tailcall:$dst, timm:$off),
(TCRETURNri64 ptr_rc_tailcall:$dst, timm:$off)>,
Requires<[In64BitMode, NotUseIndirectThunkCalls, ImportCallOptimizationDisabled]>;
+def : Pat<(X86tcret GR64_TCW64:$dst, timm:$off),
+ (TCRETURN_WIN64ri GR64_TCW64:$dst, timm:$off)>,
+ Requires<[IsWin64CCFunc, NotUseIndirectThunkCalls, ImportCallOptimizationDisabled]>;
+
def : Pat<(X86tcret ptr_rc_tailcall:$dst, timm:$off),
(TCRETURNri64_ImpCall ptr_rc_tailcall:$dst, timm:$off)>,
Requires<[In64BitMode, NotUseIndirectThunkCalls, ImportCallOptimizationEnabled]>;
More information about the llvm-commits
mailing list