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