xref: /freebsd/contrib/llvm-project/llvm/lib/Target/X86/X86FlagsCopyLowering.cpp (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
10b57cec5SDimitry Andric //====- X86FlagsCopyLowering.cpp - Lowers COPY nodes of EFLAGS ------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric /// \file
90b57cec5SDimitry Andric ///
100b57cec5SDimitry Andric /// Lowers COPY nodes of EFLAGS by directly extracting and preserving individual
110b57cec5SDimitry Andric /// flag bits.
120b57cec5SDimitry Andric ///
130b57cec5SDimitry Andric /// We have to do this by carefully analyzing and rewriting the usage of the
140b57cec5SDimitry Andric /// copied EFLAGS register because there is no general way to rematerialize the
150b57cec5SDimitry Andric /// entire EFLAGS register safely and efficiently. Using `popf` both forces
160b57cec5SDimitry Andric /// dynamic stack adjustment and can create correctness issues due to IF, TF,
170b57cec5SDimitry Andric /// and other non-status flags being overwritten. Using sequences involving
180b57cec5SDimitry Andric /// SAHF don't work on all x86 processors and are often quite slow compared to
190b57cec5SDimitry Andric /// directly testing a single status preserved in its own GPR.
200b57cec5SDimitry Andric ///
210b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric #include "X86.h"
240b57cec5SDimitry Andric #include "X86InstrBuilder.h"
250b57cec5SDimitry Andric #include "X86InstrInfo.h"
260b57cec5SDimitry Andric #include "X86Subtarget.h"
270b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
280b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
290b57cec5SDimitry Andric #include "llvm/ADT/PostOrderIterator.h"
300b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
310b57cec5SDimitry Andric #include "llvm/ADT/ScopeExit.h"
320b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
330b57cec5SDimitry Andric #include "llvm/ADT/SmallSet.h"
340b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
350b57cec5SDimitry Andric #include "llvm/ADT/SparseBitVector.h"
360b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
370b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
380b57cec5SDimitry Andric #include "llvm/CodeGen/MachineConstantPool.h"
390b57cec5SDimitry Andric #include "llvm/CodeGen/MachineDominators.h"
400b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
410b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
420b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
430b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
440b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
450b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
460b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
470b57cec5SDimitry Andric #include "llvm/CodeGen/MachineSSAUpdater.h"
480b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
490b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
500b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSchedule.h"
510b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
520b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h"
530b57cec5SDimitry Andric #include "llvm/MC/MCSchedule.h"
540b57cec5SDimitry Andric #include "llvm/Pass.h"
550b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
560b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
570b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
580b57cec5SDimitry Andric #include <algorithm>
590b57cec5SDimitry Andric #include <cassert>
600b57cec5SDimitry Andric #include <iterator>
610b57cec5SDimitry Andric #include <utility>
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric using namespace llvm;
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric #define PASS_KEY "x86-flags-copy-lowering"
660b57cec5SDimitry Andric #define DEBUG_TYPE PASS_KEY
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric STATISTIC(NumCopiesEliminated, "Number of copies of EFLAGS eliminated");
690b57cec5SDimitry Andric STATISTIC(NumSetCCsInserted, "Number of setCC instructions inserted");
700b57cec5SDimitry Andric STATISTIC(NumTestsInserted, "Number of test instructions inserted");
710b57cec5SDimitry Andric STATISTIC(NumAddsInserted, "Number of adds instructions inserted");
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric namespace {
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric // Convenient array type for storing registers associated with each condition.
760b57cec5SDimitry Andric using CondRegArray = std::array<unsigned, X86::LAST_VALID_COND + 1>;
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric class X86FlagsCopyLoweringPass : public MachineFunctionPass {
790b57cec5SDimitry Andric public:
800b57cec5SDimitry Andric   X86FlagsCopyLoweringPass() : MachineFunctionPass(ID) { }
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   StringRef getPassName() const override { return "X86 EFLAGS copy lowering"; }
830b57cec5SDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override;
840b57cec5SDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override;
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric   /// Pass identification, replacement for typeid.
870b57cec5SDimitry Andric   static char ID;
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric private:
90480093f4SDimitry Andric   MachineRegisterInfo *MRI = nullptr;
91480093f4SDimitry Andric   const X86Subtarget *Subtarget = nullptr;
92480093f4SDimitry Andric   const X86InstrInfo *TII = nullptr;
93480093f4SDimitry Andric   const TargetRegisterInfo *TRI = nullptr;
94480093f4SDimitry Andric   const TargetRegisterClass *PromoteRC = nullptr;
95480093f4SDimitry Andric   MachineDominatorTree *MDT = nullptr;
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric   CondRegArray collectCondsInRegs(MachineBasicBlock &MBB,
980b57cec5SDimitry Andric                                   MachineBasicBlock::iterator CopyDefI);
990b57cec5SDimitry Andric 
100*e8d8bef9SDimitry Andric   Register promoteCondToReg(MachineBasicBlock &MBB,
1010b57cec5SDimitry Andric                             MachineBasicBlock::iterator TestPos,
1020b57cec5SDimitry Andric                             DebugLoc TestLoc, X86::CondCode Cond);
1030b57cec5SDimitry Andric   std::pair<unsigned, bool>
1040b57cec5SDimitry Andric   getCondOrInverseInReg(MachineBasicBlock &TestMBB,
1050b57cec5SDimitry Andric                         MachineBasicBlock::iterator TestPos, DebugLoc TestLoc,
1060b57cec5SDimitry Andric                         X86::CondCode Cond, CondRegArray &CondRegs);
1070b57cec5SDimitry Andric   void insertTest(MachineBasicBlock &MBB, MachineBasicBlock::iterator Pos,
1080b57cec5SDimitry Andric                   DebugLoc Loc, unsigned Reg);
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   void rewriteArithmetic(MachineBasicBlock &TestMBB,
1110b57cec5SDimitry Andric                          MachineBasicBlock::iterator TestPos, DebugLoc TestLoc,
1120b57cec5SDimitry Andric                          MachineInstr &MI, MachineOperand &FlagUse,
1130b57cec5SDimitry Andric                          CondRegArray &CondRegs);
1140b57cec5SDimitry Andric   void rewriteCMov(MachineBasicBlock &TestMBB,
1150b57cec5SDimitry Andric                    MachineBasicBlock::iterator TestPos, DebugLoc TestLoc,
1160b57cec5SDimitry Andric                    MachineInstr &CMovI, MachineOperand &FlagUse,
1170b57cec5SDimitry Andric                    CondRegArray &CondRegs);
1182a168f03SDimitry Andric   void rewriteFCMov(MachineBasicBlock &TestMBB,
1192a168f03SDimitry Andric                     MachineBasicBlock::iterator TestPos, DebugLoc TestLoc,
1202a168f03SDimitry Andric                     MachineInstr &CMovI, MachineOperand &FlagUse,
1212a168f03SDimitry Andric                     CondRegArray &CondRegs);
1220b57cec5SDimitry Andric   void rewriteCondJmp(MachineBasicBlock &TestMBB,
1230b57cec5SDimitry Andric                       MachineBasicBlock::iterator TestPos, DebugLoc TestLoc,
1240b57cec5SDimitry Andric                       MachineInstr &JmpI, CondRegArray &CondRegs);
1250b57cec5SDimitry Andric   void rewriteCopy(MachineInstr &MI, MachineOperand &FlagUse,
1260b57cec5SDimitry Andric                    MachineInstr &CopyDefI);
1270b57cec5SDimitry Andric   void rewriteSetCC(MachineBasicBlock &TestMBB,
1280b57cec5SDimitry Andric                     MachineBasicBlock::iterator TestPos, DebugLoc TestLoc,
1290b57cec5SDimitry Andric                     MachineInstr &SetCCI, MachineOperand &FlagUse,
1300b57cec5SDimitry Andric                     CondRegArray &CondRegs);
1310b57cec5SDimitry Andric };
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric } // end anonymous namespace
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(X86FlagsCopyLoweringPass, DEBUG_TYPE,
1360b57cec5SDimitry Andric                       "X86 EFLAGS copy lowering", false, false)
1370b57cec5SDimitry Andric INITIALIZE_PASS_END(X86FlagsCopyLoweringPass, DEBUG_TYPE,
1380b57cec5SDimitry Andric                     "X86 EFLAGS copy lowering", false, false)
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric FunctionPass *llvm::createX86FlagsCopyLoweringPass() {
1410b57cec5SDimitry Andric   return new X86FlagsCopyLoweringPass();
1420b57cec5SDimitry Andric }
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric char X86FlagsCopyLoweringPass::ID = 0;
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric void X86FlagsCopyLoweringPass::getAnalysisUsage(AnalysisUsage &AU) const {
1470b57cec5SDimitry Andric   AU.addRequired<MachineDominatorTree>();
1480b57cec5SDimitry Andric   MachineFunctionPass::getAnalysisUsage(AU);
1490b57cec5SDimitry Andric }
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric namespace {
1520b57cec5SDimitry Andric /// An enumeration of the arithmetic instruction mnemonics which have
1530b57cec5SDimitry Andric /// interesting flag semantics.
1540b57cec5SDimitry Andric ///
1550b57cec5SDimitry Andric /// We can map instruction opcodes into these mnemonics to make it easy to
1560b57cec5SDimitry Andric /// dispatch with specific functionality.
1570b57cec5SDimitry Andric enum class FlagArithMnemonic {
1580b57cec5SDimitry Andric   ADC,
1590b57cec5SDimitry Andric   ADCX,
1600b57cec5SDimitry Andric   ADOX,
1610b57cec5SDimitry Andric   RCL,
1620b57cec5SDimitry Andric   RCR,
1630b57cec5SDimitry Andric   SBB,
1645ffd83dbSDimitry Andric   SETB,
1650b57cec5SDimitry Andric };
1660b57cec5SDimitry Andric } // namespace
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric static FlagArithMnemonic getMnemonicFromOpcode(unsigned Opcode) {
1690b57cec5SDimitry Andric   switch (Opcode) {
1700b57cec5SDimitry Andric   default:
1710b57cec5SDimitry Andric     report_fatal_error("No support for lowering a copy into EFLAGS when used "
1720b57cec5SDimitry Andric                        "by this instruction!");
1730b57cec5SDimitry Andric 
1740b57cec5SDimitry Andric #define LLVM_EXPAND_INSTR_SIZES(MNEMONIC, SUFFIX)                              \
1750b57cec5SDimitry Andric   case X86::MNEMONIC##8##SUFFIX:                                               \
1760b57cec5SDimitry Andric   case X86::MNEMONIC##16##SUFFIX:                                              \
1770b57cec5SDimitry Andric   case X86::MNEMONIC##32##SUFFIX:                                              \
1780b57cec5SDimitry Andric   case X86::MNEMONIC##64##SUFFIX:
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric #define LLVM_EXPAND_ADC_SBB_INSTR(MNEMONIC)                                    \
1810b57cec5SDimitry Andric   LLVM_EXPAND_INSTR_SIZES(MNEMONIC, rr)                                        \
1820b57cec5SDimitry Andric   LLVM_EXPAND_INSTR_SIZES(MNEMONIC, rr_REV)                                    \
1830b57cec5SDimitry Andric   LLVM_EXPAND_INSTR_SIZES(MNEMONIC, rm)                                        \
1840b57cec5SDimitry Andric   LLVM_EXPAND_INSTR_SIZES(MNEMONIC, mr)                                        \
1850b57cec5SDimitry Andric   case X86::MNEMONIC##8ri:                                                     \
1860b57cec5SDimitry Andric   case X86::MNEMONIC##16ri8:                                                   \
1870b57cec5SDimitry Andric   case X86::MNEMONIC##32ri8:                                                   \
1880b57cec5SDimitry Andric   case X86::MNEMONIC##64ri8:                                                   \
1890b57cec5SDimitry Andric   case X86::MNEMONIC##16ri:                                                    \
1900b57cec5SDimitry Andric   case X86::MNEMONIC##32ri:                                                    \
1910b57cec5SDimitry Andric   case X86::MNEMONIC##64ri32:                                                  \
1920b57cec5SDimitry Andric   case X86::MNEMONIC##8mi:                                                     \
1930b57cec5SDimitry Andric   case X86::MNEMONIC##16mi8:                                                   \
1940b57cec5SDimitry Andric   case X86::MNEMONIC##32mi8:                                                   \
1950b57cec5SDimitry Andric   case X86::MNEMONIC##64mi8:                                                   \
1960b57cec5SDimitry Andric   case X86::MNEMONIC##16mi:                                                    \
1970b57cec5SDimitry Andric   case X86::MNEMONIC##32mi:                                                    \
1980b57cec5SDimitry Andric   case X86::MNEMONIC##64mi32:                                                  \
1990b57cec5SDimitry Andric   case X86::MNEMONIC##8i8:                                                     \
2000b57cec5SDimitry Andric   case X86::MNEMONIC##16i16:                                                   \
2010b57cec5SDimitry Andric   case X86::MNEMONIC##32i32:                                                   \
2020b57cec5SDimitry Andric   case X86::MNEMONIC##64i32:
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric     LLVM_EXPAND_ADC_SBB_INSTR(ADC)
2050b57cec5SDimitry Andric     return FlagArithMnemonic::ADC;
2060b57cec5SDimitry Andric 
2070b57cec5SDimitry Andric     LLVM_EXPAND_ADC_SBB_INSTR(SBB)
2080b57cec5SDimitry Andric     return FlagArithMnemonic::SBB;
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric #undef LLVM_EXPAND_ADC_SBB_INSTR
2110b57cec5SDimitry Andric 
2120b57cec5SDimitry Andric     LLVM_EXPAND_INSTR_SIZES(RCL, rCL)
2130b57cec5SDimitry Andric     LLVM_EXPAND_INSTR_SIZES(RCL, r1)
2140b57cec5SDimitry Andric     LLVM_EXPAND_INSTR_SIZES(RCL, ri)
2150b57cec5SDimitry Andric     return FlagArithMnemonic::RCL;
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric     LLVM_EXPAND_INSTR_SIZES(RCR, rCL)
2180b57cec5SDimitry Andric     LLVM_EXPAND_INSTR_SIZES(RCR, r1)
2190b57cec5SDimitry Andric     LLVM_EXPAND_INSTR_SIZES(RCR, ri)
2200b57cec5SDimitry Andric     return FlagArithMnemonic::RCR;
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric #undef LLVM_EXPAND_INSTR_SIZES
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric   case X86::ADCX32rr:
2250b57cec5SDimitry Andric   case X86::ADCX64rr:
2260b57cec5SDimitry Andric   case X86::ADCX32rm:
2270b57cec5SDimitry Andric   case X86::ADCX64rm:
2280b57cec5SDimitry Andric     return FlagArithMnemonic::ADCX;
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric   case X86::ADOX32rr:
2310b57cec5SDimitry Andric   case X86::ADOX64rr:
2320b57cec5SDimitry Andric   case X86::ADOX32rm:
2330b57cec5SDimitry Andric   case X86::ADOX64rm:
2340b57cec5SDimitry Andric     return FlagArithMnemonic::ADOX;
2355ffd83dbSDimitry Andric 
2365ffd83dbSDimitry Andric   case X86::SETB_C32r:
2375ffd83dbSDimitry Andric   case X86::SETB_C64r:
2385ffd83dbSDimitry Andric     return FlagArithMnemonic::SETB;
2390b57cec5SDimitry Andric   }
2400b57cec5SDimitry Andric }
2410b57cec5SDimitry Andric 
2420b57cec5SDimitry Andric static MachineBasicBlock &splitBlock(MachineBasicBlock &MBB,
2430b57cec5SDimitry Andric                                      MachineInstr &SplitI,
2440b57cec5SDimitry Andric                                      const X86InstrInfo &TII) {
2450b57cec5SDimitry Andric   MachineFunction &MF = *MBB.getParent();
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric   assert(SplitI.getParent() == &MBB &&
2480b57cec5SDimitry Andric          "Split instruction must be in the split block!");
2490b57cec5SDimitry Andric   assert(SplitI.isBranch() &&
2500b57cec5SDimitry Andric          "Only designed to split a tail of branch instructions!");
2510b57cec5SDimitry Andric   assert(X86::getCondFromBranch(SplitI) != X86::COND_INVALID &&
2520b57cec5SDimitry Andric          "Must split on an actual jCC instruction!");
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric   // Dig out the previous instruction to the split point.
2550b57cec5SDimitry Andric   MachineInstr &PrevI = *std::prev(SplitI.getIterator());
2560b57cec5SDimitry Andric   assert(PrevI.isBranch() && "Must split after a branch!");
2570b57cec5SDimitry Andric   assert(X86::getCondFromBranch(PrevI) != X86::COND_INVALID &&
2580b57cec5SDimitry Andric          "Must split after an actual jCC instruction!");
2590b57cec5SDimitry Andric   assert(!std::prev(PrevI.getIterator())->isTerminator() &&
2600b57cec5SDimitry Andric          "Must only have this one terminator prior to the split!");
2610b57cec5SDimitry Andric 
2620b57cec5SDimitry Andric   // Grab the one successor edge that will stay in `MBB`.
2630b57cec5SDimitry Andric   MachineBasicBlock &UnsplitSucc = *PrevI.getOperand(0).getMBB();
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric   // Analyze the original block to see if we are actually splitting an edge
2660b57cec5SDimitry Andric   // into two edges. This can happen when we have multiple conditional jumps to
2670b57cec5SDimitry Andric   // the same successor.
2680b57cec5SDimitry Andric   bool IsEdgeSplit =
2690b57cec5SDimitry Andric       std::any_of(SplitI.getIterator(), MBB.instr_end(),
2700b57cec5SDimitry Andric                   [&](MachineInstr &MI) {
2710b57cec5SDimitry Andric                     assert(MI.isTerminator() &&
2720b57cec5SDimitry Andric                            "Should only have spliced terminators!");
2730b57cec5SDimitry Andric                     return llvm::any_of(
2740b57cec5SDimitry Andric                         MI.operands(), [&](MachineOperand &MOp) {
2750b57cec5SDimitry Andric                           return MOp.isMBB() && MOp.getMBB() == &UnsplitSucc;
2760b57cec5SDimitry Andric                         });
2770b57cec5SDimitry Andric                   }) ||
2780b57cec5SDimitry Andric       MBB.getFallThrough() == &UnsplitSucc;
2790b57cec5SDimitry Andric 
2800b57cec5SDimitry Andric   MachineBasicBlock &NewMBB = *MF.CreateMachineBasicBlock();
2810b57cec5SDimitry Andric 
2820b57cec5SDimitry Andric   // Insert the new block immediately after the current one. Any existing
2830b57cec5SDimitry Andric   // fallthrough will be sunk into this new block anyways.
2840b57cec5SDimitry Andric   MF.insert(std::next(MachineFunction::iterator(&MBB)), &NewMBB);
2850b57cec5SDimitry Andric 
2860b57cec5SDimitry Andric   // Splice the tail of instructions into the new block.
2870b57cec5SDimitry Andric   NewMBB.splice(NewMBB.end(), &MBB, SplitI.getIterator(), MBB.end());
2880b57cec5SDimitry Andric 
2890b57cec5SDimitry Andric   // Copy the necessary succesors (and their probability info) into the new
2900b57cec5SDimitry Andric   // block.
2910b57cec5SDimitry Andric   for (auto SI = MBB.succ_begin(), SE = MBB.succ_end(); SI != SE; ++SI)
2920b57cec5SDimitry Andric     if (IsEdgeSplit || *SI != &UnsplitSucc)
2930b57cec5SDimitry Andric       NewMBB.copySuccessor(&MBB, SI);
2940b57cec5SDimitry Andric   // Normalize the probabilities if we didn't end up splitting the edge.
2950b57cec5SDimitry Andric   if (!IsEdgeSplit)
2960b57cec5SDimitry Andric     NewMBB.normalizeSuccProbs();
2970b57cec5SDimitry Andric 
2980b57cec5SDimitry Andric   // Now replace all of the moved successors in the original block with the new
2990b57cec5SDimitry Andric   // block. This will merge their probabilities.
3000b57cec5SDimitry Andric   for (MachineBasicBlock *Succ : NewMBB.successors())
3010b57cec5SDimitry Andric     if (Succ != &UnsplitSucc)
3020b57cec5SDimitry Andric       MBB.replaceSuccessor(Succ, &NewMBB);
3030b57cec5SDimitry Andric 
3040b57cec5SDimitry Andric   // We should always end up replacing at least one successor.
3050b57cec5SDimitry Andric   assert(MBB.isSuccessor(&NewMBB) &&
3060b57cec5SDimitry Andric          "Failed to make the new block a successor!");
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric   // Now update all the PHIs.
3090b57cec5SDimitry Andric   for (MachineBasicBlock *Succ : NewMBB.successors()) {
3100b57cec5SDimitry Andric     for (MachineInstr &MI : *Succ) {
3110b57cec5SDimitry Andric       if (!MI.isPHI())
3120b57cec5SDimitry Andric         break;
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric       for (int OpIdx = 1, NumOps = MI.getNumOperands(); OpIdx < NumOps;
3150b57cec5SDimitry Andric            OpIdx += 2) {
3160b57cec5SDimitry Andric         MachineOperand &OpV = MI.getOperand(OpIdx);
3170b57cec5SDimitry Andric         MachineOperand &OpMBB = MI.getOperand(OpIdx + 1);
3180b57cec5SDimitry Andric         assert(OpMBB.isMBB() && "Block operand to a PHI is not a block!");
3190b57cec5SDimitry Andric         if (OpMBB.getMBB() != &MBB)
3200b57cec5SDimitry Andric           continue;
3210b57cec5SDimitry Andric 
3220b57cec5SDimitry Andric         // Replace the operand for unsplit successors
3230b57cec5SDimitry Andric         if (!IsEdgeSplit || Succ != &UnsplitSucc) {
3240b57cec5SDimitry Andric           OpMBB.setMBB(&NewMBB);
3250b57cec5SDimitry Andric 
3260b57cec5SDimitry Andric           // We have to continue scanning as there may be multiple entries in
3270b57cec5SDimitry Andric           // the PHI.
3280b57cec5SDimitry Andric           continue;
3290b57cec5SDimitry Andric         }
3300b57cec5SDimitry Andric 
3310b57cec5SDimitry Andric         // When we have split the edge append a new successor.
3320b57cec5SDimitry Andric         MI.addOperand(MF, OpV);
3330b57cec5SDimitry Andric         MI.addOperand(MF, MachineOperand::CreateMBB(&NewMBB));
3340b57cec5SDimitry Andric         break;
3350b57cec5SDimitry Andric       }
3360b57cec5SDimitry Andric     }
3370b57cec5SDimitry Andric   }
3380b57cec5SDimitry Andric 
3390b57cec5SDimitry Andric   return NewMBB;
3400b57cec5SDimitry Andric }
3410b57cec5SDimitry Andric 
3422a168f03SDimitry Andric static X86::CondCode getCondFromFCMOV(unsigned Opcode) {
3432a168f03SDimitry Andric   switch (Opcode) {
3442a168f03SDimitry Andric   default: return X86::COND_INVALID;
3452a168f03SDimitry Andric   case X86::CMOVBE_Fp32:  case X86::CMOVBE_Fp64:  case X86::CMOVBE_Fp80:
3462a168f03SDimitry Andric     return X86::COND_BE;
3472a168f03SDimitry Andric   case X86::CMOVB_Fp32:   case X86::CMOVB_Fp64:   case X86::CMOVB_Fp80:
3482a168f03SDimitry Andric     return X86::COND_B;
3492a168f03SDimitry Andric   case X86::CMOVE_Fp32:   case X86::CMOVE_Fp64:   case X86::CMOVE_Fp80:
3502a168f03SDimitry Andric     return X86::COND_E;
3512a168f03SDimitry Andric   case X86::CMOVNBE_Fp32: case X86::CMOVNBE_Fp64: case X86::CMOVNBE_Fp80:
3522a168f03SDimitry Andric     return X86::COND_A;
3532a168f03SDimitry Andric   case X86::CMOVNB_Fp32:  case X86::CMOVNB_Fp64:  case X86::CMOVNB_Fp80:
3542a168f03SDimitry Andric     return X86::COND_AE;
3552a168f03SDimitry Andric   case X86::CMOVNE_Fp32:  case X86::CMOVNE_Fp64:  case X86::CMOVNE_Fp80:
3562a168f03SDimitry Andric     return X86::COND_NE;
3572a168f03SDimitry Andric   case X86::CMOVNP_Fp32:  case X86::CMOVNP_Fp64:  case X86::CMOVNP_Fp80:
3582a168f03SDimitry Andric     return X86::COND_NP;
3592a168f03SDimitry Andric   case X86::CMOVP_Fp32:   case X86::CMOVP_Fp64:   case X86::CMOVP_Fp80:
3602a168f03SDimitry Andric     return X86::COND_P;
3612a168f03SDimitry Andric   }
3622a168f03SDimitry Andric }
3632a168f03SDimitry Andric 
3640b57cec5SDimitry Andric bool X86FlagsCopyLoweringPass::runOnMachineFunction(MachineFunction &MF) {
3650b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "********** " << getPassName() << " : " << MF.getName()
3660b57cec5SDimitry Andric                     << " **********\n");
3670b57cec5SDimitry Andric 
3680b57cec5SDimitry Andric   Subtarget = &MF.getSubtarget<X86Subtarget>();
3690b57cec5SDimitry Andric   MRI = &MF.getRegInfo();
3700b57cec5SDimitry Andric   TII = Subtarget->getInstrInfo();
3710b57cec5SDimitry Andric   TRI = Subtarget->getRegisterInfo();
3720b57cec5SDimitry Andric   MDT = &getAnalysis<MachineDominatorTree>();
3730b57cec5SDimitry Andric   PromoteRC = &X86::GR8RegClass;
3740b57cec5SDimitry Andric 
3750b57cec5SDimitry Andric   if (MF.begin() == MF.end())
3760b57cec5SDimitry Andric     // Nothing to do for a degenerate empty function...
3770b57cec5SDimitry Andric     return false;
3780b57cec5SDimitry Andric 
3790b57cec5SDimitry Andric   // Collect the copies in RPO so that when there are chains where a copy is in
3800b57cec5SDimitry Andric   // turn copied again we visit the first one first. This ensures we can find
3810b57cec5SDimitry Andric   // viable locations for testing the original EFLAGS that dominate all the
3820b57cec5SDimitry Andric   // uses across complex CFGs.
3830b57cec5SDimitry Andric   SmallVector<MachineInstr *, 4> Copies;
3840b57cec5SDimitry Andric   ReversePostOrderTraversal<MachineFunction *> RPOT(&MF);
3850b57cec5SDimitry Andric   for (MachineBasicBlock *MBB : RPOT)
3860b57cec5SDimitry Andric     for (MachineInstr &MI : *MBB)
3870b57cec5SDimitry Andric       if (MI.getOpcode() == TargetOpcode::COPY &&
3880b57cec5SDimitry Andric           MI.getOperand(0).getReg() == X86::EFLAGS)
3890b57cec5SDimitry Andric         Copies.push_back(&MI);
3900b57cec5SDimitry Andric 
3910b57cec5SDimitry Andric   for (MachineInstr *CopyI : Copies) {
3920b57cec5SDimitry Andric     MachineBasicBlock &MBB = *CopyI->getParent();
3930b57cec5SDimitry Andric 
3940b57cec5SDimitry Andric     MachineOperand &VOp = CopyI->getOperand(1);
3950b57cec5SDimitry Andric     assert(VOp.isReg() &&
3960b57cec5SDimitry Andric            "The input to the copy for EFLAGS should always be a register!");
3970b57cec5SDimitry Andric     MachineInstr &CopyDefI = *MRI->getVRegDef(VOp.getReg());
3980b57cec5SDimitry Andric     if (CopyDefI.getOpcode() != TargetOpcode::COPY) {
3990b57cec5SDimitry Andric       // FIXME: The big likely candidate here are PHI nodes. We could in theory
4000b57cec5SDimitry Andric       // handle PHI nodes, but it gets really, really hard. Insanely hard. Hard
4010b57cec5SDimitry Andric       // enough that it is probably better to change every other part of LLVM
4020b57cec5SDimitry Andric       // to avoid creating them. The issue is that once we have PHIs we won't
4030b57cec5SDimitry Andric       // know which original EFLAGS value we need to capture with our setCCs
4040b57cec5SDimitry Andric       // below. The end result will be computing a complete set of setCCs that
4050b57cec5SDimitry Andric       // we *might* want, computing them in every place where we copy *out* of
4060b57cec5SDimitry Andric       // EFLAGS and then doing SSA formation on all of them to insert necessary
4070b57cec5SDimitry Andric       // PHI nodes and consume those here. Then hoping that somehow we DCE the
4080b57cec5SDimitry Andric       // unnecessary ones. This DCE seems very unlikely to be successful and so
4090b57cec5SDimitry Andric       // we will almost certainly end up with a glut of dead setCC
4100b57cec5SDimitry Andric       // instructions. Until we have a motivating test case and fail to avoid
4110b57cec5SDimitry Andric       // it by changing other parts of LLVM's lowering, we refuse to handle
4120b57cec5SDimitry Andric       // this complex case here.
4130b57cec5SDimitry Andric       LLVM_DEBUG(
4140b57cec5SDimitry Andric           dbgs() << "ERROR: Encountered unexpected def of an eflags copy: ";
4150b57cec5SDimitry Andric           CopyDefI.dump());
4160b57cec5SDimitry Andric       report_fatal_error(
4170b57cec5SDimitry Andric           "Cannot lower EFLAGS copy unless it is defined in turn by a copy!");
4180b57cec5SDimitry Andric     }
4190b57cec5SDimitry Andric 
4200b57cec5SDimitry Andric     auto Cleanup = make_scope_exit([&] {
4210b57cec5SDimitry Andric       // All uses of the EFLAGS copy are now rewritten, kill the copy into
4220b57cec5SDimitry Andric       // eflags and if dead the copy from.
4230b57cec5SDimitry Andric       CopyI->eraseFromParent();
4240b57cec5SDimitry Andric       if (MRI->use_empty(CopyDefI.getOperand(0).getReg()))
4250b57cec5SDimitry Andric         CopyDefI.eraseFromParent();
4260b57cec5SDimitry Andric       ++NumCopiesEliminated;
4270b57cec5SDimitry Andric     });
4280b57cec5SDimitry Andric 
4290b57cec5SDimitry Andric     MachineOperand &DOp = CopyI->getOperand(0);
4300b57cec5SDimitry Andric     assert(DOp.isDef() && "Expected register def!");
4310b57cec5SDimitry Andric     assert(DOp.getReg() == X86::EFLAGS && "Unexpected copy def register!");
4320b57cec5SDimitry Andric     if (DOp.isDead())
4330b57cec5SDimitry Andric       continue;
4340b57cec5SDimitry Andric 
4350b57cec5SDimitry Andric     MachineBasicBlock *TestMBB = CopyDefI.getParent();
4360b57cec5SDimitry Andric     auto TestPos = CopyDefI.getIterator();
4370b57cec5SDimitry Andric     DebugLoc TestLoc = CopyDefI.getDebugLoc();
4380b57cec5SDimitry Andric 
4390b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Rewriting copy: "; CopyI->dump());
4400b57cec5SDimitry Andric 
4410b57cec5SDimitry Andric     // Walk up across live-in EFLAGS to find where they were actually def'ed.
4420b57cec5SDimitry Andric     //
4430b57cec5SDimitry Andric     // This copy's def may just be part of a region of blocks covered by
4440b57cec5SDimitry Andric     // a single def of EFLAGS and we want to find the top of that region where
4450b57cec5SDimitry Andric     // possible.
4460b57cec5SDimitry Andric     //
4470b57cec5SDimitry Andric     // This is essentially a search for a *candidate* reaching definition
4480b57cec5SDimitry Andric     // location. We don't need to ever find the actual reaching definition here,
4490b57cec5SDimitry Andric     // but we want to walk up the dominator tree to find the highest point which
4500b57cec5SDimitry Andric     // would be viable for such a definition.
4510b57cec5SDimitry Andric     auto HasEFLAGSClobber = [&](MachineBasicBlock::iterator Begin,
4520b57cec5SDimitry Andric                                 MachineBasicBlock::iterator End) {
4530b57cec5SDimitry Andric       // Scan backwards as we expect these to be relatively short and often find
4540b57cec5SDimitry Andric       // a clobber near the end.
4550b57cec5SDimitry Andric       return llvm::any_of(
4560b57cec5SDimitry Andric           llvm::reverse(llvm::make_range(Begin, End)), [&](MachineInstr &MI) {
4570b57cec5SDimitry Andric             // Flag any instruction (other than the copy we are
4580b57cec5SDimitry Andric             // currently rewriting) that defs EFLAGS.
4590b57cec5SDimitry Andric             return &MI != CopyI && MI.findRegisterDefOperand(X86::EFLAGS);
4600b57cec5SDimitry Andric           });
4610b57cec5SDimitry Andric     };
4620b57cec5SDimitry Andric     auto HasEFLAGSClobberPath = [&](MachineBasicBlock *BeginMBB,
4630b57cec5SDimitry Andric                                     MachineBasicBlock *EndMBB) {
4640b57cec5SDimitry Andric       assert(MDT->dominates(BeginMBB, EndMBB) &&
4650b57cec5SDimitry Andric              "Only support paths down the dominator tree!");
4660b57cec5SDimitry Andric       SmallPtrSet<MachineBasicBlock *, 4> Visited;
4670b57cec5SDimitry Andric       SmallVector<MachineBasicBlock *, 4> Worklist;
4680b57cec5SDimitry Andric       // We terminate at the beginning. No need to scan it.
4690b57cec5SDimitry Andric       Visited.insert(BeginMBB);
4700b57cec5SDimitry Andric       Worklist.push_back(EndMBB);
4710b57cec5SDimitry Andric       do {
4720b57cec5SDimitry Andric         auto *MBB = Worklist.pop_back_val();
4730b57cec5SDimitry Andric         for (auto *PredMBB : MBB->predecessors()) {
4740b57cec5SDimitry Andric           if (!Visited.insert(PredMBB).second)
4750b57cec5SDimitry Andric             continue;
4760b57cec5SDimitry Andric           if (HasEFLAGSClobber(PredMBB->begin(), PredMBB->end()))
4770b57cec5SDimitry Andric             return true;
4780b57cec5SDimitry Andric           // Enqueue this block to walk its predecessors.
4790b57cec5SDimitry Andric           Worklist.push_back(PredMBB);
4800b57cec5SDimitry Andric         }
4810b57cec5SDimitry Andric       } while (!Worklist.empty());
4820b57cec5SDimitry Andric       // No clobber found along a path from the begin to end.
4830b57cec5SDimitry Andric       return false;
4840b57cec5SDimitry Andric     };
4850b57cec5SDimitry Andric     while (TestMBB->isLiveIn(X86::EFLAGS) && !TestMBB->pred_empty() &&
4860b57cec5SDimitry Andric            !HasEFLAGSClobber(TestMBB->begin(), TestPos)) {
4870b57cec5SDimitry Andric       // Find the nearest common dominator of the predecessors, as
4880b57cec5SDimitry Andric       // that will be the best candidate to hoist into.
4890b57cec5SDimitry Andric       MachineBasicBlock *HoistMBB =
4900b57cec5SDimitry Andric           std::accumulate(std::next(TestMBB->pred_begin()), TestMBB->pred_end(),
4910b57cec5SDimitry Andric                           *TestMBB->pred_begin(),
4920b57cec5SDimitry Andric                           [&](MachineBasicBlock *LHS, MachineBasicBlock *RHS) {
4930b57cec5SDimitry Andric                             return MDT->findNearestCommonDominator(LHS, RHS);
4940b57cec5SDimitry Andric                           });
4950b57cec5SDimitry Andric 
4960b57cec5SDimitry Andric       // Now we need to scan all predecessors that may be reached along paths to
4970b57cec5SDimitry Andric       // the hoist block. A clobber anywhere in any of these blocks the hoist.
4980b57cec5SDimitry Andric       // Note that this even handles loops because we require *no* clobbers.
4990b57cec5SDimitry Andric       if (HasEFLAGSClobberPath(HoistMBB, TestMBB))
5000b57cec5SDimitry Andric         break;
5010b57cec5SDimitry Andric 
5020b57cec5SDimitry Andric       // We also need the terminators to not sneakily clobber flags.
5030b57cec5SDimitry Andric       if (HasEFLAGSClobber(HoistMBB->getFirstTerminator()->getIterator(),
5040b57cec5SDimitry Andric                            HoistMBB->instr_end()))
5050b57cec5SDimitry Andric         break;
5060b57cec5SDimitry Andric 
5070b57cec5SDimitry Andric       // We found a viable location, hoist our test position to it.
5080b57cec5SDimitry Andric       TestMBB = HoistMBB;
5090b57cec5SDimitry Andric       TestPos = TestMBB->getFirstTerminator()->getIterator();
5100b57cec5SDimitry Andric       // Clear the debug location as it would just be confusing after hoisting.
5110b57cec5SDimitry Andric       TestLoc = DebugLoc();
5120b57cec5SDimitry Andric     }
5130b57cec5SDimitry Andric     LLVM_DEBUG({
5140b57cec5SDimitry Andric       auto DefIt = llvm::find_if(
5150b57cec5SDimitry Andric           llvm::reverse(llvm::make_range(TestMBB->instr_begin(), TestPos)),
5160b57cec5SDimitry Andric           [&](MachineInstr &MI) {
5170b57cec5SDimitry Andric             return MI.findRegisterDefOperand(X86::EFLAGS);
5180b57cec5SDimitry Andric           });
5190b57cec5SDimitry Andric       if (DefIt.base() != TestMBB->instr_begin()) {
5200b57cec5SDimitry Andric         dbgs() << "  Using EFLAGS defined by: ";
5210b57cec5SDimitry Andric         DefIt->dump();
5220b57cec5SDimitry Andric       } else {
5230b57cec5SDimitry Andric         dbgs() << "  Using live-in flags for BB:\n";
5240b57cec5SDimitry Andric         TestMBB->dump();
5250b57cec5SDimitry Andric       }
5260b57cec5SDimitry Andric     });
5270b57cec5SDimitry Andric 
5280b57cec5SDimitry Andric     // While rewriting uses, we buffer jumps and rewrite them in a second pass
5290b57cec5SDimitry Andric     // because doing so will perturb the CFG that we are walking to find the
5300b57cec5SDimitry Andric     // uses in the first place.
5310b57cec5SDimitry Andric     SmallVector<MachineInstr *, 4> JmpIs;
5320b57cec5SDimitry Andric 
5330b57cec5SDimitry Andric     // Gather the condition flags that have already been preserved in
5340b57cec5SDimitry Andric     // registers. We do this from scratch each time as we expect there to be
5350b57cec5SDimitry Andric     // very few of them and we expect to not revisit the same copy definition
5360b57cec5SDimitry Andric     // many times. If either of those change sufficiently we could build a map
5370b57cec5SDimitry Andric     // of these up front instead.
5380b57cec5SDimitry Andric     CondRegArray CondRegs = collectCondsInRegs(*TestMBB, TestPos);
5390b57cec5SDimitry Andric 
5400b57cec5SDimitry Andric     // Collect the basic blocks we need to scan. Typically this will just be
5410b57cec5SDimitry Andric     // a single basic block but we may have to scan multiple blocks if the
5420b57cec5SDimitry Andric     // EFLAGS copy lives into successors.
5430b57cec5SDimitry Andric     SmallVector<MachineBasicBlock *, 2> Blocks;
5440b57cec5SDimitry Andric     SmallPtrSet<MachineBasicBlock *, 2> VisitedBlocks;
5450b57cec5SDimitry Andric     Blocks.push_back(&MBB);
5460b57cec5SDimitry Andric 
5470b57cec5SDimitry Andric     do {
5480b57cec5SDimitry Andric       MachineBasicBlock &UseMBB = *Blocks.pop_back_val();
5490b57cec5SDimitry Andric 
5500b57cec5SDimitry Andric       // Track when if/when we find a kill of the flags in this block.
5510b57cec5SDimitry Andric       bool FlagsKilled = false;
5520b57cec5SDimitry Andric 
5530b57cec5SDimitry Andric       // In most cases, we walk from the beginning to the end of the block. But
5540b57cec5SDimitry Andric       // when the block is the same block as the copy is from, we will visit it
5550b57cec5SDimitry Andric       // twice. The first time we start from the copy and go to the end. The
5560b57cec5SDimitry Andric       // second time we start from the beginning and go to the copy. This lets
5570b57cec5SDimitry Andric       // us handle copies inside of cycles.
5580b57cec5SDimitry Andric       // FIXME: This loop is *super* confusing. This is at least in part
5590b57cec5SDimitry Andric       // a symptom of all of this routine needing to be refactored into
5600b57cec5SDimitry Andric       // documentable components. Once done, there may be a better way to write
5610b57cec5SDimitry Andric       // this loop.
5620b57cec5SDimitry Andric       for (auto MII = (&UseMBB == &MBB && !VisitedBlocks.count(&UseMBB))
5630b57cec5SDimitry Andric                           ? std::next(CopyI->getIterator())
5640b57cec5SDimitry Andric                           : UseMBB.instr_begin(),
5650b57cec5SDimitry Andric                 MIE = UseMBB.instr_end();
5660b57cec5SDimitry Andric            MII != MIE;) {
5670b57cec5SDimitry Andric         MachineInstr &MI = *MII++;
5680b57cec5SDimitry Andric         // If we are in the original copy block and encounter either the copy
5690b57cec5SDimitry Andric         // def or the copy itself, break so that we don't re-process any part of
5700b57cec5SDimitry Andric         // the block or process the instructions in the range that was copied
5710b57cec5SDimitry Andric         // over.
5720b57cec5SDimitry Andric         if (&MI == CopyI || &MI == &CopyDefI) {
5730b57cec5SDimitry Andric           assert(&UseMBB == &MBB && VisitedBlocks.count(&MBB) &&
5740b57cec5SDimitry Andric                  "Should only encounter these on the second pass over the "
5750b57cec5SDimitry Andric                  "original block.");
5760b57cec5SDimitry Andric           break;
5770b57cec5SDimitry Andric         }
5780b57cec5SDimitry Andric 
5790b57cec5SDimitry Andric         MachineOperand *FlagUse = MI.findRegisterUseOperand(X86::EFLAGS);
5800b57cec5SDimitry Andric         if (!FlagUse) {
5810b57cec5SDimitry Andric           if (MI.findRegisterDefOperand(X86::EFLAGS)) {
5820b57cec5SDimitry Andric             // If EFLAGS are defined, it's as-if they were killed. We can stop
5830b57cec5SDimitry Andric             // scanning here.
5840b57cec5SDimitry Andric             //
5850b57cec5SDimitry Andric             // NB!!! Many instructions only modify some flags. LLVM currently
5860b57cec5SDimitry Andric             // models this as clobbering all flags, but if that ever changes
5870b57cec5SDimitry Andric             // this will need to be carefully updated to handle that more
5880b57cec5SDimitry Andric             // complex logic.
5890b57cec5SDimitry Andric             FlagsKilled = true;
5900b57cec5SDimitry Andric             break;
5910b57cec5SDimitry Andric           }
5920b57cec5SDimitry Andric           continue;
5930b57cec5SDimitry Andric         }
5940b57cec5SDimitry Andric 
5950b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "  Rewriting use: "; MI.dump());
5960b57cec5SDimitry Andric 
5970b57cec5SDimitry Andric         // Check the kill flag before we rewrite as that may change it.
5980b57cec5SDimitry Andric         if (FlagUse->isKill())
5990b57cec5SDimitry Andric           FlagsKilled = true;
6000b57cec5SDimitry Andric 
6010b57cec5SDimitry Andric         // Once we encounter a branch, the rest of the instructions must also be
6020b57cec5SDimitry Andric         // branches. We can't rewrite in place here, so we handle them below.
6030b57cec5SDimitry Andric         //
6040b57cec5SDimitry Andric         // Note that we don't have to handle tail calls here, even conditional
6050b57cec5SDimitry Andric         // tail calls, as those are not introduced into the X86 MI until post-RA
6060b57cec5SDimitry Andric         // branch folding or black placement. As a consequence, we get to deal
6070b57cec5SDimitry Andric         // with the simpler formulation of conditional branches followed by tail
6080b57cec5SDimitry Andric         // calls.
6090b57cec5SDimitry Andric         if (X86::getCondFromBranch(MI) != X86::COND_INVALID) {
6100b57cec5SDimitry Andric           auto JmpIt = MI.getIterator();
6110b57cec5SDimitry Andric           do {
6120b57cec5SDimitry Andric             JmpIs.push_back(&*JmpIt);
6130b57cec5SDimitry Andric             ++JmpIt;
6140b57cec5SDimitry Andric           } while (JmpIt != UseMBB.instr_end() &&
6150b57cec5SDimitry Andric                    X86::getCondFromBranch(*JmpIt) !=
6160b57cec5SDimitry Andric                        X86::COND_INVALID);
6170b57cec5SDimitry Andric           break;
6180b57cec5SDimitry Andric         }
6190b57cec5SDimitry Andric 
6200b57cec5SDimitry Andric         // Otherwise we can just rewrite in-place.
6210b57cec5SDimitry Andric         if (X86::getCondFromCMov(MI) != X86::COND_INVALID) {
6220b57cec5SDimitry Andric           rewriteCMov(*TestMBB, TestPos, TestLoc, MI, *FlagUse, CondRegs);
6232a168f03SDimitry Andric         } else if (getCondFromFCMOV(MI.getOpcode()) != X86::COND_INVALID) {
6242a168f03SDimitry Andric           rewriteFCMov(*TestMBB, TestPos, TestLoc, MI, *FlagUse, CondRegs);
6250b57cec5SDimitry Andric         } else if (X86::getCondFromSETCC(MI) != X86::COND_INVALID) {
6260b57cec5SDimitry Andric           rewriteSetCC(*TestMBB, TestPos, TestLoc, MI, *FlagUse, CondRegs);
6270b57cec5SDimitry Andric         } else if (MI.getOpcode() == TargetOpcode::COPY) {
6280b57cec5SDimitry Andric           rewriteCopy(MI, *FlagUse, CopyDefI);
6290b57cec5SDimitry Andric         } else {
6300b57cec5SDimitry Andric           // We assume all other instructions that use flags also def them.
6310b57cec5SDimitry Andric           assert(MI.findRegisterDefOperand(X86::EFLAGS) &&
6320b57cec5SDimitry Andric                  "Expected a def of EFLAGS for this instruction!");
6330b57cec5SDimitry Andric 
6340b57cec5SDimitry Andric           // NB!!! Several arithmetic instructions only *partially* update
6350b57cec5SDimitry Andric           // flags. Theoretically, we could generate MI code sequences that
6360b57cec5SDimitry Andric           // would rely on this fact and observe different flags independently.
6370b57cec5SDimitry Andric           // But currently LLVM models all of these instructions as clobbering
6380b57cec5SDimitry Andric           // all the flags in an undef way. We rely on that to simplify the
6390b57cec5SDimitry Andric           // logic.
6400b57cec5SDimitry Andric           FlagsKilled = true;
6410b57cec5SDimitry Andric 
6420b57cec5SDimitry Andric           // Generically handle remaining uses as arithmetic instructions.
6430b57cec5SDimitry Andric           rewriteArithmetic(*TestMBB, TestPos, TestLoc, MI, *FlagUse,
6440b57cec5SDimitry Andric                             CondRegs);
6450b57cec5SDimitry Andric         }
6460b57cec5SDimitry Andric 
6470b57cec5SDimitry Andric         // If this was the last use of the flags, we're done.
6480b57cec5SDimitry Andric         if (FlagsKilled)
6490b57cec5SDimitry Andric           break;
6500b57cec5SDimitry Andric       }
6510b57cec5SDimitry Andric 
6520b57cec5SDimitry Andric       // If the flags were killed, we're done with this block.
6530b57cec5SDimitry Andric       if (FlagsKilled)
6540b57cec5SDimitry Andric         continue;
6550b57cec5SDimitry Andric 
6560b57cec5SDimitry Andric       // Otherwise we need to scan successors for ones where the flags live-in
6570b57cec5SDimitry Andric       // and queue those up for processing.
6580b57cec5SDimitry Andric       for (MachineBasicBlock *SuccMBB : UseMBB.successors())
6590b57cec5SDimitry Andric         if (SuccMBB->isLiveIn(X86::EFLAGS) &&
6600b57cec5SDimitry Andric             VisitedBlocks.insert(SuccMBB).second) {
6610b57cec5SDimitry Andric           // We currently don't do any PHI insertion and so we require that the
6620b57cec5SDimitry Andric           // test basic block dominates all of the use basic blocks. Further, we
6630b57cec5SDimitry Andric           // can't have a cycle from the test block back to itself as that would
6640b57cec5SDimitry Andric           // create a cycle requiring a PHI to break it.
6650b57cec5SDimitry Andric           //
6660b57cec5SDimitry Andric           // We could in theory do PHI insertion here if it becomes useful by
6670b57cec5SDimitry Andric           // just taking undef values in along every edge that we don't trace
6680b57cec5SDimitry Andric           // this EFLAGS copy along. This isn't as bad as fully general PHI
6690b57cec5SDimitry Andric           // insertion, but still seems like a great deal of complexity.
6700b57cec5SDimitry Andric           //
6710b57cec5SDimitry Andric           // Because it is theoretically possible that some earlier MI pass or
6720b57cec5SDimitry Andric           // other lowering transformation could induce this to happen, we do
6730b57cec5SDimitry Andric           // a hard check even in non-debug builds here.
6740b57cec5SDimitry Andric           if (SuccMBB == TestMBB || !MDT->dominates(TestMBB, SuccMBB)) {
6750b57cec5SDimitry Andric             LLVM_DEBUG({
6760b57cec5SDimitry Andric               dbgs()
6770b57cec5SDimitry Andric                   << "ERROR: Encountered use that is not dominated by our test "
6780b57cec5SDimitry Andric                      "basic block! Rewriting this would require inserting PHI "
6790b57cec5SDimitry Andric                      "nodes to track the flag state across the CFG.\n\nTest "
6800b57cec5SDimitry Andric                      "block:\n";
6810b57cec5SDimitry Andric               TestMBB->dump();
6820b57cec5SDimitry Andric               dbgs() << "Use block:\n";
6830b57cec5SDimitry Andric               SuccMBB->dump();
6840b57cec5SDimitry Andric             });
6850b57cec5SDimitry Andric             report_fatal_error(
6860b57cec5SDimitry Andric                 "Cannot lower EFLAGS copy when original copy def "
6870b57cec5SDimitry Andric                 "does not dominate all uses.");
6880b57cec5SDimitry Andric           }
6890b57cec5SDimitry Andric 
6900b57cec5SDimitry Andric           Blocks.push_back(SuccMBB);
691480093f4SDimitry Andric 
692480093f4SDimitry Andric           // After this, EFLAGS will be recreated before each use.
693480093f4SDimitry Andric           SuccMBB->removeLiveIn(X86::EFLAGS);
6940b57cec5SDimitry Andric         }
6950b57cec5SDimitry Andric     } while (!Blocks.empty());
6960b57cec5SDimitry Andric 
6970b57cec5SDimitry Andric     // Now rewrite the jumps that use the flags. These we handle specially
6980b57cec5SDimitry Andric     // because if there are multiple jumps in a single basic block we'll have
6990b57cec5SDimitry Andric     // to do surgery on the CFG.
7000b57cec5SDimitry Andric     MachineBasicBlock *LastJmpMBB = nullptr;
7010b57cec5SDimitry Andric     for (MachineInstr *JmpI : JmpIs) {
7020b57cec5SDimitry Andric       // Past the first jump within a basic block we need to split the blocks
7030b57cec5SDimitry Andric       // apart.
7040b57cec5SDimitry Andric       if (JmpI->getParent() == LastJmpMBB)
7050b57cec5SDimitry Andric         splitBlock(*JmpI->getParent(), *JmpI, *TII);
7060b57cec5SDimitry Andric       else
7070b57cec5SDimitry Andric         LastJmpMBB = JmpI->getParent();
7080b57cec5SDimitry Andric 
7090b57cec5SDimitry Andric       rewriteCondJmp(*TestMBB, TestPos, TestLoc, *JmpI, CondRegs);
7100b57cec5SDimitry Andric     }
7110b57cec5SDimitry Andric 
7120b57cec5SDimitry Andric     // FIXME: Mark the last use of EFLAGS before the copy's def as a kill if
7130b57cec5SDimitry Andric     // the copy's def operand is itself a kill.
7140b57cec5SDimitry Andric   }
7150b57cec5SDimitry Andric 
7160b57cec5SDimitry Andric #ifndef NDEBUG
7170b57cec5SDimitry Andric   for (MachineBasicBlock &MBB : MF)
7180b57cec5SDimitry Andric     for (MachineInstr &MI : MBB)
7190b57cec5SDimitry Andric       if (MI.getOpcode() == TargetOpcode::COPY &&
7200b57cec5SDimitry Andric           (MI.getOperand(0).getReg() == X86::EFLAGS ||
7210b57cec5SDimitry Andric            MI.getOperand(1).getReg() == X86::EFLAGS)) {
7220b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "ERROR: Found a COPY involving EFLAGS: ";
7230b57cec5SDimitry Andric                    MI.dump());
7240b57cec5SDimitry Andric         llvm_unreachable("Unlowered EFLAGS copy!");
7250b57cec5SDimitry Andric       }
7260b57cec5SDimitry Andric #endif
7270b57cec5SDimitry Andric 
7280b57cec5SDimitry Andric   return true;
7290b57cec5SDimitry Andric }
7300b57cec5SDimitry Andric 
7310b57cec5SDimitry Andric /// Collect any conditions that have already been set in registers so that we
7320b57cec5SDimitry Andric /// can re-use them rather than adding duplicates.
7330b57cec5SDimitry Andric CondRegArray X86FlagsCopyLoweringPass::collectCondsInRegs(
7340b57cec5SDimitry Andric     MachineBasicBlock &MBB, MachineBasicBlock::iterator TestPos) {
7350b57cec5SDimitry Andric   CondRegArray CondRegs = {};
7360b57cec5SDimitry Andric 
7370b57cec5SDimitry Andric   // Scan backwards across the range of instructions with live EFLAGS.
7380b57cec5SDimitry Andric   for (MachineInstr &MI :
7390b57cec5SDimitry Andric        llvm::reverse(llvm::make_range(MBB.begin(), TestPos))) {
7400b57cec5SDimitry Andric     X86::CondCode Cond = X86::getCondFromSETCC(MI);
7418bcb0991SDimitry Andric     if (Cond != X86::COND_INVALID && !MI.mayStore() &&
742*e8d8bef9SDimitry Andric         MI.getOperand(0).isReg() && MI.getOperand(0).getReg().isVirtual()) {
7430b57cec5SDimitry Andric       assert(MI.getOperand(0).isDef() &&
7440b57cec5SDimitry Andric              "A non-storing SETcc should always define a register!");
7450b57cec5SDimitry Andric       CondRegs[Cond] = MI.getOperand(0).getReg();
7460b57cec5SDimitry Andric     }
7470b57cec5SDimitry Andric 
7480b57cec5SDimitry Andric     // Stop scanning when we see the first definition of the EFLAGS as prior to
7490b57cec5SDimitry Andric     // this we would potentially capture the wrong flag state.
7500b57cec5SDimitry Andric     if (MI.findRegisterDefOperand(X86::EFLAGS))
7510b57cec5SDimitry Andric       break;
7520b57cec5SDimitry Andric   }
7530b57cec5SDimitry Andric   return CondRegs;
7540b57cec5SDimitry Andric }
7550b57cec5SDimitry Andric 
756*e8d8bef9SDimitry Andric Register X86FlagsCopyLoweringPass::promoteCondToReg(
7570b57cec5SDimitry Andric     MachineBasicBlock &TestMBB, MachineBasicBlock::iterator TestPos,
7580b57cec5SDimitry Andric     DebugLoc TestLoc, X86::CondCode Cond) {
7598bcb0991SDimitry Andric   Register Reg = MRI->createVirtualRegister(PromoteRC);
7600b57cec5SDimitry Andric   auto SetI = BuildMI(TestMBB, TestPos, TestLoc,
7610b57cec5SDimitry Andric                       TII->get(X86::SETCCr), Reg).addImm(Cond);
7620b57cec5SDimitry Andric   (void)SetI;
7630b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    save cond: "; SetI->dump());
7640b57cec5SDimitry Andric   ++NumSetCCsInserted;
7650b57cec5SDimitry Andric   return Reg;
7660b57cec5SDimitry Andric }
7670b57cec5SDimitry Andric 
7680b57cec5SDimitry Andric std::pair<unsigned, bool> X86FlagsCopyLoweringPass::getCondOrInverseInReg(
7690b57cec5SDimitry Andric     MachineBasicBlock &TestMBB, MachineBasicBlock::iterator TestPos,
7700b57cec5SDimitry Andric     DebugLoc TestLoc, X86::CondCode Cond, CondRegArray &CondRegs) {
7710b57cec5SDimitry Andric   unsigned &CondReg = CondRegs[Cond];
7720b57cec5SDimitry Andric   unsigned &InvCondReg = CondRegs[X86::GetOppositeBranchCondition(Cond)];
7730b57cec5SDimitry Andric   if (!CondReg && !InvCondReg)
7740b57cec5SDimitry Andric     CondReg = promoteCondToReg(TestMBB, TestPos, TestLoc, Cond);
7750b57cec5SDimitry Andric 
7760b57cec5SDimitry Andric   if (CondReg)
7770b57cec5SDimitry Andric     return {CondReg, false};
7780b57cec5SDimitry Andric   else
7790b57cec5SDimitry Andric     return {InvCondReg, true};
7800b57cec5SDimitry Andric }
7810b57cec5SDimitry Andric 
7820b57cec5SDimitry Andric void X86FlagsCopyLoweringPass::insertTest(MachineBasicBlock &MBB,
7830b57cec5SDimitry Andric                                           MachineBasicBlock::iterator Pos,
7840b57cec5SDimitry Andric                                           DebugLoc Loc, unsigned Reg) {
7850b57cec5SDimitry Andric   auto TestI =
7860b57cec5SDimitry Andric       BuildMI(MBB, Pos, Loc, TII->get(X86::TEST8rr)).addReg(Reg).addReg(Reg);
7870b57cec5SDimitry Andric   (void)TestI;
7880b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    test cond: "; TestI->dump());
7890b57cec5SDimitry Andric   ++NumTestsInserted;
7900b57cec5SDimitry Andric }
7910b57cec5SDimitry Andric 
7920b57cec5SDimitry Andric void X86FlagsCopyLoweringPass::rewriteArithmetic(
7930b57cec5SDimitry Andric     MachineBasicBlock &TestMBB, MachineBasicBlock::iterator TestPos,
7940b57cec5SDimitry Andric     DebugLoc TestLoc, MachineInstr &MI, MachineOperand &FlagUse,
7950b57cec5SDimitry Andric     CondRegArray &CondRegs) {
7960b57cec5SDimitry Andric   // Arithmetic is either reading CF or OF. Figure out which condition we need
7970b57cec5SDimitry Andric   // to preserve in a register.
798480093f4SDimitry Andric   X86::CondCode Cond = X86::COND_INVALID;
7990b57cec5SDimitry Andric 
8000b57cec5SDimitry Andric   // The addend to use to reset CF or OF when added to the flag value.
801480093f4SDimitry Andric   int Addend = 0;
8020b57cec5SDimitry Andric 
8030b57cec5SDimitry Andric   switch (getMnemonicFromOpcode(MI.getOpcode())) {
8040b57cec5SDimitry Andric   case FlagArithMnemonic::ADC:
8050b57cec5SDimitry Andric   case FlagArithMnemonic::ADCX:
8060b57cec5SDimitry Andric   case FlagArithMnemonic::RCL:
8070b57cec5SDimitry Andric   case FlagArithMnemonic::RCR:
8080b57cec5SDimitry Andric   case FlagArithMnemonic::SBB:
8095ffd83dbSDimitry Andric   case FlagArithMnemonic::SETB:
8100b57cec5SDimitry Andric     Cond = X86::COND_B; // CF == 1
8110b57cec5SDimitry Andric     // Set up an addend that when one is added will need a carry due to not
8120b57cec5SDimitry Andric     // having a higher bit available.
8130b57cec5SDimitry Andric     Addend = 255;
8140b57cec5SDimitry Andric     break;
8150b57cec5SDimitry Andric 
8160b57cec5SDimitry Andric   case FlagArithMnemonic::ADOX:
8170b57cec5SDimitry Andric     Cond = X86::COND_O; // OF == 1
8180b57cec5SDimitry Andric     // Set up an addend that when one is added will turn from positive to
8190b57cec5SDimitry Andric     // negative and thus overflow in the signed domain.
8200b57cec5SDimitry Andric     Addend = 127;
8210b57cec5SDimitry Andric     break;
8220b57cec5SDimitry Andric   }
8230b57cec5SDimitry Andric 
8240b57cec5SDimitry Andric   // Now get a register that contains the value of the flag input to the
8250b57cec5SDimitry Andric   // arithmetic. We require exactly this flag to simplify the arithmetic
8260b57cec5SDimitry Andric   // required to materialize it back into the flag.
8270b57cec5SDimitry Andric   unsigned &CondReg = CondRegs[Cond];
8280b57cec5SDimitry Andric   if (!CondReg)
8290b57cec5SDimitry Andric     CondReg = promoteCondToReg(TestMBB, TestPos, TestLoc, Cond);
8300b57cec5SDimitry Andric 
8310b57cec5SDimitry Andric   MachineBasicBlock &MBB = *MI.getParent();
8320b57cec5SDimitry Andric 
8330b57cec5SDimitry Andric   // Insert an instruction that will set the flag back to the desired value.
8348bcb0991SDimitry Andric   Register TmpReg = MRI->createVirtualRegister(PromoteRC);
8350b57cec5SDimitry Andric   auto AddI =
8360b57cec5SDimitry Andric       BuildMI(MBB, MI.getIterator(), MI.getDebugLoc(), TII->get(X86::ADD8ri))
8370b57cec5SDimitry Andric           .addDef(TmpReg, RegState::Dead)
8380b57cec5SDimitry Andric           .addReg(CondReg)
8390b57cec5SDimitry Andric           .addImm(Addend);
8400b57cec5SDimitry Andric   (void)AddI;
8410b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    add cond: "; AddI->dump());
8420b57cec5SDimitry Andric   ++NumAddsInserted;
8430b57cec5SDimitry Andric   FlagUse.setIsKill(true);
8440b57cec5SDimitry Andric }
8450b57cec5SDimitry Andric 
8460b57cec5SDimitry Andric void X86FlagsCopyLoweringPass::rewriteCMov(MachineBasicBlock &TestMBB,
8470b57cec5SDimitry Andric                                            MachineBasicBlock::iterator TestPos,
8480b57cec5SDimitry Andric                                            DebugLoc TestLoc,
8490b57cec5SDimitry Andric                                            MachineInstr &CMovI,
8500b57cec5SDimitry Andric                                            MachineOperand &FlagUse,
8510b57cec5SDimitry Andric                                            CondRegArray &CondRegs) {
8520b57cec5SDimitry Andric   // First get the register containing this specific condition.
8530b57cec5SDimitry Andric   X86::CondCode Cond = X86::getCondFromCMov(CMovI);
8540b57cec5SDimitry Andric   unsigned CondReg;
8550b57cec5SDimitry Andric   bool Inverted;
8560b57cec5SDimitry Andric   std::tie(CondReg, Inverted) =
8570b57cec5SDimitry Andric       getCondOrInverseInReg(TestMBB, TestPos, TestLoc, Cond, CondRegs);
8580b57cec5SDimitry Andric 
8590b57cec5SDimitry Andric   MachineBasicBlock &MBB = *CMovI.getParent();
8600b57cec5SDimitry Andric 
8610b57cec5SDimitry Andric   // Insert a direct test of the saved register.
8620b57cec5SDimitry Andric   insertTest(MBB, CMovI.getIterator(), CMovI.getDebugLoc(), CondReg);
8630b57cec5SDimitry Andric 
8640b57cec5SDimitry Andric   // Rewrite the CMov to use the !ZF flag from the test, and then kill its use
8650b57cec5SDimitry Andric   // of the flags afterward.
8660b57cec5SDimitry Andric   CMovI.getOperand(CMovI.getDesc().getNumOperands() - 1)
8670b57cec5SDimitry Andric       .setImm(Inverted ? X86::COND_E : X86::COND_NE);
8680b57cec5SDimitry Andric   FlagUse.setIsKill(true);
8690b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    fixed cmov: "; CMovI.dump());
8700b57cec5SDimitry Andric }
8710b57cec5SDimitry Andric 
8722a168f03SDimitry Andric void X86FlagsCopyLoweringPass::rewriteFCMov(MachineBasicBlock &TestMBB,
8732a168f03SDimitry Andric                                             MachineBasicBlock::iterator TestPos,
8742a168f03SDimitry Andric                                             DebugLoc TestLoc,
8752a168f03SDimitry Andric                                             MachineInstr &CMovI,
8762a168f03SDimitry Andric                                             MachineOperand &FlagUse,
8772a168f03SDimitry Andric                                             CondRegArray &CondRegs) {
8782a168f03SDimitry Andric   // First get the register containing this specific condition.
8792a168f03SDimitry Andric   X86::CondCode Cond = getCondFromFCMOV(CMovI.getOpcode());
8802a168f03SDimitry Andric   unsigned CondReg;
8812a168f03SDimitry Andric   bool Inverted;
8822a168f03SDimitry Andric   std::tie(CondReg, Inverted) =
8832a168f03SDimitry Andric       getCondOrInverseInReg(TestMBB, TestPos, TestLoc, Cond, CondRegs);
8842a168f03SDimitry Andric 
8852a168f03SDimitry Andric   MachineBasicBlock &MBB = *CMovI.getParent();
8862a168f03SDimitry Andric 
8872a168f03SDimitry Andric   // Insert a direct test of the saved register.
8882a168f03SDimitry Andric   insertTest(MBB, CMovI.getIterator(), CMovI.getDebugLoc(), CondReg);
8892a168f03SDimitry Andric 
8902a168f03SDimitry Andric   auto getFCMOVOpcode = [](unsigned Opcode, bool Inverted) {
8912a168f03SDimitry Andric     switch (Opcode) {
8922a168f03SDimitry Andric     default: llvm_unreachable("Unexpected opcode!");
8932a168f03SDimitry Andric     case X86::CMOVBE_Fp32: case X86::CMOVNBE_Fp32:
8942a168f03SDimitry Andric     case X86::CMOVB_Fp32:  case X86::CMOVNB_Fp32:
8952a168f03SDimitry Andric     case X86::CMOVE_Fp32:  case X86::CMOVNE_Fp32:
8962a168f03SDimitry Andric     case X86::CMOVP_Fp32:  case X86::CMOVNP_Fp32:
8972a168f03SDimitry Andric       return Inverted ? X86::CMOVE_Fp32 : X86::CMOVNE_Fp32;
8982a168f03SDimitry Andric     case X86::CMOVBE_Fp64: case X86::CMOVNBE_Fp64:
8992a168f03SDimitry Andric     case X86::CMOVB_Fp64:  case X86::CMOVNB_Fp64:
9002a168f03SDimitry Andric     case X86::CMOVE_Fp64:  case X86::CMOVNE_Fp64:
9012a168f03SDimitry Andric     case X86::CMOVP_Fp64:  case X86::CMOVNP_Fp64:
9022a168f03SDimitry Andric       return Inverted ? X86::CMOVE_Fp64 : X86::CMOVNE_Fp64;
9032a168f03SDimitry Andric     case X86::CMOVBE_Fp80: case X86::CMOVNBE_Fp80:
9042a168f03SDimitry Andric     case X86::CMOVB_Fp80:  case X86::CMOVNB_Fp80:
9052a168f03SDimitry Andric     case X86::CMOVE_Fp80:  case X86::CMOVNE_Fp80:
9062a168f03SDimitry Andric     case X86::CMOVP_Fp80:  case X86::CMOVNP_Fp80:
9072a168f03SDimitry Andric       return Inverted ? X86::CMOVE_Fp80 : X86::CMOVNE_Fp80;
9082a168f03SDimitry Andric     }
9092a168f03SDimitry Andric   };
9102a168f03SDimitry Andric 
9112a168f03SDimitry Andric   // Rewrite the CMov to use the !ZF flag from the test.
9122a168f03SDimitry Andric   CMovI.setDesc(TII->get(getFCMOVOpcode(CMovI.getOpcode(), Inverted)));
9132a168f03SDimitry Andric   FlagUse.setIsKill(true);
9142a168f03SDimitry Andric   LLVM_DEBUG(dbgs() << "    fixed fcmov: "; CMovI.dump());
9152a168f03SDimitry Andric }
9162a168f03SDimitry Andric 
9170b57cec5SDimitry Andric void X86FlagsCopyLoweringPass::rewriteCondJmp(
9180b57cec5SDimitry Andric     MachineBasicBlock &TestMBB, MachineBasicBlock::iterator TestPos,
9190b57cec5SDimitry Andric     DebugLoc TestLoc, MachineInstr &JmpI, CondRegArray &CondRegs) {
9200b57cec5SDimitry Andric   // First get the register containing this specific condition.
9210b57cec5SDimitry Andric   X86::CondCode Cond = X86::getCondFromBranch(JmpI);
9220b57cec5SDimitry Andric   unsigned CondReg;
9230b57cec5SDimitry Andric   bool Inverted;
9240b57cec5SDimitry Andric   std::tie(CondReg, Inverted) =
9250b57cec5SDimitry Andric       getCondOrInverseInReg(TestMBB, TestPos, TestLoc, Cond, CondRegs);
9260b57cec5SDimitry Andric 
9270b57cec5SDimitry Andric   MachineBasicBlock &JmpMBB = *JmpI.getParent();
9280b57cec5SDimitry Andric 
9290b57cec5SDimitry Andric   // Insert a direct test of the saved register.
9300b57cec5SDimitry Andric   insertTest(JmpMBB, JmpI.getIterator(), JmpI.getDebugLoc(), CondReg);
9310b57cec5SDimitry Andric 
9320b57cec5SDimitry Andric   // Rewrite the jump to use the !ZF flag from the test, and kill its use of
9330b57cec5SDimitry Andric   // flags afterward.
9340b57cec5SDimitry Andric   JmpI.getOperand(1).setImm(Inverted ? X86::COND_E : X86::COND_NE);
9350b57cec5SDimitry Andric   JmpI.findRegisterUseOperand(X86::EFLAGS)->setIsKill(true);
9360b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "    fixed jCC: "; JmpI.dump());
9370b57cec5SDimitry Andric }
9380b57cec5SDimitry Andric 
9390b57cec5SDimitry Andric void X86FlagsCopyLoweringPass::rewriteCopy(MachineInstr &MI,
9400b57cec5SDimitry Andric                                            MachineOperand &FlagUse,
9410b57cec5SDimitry Andric                                            MachineInstr &CopyDefI) {
9420b57cec5SDimitry Andric   // Just replace this copy with the original copy def.
9430b57cec5SDimitry Andric   MRI->replaceRegWith(MI.getOperand(0).getReg(),
9440b57cec5SDimitry Andric                       CopyDefI.getOperand(0).getReg());
9450b57cec5SDimitry Andric   MI.eraseFromParent();
9460b57cec5SDimitry Andric }
9470b57cec5SDimitry Andric 
9480b57cec5SDimitry Andric void X86FlagsCopyLoweringPass::rewriteSetCC(MachineBasicBlock &TestMBB,
9490b57cec5SDimitry Andric                                             MachineBasicBlock::iterator TestPos,
9500b57cec5SDimitry Andric                                             DebugLoc TestLoc,
9510b57cec5SDimitry Andric                                             MachineInstr &SetCCI,
9520b57cec5SDimitry Andric                                             MachineOperand &FlagUse,
9530b57cec5SDimitry Andric                                             CondRegArray &CondRegs) {
9540b57cec5SDimitry Andric   X86::CondCode Cond = X86::getCondFromSETCC(SetCCI);
9550b57cec5SDimitry Andric   // Note that we can't usefully rewrite this to the inverse without complex
9560b57cec5SDimitry Andric   // analysis of the users of the setCC. Largely we rely on duplicates which
9570b57cec5SDimitry Andric   // could have been avoided already being avoided here.
9580b57cec5SDimitry Andric   unsigned &CondReg = CondRegs[Cond];
9590b57cec5SDimitry Andric   if (!CondReg)
9600b57cec5SDimitry Andric     CondReg = promoteCondToReg(TestMBB, TestPos, TestLoc, Cond);
9610b57cec5SDimitry Andric 
9620b57cec5SDimitry Andric   // Rewriting a register def is trivial: we just replace the register and
9630b57cec5SDimitry Andric   // remove the setcc.
9640b57cec5SDimitry Andric   if (!SetCCI.mayStore()) {
9650b57cec5SDimitry Andric     assert(SetCCI.getOperand(0).isReg() &&
9660b57cec5SDimitry Andric            "Cannot have a non-register defined operand to SETcc!");
9670b57cec5SDimitry Andric     MRI->replaceRegWith(SetCCI.getOperand(0).getReg(), CondReg);
9680b57cec5SDimitry Andric     SetCCI.eraseFromParent();
9690b57cec5SDimitry Andric     return;
9700b57cec5SDimitry Andric   }
9710b57cec5SDimitry Andric 
9720b57cec5SDimitry Andric   // Otherwise, we need to emit a store.
9730b57cec5SDimitry Andric   auto MIB = BuildMI(*SetCCI.getParent(), SetCCI.getIterator(),
9740b57cec5SDimitry Andric                      SetCCI.getDebugLoc(), TII->get(X86::MOV8mr));
9750b57cec5SDimitry Andric   // Copy the address operands.
9760b57cec5SDimitry Andric   for (int i = 0; i < X86::AddrNumOperands; ++i)
9770b57cec5SDimitry Andric     MIB.add(SetCCI.getOperand(i));
9780b57cec5SDimitry Andric 
9790b57cec5SDimitry Andric   MIB.addReg(CondReg);
9800b57cec5SDimitry Andric 
9810b57cec5SDimitry Andric   MIB.setMemRefs(SetCCI.memoperands());
9820b57cec5SDimitry Andric 
9830b57cec5SDimitry Andric   SetCCI.eraseFromParent();
9840b57cec5SDimitry Andric }
985