[llvm] 2654b51 - X86: Switch to RegClassByHwMode (#158274)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 19 06:42:04 PDT 2025
Author: Matt Arsenault
Date: 2025-09-19T13:42:00Z
New Revision: 2654b511fea7f5e6d56bdf6f1923c7b9f1899542
URL: https://github.com/llvm/llvm-project/commit/2654b511fea7f5e6d56bdf6f1923c7b9f1899542
DIFF: https://github.com/llvm/llvm-project/commit/2654b511fea7f5e6d56bdf6f1923c7b9f1899542.diff
LOG: X86: Switch to RegClassByHwMode (#158274)
Replace the target uses of PointerLikeRegClass with RegClassByHwMode
Added:
Modified:
llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
llvm/lib/Target/X86/X86.td
llvm/lib/Target/X86/X86InstrInfo.td
llvm/lib/Target/X86/X86InstrOperands.td
llvm/lib/Target/X86/X86InstrPredicates.td
llvm/lib/Target/X86/X86RegisterInfo.cpp
llvm/lib/Target/X86/X86Subtarget.h
llvm/utils/TableGen/X86FoldTablesEmitter.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
index d8cb4eacf905c..1c06dc4923c2d 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
@@ -55,6 +55,9 @@ std::string X86_MC::ParseX86Triple(const Triple &TT) {
else
FS = "-64bit-mode,-32bit-mode,+16bit-mode";
+ if (TT.isX32())
+ FS += ",+x32";
+
return FS;
}
diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td
index 7c9e821c02fda..3af8b3e060a16 100644
--- a/llvm/lib/Target/X86/X86.td
+++ b/llvm/lib/Target/X86/X86.td
@@ -25,6 +25,8 @@ def Is32Bit : SubtargetFeature<"32bit-mode", "Is32Bit", "true",
"32-bit mode (80386)">;
def Is16Bit : SubtargetFeature<"16bit-mode", "Is16Bit", "true",
"16-bit mode (i8086)">;
+def IsX32 : SubtargetFeature<"x32", "IsX32", "true",
+ "64-bit with ILP32 programming model (e.g. x32 ABI)">;
//===----------------------------------------------------------------------===//
// X86 Subtarget ISA features
diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td
index 7f6c5614847e3..0c4abc2c400f6 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.td
+++ b/llvm/lib/Target/X86/X86InstrInfo.td
@@ -18,14 +18,14 @@ include "X86InstrFragments.td"
include "X86InstrFragmentsSIMD.td"
//===----------------------------------------------------------------------===//
-// X86 Operand Definitions.
+// X86 Predicate Definitions.
//
-include "X86InstrOperands.td"
+include "X86InstrPredicates.td"
//===----------------------------------------------------------------------===//
-// X86 Predicate Definitions.
+// X86 Operand Definitions.
//
-include "X86InstrPredicates.td"
+include "X86InstrOperands.td"
//===----------------------------------------------------------------------===//
// X86 Instruction Format Definitions.
diff --git a/llvm/lib/Target/X86/X86InstrOperands.td b/llvm/lib/Target/X86/X86InstrOperands.td
index 80843f6bb80e6..5207ecad127a2 100644
--- a/llvm/lib/Target/X86/X86InstrOperands.td
+++ b/llvm/lib/Target/X86/X86InstrOperands.td
@@ -6,9 +6,15 @@
//
//===----------------------------------------------------------------------===//
+def x86_ptr_rc : RegClassByHwMode<
+ [X86_32, X86_64, X86_64_X32],
+ [GR32, GR64, LOW32_ADDR_ACCESS]>;
+
// A version of ptr_rc which excludes SP, ESP, and RSP. This is used for
// the index operand of an address, to conform to x86 encoding restrictions.
-def ptr_rc_nosp : PointerLikeRegClass<1>;
+def ptr_rc_nosp : RegClassByHwMode<
+ [X86_32, X86_64, X86_64_X32],
+ [GR32_NOSP, GR64_NOSP, GR32_NOSP]>;
// *mem - Operand definitions for the funky X86 addressing mode operands.
//
@@ -53,7 +59,7 @@ class X86MemOperand<string printMethod,
AsmOperandClass parserMatchClass = X86MemAsmOperand,
int size = 0> : Operand<iPTR> {
let PrintMethod = printMethod;
- let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, SEGMENT_REG);
+ let MIOperandInfo = (ops x86_ptr_rc, i8imm, ptr_rc_nosp, i32imm, SEGMENT_REG);
let ParserMatchClass = parserMatchClass;
let OperandType = "OPERAND_MEMORY";
int Size = size;
@@ -63,7 +69,7 @@ class X86MemOperand<string printMethod,
class X86VMemOperand<RegisterClass RC, string printMethod,
AsmOperandClass parserMatchClass, int size = 0>
: X86MemOperand<printMethod, parserMatchClass, size> {
- let MIOperandInfo = (ops ptr_rc, i8imm, RC, i32imm, SEGMENT_REG);
+ let MIOperandInfo = (ops x86_ptr_rc, i8imm, RC, i32imm, SEGMENT_REG);
}
def anymem : X86MemOperand<"printMemReference">;
@@ -113,8 +119,14 @@ def sdmem : X86MemOperand<"printqwordmem", X86Mem64AsmOperand>;
// A version of i8mem for use on x86-64 and x32 that uses a NOREX GPR instead
// of a plain GPR, so that it doesn't potentially require a REX prefix.
-def ptr_rc_norex : PointerLikeRegClass<2>;
-def ptr_rc_norex_nosp : PointerLikeRegClass<3>;
+def ptr_rc_norex : RegClassByHwMode<
+ [X86_32, X86_64, X86_64_X32],
+ [GR32_NOREX, GR64_NOREX, GR32_NOREX]>;
+
+def ptr_rc_norex_nosp : RegClassByHwMode<
+ [X86_32, X86_64, X86_64_X32],
+ [GR32_NOREX_NOSP, GR64_NOREX_NOSP, GR32_NOREX_NOSP]>;
+
def i8mem_NOREX : X86MemOperand<"printbytemem", X86Mem8AsmOperand, 8> {
let MIOperandInfo = (ops ptr_rc_norex, i8imm, ptr_rc_norex_nosp, i32imm,
@@ -123,7 +135,9 @@ def i8mem_NOREX : X86MemOperand<"printbytemem", X86Mem8AsmOperand, 8> {
// GPRs available for tailcall.
// It represents GR32_TC, GR64_TC or GR64_TCW64.
-def ptr_rc_tailcall : PointerLikeRegClass<4>;
+def ptr_rc_tailcall : RegClassByHwMode<
+ [X86_32, X86_64, X86_64_X32],
+ [GR32_TC, GR64_TC, GR64_TC]>;
// Special i32mem for addresses of load folding tail calls. These are not
// allowed to use callee-saved registers since they must be scheduled
@@ -270,12 +284,12 @@ let RenderMethod = "addMemOffsOperands" in {
class X86SrcIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
: X86MemOperand<printMethod, parserMatchClass> {
- let MIOperandInfo = (ops ptr_rc, SEGMENT_REG);
+ let MIOperandInfo = (ops x86_ptr_rc, SEGMENT_REG);
}
class X86DstIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
: X86MemOperand<printMethod, parserMatchClass> {
- let MIOperandInfo = (ops ptr_rc);
+ let MIOperandInfo = (ops x86_ptr_rc);
}
def srcidx8 : X86SrcIdxOperand<"printSrcIdx8", X86SrcIdx8Operand>;
diff --git a/llvm/lib/Target/X86/X86InstrPredicates.td b/llvm/lib/Target/X86/X86InstrPredicates.td
index 8339c2081842d..c20bb05018b4d 100644
--- a/llvm/lib/Target/X86/X86InstrPredicates.td
+++ b/llvm/lib/Target/X86/X86InstrPredicates.td
@@ -195,6 +195,12 @@ def Not64BitMode : Predicate<"!Subtarget->is64Bit()">,
AssemblerPredicate<(all_of (not Is64Bit)), "Not 64-bit mode">;
def In64BitMode : Predicate<"Subtarget->is64Bit()">,
AssemblerPredicate<(all_of Is64Bit), "64-bit mode">;
+
+def IsX32Mode : Predicate<"Subtarget->getTargetTriple().isX32()">,
+ AssemblerPredicate<(all_of IsX32), "x32 ABI">;
+def NotX32Mode : Predicate<"!Subtarget->getTargetTriple().isX32()">,
+ AssemblerPredicate<(all_of (not IsX32)), "not x32 ABI">;
+
def IsLP64 : Predicate<"Subtarget->isTarget64BitLP64()">;
def NotLP64 : Predicate<"!Subtarget->isTarget64BitLP64()">;
def In16BitMode : Predicate<"Subtarget->is16Bit()">,
@@ -250,3 +256,11 @@ def HasMFence : Predicate<"Subtarget->hasMFence()">;
def HasFastDPWSSD: Predicate<"Subtarget->hasFastDPWSSD()">;
def UseIndirectThunkCalls : Predicate<"Subtarget->useIndirectThunkCalls()">;
def NotUseIndirectThunkCalls : Predicate<"!Subtarget->useIndirectThunkCalls()">;
+
+//===----------------------------------------------------------------------===//
+// HwModes
+//===----------------------------------------------------------------------===//
+
+defvar X86_32 = DefaultMode;
+def X86_64 : HwMode<[In64BitMode, NotX32Mode]>;
+def X86_64_X32 : HwMode<[IsX32Mode]>;
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp
index 6ba1076dbaa6c..76979e37c4618 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.cpp
+++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp
@@ -194,33 +194,14 @@ X86RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
const TargetRegisterClass *
X86RegisterInfo::getPointerRegClass(unsigned Kind) const {
- switch (Kind) {
- default: llvm_unreachable("Unexpected Kind in getPointerRegClass!");
- case 0: // Normal GPRs.
- if (IsTarget64BitLP64)
- return &X86::GR64RegClass;
- // If the target is 64bit but we have been told to use 32bit addresses,
- // we can still use 64-bit register as long as we know the high bits
- // are zeros.
- // Reflect that in the returned register class.
- return Is64Bit ? &X86::LOW32_ADDR_ACCESSRegClass : &X86::GR32RegClass;
- case 1: // Normal GPRs except the stack pointer (for encoding reasons).
- if (IsTarget64BitLP64)
- return &X86::GR64_NOSPRegClass;
- // NOSP does not contain RIP, so no special case here.
- return &X86::GR32_NOSPRegClass;
- case 2: // NOREX GPRs.
- if (IsTarget64BitLP64)
- return &X86::GR64_NOREXRegClass;
- return &X86::GR32_NOREXRegClass;
- case 3: // NOREX GPRs except the stack pointer (for encoding reasons).
- if (IsTarget64BitLP64)
- return &X86::GR64_NOREX_NOSPRegClass;
- // 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 Is64Bit ? &X86::GR64_TCRegClass : &X86::GR32_TCRegClass;
- }
+ assert(Kind == 0 && "this should only be used for default cases");
+ if (IsTarget64BitLP64)
+ return &X86::GR64RegClass;
+ // If the target is 64bit but we have been told to use 32bit addresses,
+ // we can still use 64-bit register as long as we know the high bits
+ // are zeros.
+ // Reflect that in the returned register class.
+ return Is64Bit ? &X86::LOW32_ADDR_ACCESSRegClass : &X86::GR32RegClass;
}
const TargetRegisterClass *
diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h
index fa3f3b59741df..a8802c4bf164d 100644
--- a/llvm/lib/Target/X86/X86Subtarget.h
+++ b/llvm/lib/Target/X86/X86Subtarget.h
@@ -170,10 +170,10 @@ class X86Subtarget final : public X86GenSubtargetInfo {
#include "X86GenSubtargetInfo.inc"
/// Is this x86_64 with the ILP32 programming model (x32 ABI)?
- bool isTarget64BitILP32() const { return Is64Bit && (TargetTriple.isX32()); }
+ bool isTarget64BitILP32() const { return Is64Bit && IsX32; }
/// Is this x86_64 with the LP64 programming model (standard AMD64, no x32)?
- bool isTarget64BitLP64() const { return Is64Bit && (!TargetTriple.isX32()); }
+ bool isTarget64BitLP64() const { return Is64Bit && !IsX32; }
PICStyles::Style getPICStyle() const { return PICStyle; }
void setPICStyle(PICStyles::Style Style) { PICStyle = Style; }
diff --git a/llvm/utils/TableGen/X86FoldTablesEmitter.cpp b/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
index b1f7b9a6b4ad9..1e1e4ab650030 100644
--- a/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
+++ b/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
@@ -553,10 +553,10 @@ void X86FoldTablesEmitter::updateTables(const CodeGenInstruction *RegInst,
for (unsigned I = RegOutSize, E = RegInst->Operands.size(); I < E; I++) {
const Record *RegOpRec = RegInst->Operands[I].Rec;
const Record *MemOpRec = MemInst->Operands[I].Rec;
- // PointerLikeRegClass: For instructions like TAILJMPr, TAILJMPr64,
+ // RegClassByHwMode: For instructions like TAILJMPr, TAILJMPr64,
// TAILJMPr64_REX
if ((isRegisterOperand(RegOpRec) ||
- RegOpRec->isSubClassOf("PointerLikeRegClass")) &&
+ (RegOpRec->isSubClassOf("RegClassByHwMode"))) &&
isMemoryOperand(MemOpRec)) {
switch (I) {
case 0:
More information about the llvm-commits
mailing list