119618fc6SChandler Carruth //====- X86FlagsCopyLowering.cpp - Lowers COPY nodes of EFLAGS ------------===//
219618fc6SChandler Carruth //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
619618fc6SChandler Carruth //
719618fc6SChandler Carruth //===----------------------------------------------------------------------===//
819618fc6SChandler Carruth /// \file
919618fc6SChandler Carruth ///
1019618fc6SChandler Carruth /// Lowers COPY nodes of EFLAGS by directly extracting and preserving individual
1119618fc6SChandler Carruth /// flag bits.
1219618fc6SChandler Carruth ///
1319618fc6SChandler Carruth /// We have to do this by carefully analyzing and rewriting the usage of the
1419618fc6SChandler Carruth /// copied EFLAGS register because there is no general way to rematerialize the
1519618fc6SChandler Carruth /// entire EFLAGS register safely and efficiently. Using `popf` both forces
1619618fc6SChandler Carruth /// dynamic stack adjustment and can create correctness issues due to IF, TF,
1719618fc6SChandler Carruth /// and other non-status flags being overwritten. Using sequences involving
1819618fc6SChandler Carruth /// SAHF don't work on all x86 processors and are often quite slow compared to
1919618fc6SChandler Carruth /// directly testing a single status preserved in its own GPR.
2019618fc6SChandler Carruth ///
2119618fc6SChandler Carruth //===----------------------------------------------------------------------===//
2219618fc6SChandler Carruth
2319618fc6SChandler Carruth #include "X86.h"
2419618fc6SChandler Carruth #include "X86InstrBuilder.h"
2519618fc6SChandler Carruth #include "X86InstrInfo.h"
2619618fc6SChandler Carruth #include "X86Subtarget.h"
2719618fc6SChandler Carruth #include "llvm/ADT/ArrayRef.h"
2819618fc6SChandler Carruth #include "llvm/ADT/DenseMap.h"
29caa7b03aSChandler Carruth #include "llvm/ADT/PostOrderIterator.h"
3019618fc6SChandler Carruth #include "llvm/ADT/STLExtras.h"
3119618fc6SChandler Carruth #include "llvm/ADT/ScopeExit.h"
3219618fc6SChandler Carruth #include "llvm/ADT/SmallPtrSet.h"
3319618fc6SChandler Carruth #include "llvm/ADT/SmallSet.h"
3419618fc6SChandler Carruth #include "llvm/ADT/SmallVector.h"
3519618fc6SChandler Carruth #include "llvm/ADT/SparseBitVector.h"
3619618fc6SChandler Carruth #include "llvm/ADT/Statistic.h"
3719618fc6SChandler Carruth #include "llvm/CodeGen/MachineBasicBlock.h"
3819618fc6SChandler Carruth #include "llvm/CodeGen/MachineConstantPool.h"
391f87618fSChandler Carruth #include "llvm/CodeGen/MachineDominators.h"
4019618fc6SChandler Carruth #include "llvm/CodeGen/MachineFunction.h"
4119618fc6SChandler Carruth #include "llvm/CodeGen/MachineFunctionPass.h"
4219618fc6SChandler Carruth #include "llvm/CodeGen/MachineInstr.h"
4319618fc6SChandler Carruth #include "llvm/CodeGen/MachineInstrBuilder.h"
4419618fc6SChandler Carruth #include "llvm/CodeGen/MachineModuleInfo.h"
4519618fc6SChandler Carruth #include "llvm/CodeGen/MachineOperand.h"
4619618fc6SChandler Carruth #include "llvm/CodeGen/MachineRegisterInfo.h"
4719618fc6SChandler Carruth #include "llvm/CodeGen/MachineSSAUpdater.h"
4819618fc6SChandler Carruth #include "llvm/CodeGen/TargetInstrInfo.h"
4919618fc6SChandler Carruth #include "llvm/CodeGen/TargetRegisterInfo.h"
5019618fc6SChandler Carruth #include "llvm/CodeGen/TargetSchedule.h"
5119618fc6SChandler Carruth #include "llvm/CodeGen/TargetSubtargetInfo.h"
5219618fc6SChandler Carruth #include "llvm/IR/DebugLoc.h"
5319618fc6SChandler Carruth #include "llvm/MC/MCSchedule.h"
5419618fc6SChandler Carruth #include "llvm/Pass.h"
5519618fc6SChandler Carruth #include "llvm/Support/CommandLine.h"
5619618fc6SChandler Carruth #include "llvm/Support/Debug.h"
5719618fc6SChandler Carruth #include "llvm/Support/raw_ostream.h"
5819618fc6SChandler Carruth #include <algorithm>
5919618fc6SChandler Carruth #include <cassert>
6019618fc6SChandler Carruth #include <iterator>
6119618fc6SChandler Carruth #include <utility>
6219618fc6SChandler Carruth
6319618fc6SChandler Carruth using namespace llvm;
6419618fc6SChandler Carruth
6519618fc6SChandler Carruth #define PASS_KEY "x86-flags-copy-lowering"
6619618fc6SChandler Carruth #define DEBUG_TYPE PASS_KEY
6719618fc6SChandler Carruth
6819618fc6SChandler Carruth STATISTIC(NumCopiesEliminated, "Number of copies of EFLAGS eliminated");
6919618fc6SChandler Carruth STATISTIC(NumSetCCsInserted, "Number of setCC instructions inserted");
7019618fc6SChandler Carruth STATISTIC(NumTestsInserted, "Number of test instructions inserted");
7119618fc6SChandler Carruth STATISTIC(NumAddsInserted, "Number of adds instructions inserted");
7219618fc6SChandler Carruth
7319618fc6SChandler Carruth namespace {
7419618fc6SChandler Carruth
7519618fc6SChandler Carruth // Convenient array type for storing registers associated with each condition.
7619618fc6SChandler Carruth using CondRegArray = std::array<unsigned, X86::LAST_VALID_COND + 1>;
7719618fc6SChandler Carruth
7819618fc6SChandler Carruth class X86FlagsCopyLoweringPass : public MachineFunctionPass {
7919618fc6SChandler Carruth public:
X86FlagsCopyLoweringPass()80f3356722STom Stellard X86FlagsCopyLoweringPass() : MachineFunctionPass(ID) { }
8119618fc6SChandler Carruth
getPassName() const8219618fc6SChandler Carruth StringRef getPassName() const override { return "X86 EFLAGS copy lowering"; }
8319618fc6SChandler Carruth bool runOnMachineFunction(MachineFunction &MF) override;
8419618fc6SChandler Carruth void getAnalysisUsage(AnalysisUsage &AU) const override;
8519618fc6SChandler Carruth
8619618fc6SChandler Carruth /// Pass identification, replacement for typeid.
8719618fc6SChandler Carruth static char ID;
8819618fc6SChandler Carruth
8919618fc6SChandler Carruth private:
90a8653da4SSimon Pilgrim MachineRegisterInfo *MRI = nullptr;
91a8653da4SSimon Pilgrim const X86Subtarget *Subtarget = nullptr;
92a8653da4SSimon Pilgrim const X86InstrInfo *TII = nullptr;
93a8653da4SSimon Pilgrim const TargetRegisterInfo *TRI = nullptr;
94a8653da4SSimon Pilgrim const TargetRegisterClass *PromoteRC = nullptr;
95a8653da4SSimon Pilgrim MachineDominatorTree *MDT = nullptr;
9619618fc6SChandler Carruth
9719618fc6SChandler Carruth CondRegArray collectCondsInRegs(MachineBasicBlock &MBB,
98caa7b03aSChandler Carruth MachineBasicBlock::iterator CopyDefI);
9919618fc6SChandler Carruth
1003726b144SGaurav Jain Register promoteCondToReg(MachineBasicBlock &MBB,
10119618fc6SChandler Carruth MachineBasicBlock::iterator TestPos,
102605f9047SSimon Pilgrim const DebugLoc &TestLoc, X86::CondCode Cond);
103605f9047SSimon Pilgrim std::pair<unsigned, bool> getCondOrInverseInReg(
104605f9047SSimon Pilgrim MachineBasicBlock &TestMBB, MachineBasicBlock::iterator TestPos,
105605f9047SSimon Pilgrim const DebugLoc &TestLoc, X86::CondCode Cond, CondRegArray &CondRegs);
10619618fc6SChandler Carruth void insertTest(MachineBasicBlock &MBB, MachineBasicBlock::iterator Pos,
107605f9047SSimon Pilgrim const DebugLoc &Loc, unsigned Reg);
10819618fc6SChandler Carruth
10919618fc6SChandler Carruth void rewriteArithmetic(MachineBasicBlock &TestMBB,
110605f9047SSimon Pilgrim MachineBasicBlock::iterator TestPos,
111605f9047SSimon Pilgrim const DebugLoc &TestLoc, MachineInstr &MI,
112605f9047SSimon Pilgrim MachineOperand &FlagUse, CondRegArray &CondRegs);
11319618fc6SChandler Carruth void rewriteCMov(MachineBasicBlock &TestMBB,
114605f9047SSimon Pilgrim MachineBasicBlock::iterator TestPos, const DebugLoc &TestLoc,
11519618fc6SChandler Carruth MachineInstr &CMovI, MachineOperand &FlagUse,
11619618fc6SChandler Carruth CondRegArray &CondRegs);
117468a0cb5SCraig Topper void rewriteFCMov(MachineBasicBlock &TestMBB,
118605f9047SSimon Pilgrim MachineBasicBlock::iterator TestPos,
119605f9047SSimon Pilgrim const DebugLoc &TestLoc, MachineInstr &CMovI,
120605f9047SSimon Pilgrim MachineOperand &FlagUse, CondRegArray &CondRegs);
12119618fc6SChandler Carruth void rewriteCondJmp(MachineBasicBlock &TestMBB,
122605f9047SSimon Pilgrim MachineBasicBlock::iterator TestPos,
123605f9047SSimon Pilgrim const DebugLoc &TestLoc, MachineInstr &JmpI,
124605f9047SSimon Pilgrim CondRegArray &CondRegs);
12519618fc6SChandler Carruth void rewriteCopy(MachineInstr &MI, MachineOperand &FlagUse,
12619618fc6SChandler Carruth MachineInstr &CopyDefI);
12719618fc6SChandler Carruth void rewriteSetCC(MachineBasicBlock &TestMBB,
128605f9047SSimon Pilgrim MachineBasicBlock::iterator TestPos,
129605f9047SSimon Pilgrim const DebugLoc &TestLoc, MachineInstr &SetCCI,
130605f9047SSimon Pilgrim MachineOperand &FlagUse, CondRegArray &CondRegs);
13119618fc6SChandler Carruth };
13219618fc6SChandler Carruth
13319618fc6SChandler Carruth } // end anonymous namespace
13419618fc6SChandler Carruth
13519618fc6SChandler Carruth INITIALIZE_PASS_BEGIN(X86FlagsCopyLoweringPass, DEBUG_TYPE,
13619618fc6SChandler Carruth "X86 EFLAGS copy lowering", false, false)
13719618fc6SChandler Carruth INITIALIZE_PASS_END(X86FlagsCopyLoweringPass, DEBUG_TYPE,
13819618fc6SChandler Carruth "X86 EFLAGS copy lowering", false, false)
13919618fc6SChandler Carruth
createX86FlagsCopyLoweringPass()14019618fc6SChandler Carruth FunctionPass *llvm::createX86FlagsCopyLoweringPass() {
14119618fc6SChandler Carruth return new X86FlagsCopyLoweringPass();
14219618fc6SChandler Carruth }
14319618fc6SChandler Carruth
14419618fc6SChandler Carruth char X86FlagsCopyLoweringPass::ID = 0;
14519618fc6SChandler Carruth
getAnalysisUsage(AnalysisUsage & AU) const14619618fc6SChandler Carruth void X86FlagsCopyLoweringPass::getAnalysisUsage(AnalysisUsage &AU) const {
1471f87618fSChandler Carruth AU.addRequired<MachineDominatorTree>();
14819618fc6SChandler Carruth MachineFunctionPass::getAnalysisUsage(AU);
14919618fc6SChandler Carruth }
15019618fc6SChandler Carruth
15119618fc6SChandler Carruth namespace {
15219618fc6SChandler Carruth /// An enumeration of the arithmetic instruction mnemonics which have
15319618fc6SChandler Carruth /// interesting flag semantics.
15419618fc6SChandler Carruth ///
15519618fc6SChandler Carruth /// We can map instruction opcodes into these mnemonics to make it easy to
15619618fc6SChandler Carruth /// dispatch with specific functionality.
15719618fc6SChandler Carruth enum class FlagArithMnemonic {
15819618fc6SChandler Carruth ADC,
15919618fc6SChandler Carruth ADCX,
16019618fc6SChandler Carruth ADOX,
16119618fc6SChandler Carruth RCL,
16219618fc6SChandler Carruth RCR,
16319618fc6SChandler Carruth SBB,
16427857874SCraig Topper SETB,
16519618fc6SChandler Carruth };
16619618fc6SChandler Carruth } // namespace
16719618fc6SChandler Carruth
getMnemonicFromOpcode(unsigned Opcode)16819618fc6SChandler Carruth static FlagArithMnemonic getMnemonicFromOpcode(unsigned Opcode) {
16919618fc6SChandler Carruth switch (Opcode) {
17019618fc6SChandler Carruth default:
17119618fc6SChandler Carruth report_fatal_error("No support for lowering a copy into EFLAGS when used "
17219618fc6SChandler Carruth "by this instruction!");
17319618fc6SChandler Carruth
17419618fc6SChandler Carruth #define LLVM_EXPAND_INSTR_SIZES(MNEMONIC, SUFFIX) \
17519618fc6SChandler Carruth case X86::MNEMONIC##8##SUFFIX: \
17619618fc6SChandler Carruth case X86::MNEMONIC##16##SUFFIX: \
17719618fc6SChandler Carruth case X86::MNEMONIC##32##SUFFIX: \
17819618fc6SChandler Carruth case X86::MNEMONIC##64##SUFFIX:
17919618fc6SChandler Carruth
18019618fc6SChandler Carruth #define LLVM_EXPAND_ADC_SBB_INSTR(MNEMONIC) \
18119618fc6SChandler Carruth LLVM_EXPAND_INSTR_SIZES(MNEMONIC, rr) \
18219618fc6SChandler Carruth LLVM_EXPAND_INSTR_SIZES(MNEMONIC, rr_REV) \
18319618fc6SChandler Carruth LLVM_EXPAND_INSTR_SIZES(MNEMONIC, rm) \
18419618fc6SChandler Carruth LLVM_EXPAND_INSTR_SIZES(MNEMONIC, mr) \
18519618fc6SChandler Carruth case X86::MNEMONIC##8ri: \
18619618fc6SChandler Carruth case X86::MNEMONIC##16ri8: \
18719618fc6SChandler Carruth case X86::MNEMONIC##32ri8: \
18819618fc6SChandler Carruth case X86::MNEMONIC##64ri8: \
18919618fc6SChandler Carruth case X86::MNEMONIC##16ri: \
19019618fc6SChandler Carruth case X86::MNEMONIC##32ri: \
19119618fc6SChandler Carruth case X86::MNEMONIC##64ri32: \
19219618fc6SChandler Carruth case X86::MNEMONIC##8mi: \
19319618fc6SChandler Carruth case X86::MNEMONIC##16mi8: \
19419618fc6SChandler Carruth case X86::MNEMONIC##32mi8: \
19519618fc6SChandler Carruth case X86::MNEMONIC##64mi8: \
19619618fc6SChandler Carruth case X86::MNEMONIC##16mi: \
19719618fc6SChandler Carruth case X86::MNEMONIC##32mi: \
19819618fc6SChandler Carruth case X86::MNEMONIC##64mi32: \
19919618fc6SChandler Carruth case X86::MNEMONIC##8i8: \
20019618fc6SChandler Carruth case X86::MNEMONIC##16i16: \
20119618fc6SChandler Carruth case X86::MNEMONIC##32i32: \
20219618fc6SChandler Carruth case X86::MNEMONIC##64i32:
20319618fc6SChandler Carruth
20419618fc6SChandler Carruth LLVM_EXPAND_ADC_SBB_INSTR(ADC)
20519618fc6SChandler Carruth return FlagArithMnemonic::ADC;
20619618fc6SChandler Carruth
20719618fc6SChandler Carruth LLVM_EXPAND_ADC_SBB_INSTR(SBB)
20819618fc6SChandler Carruth return FlagArithMnemonic::SBB;
20919618fc6SChandler Carruth
21019618fc6SChandler Carruth #undef LLVM_EXPAND_ADC_SBB_INSTR
21119618fc6SChandler Carruth
21219618fc6SChandler Carruth LLVM_EXPAND_INSTR_SIZES(RCL, rCL)
21319618fc6SChandler Carruth LLVM_EXPAND_INSTR_SIZES(RCL, r1)
21419618fc6SChandler Carruth LLVM_EXPAND_INSTR_SIZES(RCL, ri)
21519618fc6SChandler Carruth return FlagArithMnemonic::RCL;
21619618fc6SChandler Carruth
21719618fc6SChandler Carruth LLVM_EXPAND_INSTR_SIZES(RCR, rCL)
21819618fc6SChandler Carruth LLVM_EXPAND_INSTR_SIZES(RCR, r1)
21919618fc6SChandler Carruth LLVM_EXPAND_INSTR_SIZES(RCR, ri)
22019618fc6SChandler Carruth return FlagArithMnemonic::RCR;
22119618fc6SChandler Carruth
22219618fc6SChandler Carruth #undef LLVM_EXPAND_INSTR_SIZES
22319618fc6SChandler Carruth
22419618fc6SChandler Carruth case X86::ADCX32rr:
22519618fc6SChandler Carruth case X86::ADCX64rr:
22619618fc6SChandler Carruth case X86::ADCX32rm:
22719618fc6SChandler Carruth case X86::ADCX64rm:
22819618fc6SChandler Carruth return FlagArithMnemonic::ADCX;
22919618fc6SChandler Carruth
23019618fc6SChandler Carruth case X86::ADOX32rr:
23119618fc6SChandler Carruth case X86::ADOX64rr:
23219618fc6SChandler Carruth case X86::ADOX32rm:
23319618fc6SChandler Carruth case X86::ADOX64rm:
23419618fc6SChandler Carruth return FlagArithMnemonic::ADOX;
23527857874SCraig Topper
23627857874SCraig Topper case X86::SETB_C32r:
23727857874SCraig Topper case X86::SETB_C64r:
23827857874SCraig Topper return FlagArithMnemonic::SETB;
23919618fc6SChandler Carruth }
24019618fc6SChandler Carruth }
24119618fc6SChandler Carruth
splitBlock(MachineBasicBlock & MBB,MachineInstr & SplitI,const X86InstrInfo & TII)24219618fc6SChandler Carruth static MachineBasicBlock &splitBlock(MachineBasicBlock &MBB,
24319618fc6SChandler Carruth MachineInstr &SplitI,
24419618fc6SChandler Carruth const X86InstrInfo &TII) {
24519618fc6SChandler Carruth MachineFunction &MF = *MBB.getParent();
24619618fc6SChandler Carruth
24719618fc6SChandler Carruth assert(SplitI.getParent() == &MBB &&
24819618fc6SChandler Carruth "Split instruction must be in the split block!");
24919618fc6SChandler Carruth assert(SplitI.isBranch() &&
25019618fc6SChandler Carruth "Only designed to split a tail of branch instructions!");
25180aa2290SCraig Topper assert(X86::getCondFromBranch(SplitI) != X86::COND_INVALID &&
25219618fc6SChandler Carruth "Must split on an actual jCC instruction!");
25319618fc6SChandler Carruth
25419618fc6SChandler Carruth // Dig out the previous instruction to the split point.
25519618fc6SChandler Carruth MachineInstr &PrevI = *std::prev(SplitI.getIterator());
25619618fc6SChandler Carruth assert(PrevI.isBranch() && "Must split after a branch!");
25780aa2290SCraig Topper assert(X86::getCondFromBranch(PrevI) != X86::COND_INVALID &&
25819618fc6SChandler Carruth "Must split after an actual jCC instruction!");
25919618fc6SChandler Carruth assert(!std::prev(PrevI.getIterator())->isTerminator() &&
26019618fc6SChandler Carruth "Must only have this one terminator prior to the split!");
26119618fc6SChandler Carruth
26219618fc6SChandler Carruth // Grab the one successor edge that will stay in `MBB`.
26319618fc6SChandler Carruth MachineBasicBlock &UnsplitSucc = *PrevI.getOperand(0).getMBB();
26419618fc6SChandler Carruth
26519618fc6SChandler Carruth // Analyze the original block to see if we are actually splitting an edge
26619618fc6SChandler Carruth // into two edges. This can happen when we have multiple conditional jumps to
26719618fc6SChandler Carruth // the same successor.
26819618fc6SChandler Carruth bool IsEdgeSplit =
26919618fc6SChandler Carruth std::any_of(SplitI.getIterator(), MBB.instr_end(),
27019618fc6SChandler Carruth [&](MachineInstr &MI) {
27119618fc6SChandler Carruth assert(MI.isTerminator() &&
27219618fc6SChandler Carruth "Should only have spliced terminators!");
27319618fc6SChandler Carruth return llvm::any_of(
27419618fc6SChandler Carruth MI.operands(), [&](MachineOperand &MOp) {
27519618fc6SChandler Carruth return MOp.isMBB() && MOp.getMBB() == &UnsplitSucc;
27619618fc6SChandler Carruth });
27719618fc6SChandler Carruth }) ||
27819618fc6SChandler Carruth MBB.getFallThrough() == &UnsplitSucc;
27919618fc6SChandler Carruth
28019618fc6SChandler Carruth MachineBasicBlock &NewMBB = *MF.CreateMachineBasicBlock();
28119618fc6SChandler Carruth
28219618fc6SChandler Carruth // Insert the new block immediately after the current one. Any existing
28319618fc6SChandler Carruth // fallthrough will be sunk into this new block anyways.
28419618fc6SChandler Carruth MF.insert(std::next(MachineFunction::iterator(&MBB)), &NewMBB);
28519618fc6SChandler Carruth
28619618fc6SChandler Carruth // Splice the tail of instructions into the new block.
28719618fc6SChandler Carruth NewMBB.splice(NewMBB.end(), &MBB, SplitI.getIterator(), MBB.end());
28819618fc6SChandler Carruth
28919618fc6SChandler Carruth // Copy the necessary succesors (and their probability info) into the new
29019618fc6SChandler Carruth // block.
29119618fc6SChandler Carruth for (auto SI = MBB.succ_begin(), SE = MBB.succ_end(); SI != SE; ++SI)
29219618fc6SChandler Carruth if (IsEdgeSplit || *SI != &UnsplitSucc)
29319618fc6SChandler Carruth NewMBB.copySuccessor(&MBB, SI);
29419618fc6SChandler Carruth // Normalize the probabilities if we didn't end up splitting the edge.
29519618fc6SChandler Carruth if (!IsEdgeSplit)
29619618fc6SChandler Carruth NewMBB.normalizeSuccProbs();
29719618fc6SChandler Carruth
29819618fc6SChandler Carruth // Now replace all of the moved successors in the original block with the new
29919618fc6SChandler Carruth // block. This will merge their probabilities.
30019618fc6SChandler Carruth for (MachineBasicBlock *Succ : NewMBB.successors())
30119618fc6SChandler Carruth if (Succ != &UnsplitSucc)
30219618fc6SChandler Carruth MBB.replaceSuccessor(Succ, &NewMBB);
30319618fc6SChandler Carruth
30419618fc6SChandler Carruth // We should always end up replacing at least one successor.
30519618fc6SChandler Carruth assert(MBB.isSuccessor(&NewMBB) &&
30619618fc6SChandler Carruth "Failed to make the new block a successor!");
30719618fc6SChandler Carruth
30819618fc6SChandler Carruth // Now update all the PHIs.
30919618fc6SChandler Carruth for (MachineBasicBlock *Succ : NewMBB.successors()) {
31019618fc6SChandler Carruth for (MachineInstr &MI : *Succ) {
31119618fc6SChandler Carruth if (!MI.isPHI())
31219618fc6SChandler Carruth break;
31319618fc6SChandler Carruth
31419618fc6SChandler Carruth for (int OpIdx = 1, NumOps = MI.getNumOperands(); OpIdx < NumOps;
31519618fc6SChandler Carruth OpIdx += 2) {
31619618fc6SChandler Carruth MachineOperand &OpV = MI.getOperand(OpIdx);
31719618fc6SChandler Carruth MachineOperand &OpMBB = MI.getOperand(OpIdx + 1);
31819618fc6SChandler Carruth assert(OpMBB.isMBB() && "Block operand to a PHI is not a block!");
31919618fc6SChandler Carruth if (OpMBB.getMBB() != &MBB)
32019618fc6SChandler Carruth continue;
32119618fc6SChandler Carruth
32219618fc6SChandler Carruth // Replace the operand for unsplit successors
32319618fc6SChandler Carruth if (!IsEdgeSplit || Succ != &UnsplitSucc) {
32419618fc6SChandler Carruth OpMBB.setMBB(&NewMBB);
32519618fc6SChandler Carruth
32619618fc6SChandler Carruth // We have to continue scanning as there may be multiple entries in
32719618fc6SChandler Carruth // the PHI.
32819618fc6SChandler Carruth continue;
32919618fc6SChandler Carruth }
33019618fc6SChandler Carruth
33119618fc6SChandler Carruth // When we have split the edge append a new successor.
33219618fc6SChandler Carruth MI.addOperand(MF, OpV);
33319618fc6SChandler Carruth MI.addOperand(MF, MachineOperand::CreateMBB(&NewMBB));
33419618fc6SChandler Carruth break;
33519618fc6SChandler Carruth }
33619618fc6SChandler Carruth }
33719618fc6SChandler Carruth }
33819618fc6SChandler Carruth
33919618fc6SChandler Carruth return NewMBB;
34019618fc6SChandler Carruth }
34119618fc6SChandler Carruth
getCondFromFCMOV(unsigned Opcode)342468a0cb5SCraig Topper static X86::CondCode getCondFromFCMOV(unsigned Opcode) {
343468a0cb5SCraig Topper switch (Opcode) {
344468a0cb5SCraig Topper default: return X86::COND_INVALID;
345468a0cb5SCraig Topper case X86::CMOVBE_Fp32: case X86::CMOVBE_Fp64: case X86::CMOVBE_Fp80:
346468a0cb5SCraig Topper return X86::COND_BE;
347468a0cb5SCraig Topper case X86::CMOVB_Fp32: case X86::CMOVB_Fp64: case X86::CMOVB_Fp80:
348468a0cb5SCraig Topper return X86::COND_B;
349468a0cb5SCraig Topper case X86::CMOVE_Fp32: case X86::CMOVE_Fp64: case X86::CMOVE_Fp80:
350468a0cb5SCraig Topper return X86::COND_E;
351468a0cb5SCraig Topper case X86::CMOVNBE_Fp32: case X86::CMOVNBE_Fp64: case X86::CMOVNBE_Fp80:
352468a0cb5SCraig Topper return X86::COND_A;
353468a0cb5SCraig Topper case X86::CMOVNB_Fp32: case X86::CMOVNB_Fp64: case X86::CMOVNB_Fp80:
354468a0cb5SCraig Topper return X86::COND_AE;
355468a0cb5SCraig Topper case X86::CMOVNE_Fp32: case X86::CMOVNE_Fp64: case X86::CMOVNE_Fp80:
356468a0cb5SCraig Topper return X86::COND_NE;
357468a0cb5SCraig Topper case X86::CMOVNP_Fp32: case X86::CMOVNP_Fp64: case X86::CMOVNP_Fp80:
358468a0cb5SCraig Topper return X86::COND_NP;
359468a0cb5SCraig Topper case X86::CMOVP_Fp32: case X86::CMOVP_Fp64: case X86::CMOVP_Fp80:
360468a0cb5SCraig Topper return X86::COND_P;
361468a0cb5SCraig Topper }
362468a0cb5SCraig Topper }
363468a0cb5SCraig Topper
runOnMachineFunction(MachineFunction & MF)36419618fc6SChandler Carruth bool X86FlagsCopyLoweringPass::runOnMachineFunction(MachineFunction &MF) {
365d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "********** " << getPassName() << " : " << MF.getName()
36619618fc6SChandler Carruth << " **********\n");
36719618fc6SChandler Carruth
368bde2b43cSCraig Topper Subtarget = &MF.getSubtarget<X86Subtarget>();
36919618fc6SChandler Carruth MRI = &MF.getRegInfo();
370bde2b43cSCraig Topper TII = Subtarget->getInstrInfo();
371bde2b43cSCraig Topper TRI = Subtarget->getRegisterInfo();
3721f87618fSChandler Carruth MDT = &getAnalysis<MachineDominatorTree>();
37319618fc6SChandler Carruth PromoteRC = &X86::GR8RegClass;
37419618fc6SChandler Carruth
37519618fc6SChandler Carruth if (MF.begin() == MF.end())
37619618fc6SChandler Carruth // Nothing to do for a degenerate empty function...
37719618fc6SChandler Carruth return false;
37819618fc6SChandler Carruth
379caa7b03aSChandler Carruth // Collect the copies in RPO so that when there are chains where a copy is in
380caa7b03aSChandler Carruth // turn copied again we visit the first one first. This ensures we can find
381caa7b03aSChandler Carruth // viable locations for testing the original EFLAGS that dominate all the
382caa7b03aSChandler Carruth // uses across complex CFGs.
38319618fc6SChandler Carruth SmallVector<MachineInstr *, 4> Copies;
384caa7b03aSChandler Carruth ReversePostOrderTraversal<MachineFunction *> RPOT(&MF);
385caa7b03aSChandler Carruth for (MachineBasicBlock *MBB : RPOT)
386caa7b03aSChandler Carruth for (MachineInstr &MI : *MBB)
38719618fc6SChandler Carruth if (MI.getOpcode() == TargetOpcode::COPY &&
38819618fc6SChandler Carruth MI.getOperand(0).getReg() == X86::EFLAGS)
38919618fc6SChandler Carruth Copies.push_back(&MI);
39019618fc6SChandler Carruth
39119618fc6SChandler Carruth for (MachineInstr *CopyI : Copies) {
39219618fc6SChandler Carruth MachineBasicBlock &MBB = *CopyI->getParent();
39319618fc6SChandler Carruth
39419618fc6SChandler Carruth MachineOperand &VOp = CopyI->getOperand(1);
39519618fc6SChandler Carruth assert(VOp.isReg() &&
39619618fc6SChandler Carruth "The input to the copy for EFLAGS should always be a register!");
39719618fc6SChandler Carruth MachineInstr &CopyDefI = *MRI->getVRegDef(VOp.getReg());
39819618fc6SChandler Carruth if (CopyDefI.getOpcode() != TargetOpcode::COPY) {
39919618fc6SChandler Carruth // FIXME: The big likely candidate here are PHI nodes. We could in theory
40019618fc6SChandler Carruth // handle PHI nodes, but it gets really, really hard. Insanely hard. Hard
40119618fc6SChandler Carruth // enough that it is probably better to change every other part of LLVM
40219618fc6SChandler Carruth // to avoid creating them. The issue is that once we have PHIs we won't
40319618fc6SChandler Carruth // know which original EFLAGS value we need to capture with our setCCs
40419618fc6SChandler Carruth // below. The end result will be computing a complete set of setCCs that
40519618fc6SChandler Carruth // we *might* want, computing them in every place where we copy *out* of
40619618fc6SChandler Carruth // EFLAGS and then doing SSA formation on all of them to insert necessary
40719618fc6SChandler Carruth // PHI nodes and consume those here. Then hoping that somehow we DCE the
40819618fc6SChandler Carruth // unnecessary ones. This DCE seems very unlikely to be successful and so
40919618fc6SChandler Carruth // we will almost certainly end up with a glut of dead setCC
41019618fc6SChandler Carruth // instructions. Until we have a motivating test case and fail to avoid
41119618fc6SChandler Carruth // it by changing other parts of LLVM's lowering, we refuse to handle
41219618fc6SChandler Carruth // this complex case here.
413d34e60caSNicola Zaghen LLVM_DEBUG(
414d34e60caSNicola Zaghen dbgs() << "ERROR: Encountered unexpected def of an eflags copy: ";
41519618fc6SChandler Carruth CopyDefI.dump());
41619618fc6SChandler Carruth report_fatal_error(
41719618fc6SChandler Carruth "Cannot lower EFLAGS copy unless it is defined in turn by a copy!");
41819618fc6SChandler Carruth }
41919618fc6SChandler Carruth
42019618fc6SChandler Carruth auto Cleanup = make_scope_exit([&] {
42119618fc6SChandler Carruth // All uses of the EFLAGS copy are now rewritten, kill the copy into
42219618fc6SChandler Carruth // eflags and if dead the copy from.
42319618fc6SChandler Carruth CopyI->eraseFromParent();
42419618fc6SChandler Carruth if (MRI->use_empty(CopyDefI.getOperand(0).getReg()))
42519618fc6SChandler Carruth CopyDefI.eraseFromParent();
42619618fc6SChandler Carruth ++NumCopiesEliminated;
42719618fc6SChandler Carruth });
42819618fc6SChandler Carruth
42919618fc6SChandler Carruth MachineOperand &DOp = CopyI->getOperand(0);
43019618fc6SChandler Carruth assert(DOp.isDef() && "Expected register def!");
43119618fc6SChandler Carruth assert(DOp.getReg() == X86::EFLAGS && "Unexpected copy def register!");
43219618fc6SChandler Carruth if (DOp.isDead())
43319618fc6SChandler Carruth continue;
43419618fc6SChandler Carruth
435caa7b03aSChandler Carruth MachineBasicBlock *TestMBB = CopyDefI.getParent();
43619618fc6SChandler Carruth auto TestPos = CopyDefI.getIterator();
43719618fc6SChandler Carruth DebugLoc TestLoc = CopyDefI.getDebugLoc();
43819618fc6SChandler Carruth
439d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Rewriting copy: "; CopyI->dump());
44019618fc6SChandler Carruth
441caa7b03aSChandler Carruth // Walk up across live-in EFLAGS to find where they were actually def'ed.
442caa7b03aSChandler Carruth //
443caa7b03aSChandler Carruth // This copy's def may just be part of a region of blocks covered by
444caa7b03aSChandler Carruth // a single def of EFLAGS and we want to find the top of that region where
445caa7b03aSChandler Carruth // possible.
446caa7b03aSChandler Carruth //
447caa7b03aSChandler Carruth // This is essentially a search for a *candidate* reaching definition
448caa7b03aSChandler Carruth // location. We don't need to ever find the actual reaching definition here,
449caa7b03aSChandler Carruth // but we want to walk up the dominator tree to find the highest point which
450caa7b03aSChandler Carruth // would be viable for such a definition.
451caa7b03aSChandler Carruth auto HasEFLAGSClobber = [&](MachineBasicBlock::iterator Begin,
452caa7b03aSChandler Carruth MachineBasicBlock::iterator End) {
453caa7b03aSChandler Carruth // Scan backwards as we expect these to be relatively short and often find
454caa7b03aSChandler Carruth // a clobber near the end.
455caa7b03aSChandler Carruth return llvm::any_of(
456caa7b03aSChandler Carruth llvm::reverse(llvm::make_range(Begin, End)), [&](MachineInstr &MI) {
457caa7b03aSChandler Carruth // Flag any instruction (other than the copy we are
458caa7b03aSChandler Carruth // currently rewriting) that defs EFLAGS.
459caa7b03aSChandler Carruth return &MI != CopyI && MI.findRegisterDefOperand(X86::EFLAGS);
460caa7b03aSChandler Carruth });
461caa7b03aSChandler Carruth };
462caa7b03aSChandler Carruth auto HasEFLAGSClobberPath = [&](MachineBasicBlock *BeginMBB,
463caa7b03aSChandler Carruth MachineBasicBlock *EndMBB) {
464caa7b03aSChandler Carruth assert(MDT->dominates(BeginMBB, EndMBB) &&
465caa7b03aSChandler Carruth "Only support paths down the dominator tree!");
466caa7b03aSChandler Carruth SmallPtrSet<MachineBasicBlock *, 4> Visited;
467caa7b03aSChandler Carruth SmallVector<MachineBasicBlock *, 4> Worklist;
468caa7b03aSChandler Carruth // We terminate at the beginning. No need to scan it.
469caa7b03aSChandler Carruth Visited.insert(BeginMBB);
470caa7b03aSChandler Carruth Worklist.push_back(EndMBB);
471caa7b03aSChandler Carruth do {
472caa7b03aSChandler Carruth auto *MBB = Worklist.pop_back_val();
473caa7b03aSChandler Carruth for (auto *PredMBB : MBB->predecessors()) {
474caa7b03aSChandler Carruth if (!Visited.insert(PredMBB).second)
475caa7b03aSChandler Carruth continue;
476caa7b03aSChandler Carruth if (HasEFLAGSClobber(PredMBB->begin(), PredMBB->end()))
477caa7b03aSChandler Carruth return true;
478caa7b03aSChandler Carruth // Enqueue this block to walk its predecessors.
479caa7b03aSChandler Carruth Worklist.push_back(PredMBB);
480caa7b03aSChandler Carruth }
481caa7b03aSChandler Carruth } while (!Worklist.empty());
482caa7b03aSChandler Carruth // No clobber found along a path from the begin to end.
483caa7b03aSChandler Carruth return false;
484caa7b03aSChandler Carruth };
485caa7b03aSChandler Carruth while (TestMBB->isLiveIn(X86::EFLAGS) && !TestMBB->pred_empty() &&
486caa7b03aSChandler Carruth !HasEFLAGSClobber(TestMBB->begin(), TestPos)) {
487caa7b03aSChandler Carruth // Find the nearest common dominator of the predecessors, as
488caa7b03aSChandler Carruth // that will be the best candidate to hoist into.
489caa7b03aSChandler Carruth MachineBasicBlock *HoistMBB =
490caa7b03aSChandler Carruth std::accumulate(std::next(TestMBB->pred_begin()), TestMBB->pred_end(),
491caa7b03aSChandler Carruth *TestMBB->pred_begin(),
492caa7b03aSChandler Carruth [&](MachineBasicBlock *LHS, MachineBasicBlock *RHS) {
493caa7b03aSChandler Carruth return MDT->findNearestCommonDominator(LHS, RHS);
494caa7b03aSChandler Carruth });
495caa7b03aSChandler Carruth
496caa7b03aSChandler Carruth // Now we need to scan all predecessors that may be reached along paths to
497caa7b03aSChandler Carruth // the hoist block. A clobber anywhere in any of these blocks the hoist.
498caa7b03aSChandler Carruth // Note that this even handles loops because we require *no* clobbers.
499caa7b03aSChandler Carruth if (HasEFLAGSClobberPath(HoistMBB, TestMBB))
500caa7b03aSChandler Carruth break;
501caa7b03aSChandler Carruth
502caa7b03aSChandler Carruth // We also need the terminators to not sneakily clobber flags.
503caa7b03aSChandler Carruth if (HasEFLAGSClobber(HoistMBB->getFirstTerminator()->getIterator(),
504caa7b03aSChandler Carruth HoistMBB->instr_end()))
505caa7b03aSChandler Carruth break;
506caa7b03aSChandler Carruth
507caa7b03aSChandler Carruth // We found a viable location, hoist our test position to it.
508caa7b03aSChandler Carruth TestMBB = HoistMBB;
509caa7b03aSChandler Carruth TestPos = TestMBB->getFirstTerminator()->getIterator();
510caa7b03aSChandler Carruth // Clear the debug location as it would just be confusing after hoisting.
511caa7b03aSChandler Carruth TestLoc = DebugLoc();
512caa7b03aSChandler Carruth }
513caa7b03aSChandler Carruth LLVM_DEBUG({
514caa7b03aSChandler Carruth auto DefIt = llvm::find_if(
515caa7b03aSChandler Carruth llvm::reverse(llvm::make_range(TestMBB->instr_begin(), TestPos)),
516caa7b03aSChandler Carruth [&](MachineInstr &MI) {
517caa7b03aSChandler Carruth return MI.findRegisterDefOperand(X86::EFLAGS);
518caa7b03aSChandler Carruth });
519caa7b03aSChandler Carruth if (DefIt.base() != TestMBB->instr_begin()) {
520caa7b03aSChandler Carruth dbgs() << " Using EFLAGS defined by: ";
521caa7b03aSChandler Carruth DefIt->dump();
522caa7b03aSChandler Carruth } else {
523caa7b03aSChandler Carruth dbgs() << " Using live-in flags for BB:\n";
524caa7b03aSChandler Carruth TestMBB->dump();
525caa7b03aSChandler Carruth }
526caa7b03aSChandler Carruth });
527caa7b03aSChandler Carruth
528b4faf4ceSChandler Carruth // While rewriting uses, we buffer jumps and rewrite them in a second pass
529b4faf4ceSChandler Carruth // because doing so will perturb the CFG that we are walking to find the
530b4faf4ceSChandler Carruth // uses in the first place.
53119618fc6SChandler Carruth SmallVector<MachineInstr *, 4> JmpIs;
53219618fc6SChandler Carruth
53319618fc6SChandler Carruth // Gather the condition flags that have already been preserved in
53419618fc6SChandler Carruth // registers. We do this from scratch each time as we expect there to be
53519618fc6SChandler Carruth // very few of them and we expect to not revisit the same copy definition
53619618fc6SChandler Carruth // many times. If either of those change sufficiently we could build a map
53719618fc6SChandler Carruth // of these up front instead.
538caa7b03aSChandler Carruth CondRegArray CondRegs = collectCondsInRegs(*TestMBB, TestPos);
53919618fc6SChandler Carruth
5401f87618fSChandler Carruth // Collect the basic blocks we need to scan. Typically this will just be
5411f87618fSChandler Carruth // a single basic block but we may have to scan multiple blocks if the
5421f87618fSChandler Carruth // EFLAGS copy lives into successors.
5431f87618fSChandler Carruth SmallVector<MachineBasicBlock *, 2> Blocks;
5441f87618fSChandler Carruth SmallPtrSet<MachineBasicBlock *, 2> VisitedBlocks;
5451f87618fSChandler Carruth Blocks.push_back(&MBB);
5461f87618fSChandler Carruth
5471f87618fSChandler Carruth do {
5481f87618fSChandler Carruth MachineBasicBlock &UseMBB = *Blocks.pop_back_val();
5491f87618fSChandler Carruth
550b4faf4ceSChandler Carruth // Track when if/when we find a kill of the flags in this block.
551b4faf4ceSChandler Carruth bool FlagsKilled = false;
552b4faf4ceSChandler Carruth
553caa7b03aSChandler Carruth // In most cases, we walk from the beginning to the end of the block. But
554caa7b03aSChandler Carruth // when the block is the same block as the copy is from, we will visit it
555caa7b03aSChandler Carruth // twice. The first time we start from the copy and go to the end. The
556caa7b03aSChandler Carruth // second time we start from the beginning and go to the copy. This lets
557caa7b03aSChandler Carruth // us handle copies inside of cycles.
558caa7b03aSChandler Carruth // FIXME: This loop is *super* confusing. This is at least in part
559caa7b03aSChandler Carruth // a symptom of all of this routine needing to be refactored into
560caa7b03aSChandler Carruth // documentable components. Once done, there may be a better way to write
561caa7b03aSChandler Carruth // this loop.
562caa7b03aSChandler Carruth for (auto MII = (&UseMBB == &MBB && !VisitedBlocks.count(&UseMBB))
563caa7b03aSChandler Carruth ? std::next(CopyI->getIterator())
5641f87618fSChandler Carruth : UseMBB.instr_begin(),
5651f87618fSChandler Carruth MIE = UseMBB.instr_end();
56619618fc6SChandler Carruth MII != MIE;) {
56719618fc6SChandler Carruth MachineInstr &MI = *MII++;
568caa7b03aSChandler Carruth // If we are in the original copy block and encounter either the copy
569caa7b03aSChandler Carruth // def or the copy itself, break so that we don't re-process any part of
570caa7b03aSChandler Carruth // the block or process the instructions in the range that was copied
571caa7b03aSChandler Carruth // over.
572caa7b03aSChandler Carruth if (&MI == CopyI || &MI == &CopyDefI) {
573caa7b03aSChandler Carruth assert(&UseMBB == &MBB && VisitedBlocks.count(&MBB) &&
574caa7b03aSChandler Carruth "Should only encounter these on the second pass over the "
575caa7b03aSChandler Carruth "original block.");
576caa7b03aSChandler Carruth break;
577caa7b03aSChandler Carruth }
578caa7b03aSChandler Carruth
57919618fc6SChandler Carruth MachineOperand *FlagUse = MI.findRegisterUseOperand(X86::EFLAGS);
58019618fc6SChandler Carruth if (!FlagUse) {
58119618fc6SChandler Carruth if (MI.findRegisterDefOperand(X86::EFLAGS)) {
58219618fc6SChandler Carruth // If EFLAGS are defined, it's as-if they were killed. We can stop
58319618fc6SChandler Carruth // scanning here.
58419618fc6SChandler Carruth //
58519618fc6SChandler Carruth // NB!!! Many instructions only modify some flags. LLVM currently
5861f87618fSChandler Carruth // models this as clobbering all flags, but if that ever changes
5871f87618fSChandler Carruth // this will need to be carefully updated to handle that more
5881f87618fSChandler Carruth // complex logic.
58919618fc6SChandler Carruth FlagsKilled = true;
59019618fc6SChandler Carruth break;
59119618fc6SChandler Carruth }
59219618fc6SChandler Carruth continue;
59319618fc6SChandler Carruth }
59419618fc6SChandler Carruth
595d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " Rewriting use: "; MI.dump());
59619618fc6SChandler Carruth
59719618fc6SChandler Carruth // Check the kill flag before we rewrite as that may change it.
59819618fc6SChandler Carruth if (FlagUse->isKill())
59919618fc6SChandler Carruth FlagsKilled = true;
60019618fc6SChandler Carruth
60119618fc6SChandler Carruth // Once we encounter a branch, the rest of the instructions must also be
60219618fc6SChandler Carruth // branches. We can't rewrite in place here, so we handle them below.
60319618fc6SChandler Carruth //
60419618fc6SChandler Carruth // Note that we don't have to handle tail calls here, even conditional
60519618fc6SChandler Carruth // tail calls, as those are not introduced into the X86 MI until post-RA
60619618fc6SChandler Carruth // branch folding or black placement. As a consequence, we get to deal
60719618fc6SChandler Carruth // with the simpler formulation of conditional branches followed by tail
60819618fc6SChandler Carruth // calls.
60980aa2290SCraig Topper if (X86::getCondFromBranch(MI) != X86::COND_INVALID) {
61019618fc6SChandler Carruth auto JmpIt = MI.getIterator();
61119618fc6SChandler Carruth do {
61219618fc6SChandler Carruth JmpIs.push_back(&*JmpIt);
61319618fc6SChandler Carruth ++JmpIt;
6141f87618fSChandler Carruth } while (JmpIt != UseMBB.instr_end() &&
61580aa2290SCraig Topper X86::getCondFromBranch(*JmpIt) !=
61619618fc6SChandler Carruth X86::COND_INVALID);
61719618fc6SChandler Carruth break;
61819618fc6SChandler Carruth }
61919618fc6SChandler Carruth
62019618fc6SChandler Carruth // Otherwise we can just rewrite in-place.
621e0bfeb5fSCraig Topper if (X86::getCondFromCMov(MI) != X86::COND_INVALID) {
622caa7b03aSChandler Carruth rewriteCMov(*TestMBB, TestPos, TestLoc, MI, *FlagUse, CondRegs);
623468a0cb5SCraig Topper } else if (getCondFromFCMOV(MI.getOpcode()) != X86::COND_INVALID) {
624468a0cb5SCraig Topper rewriteFCMov(*TestMBB, TestPos, TestLoc, MI, *FlagUse, CondRegs);
6257323c2bfSCraig Topper } else if (X86::getCondFromSETCC(MI) != X86::COND_INVALID) {
626caa7b03aSChandler Carruth rewriteSetCC(*TestMBB, TestPos, TestLoc, MI, *FlagUse, CondRegs);
62719618fc6SChandler Carruth } else if (MI.getOpcode() == TargetOpcode::COPY) {
62819618fc6SChandler Carruth rewriteCopy(MI, *FlagUse, CopyDefI);
62919618fc6SChandler Carruth } else {
6305ecd81aaSChandler Carruth // We assume all other instructions that use flags also def them.
63119618fc6SChandler Carruth assert(MI.findRegisterDefOperand(X86::EFLAGS) &&
63219618fc6SChandler Carruth "Expected a def of EFLAGS for this instruction!");
63319618fc6SChandler Carruth
63419618fc6SChandler Carruth // NB!!! Several arithmetic instructions only *partially* update
63519618fc6SChandler Carruth // flags. Theoretically, we could generate MI code sequences that
63619618fc6SChandler Carruth // would rely on this fact and observe different flags independently.
63719618fc6SChandler Carruth // But currently LLVM models all of these instructions as clobbering
63819618fc6SChandler Carruth // all the flags in an undef way. We rely on that to simplify the
63919618fc6SChandler Carruth // logic.
64019618fc6SChandler Carruth FlagsKilled = true;
64119618fc6SChandler Carruth
6425ecd81aaSChandler Carruth // Generically handle remaining uses as arithmetic instructions.
643caa7b03aSChandler Carruth rewriteArithmetic(*TestMBB, TestPos, TestLoc, MI, *FlagUse,
6445ecd81aaSChandler Carruth CondRegs);
64519618fc6SChandler Carruth }
64619618fc6SChandler Carruth
64719618fc6SChandler Carruth // If this was the last use of the flags, we're done.
64819618fc6SChandler Carruth if (FlagsKilled)
64919618fc6SChandler Carruth break;
65019618fc6SChandler Carruth }
65119618fc6SChandler Carruth
6521f87618fSChandler Carruth // If the flags were killed, we're done with this block.
6531f87618fSChandler Carruth if (FlagsKilled)
6541c8234f6SChandler Carruth continue;
6551f87618fSChandler Carruth
6561f87618fSChandler Carruth // Otherwise we need to scan successors for ones where the flags live-in
6571f87618fSChandler Carruth // and queue those up for processing.
6581f87618fSChandler Carruth for (MachineBasicBlock *SuccMBB : UseMBB.successors())
6591f87618fSChandler Carruth if (SuccMBB->isLiveIn(X86::EFLAGS) &&
660caa7b03aSChandler Carruth VisitedBlocks.insert(SuccMBB).second) {
661caa7b03aSChandler Carruth // We currently don't do any PHI insertion and so we require that the
662caa7b03aSChandler Carruth // test basic block dominates all of the use basic blocks. Further, we
663caa7b03aSChandler Carruth // can't have a cycle from the test block back to itself as that would
664caa7b03aSChandler Carruth // create a cycle requiring a PHI to break it.
665caa7b03aSChandler Carruth //
666caa7b03aSChandler Carruth // We could in theory do PHI insertion here if it becomes useful by
667caa7b03aSChandler Carruth // just taking undef values in along every edge that we don't trace
668caa7b03aSChandler Carruth // this EFLAGS copy along. This isn't as bad as fully general PHI
669caa7b03aSChandler Carruth // insertion, but still seems like a great deal of complexity.
670caa7b03aSChandler Carruth //
671caa7b03aSChandler Carruth // Because it is theoretically possible that some earlier MI pass or
672caa7b03aSChandler Carruth // other lowering transformation could induce this to happen, we do
673caa7b03aSChandler Carruth // a hard check even in non-debug builds here.
674caa7b03aSChandler Carruth if (SuccMBB == TestMBB || !MDT->dominates(TestMBB, SuccMBB)) {
675caa7b03aSChandler Carruth LLVM_DEBUG({
676caa7b03aSChandler Carruth dbgs()
677caa7b03aSChandler Carruth << "ERROR: Encountered use that is not dominated by our test "
678caa7b03aSChandler Carruth "basic block! Rewriting this would require inserting PHI "
679caa7b03aSChandler Carruth "nodes to track the flag state across the CFG.\n\nTest "
680caa7b03aSChandler Carruth "block:\n";
681caa7b03aSChandler Carruth TestMBB->dump();
682caa7b03aSChandler Carruth dbgs() << "Use block:\n";
683caa7b03aSChandler Carruth SuccMBB->dump();
684caa7b03aSChandler Carruth });
685caa7b03aSChandler Carruth report_fatal_error(
686caa7b03aSChandler Carruth "Cannot lower EFLAGS copy when original copy def "
687caa7b03aSChandler Carruth "does not dominate all uses.");
688caa7b03aSChandler Carruth }
689caa7b03aSChandler Carruth
6901f87618fSChandler Carruth Blocks.push_back(SuccMBB);
691ee57469aSJonas Paulsson
692ee57469aSJonas Paulsson // After this, EFLAGS will be recreated before each use.
693ee57469aSJonas Paulsson SuccMBB->removeLiveIn(X86::EFLAGS);
694caa7b03aSChandler Carruth }
6951f87618fSChandler Carruth } while (!Blocks.empty());
69619618fc6SChandler Carruth
69719618fc6SChandler Carruth // Now rewrite the jumps that use the flags. These we handle specially
6981f87618fSChandler Carruth // because if there are multiple jumps in a single basic block we'll have
6991f87618fSChandler Carruth // to do surgery on the CFG.
7001f87618fSChandler Carruth MachineBasicBlock *LastJmpMBB = nullptr;
70119618fc6SChandler Carruth for (MachineInstr *JmpI : JmpIs) {
7021f87618fSChandler Carruth // Past the first jump within a basic block we need to split the blocks
7031f87618fSChandler Carruth // apart.
7041f87618fSChandler Carruth if (JmpI->getParent() == LastJmpMBB)
70519618fc6SChandler Carruth splitBlock(*JmpI->getParent(), *JmpI, *TII);
7061f87618fSChandler Carruth else
7071f87618fSChandler Carruth LastJmpMBB = JmpI->getParent();
70819618fc6SChandler Carruth
709caa7b03aSChandler Carruth rewriteCondJmp(*TestMBB, TestPos, TestLoc, *JmpI, CondRegs);
71019618fc6SChandler Carruth }
71119618fc6SChandler Carruth
71219618fc6SChandler Carruth // FIXME: Mark the last use of EFLAGS before the copy's def as a kill if
71319618fc6SChandler Carruth // the copy's def operand is itself a kill.
71419618fc6SChandler Carruth }
71519618fc6SChandler Carruth
71619618fc6SChandler Carruth #ifndef NDEBUG
71719618fc6SChandler Carruth for (MachineBasicBlock &MBB : MF)
71819618fc6SChandler Carruth for (MachineInstr &MI : MBB)
71919618fc6SChandler Carruth if (MI.getOpcode() == TargetOpcode::COPY &&
72019618fc6SChandler Carruth (MI.getOperand(0).getReg() == X86::EFLAGS ||
72119618fc6SChandler Carruth MI.getOperand(1).getReg() == X86::EFLAGS)) {
722d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "ERROR: Found a COPY involving EFLAGS: ";
723d34e60caSNicola Zaghen MI.dump());
72419618fc6SChandler Carruth llvm_unreachable("Unlowered EFLAGS copy!");
72519618fc6SChandler Carruth }
72619618fc6SChandler Carruth #endif
72719618fc6SChandler Carruth
72819618fc6SChandler Carruth return true;
72919618fc6SChandler Carruth }
73019618fc6SChandler Carruth
73119618fc6SChandler Carruth /// Collect any conditions that have already been set in registers so that we
73219618fc6SChandler Carruth /// can re-use them rather than adding duplicates.
collectCondsInRegs(MachineBasicBlock & MBB,MachineBasicBlock::iterator TestPos)733caa7b03aSChandler Carruth CondRegArray X86FlagsCopyLoweringPass::collectCondsInRegs(
734caa7b03aSChandler Carruth MachineBasicBlock &MBB, MachineBasicBlock::iterator TestPos) {
73519618fc6SChandler Carruth CondRegArray CondRegs = {};
73619618fc6SChandler Carruth
73719618fc6SChandler Carruth // Scan backwards across the range of instructions with live EFLAGS.
738caa7b03aSChandler Carruth for (MachineInstr &MI :
739caa7b03aSChandler Carruth llvm::reverse(llvm::make_range(MBB.begin(), TestPos))) {
7407323c2bfSCraig Topper X86::CondCode Cond = X86::getCondFromSETCC(MI);
7412bea69bfSDaniel Sanders if (Cond != X86::COND_INVALID && !MI.mayStore() &&
7423726b144SGaurav Jain MI.getOperand(0).isReg() && MI.getOperand(0).getReg().isVirtual()) {
7432ce191e2SChandler Carruth assert(MI.getOperand(0).isDef() &&
7442ce191e2SChandler Carruth "A non-storing SETcc should always define a register!");
74519618fc6SChandler Carruth CondRegs[Cond] = MI.getOperand(0).getReg();
7462ce191e2SChandler Carruth }
74719618fc6SChandler Carruth
74819618fc6SChandler Carruth // Stop scanning when we see the first definition of the EFLAGS as prior to
74919618fc6SChandler Carruth // this we would potentially capture the wrong flag state.
75019618fc6SChandler Carruth if (MI.findRegisterDefOperand(X86::EFLAGS))
75119618fc6SChandler Carruth break;
75219618fc6SChandler Carruth }
75319618fc6SChandler Carruth return CondRegs;
75419618fc6SChandler Carruth }
75519618fc6SChandler Carruth
promoteCondToReg(MachineBasicBlock & TestMBB,MachineBasicBlock::iterator TestPos,const DebugLoc & TestLoc,X86::CondCode Cond)7563726b144SGaurav Jain Register X86FlagsCopyLoweringPass::promoteCondToReg(
75719618fc6SChandler Carruth MachineBasicBlock &TestMBB, MachineBasicBlock::iterator TestPos,
758605f9047SSimon Pilgrim const DebugLoc &TestLoc, X86::CondCode Cond) {
7590c476111SDaniel Sanders Register Reg = MRI->createVirtualRegister(PromoteRC);
76019618fc6SChandler Carruth auto SetI = BuildMI(TestMBB, TestPos, TestLoc,
7617323c2bfSCraig Topper TII->get(X86::SETCCr), Reg).addImm(Cond);
76219618fc6SChandler Carruth (void)SetI;
763d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " save cond: "; SetI->dump());
76419618fc6SChandler Carruth ++NumSetCCsInserted;
76519618fc6SChandler Carruth return Reg;
76619618fc6SChandler Carruth }
76719618fc6SChandler Carruth
getCondOrInverseInReg(MachineBasicBlock & TestMBB,MachineBasicBlock::iterator TestPos,const DebugLoc & TestLoc,X86::CondCode Cond,CondRegArray & CondRegs)76819618fc6SChandler Carruth std::pair<unsigned, bool> X86FlagsCopyLoweringPass::getCondOrInverseInReg(
76919618fc6SChandler Carruth MachineBasicBlock &TestMBB, MachineBasicBlock::iterator TestPos,
770605f9047SSimon Pilgrim const DebugLoc &TestLoc, X86::CondCode Cond, CondRegArray &CondRegs) {
77119618fc6SChandler Carruth unsigned &CondReg = CondRegs[Cond];
77219618fc6SChandler Carruth unsigned &InvCondReg = CondRegs[X86::GetOppositeBranchCondition(Cond)];
77319618fc6SChandler Carruth if (!CondReg && !InvCondReg)
77419618fc6SChandler Carruth CondReg = promoteCondToReg(TestMBB, TestPos, TestLoc, Cond);
77519618fc6SChandler Carruth
77619618fc6SChandler Carruth if (CondReg)
77719618fc6SChandler Carruth return {CondReg, false};
77819618fc6SChandler Carruth else
77919618fc6SChandler Carruth return {InvCondReg, true};
78019618fc6SChandler Carruth }
78119618fc6SChandler Carruth
insertTest(MachineBasicBlock & MBB,MachineBasicBlock::iterator Pos,const DebugLoc & Loc,unsigned Reg)78219618fc6SChandler Carruth void X86FlagsCopyLoweringPass::insertTest(MachineBasicBlock &MBB,
78319618fc6SChandler Carruth MachineBasicBlock::iterator Pos,
784605f9047SSimon Pilgrim const DebugLoc &Loc, unsigned Reg) {
78519618fc6SChandler Carruth auto TestI =
786ccd3ecb9SChandler Carruth BuildMI(MBB, Pos, Loc, TII->get(X86::TEST8rr)).addReg(Reg).addReg(Reg);
78719618fc6SChandler Carruth (void)TestI;
788d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " test cond: "; TestI->dump());
78919618fc6SChandler Carruth ++NumTestsInserted;
79019618fc6SChandler Carruth }
79119618fc6SChandler Carruth
rewriteArithmetic(MachineBasicBlock & TestMBB,MachineBasicBlock::iterator TestPos,const DebugLoc & TestLoc,MachineInstr & MI,MachineOperand & FlagUse,CondRegArray & CondRegs)79219618fc6SChandler Carruth void X86FlagsCopyLoweringPass::rewriteArithmetic(
79319618fc6SChandler Carruth MachineBasicBlock &TestMBB, MachineBasicBlock::iterator TestPos,
794605f9047SSimon Pilgrim const DebugLoc &TestLoc, MachineInstr &MI, MachineOperand &FlagUse,
79519618fc6SChandler Carruth CondRegArray &CondRegs) {
79619618fc6SChandler Carruth // Arithmetic is either reading CF or OF. Figure out which condition we need
79719618fc6SChandler Carruth // to preserve in a register.
798a8653da4SSimon Pilgrim X86::CondCode Cond = X86::COND_INVALID;
79919618fc6SChandler Carruth
80019618fc6SChandler Carruth // The addend to use to reset CF or OF when added to the flag value.
801a8653da4SSimon Pilgrim int Addend = 0;
80219618fc6SChandler Carruth
80319618fc6SChandler Carruth switch (getMnemonicFromOpcode(MI.getOpcode())) {
80419618fc6SChandler Carruth case FlagArithMnemonic::ADC:
80519618fc6SChandler Carruth case FlagArithMnemonic::ADCX:
80619618fc6SChandler Carruth case FlagArithMnemonic::RCL:
80719618fc6SChandler Carruth case FlagArithMnemonic::RCR:
80819618fc6SChandler Carruth case FlagArithMnemonic::SBB:
80927857874SCraig Topper case FlagArithMnemonic::SETB:
81019618fc6SChandler Carruth Cond = X86::COND_B; // CF == 1
81119618fc6SChandler Carruth // Set up an addend that when one is added will need a carry due to not
81219618fc6SChandler Carruth // having a higher bit available.
81319618fc6SChandler Carruth Addend = 255;
81419618fc6SChandler Carruth break;
81519618fc6SChandler Carruth
81619618fc6SChandler Carruth case FlagArithMnemonic::ADOX:
81719618fc6SChandler Carruth Cond = X86::COND_O; // OF == 1
81819618fc6SChandler Carruth // Set up an addend that when one is added will turn from positive to
81919618fc6SChandler Carruth // negative and thus overflow in the signed domain.
82019618fc6SChandler Carruth Addend = 127;
82119618fc6SChandler Carruth break;
82219618fc6SChandler Carruth }
82319618fc6SChandler Carruth
82419618fc6SChandler Carruth // Now get a register that contains the value of the flag input to the
82519618fc6SChandler Carruth // arithmetic. We require exactly this flag to simplify the arithmetic
82619618fc6SChandler Carruth // required to materialize it back into the flag.
82719618fc6SChandler Carruth unsigned &CondReg = CondRegs[Cond];
82819618fc6SChandler Carruth if (!CondReg)
82919618fc6SChandler Carruth CondReg = promoteCondToReg(TestMBB, TestPos, TestLoc, Cond);
83019618fc6SChandler Carruth
83119618fc6SChandler Carruth MachineBasicBlock &MBB = *MI.getParent();
83219618fc6SChandler Carruth
83319618fc6SChandler Carruth // Insert an instruction that will set the flag back to the desired value.
8340c476111SDaniel Sanders Register TmpReg = MRI->createVirtualRegister(PromoteRC);
83519618fc6SChandler Carruth auto AddI =
83619618fc6SChandler Carruth BuildMI(MBB, MI.getIterator(), MI.getDebugLoc(), TII->get(X86::ADD8ri))
83719618fc6SChandler Carruth .addDef(TmpReg, RegState::Dead)
83819618fc6SChandler Carruth .addReg(CondReg)
83919618fc6SChandler Carruth .addImm(Addend);
84019618fc6SChandler Carruth (void)AddI;
841d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " add cond: "; AddI->dump());
84219618fc6SChandler Carruth ++NumAddsInserted;
84319618fc6SChandler Carruth FlagUse.setIsKill(true);
84419618fc6SChandler Carruth }
84519618fc6SChandler Carruth
rewriteCMov(MachineBasicBlock & TestMBB,MachineBasicBlock::iterator TestPos,const DebugLoc & TestLoc,MachineInstr & CMovI,MachineOperand & FlagUse,CondRegArray & CondRegs)84619618fc6SChandler Carruth void X86FlagsCopyLoweringPass::rewriteCMov(MachineBasicBlock &TestMBB,
84719618fc6SChandler Carruth MachineBasicBlock::iterator TestPos,
848605f9047SSimon Pilgrim const DebugLoc &TestLoc,
84919618fc6SChandler Carruth MachineInstr &CMovI,
85019618fc6SChandler Carruth MachineOperand &FlagUse,
85119618fc6SChandler Carruth CondRegArray &CondRegs) {
85219618fc6SChandler Carruth // First get the register containing this specific condition.
853e0bfeb5fSCraig Topper X86::CondCode Cond = X86::getCondFromCMov(CMovI);
85419618fc6SChandler Carruth unsigned CondReg;
85519618fc6SChandler Carruth bool Inverted;
85619618fc6SChandler Carruth std::tie(CondReg, Inverted) =
85719618fc6SChandler Carruth getCondOrInverseInReg(TestMBB, TestPos, TestLoc, Cond, CondRegs);
85819618fc6SChandler Carruth
85919618fc6SChandler Carruth MachineBasicBlock &MBB = *CMovI.getParent();
86019618fc6SChandler Carruth
86119618fc6SChandler Carruth // Insert a direct test of the saved register.
86219618fc6SChandler Carruth insertTest(MBB, CMovI.getIterator(), CMovI.getDebugLoc(), CondReg);
86319618fc6SChandler Carruth
864e0bfeb5fSCraig Topper // Rewrite the CMov to use the !ZF flag from the test, and then kill its use
865e0bfeb5fSCraig Topper // of the flags afterward.
866e0bfeb5fSCraig Topper CMovI.getOperand(CMovI.getDesc().getNumOperands() - 1)
867e0bfeb5fSCraig Topper .setImm(Inverted ? X86::COND_E : X86::COND_NE);
86819618fc6SChandler Carruth FlagUse.setIsKill(true);
869d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " fixed cmov: "; CMovI.dump());
87019618fc6SChandler Carruth }
87119618fc6SChandler Carruth
rewriteFCMov(MachineBasicBlock & TestMBB,MachineBasicBlock::iterator TestPos,const DebugLoc & TestLoc,MachineInstr & CMovI,MachineOperand & FlagUse,CondRegArray & CondRegs)872468a0cb5SCraig Topper void X86FlagsCopyLoweringPass::rewriteFCMov(MachineBasicBlock &TestMBB,
873468a0cb5SCraig Topper MachineBasicBlock::iterator TestPos,
874605f9047SSimon Pilgrim const DebugLoc &TestLoc,
875468a0cb5SCraig Topper MachineInstr &CMovI,
876468a0cb5SCraig Topper MachineOperand &FlagUse,
877468a0cb5SCraig Topper CondRegArray &CondRegs) {
878468a0cb5SCraig Topper // First get the register containing this specific condition.
879468a0cb5SCraig Topper X86::CondCode Cond = getCondFromFCMOV(CMovI.getOpcode());
880468a0cb5SCraig Topper unsigned CondReg;
881468a0cb5SCraig Topper bool Inverted;
882468a0cb5SCraig Topper std::tie(CondReg, Inverted) =
883468a0cb5SCraig Topper getCondOrInverseInReg(TestMBB, TestPos, TestLoc, Cond, CondRegs);
884468a0cb5SCraig Topper
885468a0cb5SCraig Topper MachineBasicBlock &MBB = *CMovI.getParent();
886468a0cb5SCraig Topper
887468a0cb5SCraig Topper // Insert a direct test of the saved register.
888468a0cb5SCraig Topper insertTest(MBB, CMovI.getIterator(), CMovI.getDebugLoc(), CondReg);
889468a0cb5SCraig Topper
890468a0cb5SCraig Topper auto getFCMOVOpcode = [](unsigned Opcode, bool Inverted) {
891468a0cb5SCraig Topper switch (Opcode) {
892468a0cb5SCraig Topper default: llvm_unreachable("Unexpected opcode!");
893468a0cb5SCraig Topper case X86::CMOVBE_Fp32: case X86::CMOVNBE_Fp32:
894468a0cb5SCraig Topper case X86::CMOVB_Fp32: case X86::CMOVNB_Fp32:
895468a0cb5SCraig Topper case X86::CMOVE_Fp32: case X86::CMOVNE_Fp32:
896468a0cb5SCraig Topper case X86::CMOVP_Fp32: case X86::CMOVNP_Fp32:
897468a0cb5SCraig Topper return Inverted ? X86::CMOVE_Fp32 : X86::CMOVNE_Fp32;
898468a0cb5SCraig Topper case X86::CMOVBE_Fp64: case X86::CMOVNBE_Fp64:
899468a0cb5SCraig Topper case X86::CMOVB_Fp64: case X86::CMOVNB_Fp64:
900468a0cb5SCraig Topper case X86::CMOVE_Fp64: case X86::CMOVNE_Fp64:
901468a0cb5SCraig Topper case X86::CMOVP_Fp64: case X86::CMOVNP_Fp64:
902468a0cb5SCraig Topper return Inverted ? X86::CMOVE_Fp64 : X86::CMOVNE_Fp64;
903468a0cb5SCraig Topper case X86::CMOVBE_Fp80: case X86::CMOVNBE_Fp80:
904468a0cb5SCraig Topper case X86::CMOVB_Fp80: case X86::CMOVNB_Fp80:
905468a0cb5SCraig Topper case X86::CMOVE_Fp80: case X86::CMOVNE_Fp80:
906468a0cb5SCraig Topper case X86::CMOVP_Fp80: case X86::CMOVNP_Fp80:
907468a0cb5SCraig Topper return Inverted ? X86::CMOVE_Fp80 : X86::CMOVNE_Fp80;
908468a0cb5SCraig Topper }
909468a0cb5SCraig Topper };
910468a0cb5SCraig Topper
911468a0cb5SCraig Topper // Rewrite the CMov to use the !ZF flag from the test.
912468a0cb5SCraig Topper CMovI.setDesc(TII->get(getFCMOVOpcode(CMovI.getOpcode(), Inverted)));
913468a0cb5SCraig Topper FlagUse.setIsKill(true);
914468a0cb5SCraig Topper LLVM_DEBUG(dbgs() << " fixed fcmov: "; CMovI.dump());
915468a0cb5SCraig Topper }
916468a0cb5SCraig Topper
rewriteCondJmp(MachineBasicBlock & TestMBB,MachineBasicBlock::iterator TestPos,const DebugLoc & TestLoc,MachineInstr & JmpI,CondRegArray & CondRegs)91719618fc6SChandler Carruth void X86FlagsCopyLoweringPass::rewriteCondJmp(
91819618fc6SChandler Carruth MachineBasicBlock &TestMBB, MachineBasicBlock::iterator TestPos,
919605f9047SSimon Pilgrim const DebugLoc &TestLoc, MachineInstr &JmpI, CondRegArray &CondRegs) {
92019618fc6SChandler Carruth // First get the register containing this specific condition.
92180aa2290SCraig Topper X86::CondCode Cond = X86::getCondFromBranch(JmpI);
92219618fc6SChandler Carruth unsigned CondReg;
92319618fc6SChandler Carruth bool Inverted;
92419618fc6SChandler Carruth std::tie(CondReg, Inverted) =
92519618fc6SChandler Carruth getCondOrInverseInReg(TestMBB, TestPos, TestLoc, Cond, CondRegs);
92619618fc6SChandler Carruth
92719618fc6SChandler Carruth MachineBasicBlock &JmpMBB = *JmpI.getParent();
92819618fc6SChandler Carruth
92919618fc6SChandler Carruth // Insert a direct test of the saved register.
93019618fc6SChandler Carruth insertTest(JmpMBB, JmpI.getIterator(), JmpI.getDebugLoc(), CondReg);
93119618fc6SChandler Carruth
93219618fc6SChandler Carruth // Rewrite the jump to use the !ZF flag from the test, and kill its use of
93319618fc6SChandler Carruth // flags afterward.
93480aa2290SCraig Topper JmpI.getOperand(1).setImm(Inverted ? X86::COND_E : X86::COND_NE);
93580aa2290SCraig Topper JmpI.findRegisterUseOperand(X86::EFLAGS)->setIsKill(true);
936d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " fixed jCC: "; JmpI.dump());
93719618fc6SChandler Carruth }
93819618fc6SChandler Carruth
rewriteCopy(MachineInstr & MI,MachineOperand & FlagUse,MachineInstr & CopyDefI)93919618fc6SChandler Carruth void X86FlagsCopyLoweringPass::rewriteCopy(MachineInstr &MI,
94019618fc6SChandler Carruth MachineOperand &FlagUse,
94119618fc6SChandler Carruth MachineInstr &CopyDefI) {
942372ffa15SHiroshi Inoue // Just replace this copy with the original copy def.
94319618fc6SChandler Carruth MRI->replaceRegWith(MI.getOperand(0).getReg(),
94419618fc6SChandler Carruth CopyDefI.getOperand(0).getReg());
94519618fc6SChandler Carruth MI.eraseFromParent();
94619618fc6SChandler Carruth }
94719618fc6SChandler Carruth
rewriteSetCC(MachineBasicBlock & TestMBB,MachineBasicBlock::iterator TestPos,const DebugLoc & TestLoc,MachineInstr & SetCCI,MachineOperand & FlagUse,CondRegArray & CondRegs)94819618fc6SChandler Carruth void X86FlagsCopyLoweringPass::rewriteSetCC(MachineBasicBlock &TestMBB,
94919618fc6SChandler Carruth MachineBasicBlock::iterator TestPos,
950605f9047SSimon Pilgrim const DebugLoc &TestLoc,
95119618fc6SChandler Carruth MachineInstr &SetCCI,
95219618fc6SChandler Carruth MachineOperand &FlagUse,
95319618fc6SChandler Carruth CondRegArray &CondRegs) {
9547323c2bfSCraig Topper X86::CondCode Cond = X86::getCondFromSETCC(SetCCI);
95519618fc6SChandler Carruth // Note that we can't usefully rewrite this to the inverse without complex
95619618fc6SChandler Carruth // analysis of the users of the setCC. Largely we rely on duplicates which
95719618fc6SChandler Carruth // could have been avoided already being avoided here.
95819618fc6SChandler Carruth unsigned &CondReg = CondRegs[Cond];
95919618fc6SChandler Carruth if (!CondReg)
96019618fc6SChandler Carruth CondReg = promoteCondToReg(TestMBB, TestPos, TestLoc, Cond);
96119618fc6SChandler Carruth
962ee2c1deaSCraig Topper // Rewriting a register def is trivial: we just replace the register and
963ee2c1deaSCraig Topper // remove the setcc.
964ee2c1deaSCraig Topper if (!SetCCI.mayStore()) {
965ee2c1deaSCraig Topper assert(SetCCI.getOperand(0).isReg() &&
966ee2c1deaSCraig Topper "Cannot have a non-register defined operand to SETcc!");
967*b81e26c7SCraig Topper Register OldReg = SetCCI.getOperand(0).getReg();
968*b81e26c7SCraig Topper // Drop Kill flags on the old register before replacing. CondReg may have
969*b81e26c7SCraig Topper // a longer live range.
970*b81e26c7SCraig Topper MRI->clearKillFlags(OldReg);
971*b81e26c7SCraig Topper MRI->replaceRegWith(OldReg, CondReg);
97219618fc6SChandler Carruth SetCCI.eraseFromParent();
973ee2c1deaSCraig Topper return;
974ee2c1deaSCraig Topper }
975ee2c1deaSCraig Topper
976ee2c1deaSCraig Topper // Otherwise, we need to emit a store.
977ee2c1deaSCraig Topper auto MIB = BuildMI(*SetCCI.getParent(), SetCCI.getIterator(),
978ee2c1deaSCraig Topper SetCCI.getDebugLoc(), TII->get(X86::MOV8mr));
979ee2c1deaSCraig Topper // Copy the address operands.
980ee2c1deaSCraig Topper for (int i = 0; i < X86::AddrNumOperands; ++i)
981ee2c1deaSCraig Topper MIB.add(SetCCI.getOperand(i));
982ee2c1deaSCraig Topper
983ee2c1deaSCraig Topper MIB.addReg(CondReg);
984ee2c1deaSCraig Topper
985c73c0307SChandler Carruth MIB.setMemRefs(SetCCI.memoperands());
986ee2c1deaSCraig Topper
987ee2c1deaSCraig Topper SetCCI.eraseFromParent();
98819618fc6SChandler Carruth }
989