Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NFC][X86] Reorder the registers to reduce unnecessary iterations #70222

Merged
merged 8 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions llvm/include/llvm/CodeGen/LiveVariables.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ class LiveVariables : public MachineFunctionPass {
bool HandlePhysRegKill(Register Reg, MachineInstr *MI);

/// HandleRegMask - Call HandlePhysRegKill for all registers clobbered by Mask.
void HandleRegMask(const MachineOperand&);
void HandleRegMask(const MachineOperand &, unsigned);

void HandlePhysRegUse(Register Reg, MachineInstr &MI);
void HandlePhysRegDef(Register Reg, MachineInstr *MI,
Expand All @@ -170,7 +170,8 @@ class LiveVariables : public MachineFunctionPass {
/// is coming from.
void analyzePHINodes(const MachineFunction& Fn);

void runOnInstr(MachineInstr &MI, SmallVectorImpl<unsigned> &Defs);
void runOnInstr(MachineInstr &MI, SmallVectorImpl<unsigned> &Defs,
unsigned NumRegs);

void runOnBlock(MachineBasicBlock *MBB, unsigned NumRegs);
public:
Expand Down
5 changes: 5 additions & 0 deletions llvm/include/llvm/CodeGen/TargetRegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,11 @@ class TargetRegisterInfo : public MCRegisterInfo {
virtual ~TargetRegisterInfo();

public:
/// Return the number of registers for the function. (may overestimate)
virtual unsigned getNumSupportedRegs(const MachineFunction &) const {
return getNumRegs();
}

// Register numbers can represent physical registers, virtual registers, and
// sometimes stack slots. The unsigned values are divided into these ranges:
//
Expand Down
5 changes: 5 additions & 0 deletions llvm/include/llvm/TableGen/Record.h
Original file line number Diff line number Diff line change
Expand Up @@ -2154,6 +2154,11 @@ struct LessRecordRegister {
};

bool operator()(const Record *Rec1, const Record *Rec2) const {
int64_t LHSPositionOrder = Rec1->getValueAsInt("PositionOrder");
int64_t RHSPositionOrder = Rec2->getValueAsInt("PositionOrder");
if (LHSPositionOrder != RHSPositionOrder)
return LHSPositionOrder < RHSPositionOrder;

RecordParts LHSParts(StringRef(Rec1->getName()));
RecordParts RHSParts(StringRef(Rec2->getName()));

Expand Down
8 changes: 8 additions & 0 deletions llvm/include/llvm/Target/Target.td
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,10 @@ class Register<string n, list<string> altNames = []> {
// isConstant - This register always holds a constant value (e.g. the zero
// register in architectures such as MIPS)
bit isConstant = false;

/// PositionOrder - Indicate tablegen to place the newly added register at a later
/// position to avoid iterations on them on unsupported target.
int PositionOrder = 0;
}

// RegisterWithSubRegs - This can be used to define instances of Register which
Expand Down Expand Up @@ -417,6 +421,10 @@ class RegisterTuples<list<SubRegIndex> Indices, list<dag> Regs,

// List of asm names for the generated tuple registers.
list<string> RegAsmNames = RegNames;

// PositionOrder - Indicate tablegen to place the newly added register at a later
// position to avoid iterations on them on unsupported target.
int PositionOrder = 0;
}

// RegisterCategory - This class is a list of RegisterClasses that belong to a
Expand Down
18 changes: 10 additions & 8 deletions llvm/lib/CodeGen/LiveVariables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,11 +406,11 @@ bool LiveVariables::HandlePhysRegKill(Register Reg, MachineInstr *MI) {
return true;
}

void LiveVariables::HandleRegMask(const MachineOperand &MO) {
void LiveVariables::HandleRegMask(const MachineOperand &MO, unsigned NumRegs) {
// Call HandlePhysRegKill() for all live registers clobbered by Mask.
// Clobbered registers are always dead, sp there is no need to use
// HandlePhysRegDef().
for (unsigned Reg = 1, NumRegs = TRI->getNumRegs(); Reg != NumRegs; ++Reg) {
for (unsigned Reg = 1; Reg != NumRegs; ++Reg) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to take a step back.

Have you tried checking MRI->isReserved(Reg) here? Does that do anything to improve compile time?

Where is the time spent?

Am I reading this right, that it calls HandlePhysRegKill on the super register anytime it finds one of the subregisters is clobbered? Even if its already called it before?

Copy link
Contributor Author

@KanRobert KanRobert Oct 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did an analysis on the spent time there #67702 (comment).

The extra time is spent on iterations over the new registers and new register classes. LiveVariables is one of the passes with the greatest impact b/c it iterates them for each basic block. Besides, for LiveVariables and some other passes, the new registers make a bigger regmask and regset, and then operations on the regmask and regset take more time too, including allocation and loopup, etc.

MRI->isReserved(Reg)? I think it's a AArch64 function only and even not used by X86 at all.

Am I reading this right, that it calls HandlePhysRegKill on the super register anytime it finds one of the subregisters is clobbered? Even if its already called it before?

My understanding is same as yours.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MRI->isReserved(Reg) doesn't use the information from X86RegisterInfo::getReservedRegs?

Copy link
Contributor Author

@KanRobert KanRobert Oct 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I misunderstood your idea...

diff --git a/llvm/lib/CodeGen/LiveVariables.cpp b/llvm/lib/CodeGen/LiveVariables.cpp
index 6b983b6320c7..44e127151004 100644
--- a/llvm/lib/CodeGen/LiveVariables.cpp
+++ b/llvm/lib/CodeGen/LiveVariables.cpp
@@ -411,6 +411,9 @@ void LiveVariables::HandleRegMask(const MachineOperand &MO) {
   // Clobbered registers are always dead, sp there is no need to use
   // HandlePhysRegDef().
   for (unsigned Reg = 1, NumRegs = TRI->getNumRegs(); Reg != NumRegs; ++Reg) {
+    // Skip reserved regs.
+    if (MRI->isReserved(Reg))
+      continue;
     // Skip dead regs.
     if (!PhysRegDef[Reg] && !PhysRegUse[Reg])
       continue;

After testing, I find checking MRI->isReserved(Reg) does not improve compile time, instead, it will bring 0.2% instruction count regression.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did an analysis on the spent time there #67702 (comment).

The extra time is spent on iterations over the new registers and new register classes. LiveVariables is one of the passes with the greatest impact b/c it iterates them for each basic block. Besides, for LiveVariables and some other passes, the new registers make a bigger regmask and regset, and then operations on the regmask and regset take more time too, including allocation and loopup, etc.

FYI LiveVariables is deprecated and we should work towards getting rid of it. LiveIntervals has been the replacement for ages

Copy link
Contributor Author

@KanRobert KanRobert Oct 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by "deprecated"? I see this function is still called when compiling workloads.
And according to the comment #67702 (comment) , we have not got rid of LiveVariables completely

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As in all uses of it should be removed and replaced with LiveIntervals. You still see it because nobody ever completed the work to remove it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. But currently LiveVariables brings about 0.3% instruction count regression when I introduce new registers in #67702. If the regression is intolerable, then it will block my APX enabling work. I have to resolve it to before the migration is complete.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How much work is left to remove LIveVariables?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jayfoad commented in #67702. I believe he/she knows more about that than me.

// Skip dead regs.
if (!PhysRegDef[Reg] && !PhysRegUse[Reg])
continue;
Expand All @@ -421,7 +421,8 @@ void LiveVariables::HandleRegMask(const MachineOperand &MO) {
// This avoids needless implicit operands.
unsigned Super = Reg;
for (MCPhysReg SR : TRI->superregs(Reg))
if ((PhysRegDef[SR] || PhysRegUse[SR]) && MO.clobbersPhysReg(SR))
if (SR < NumRegs && (PhysRegDef[SR] || PhysRegUse[SR]) &&
MO.clobbersPhysReg(SR))
Super = SR;
HandlePhysRegKill(Super, nullptr);
}
Expand Down Expand Up @@ -478,7 +479,8 @@ void LiveVariables::UpdatePhysRegDefs(MachineInstr &MI,
}

void LiveVariables::runOnInstr(MachineInstr &MI,
SmallVectorImpl<unsigned> &Defs) {
SmallVectorImpl<unsigned> &Defs,
unsigned NumRegs) {
assert(!MI.isDebugOrPseudoInstr());
// Process all of the operands of the instruction...
unsigned NumOperandsToProcess = MI.getNumOperands();
Expand Down Expand Up @@ -527,7 +529,7 @@ void LiveVariables::runOnInstr(MachineInstr &MI,

// Process all masked registers. (Call clobbers).
for (unsigned Mask : RegMasks)
HandleRegMask(MI.getOperand(Mask));
HandleRegMask(MI.getOperand(Mask), NumRegs);

// Process all defs.
for (unsigned MOReg : DefRegs) {
Expand All @@ -539,7 +541,7 @@ void LiveVariables::runOnInstr(MachineInstr &MI,
UpdatePhysRegDefs(MI, Defs);
}

void LiveVariables::runOnBlock(MachineBasicBlock *MBB, const unsigned NumRegs) {
void LiveVariables::runOnBlock(MachineBasicBlock *MBB, unsigned NumRegs) {
// Mark live-in registers as live-in.
SmallVector<unsigned, 4> Defs;
for (const auto &LI : MBB->liveins()) {
Expand All @@ -556,7 +558,7 @@ void LiveVariables::runOnBlock(MachineBasicBlock *MBB, const unsigned NumRegs) {
continue;
DistanceMap.insert(std::make_pair(&MI, Dist++));

runOnInstr(MI, Defs);
runOnInstr(MI, Defs, NumRegs);
}

// Handle any virtual assignments from PHI nodes which might be at the
Expand Down Expand Up @@ -597,7 +599,7 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
MRI = &mf.getRegInfo();
TRI = MF->getSubtarget().getRegisterInfo();

const unsigned NumRegs = TRI->getNumRegs();
const unsigned NumRegs = TRI->getNumSupportedRegs(mf);
PhysRegDef.assign(NumRegs, nullptr);
PhysRegUse.assign(NumRegs, nullptr);
PHIVarInfo.resize(MF->getNumBlockIDs());
Expand Down
16 changes: 8 additions & 8 deletions llvm/lib/Target/X86/AsmParser/X86Operand.h
Original file line number Diff line number Diff line change
Expand Up @@ -357,28 +357,28 @@ struct X86Operand final : public MCParsedAsmOperand {
}

bool isMem64_RC128X() const {
return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM31);
return isMem64() && X86II::isXMMReg(Mem.IndexReg);
}
bool isMem128_RC128X() const {
return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM31);
return isMem128() && X86II::isXMMReg(Mem.IndexReg);
}
bool isMem128_RC256X() const {
return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM31);
return isMem128() && X86II::isYMMReg(Mem.IndexReg);
}
bool isMem256_RC128X() const {
return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM31);
return isMem256() && X86II::isXMMReg(Mem.IndexReg);
}
bool isMem256_RC256X() const {
return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM31);
return isMem256() && X86II::isYMMReg(Mem.IndexReg);
}
bool isMem256_RC512() const {
return isMem256() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
return isMem256() && X86II::isZMMReg(Mem.IndexReg);
}
bool isMem512_RC256X() const {
return isMem512() && isMemIndexReg(X86::YMM0, X86::YMM31);
return isMem512() && X86II::isYMMReg(Mem.IndexReg);
}
bool isMem512_RC512() const {
return isMem512() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
return isMem512() && X86II::isZMMReg(Mem.IndexReg);
}
bool isMem512_GR16() const {
if (!isMem512())
Expand Down
32 changes: 30 additions & 2 deletions llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1182,11 +1182,39 @@ namespace X86II {
}
}

/// \returns true if the register is a XMM.
inline bool isXMMReg(unsigned RegNo) {
KanRobert marked this conversation as resolved.
Show resolved Hide resolved
assert(X86::XMM15 - X86::XMM0 == 15 &&
"XMM0-15 registers are not continuous");
assert(X86::XMM31 - X86::XMM16 == 15 &&
"XMM16-31 registers are not continuous");
return (RegNo >= X86::XMM0 && RegNo <= X86::XMM15) ||
KanRobert marked this conversation as resolved.
Show resolved Hide resolved
(RegNo >= X86::XMM16 && RegNo <= X86::XMM31);
}

/// \returns true if the register is a YMM.
inline bool isYMMReg(unsigned RegNo) {
assert(X86::YMM15 - X86::YMM0 == 15 &&
"YMM0-15 registers are not continuous");
assert(X86::YMM31 - X86::YMM16 == 15 &&
"YMM16-31 registers are not continuous");
return (RegNo >= X86::YMM0 && RegNo <= X86::YMM15) ||
(RegNo >= X86::YMM16 && RegNo <= X86::YMM31);
}

/// \returns true if the register is a ZMM.
inline bool isZMMReg(unsigned RegNo) {
assert(X86::ZMM31 - X86::ZMM0 == 31 && "ZMM registers are not continuous");
return RegNo >= X86::ZMM0 && RegNo <= X86::ZMM31;
}

/// \returns true if the MachineOperand is a x86-64 extended (r8 or
/// higher) register, e.g. r8, xmm8, xmm13, etc.
inline bool isX86_64ExtendedReg(unsigned RegNo) {
if ((RegNo >= X86::XMM8 && RegNo <= X86::XMM31) ||
(RegNo >= X86::YMM8 && RegNo <= X86::YMM31) ||
if ((RegNo >= X86::XMM8 && RegNo <= X86::XMM15) ||
(RegNo >= X86::XMM16 && RegNo <= X86::XMM31) ||
(RegNo >= X86::YMM8 && RegNo <= X86::YMM15) ||
(RegNo >= X86::YMM16 && RegNo <= X86::YMM31) ||
(RegNo >= X86::ZMM8 && RegNo <= X86::ZMM31))
return true;

Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Target/X86/MCTargetDesc/X86InstComments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,11 @@ using namespace llvm;
CASE_AVX_INS_COMMON(Inst##SS4, , mr_Int)

static unsigned getVectorRegSize(unsigned RegNo) {
if (X86::ZMM0 <= RegNo && RegNo <= X86::ZMM31)
if (X86II::isZMMReg(RegNo))
return 512;
if (X86::YMM0 <= RegNo && RegNo <= X86::YMM31)
if (X86II::isYMMReg(RegNo))
return 256;
if (X86::XMM0 <= RegNo && RegNo <= X86::XMM31)
if (X86II::isXMMReg(RegNo))
return 128;
if (X86::MM0 <= RegNo && RegNo <= X86::MM7)
return 64;
Expand Down
36 changes: 34 additions & 2 deletions llvm/lib/Target/X86/X86RegisterInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,8 +604,9 @@ BitVector X86RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
}
}
if (!Is64Bit || !MF.getSubtarget<X86Subtarget>().hasAVX512()) {
for (unsigned n = 16; n != 32; ++n) {
for (MCRegAliasIterator AI(X86::XMM0 + n, this, true); AI.isValid(); ++AI)
for (unsigned n = 0; n != 16; ++n) {
for (MCRegAliasIterator AI(X86::XMM16 + n, this, true); AI.isValid();
++AI)
Reserved.set(*AI);
}
}
Expand All @@ -616,6 +617,37 @@ BitVector X86RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
return Reserved;
}

unsigned X86RegisterInfo::getNumSupportedRegs(const MachineFunction &MF) const {
const X86Subtarget &ST = MF.getSubtarget<X86Subtarget>();
// All existing Intel CPUs that support AMX support AVX512 and all existing
// Intel CPUs that support APX support AMX. AVX512 implies AVX.
//
// We enumerate the registers in X86GenRegisterInfo.inc in this order:
//
// Registers before AVX512,
// AVX512 registers (X/YMM16-31, ZMM0-31, K registers)
// AMX registers (TMM)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can also see the difference by the update in llvm/test/CodeGen/X86/ipra-reg-usage.ll

// APX registers (R16-R31)
//
// and try to return the minimum number of registers supported by the target.

assert((X86::R15WH + 1 == X86 ::YMM0) && (X86::YMM15 + 1 == X86::K0) &&
(X86::K6_K7 + 1 == X86::TMMCFG) &&
(X86::TMM7 + 1 == X86::NUM_TARGET_REGS) &&
"Register number may be incorrect");

bool HasAVX = ST.hasAVX();
bool HasAVX512 = ST.hasAVX512();
bool HasAMX = ST.hasAMXTILE();
if (HasAMX)
return X86::TMM7 + 1;
if (HasAVX512)
return X86::K6_K7 + 1;
if (HasAVX)
return X86::YMM15 + 1;
return X86::YMM0;
KanRobert marked this conversation as resolved.
Show resolved Hide resolved
}

bool X86RegisterInfo::isArgumentRegister(const MachineFunction &MF,
MCRegister Reg) const {
const X86Subtarget &ST = MF.getSubtarget<X86Subtarget>();
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/X86/X86RegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ class X86RegisterInfo final : public X86GenRegisterInfo {
public:
explicit X86RegisterInfo(const Triple &TT);

/// Return the number of registers for the function.
unsigned getNumSupportedRegs(const MachineFunction &MF) const override;

// FIXME: This should be tablegen'd like getDwarfRegNum is
int getSEHRegNum(unsigned i) const;

Expand Down
49 changes: 31 additions & 18 deletions llvm/lib/Target/X86/X86RegisterInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ def XMM13: X86Reg<"xmm13", 13>, DwarfRegNum<[30, -2, -2]>;
def XMM14: X86Reg<"xmm14", 14>, DwarfRegNum<[31, -2, -2]>;
def XMM15: X86Reg<"xmm15", 15>, DwarfRegNum<[32, -2, -2]>;

let PositionOrder = 2 in {
// XMM16-31 registers, used by AVX-512 instructions.
def XMM16: X86Reg<"xmm16", 16>, DwarfRegNum<[67, -2, -2]>;
def XMM17: X86Reg<"xmm17", 17>, DwarfRegNum<[68, -2, -2]>;
def XMM18: X86Reg<"xmm18", 18>, DwarfRegNum<[69, -2, -2]>;
Expand All @@ -239,27 +241,51 @@ def XMM28: X86Reg<"xmm28", 28>, DwarfRegNum<[79, -2, -2]>;
def XMM29: X86Reg<"xmm29", 29>, DwarfRegNum<[80, -2, -2]>;
def XMM30: X86Reg<"xmm30", 30>, DwarfRegNum<[81, -2, -2]>;
def XMM31: X86Reg<"xmm31", 31>, DwarfRegNum<[82, -2, -2]>;
}

// YMM0-15 registers, used by AVX instructions and
// YMM16-31 registers, used by AVX-512 instructions.
let SubRegIndices = [sub_xmm] in {
foreach Index = 0-31 in {
let SubRegIndices = [sub_xmm], PositionOrder = 1 in {
foreach Index = 0-15 in {
def YMM#Index : X86Reg<"ymm"#Index, Index, [!cast<X86Reg>("XMM"#Index)]>,
DwarfRegAlias<!cast<X86Reg>("XMM"#Index)>;
}
}
let SubRegIndices = [sub_xmm], PositionOrder = 2 in {
foreach Index = 16-31 in {
def YMM#Index : X86Reg<"ymm"#Index, Index, [!cast<X86Reg>("XMM"#Index)]>,
DwarfRegAlias<!cast<X86Reg>("XMM"#Index)>;
}
}


// ZMM Registers, used by AVX-512 instructions.
let SubRegIndices = [sub_ymm] in {
let SubRegIndices = [sub_ymm], PositionOrder = 2 in {
foreach Index = 0-31 in {
def ZMM#Index : X86Reg<"zmm"#Index, Index, [!cast<X86Reg>("YMM"#Index)]>,
DwarfRegAlias<!cast<X86Reg>("XMM"#Index)>;
}
}

let PositionOrder = 2 in {
// Mask Registers, used by AVX-512 instructions.
def K0 : X86Reg<"k0", 0>, DwarfRegNum<[118, 93, 93]>;
def K1 : X86Reg<"k1", 1>, DwarfRegNum<[119, 94, 94]>;
def K2 : X86Reg<"k2", 2>, DwarfRegNum<[120, 95, 95]>;
def K3 : X86Reg<"k3", 3>, DwarfRegNum<[121, 96, 96]>;
def K4 : X86Reg<"k4", 4>, DwarfRegNum<[122, 97, 97]>;
def K5 : X86Reg<"k5", 5>, DwarfRegNum<[123, 98, 98]>;
def K6 : X86Reg<"k6", 6>, DwarfRegNum<[124, 99, 99]>;
def K7 : X86Reg<"k7", 7>, DwarfRegNum<[125, 100, 100]>;
// Mask register pairs
def KPAIRS : RegisterTuples<[sub_mask_0, sub_mask_1],
[(add K0, K2, K4, K6), (add K1, K3, K5, K7)]>;
}

// TMM registers, used by AMX instructions.
let PositionOrder = 3 in {
// Tile config registers.
def TMMCFG: X86Reg<"tmmcfg", 0>;

// Tile "registers".
def TMM0: X86Reg<"tmm0", 0>;
def TMM1: X86Reg<"tmm1", 1>;
Expand All @@ -269,16 +295,7 @@ def TMM4: X86Reg<"tmm4", 4>;
def TMM5: X86Reg<"tmm5", 5>;
def TMM6: X86Reg<"tmm6", 6>;
def TMM7: X86Reg<"tmm7", 7>;

// Mask Registers, used by AVX-512 instructions.
def K0 : X86Reg<"k0", 0>, DwarfRegNum<[118, 93, 93]>;
def K1 : X86Reg<"k1", 1>, DwarfRegNum<[119, 94, 94]>;
def K2 : X86Reg<"k2", 2>, DwarfRegNum<[120, 95, 95]>;
def K3 : X86Reg<"k3", 3>, DwarfRegNum<[121, 96, 96]>;
def K4 : X86Reg<"k4", 4>, DwarfRegNum<[122, 97, 97]>;
def K5 : X86Reg<"k5", 5>, DwarfRegNum<[123, 98, 98]>;
def K6 : X86Reg<"k6", 6>, DwarfRegNum<[124, 99, 99]>;
def K7 : X86Reg<"k7", 7>, DwarfRegNum<[125, 100, 100]>;
}

// Floating point stack registers. These don't map one-to-one to the FP
// pseudo registers, but we still mark them as aliasing FP registers. That
Expand Down Expand Up @@ -627,10 +644,6 @@ def VK16 : RegisterClass<"X86", [v16i1], 16, (add VK8)> {let Size = 16;}
def VK32 : RegisterClass<"X86", [v32i1], 32, (add VK16)> {let Size = 32;}
def VK64 : RegisterClass<"X86", [v64i1], 64, (add VK32)> {let Size = 64;}

// Mask register pairs
def KPAIRS : RegisterTuples<[sub_mask_0, sub_mask_1],
[(add K0, K2, K4, K6), (add K1, K3, K5, K7)]>;

def VK1PAIR : RegisterClass<"X86", [untyped], 16, (add KPAIRS)> {let Size = 32;}
def VK2PAIR : RegisterClass<"X86", [untyped], 16, (add KPAIRS)> {let Size = 32;}
def VK4PAIR : RegisterClass<"X86", [untyped], 16, (add KPAIRS)> {let Size = 32;}
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/X86/ipra-reg-usage.ll
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
target triple = "x86_64-unknown-unknown"
declare void @bar1()
define preserve_allcc void @foo()#0 {
; CHECK: foo Clobbered Registers: $cs $df $ds $eflags $eip $eiz $es $esp $fpcw $fpsw $fs $fs_base $gs $gs_base $hip $hsp $ip $mxcsr $rflags $rip $riz $rsp $sp $sph $spl $ss $ssp $tmmcfg $_eflags $cr0 $cr1 $cr2 $cr3 $cr4 $cr5 $cr6 $cr7 $cr8 $cr9 $cr10 $cr11 $cr12 $cr13 $cr14 $cr15 $dr0 $dr1 $dr2 $dr3 $dr4 $dr5 $dr6 $dr7 $dr8 $dr9 $dr10 $dr11 $dr12 $dr13 $dr14 $dr15 $fp0 $fp1 $fp2 $fp3 $fp4 $fp5 $fp6 $fp7 $k0 $k1 $k2 $k3 $k4 $k5 $k6 $k7 $mm0 $mm1 $mm2 $mm3 $mm4 $mm5 $mm6 $mm7 $r11 $st0 $st1 $st2 $st3 $st4 $st5 $st6 $st7 $tmm0 $tmm1 $tmm2 $tmm3 $tmm4 $tmm5 $tmm6 $tmm7 $xmm16 $xmm17 $xmm18 $xmm19 $xmm20 $xmm21 $xmm22 $xmm23 $xmm24 $xmm25 $xmm26 $xmm27 $xmm28 $xmm29 $xmm30 $xmm31 $ymm0 $ymm1 $ymm2 $ymm3 $ymm4 $ymm5 $ymm6 $ymm7 $ymm8 $ymm9 $ymm10 $ymm11 $ymm12 $ymm13 $ymm14 $ymm15 $ymm16 $ymm17 $ymm18 $ymm19 $ymm20 $ymm21 $ymm22 $ymm23 $ymm24 $ymm25 $ymm26 $ymm27 $ymm28 $ymm29 $ymm30 $ymm31 $zmm0 $zmm1 $zmm2 $zmm3 $zmm4 $zmm5 $zmm6 $zmm7 $zmm8 $zmm9 $zmm10 $zmm11 $zmm12 $zmm13 $zmm14 $zmm15 $zmm16 $zmm17 $zmm18 $zmm19 $zmm20 $zmm21 $zmm22 $zmm23 $zmm24 $zmm25 $zmm26 $zmm27 $zmm28 $zmm29 $zmm30 $zmm31 $r11b $r11bh $r11d $r11w $r11wh $k0_k1 $k2_k3 $k4_k5 $k6_k7
; CHECK: foo Clobbered Registers: $cs $df $ds $eflags $eip $eiz $es $esp $fpcw $fpsw $fs $fs_base $gs $gs_base $hip $hsp $ip $mxcsr $rflags $rip $riz $rsp $sp $sph $spl $ss $ssp $_eflags $cr0 $cr1 $cr2 $cr3 $cr4 $cr5 $cr6 $cr7 $cr8 $cr9 $cr10 $cr11 $cr12 $cr13 $cr14 $cr15 $dr0 $dr1 $dr2 $dr3 $dr4 $dr5 $dr6 $dr7 $dr8 $dr9 $dr10 $dr11 $dr12 $dr13 $dr14 $dr15 $fp0 $fp1 $fp2 $fp3 $fp4 $fp5 $fp6 $fp7 $mm0 $mm1 $mm2 $mm3 $mm4 $mm5 $mm6 $mm7 $r11 $st0 $st1 $st2 $st3 $st4 $st5 $st6 $st7 $r11b $r11bh $r11d $r11w $r11wh $ymm0 $ymm1 $ymm2 $ymm3 $ymm4 $ymm5 $ymm6 $ymm7 $ymm8 $ymm9 $ymm10 $ymm11 $ymm12 $ymm13 $ymm14 $ymm15 $k0 $k1 $k2 $k3 $k4 $k5 $k6 $k7 $xmm16 $xmm17 $xmm18 $xmm19 $xmm20 $xmm21 $xmm22 $xmm23 $xmm24 $xmm25 $xmm26 $xmm27 $xmm28 $xmm29 $xmm30 $xmm31 $ymm16 $ymm17 $ymm18 $ymm19 $ymm20 $ymm21 $ymm22 $ymm23 $ymm24 $ymm25 $ymm26 $ymm27 $ymm28 $ymm29 $ymm30 $ymm31 $zmm0 $zmm1 $zmm2 $zmm3 $zmm4 $zmm5 $zmm6 $zmm7 $zmm8 $zmm9 $zmm10 $zmm11 $zmm12 $zmm13 $zmm14 $zmm15 $zmm16 $zmm17 $zmm18 $zmm19 $zmm20 $zmm21 $zmm22 $zmm23 $zmm24 $zmm25 $zmm26 $zmm27 $zmm28 $zmm29 $zmm30 $zmm31 $k0_k1 $k2_k3 $k4_k5 $k6_k7 $tmmcfg $tmm0 $tmm1 $tmm2 $tmm3 $tmm4 $tmm5 $tmm6 $tmm7
call void @bar1()
call void @bar2()
ret void
Expand Down
Loading