Skip to content

Commit 1f6165e

Browse files
authored
X86: Fix convertToThreeAddress losing subregister indexes (#124098)
This avoids dozens of regressions in a future patch. These primarily manifested as assertions where we had copies of 64-bit registers to 32-bit registers. This is testable in principle with hand written MIR, but that's a bit too much x86 for me.
1 parent b22fc43 commit 1f6165e

File tree

4 files changed

+66
-43
lines changed

4 files changed

+66
-43
lines changed

llvm/lib/Target/X86/X86FastISel.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3830,7 +3830,8 @@ unsigned X86FastISel::X86MaterializeFP(const ConstantFP *CFP, MVT VT) {
38303830
.addConstantPoolIndex(CPI, 0, OpFlag);
38313831
MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
38323832
TII.get(Opc), ResultReg);
3833-
addRegReg(MIB, AddrReg, false, PICBase, false);
3833+
addRegReg(MIB, AddrReg, false, X86::NoSubRegister, PICBase, false,
3834+
X86::NoSubRegister);
38343835
MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
38353836
MachinePointerInfo::getConstantPool(*FuncInfo.MF),
38363837
MachineMemOperand::MOLoad, DL.getPointerSize(), Alignment);

llvm/lib/Target/X86/X86InstrBuilder.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,11 +161,14 @@ addRegOffset(const MachineInstrBuilder &MIB,
161161

162162
/// addRegReg - This function is used to add a memory reference of the form:
163163
/// [Reg + Reg].
164-
static inline const MachineInstrBuilder &addRegReg(const MachineInstrBuilder &MIB,
165-
unsigned Reg1, bool isKill1,
166-
unsigned Reg2, bool isKill2) {
167-
return MIB.addReg(Reg1, getKillRegState(isKill1)).addImm(1)
168-
.addReg(Reg2, getKillRegState(isKill2)).addImm(0).addReg(0);
164+
static inline const MachineInstrBuilder &
165+
addRegReg(const MachineInstrBuilder &MIB, unsigned Reg1, bool isKill1,
166+
unsigned SubReg1, unsigned Reg2, bool isKill2, unsigned SubReg2) {
167+
return MIB.addReg(Reg1, getKillRegState(isKill1), SubReg1)
168+
.addImm(1)
169+
.addReg(Reg2, getKillRegState(isKill2), SubReg2)
170+
.addImm(0)
171+
.addReg(0);
169172
}
170173

171174
static inline const MachineInstrBuilder &

llvm/lib/Target/X86/X86InstrInfo.cpp

Lines changed: 53 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,8 +1158,9 @@ static bool findRedundantFlagInstr(MachineInstr &CmpInstr,
11581158

11591159
bool X86InstrInfo::classifyLEAReg(MachineInstr &MI, const MachineOperand &Src,
11601160
unsigned Opc, bool AllowSP, Register &NewSrc,
1161-
bool &isKill, MachineOperand &ImplicitOp,
1162-
LiveVariables *LV, LiveIntervals *LIS) const {
1161+
unsigned &NewSrcSubReg, bool &isKill,
1162+
MachineOperand &ImplicitOp, LiveVariables *LV,
1163+
LiveIntervals *LIS) const {
11631164
MachineFunction &MF = *MI.getParent()->getParent();
11641165
const TargetRegisterClass *RC;
11651166
if (AllowSP) {
@@ -1168,12 +1169,16 @@ bool X86InstrInfo::classifyLEAReg(MachineInstr &MI, const MachineOperand &Src,
11681169
RC = Opc != X86::LEA32r ? &X86::GR64_NOSPRegClass : &X86::GR32_NOSPRegClass;
11691170
}
11701171
Register SrcReg = Src.getReg();
1172+
unsigned SubReg = Src.getSubReg();
11711173
isKill = MI.killsRegister(SrcReg, /*TRI=*/nullptr);
11721174

1175+
NewSrcSubReg = X86::NoSubRegister;
1176+
11731177
// For both LEA64 and LEA32 the register already has essentially the right
11741178
// type (32-bit or 64-bit) we may just need to forbid SP.
11751179
if (Opc != X86::LEA64_32r) {
11761180
NewSrc = SrcReg;
1181+
NewSrcSubReg = SubReg;
11771182
assert(!Src.isUndef() && "Undef op doesn't need optimization");
11781183

11791184
if (NewSrc.isVirtual() && !MF.getRegInfo().constrainRegClass(NewSrc, RC))
@@ -1189,16 +1194,18 @@ bool X86InstrInfo::classifyLEAReg(MachineInstr &MI, const MachineOperand &Src,
11891194
ImplicitOp.setImplicit();
11901195

11911196
NewSrc = getX86SubSuperRegister(SrcReg, 64);
1197+
assert(!SubReg && "no superregister for source");
11921198
assert(NewSrc.isValid() && "Invalid Operand");
11931199
assert(!Src.isUndef() && "Undef op doesn't need optimization");
11941200
} else {
11951201
// Virtual register of the wrong class, we have to create a temporary 64-bit
11961202
// vreg to feed into the LEA.
11971203
NewSrc = MF.getRegInfo().createVirtualRegister(RC);
1204+
NewSrcSubReg = X86::NoSubRegister;
11981205
MachineInstr *Copy =
11991206
BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), get(TargetOpcode::COPY))
12001207
.addReg(NewSrc, RegState::Define | RegState::Undef, X86::sub_32bit)
1201-
.addReg(SrcReg, getKillRegState(isKill));
1208+
.addReg(SrcReg, getKillRegState(isKill), SubReg);
12021209

12031210
// Which is obviously going to be dead after we're done with it.
12041211
isKill = true;
@@ -1258,7 +1265,9 @@ MachineInstr *X86InstrInfo::convertToThreeAddressWithLEA(unsigned MIOpc,
12581265
MachineBasicBlock::iterator MBBI = MI.getIterator();
12591266
Register Dest = MI.getOperand(0).getReg();
12601267
Register Src = MI.getOperand(1).getReg();
1268+
unsigned SrcSubReg = MI.getOperand(1).getSubReg();
12611269
Register Src2;
1270+
unsigned Src2SubReg;
12621271
bool IsDead = MI.getOperand(0).isDead();
12631272
bool IsKill = MI.getOperand(1).isKill();
12641273
unsigned SubReg = Is8BitOp ? X86::sub_8bit : X86::sub_16bit;
@@ -1268,7 +1277,7 @@ MachineInstr *X86InstrInfo::convertToThreeAddressWithLEA(unsigned MIOpc,
12681277
MachineInstr *InsMI =
12691278
BuildMI(MBB, MBBI, MI.getDebugLoc(), get(TargetOpcode::COPY))
12701279
.addReg(InRegLEA, RegState::Define, SubReg)
1271-
.addReg(Src, getKillRegState(IsKill));
1280+
.addReg(Src, getKillRegState(IsKill), SrcSubReg);
12721281
MachineInstr *ImpDef2 = nullptr;
12731282
MachineInstr *InsMI2 = nullptr;
12741283

@@ -1306,12 +1315,14 @@ MachineInstr *X86InstrInfo::convertToThreeAddressWithLEA(unsigned MIOpc,
13061315
case X86::ADD16rr:
13071316
case X86::ADD16rr_DB: {
13081317
Src2 = MI.getOperand(2).getReg();
1318+
Src2SubReg = MI.getOperand(2).getSubReg();
13091319
bool IsKill2 = MI.getOperand(2).isKill();
13101320
assert(!MI.getOperand(2).isUndef() && "Undef op doesn't need optimization");
13111321
if (Src == Src2) {
13121322
// ADD8rr/ADD16rr killed %reg1028, %reg1028
13131323
// just a single insert_subreg.
1314-
addRegReg(MIB, InRegLEA, true, InRegLEA, false);
1324+
addRegReg(MIB, InRegLEA, true, X86::NoSubRegister, InRegLEA, false,
1325+
X86::NoSubRegister);
13151326
} else {
13161327
if (Subtarget.is64Bit())
13171328
InRegLEA2 = RegInfo.createVirtualRegister(&X86::GR64_NOSPRegClass);
@@ -1323,8 +1334,9 @@ MachineInstr *X86InstrInfo::convertToThreeAddressWithLEA(unsigned MIOpc,
13231334
InRegLEA2);
13241335
InsMI2 = BuildMI(MBB, &*MIB, MI.getDebugLoc(), get(TargetOpcode::COPY))
13251336
.addReg(InRegLEA2, RegState::Define, SubReg)
1326-
.addReg(Src2, getKillRegState(IsKill2));
1327-
addRegReg(MIB, InRegLEA, true, InRegLEA2, true);
1337+
.addReg(Src2, getKillRegState(IsKill2), Src2SubReg);
1338+
addRegReg(MIB, InRegLEA, true, X86::NoSubRegister, InRegLEA2, true,
1339+
X86::NoSubRegister);
13281340
}
13291341
if (LV && IsKill2 && InsMI2)
13301342
LV->replaceKillInstruction(Src2, MI, *InsMI2);
@@ -1428,6 +1440,7 @@ MachineInstr *X86InstrInfo::convertToThreeAddress(MachineInstr &MI,
14281440

14291441
MachineInstr *NewMI = nullptr;
14301442
Register SrcReg, SrcReg2;
1443+
unsigned SrcSubReg, SrcSubReg2;
14311444
bool Is64Bit = Subtarget.is64Bit();
14321445

14331446
bool Is8BitOp = false;
@@ -1467,17 +1480,18 @@ MachineInstr *X86InstrInfo::convertToThreeAddress(MachineInstr &MI,
14671480
// LEA can't handle ESP.
14681481
bool isKill;
14691482
MachineOperand ImplicitOp = MachineOperand::CreateReg(0, false);
1470-
if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/false, SrcReg, isKill,
1471-
ImplicitOp, LV, LIS))
1483+
if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/false, SrcReg, SrcSubReg,
1484+
isKill, ImplicitOp, LV, LIS))
14721485
return nullptr;
14731486

1474-
MachineInstrBuilder MIB = BuildMI(MF, MI.getDebugLoc(), get(Opc))
1475-
.add(Dest)
1476-
.addReg(0)
1477-
.addImm(1LL << ShAmt)
1478-
.addReg(SrcReg, getKillRegState(isKill))
1479-
.addImm(0)
1480-
.addReg(0);
1487+
MachineInstrBuilder MIB =
1488+
BuildMI(MF, MI.getDebugLoc(), get(Opc))
1489+
.add(Dest)
1490+
.addReg(0)
1491+
.addImm(1LL << ShAmt)
1492+
.addReg(SrcReg, getKillRegState(isKill), SrcSubReg)
1493+
.addImm(0)
1494+
.addReg(0);
14811495
if (ImplicitOp.getReg() != 0)
14821496
MIB.add(ImplicitOp);
14831497
NewMI = MIB;
@@ -1505,8 +1519,8 @@ MachineInstr *X86InstrInfo::convertToThreeAddress(MachineInstr &MI,
15051519
: (Is64Bit ? X86::LEA64_32r : X86::LEA32r);
15061520
bool isKill;
15071521
MachineOperand ImplicitOp = MachineOperand::CreateReg(0, false);
1508-
if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/false, SrcReg, isKill,
1509-
ImplicitOp, LV, LIS))
1522+
if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/false, SrcReg, SrcSubReg,
1523+
isKill, ImplicitOp, LV, LIS))
15101524
return nullptr;
15111525

15121526
MachineInstrBuilder MIB = BuildMI(MF, MI.getDebugLoc(), get(Opc))
@@ -1531,8 +1545,8 @@ MachineInstr *X86InstrInfo::convertToThreeAddress(MachineInstr &MI,
15311545

15321546
bool isKill;
15331547
MachineOperand ImplicitOp = MachineOperand::CreateReg(0, false);
1534-
if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/false, SrcReg, isKill,
1535-
ImplicitOp, LV, LIS))
1548+
if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/false, SrcReg, SrcSubReg,
1549+
isKill, ImplicitOp, LV, LIS))
15361550
return nullptr;
15371551

15381552
MachineInstrBuilder MIB = BuildMI(MF, MI.getDebugLoc(), get(Opc))
@@ -1569,8 +1583,8 @@ MachineInstr *X86InstrInfo::convertToThreeAddress(MachineInstr &MI,
15691583
const MachineOperand &Src2 = MI.getOperand(2);
15701584
bool isKill2;
15711585
MachineOperand ImplicitOp2 = MachineOperand::CreateReg(0, false);
1572-
if (!classifyLEAReg(MI, Src2, Opc, /*AllowSP=*/false, SrcReg2, isKill2,
1573-
ImplicitOp2, LV, LIS))
1586+
if (!classifyLEAReg(MI, Src2, Opc, /*AllowSP=*/false, SrcReg2, SrcSubReg2,
1587+
isKill2, ImplicitOp2, LV, LIS))
15741588
return nullptr;
15751589

15761590
bool isKill;
@@ -1580,9 +1594,10 @@ MachineInstr *X86InstrInfo::convertToThreeAddress(MachineInstr &MI,
15801594
// the first call inserted a COPY from Src2 and marked it as killed.
15811595
isKill = isKill2;
15821596
SrcReg = SrcReg2;
1597+
SrcSubReg = SrcSubReg2;
15831598
} else {
1584-
if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/true, SrcReg, isKill,
1585-
ImplicitOp, LV, LIS))
1599+
if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/true, SrcReg, SrcSubReg,
1600+
isKill, ImplicitOp, LV, LIS))
15861601
return nullptr;
15871602
}
15881603

@@ -1592,7 +1607,8 @@ MachineInstr *X86InstrInfo::convertToThreeAddress(MachineInstr &MI,
15921607
if (ImplicitOp2.getReg() != 0)
15931608
MIB.add(ImplicitOp2);
15941609

1595-
NewMI = addRegReg(MIB, SrcReg, isKill, SrcReg2, isKill2);
1610+
NewMI =
1611+
addRegReg(MIB, SrcReg, isKill, SrcSubReg, SrcReg2, isKill2, SrcSubReg2);
15961612

15971613
// Add kills if classifyLEAReg created a new register.
15981614
if (LV) {
@@ -1625,13 +1641,14 @@ MachineInstr *X86InstrInfo::convertToThreeAddress(MachineInstr &MI,
16251641

16261642
bool isKill;
16271643
MachineOperand ImplicitOp = MachineOperand::CreateReg(0, false);
1628-
if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/true, SrcReg, isKill,
1629-
ImplicitOp, LV, LIS))
1644+
if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/true, SrcReg, SrcSubReg,
1645+
isKill, ImplicitOp, LV, LIS))
16301646
return nullptr;
16311647

1632-
MachineInstrBuilder MIB = BuildMI(MF, MI.getDebugLoc(), get(Opc))
1633-
.add(Dest)
1634-
.addReg(SrcReg, getKillRegState(isKill));
1648+
MachineInstrBuilder MIB =
1649+
BuildMI(MF, MI.getDebugLoc(), get(Opc))
1650+
.add(Dest)
1651+
.addReg(SrcReg, getKillRegState(isKill), SrcSubReg);
16351652
if (ImplicitOp.getReg() != 0)
16361653
MIB.add(ImplicitOp);
16371654

@@ -1665,13 +1682,14 @@ MachineInstr *X86InstrInfo::convertToThreeAddress(MachineInstr &MI,
16651682

16661683
bool isKill;
16671684
MachineOperand ImplicitOp = MachineOperand::CreateReg(0, false);
1668-
if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/true, SrcReg, isKill,
1669-
ImplicitOp, LV, LIS))
1685+
if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/true, SrcReg, SrcSubReg,
1686+
isKill, ImplicitOp, LV, LIS))
16701687
return nullptr;
16711688

1672-
MachineInstrBuilder MIB = BuildMI(MF, MI.getDebugLoc(), get(Opc))
1673-
.add(Dest)
1674-
.addReg(SrcReg, getKillRegState(isKill));
1689+
MachineInstrBuilder MIB =
1690+
BuildMI(MF, MI.getDebugLoc(), get(Opc))
1691+
.add(Dest)
1692+
.addReg(SrcReg, getKillRegState(isKill), SrcSubReg);
16751693
if (ImplicitOp.getReg() != 0)
16761694
MIB.add(ImplicitOp);
16771695

llvm/lib/Target/X86/X86InstrInfo.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,9 @@ class X86InstrInfo final : public X86GenInstrInfo {
310310
/// operand to the LEA instruction.
311311
bool classifyLEAReg(MachineInstr &MI, const MachineOperand &Src,
312312
unsigned LEAOpcode, bool AllowSP, Register &NewSrc,
313-
bool &isKill, MachineOperand &ImplicitOp,
314-
LiveVariables *LV, LiveIntervals *LIS) const;
313+
unsigned &NewSrcSubReg, bool &isKill,
314+
MachineOperand &ImplicitOp, LiveVariables *LV,
315+
LiveIntervals *LIS) const;
315316

316317
/// convertToThreeAddress - This method must be implemented by targets that
317318
/// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target

0 commit comments

Comments
 (0)