Skip to content

Commit 5586bc5

Browse files
committed
[X86] Remove patterns for ADD/AND/OR/SUB/XOR/CMP with immediate 8 and optimize during MC lowering, NFCI
This is follow-up of D150107. In addition, the function `X86::optimizeToFixedRegisterOrShortImmediateForm` can be shared with project bolt and eliminates the code in X86InstrRelaxTables.cpp. Differential Revision: https://reviews.llvm.org/D150949
1 parent 91a7aa4 commit 5586bc5

File tree

63 files changed

+430
-711
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+430
-711
lines changed

llvm/lib/Target/X86/MCTargetDesc/X86EncodingOptimization.cpp

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ bool X86::optimizeMOV(MCInst &MI, bool In64BitMode) {
370370

371371
/// Simplify FOO $imm, %{al,ax,eax,rax} to FOO $imm, for instruction with
372372
/// a short fixed-register form.
373-
bool X86::optimizeToFixedRegisterForm(MCInst &MI) {
373+
static bool optimizeToFixedRegisterForm(MCInst &MI) {
374374
unsigned NewOpc;
375375
switch (MI.getOpcode()) {
376376
default:
@@ -425,7 +425,7 @@ bool X86::optimizeToFixedRegisterForm(MCInst &MI) {
425425
return true;
426426
}
427427

428-
bool X86::optimizeToShortImmediateForm(MCInst &MI) {
428+
static bool optimizeToShortImmediateForm(MCInst &MI) {
429429
unsigned NewOpc;
430430
switch (MI.getOpcode()) {
431431
default:
@@ -442,9 +442,59 @@ bool X86::optimizeToShortImmediateForm(MCInst &MI) {
442442
FROM_TO(SBB32ri, SBB32ri8)
443443
FROM_TO(SBB64mi32, SBB64mi8)
444444
FROM_TO(SBB64ri32, SBB64ri8)
445+
FROM_TO(ADD16mi, ADD16mi8)
446+
FROM_TO(ADD16ri, ADD16ri8)
447+
FROM_TO(ADD32mi, ADD32mi8)
448+
FROM_TO(ADD32ri, ADD32ri8)
449+
FROM_TO(ADD64mi32, ADD64mi8)
450+
FROM_TO(ADD64ri32, ADD64ri8)
451+
FROM_TO(AND16mi, AND16mi8)
452+
FROM_TO(AND16ri, AND16ri8)
453+
FROM_TO(AND32mi, AND32mi8)
454+
FROM_TO(AND32ri, AND32ri8)
455+
FROM_TO(AND64mi32, AND64mi8)
456+
FROM_TO(AND64ri32, AND64ri8)
457+
FROM_TO(OR16mi, OR16mi8)
458+
FROM_TO(OR16ri, OR16ri8)
459+
FROM_TO(OR32mi, OR32mi8)
460+
FROM_TO(OR32ri, OR32ri8)
461+
FROM_TO(OR64mi32, OR64mi8)
462+
FROM_TO(OR64ri32, OR64ri8)
463+
FROM_TO(SUB16mi, SUB16mi8)
464+
FROM_TO(SUB16ri, SUB16ri8)
465+
FROM_TO(SUB32mi, SUB32mi8)
466+
FROM_TO(SUB32ri, SUB32ri8)
467+
FROM_TO(SUB64mi32, SUB64mi8)
468+
FROM_TO(SUB64ri32, SUB64ri8)
469+
FROM_TO(XOR16mi, XOR16mi8)
470+
FROM_TO(XOR16ri, XOR16ri8)
471+
FROM_TO(XOR32mi, XOR32mi8)
472+
FROM_TO(XOR32ri, XOR32ri8)
473+
FROM_TO(XOR64mi32, XOR64mi8)
474+
FROM_TO(XOR64ri32, XOR64ri8)
475+
FROM_TO(CMP16mi, CMP16mi8)
476+
FROM_TO(CMP16ri, CMP16ri8)
477+
FROM_TO(CMP32mi, CMP32mi8)
478+
FROM_TO(CMP32ri, CMP32ri8)
479+
FROM_TO(CMP64mi32, CMP64mi8)
480+
FROM_TO(CMP64ri32, CMP64ri8)
481+
}
482+
MCOperand &LastOp = MI.getOperand(MI.getNumOperands() - 1);
483+
if (LastOp.isExpr()) {
484+
const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(LastOp.getExpr());
485+
if (!SRE || SRE->getKind() != MCSymbolRefExpr::VK_X86_ABS8)
486+
return false;
487+
} else if (LastOp.isImm()) {
488+
if (!isInt<8>(LastOp.getImm()))
489+
return false;
445490
}
446-
if (!isInt<8>(MI.getOperand(MI.getNumOperands() - 1).getImm()))
447-
return false;
448491
MI.setOpcode(NewOpc);
449492
return true;
450493
}
494+
495+
bool X86::optimizeToFixedRegisterOrShortImmediateForm(MCInst &MI) {
496+
// We may optimize twice here.
497+
bool ShortImm = optimizeToShortImmediateForm(MI);
498+
bool FixedReg = optimizeToFixedRegisterForm(MI);
499+
return ShortImm || FixedReg;
500+
}

llvm/lib/Target/X86/MCTargetDesc/X86EncodingOptimization.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ bool optimizeVPCMPWithImmediateOneOrSix(MCInst &MI);
2222
bool optimizeMOVSX(MCInst &MI);
2323
bool optimizeINCDEC(MCInst &MI, bool In64BitMode);
2424
bool optimizeMOV(MCInst &MI, bool In64BitMode);
25-
bool optimizeToFixedRegisterForm(MCInst &MI);
26-
bool optimizeToShortImmediateForm(MCInst &MI);
25+
bool optimizeToFixedRegisterOrShortImmediateForm(MCInst &MI);
2726
} // namespace X86
2827
} // namespace llvm
2928
#endif

llvm/lib/Target/X86/X86CallFrameOptimization.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -285,15 +285,15 @@ X86CallFrameOptimization::classifyInstruction(
285285
// The instructions we actually care about are movs onto the stack or special
286286
// cases of constant-stores to stack
287287
switch (MI->getOpcode()) {
288-
case X86::AND16mi8:
289-
case X86::AND32mi8:
290-
case X86::AND64mi8: {
288+
case X86::AND16mi:
289+
case X86::AND32mi:
290+
case X86::AND64mi32: {
291291
const MachineOperand &ImmOp = MI->getOperand(X86::AddrNumOperands);
292292
return ImmOp.getImm() == 0 ? Convert : Exit;
293293
}
294-
case X86::OR16mi8:
295-
case X86::OR32mi8:
296-
case X86::OR64mi8: {
294+
case X86::OR16mi:
295+
case X86::OR32mi:
296+
case X86::OR64mi32: {
297297
const MachineOperand &ImmOp = MI->getOperand(X86::AddrNumOperands);
298298
return ImmOp.getImm() == -1 ? Convert : Exit;
299299
}
@@ -512,12 +512,12 @@ void X86CallFrameOptimization::adjustCallSequence(MachineFunction &MF,
512512
switch (Store->getOpcode()) {
513513
default:
514514
llvm_unreachable("Unexpected Opcode!");
515-
case X86::AND16mi8:
516-
case X86::AND32mi8:
517-
case X86::AND64mi8:
518-
case X86::OR16mi8:
519-
case X86::OR32mi8:
520-
case X86::OR64mi8:
515+
case X86::AND16mi:
516+
case X86::AND32mi:
517+
case X86::AND64mi32:
518+
case X86::OR16mi:
519+
case X86::OR32mi:
520+
case X86::OR64mi32:
521521
case X86::MOV32mi:
522522
case X86::MOV64mi32:
523523
PushOpcode = Is64Bit ? X86::PUSH64i32 : X86::PUSHi32;

llvm/lib/Target/X86/X86DynAllocaExpander.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,10 @@ void X86DynAllocaExpander::computeLowerings(MachineFunction &MF,
189189
}
190190
}
191191

192-
static unsigned getSubOpcode(bool Is64Bit, int64_t Amount) {
192+
static unsigned getSubOpcode(bool Is64Bit) {
193193
if (Is64Bit)
194-
return isInt<8>(Amount) ? X86::SUB64ri8 : X86::SUB64ri32;
195-
return isInt<8>(Amount) ? X86::SUB32ri8 : X86::SUB32ri;
194+
return X86::SUB64ri32;
195+
return X86::SUB32ri;
196196
}
197197

198198
void X86DynAllocaExpander::lower(MachineInstr *MI, Lowering L) {
@@ -242,8 +242,7 @@ void X86DynAllocaExpander::lower(MachineInstr *MI, Lowering L) {
242242
.addReg(RegA, RegState::Undef);
243243
} else {
244244
// Sub.
245-
BuildMI(*MBB, I, DL,
246-
TII->get(getSubOpcode(Is64BitAlloca, Amount)), StackPtr)
245+
BuildMI(*MBB, I, DL, TII->get(getSubOpcode(Is64BitAlloca)), StackPtr)
247246
.addReg(StackPtr)
248247
.addImm(Amount);
249248
}

llvm/lib/Target/X86/X86FastISel.cpp

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,29 +1376,20 @@ static unsigned X86ChooseCmpOpcode(EVT VT, const X86Subtarget *Subtarget) {
13761376
/// If we have a comparison with RHS as the RHS of the comparison, return an
13771377
/// opcode that works for the compare (e.g. CMP32ri) otherwise return 0.
13781378
static unsigned X86ChooseCmpImmediateOpcode(EVT VT, const ConstantInt *RHSC) {
1379-
int64_t Val = RHSC->getSExtValue();
13801379
switch (VT.getSimpleVT().SimpleTy) {
13811380
// Otherwise, we can't fold the immediate into this comparison.
13821381
default:
13831382
return 0;
13841383
case MVT::i8:
13851384
return X86::CMP8ri;
13861385
case MVT::i16:
1387-
if (isInt<8>(Val))
1388-
return X86::CMP16ri8;
13891386
return X86::CMP16ri;
13901387
case MVT::i32:
1391-
if (isInt<8>(Val))
1392-
return X86::CMP32ri8;
13931388
return X86::CMP32ri;
13941389
case MVT::i64:
1395-
if (isInt<8>(Val))
1396-
return X86::CMP64ri8;
13971390
// 64-bit comparisons are only valid if the immediate fits in a 32-bit sext
13981391
// field.
1399-
if (isInt<32>(Val))
1400-
return X86::CMP64ri32;
1401-
return 0;
1392+
return isInt<32>(RHSC->getSExtValue()) ? X86::CMP64ri32 : 0;
14021393
}
14031394
}
14041395

llvm/lib/Target/X86/X86FixupLEAs.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -186,13 +186,9 @@ FixupLEAPass::postRAConvertToLEA(MachineBasicBlock &MBB,
186186
// Only convert instructions that we've verified are safe.
187187
return nullptr;
188188
case X86::ADD64ri32:
189-
case X86::ADD64ri8:
190189
case X86::ADD64ri32_DB:
191-
case X86::ADD64ri8_DB:
192190
case X86::ADD32ri:
193-
case X86::ADD32ri8:
194191
case X86::ADD32ri_DB:
195-
case X86::ADD32ri8_DB:
196192
if (!MI.getOperand(2).isImm()) {
197193
// convertToThreeAddress will call getImm()
198194
// which requires isImm() to be true
@@ -374,15 +370,14 @@ static inline unsigned getSUBrrFromLEA(unsigned LEAOpcode) {
374370

375371
static inline unsigned getADDriFromLEA(unsigned LEAOpcode,
376372
const MachineOperand &Offset) {
377-
bool IsInt8 = Offset.isImm() && isInt<8>(Offset.getImm());
378373
switch (LEAOpcode) {
379374
default:
380375
llvm_unreachable("Unexpected LEA instruction");
381376
case X86::LEA32r:
382377
case X86::LEA64_32r:
383-
return IsInt8 ? X86::ADD32ri8 : X86::ADD32ri;
378+
return X86::ADD32ri;
384379
case X86::LEA64r:
385-
return IsInt8 ? X86::ADD64ri8 : X86::ADD64ri32;
380+
return X86::ADD64ri32;
386381
}
387382
}
388383

llvm/lib/Target/X86/X86FrameLowering.cpp

Lines changed: 16 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -105,28 +105,12 @@ bool X86FrameLowering::hasFP(const MachineFunction &MF) const {
105105
(isWin64Prologue(MF) && MFI.hasCopyImplyingStackAdjustment()));
106106
}
107107

108-
static unsigned getSUBriOpcode(bool IsLP64, int64_t Imm) {
109-
if (IsLP64) {
110-
if (isInt<8>(Imm))
111-
return X86::SUB64ri8;
112-
return X86::SUB64ri32;
113-
} else {
114-
if (isInt<8>(Imm))
115-
return X86::SUB32ri8;
116-
return X86::SUB32ri;
117-
}
108+
static unsigned getSUBriOpcode(bool IsLP64) {
109+
return IsLP64 ? X86::SUB64ri32 : X86::SUB32ri;
118110
}
119111

120-
static unsigned getADDriOpcode(bool IsLP64, int64_t Imm) {
121-
if (IsLP64) {
122-
if (isInt<8>(Imm))
123-
return X86::ADD64ri8;
124-
return X86::ADD64ri32;
125-
} else {
126-
if (isInt<8>(Imm))
127-
return X86::ADD32ri8;
128-
return X86::ADD32ri;
129-
}
112+
static unsigned getADDriOpcode(bool IsLP64) {
113+
return IsLP64 ? X86::ADD64ri32 : X86::ADD32ri;
130114
}
131115

132116
static unsigned getSUBrrOpcode(bool IsLP64) {
@@ -138,14 +122,7 @@ static unsigned getADDrrOpcode(bool IsLP64) {
138122
}
139123

140124
static unsigned getANDriOpcode(bool IsLP64, int64_t Imm) {
141-
if (IsLP64) {
142-
if (isInt<8>(Imm))
143-
return X86::AND64ri8;
144-
return X86::AND64ri32;
145-
}
146-
if (isInt<8>(Imm))
147-
return X86::AND32ri8;
148-
return X86::AND32ri;
125+
return IsLP64 ? X86::AND64ri32 : X86::AND32ri;
149126
}
150127

151128
static unsigned getLEArOpcode(bool IsLP64) {
@@ -363,8 +340,8 @@ MachineInstrBuilder X86FrameLowering::BuildStackAdjustment(
363340
} else {
364341
bool IsSub = Offset < 0;
365342
uint64_t AbsOffset = IsSub ? -Offset : Offset;
366-
const unsigned Opc = IsSub ? getSUBriOpcode(Uses64BitFramePtr, AbsOffset)
367-
: getADDriOpcode(Uses64BitFramePtr, AbsOffset);
343+
const unsigned Opc = IsSub ? getSUBriOpcode(Uses64BitFramePtr)
344+
: getADDriOpcode(Uses64BitFramePtr);
368345
MI = BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr)
369346
.addReg(StackPtr)
370347
.addImm(AbsOffset);
@@ -400,9 +377,8 @@ int X86FrameLowering::mergeSPUpdates(MachineBasicBlock &MBB,
400377
unsigned Opc = PI->getOpcode();
401378
int Offset = 0;
402379

403-
if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 ||
404-
Opc == X86::ADD32ri || Opc == X86::ADD32ri8) &&
405-
PI->getOperand(0).getReg() == StackPtr){
380+
if ((Opc == X86::ADD64ri32 || Opc == X86::ADD32ri) &&
381+
PI->getOperand(0).getReg() == StackPtr) {
406382
assert(PI->getOperand(1).getReg() == StackPtr);
407383
Offset = PI->getOperand(2).getImm();
408384
} else if ((Opc == X86::LEA32r || Opc == X86::LEA64_32r) &&
@@ -413,8 +389,7 @@ int X86FrameLowering::mergeSPUpdates(MachineBasicBlock &MBB,
413389
PI->getOperand(5).getReg() == X86::NoRegister) {
414390
// For LEAs we have: def = lea SP, FI, noreg, Offset, noreg.
415391
Offset = PI->getOperand(4).getImm();
416-
} else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 ||
417-
Opc == X86::SUB32ri || Opc == X86::SUB32ri8) &&
392+
} else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB32ri) &&
418393
PI->getOperand(0).getReg() == StackPtr) {
419394
assert(PI->getOperand(1).getReg() == StackPtr);
420395
Offset = -PI->getOperand(2).getImm();
@@ -833,7 +808,7 @@ void X86FrameLowering::emitStackProbeInlineGenericLoop(
833808
// save loop bound
834809
{
835810
const unsigned BoundOffset = alignDown(Offset, StackProbeSize);
836-
const unsigned SUBOpc = getSUBriOpcode(Uses64BitFramePtr, BoundOffset);
811+
const unsigned SUBOpc = getSUBriOpcode(Uses64BitFramePtr);
837812
BuildMI(MBB, MBBI, DL, TII.get(SUBOpc), FinalStackProbed)
838813
.addReg(FinalStackProbed)
839814
.addImm(BoundOffset)
@@ -1336,7 +1311,7 @@ void X86FrameLowering::BuildStackAlignAND(MachineBasicBlock &MBB,
13361311

13371312
{
13381313
const unsigned SUBOpc =
1339-
getSUBriOpcode(Uses64BitFramePtr, StackProbeSize);
1314+
getSUBriOpcode(Uses64BitFramePtr);
13401315
BuildMI(headMBB, DL, TII.get(SUBOpc), StackPtr)
13411316
.addReg(StackPtr)
13421317
.addImm(StackProbeSize)
@@ -1367,7 +1342,7 @@ void X86FrameLowering::BuildStackAlignAND(MachineBasicBlock &MBB,
13671342
.setMIFlag(MachineInstr::FrameSetup);
13681343

13691344
const unsigned SUBOpc =
1370-
getSUBriOpcode(Uses64BitFramePtr, StackProbeSize);
1345+
getSUBriOpcode(Uses64BitFramePtr);
13711346
BuildMI(bodyMBB, DL, TII.get(SUBOpc), StackPtr)
13721347
.addReg(StackPtr)
13731348
.addImm(StackProbeSize)
@@ -1800,7 +1775,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
18001775
.addImm(8)
18011776
.addUse(X86::NoRegister)
18021777
.setMIFlag(MachineInstr::FrameSetup);
1803-
BuildMI(MBB, MBBI, DL, TII.get(X86::SUB64ri8), X86::RSP)
1778+
BuildMI(MBB, MBBI, DL, TII.get(X86::SUB64ri32), X86::RSP)
18041779
.addUse(X86::RSP)
18051780
.addImm(8)
18061781
.setMIFlag(MachineInstr::FrameSetup);
@@ -2419,7 +2394,7 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
24192394
if ((Opc != X86::POP32r || !PI->getFlag(MachineInstr::FrameDestroy)) &&
24202395
(Opc != X86::POP64r || !PI->getFlag(MachineInstr::FrameDestroy)) &&
24212396
(Opc != X86::BTR64ri8 || !PI->getFlag(MachineInstr::FrameDestroy)) &&
2422-
(Opc != X86::ADD64ri8 || !PI->getFlag(MachineInstr::FrameDestroy)))
2397+
(Opc != X86::ADD64ri32 || !PI->getFlag(MachineInstr::FrameDestroy)))
24232398
break;
24242399
FirstCSPop = PI;
24252400
}
@@ -3793,7 +3768,7 @@ MachineBasicBlock::iterator X86FrameLowering::restoreWin32EHStackPointers(
37933768

37943769
if (UsedReg == FramePtr) {
37953770
// ADD $offset, %ebp
3796-
unsigned ADDri = getADDriOpcode(false, EndOffset);
3771+
unsigned ADDri = getADDriOpcode(false);
37973772
BuildMI(MBB, MBBI, DL, TII.get(ADDri), FramePtr)
37983773
.addReg(FramePtr)
37993774
.addImm(EndOffset)

llvm/lib/Target/X86/X86ISelDAGToDAG.cpp

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3400,26 +3400,6 @@ bool X86DAGToDAGISel::foldLoadStoreIntoMemOperand(SDNode *Node) {
34003400
llvm_unreachable("Invalid opcode!");
34013401
}
34023402
};
3403-
auto SelectImm8Opcode = [SelectOpcode](unsigned Opc) {
3404-
switch (Opc) {
3405-
case X86ISD::ADD:
3406-
return SelectOpcode(X86::ADD64mi8, X86::ADD32mi8, X86::ADD16mi8, 0);
3407-
case X86ISD::ADC:
3408-
return SelectOpcode(X86::ADC64mi8, X86::ADC32mi8, X86::ADC16mi8, 0);
3409-
case X86ISD::SUB:
3410-
return SelectOpcode(X86::SUB64mi8, X86::SUB32mi8, X86::SUB16mi8, 0);
3411-
case X86ISD::SBB:
3412-
return SelectOpcode(X86::SBB64mi8, X86::SBB32mi8, X86::SBB16mi8, 0);
3413-
case X86ISD::AND:
3414-
return SelectOpcode(X86::AND64mi8, X86::AND32mi8, X86::AND16mi8, 0);
3415-
case X86ISD::OR:
3416-
return SelectOpcode(X86::OR64mi8, X86::OR32mi8, X86::OR16mi8, 0);
3417-
case X86ISD::XOR:
3418-
return SelectOpcode(X86::XOR64mi8, X86::XOR32mi8, X86::XOR16mi8, 0);
3419-
default:
3420-
llvm_unreachable("Invalid opcode!");
3421-
}
3422-
};
34233403
auto SelectImmOpcode = [SelectOpcode](unsigned Opc) {
34243404
switch (Opc) {
34253405
case X86ISD::ADD:
@@ -3468,12 +3448,7 @@ bool X86DAGToDAGISel::foldLoadStoreIntoMemOperand(SDNode *Node) {
34683448
Opc = Opc == X86ISD::ADD ? X86ISD::SUB : X86ISD::ADD;
34693449
}
34703450

3471-
// First try to fit this into an Imm8 operand. If it doesn't fit, then try
3472-
// the larger immediate operand.
3473-
if (MemVT != MVT::i8 && isInt<8>(OperandV)) {
3474-
Operand = CurDAG->getTargetConstant(OperandV, SDLoc(Node), MemVT);
3475-
NewOpc = SelectImm8Opcode(Opc);
3476-
} else if (MemVT != MVT::i64 || isInt<32>(OperandV)) {
3451+
if (MemVT != MVT::i64 || isInt<32>(OperandV)) {
34773452
Operand = CurDAG->getTargetConstant(OperandV, SDLoc(Node), MemVT);
34783453
NewOpc = SelectImmOpcode(Opc);
34793454
}

0 commit comments

Comments
 (0)