10b57cec5SDimitry Andric //===- llvm/CodeGen/GlobalISel/IRTranslator.cpp - IRTranslator ---*- C++ -*-==//
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 /// This file implements the IRTranslator class.
100b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/IRTranslator.h"
130b57cec5SDimitry Andric #include "llvm/ADT/PostOrderIterator.h"
140b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
150b57cec5SDimitry Andric #include "llvm/ADT/ScopeExit.h"
160b57cec5SDimitry Andric #include "llvm/ADT/SmallSet.h"
170b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
18fcaf7f86SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h"
19bdd1243dSDimitry Andric #include "llvm/Analysis/AssumptionCache.h"
200b57cec5SDimitry Andric #include "llvm/Analysis/BranchProbabilityInfo.h"
21bdd1243dSDimitry Andric #include "llvm/Analysis/Loads.h"
220b57cec5SDimitry Andric #include "llvm/Analysis/OptimizationRemarkEmitter.h"
230b57cec5SDimitry Andric #include "llvm/Analysis/ValueTracking.h"
240b57cec5SDimitry Andric #include "llvm/CodeGen/Analysis.h"
2581ad6265SDimitry Andric #include "llvm/CodeGen/GlobalISel/CSEInfo.h"
2681ad6265SDimitry Andric #include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
270b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/CallLowering.h"
280b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
295ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/InlineAsmLowering.h"
30349cc55cSDimitry Andric #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
310b57cec5SDimitry Andric #include "llvm/CodeGen/LowLevelType.h"
3206c3fb27SDimitry Andric #include "llvm/CodeGen/LowLevelTypeUtils.h"
330b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
340b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
350b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
360b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
370b57cec5SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h"
38e8d8bef9SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
390b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
400b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
41349cc55cSDimitry Andric #include "llvm/CodeGen/RuntimeLibcalls.h"
420b57cec5SDimitry Andric #include "llvm/CodeGen/StackProtector.h"
43e8d8bef9SDimitry Andric #include "llvm/CodeGen/SwitchLoweringUtils.h"
440b57cec5SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h"
458bcb0991SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
460b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLowering.h"
4706c3fb27SDimitry Andric #include "llvm/CodeGen/TargetOpcodes.h"
480b57cec5SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h"
490b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
500b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
510b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h"
520b57cec5SDimitry Andric #include "llvm/IR/CFG.h"
530b57cec5SDimitry Andric #include "llvm/IR/Constant.h"
540b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
550b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h"
560b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h"
57349cc55cSDimitry Andric #include "llvm/IR/DiagnosticInfo.h"
580b57cec5SDimitry Andric #include "llvm/IR/Function.h"
590b57cec5SDimitry Andric #include "llvm/IR/GetElementPtrTypeIterator.h"
600b57cec5SDimitry Andric #include "llvm/IR/InlineAsm.h"
61e8d8bef9SDimitry Andric #include "llvm/IR/InstrTypes.h"
620b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
630b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
640b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h"
655f757f3fSDimitry Andric #include "llvm/IR/IntrinsicsAMDGPU.h"
660b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h"
670b57cec5SDimitry Andric #include "llvm/IR/Metadata.h"
68e8d8bef9SDimitry Andric #include "llvm/IR/PatternMatch.h"
69bdd1243dSDimitry Andric #include "llvm/IR/Statepoint.h"
700b57cec5SDimitry Andric #include "llvm/IR/Type.h"
710b57cec5SDimitry Andric #include "llvm/IR/User.h"
720b57cec5SDimitry Andric #include "llvm/IR/Value.h"
73480093f4SDimitry Andric #include "llvm/InitializePasses.h"
740b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
750b57cec5SDimitry Andric #include "llvm/Pass.h"
760b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
770b57cec5SDimitry Andric #include "llvm/Support/CodeGen.h"
780b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
790b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
800b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
810b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
820b57cec5SDimitry Andric #include "llvm/Target/TargetIntrinsicInfo.h"
830b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
845f757f3fSDimitry Andric #include "llvm/Transforms/Utils/Local.h"
85fe6060f1SDimitry Andric #include "llvm/Transforms/Utils/MemoryOpRemark.h"
860b57cec5SDimitry Andric #include <algorithm>
870b57cec5SDimitry Andric #include <cassert>
880b57cec5SDimitry Andric #include <cstdint>
890b57cec5SDimitry Andric #include <iterator>
90bdd1243dSDimitry Andric #include <optional>
910b57cec5SDimitry Andric #include <string>
920b57cec5SDimitry Andric #include <utility>
930b57cec5SDimitry Andric #include <vector>
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric #define DEBUG_TYPE "irtranslator"
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric using namespace llvm;
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric static cl::opt<bool>
1000b57cec5SDimitry Andric     EnableCSEInIRTranslator("enable-cse-in-irtranslator",
1010b57cec5SDimitry Andric                             cl::desc("Should enable CSE in irtranslator"),
1020b57cec5SDimitry Andric                             cl::Optional, cl::init(false));
1030b57cec5SDimitry Andric char IRTranslator::ID = 0;
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(IRTranslator, DEBUG_TYPE, "IRTranslator LLVM IR -> MI",
1060b57cec5SDimitry Andric                 false, false)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)1070b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
1080b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
109e8d8bef9SDimitry Andric INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
110e8d8bef9SDimitry Andric INITIALIZE_PASS_DEPENDENCY(StackProtector)
111fe6060f1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
1120b57cec5SDimitry Andric INITIALIZE_PASS_END(IRTranslator, DEBUG_TYPE, "IRTranslator LLVM IR -> MI",
1130b57cec5SDimitry Andric                 false, false)
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric static void reportTranslationError(MachineFunction &MF,
1160b57cec5SDimitry Andric                                    const TargetPassConfig &TPC,
1170b57cec5SDimitry Andric                                    OptimizationRemarkEmitter &ORE,
1180b57cec5SDimitry Andric                                    OptimizationRemarkMissed &R) {
1190b57cec5SDimitry Andric   MF.getProperties().set(MachineFunctionProperties::Property::FailedISel);
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric   // Print the function name explicitly if we don't have a debug location (which
1220b57cec5SDimitry Andric   // makes the diagnostic less useful) or if we're going to emit a raw error.
1230b57cec5SDimitry Andric   if (!R.getLocation().isValid() || TPC.isGlobalISelAbortEnabled())
1240b57cec5SDimitry Andric     R << (" (in function: " + MF.getName() + ")").str();
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric   if (TPC.isGlobalISelAbortEnabled())
127349cc55cSDimitry Andric     report_fatal_error(Twine(R.getMsg()));
1280b57cec5SDimitry Andric   else
1290b57cec5SDimitry Andric     ORE.emit(R);
1300b57cec5SDimitry Andric }
1310b57cec5SDimitry Andric 
IRTranslator(CodeGenOptLevel optlevel)1325f757f3fSDimitry Andric IRTranslator::IRTranslator(CodeGenOptLevel optlevel)
133e8d8bef9SDimitry Andric     : MachineFunctionPass(ID), OptLevel(optlevel) {}
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric #ifndef NDEBUG
1360b57cec5SDimitry Andric namespace {
1370b57cec5SDimitry Andric /// Verify that every instruction created has the same DILocation as the
1380b57cec5SDimitry Andric /// instruction being translated.
1390b57cec5SDimitry Andric class DILocationVerifier : public GISelChangeObserver {
1400b57cec5SDimitry Andric   const Instruction *CurrInst = nullptr;
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric public:
1430b57cec5SDimitry Andric   DILocationVerifier() = default;
1440b57cec5SDimitry Andric   ~DILocationVerifier() = default;
1450b57cec5SDimitry Andric 
getCurrentInst() const1460b57cec5SDimitry Andric   const Instruction *getCurrentInst() const { return CurrInst; }
setCurrentInst(const Instruction * Inst)1470b57cec5SDimitry Andric   void setCurrentInst(const Instruction *Inst) { CurrInst = Inst; }
1480b57cec5SDimitry Andric 
erasingInstr(MachineInstr & MI)1490b57cec5SDimitry Andric   void erasingInstr(MachineInstr &MI) override {}
changingInstr(MachineInstr & MI)1500b57cec5SDimitry Andric   void changingInstr(MachineInstr &MI) override {}
changedInstr(MachineInstr & MI)1510b57cec5SDimitry Andric   void changedInstr(MachineInstr &MI) override {}
1520b57cec5SDimitry Andric 
createdInstr(MachineInstr & MI)1530b57cec5SDimitry Andric   void createdInstr(MachineInstr &MI) override {
1540b57cec5SDimitry Andric     assert(getCurrentInst() && "Inserted instruction without a current MI");
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric     // Only print the check message if we're actually checking it.
1570b57cec5SDimitry Andric #ifndef NDEBUG
1580b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Checking DILocation from " << *CurrInst
1590b57cec5SDimitry Andric                       << " was copied to " << MI);
1600b57cec5SDimitry Andric #endif
161972a253aSDimitry Andric     // We allow insts in the entry block to have no debug loc because
1620b57cec5SDimitry Andric     // they could have originated from constants, and we don't want a jumpy
1630b57cec5SDimitry Andric     // debug experience.
1640b57cec5SDimitry Andric     assert((CurrInst->getDebugLoc() == MI.getDebugLoc() ||
1657a6dacacSDimitry Andric             (MI.getParent()->isEntryBlock() && !MI.getDebugLoc()) ||
1667a6dacacSDimitry Andric             (MI.isDebugInstr())) &&
1670b57cec5SDimitry Andric            "Line info was not transferred to all instructions");
1680b57cec5SDimitry Andric   }
1690b57cec5SDimitry Andric };
1700b57cec5SDimitry Andric } // namespace
1710b57cec5SDimitry Andric #endif // ifndef NDEBUG
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric 
getAnalysisUsage(AnalysisUsage & AU) const1740b57cec5SDimitry Andric void IRTranslator::getAnalysisUsage(AnalysisUsage &AU) const {
1750b57cec5SDimitry Andric   AU.addRequired<StackProtector>();
1760b57cec5SDimitry Andric   AU.addRequired<TargetPassConfig>();
1770b57cec5SDimitry Andric   AU.addRequired<GISelCSEAnalysisWrapperPass>();
178bdd1243dSDimitry Andric   AU.addRequired<AssumptionCacheTracker>();
1795f757f3fSDimitry Andric   if (OptLevel != CodeGenOptLevel::None) {
180e8d8bef9SDimitry Andric     AU.addRequired<BranchProbabilityInfoWrapperPass>();
181fcaf7f86SDimitry Andric     AU.addRequired<AAResultsWrapperPass>();
182fcaf7f86SDimitry Andric   }
183fe6060f1SDimitry Andric   AU.addRequired<TargetLibraryInfoWrapperPass>();
184fe6060f1SDimitry Andric   AU.addPreserved<TargetLibraryInfoWrapperPass>();
1850b57cec5SDimitry Andric   getSelectionDAGFallbackAnalysisUsage(AU);
1860b57cec5SDimitry Andric   MachineFunctionPass::getAnalysisUsage(AU);
1870b57cec5SDimitry Andric }
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric IRTranslator::ValueToVRegInfo::VRegListT &
allocateVRegs(const Value & Val)1900b57cec5SDimitry Andric IRTranslator::allocateVRegs(const Value &Val) {
191e8d8bef9SDimitry Andric   auto VRegsIt = VMap.findVRegs(Val);
192e8d8bef9SDimitry Andric   if (VRegsIt != VMap.vregs_end())
193e8d8bef9SDimitry Andric     return *VRegsIt->second;
1940b57cec5SDimitry Andric   auto *Regs = VMap.getVRegs(Val);
1950b57cec5SDimitry Andric   auto *Offsets = VMap.getOffsets(Val);
1960b57cec5SDimitry Andric   SmallVector<LLT, 4> SplitTys;
1970b57cec5SDimitry Andric   computeValueLLTs(*DL, *Val.getType(), SplitTys,
1980b57cec5SDimitry Andric                    Offsets->empty() ? Offsets : nullptr);
1990b57cec5SDimitry Andric   for (unsigned i = 0; i < SplitTys.size(); ++i)
2000b57cec5SDimitry Andric     Regs->push_back(0);
2010b57cec5SDimitry Andric   return *Regs;
2020b57cec5SDimitry Andric }
2030b57cec5SDimitry Andric 
getOrCreateVRegs(const Value & Val)2040b57cec5SDimitry Andric ArrayRef<Register> IRTranslator::getOrCreateVRegs(const Value &Val) {
2050b57cec5SDimitry Andric   auto VRegsIt = VMap.findVRegs(Val);
2060b57cec5SDimitry Andric   if (VRegsIt != VMap.vregs_end())
2070b57cec5SDimitry Andric     return *VRegsIt->second;
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric   if (Val.getType()->isVoidTy())
2100b57cec5SDimitry Andric     return *VMap.getVRegs(Val);
2110b57cec5SDimitry Andric 
2120b57cec5SDimitry Andric   // Create entry for this type.
2130b57cec5SDimitry Andric   auto *VRegs = VMap.getVRegs(Val);
2140b57cec5SDimitry Andric   auto *Offsets = VMap.getOffsets(Val);
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric   assert(Val.getType()->isSized() &&
2170b57cec5SDimitry Andric          "Don't know how to create an empty vreg");
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric   SmallVector<LLT, 4> SplitTys;
2200b57cec5SDimitry Andric   computeValueLLTs(*DL, *Val.getType(), SplitTys,
2210b57cec5SDimitry Andric                    Offsets->empty() ? Offsets : nullptr);
2220b57cec5SDimitry Andric 
2230b57cec5SDimitry Andric   if (!isa<Constant>(Val)) {
2240b57cec5SDimitry Andric     for (auto Ty : SplitTys)
2250b57cec5SDimitry Andric       VRegs->push_back(MRI->createGenericVirtualRegister(Ty));
2260b57cec5SDimitry Andric     return *VRegs;
2270b57cec5SDimitry Andric   }
2280b57cec5SDimitry Andric 
2290b57cec5SDimitry Andric   if (Val.getType()->isAggregateType()) {
2300b57cec5SDimitry Andric     // UndefValue, ConstantAggregateZero
2310b57cec5SDimitry Andric     auto &C = cast<Constant>(Val);
2320b57cec5SDimitry Andric     unsigned Idx = 0;
2330b57cec5SDimitry Andric     while (auto Elt = C.getAggregateElement(Idx++)) {
2340b57cec5SDimitry Andric       auto EltRegs = getOrCreateVRegs(*Elt);
2350b57cec5SDimitry Andric       llvm::copy(EltRegs, std::back_inserter(*VRegs));
2360b57cec5SDimitry Andric     }
2370b57cec5SDimitry Andric   } else {
2380b57cec5SDimitry Andric     assert(SplitTys.size() == 1 && "unexpectedly split LLT");
2390b57cec5SDimitry Andric     VRegs->push_back(MRI->createGenericVirtualRegister(SplitTys[0]));
2400b57cec5SDimitry Andric     bool Success = translate(cast<Constant>(Val), VRegs->front());
2410b57cec5SDimitry Andric     if (!Success) {
2420b57cec5SDimitry Andric       OptimizationRemarkMissed R("gisel-irtranslator", "GISelFailure",
2430b57cec5SDimitry Andric                                  MF->getFunction().getSubprogram(),
2440b57cec5SDimitry Andric                                  &MF->getFunction().getEntryBlock());
2450b57cec5SDimitry Andric       R << "unable to translate constant: " << ore::NV("Type", Val.getType());
2460b57cec5SDimitry Andric       reportTranslationError(*MF, *TPC, *ORE, R);
2470b57cec5SDimitry Andric       return *VRegs;
2480b57cec5SDimitry Andric     }
2490b57cec5SDimitry Andric   }
2500b57cec5SDimitry Andric 
2510b57cec5SDimitry Andric   return *VRegs;
2520b57cec5SDimitry Andric }
2530b57cec5SDimitry Andric 
getOrCreateFrameIndex(const AllocaInst & AI)2540b57cec5SDimitry Andric int IRTranslator::getOrCreateFrameIndex(const AllocaInst &AI) {
255e8d8bef9SDimitry Andric   auto MapEntry = FrameIndices.find(&AI);
256e8d8bef9SDimitry Andric   if (MapEntry != FrameIndices.end())
257e8d8bef9SDimitry Andric     return MapEntry->second;
2580b57cec5SDimitry Andric 
259480093f4SDimitry Andric   uint64_t ElementSize = DL->getTypeAllocSize(AI.getAllocatedType());
260480093f4SDimitry Andric   uint64_t Size =
2610b57cec5SDimitry Andric       ElementSize * cast<ConstantInt>(AI.getArraySize())->getZExtValue();
2620b57cec5SDimitry Andric 
2630b57cec5SDimitry Andric   // Always allocate at least one byte.
264480093f4SDimitry Andric   Size = std::max<uint64_t>(Size, 1u);
2650b57cec5SDimitry Andric 
2660b57cec5SDimitry Andric   int &FI = FrameIndices[&AI];
2675ffd83dbSDimitry Andric   FI = MF->getFrameInfo().CreateStackObject(Size, AI.getAlign(), false, &AI);
2680b57cec5SDimitry Andric   return FI;
2690b57cec5SDimitry Andric }
2700b57cec5SDimitry Andric 
getMemOpAlign(const Instruction & I)2715ffd83dbSDimitry Andric Align IRTranslator::getMemOpAlign(const Instruction &I) {
2725ffd83dbSDimitry Andric   if (const StoreInst *SI = dyn_cast<StoreInst>(&I))
2735ffd83dbSDimitry Andric     return SI->getAlign();
274fe6060f1SDimitry Andric   if (const LoadInst *LI = dyn_cast<LoadInst>(&I))
2755ffd83dbSDimitry Andric     return LI->getAlign();
276fe6060f1SDimitry Andric   if (const AtomicCmpXchgInst *AI = dyn_cast<AtomicCmpXchgInst>(&I))
277fe6060f1SDimitry Andric     return AI->getAlign();
278fe6060f1SDimitry Andric   if (const AtomicRMWInst *AI = dyn_cast<AtomicRMWInst>(&I))
279fe6060f1SDimitry Andric     return AI->getAlign();
280fe6060f1SDimitry Andric 
2810b57cec5SDimitry Andric   OptimizationRemarkMissed R("gisel-irtranslator", "", &I);
2820b57cec5SDimitry Andric   R << "unable to translate memop: " << ore::NV("Opcode", &I);
2830b57cec5SDimitry Andric   reportTranslationError(*MF, *TPC, *ORE, R);
2845ffd83dbSDimitry Andric   return Align(1);
2850b57cec5SDimitry Andric }
2860b57cec5SDimitry Andric 
getMBB(const BasicBlock & BB)2870b57cec5SDimitry Andric MachineBasicBlock &IRTranslator::getMBB(const BasicBlock &BB) {
2880b57cec5SDimitry Andric   MachineBasicBlock *&MBB = BBToMBB[&BB];
2890b57cec5SDimitry Andric   assert(MBB && "BasicBlock was not encountered before");
2900b57cec5SDimitry Andric   return *MBB;
2910b57cec5SDimitry Andric }
2920b57cec5SDimitry Andric 
addMachineCFGPred(CFGEdge Edge,MachineBasicBlock * NewPred)2930b57cec5SDimitry Andric void IRTranslator::addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred) {
2940b57cec5SDimitry Andric   assert(NewPred && "new predecessor must be a real MachineBasicBlock");
2950b57cec5SDimitry Andric   MachinePreds[Edge].push_back(NewPred);
2960b57cec5SDimitry Andric }
2970b57cec5SDimitry Andric 
translateBinaryOp(unsigned Opcode,const User & U,MachineIRBuilder & MIRBuilder)2980b57cec5SDimitry Andric bool IRTranslator::translateBinaryOp(unsigned Opcode, const User &U,
2990b57cec5SDimitry Andric                                      MachineIRBuilder &MIRBuilder) {
3000b57cec5SDimitry Andric   // Get or create a virtual register for each value.
3010b57cec5SDimitry Andric   // Unless the value is a Constant => loadimm cst?
3020b57cec5SDimitry Andric   // or inline constant each time?
3030b57cec5SDimitry Andric   // Creation of a virtual register needs to have a size.
3040b57cec5SDimitry Andric   Register Op0 = getOrCreateVReg(*U.getOperand(0));
3050b57cec5SDimitry Andric   Register Op1 = getOrCreateVReg(*U.getOperand(1));
3060b57cec5SDimitry Andric   Register Res = getOrCreateVReg(U);
30706c3fb27SDimitry Andric   uint32_t Flags = 0;
3080b57cec5SDimitry Andric   if (isa<Instruction>(U)) {
3090b57cec5SDimitry Andric     const Instruction &I = cast<Instruction>(U);
3100b57cec5SDimitry Andric     Flags = MachineInstr::copyFlagsFromInstruction(I);
3110b57cec5SDimitry Andric   }
3120b57cec5SDimitry Andric 
3130b57cec5SDimitry Andric   MIRBuilder.buildInstr(Opcode, {Res}, {Op0, Op1}, Flags);
3140b57cec5SDimitry Andric   return true;
3150b57cec5SDimitry Andric }
3160b57cec5SDimitry Andric 
translateUnaryOp(unsigned Opcode,const User & U,MachineIRBuilder & MIRBuilder)317e8d8bef9SDimitry Andric bool IRTranslator::translateUnaryOp(unsigned Opcode, const User &U,
318e8d8bef9SDimitry Andric                                     MachineIRBuilder &MIRBuilder) {
3190b57cec5SDimitry Andric   Register Op0 = getOrCreateVReg(*U.getOperand(0));
3200b57cec5SDimitry Andric   Register Res = getOrCreateVReg(U);
32106c3fb27SDimitry Andric   uint32_t Flags = 0;
3220b57cec5SDimitry Andric   if (isa<Instruction>(U)) {
3230b57cec5SDimitry Andric     const Instruction &I = cast<Instruction>(U);
3240b57cec5SDimitry Andric     Flags = MachineInstr::copyFlagsFromInstruction(I);
3250b57cec5SDimitry Andric   }
326e8d8bef9SDimitry Andric   MIRBuilder.buildInstr(Opcode, {Res}, {Op0}, Flags);
3270b57cec5SDimitry Andric   return true;
3280b57cec5SDimitry Andric }
3290b57cec5SDimitry Andric 
translateFNeg(const User & U,MachineIRBuilder & MIRBuilder)330e8d8bef9SDimitry Andric bool IRTranslator::translateFNeg(const User &U, MachineIRBuilder &MIRBuilder) {
331e8d8bef9SDimitry Andric   return translateUnaryOp(TargetOpcode::G_FNEG, U, MIRBuilder);
332e8d8bef9SDimitry Andric }
333e8d8bef9SDimitry Andric 
translateCompare(const User & U,MachineIRBuilder & MIRBuilder)3340b57cec5SDimitry Andric bool IRTranslator::translateCompare(const User &U,
3350b57cec5SDimitry Andric                                     MachineIRBuilder &MIRBuilder) {
3368bcb0991SDimitry Andric   auto *CI = dyn_cast<CmpInst>(&U);
3370b57cec5SDimitry Andric   Register Op0 = getOrCreateVReg(*U.getOperand(0));
3380b57cec5SDimitry Andric   Register Op1 = getOrCreateVReg(*U.getOperand(1));
3390b57cec5SDimitry Andric   Register Res = getOrCreateVReg(U);
3400b57cec5SDimitry Andric   CmpInst::Predicate Pred =
3410b57cec5SDimitry Andric       CI ? CI->getPredicate() : static_cast<CmpInst::Predicate>(
3420b57cec5SDimitry Andric                                     cast<ConstantExpr>(U).getPredicate());
3430b57cec5SDimitry Andric   if (CmpInst::isIntPredicate(Pred))
3440b57cec5SDimitry Andric     MIRBuilder.buildICmp(Pred, Res, Op0, Op1);
3450b57cec5SDimitry Andric   else if (Pred == CmpInst::FCMP_FALSE)
3460b57cec5SDimitry Andric     MIRBuilder.buildCopy(
3478bcb0991SDimitry Andric         Res, getOrCreateVReg(*Constant::getNullValue(U.getType())));
3480b57cec5SDimitry Andric   else if (Pred == CmpInst::FCMP_TRUE)
3490b57cec5SDimitry Andric     MIRBuilder.buildCopy(
3508bcb0991SDimitry Andric         Res, getOrCreateVReg(*Constant::getAllOnesValue(U.getType())));
3510b57cec5SDimitry Andric   else {
35206c3fb27SDimitry Andric     uint32_t Flags = 0;
3530eae32dcSDimitry Andric     if (CI)
3540eae32dcSDimitry Andric       Flags = MachineInstr::copyFlagsFromInstruction(*CI);
3550eae32dcSDimitry Andric     MIRBuilder.buildFCmp(Pred, Res, Op0, Op1, Flags);
3560b57cec5SDimitry Andric   }
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric   return true;
3590b57cec5SDimitry Andric }
3600b57cec5SDimitry Andric 
translateRet(const User & U,MachineIRBuilder & MIRBuilder)3610b57cec5SDimitry Andric bool IRTranslator::translateRet(const User &U, MachineIRBuilder &MIRBuilder) {
3620b57cec5SDimitry Andric   const ReturnInst &RI = cast<ReturnInst>(U);
3630b57cec5SDimitry Andric   const Value *Ret = RI.getReturnValue();
3645f757f3fSDimitry Andric   if (Ret && DL->getTypeStoreSize(Ret->getType()).isZero())
3650b57cec5SDimitry Andric     Ret = nullptr;
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric   ArrayRef<Register> VRegs;
3680b57cec5SDimitry Andric   if (Ret)
3690b57cec5SDimitry Andric     VRegs = getOrCreateVRegs(*Ret);
3700b57cec5SDimitry Andric 
3710b57cec5SDimitry Andric   Register SwiftErrorVReg = 0;
3720b57cec5SDimitry Andric   if (CLI->supportSwiftError() && SwiftError.getFunctionArg()) {
3730b57cec5SDimitry Andric     SwiftErrorVReg = SwiftError.getOrCreateVRegUseAt(
3740b57cec5SDimitry Andric         &RI, &MIRBuilder.getMBB(), SwiftError.getFunctionArg());
3750b57cec5SDimitry Andric   }
3760b57cec5SDimitry Andric 
3770b57cec5SDimitry Andric   // The target may mess up with the insertion point, but
3780b57cec5SDimitry Andric   // this is not important as a return is the last instruction
3790b57cec5SDimitry Andric   // of the block anyway.
380e8d8bef9SDimitry Andric   return CLI->lowerReturn(MIRBuilder, Ret, VRegs, FuncInfo, SwiftErrorVReg);
381e8d8bef9SDimitry Andric }
382e8d8bef9SDimitry Andric 
emitBranchForMergedCondition(const Value * Cond,MachineBasicBlock * TBB,MachineBasicBlock * FBB,MachineBasicBlock * CurBB,MachineBasicBlock * SwitchBB,BranchProbability TProb,BranchProbability FProb,bool InvertCond)383e8d8bef9SDimitry Andric void IRTranslator::emitBranchForMergedCondition(
384e8d8bef9SDimitry Andric     const Value *Cond, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
385e8d8bef9SDimitry Andric     MachineBasicBlock *CurBB, MachineBasicBlock *SwitchBB,
386e8d8bef9SDimitry Andric     BranchProbability TProb, BranchProbability FProb, bool InvertCond) {
387e8d8bef9SDimitry Andric   // If the leaf of the tree is a comparison, merge the condition into
388e8d8bef9SDimitry Andric   // the caseblock.
389e8d8bef9SDimitry Andric   if (const CmpInst *BOp = dyn_cast<CmpInst>(Cond)) {
390e8d8bef9SDimitry Andric     CmpInst::Predicate Condition;
391e8d8bef9SDimitry Andric     if (const ICmpInst *IC = dyn_cast<ICmpInst>(Cond)) {
392e8d8bef9SDimitry Andric       Condition = InvertCond ? IC->getInversePredicate() : IC->getPredicate();
393e8d8bef9SDimitry Andric     } else {
394e8d8bef9SDimitry Andric       const FCmpInst *FC = cast<FCmpInst>(Cond);
395e8d8bef9SDimitry Andric       Condition = InvertCond ? FC->getInversePredicate() : FC->getPredicate();
396e8d8bef9SDimitry Andric     }
397e8d8bef9SDimitry Andric 
398e8d8bef9SDimitry Andric     SwitchCG::CaseBlock CB(Condition, false, BOp->getOperand(0),
399e8d8bef9SDimitry Andric                            BOp->getOperand(1), nullptr, TBB, FBB, CurBB,
400e8d8bef9SDimitry Andric                            CurBuilder->getDebugLoc(), TProb, FProb);
401e8d8bef9SDimitry Andric     SL->SwitchCases.push_back(CB);
402e8d8bef9SDimitry Andric     return;
403e8d8bef9SDimitry Andric   }
404e8d8bef9SDimitry Andric 
405e8d8bef9SDimitry Andric   // Create a CaseBlock record representing this branch.
406e8d8bef9SDimitry Andric   CmpInst::Predicate Pred = InvertCond ? CmpInst::ICMP_NE : CmpInst::ICMP_EQ;
407e8d8bef9SDimitry Andric   SwitchCG::CaseBlock CB(
408e8d8bef9SDimitry Andric       Pred, false, Cond, ConstantInt::getTrue(MF->getFunction().getContext()),
409e8d8bef9SDimitry Andric       nullptr, TBB, FBB, CurBB, CurBuilder->getDebugLoc(), TProb, FProb);
410e8d8bef9SDimitry Andric   SL->SwitchCases.push_back(CB);
411e8d8bef9SDimitry Andric }
412e8d8bef9SDimitry Andric 
isValInBlock(const Value * V,const BasicBlock * BB)413e8d8bef9SDimitry Andric static bool isValInBlock(const Value *V, const BasicBlock *BB) {
414e8d8bef9SDimitry Andric   if (const Instruction *I = dyn_cast<Instruction>(V))
415e8d8bef9SDimitry Andric     return I->getParent() == BB;
416e8d8bef9SDimitry Andric   return true;
417e8d8bef9SDimitry Andric }
418e8d8bef9SDimitry Andric 
findMergedConditions(const Value * Cond,MachineBasicBlock * TBB,MachineBasicBlock * FBB,MachineBasicBlock * CurBB,MachineBasicBlock * SwitchBB,Instruction::BinaryOps Opc,BranchProbability TProb,BranchProbability FProb,bool InvertCond)419e8d8bef9SDimitry Andric void IRTranslator::findMergedConditions(
420e8d8bef9SDimitry Andric     const Value *Cond, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
421e8d8bef9SDimitry Andric     MachineBasicBlock *CurBB, MachineBasicBlock *SwitchBB,
422e8d8bef9SDimitry Andric     Instruction::BinaryOps Opc, BranchProbability TProb,
423e8d8bef9SDimitry Andric     BranchProbability FProb, bool InvertCond) {
424e8d8bef9SDimitry Andric   using namespace PatternMatch;
425e8d8bef9SDimitry Andric   assert((Opc == Instruction::And || Opc == Instruction::Or) &&
426e8d8bef9SDimitry Andric          "Expected Opc to be AND/OR");
427e8d8bef9SDimitry Andric   // Skip over not part of the tree and remember to invert op and operands at
428e8d8bef9SDimitry Andric   // next level.
429e8d8bef9SDimitry Andric   Value *NotCond;
430e8d8bef9SDimitry Andric   if (match(Cond, m_OneUse(m_Not(m_Value(NotCond)))) &&
431e8d8bef9SDimitry Andric       isValInBlock(NotCond, CurBB->getBasicBlock())) {
432e8d8bef9SDimitry Andric     findMergedConditions(NotCond, TBB, FBB, CurBB, SwitchBB, Opc, TProb, FProb,
433e8d8bef9SDimitry Andric                          !InvertCond);
434e8d8bef9SDimitry Andric     return;
435e8d8bef9SDimitry Andric   }
436e8d8bef9SDimitry Andric 
437e8d8bef9SDimitry Andric   const Instruction *BOp = dyn_cast<Instruction>(Cond);
438e8d8bef9SDimitry Andric   const Value *BOpOp0, *BOpOp1;
439e8d8bef9SDimitry Andric   // Compute the effective opcode for Cond, taking into account whether it needs
440e8d8bef9SDimitry Andric   // to be inverted, e.g.
441e8d8bef9SDimitry Andric   //   and (not (or A, B)), C
442e8d8bef9SDimitry Andric   // gets lowered as
443e8d8bef9SDimitry Andric   //   and (and (not A, not B), C)
444e8d8bef9SDimitry Andric   Instruction::BinaryOps BOpc = (Instruction::BinaryOps)0;
445e8d8bef9SDimitry Andric   if (BOp) {
446e8d8bef9SDimitry Andric     BOpc = match(BOp, m_LogicalAnd(m_Value(BOpOp0), m_Value(BOpOp1)))
447e8d8bef9SDimitry Andric                ? Instruction::And
448e8d8bef9SDimitry Andric                : (match(BOp, m_LogicalOr(m_Value(BOpOp0), m_Value(BOpOp1)))
449e8d8bef9SDimitry Andric                       ? Instruction::Or
450e8d8bef9SDimitry Andric                       : (Instruction::BinaryOps)0);
451e8d8bef9SDimitry Andric     if (InvertCond) {
452e8d8bef9SDimitry Andric       if (BOpc == Instruction::And)
453e8d8bef9SDimitry Andric         BOpc = Instruction::Or;
454e8d8bef9SDimitry Andric       else if (BOpc == Instruction::Or)
455e8d8bef9SDimitry Andric         BOpc = Instruction::And;
456e8d8bef9SDimitry Andric     }
457e8d8bef9SDimitry Andric   }
458e8d8bef9SDimitry Andric 
459e8d8bef9SDimitry Andric   // If this node is not part of the or/and tree, emit it as a branch.
460e8d8bef9SDimitry Andric   // Note that all nodes in the tree should have same opcode.
461e8d8bef9SDimitry Andric   bool BOpIsInOrAndTree = BOpc && BOpc == Opc && BOp->hasOneUse();
462e8d8bef9SDimitry Andric   if (!BOpIsInOrAndTree || BOp->getParent() != CurBB->getBasicBlock() ||
463e8d8bef9SDimitry Andric       !isValInBlock(BOpOp0, CurBB->getBasicBlock()) ||
464e8d8bef9SDimitry Andric       !isValInBlock(BOpOp1, CurBB->getBasicBlock())) {
465e8d8bef9SDimitry Andric     emitBranchForMergedCondition(Cond, TBB, FBB, CurBB, SwitchBB, TProb, FProb,
466e8d8bef9SDimitry Andric                                  InvertCond);
467e8d8bef9SDimitry Andric     return;
468e8d8bef9SDimitry Andric   }
469e8d8bef9SDimitry Andric 
470e8d8bef9SDimitry Andric   //  Create TmpBB after CurBB.
471e8d8bef9SDimitry Andric   MachineFunction::iterator BBI(CurBB);
472e8d8bef9SDimitry Andric   MachineBasicBlock *TmpBB =
473e8d8bef9SDimitry Andric       MF->CreateMachineBasicBlock(CurBB->getBasicBlock());
474e8d8bef9SDimitry Andric   CurBB->getParent()->insert(++BBI, TmpBB);
475e8d8bef9SDimitry Andric 
476e8d8bef9SDimitry Andric   if (Opc == Instruction::Or) {
477e8d8bef9SDimitry Andric     // Codegen X | Y as:
478e8d8bef9SDimitry Andric     // BB1:
479e8d8bef9SDimitry Andric     //   jmp_if_X TBB
480e8d8bef9SDimitry Andric     //   jmp TmpBB
481e8d8bef9SDimitry Andric     // TmpBB:
482e8d8bef9SDimitry Andric     //   jmp_if_Y TBB
483e8d8bef9SDimitry Andric     //   jmp FBB
484e8d8bef9SDimitry Andric     //
485e8d8bef9SDimitry Andric 
486e8d8bef9SDimitry Andric     // We have flexibility in setting Prob for BB1 and Prob for TmpBB.
487e8d8bef9SDimitry Andric     // The requirement is that
488e8d8bef9SDimitry Andric     //   TrueProb for BB1 + (FalseProb for BB1 * TrueProb for TmpBB)
489e8d8bef9SDimitry Andric     //     = TrueProb for original BB.
490e8d8bef9SDimitry Andric     // Assuming the original probabilities are A and B, one choice is to set
491e8d8bef9SDimitry Andric     // BB1's probabilities to A/2 and A/2+B, and set TmpBB's probabilities to
492e8d8bef9SDimitry Andric     // A/(1+B) and 2B/(1+B). This choice assumes that
493e8d8bef9SDimitry Andric     //   TrueProb for BB1 == FalseProb for BB1 * TrueProb for TmpBB.
494e8d8bef9SDimitry Andric     // Another choice is to assume TrueProb for BB1 equals to TrueProb for
495e8d8bef9SDimitry Andric     // TmpBB, but the math is more complicated.
496e8d8bef9SDimitry Andric 
497e8d8bef9SDimitry Andric     auto NewTrueProb = TProb / 2;
498e8d8bef9SDimitry Andric     auto NewFalseProb = TProb / 2 + FProb;
499e8d8bef9SDimitry Andric     // Emit the LHS condition.
500e8d8bef9SDimitry Andric     findMergedConditions(BOpOp0, TBB, TmpBB, CurBB, SwitchBB, Opc, NewTrueProb,
501e8d8bef9SDimitry Andric                          NewFalseProb, InvertCond);
502e8d8bef9SDimitry Andric 
503e8d8bef9SDimitry Andric     // Normalize A/2 and B to get A/(1+B) and 2B/(1+B).
504e8d8bef9SDimitry Andric     SmallVector<BranchProbability, 2> Probs{TProb / 2, FProb};
505e8d8bef9SDimitry Andric     BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
506e8d8bef9SDimitry Andric     // Emit the RHS condition into TmpBB.
507e8d8bef9SDimitry Andric     findMergedConditions(BOpOp1, TBB, FBB, TmpBB, SwitchBB, Opc, Probs[0],
508e8d8bef9SDimitry Andric                          Probs[1], InvertCond);
509e8d8bef9SDimitry Andric   } else {
510e8d8bef9SDimitry Andric     assert(Opc == Instruction::And && "Unknown merge op!");
511e8d8bef9SDimitry Andric     // Codegen X & Y as:
512e8d8bef9SDimitry Andric     // BB1:
513e8d8bef9SDimitry Andric     //   jmp_if_X TmpBB
514e8d8bef9SDimitry Andric     //   jmp FBB
515e8d8bef9SDimitry Andric     // TmpBB:
516e8d8bef9SDimitry Andric     //   jmp_if_Y TBB
517e8d8bef9SDimitry Andric     //   jmp FBB
518e8d8bef9SDimitry Andric     //
519e8d8bef9SDimitry Andric     //  This requires creation of TmpBB after CurBB.
520e8d8bef9SDimitry Andric 
521e8d8bef9SDimitry Andric     // We have flexibility in setting Prob for BB1 and Prob for TmpBB.
522e8d8bef9SDimitry Andric     // The requirement is that
523e8d8bef9SDimitry Andric     //   FalseProb for BB1 + (TrueProb for BB1 * FalseProb for TmpBB)
524e8d8bef9SDimitry Andric     //     = FalseProb for original BB.
525e8d8bef9SDimitry Andric     // Assuming the original probabilities are A and B, one choice is to set
526e8d8bef9SDimitry Andric     // BB1's probabilities to A+B/2 and B/2, and set TmpBB's probabilities to
527e8d8bef9SDimitry Andric     // 2A/(1+A) and B/(1+A). This choice assumes that FalseProb for BB1 ==
528e8d8bef9SDimitry Andric     // TrueProb for BB1 * FalseProb for TmpBB.
529e8d8bef9SDimitry Andric 
530e8d8bef9SDimitry Andric     auto NewTrueProb = TProb + FProb / 2;
531e8d8bef9SDimitry Andric     auto NewFalseProb = FProb / 2;
532e8d8bef9SDimitry Andric     // Emit the LHS condition.
533e8d8bef9SDimitry Andric     findMergedConditions(BOpOp0, TmpBB, FBB, CurBB, SwitchBB, Opc, NewTrueProb,
534e8d8bef9SDimitry Andric                          NewFalseProb, InvertCond);
535e8d8bef9SDimitry Andric 
536e8d8bef9SDimitry Andric     // Normalize A and B/2 to get 2A/(1+A) and B/(1+A).
537e8d8bef9SDimitry Andric     SmallVector<BranchProbability, 2> Probs{TProb, FProb / 2};
538e8d8bef9SDimitry Andric     BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
539e8d8bef9SDimitry Andric     // Emit the RHS condition into TmpBB.
540e8d8bef9SDimitry Andric     findMergedConditions(BOpOp1, TBB, FBB, TmpBB, SwitchBB, Opc, Probs[0],
541e8d8bef9SDimitry Andric                          Probs[1], InvertCond);
542e8d8bef9SDimitry Andric   }
543e8d8bef9SDimitry Andric }
544e8d8bef9SDimitry Andric 
shouldEmitAsBranches(const std::vector<SwitchCG::CaseBlock> & Cases)545e8d8bef9SDimitry Andric bool IRTranslator::shouldEmitAsBranches(
546e8d8bef9SDimitry Andric     const std::vector<SwitchCG::CaseBlock> &Cases) {
547e8d8bef9SDimitry Andric   // For multiple cases, it's better to emit as branches.
548e8d8bef9SDimitry Andric   if (Cases.size() != 2)
549e8d8bef9SDimitry Andric     return true;
550e8d8bef9SDimitry Andric 
551e8d8bef9SDimitry Andric   // If this is two comparisons of the same values or'd or and'd together, they
552e8d8bef9SDimitry Andric   // will get folded into a single comparison, so don't emit two blocks.
553e8d8bef9SDimitry Andric   if ((Cases[0].CmpLHS == Cases[1].CmpLHS &&
554e8d8bef9SDimitry Andric        Cases[0].CmpRHS == Cases[1].CmpRHS) ||
555e8d8bef9SDimitry Andric       (Cases[0].CmpRHS == Cases[1].CmpLHS &&
556e8d8bef9SDimitry Andric        Cases[0].CmpLHS == Cases[1].CmpRHS)) {
557e8d8bef9SDimitry Andric     return false;
558e8d8bef9SDimitry Andric   }
559e8d8bef9SDimitry Andric 
560e8d8bef9SDimitry Andric   // Handle: (X != null) | (Y != null) --> (X|Y) != 0
561e8d8bef9SDimitry Andric   // Handle: (X == null) & (Y == null) --> (X|Y) == 0
562e8d8bef9SDimitry Andric   if (Cases[0].CmpRHS == Cases[1].CmpRHS &&
563e8d8bef9SDimitry Andric       Cases[0].PredInfo.Pred == Cases[1].PredInfo.Pred &&
564e8d8bef9SDimitry Andric       isa<Constant>(Cases[0].CmpRHS) &&
565e8d8bef9SDimitry Andric       cast<Constant>(Cases[0].CmpRHS)->isNullValue()) {
566e8d8bef9SDimitry Andric     if (Cases[0].PredInfo.Pred == CmpInst::ICMP_EQ &&
567e8d8bef9SDimitry Andric         Cases[0].TrueBB == Cases[1].ThisBB)
568e8d8bef9SDimitry Andric       return false;
569e8d8bef9SDimitry Andric     if (Cases[0].PredInfo.Pred == CmpInst::ICMP_NE &&
570e8d8bef9SDimitry Andric         Cases[0].FalseBB == Cases[1].ThisBB)
571e8d8bef9SDimitry Andric       return false;
572e8d8bef9SDimitry Andric   }
573e8d8bef9SDimitry Andric 
574e8d8bef9SDimitry Andric   return true;
5750b57cec5SDimitry Andric }
5760b57cec5SDimitry Andric 
translateBr(const User & U,MachineIRBuilder & MIRBuilder)5770b57cec5SDimitry Andric bool IRTranslator::translateBr(const User &U, MachineIRBuilder &MIRBuilder) {
5780b57cec5SDimitry Andric   const BranchInst &BrInst = cast<BranchInst>(U);
579e8d8bef9SDimitry Andric   auto &CurMBB = MIRBuilder.getMBB();
580e8d8bef9SDimitry Andric   auto *Succ0MBB = &getMBB(*BrInst.getSuccessor(0));
5810b57cec5SDimitry Andric 
582e8d8bef9SDimitry Andric   if (BrInst.isUnconditional()) {
5830b57cec5SDimitry Andric     // If the unconditional target is the layout successor, fallthrough.
5845f757f3fSDimitry Andric     if (OptLevel == CodeGenOptLevel::None ||
5855f757f3fSDimitry Andric         !CurMBB.isLayoutSuccessor(Succ0MBB))
586e8d8bef9SDimitry Andric       MIRBuilder.buildBr(*Succ0MBB);
5870b57cec5SDimitry Andric 
5880b57cec5SDimitry Andric     // Link successors.
5890b57cec5SDimitry Andric     for (const BasicBlock *Succ : successors(&BrInst))
590e8d8bef9SDimitry Andric       CurMBB.addSuccessor(&getMBB(*Succ));
591e8d8bef9SDimitry Andric     return true;
592e8d8bef9SDimitry Andric   }
593e8d8bef9SDimitry Andric 
594e8d8bef9SDimitry Andric   // If this condition is one of the special cases we handle, do special stuff
595e8d8bef9SDimitry Andric   // now.
596e8d8bef9SDimitry Andric   const Value *CondVal = BrInst.getCondition();
597e8d8bef9SDimitry Andric   MachineBasicBlock *Succ1MBB = &getMBB(*BrInst.getSuccessor(1));
598e8d8bef9SDimitry Andric 
599e8d8bef9SDimitry Andric   const auto &TLI = *MF->getSubtarget().getTargetLowering();
600e8d8bef9SDimitry Andric 
601e8d8bef9SDimitry Andric   // If this is a series of conditions that are or'd or and'd together, emit
602e8d8bef9SDimitry Andric   // this as a sequence of branches instead of setcc's with and/or operations.
603e8d8bef9SDimitry Andric   // As long as jumps are not expensive (exceptions for multi-use logic ops,
604e8d8bef9SDimitry Andric   // unpredictable branches, and vector extracts because those jumps are likely
605e8d8bef9SDimitry Andric   // expensive for any target), this should improve performance.
606e8d8bef9SDimitry Andric   // For example, instead of something like:
607e8d8bef9SDimitry Andric   //     cmp A, B
608e8d8bef9SDimitry Andric   //     C = seteq
609e8d8bef9SDimitry Andric   //     cmp D, E
610e8d8bef9SDimitry Andric   //     F = setle
611e8d8bef9SDimitry Andric   //     or C, F
612e8d8bef9SDimitry Andric   //     jnz foo
613e8d8bef9SDimitry Andric   // Emit:
614e8d8bef9SDimitry Andric   //     cmp A, B
615e8d8bef9SDimitry Andric   //     je foo
616e8d8bef9SDimitry Andric   //     cmp D, E
617e8d8bef9SDimitry Andric   //     jle foo
618e8d8bef9SDimitry Andric   using namespace PatternMatch;
619e8d8bef9SDimitry Andric   const Instruction *CondI = dyn_cast<Instruction>(CondVal);
620e8d8bef9SDimitry Andric   if (!TLI.isJumpExpensive() && CondI && CondI->hasOneUse() &&
621e8d8bef9SDimitry Andric       !BrInst.hasMetadata(LLVMContext::MD_unpredictable)) {
622e8d8bef9SDimitry Andric     Instruction::BinaryOps Opcode = (Instruction::BinaryOps)0;
623e8d8bef9SDimitry Andric     Value *Vec;
624e8d8bef9SDimitry Andric     const Value *BOp0, *BOp1;
625e8d8bef9SDimitry Andric     if (match(CondI, m_LogicalAnd(m_Value(BOp0), m_Value(BOp1))))
626e8d8bef9SDimitry Andric       Opcode = Instruction::And;
627e8d8bef9SDimitry Andric     else if (match(CondI, m_LogicalOr(m_Value(BOp0), m_Value(BOp1))))
628e8d8bef9SDimitry Andric       Opcode = Instruction::Or;
629e8d8bef9SDimitry Andric 
630e8d8bef9SDimitry Andric     if (Opcode && !(match(BOp0, m_ExtractElt(m_Value(Vec), m_Value())) &&
631e8d8bef9SDimitry Andric                     match(BOp1, m_ExtractElt(m_Specific(Vec), m_Value())))) {
632e8d8bef9SDimitry Andric       findMergedConditions(CondI, Succ0MBB, Succ1MBB, &CurMBB, &CurMBB, Opcode,
633e8d8bef9SDimitry Andric                            getEdgeProbability(&CurMBB, Succ0MBB),
634e8d8bef9SDimitry Andric                            getEdgeProbability(&CurMBB, Succ1MBB),
635e8d8bef9SDimitry Andric                            /*InvertCond=*/false);
636e8d8bef9SDimitry Andric       assert(SL->SwitchCases[0].ThisBB == &CurMBB && "Unexpected lowering!");
637e8d8bef9SDimitry Andric 
638e8d8bef9SDimitry Andric       // Allow some cases to be rejected.
639e8d8bef9SDimitry Andric       if (shouldEmitAsBranches(SL->SwitchCases)) {
640e8d8bef9SDimitry Andric         // Emit the branch for this block.
641e8d8bef9SDimitry Andric         emitSwitchCase(SL->SwitchCases[0], &CurMBB, *CurBuilder);
642e8d8bef9SDimitry Andric         SL->SwitchCases.erase(SL->SwitchCases.begin());
643e8d8bef9SDimitry Andric         return true;
644e8d8bef9SDimitry Andric       }
645e8d8bef9SDimitry Andric 
646e8d8bef9SDimitry Andric       // Okay, we decided not to do this, remove any inserted MBB's and clear
647e8d8bef9SDimitry Andric       // SwitchCases.
648e8d8bef9SDimitry Andric       for (unsigned I = 1, E = SL->SwitchCases.size(); I != E; ++I)
649e8d8bef9SDimitry Andric         MF->erase(SL->SwitchCases[I].ThisBB);
650e8d8bef9SDimitry Andric 
651e8d8bef9SDimitry Andric       SL->SwitchCases.clear();
652e8d8bef9SDimitry Andric     }
653e8d8bef9SDimitry Andric   }
654e8d8bef9SDimitry Andric 
655e8d8bef9SDimitry Andric   // Create a CaseBlock record representing this branch.
656e8d8bef9SDimitry Andric   SwitchCG::CaseBlock CB(CmpInst::ICMP_EQ, false, CondVal,
657e8d8bef9SDimitry Andric                          ConstantInt::getTrue(MF->getFunction().getContext()),
658e8d8bef9SDimitry Andric                          nullptr, Succ0MBB, Succ1MBB, &CurMBB,
659e8d8bef9SDimitry Andric                          CurBuilder->getDebugLoc());
660e8d8bef9SDimitry Andric 
661e8d8bef9SDimitry Andric   // Use emitSwitchCase to actually insert the fast branch sequence for this
662e8d8bef9SDimitry Andric   // cond branch.
663e8d8bef9SDimitry Andric   emitSwitchCase(CB, &CurMBB, *CurBuilder);
6640b57cec5SDimitry Andric   return true;
6650b57cec5SDimitry Andric }
6660b57cec5SDimitry Andric 
addSuccessorWithProb(MachineBasicBlock * Src,MachineBasicBlock * Dst,BranchProbability Prob)6670b57cec5SDimitry Andric void IRTranslator::addSuccessorWithProb(MachineBasicBlock *Src,
6680b57cec5SDimitry Andric                                         MachineBasicBlock *Dst,
6690b57cec5SDimitry Andric                                         BranchProbability Prob) {
6700b57cec5SDimitry Andric   if (!FuncInfo.BPI) {
6710b57cec5SDimitry Andric     Src->addSuccessorWithoutProb(Dst);
6720b57cec5SDimitry Andric     return;
6730b57cec5SDimitry Andric   }
6740b57cec5SDimitry Andric   if (Prob.isUnknown())
6750b57cec5SDimitry Andric     Prob = getEdgeProbability(Src, Dst);
6760b57cec5SDimitry Andric   Src->addSuccessor(Dst, Prob);
6770b57cec5SDimitry Andric }
6780b57cec5SDimitry Andric 
6790b57cec5SDimitry Andric BranchProbability
getEdgeProbability(const MachineBasicBlock * Src,const MachineBasicBlock * Dst) const6800b57cec5SDimitry Andric IRTranslator::getEdgeProbability(const MachineBasicBlock *Src,
6810b57cec5SDimitry Andric                                  const MachineBasicBlock *Dst) const {
6820b57cec5SDimitry Andric   const BasicBlock *SrcBB = Src->getBasicBlock();
6830b57cec5SDimitry Andric   const BasicBlock *DstBB = Dst->getBasicBlock();
6840b57cec5SDimitry Andric   if (!FuncInfo.BPI) {
6850b57cec5SDimitry Andric     // If BPI is not available, set the default probability as 1 / N, where N is
6860b57cec5SDimitry Andric     // the number of successors.
6870b57cec5SDimitry Andric     auto SuccSize = std::max<uint32_t>(succ_size(SrcBB), 1);
6880b57cec5SDimitry Andric     return BranchProbability(1, SuccSize);
6890b57cec5SDimitry Andric   }
6900b57cec5SDimitry Andric   return FuncInfo.BPI->getEdgeProbability(SrcBB, DstBB);
6910b57cec5SDimitry Andric }
6920b57cec5SDimitry Andric 
translateSwitch(const User & U,MachineIRBuilder & MIB)6930b57cec5SDimitry Andric bool IRTranslator::translateSwitch(const User &U, MachineIRBuilder &MIB) {
6940b57cec5SDimitry Andric   using namespace SwitchCG;
6950b57cec5SDimitry Andric   // Extract cases from the switch.
6960b57cec5SDimitry Andric   const SwitchInst &SI = cast<SwitchInst>(U);
6970b57cec5SDimitry Andric   BranchProbabilityInfo *BPI = FuncInfo.BPI;
6980b57cec5SDimitry Andric   CaseClusterVector Clusters;
6990b57cec5SDimitry Andric   Clusters.reserve(SI.getNumCases());
700fcaf7f86SDimitry Andric   for (const auto &I : SI.cases()) {
7010b57cec5SDimitry Andric     MachineBasicBlock *Succ = &getMBB(*I.getCaseSuccessor());
7020b57cec5SDimitry Andric     assert(Succ && "Could not find successor mbb in mapping");
7030b57cec5SDimitry Andric     const ConstantInt *CaseVal = I.getCaseValue();
7040b57cec5SDimitry Andric     BranchProbability Prob =
7050b57cec5SDimitry Andric         BPI ? BPI->getEdgeProbability(SI.getParent(), I.getSuccessorIndex())
7060b57cec5SDimitry Andric             : BranchProbability(1, SI.getNumCases() + 1);
7070b57cec5SDimitry Andric     Clusters.push_back(CaseCluster::range(CaseVal, CaseVal, Succ, Prob));
7080b57cec5SDimitry Andric   }
7090b57cec5SDimitry Andric 
7100b57cec5SDimitry Andric   MachineBasicBlock *DefaultMBB = &getMBB(*SI.getDefaultDest());
7110b57cec5SDimitry Andric 
7120b57cec5SDimitry Andric   // Cluster adjacent cases with the same destination. We do this at all
7130b57cec5SDimitry Andric   // optimization levels because it's cheap to do and will make codegen faster
7140b57cec5SDimitry Andric   // if there are many clusters.
7150b57cec5SDimitry Andric   sortAndRangeify(Clusters);
7160b57cec5SDimitry Andric 
7170b57cec5SDimitry Andric   MachineBasicBlock *SwitchMBB = &getMBB(*SI.getParent());
7180b57cec5SDimitry Andric 
7190b57cec5SDimitry Andric   // If there is only the default destination, jump there directly.
7200b57cec5SDimitry Andric   if (Clusters.empty()) {
7210b57cec5SDimitry Andric     SwitchMBB->addSuccessor(DefaultMBB);
7220b57cec5SDimitry Andric     if (DefaultMBB != SwitchMBB->getNextNode())
7230b57cec5SDimitry Andric       MIB.buildBr(*DefaultMBB);
7240b57cec5SDimitry Andric     return true;
7250b57cec5SDimitry Andric   }
7260b57cec5SDimitry Andric 
7275f757f3fSDimitry Andric   SL->findJumpTables(Clusters, &SI, std::nullopt, DefaultMBB, nullptr, nullptr);
728e8d8bef9SDimitry Andric   SL->findBitTestClusters(Clusters, &SI);
7290b57cec5SDimitry Andric 
7300b57cec5SDimitry Andric   LLVM_DEBUG({
7310b57cec5SDimitry Andric     dbgs() << "Case clusters: ";
7320b57cec5SDimitry Andric     for (const CaseCluster &C : Clusters) {
7330b57cec5SDimitry Andric       if (C.Kind == CC_JumpTable)
7340b57cec5SDimitry Andric         dbgs() << "JT:";
7350b57cec5SDimitry Andric       if (C.Kind == CC_BitTests)
7360b57cec5SDimitry Andric         dbgs() << "BT:";
7370b57cec5SDimitry Andric 
7380b57cec5SDimitry Andric       C.Low->getValue().print(dbgs(), true);
7390b57cec5SDimitry Andric       if (C.Low != C.High) {
7400b57cec5SDimitry Andric         dbgs() << '-';
7410b57cec5SDimitry Andric         C.High->getValue().print(dbgs(), true);
7420b57cec5SDimitry Andric       }
7430b57cec5SDimitry Andric       dbgs() << ' ';
7440b57cec5SDimitry Andric     }
7450b57cec5SDimitry Andric     dbgs() << '\n';
7460b57cec5SDimitry Andric   });
7470b57cec5SDimitry Andric 
7480b57cec5SDimitry Andric   assert(!Clusters.empty());
7490b57cec5SDimitry Andric   SwitchWorkList WorkList;
7500b57cec5SDimitry Andric   CaseClusterIt First = Clusters.begin();
7510b57cec5SDimitry Andric   CaseClusterIt Last = Clusters.end() - 1;
7520b57cec5SDimitry Andric   auto DefaultProb = getEdgeProbability(SwitchMBB, DefaultMBB);
7530b57cec5SDimitry Andric   WorkList.push_back({SwitchMBB, First, Last, nullptr, nullptr, DefaultProb});
7540b57cec5SDimitry Andric 
7550b57cec5SDimitry Andric   while (!WorkList.empty()) {
756349cc55cSDimitry Andric     SwitchWorkListItem W = WorkList.pop_back_val();
7571db9f3b2SDimitry Andric 
7581db9f3b2SDimitry Andric     unsigned NumClusters = W.LastCluster - W.FirstCluster + 1;
7591db9f3b2SDimitry Andric     // For optimized builds, lower large range as a balanced binary tree.
7601db9f3b2SDimitry Andric     if (NumClusters > 3 &&
7611db9f3b2SDimitry Andric         MF->getTarget().getOptLevel() != CodeGenOptLevel::None &&
7621db9f3b2SDimitry Andric         !DefaultMBB->getParent()->getFunction().hasMinSize()) {
7631db9f3b2SDimitry Andric       splitWorkItem(WorkList, W, SI.getCondition(), SwitchMBB, MIB);
7641db9f3b2SDimitry Andric       continue;
7651db9f3b2SDimitry Andric     }
7661db9f3b2SDimitry Andric 
7670b57cec5SDimitry Andric     if (!lowerSwitchWorkItem(W, SI.getCondition(), SwitchMBB, DefaultMBB, MIB))
7680b57cec5SDimitry Andric       return false;
7690b57cec5SDimitry Andric   }
7700b57cec5SDimitry Andric   return true;
7710b57cec5SDimitry Andric }
7720b57cec5SDimitry Andric 
splitWorkItem(SwitchCG::SwitchWorkList & WorkList,const SwitchCG::SwitchWorkListItem & W,Value * Cond,MachineBasicBlock * SwitchMBB,MachineIRBuilder & MIB)7731db9f3b2SDimitry Andric void IRTranslator::splitWorkItem(SwitchCG::SwitchWorkList &WorkList,
7741db9f3b2SDimitry Andric                                  const SwitchCG::SwitchWorkListItem &W,
7751db9f3b2SDimitry Andric                                  Value *Cond, MachineBasicBlock *SwitchMBB,
7761db9f3b2SDimitry Andric                                  MachineIRBuilder &MIB) {
7771db9f3b2SDimitry Andric   using namespace SwitchCG;
7781db9f3b2SDimitry Andric   assert(W.FirstCluster->Low->getValue().slt(W.LastCluster->Low->getValue()) &&
7791db9f3b2SDimitry Andric          "Clusters not sorted?");
7801db9f3b2SDimitry Andric   assert(W.LastCluster - W.FirstCluster + 1 >= 2 && "Too small to split!");
7811db9f3b2SDimitry Andric 
7821db9f3b2SDimitry Andric   auto [LastLeft, FirstRight, LeftProb, RightProb] =
7831db9f3b2SDimitry Andric       SL->computeSplitWorkItemInfo(W);
7841db9f3b2SDimitry Andric 
7851db9f3b2SDimitry Andric   // Use the first element on the right as pivot since we will make less-than
7861db9f3b2SDimitry Andric   // comparisons against it.
7871db9f3b2SDimitry Andric   CaseClusterIt PivotCluster = FirstRight;
7881db9f3b2SDimitry Andric   assert(PivotCluster > W.FirstCluster);
7891db9f3b2SDimitry Andric   assert(PivotCluster <= W.LastCluster);
7901db9f3b2SDimitry Andric 
7911db9f3b2SDimitry Andric   CaseClusterIt FirstLeft = W.FirstCluster;
7921db9f3b2SDimitry Andric   CaseClusterIt LastRight = W.LastCluster;
7931db9f3b2SDimitry Andric 
7941db9f3b2SDimitry Andric   const ConstantInt *Pivot = PivotCluster->Low;
7951db9f3b2SDimitry Andric 
7961db9f3b2SDimitry Andric   // New blocks will be inserted immediately after the current one.
7971db9f3b2SDimitry Andric   MachineFunction::iterator BBI(W.MBB);
7981db9f3b2SDimitry Andric   ++BBI;
7991db9f3b2SDimitry Andric 
8001db9f3b2SDimitry Andric   // We will branch to the LHS if Value < Pivot. If LHS is a single cluster,
8011db9f3b2SDimitry Andric   // we can branch to its destination directly if it's squeezed exactly in
8021db9f3b2SDimitry Andric   // between the known lower bound and Pivot - 1.
8031db9f3b2SDimitry Andric   MachineBasicBlock *LeftMBB;
8041db9f3b2SDimitry Andric   if (FirstLeft == LastLeft && FirstLeft->Kind == CC_Range &&
8051db9f3b2SDimitry Andric       FirstLeft->Low == W.GE &&
8061db9f3b2SDimitry Andric       (FirstLeft->High->getValue() + 1LL) == Pivot->getValue()) {
8071db9f3b2SDimitry Andric     LeftMBB = FirstLeft->MBB;
8081db9f3b2SDimitry Andric   } else {
8091db9f3b2SDimitry Andric     LeftMBB = FuncInfo.MF->CreateMachineBasicBlock(W.MBB->getBasicBlock());
8101db9f3b2SDimitry Andric     FuncInfo.MF->insert(BBI, LeftMBB);
8111db9f3b2SDimitry Andric     WorkList.push_back(
8121db9f3b2SDimitry Andric         {LeftMBB, FirstLeft, LastLeft, W.GE, Pivot, W.DefaultProb / 2});
8131db9f3b2SDimitry Andric   }
8141db9f3b2SDimitry Andric 
8151db9f3b2SDimitry Andric   // Similarly, we will branch to the RHS if Value >= Pivot. If RHS is a
8161db9f3b2SDimitry Andric   // single cluster, RHS.Low == Pivot, and we can branch to its destination
8171db9f3b2SDimitry Andric   // directly if RHS.High equals the current upper bound.
8181db9f3b2SDimitry Andric   MachineBasicBlock *RightMBB;
8191db9f3b2SDimitry Andric   if (FirstRight == LastRight && FirstRight->Kind == CC_Range && W.LT &&
8201db9f3b2SDimitry Andric       (FirstRight->High->getValue() + 1ULL) == W.LT->getValue()) {
8211db9f3b2SDimitry Andric     RightMBB = FirstRight->MBB;
8221db9f3b2SDimitry Andric   } else {
8231db9f3b2SDimitry Andric     RightMBB = FuncInfo.MF->CreateMachineBasicBlock(W.MBB->getBasicBlock());
8241db9f3b2SDimitry Andric     FuncInfo.MF->insert(BBI, RightMBB);
8251db9f3b2SDimitry Andric     WorkList.push_back(
8261db9f3b2SDimitry Andric         {RightMBB, FirstRight, LastRight, Pivot, W.LT, W.DefaultProb / 2});
8271db9f3b2SDimitry Andric   }
8281db9f3b2SDimitry Andric 
8291db9f3b2SDimitry Andric   // Create the CaseBlock record that will be used to lower the branch.
8301db9f3b2SDimitry Andric   CaseBlock CB(ICmpInst::Predicate::ICMP_SLT, false, Cond, Pivot, nullptr,
8311db9f3b2SDimitry Andric                LeftMBB, RightMBB, W.MBB, MIB.getDebugLoc(), LeftProb,
8321db9f3b2SDimitry Andric                RightProb);
8331db9f3b2SDimitry Andric 
8341db9f3b2SDimitry Andric   if (W.MBB == SwitchMBB)
8351db9f3b2SDimitry Andric     emitSwitchCase(CB, SwitchMBB, MIB);
8361db9f3b2SDimitry Andric   else
8371db9f3b2SDimitry Andric     SL->SwitchCases.push_back(CB);
8381db9f3b2SDimitry Andric }
8391db9f3b2SDimitry Andric 
emitJumpTable(SwitchCG::JumpTable & JT,MachineBasicBlock * MBB)8400b57cec5SDimitry Andric void IRTranslator::emitJumpTable(SwitchCG::JumpTable &JT,
8410b57cec5SDimitry Andric                                  MachineBasicBlock *MBB) {
8420b57cec5SDimitry Andric   // Emit the code for the jump table
8430b57cec5SDimitry Andric   assert(JT.Reg != -1U && "Should lower JT Header first!");
8440b57cec5SDimitry Andric   MachineIRBuilder MIB(*MBB->getParent());
8450b57cec5SDimitry Andric   MIB.setMBB(*MBB);
8460b57cec5SDimitry Andric   MIB.setDebugLoc(CurBuilder->getDebugLoc());
8470b57cec5SDimitry Andric 
8485f757f3fSDimitry Andric   Type *PtrIRTy = PointerType::getUnqual(MF->getFunction().getContext());
8490b57cec5SDimitry Andric   const LLT PtrTy = getLLTForType(*PtrIRTy, *DL);
8500b57cec5SDimitry Andric 
8510b57cec5SDimitry Andric   auto Table = MIB.buildJumpTable(PtrTy, JT.JTI);
8520b57cec5SDimitry Andric   MIB.buildBrJT(Table.getReg(0), JT.JTI, JT.Reg);
8530b57cec5SDimitry Andric }
8540b57cec5SDimitry Andric 
emitJumpTableHeader(SwitchCG::JumpTable & JT,SwitchCG::JumpTableHeader & JTH,MachineBasicBlock * HeaderBB)8550b57cec5SDimitry Andric bool IRTranslator::emitJumpTableHeader(SwitchCG::JumpTable &JT,
8560b57cec5SDimitry Andric                                        SwitchCG::JumpTableHeader &JTH,
8570b57cec5SDimitry Andric                                        MachineBasicBlock *HeaderBB) {
8580b57cec5SDimitry Andric   MachineIRBuilder MIB(*HeaderBB->getParent());
8590b57cec5SDimitry Andric   MIB.setMBB(*HeaderBB);
8600b57cec5SDimitry Andric   MIB.setDebugLoc(CurBuilder->getDebugLoc());
8610b57cec5SDimitry Andric 
8620b57cec5SDimitry Andric   const Value &SValue = *JTH.SValue;
8630b57cec5SDimitry Andric   // Subtract the lowest switch case value from the value being switched on.
8640b57cec5SDimitry Andric   const LLT SwitchTy = getLLTForType(*SValue.getType(), *DL);
8650b57cec5SDimitry Andric   Register SwitchOpReg = getOrCreateVReg(SValue);
8660b57cec5SDimitry Andric   auto FirstCst = MIB.buildConstant(SwitchTy, JTH.First);
8670b57cec5SDimitry Andric   auto Sub = MIB.buildSub({SwitchTy}, SwitchOpReg, FirstCst);
8680b57cec5SDimitry Andric 
8690b57cec5SDimitry Andric   // This value may be smaller or larger than the target's pointer type, and
8700b57cec5SDimitry Andric   // therefore require extension or truncating.
8715f757f3fSDimitry Andric   auto *PtrIRTy = PointerType::getUnqual(SValue.getContext());
8720b57cec5SDimitry Andric   const LLT PtrScalarTy = LLT::scalar(DL->getTypeSizeInBits(PtrIRTy));
8730b57cec5SDimitry Andric   Sub = MIB.buildZExtOrTrunc(PtrScalarTy, Sub);
8740b57cec5SDimitry Andric 
8750b57cec5SDimitry Andric   JT.Reg = Sub.getReg(0);
8760b57cec5SDimitry Andric 
877349cc55cSDimitry Andric   if (JTH.FallthroughUnreachable) {
8780b57cec5SDimitry Andric     if (JT.MBB != HeaderBB->getNextNode())
8790b57cec5SDimitry Andric       MIB.buildBr(*JT.MBB);
8800b57cec5SDimitry Andric     return true;
8810b57cec5SDimitry Andric   }
8820b57cec5SDimitry Andric 
8830b57cec5SDimitry Andric   // Emit the range check for the jump table, and branch to the default block
8840b57cec5SDimitry Andric   // for the switch statement if the value being switched on exceeds the
8850b57cec5SDimitry Andric   // largest case in the switch.
8860b57cec5SDimitry Andric   auto Cst = getOrCreateVReg(
8870b57cec5SDimitry Andric       *ConstantInt::get(SValue.getType(), JTH.Last - JTH.First));
8880b57cec5SDimitry Andric   Cst = MIB.buildZExtOrTrunc(PtrScalarTy, Cst).getReg(0);
8890b57cec5SDimitry Andric   auto Cmp = MIB.buildICmp(CmpInst::ICMP_UGT, LLT::scalar(1), Sub, Cst);
8900b57cec5SDimitry Andric 
8910b57cec5SDimitry Andric   auto BrCond = MIB.buildBrCond(Cmp.getReg(0), *JT.Default);
8920b57cec5SDimitry Andric 
8930b57cec5SDimitry Andric   // Avoid emitting unnecessary branches to the next block.
8940b57cec5SDimitry Andric   if (JT.MBB != HeaderBB->getNextNode())
8950b57cec5SDimitry Andric     BrCond = MIB.buildBr(*JT.MBB);
8960b57cec5SDimitry Andric   return true;
8970b57cec5SDimitry Andric }
8980b57cec5SDimitry Andric 
emitSwitchCase(SwitchCG::CaseBlock & CB,MachineBasicBlock * SwitchBB,MachineIRBuilder & MIB)8990b57cec5SDimitry Andric void IRTranslator::emitSwitchCase(SwitchCG::CaseBlock &CB,
9000b57cec5SDimitry Andric                                   MachineBasicBlock *SwitchBB,
9010b57cec5SDimitry Andric                                   MachineIRBuilder &MIB) {
9020b57cec5SDimitry Andric   Register CondLHS = getOrCreateVReg(*CB.CmpLHS);
9030b57cec5SDimitry Andric   Register Cond;
9040b57cec5SDimitry Andric   DebugLoc OldDbgLoc = MIB.getDebugLoc();
9050b57cec5SDimitry Andric   MIB.setDebugLoc(CB.DbgLoc);
9060b57cec5SDimitry Andric   MIB.setMBB(*CB.ThisBB);
9070b57cec5SDimitry Andric 
9080b57cec5SDimitry Andric   if (CB.PredInfo.NoCmp) {
9090b57cec5SDimitry Andric     // Branch or fall through to TrueBB.
9100b57cec5SDimitry Andric     addSuccessorWithProb(CB.ThisBB, CB.TrueBB, CB.TrueProb);
9110b57cec5SDimitry Andric     addMachineCFGPred({SwitchBB->getBasicBlock(), CB.TrueBB->getBasicBlock()},
9120b57cec5SDimitry Andric                       CB.ThisBB);
9130b57cec5SDimitry Andric     CB.ThisBB->normalizeSuccProbs();
9140b57cec5SDimitry Andric     if (CB.TrueBB != CB.ThisBB->getNextNode())
9150b57cec5SDimitry Andric       MIB.buildBr(*CB.TrueBB);
9160b57cec5SDimitry Andric     MIB.setDebugLoc(OldDbgLoc);
9170b57cec5SDimitry Andric     return;
9180b57cec5SDimitry Andric   }
9190b57cec5SDimitry Andric 
9200b57cec5SDimitry Andric   const LLT i1Ty = LLT::scalar(1);
9210b57cec5SDimitry Andric   // Build the compare.
9220b57cec5SDimitry Andric   if (!CB.CmpMHS) {
923e8d8bef9SDimitry Andric     const auto *CI = dyn_cast<ConstantInt>(CB.CmpRHS);
924e8d8bef9SDimitry Andric     // For conditional branch lowering, we might try to do something silly like
925e8d8bef9SDimitry Andric     // emit an G_ICMP to compare an existing G_ICMP i1 result with true. If so,
926e8d8bef9SDimitry Andric     // just re-use the existing condition vreg.
92706c3fb27SDimitry Andric     if (MRI->getType(CondLHS).getSizeInBits() == 1 && CI && CI->isOne() &&
92806c3fb27SDimitry Andric         CB.PredInfo.Pred == CmpInst::ICMP_EQ) {
929e8d8bef9SDimitry Andric       Cond = CondLHS;
930e8d8bef9SDimitry Andric     } else {
9310b57cec5SDimitry Andric       Register CondRHS = getOrCreateVReg(*CB.CmpRHS);
932e8d8bef9SDimitry Andric       if (CmpInst::isFPPredicate(CB.PredInfo.Pred))
933e8d8bef9SDimitry Andric         Cond =
934e8d8bef9SDimitry Andric             MIB.buildFCmp(CB.PredInfo.Pred, i1Ty, CondLHS, CondRHS).getReg(0);
935e8d8bef9SDimitry Andric       else
936e8d8bef9SDimitry Andric         Cond =
937e8d8bef9SDimitry Andric             MIB.buildICmp(CB.PredInfo.Pred, i1Ty, CondLHS, CondRHS).getReg(0);
938e8d8bef9SDimitry Andric     }
9390b57cec5SDimitry Andric   } else {
940c14a5a88SDimitry Andric     assert(CB.PredInfo.Pred == CmpInst::ICMP_SLE &&
941c14a5a88SDimitry Andric            "Can only handle SLE ranges");
9420b57cec5SDimitry Andric 
9430b57cec5SDimitry Andric     const APInt& Low = cast<ConstantInt>(CB.CmpLHS)->getValue();
9440b57cec5SDimitry Andric     const APInt& High = cast<ConstantInt>(CB.CmpRHS)->getValue();
9450b57cec5SDimitry Andric 
9460b57cec5SDimitry Andric     Register CmpOpReg = getOrCreateVReg(*CB.CmpMHS);
9470b57cec5SDimitry Andric     if (cast<ConstantInt>(CB.CmpLHS)->isMinValue(true)) {
9480b57cec5SDimitry Andric       Register CondRHS = getOrCreateVReg(*CB.CmpRHS);
9490b57cec5SDimitry Andric       Cond =
950c14a5a88SDimitry Andric           MIB.buildICmp(CmpInst::ICMP_SLE, i1Ty, CmpOpReg, CondRHS).getReg(0);
9510b57cec5SDimitry Andric     } else {
9525ffd83dbSDimitry Andric       const LLT CmpTy = MRI->getType(CmpOpReg);
9530b57cec5SDimitry Andric       auto Sub = MIB.buildSub({CmpTy}, CmpOpReg, CondLHS);
9540b57cec5SDimitry Andric       auto Diff = MIB.buildConstant(CmpTy, High - Low);
9550b57cec5SDimitry Andric       Cond = MIB.buildICmp(CmpInst::ICMP_ULE, i1Ty, Sub, Diff).getReg(0);
9560b57cec5SDimitry Andric     }
9570b57cec5SDimitry Andric   }
9580b57cec5SDimitry Andric 
9590b57cec5SDimitry Andric   // Update successor info
9600b57cec5SDimitry Andric   addSuccessorWithProb(CB.ThisBB, CB.TrueBB, CB.TrueProb);
9610b57cec5SDimitry Andric 
9620b57cec5SDimitry Andric   addMachineCFGPred({SwitchBB->getBasicBlock(), CB.TrueBB->getBasicBlock()},
9630b57cec5SDimitry Andric                     CB.ThisBB);
9640b57cec5SDimitry Andric 
9650b57cec5SDimitry Andric   // TrueBB and FalseBB are always different unless the incoming IR is
9660b57cec5SDimitry Andric   // degenerate. This only happens when running llc on weird IR.
9670b57cec5SDimitry Andric   if (CB.TrueBB != CB.FalseBB)
9680b57cec5SDimitry Andric     addSuccessorWithProb(CB.ThisBB, CB.FalseBB, CB.FalseProb);
9690b57cec5SDimitry Andric   CB.ThisBB->normalizeSuccProbs();
9700b57cec5SDimitry Andric 
9710b57cec5SDimitry Andric   addMachineCFGPred({SwitchBB->getBasicBlock(), CB.FalseBB->getBasicBlock()},
9720b57cec5SDimitry Andric                     CB.ThisBB);
9730b57cec5SDimitry Andric 
9740b57cec5SDimitry Andric   MIB.buildBrCond(Cond, *CB.TrueBB);
9750b57cec5SDimitry Andric   MIB.buildBr(*CB.FalseBB);
9760b57cec5SDimitry Andric   MIB.setDebugLoc(OldDbgLoc);
9770b57cec5SDimitry Andric }
9780b57cec5SDimitry Andric 
lowerJumpTableWorkItem(SwitchCG::SwitchWorkListItem W,MachineBasicBlock * SwitchMBB,MachineBasicBlock * CurMBB,MachineBasicBlock * DefaultMBB,MachineIRBuilder & MIB,MachineFunction::iterator BBI,BranchProbability UnhandledProbs,SwitchCG::CaseClusterIt I,MachineBasicBlock * Fallthrough,bool FallthroughUnreachable)9790b57cec5SDimitry Andric bool IRTranslator::lowerJumpTableWorkItem(SwitchCG::SwitchWorkListItem W,
9800b57cec5SDimitry Andric                                           MachineBasicBlock *SwitchMBB,
9810b57cec5SDimitry Andric                                           MachineBasicBlock *CurMBB,
9820b57cec5SDimitry Andric                                           MachineBasicBlock *DefaultMBB,
9830b57cec5SDimitry Andric                                           MachineIRBuilder &MIB,
9840b57cec5SDimitry Andric                                           MachineFunction::iterator BBI,
9850b57cec5SDimitry Andric                                           BranchProbability UnhandledProbs,
9860b57cec5SDimitry Andric                                           SwitchCG::CaseClusterIt I,
9870b57cec5SDimitry Andric                                           MachineBasicBlock *Fallthrough,
9880b57cec5SDimitry Andric                                           bool FallthroughUnreachable) {
9890b57cec5SDimitry Andric   using namespace SwitchCG;
9900b57cec5SDimitry Andric   MachineFunction *CurMF = SwitchMBB->getParent();
9910b57cec5SDimitry Andric   // FIXME: Optimize away range check based on pivot comparisons.
9920b57cec5SDimitry Andric   JumpTableHeader *JTH = &SL->JTCases[I->JTCasesIndex].first;
9930b57cec5SDimitry Andric   SwitchCG::JumpTable *JT = &SL->JTCases[I->JTCasesIndex].second;
9940b57cec5SDimitry Andric   BranchProbability DefaultProb = W.DefaultProb;
9950b57cec5SDimitry Andric 
9960b57cec5SDimitry Andric   // The jump block hasn't been inserted yet; insert it here.
9970b57cec5SDimitry Andric   MachineBasicBlock *JumpMBB = JT->MBB;
9980b57cec5SDimitry Andric   CurMF->insert(BBI, JumpMBB);
9990b57cec5SDimitry Andric 
10000b57cec5SDimitry Andric   // Since the jump table block is separate from the switch block, we need
10010b57cec5SDimitry Andric   // to keep track of it as a machine predecessor to the default block,
10020b57cec5SDimitry Andric   // otherwise we lose the phi edges.
10030b57cec5SDimitry Andric   addMachineCFGPred({SwitchMBB->getBasicBlock(), DefaultMBB->getBasicBlock()},
10040b57cec5SDimitry Andric                     CurMBB);
10050b57cec5SDimitry Andric   addMachineCFGPred({SwitchMBB->getBasicBlock(), DefaultMBB->getBasicBlock()},
10060b57cec5SDimitry Andric                     JumpMBB);
10070b57cec5SDimitry Andric 
10080b57cec5SDimitry Andric   auto JumpProb = I->Prob;
10090b57cec5SDimitry Andric   auto FallthroughProb = UnhandledProbs;
10100b57cec5SDimitry Andric 
10110b57cec5SDimitry Andric   // If the default statement is a target of the jump table, we evenly
10120b57cec5SDimitry Andric   // distribute the default probability to successors of CurMBB. Also
10130b57cec5SDimitry Andric   // update the probability on the edge from JumpMBB to Fallthrough.
10140b57cec5SDimitry Andric   for (MachineBasicBlock::succ_iterator SI = JumpMBB->succ_begin(),
10150b57cec5SDimitry Andric                                         SE = JumpMBB->succ_end();
10160b57cec5SDimitry Andric        SI != SE; ++SI) {
10170b57cec5SDimitry Andric     if (*SI == DefaultMBB) {
10180b57cec5SDimitry Andric       JumpProb += DefaultProb / 2;
10190b57cec5SDimitry Andric       FallthroughProb -= DefaultProb / 2;
10200b57cec5SDimitry Andric       JumpMBB->setSuccProbability(SI, DefaultProb / 2);
10210b57cec5SDimitry Andric       JumpMBB->normalizeSuccProbs();
10220b57cec5SDimitry Andric     } else {
10230b57cec5SDimitry Andric       // Also record edges from the jump table block to it's successors.
10240b57cec5SDimitry Andric       addMachineCFGPred({SwitchMBB->getBasicBlock(), (*SI)->getBasicBlock()},
10250b57cec5SDimitry Andric                         JumpMBB);
10260b57cec5SDimitry Andric     }
10270b57cec5SDimitry Andric   }
10280b57cec5SDimitry Andric 
10290b57cec5SDimitry Andric   if (FallthroughUnreachable)
1030349cc55cSDimitry Andric     JTH->FallthroughUnreachable = true;
10310b57cec5SDimitry Andric 
1032349cc55cSDimitry Andric   if (!JTH->FallthroughUnreachable)
10330b57cec5SDimitry Andric     addSuccessorWithProb(CurMBB, Fallthrough, FallthroughProb);
10340b57cec5SDimitry Andric   addSuccessorWithProb(CurMBB, JumpMBB, JumpProb);
10350b57cec5SDimitry Andric   CurMBB->normalizeSuccProbs();
10360b57cec5SDimitry Andric 
10370b57cec5SDimitry Andric   // The jump table header will be inserted in our current block, do the
10380b57cec5SDimitry Andric   // range check, and fall through to our fallthrough block.
10390b57cec5SDimitry Andric   JTH->HeaderBB = CurMBB;
10400b57cec5SDimitry Andric   JT->Default = Fallthrough; // FIXME: Move Default to JumpTableHeader.
10410b57cec5SDimitry Andric 
10420b57cec5SDimitry Andric   // If we're in the right place, emit the jump table header right now.
10430b57cec5SDimitry Andric   if (CurMBB == SwitchMBB) {
10440b57cec5SDimitry Andric     if (!emitJumpTableHeader(*JT, *JTH, CurMBB))
10450b57cec5SDimitry Andric       return false;
10460b57cec5SDimitry Andric     JTH->Emitted = true;
10470b57cec5SDimitry Andric   }
10480b57cec5SDimitry Andric   return true;
10490b57cec5SDimitry Andric }
lowerSwitchRangeWorkItem(SwitchCG::CaseClusterIt I,Value * Cond,MachineBasicBlock * Fallthrough,bool FallthroughUnreachable,BranchProbability UnhandledProbs,MachineBasicBlock * CurMBB,MachineIRBuilder & MIB,MachineBasicBlock * SwitchMBB)10500b57cec5SDimitry Andric bool IRTranslator::lowerSwitchRangeWorkItem(SwitchCG::CaseClusterIt I,
10510b57cec5SDimitry Andric                                             Value *Cond,
10520b57cec5SDimitry Andric                                             MachineBasicBlock *Fallthrough,
10530b57cec5SDimitry Andric                                             bool FallthroughUnreachable,
10540b57cec5SDimitry Andric                                             BranchProbability UnhandledProbs,
10550b57cec5SDimitry Andric                                             MachineBasicBlock *CurMBB,
10560b57cec5SDimitry Andric                                             MachineIRBuilder &MIB,
10570b57cec5SDimitry Andric                                             MachineBasicBlock *SwitchMBB) {
10580b57cec5SDimitry Andric   using namespace SwitchCG;
10590b57cec5SDimitry Andric   const Value *RHS, *LHS, *MHS;
10600b57cec5SDimitry Andric   CmpInst::Predicate Pred;
10610b57cec5SDimitry Andric   if (I->Low == I->High) {
10620b57cec5SDimitry Andric     // Check Cond == I->Low.
10630b57cec5SDimitry Andric     Pred = CmpInst::ICMP_EQ;
10640b57cec5SDimitry Andric     LHS = Cond;
10650b57cec5SDimitry Andric     RHS = I->Low;
10660b57cec5SDimitry Andric     MHS = nullptr;
10670b57cec5SDimitry Andric   } else {
10680b57cec5SDimitry Andric     // Check I->Low <= Cond <= I->High.
1069c14a5a88SDimitry Andric     Pred = CmpInst::ICMP_SLE;
10700b57cec5SDimitry Andric     LHS = I->Low;
10710b57cec5SDimitry Andric     MHS = Cond;
10720b57cec5SDimitry Andric     RHS = I->High;
10730b57cec5SDimitry Andric   }
10740b57cec5SDimitry Andric 
10750b57cec5SDimitry Andric   // If Fallthrough is unreachable, fold away the comparison.
10760b57cec5SDimitry Andric   // The false probability is the sum of all unhandled cases.
10770b57cec5SDimitry Andric   CaseBlock CB(Pred, FallthroughUnreachable, LHS, RHS, MHS, I->MBB, Fallthrough,
10780b57cec5SDimitry Andric                CurMBB, MIB.getDebugLoc(), I->Prob, UnhandledProbs);
10790b57cec5SDimitry Andric 
10800b57cec5SDimitry Andric   emitSwitchCase(CB, SwitchMBB, MIB);
10810b57cec5SDimitry Andric   return true;
10820b57cec5SDimitry Andric }
10830b57cec5SDimitry Andric 
emitBitTestHeader(SwitchCG::BitTestBlock & B,MachineBasicBlock * SwitchBB)1084e8d8bef9SDimitry Andric void IRTranslator::emitBitTestHeader(SwitchCG::BitTestBlock &B,
1085e8d8bef9SDimitry Andric                                      MachineBasicBlock *SwitchBB) {
1086e8d8bef9SDimitry Andric   MachineIRBuilder &MIB = *CurBuilder;
1087e8d8bef9SDimitry Andric   MIB.setMBB(*SwitchBB);
1088e8d8bef9SDimitry Andric 
1089e8d8bef9SDimitry Andric   // Subtract the minimum value.
1090e8d8bef9SDimitry Andric   Register SwitchOpReg = getOrCreateVReg(*B.SValue);
1091e8d8bef9SDimitry Andric 
1092e8d8bef9SDimitry Andric   LLT SwitchOpTy = MRI->getType(SwitchOpReg);
1093e8d8bef9SDimitry Andric   Register MinValReg = MIB.buildConstant(SwitchOpTy, B.First).getReg(0);
1094e8d8bef9SDimitry Andric   auto RangeSub = MIB.buildSub(SwitchOpTy, SwitchOpReg, MinValReg);
1095e8d8bef9SDimitry Andric 
10965f757f3fSDimitry Andric   Type *PtrIRTy = PointerType::getUnqual(MF->getFunction().getContext());
1097349cc55cSDimitry Andric   const LLT PtrTy = getLLTForType(*PtrIRTy, *DL);
1098349cc55cSDimitry Andric 
1099e8d8bef9SDimitry Andric   LLT MaskTy = SwitchOpTy;
1100349cc55cSDimitry Andric   if (MaskTy.getSizeInBits() > PtrTy.getSizeInBits() ||
110106c3fb27SDimitry Andric       !llvm::has_single_bit<uint32_t>(MaskTy.getSizeInBits()))
1102349cc55cSDimitry Andric     MaskTy = LLT::scalar(PtrTy.getSizeInBits());
1103349cc55cSDimitry Andric   else {
1104349cc55cSDimitry Andric     // Ensure that the type will fit the mask value.
1105e8d8bef9SDimitry Andric     for (unsigned I = 0, E = B.Cases.size(); I != E; ++I) {
1106e8d8bef9SDimitry Andric       if (!isUIntN(SwitchOpTy.getSizeInBits(), B.Cases[I].Mask)) {
1107e8d8bef9SDimitry Andric         // Switch table case range are encoded into series of masks.
1108e8d8bef9SDimitry Andric         // Just use pointer type, it's guaranteed to fit.
1109349cc55cSDimitry Andric         MaskTy = LLT::scalar(PtrTy.getSizeInBits());
1110e8d8bef9SDimitry Andric         break;
1111e8d8bef9SDimitry Andric       }
1112e8d8bef9SDimitry Andric     }
1113349cc55cSDimitry Andric   }
1114e8d8bef9SDimitry Andric   Register SubReg = RangeSub.getReg(0);
1115e8d8bef9SDimitry Andric   if (SwitchOpTy != MaskTy)
1116e8d8bef9SDimitry Andric     SubReg = MIB.buildZExtOrTrunc(MaskTy, SubReg).getReg(0);
1117e8d8bef9SDimitry Andric 
1118e8d8bef9SDimitry Andric   B.RegVT = getMVTForLLT(MaskTy);
1119e8d8bef9SDimitry Andric   B.Reg = SubReg;
1120e8d8bef9SDimitry Andric 
1121e8d8bef9SDimitry Andric   MachineBasicBlock *MBB = B.Cases[0].ThisBB;
1122e8d8bef9SDimitry Andric 
1123349cc55cSDimitry Andric   if (!B.FallthroughUnreachable)
1124e8d8bef9SDimitry Andric     addSuccessorWithProb(SwitchBB, B.Default, B.DefaultProb);
1125e8d8bef9SDimitry Andric   addSuccessorWithProb(SwitchBB, MBB, B.Prob);
1126e8d8bef9SDimitry Andric 
1127e8d8bef9SDimitry Andric   SwitchBB->normalizeSuccProbs();
1128e8d8bef9SDimitry Andric 
1129349cc55cSDimitry Andric   if (!B.FallthroughUnreachable) {
1130e8d8bef9SDimitry Andric     // Conditional branch to the default block.
1131e8d8bef9SDimitry Andric     auto RangeCst = MIB.buildConstant(SwitchOpTy, B.Range);
1132e8d8bef9SDimitry Andric     auto RangeCmp = MIB.buildICmp(CmpInst::Predicate::ICMP_UGT, LLT::scalar(1),
1133e8d8bef9SDimitry Andric                                   RangeSub, RangeCst);
1134e8d8bef9SDimitry Andric     MIB.buildBrCond(RangeCmp, *B.Default);
1135e8d8bef9SDimitry Andric   }
1136e8d8bef9SDimitry Andric 
1137e8d8bef9SDimitry Andric   // Avoid emitting unnecessary branches to the next block.
1138e8d8bef9SDimitry Andric   if (MBB != SwitchBB->getNextNode())
1139e8d8bef9SDimitry Andric     MIB.buildBr(*MBB);
1140e8d8bef9SDimitry Andric }
1141e8d8bef9SDimitry Andric 
emitBitTestCase(SwitchCG::BitTestBlock & BB,MachineBasicBlock * NextMBB,BranchProbability BranchProbToNext,Register Reg,SwitchCG::BitTestCase & B,MachineBasicBlock * SwitchBB)1142e8d8bef9SDimitry Andric void IRTranslator::emitBitTestCase(SwitchCG::BitTestBlock &BB,
1143e8d8bef9SDimitry Andric                                    MachineBasicBlock *NextMBB,
1144e8d8bef9SDimitry Andric                                    BranchProbability BranchProbToNext,
1145e8d8bef9SDimitry Andric                                    Register Reg, SwitchCG::BitTestCase &B,
1146e8d8bef9SDimitry Andric                                    MachineBasicBlock *SwitchBB) {
1147e8d8bef9SDimitry Andric   MachineIRBuilder &MIB = *CurBuilder;
1148e8d8bef9SDimitry Andric   MIB.setMBB(*SwitchBB);
1149e8d8bef9SDimitry Andric 
1150e8d8bef9SDimitry Andric   LLT SwitchTy = getLLTForMVT(BB.RegVT);
1151e8d8bef9SDimitry Andric   Register Cmp;
1152bdd1243dSDimitry Andric   unsigned PopCount = llvm::popcount(B.Mask);
1153e8d8bef9SDimitry Andric   if (PopCount == 1) {
1154e8d8bef9SDimitry Andric     // Testing for a single bit; just compare the shift count with what it
1155e8d8bef9SDimitry Andric     // would need to be to shift a 1 bit in that position.
1156e8d8bef9SDimitry Andric     auto MaskTrailingZeros =
115706c3fb27SDimitry Andric         MIB.buildConstant(SwitchTy, llvm::countr_zero(B.Mask));
1158e8d8bef9SDimitry Andric     Cmp =
1159e8d8bef9SDimitry Andric         MIB.buildICmp(ICmpInst::ICMP_EQ, LLT::scalar(1), Reg, MaskTrailingZeros)
1160e8d8bef9SDimitry Andric             .getReg(0);
1161e8d8bef9SDimitry Andric   } else if (PopCount == BB.Range) {
1162e8d8bef9SDimitry Andric     // There is only one zero bit in the range, test for it directly.
1163e8d8bef9SDimitry Andric     auto MaskTrailingOnes =
116406c3fb27SDimitry Andric         MIB.buildConstant(SwitchTy, llvm::countr_one(B.Mask));
1165e8d8bef9SDimitry Andric     Cmp = MIB.buildICmp(CmpInst::ICMP_NE, LLT::scalar(1), Reg, MaskTrailingOnes)
1166e8d8bef9SDimitry Andric               .getReg(0);
1167e8d8bef9SDimitry Andric   } else {
1168e8d8bef9SDimitry Andric     // Make desired shift.
1169e8d8bef9SDimitry Andric     auto CstOne = MIB.buildConstant(SwitchTy, 1);
1170e8d8bef9SDimitry Andric     auto SwitchVal = MIB.buildShl(SwitchTy, CstOne, Reg);
1171e8d8bef9SDimitry Andric 
1172e8d8bef9SDimitry Andric     // Emit bit tests and jumps.
1173e8d8bef9SDimitry Andric     auto CstMask = MIB.buildConstant(SwitchTy, B.Mask);
1174e8d8bef9SDimitry Andric     auto AndOp = MIB.buildAnd(SwitchTy, SwitchVal, CstMask);
1175e8d8bef9SDimitry Andric     auto CstZero = MIB.buildConstant(SwitchTy, 0);
1176e8d8bef9SDimitry Andric     Cmp = MIB.buildICmp(CmpInst::ICMP_NE, LLT::scalar(1), AndOp, CstZero)
1177e8d8bef9SDimitry Andric               .getReg(0);
1178e8d8bef9SDimitry Andric   }
1179e8d8bef9SDimitry Andric 
1180e8d8bef9SDimitry Andric   // The branch probability from SwitchBB to B.TargetBB is B.ExtraProb.
1181e8d8bef9SDimitry Andric   addSuccessorWithProb(SwitchBB, B.TargetBB, B.ExtraProb);
1182e8d8bef9SDimitry Andric   // The branch probability from SwitchBB to NextMBB is BranchProbToNext.
1183e8d8bef9SDimitry Andric   addSuccessorWithProb(SwitchBB, NextMBB, BranchProbToNext);
1184e8d8bef9SDimitry Andric   // It is not guaranteed that the sum of B.ExtraProb and BranchProbToNext is
1185e8d8bef9SDimitry Andric   // one as they are relative probabilities (and thus work more like weights),
1186e8d8bef9SDimitry Andric   // and hence we need to normalize them to let the sum of them become one.
1187e8d8bef9SDimitry Andric   SwitchBB->normalizeSuccProbs();
1188e8d8bef9SDimitry Andric 
1189e8d8bef9SDimitry Andric   // Record the fact that the IR edge from the header to the bit test target
1190e8d8bef9SDimitry Andric   // will go through our new block. Neeeded for PHIs to have nodes added.
1191e8d8bef9SDimitry Andric   addMachineCFGPred({BB.Parent->getBasicBlock(), B.TargetBB->getBasicBlock()},
1192e8d8bef9SDimitry Andric                     SwitchBB);
1193e8d8bef9SDimitry Andric 
1194e8d8bef9SDimitry Andric   MIB.buildBrCond(Cmp, *B.TargetBB);
1195e8d8bef9SDimitry Andric 
1196e8d8bef9SDimitry Andric   // Avoid emitting unnecessary branches to the next block.
1197e8d8bef9SDimitry Andric   if (NextMBB != SwitchBB->getNextNode())
1198e8d8bef9SDimitry Andric     MIB.buildBr(*NextMBB);
1199e8d8bef9SDimitry Andric }
1200e8d8bef9SDimitry Andric 
lowerBitTestWorkItem(SwitchCG::SwitchWorkListItem W,MachineBasicBlock * SwitchMBB,MachineBasicBlock * CurMBB,MachineBasicBlock * DefaultMBB,MachineIRBuilder & MIB,MachineFunction::iterator BBI,BranchProbability DefaultProb,BranchProbability UnhandledProbs,SwitchCG::CaseClusterIt I,MachineBasicBlock * Fallthrough,bool FallthroughUnreachable)1201e8d8bef9SDimitry Andric bool IRTranslator::lowerBitTestWorkItem(
1202e8d8bef9SDimitry Andric     SwitchCG::SwitchWorkListItem W, MachineBasicBlock *SwitchMBB,
1203e8d8bef9SDimitry Andric     MachineBasicBlock *CurMBB, MachineBasicBlock *DefaultMBB,
1204e8d8bef9SDimitry Andric     MachineIRBuilder &MIB, MachineFunction::iterator BBI,
1205e8d8bef9SDimitry Andric     BranchProbability DefaultProb, BranchProbability UnhandledProbs,
1206e8d8bef9SDimitry Andric     SwitchCG::CaseClusterIt I, MachineBasicBlock *Fallthrough,
1207e8d8bef9SDimitry Andric     bool FallthroughUnreachable) {
1208e8d8bef9SDimitry Andric   using namespace SwitchCG;
1209e8d8bef9SDimitry Andric   MachineFunction *CurMF = SwitchMBB->getParent();
1210e8d8bef9SDimitry Andric   // FIXME: Optimize away range check based on pivot comparisons.
1211e8d8bef9SDimitry Andric   BitTestBlock *BTB = &SL->BitTestCases[I->BTCasesIndex];
1212e8d8bef9SDimitry Andric   // The bit test blocks haven't been inserted yet; insert them here.
1213e8d8bef9SDimitry Andric   for (BitTestCase &BTC : BTB->Cases)
1214e8d8bef9SDimitry Andric     CurMF->insert(BBI, BTC.ThisBB);
1215e8d8bef9SDimitry Andric 
1216e8d8bef9SDimitry Andric   // Fill in fields of the BitTestBlock.
1217e8d8bef9SDimitry Andric   BTB->Parent = CurMBB;
1218e8d8bef9SDimitry Andric   BTB->Default = Fallthrough;
1219e8d8bef9SDimitry Andric 
1220e8d8bef9SDimitry Andric   BTB->DefaultProb = UnhandledProbs;
1221e8d8bef9SDimitry Andric   // If the cases in bit test don't form a contiguous range, we evenly
1222e8d8bef9SDimitry Andric   // distribute the probability on the edge to Fallthrough to two
1223e8d8bef9SDimitry Andric   // successors of CurMBB.
1224e8d8bef9SDimitry Andric   if (!BTB->ContiguousRange) {
1225e8d8bef9SDimitry Andric     BTB->Prob += DefaultProb / 2;
1226e8d8bef9SDimitry Andric     BTB->DefaultProb -= DefaultProb / 2;
1227e8d8bef9SDimitry Andric   }
1228e8d8bef9SDimitry Andric 
1229349cc55cSDimitry Andric   if (FallthroughUnreachable)
1230349cc55cSDimitry Andric     BTB->FallthroughUnreachable = true;
1231e8d8bef9SDimitry Andric 
1232e8d8bef9SDimitry Andric   // If we're in the right place, emit the bit test header right now.
1233e8d8bef9SDimitry Andric   if (CurMBB == SwitchMBB) {
1234e8d8bef9SDimitry Andric     emitBitTestHeader(*BTB, SwitchMBB);
1235e8d8bef9SDimitry Andric     BTB->Emitted = true;
1236e8d8bef9SDimitry Andric   }
1237e8d8bef9SDimitry Andric   return true;
1238e8d8bef9SDimitry Andric }
1239e8d8bef9SDimitry Andric 
lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W,Value * Cond,MachineBasicBlock * SwitchMBB,MachineBasicBlock * DefaultMBB,MachineIRBuilder & MIB)12400b57cec5SDimitry Andric bool IRTranslator::lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W,
12410b57cec5SDimitry Andric                                        Value *Cond,
12420b57cec5SDimitry Andric                                        MachineBasicBlock *SwitchMBB,
12430b57cec5SDimitry Andric                                        MachineBasicBlock *DefaultMBB,
12440b57cec5SDimitry Andric                                        MachineIRBuilder &MIB) {
12450b57cec5SDimitry Andric   using namespace SwitchCG;
12460b57cec5SDimitry Andric   MachineFunction *CurMF = FuncInfo.MF;
12470b57cec5SDimitry Andric   MachineBasicBlock *NextMBB = nullptr;
12480b57cec5SDimitry Andric   MachineFunction::iterator BBI(W.MBB);
12490b57cec5SDimitry Andric   if (++BBI != FuncInfo.MF->end())
12500b57cec5SDimitry Andric     NextMBB = &*BBI;
12510b57cec5SDimitry Andric 
12520b57cec5SDimitry Andric   if (EnableOpts) {
12530b57cec5SDimitry Andric     // Here, we order cases by probability so the most likely case will be
12540b57cec5SDimitry Andric     // checked first. However, two clusters can have the same probability in
12550b57cec5SDimitry Andric     // which case their relative ordering is non-deterministic. So we use Low
12560b57cec5SDimitry Andric     // as a tie-breaker as clusters are guaranteed to never overlap.
12570b57cec5SDimitry Andric     llvm::sort(W.FirstCluster, W.LastCluster + 1,
12580b57cec5SDimitry Andric                [](const CaseCluster &a, const CaseCluster &b) {
12590b57cec5SDimitry Andric                  return a.Prob != b.Prob
12600b57cec5SDimitry Andric                             ? a.Prob > b.Prob
12610b57cec5SDimitry Andric                             : a.Low->getValue().slt(b.Low->getValue());
12620b57cec5SDimitry Andric                });
12630b57cec5SDimitry Andric 
12640b57cec5SDimitry Andric     // Rearrange the case blocks so that the last one falls through if possible
12650b57cec5SDimitry Andric     // without changing the order of probabilities.
12660b57cec5SDimitry Andric     for (CaseClusterIt I = W.LastCluster; I > W.FirstCluster;) {
12670b57cec5SDimitry Andric       --I;
12680b57cec5SDimitry Andric       if (I->Prob > W.LastCluster->Prob)
12690b57cec5SDimitry Andric         break;
12700b57cec5SDimitry Andric       if (I->Kind == CC_Range && I->MBB == NextMBB) {
12710b57cec5SDimitry Andric         std::swap(*I, *W.LastCluster);
12720b57cec5SDimitry Andric         break;
12730b57cec5SDimitry Andric       }
12740b57cec5SDimitry Andric     }
12750b57cec5SDimitry Andric   }
12760b57cec5SDimitry Andric 
12770b57cec5SDimitry Andric   // Compute total probability.
12780b57cec5SDimitry Andric   BranchProbability DefaultProb = W.DefaultProb;
12790b57cec5SDimitry Andric   BranchProbability UnhandledProbs = DefaultProb;
12800b57cec5SDimitry Andric   for (CaseClusterIt I = W.FirstCluster; I <= W.LastCluster; ++I)
12810b57cec5SDimitry Andric     UnhandledProbs += I->Prob;
12820b57cec5SDimitry Andric 
12830b57cec5SDimitry Andric   MachineBasicBlock *CurMBB = W.MBB;
12840b57cec5SDimitry Andric   for (CaseClusterIt I = W.FirstCluster, E = W.LastCluster; I <= E; ++I) {
12850b57cec5SDimitry Andric     bool FallthroughUnreachable = false;
12860b57cec5SDimitry Andric     MachineBasicBlock *Fallthrough;
12870b57cec5SDimitry Andric     if (I == W.LastCluster) {
12880b57cec5SDimitry Andric       // For the last cluster, fall through to the default destination.
12890b57cec5SDimitry Andric       Fallthrough = DefaultMBB;
12900b57cec5SDimitry Andric       FallthroughUnreachable = isa<UnreachableInst>(
12910b57cec5SDimitry Andric           DefaultMBB->getBasicBlock()->getFirstNonPHIOrDbg());
12920b57cec5SDimitry Andric     } else {
12930b57cec5SDimitry Andric       Fallthrough = CurMF->CreateMachineBasicBlock(CurMBB->getBasicBlock());
12940b57cec5SDimitry Andric       CurMF->insert(BBI, Fallthrough);
12950b57cec5SDimitry Andric     }
12960b57cec5SDimitry Andric     UnhandledProbs -= I->Prob;
12970b57cec5SDimitry Andric 
12980b57cec5SDimitry Andric     switch (I->Kind) {
12990b57cec5SDimitry Andric     case CC_BitTests: {
1300e8d8bef9SDimitry Andric       if (!lowerBitTestWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
1301e8d8bef9SDimitry Andric                                 DefaultProb, UnhandledProbs, I, Fallthrough,
1302e8d8bef9SDimitry Andric                                 FallthroughUnreachable)) {
1303e8d8bef9SDimitry Andric         LLVM_DEBUG(dbgs() << "Failed to lower bit test for switch");
1304e8d8bef9SDimitry Andric         return false;
13050b57cec5SDimitry Andric       }
1306e8d8bef9SDimitry Andric       break;
1307e8d8bef9SDimitry Andric     }
1308e8d8bef9SDimitry Andric 
13090b57cec5SDimitry Andric     case CC_JumpTable: {
13100b57cec5SDimitry Andric       if (!lowerJumpTableWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
13110b57cec5SDimitry Andric                                   UnhandledProbs, I, Fallthrough,
13120b57cec5SDimitry Andric                                   FallthroughUnreachable)) {
13130b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "Failed to lower jump table");
13140b57cec5SDimitry Andric         return false;
13150b57cec5SDimitry Andric       }
13160b57cec5SDimitry Andric       break;
13170b57cec5SDimitry Andric     }
13180b57cec5SDimitry Andric     case CC_Range: {
13190b57cec5SDimitry Andric       if (!lowerSwitchRangeWorkItem(I, Cond, Fallthrough,
13200b57cec5SDimitry Andric                                     FallthroughUnreachable, UnhandledProbs,
13210b57cec5SDimitry Andric                                     CurMBB, MIB, SwitchMBB)) {
13220b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "Failed to lower switch range");
13230b57cec5SDimitry Andric         return false;
13240b57cec5SDimitry Andric       }
13250b57cec5SDimitry Andric       break;
13260b57cec5SDimitry Andric     }
13270b57cec5SDimitry Andric     }
13280b57cec5SDimitry Andric     CurMBB = Fallthrough;
13290b57cec5SDimitry Andric   }
13300b57cec5SDimitry Andric 
13310b57cec5SDimitry Andric   return true;
13320b57cec5SDimitry Andric }
13330b57cec5SDimitry Andric 
translateIndirectBr(const User & U,MachineIRBuilder & MIRBuilder)13340b57cec5SDimitry Andric bool IRTranslator::translateIndirectBr(const User &U,
13350b57cec5SDimitry Andric                                        MachineIRBuilder &MIRBuilder) {
13360b57cec5SDimitry Andric   const IndirectBrInst &BrInst = cast<IndirectBrInst>(U);
13370b57cec5SDimitry Andric 
13380b57cec5SDimitry Andric   const Register Tgt = getOrCreateVReg(*BrInst.getAddress());
13390b57cec5SDimitry Andric   MIRBuilder.buildBrIndirect(Tgt);
13400b57cec5SDimitry Andric 
13410b57cec5SDimitry Andric   // Link successors.
13425ffd83dbSDimitry Andric   SmallPtrSet<const BasicBlock *, 32> AddedSuccessors;
13430b57cec5SDimitry Andric   MachineBasicBlock &CurBB = MIRBuilder.getMBB();
13445ffd83dbSDimitry Andric   for (const BasicBlock *Succ : successors(&BrInst)) {
13455ffd83dbSDimitry Andric     // It's legal for indirectbr instructions to have duplicate blocks in the
13465ffd83dbSDimitry Andric     // destination list. We don't allow this in MIR. Skip anything that's
13475ffd83dbSDimitry Andric     // already a successor.
13485ffd83dbSDimitry Andric     if (!AddedSuccessors.insert(Succ).second)
13495ffd83dbSDimitry Andric       continue;
13500b57cec5SDimitry Andric     CurBB.addSuccessor(&getMBB(*Succ));
13515ffd83dbSDimitry Andric   }
13520b57cec5SDimitry Andric 
13530b57cec5SDimitry Andric   return true;
13540b57cec5SDimitry Andric }
13550b57cec5SDimitry Andric 
isSwiftError(const Value * V)13560b57cec5SDimitry Andric static bool isSwiftError(const Value *V) {
13570b57cec5SDimitry Andric   if (auto Arg = dyn_cast<Argument>(V))
13580b57cec5SDimitry Andric     return Arg->hasSwiftErrorAttr();
13590b57cec5SDimitry Andric   if (auto AI = dyn_cast<AllocaInst>(V))
13600b57cec5SDimitry Andric     return AI->isSwiftError();
13610b57cec5SDimitry Andric   return false;
13620b57cec5SDimitry Andric }
13630b57cec5SDimitry Andric 
translateLoad(const User & U,MachineIRBuilder & MIRBuilder)13640b57cec5SDimitry Andric bool IRTranslator::translateLoad(const User &U, MachineIRBuilder &MIRBuilder) {
13650b57cec5SDimitry Andric   const LoadInst &LI = cast<LoadInst>(U);
1366fcaf7f86SDimitry Andric 
1367fcaf7f86SDimitry Andric   unsigned StoreSize = DL->getTypeStoreSize(LI.getType());
1368fcaf7f86SDimitry Andric   if (StoreSize == 0)
13690b57cec5SDimitry Andric     return true;
13700b57cec5SDimitry Andric 
13710b57cec5SDimitry Andric   ArrayRef<Register> Regs = getOrCreateVRegs(LI);
13720b57cec5SDimitry Andric   ArrayRef<uint64_t> Offsets = *VMap.getOffsets(LI);
13730b57cec5SDimitry Andric   Register Base = getOrCreateVReg(*LI.getPointerOperand());
1374fcaf7f86SDimitry Andric   AAMDNodes AAInfo = LI.getAAMetadata();
13750b57cec5SDimitry Andric 
1376fcaf7f86SDimitry Andric   const Value *Ptr = LI.getPointerOperand();
137706c3fb27SDimitry Andric   Type *OffsetIRTy = DL->getIndexType(Ptr->getType());
13780b57cec5SDimitry Andric   LLT OffsetTy = getLLTForType(*OffsetIRTy, *DL);
13790b57cec5SDimitry Andric 
1380fcaf7f86SDimitry Andric   if (CLI->supportSwiftError() && isSwiftError(Ptr)) {
13810b57cec5SDimitry Andric     assert(Regs.size() == 1 && "swifterror should be single pointer");
1382fcaf7f86SDimitry Andric     Register VReg =
1383fcaf7f86SDimitry Andric         SwiftError.getOrCreateVRegUseAt(&LI, &MIRBuilder.getMBB(), Ptr);
13840b57cec5SDimitry Andric     MIRBuilder.buildCopy(Regs[0], VReg);
13850b57cec5SDimitry Andric     return true;
13860b57cec5SDimitry Andric   }
13870b57cec5SDimitry Andric 
13885ffd83dbSDimitry Andric   auto &TLI = *MF->getSubtarget().getTargetLowering();
1389bdd1243dSDimitry Andric   MachineMemOperand::Flags Flags =
1390bdd1243dSDimitry Andric       TLI.getLoadMemOperandFlags(LI, *DL, AC, LibInfo);
1391fcaf7f86SDimitry Andric   if (AA && !(Flags & MachineMemOperand::MOInvariant)) {
1392fcaf7f86SDimitry Andric     if (AA->pointsToConstantMemory(
1393fcaf7f86SDimitry Andric             MemoryLocation(Ptr, LocationSize::precise(StoreSize), AAInfo))) {
1394fcaf7f86SDimitry Andric       Flags |= MachineMemOperand::MOInvariant;
1395fcaf7f86SDimitry Andric     }
1396fcaf7f86SDimitry Andric   }
13975ffd83dbSDimitry Andric 
13988bcb0991SDimitry Andric   const MDNode *Ranges =
13998bcb0991SDimitry Andric       Regs.size() == 1 ? LI.getMetadata(LLVMContext::MD_range) : nullptr;
14000b57cec5SDimitry Andric   for (unsigned i = 0; i < Regs.size(); ++i) {
14010b57cec5SDimitry Andric     Register Addr;
1402480093f4SDimitry Andric     MIRBuilder.materializePtrAdd(Addr, Base, OffsetTy, Offsets[i] / 8);
14030b57cec5SDimitry Andric 
14040b57cec5SDimitry Andric     MachinePointerInfo Ptr(LI.getPointerOperand(), Offsets[i] / 8);
14055ffd83dbSDimitry Andric     Align BaseAlign = getMemOpAlign(LI);
14060b57cec5SDimitry Andric     auto MMO = MF->getMachineMemOperand(
1407fe6060f1SDimitry Andric         Ptr, Flags, MRI->getType(Regs[i]),
1408fcaf7f86SDimitry Andric         commonAlignment(BaseAlign, Offsets[i] / 8), AAInfo, Ranges,
14090b57cec5SDimitry Andric         LI.getSyncScopeID(), LI.getOrdering());
14100b57cec5SDimitry Andric     MIRBuilder.buildLoad(Regs[i], Addr, *MMO);
14110b57cec5SDimitry Andric   }
14120b57cec5SDimitry Andric 
14130b57cec5SDimitry Andric   return true;
14140b57cec5SDimitry Andric }
14150b57cec5SDimitry Andric 
translateStore(const User & U,MachineIRBuilder & MIRBuilder)14160b57cec5SDimitry Andric bool IRTranslator::translateStore(const User &U, MachineIRBuilder &MIRBuilder) {
14170b57cec5SDimitry Andric   const StoreInst &SI = cast<StoreInst>(U);
14180b57cec5SDimitry Andric   if (DL->getTypeStoreSize(SI.getValueOperand()->getType()) == 0)
14190b57cec5SDimitry Andric     return true;
14200b57cec5SDimitry Andric 
14210b57cec5SDimitry Andric   ArrayRef<Register> Vals = getOrCreateVRegs(*SI.getValueOperand());
14220b57cec5SDimitry Andric   ArrayRef<uint64_t> Offsets = *VMap.getOffsets(*SI.getValueOperand());
14230b57cec5SDimitry Andric   Register Base = getOrCreateVReg(*SI.getPointerOperand());
14240b57cec5SDimitry Andric 
142506c3fb27SDimitry Andric   Type *OffsetIRTy = DL->getIndexType(SI.getPointerOperandType());
14260b57cec5SDimitry Andric   LLT OffsetTy = getLLTForType(*OffsetIRTy, *DL);
14270b57cec5SDimitry Andric 
14280b57cec5SDimitry Andric   if (CLI->supportSwiftError() && isSwiftError(SI.getPointerOperand())) {
14290b57cec5SDimitry Andric     assert(Vals.size() == 1 && "swifterror should be single pointer");
14300b57cec5SDimitry Andric 
14310b57cec5SDimitry Andric     Register VReg = SwiftError.getOrCreateVRegDefAt(&SI, &MIRBuilder.getMBB(),
14320b57cec5SDimitry Andric                                                     SI.getPointerOperand());
14330b57cec5SDimitry Andric     MIRBuilder.buildCopy(VReg, Vals[0]);
14340b57cec5SDimitry Andric     return true;
14350b57cec5SDimitry Andric   }
14360b57cec5SDimitry Andric 
14375ffd83dbSDimitry Andric   auto &TLI = *MF->getSubtarget().getTargetLowering();
14385ffd83dbSDimitry Andric   MachineMemOperand::Flags Flags = TLI.getStoreMemOperandFlags(SI, *DL);
14395ffd83dbSDimitry Andric 
14400b57cec5SDimitry Andric   for (unsigned i = 0; i < Vals.size(); ++i) {
14410b57cec5SDimitry Andric     Register Addr;
1442480093f4SDimitry Andric     MIRBuilder.materializePtrAdd(Addr, Base, OffsetTy, Offsets[i] / 8);
14430b57cec5SDimitry Andric 
14440b57cec5SDimitry Andric     MachinePointerInfo Ptr(SI.getPointerOperand(), Offsets[i] / 8);
14455ffd83dbSDimitry Andric     Align BaseAlign = getMemOpAlign(SI);
14460b57cec5SDimitry Andric     auto MMO = MF->getMachineMemOperand(
1447fe6060f1SDimitry Andric         Ptr, Flags, MRI->getType(Vals[i]),
1448349cc55cSDimitry Andric         commonAlignment(BaseAlign, Offsets[i] / 8), SI.getAAMetadata(), nullptr,
14490b57cec5SDimitry Andric         SI.getSyncScopeID(), SI.getOrdering());
14500b57cec5SDimitry Andric     MIRBuilder.buildStore(Vals[i], Addr, *MMO);
14510b57cec5SDimitry Andric   }
14520b57cec5SDimitry Andric   return true;
14530b57cec5SDimitry Andric }
14540b57cec5SDimitry Andric 
getOffsetFromIndices(const User & U,const DataLayout & DL)14550b57cec5SDimitry Andric static uint64_t getOffsetFromIndices(const User &U, const DataLayout &DL) {
14560b57cec5SDimitry Andric   const Value *Src = U.getOperand(0);
14570b57cec5SDimitry Andric   Type *Int32Ty = Type::getInt32Ty(U.getContext());
14580b57cec5SDimitry Andric 
14590b57cec5SDimitry Andric   // getIndexedOffsetInType is designed for GEPs, so the first index is the
14600b57cec5SDimitry Andric   // usual array element rather than looking into the actual aggregate.
14610b57cec5SDimitry Andric   SmallVector<Value *, 1> Indices;
14620b57cec5SDimitry Andric   Indices.push_back(ConstantInt::get(Int32Ty, 0));
14630b57cec5SDimitry Andric 
14640b57cec5SDimitry Andric   if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(&U)) {
14650b57cec5SDimitry Andric     for (auto Idx : EVI->indices())
14660b57cec5SDimitry Andric       Indices.push_back(ConstantInt::get(Int32Ty, Idx));
14670b57cec5SDimitry Andric   } else if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(&U)) {
14680b57cec5SDimitry Andric     for (auto Idx : IVI->indices())
14690b57cec5SDimitry Andric       Indices.push_back(ConstantInt::get(Int32Ty, Idx));
14700b57cec5SDimitry Andric   } else {
14710b57cec5SDimitry Andric     for (unsigned i = 1; i < U.getNumOperands(); ++i)
14720b57cec5SDimitry Andric       Indices.push_back(U.getOperand(i));
14730b57cec5SDimitry Andric   }
14740b57cec5SDimitry Andric 
14750b57cec5SDimitry Andric   return 8 * static_cast<uint64_t>(
14760b57cec5SDimitry Andric                  DL.getIndexedOffsetInType(Src->getType(), Indices));
14770b57cec5SDimitry Andric }
14780b57cec5SDimitry Andric 
translateExtractValue(const User & U,MachineIRBuilder & MIRBuilder)14790b57cec5SDimitry Andric bool IRTranslator::translateExtractValue(const User &U,
14800b57cec5SDimitry Andric                                          MachineIRBuilder &MIRBuilder) {
14810b57cec5SDimitry Andric   const Value *Src = U.getOperand(0);
14820b57cec5SDimitry Andric   uint64_t Offset = getOffsetFromIndices(U, *DL);
14830b57cec5SDimitry Andric   ArrayRef<Register> SrcRegs = getOrCreateVRegs(*Src);
14840b57cec5SDimitry Andric   ArrayRef<uint64_t> Offsets = *VMap.getOffsets(*Src);
14850b57cec5SDimitry Andric   unsigned Idx = llvm::lower_bound(Offsets, Offset) - Offsets.begin();
14860b57cec5SDimitry Andric   auto &DstRegs = allocateVRegs(U);
14870b57cec5SDimitry Andric 
14880b57cec5SDimitry Andric   for (unsigned i = 0; i < DstRegs.size(); ++i)
14890b57cec5SDimitry Andric     DstRegs[i] = SrcRegs[Idx++];
14900b57cec5SDimitry Andric 
14910b57cec5SDimitry Andric   return true;
14920b57cec5SDimitry Andric }
14930b57cec5SDimitry Andric 
translateInsertValue(const User & U,MachineIRBuilder & MIRBuilder)14940b57cec5SDimitry Andric bool IRTranslator::translateInsertValue(const User &U,
14950b57cec5SDimitry Andric                                         MachineIRBuilder &MIRBuilder) {
14960b57cec5SDimitry Andric   const Value *Src = U.getOperand(0);
14970b57cec5SDimitry Andric   uint64_t Offset = getOffsetFromIndices(U, *DL);
14980b57cec5SDimitry Andric   auto &DstRegs = allocateVRegs(U);
14990b57cec5SDimitry Andric   ArrayRef<uint64_t> DstOffsets = *VMap.getOffsets(U);
15000b57cec5SDimitry Andric   ArrayRef<Register> SrcRegs = getOrCreateVRegs(*Src);
15010b57cec5SDimitry Andric   ArrayRef<Register> InsertedRegs = getOrCreateVRegs(*U.getOperand(1));
1502fcaf7f86SDimitry Andric   auto *InsertedIt = InsertedRegs.begin();
15030b57cec5SDimitry Andric 
15040b57cec5SDimitry Andric   for (unsigned i = 0; i < DstRegs.size(); ++i) {
15050b57cec5SDimitry Andric     if (DstOffsets[i] >= Offset && InsertedIt != InsertedRegs.end())
15060b57cec5SDimitry Andric       DstRegs[i] = *InsertedIt++;
15070b57cec5SDimitry Andric     else
15080b57cec5SDimitry Andric       DstRegs[i] = SrcRegs[i];
15090b57cec5SDimitry Andric   }
15100b57cec5SDimitry Andric 
15110b57cec5SDimitry Andric   return true;
15120b57cec5SDimitry Andric }
15130b57cec5SDimitry Andric 
translateSelect(const User & U,MachineIRBuilder & MIRBuilder)15140b57cec5SDimitry Andric bool IRTranslator::translateSelect(const User &U,
15150b57cec5SDimitry Andric                                    MachineIRBuilder &MIRBuilder) {
15160b57cec5SDimitry Andric   Register Tst = getOrCreateVReg(*U.getOperand(0));
15170b57cec5SDimitry Andric   ArrayRef<Register> ResRegs = getOrCreateVRegs(U);
15180b57cec5SDimitry Andric   ArrayRef<Register> Op0Regs = getOrCreateVRegs(*U.getOperand(1));
15190b57cec5SDimitry Andric   ArrayRef<Register> Op1Regs = getOrCreateVRegs(*U.getOperand(2));
15200b57cec5SDimitry Andric 
152106c3fb27SDimitry Andric   uint32_t Flags = 0;
15225ffd83dbSDimitry Andric   if (const SelectInst *SI = dyn_cast<SelectInst>(&U))
15235ffd83dbSDimitry Andric     Flags = MachineInstr::copyFlagsFromInstruction(*SI);
15240b57cec5SDimitry Andric 
15250b57cec5SDimitry Andric   for (unsigned i = 0; i < ResRegs.size(); ++i) {
15265ffd83dbSDimitry Andric     MIRBuilder.buildSelect(ResRegs[i], Tst, Op0Regs[i], Op1Regs[i], Flags);
15270b57cec5SDimitry Andric   }
15280b57cec5SDimitry Andric 
15290b57cec5SDimitry Andric   return true;
15300b57cec5SDimitry Andric }
15310b57cec5SDimitry Andric 
translateCopy(const User & U,const Value & V,MachineIRBuilder & MIRBuilder)15325ffd83dbSDimitry Andric bool IRTranslator::translateCopy(const User &U, const Value &V,
15335ffd83dbSDimitry Andric                                  MachineIRBuilder &MIRBuilder) {
15345ffd83dbSDimitry Andric   Register Src = getOrCreateVReg(V);
15355ffd83dbSDimitry Andric   auto &Regs = *VMap.getVRegs(U);
15365ffd83dbSDimitry Andric   if (Regs.empty()) {
15375ffd83dbSDimitry Andric     Regs.push_back(Src);
15385ffd83dbSDimitry Andric     VMap.getOffsets(U)->push_back(0);
15395ffd83dbSDimitry Andric   } else {
15405ffd83dbSDimitry Andric     // If we already assigned a vreg for this instruction, we can't change that.
15415ffd83dbSDimitry Andric     // Emit a copy to satisfy the users we already emitted.
15425ffd83dbSDimitry Andric     MIRBuilder.buildCopy(Regs[0], Src);
15435ffd83dbSDimitry Andric   }
15445ffd83dbSDimitry Andric   return true;
15455ffd83dbSDimitry Andric }
15465ffd83dbSDimitry Andric 
translateBitCast(const User & U,MachineIRBuilder & MIRBuilder)15470b57cec5SDimitry Andric bool IRTranslator::translateBitCast(const User &U,
15480b57cec5SDimitry Andric                                     MachineIRBuilder &MIRBuilder) {
15490b57cec5SDimitry Andric   // If we're bitcasting to the source type, we can reuse the source vreg.
15500b57cec5SDimitry Andric   if (getLLTForType(*U.getOperand(0)->getType(), *DL) ==
155106c3fb27SDimitry Andric       getLLTForType(*U.getType(), *DL)) {
155206c3fb27SDimitry Andric     // If the source is a ConstantInt then it was probably created by
155306c3fb27SDimitry Andric     // ConstantHoisting and we should leave it alone.
155406c3fb27SDimitry Andric     if (isa<ConstantInt>(U.getOperand(0)))
155506c3fb27SDimitry Andric       return translateCast(TargetOpcode::G_CONSTANT_FOLD_BARRIER, U,
155606c3fb27SDimitry Andric                            MIRBuilder);
15575ffd83dbSDimitry Andric     return translateCopy(U, *U.getOperand(0), MIRBuilder);
155806c3fb27SDimitry Andric   }
15595ffd83dbSDimitry Andric 
15600b57cec5SDimitry Andric   return translateCast(TargetOpcode::G_BITCAST, U, MIRBuilder);
15610b57cec5SDimitry Andric }
15620b57cec5SDimitry Andric 
translateCast(unsigned Opcode,const User & U,MachineIRBuilder & MIRBuilder)15630b57cec5SDimitry Andric bool IRTranslator::translateCast(unsigned Opcode, const User &U,
15640b57cec5SDimitry Andric                                  MachineIRBuilder &MIRBuilder) {
15655f757f3fSDimitry Andric   if (U.getType()->getScalarType()->isBFloatTy() ||
15665f757f3fSDimitry Andric       U.getOperand(0)->getType()->getScalarType()->isBFloatTy())
15675f757f3fSDimitry Andric     return false;
15680b57cec5SDimitry Andric   Register Op = getOrCreateVReg(*U.getOperand(0));
15690b57cec5SDimitry Andric   Register Res = getOrCreateVReg(U);
15700b57cec5SDimitry Andric   MIRBuilder.buildInstr(Opcode, {Res}, {Op});
15710b57cec5SDimitry Andric   return true;
15720b57cec5SDimitry Andric }
15730b57cec5SDimitry Andric 
translateGetElementPtr(const User & U,MachineIRBuilder & MIRBuilder)15740b57cec5SDimitry Andric bool IRTranslator::translateGetElementPtr(const User &U,
15750b57cec5SDimitry Andric                                           MachineIRBuilder &MIRBuilder) {
15760b57cec5SDimitry Andric   Value &Op0 = *U.getOperand(0);
15770b57cec5SDimitry Andric   Register BaseReg = getOrCreateVReg(Op0);
15780b57cec5SDimitry Andric   Type *PtrIRTy = Op0.getType();
15790b57cec5SDimitry Andric   LLT PtrTy = getLLTForType(*PtrIRTy, *DL);
158006c3fb27SDimitry Andric   Type *OffsetIRTy = DL->getIndexType(PtrIRTy);
15810b57cec5SDimitry Andric   LLT OffsetTy = getLLTForType(*OffsetIRTy, *DL);
15820b57cec5SDimitry Andric 
15835f757f3fSDimitry Andric   uint32_t Flags = 0;
15845f757f3fSDimitry Andric   if (isa<Instruction>(U)) {
15855f757f3fSDimitry Andric     const Instruction &I = cast<Instruction>(U);
15865f757f3fSDimitry Andric     Flags = MachineInstr::copyFlagsFromInstruction(I);
15875f757f3fSDimitry Andric   }
15885f757f3fSDimitry Andric 
15895ffd83dbSDimitry Andric   // Normalize Vector GEP - all scalar operands should be converted to the
15905ffd83dbSDimitry Andric   // splat vector.
15915ffd83dbSDimitry Andric   unsigned VectorWidth = 0;
1592fe6060f1SDimitry Andric 
1593fe6060f1SDimitry Andric   // True if we should use a splat vector; using VectorWidth alone is not
1594fe6060f1SDimitry Andric   // sufficient.
1595fe6060f1SDimitry Andric   bool WantSplatVector = false;
1596fe6060f1SDimitry Andric   if (auto *VT = dyn_cast<VectorType>(U.getType())) {
15975ffd83dbSDimitry Andric     VectorWidth = cast<FixedVectorType>(VT)->getNumElements();
1598fe6060f1SDimitry Andric     // We don't produce 1 x N vectors; those are treated as scalars.
1599fe6060f1SDimitry Andric     WantSplatVector = VectorWidth > 1;
1600fe6060f1SDimitry Andric   }
16015ffd83dbSDimitry Andric 
16025ffd83dbSDimitry Andric   // We might need to splat the base pointer into a vector if the offsets
16035ffd83dbSDimitry Andric   // are vectors.
1604fe6060f1SDimitry Andric   if (WantSplatVector && !PtrTy.isVector()) {
16055ffd83dbSDimitry Andric     BaseReg =
1606fe6060f1SDimitry Andric         MIRBuilder
1607fe6060f1SDimitry Andric             .buildSplatVector(LLT::fixed_vector(VectorWidth, PtrTy), BaseReg)
16085ffd83dbSDimitry Andric             .getReg(0);
16095ffd83dbSDimitry Andric     PtrIRTy = FixedVectorType::get(PtrIRTy, VectorWidth);
16105ffd83dbSDimitry Andric     PtrTy = getLLTForType(*PtrIRTy, *DL);
161106c3fb27SDimitry Andric     OffsetIRTy = DL->getIndexType(PtrIRTy);
16125ffd83dbSDimitry Andric     OffsetTy = getLLTForType(*OffsetIRTy, *DL);
16135ffd83dbSDimitry Andric   }
16145ffd83dbSDimitry Andric 
16150b57cec5SDimitry Andric   int64_t Offset = 0;
16160b57cec5SDimitry Andric   for (gep_type_iterator GTI = gep_type_begin(&U), E = gep_type_end(&U);
16170b57cec5SDimitry Andric        GTI != E; ++GTI) {
16180b57cec5SDimitry Andric     const Value *Idx = GTI.getOperand();
16190b57cec5SDimitry Andric     if (StructType *StTy = GTI.getStructTypeOrNull()) {
16200b57cec5SDimitry Andric       unsigned Field = cast<Constant>(Idx)->getUniqueInteger().getZExtValue();
16210b57cec5SDimitry Andric       Offset += DL->getStructLayout(StTy)->getElementOffset(Field);
16220b57cec5SDimitry Andric       continue;
16230b57cec5SDimitry Andric     } else {
16241db9f3b2SDimitry Andric       uint64_t ElementSize = GTI.getSequentialElementStride(*DL);
16250b57cec5SDimitry Andric 
16260b57cec5SDimitry Andric       // If this is a scalar constant or a splat vector of constants,
16270b57cec5SDimitry Andric       // handle it quickly.
16280b57cec5SDimitry Andric       if (const auto *CI = dyn_cast<ConstantInt>(Idx)) {
16295f757f3fSDimitry Andric         if (std::optional<int64_t> Val = CI->getValue().trySExtValue()) {
16305f757f3fSDimitry Andric           Offset += ElementSize * *Val;
16310b57cec5SDimitry Andric           continue;
16320b57cec5SDimitry Andric         }
16335f757f3fSDimitry Andric       }
16340b57cec5SDimitry Andric 
16350b57cec5SDimitry Andric       if (Offset != 0) {
16360b57cec5SDimitry Andric         auto OffsetMIB = MIRBuilder.buildConstant({OffsetTy}, Offset);
1637480093f4SDimitry Andric         BaseReg = MIRBuilder.buildPtrAdd(PtrTy, BaseReg, OffsetMIB.getReg(0))
1638480093f4SDimitry Andric                       .getReg(0);
16390b57cec5SDimitry Andric         Offset = 0;
16400b57cec5SDimitry Andric       }
16410b57cec5SDimitry Andric 
16420b57cec5SDimitry Andric       Register IdxReg = getOrCreateVReg(*Idx);
16435ffd83dbSDimitry Andric       LLT IdxTy = MRI->getType(IdxReg);
16445ffd83dbSDimitry Andric       if (IdxTy != OffsetTy) {
1645fe6060f1SDimitry Andric         if (!IdxTy.isVector() && WantSplatVector) {
16465ffd83dbSDimitry Andric           IdxReg = MIRBuilder.buildSplatVector(
16475ffd83dbSDimitry Andric             OffsetTy.changeElementType(IdxTy), IdxReg).getReg(0);
16485ffd83dbSDimitry Andric         }
16495ffd83dbSDimitry Andric 
16508bcb0991SDimitry Andric         IdxReg = MIRBuilder.buildSExtOrTrunc(OffsetTy, IdxReg).getReg(0);
16515ffd83dbSDimitry Andric       }
16520b57cec5SDimitry Andric 
16530b57cec5SDimitry Andric       // N = N + Idx * ElementSize;
16540b57cec5SDimitry Andric       // Avoid doing it for ElementSize of 1.
16550b57cec5SDimitry Andric       Register GepOffsetReg;
16560b57cec5SDimitry Andric       if (ElementSize != 1) {
16570b57cec5SDimitry Andric         auto ElementSizeMIB = MIRBuilder.buildConstant(
16580b57cec5SDimitry Andric             getLLTForType(*OffsetIRTy, *DL), ElementSize);
16598bcb0991SDimitry Andric         GepOffsetReg =
16605ffd83dbSDimitry Andric             MIRBuilder.buildMul(OffsetTy, IdxReg, ElementSizeMIB).getReg(0);
16610b57cec5SDimitry Andric       } else
16620b57cec5SDimitry Andric         GepOffsetReg = IdxReg;
16630b57cec5SDimitry Andric 
1664480093f4SDimitry Andric       BaseReg = MIRBuilder.buildPtrAdd(PtrTy, BaseReg, GepOffsetReg).getReg(0);
16650b57cec5SDimitry Andric     }
16660b57cec5SDimitry Andric   }
16670b57cec5SDimitry Andric 
16680b57cec5SDimitry Andric   if (Offset != 0) {
16690b57cec5SDimitry Andric     auto OffsetMIB =
16705ffd83dbSDimitry Andric         MIRBuilder.buildConstant(OffsetTy, Offset);
16715f757f3fSDimitry Andric 
16725f757f3fSDimitry Andric     if (int64_t(Offset) >= 0 && cast<GEPOperator>(U).isInBounds())
16735f757f3fSDimitry Andric       Flags |= MachineInstr::MIFlag::NoUWrap;
16745f757f3fSDimitry Andric 
16755f757f3fSDimitry Andric     MIRBuilder.buildPtrAdd(getOrCreateVReg(U), BaseReg, OffsetMIB.getReg(0),
16765f757f3fSDimitry Andric                            Flags);
16770b57cec5SDimitry Andric     return true;
16780b57cec5SDimitry Andric   }
16790b57cec5SDimitry Andric 
16800b57cec5SDimitry Andric   MIRBuilder.buildCopy(getOrCreateVReg(U), BaseReg);
16810b57cec5SDimitry Andric   return true;
16820b57cec5SDimitry Andric }
16830b57cec5SDimitry Andric 
translateMemFunc(const CallInst & CI,MachineIRBuilder & MIRBuilder,unsigned Opcode)16848bcb0991SDimitry Andric bool IRTranslator::translateMemFunc(const CallInst &CI,
16850b57cec5SDimitry Andric                                     MachineIRBuilder &MIRBuilder,
1686e8d8bef9SDimitry Andric                                     unsigned Opcode) {
1687fcaf7f86SDimitry Andric   const Value *SrcPtr = CI.getArgOperand(1);
16880b57cec5SDimitry Andric   // If the source is undef, then just emit a nop.
1689fcaf7f86SDimitry Andric   if (isa<UndefValue>(SrcPtr))
16900b57cec5SDimitry Andric     return true;
16918bcb0991SDimitry Andric 
1692e8d8bef9SDimitry Andric   SmallVector<Register, 3> SrcRegs;
1693e8d8bef9SDimitry Andric 
1694e8d8bef9SDimitry Andric   unsigned MinPtrSize = UINT_MAX;
1695e8d8bef9SDimitry Andric   for (auto AI = CI.arg_begin(), AE = CI.arg_end(); std::next(AI) != AE; ++AI) {
1696e8d8bef9SDimitry Andric     Register SrcReg = getOrCreateVReg(**AI);
1697e8d8bef9SDimitry Andric     LLT SrcTy = MRI->getType(SrcReg);
1698e8d8bef9SDimitry Andric     if (SrcTy.isPointer())
1699fe6060f1SDimitry Andric       MinPtrSize = std::min<unsigned>(SrcTy.getSizeInBits(), MinPtrSize);
1700e8d8bef9SDimitry Andric     SrcRegs.push_back(SrcReg);
1701e8d8bef9SDimitry Andric   }
1702e8d8bef9SDimitry Andric 
1703e8d8bef9SDimitry Andric   LLT SizeTy = LLT::scalar(MinPtrSize);
1704e8d8bef9SDimitry Andric 
1705e8d8bef9SDimitry Andric   // The size operand should be the minimum of the pointer sizes.
1706e8d8bef9SDimitry Andric   Register &SizeOpReg = SrcRegs[SrcRegs.size() - 1];
1707e8d8bef9SDimitry Andric   if (MRI->getType(SizeOpReg) != SizeTy)
1708e8d8bef9SDimitry Andric     SizeOpReg = MIRBuilder.buildZExtOrTrunc(SizeTy, SizeOpReg).getReg(0);
1709e8d8bef9SDimitry Andric 
1710e8d8bef9SDimitry Andric   auto ICall = MIRBuilder.buildInstr(Opcode);
1711e8d8bef9SDimitry Andric   for (Register SrcReg : SrcRegs)
1712e8d8bef9SDimitry Andric     ICall.addUse(SrcReg);
17138bcb0991SDimitry Andric 
17145ffd83dbSDimitry Andric   Align DstAlign;
17155ffd83dbSDimitry Andric   Align SrcAlign;
17168bcb0991SDimitry Andric   unsigned IsVol =
1717349cc55cSDimitry Andric       cast<ConstantInt>(CI.getArgOperand(CI.arg_size() - 1))->getZExtValue();
17188bcb0991SDimitry Andric 
1719fcaf7f86SDimitry Andric   ConstantInt *CopySize = nullptr;
1720fcaf7f86SDimitry Andric 
17218bcb0991SDimitry Andric   if (auto *MCI = dyn_cast<MemCpyInst>(&CI)) {
17225ffd83dbSDimitry Andric     DstAlign = MCI->getDestAlign().valueOrOne();
17235ffd83dbSDimitry Andric     SrcAlign = MCI->getSourceAlign().valueOrOne();
1724fcaf7f86SDimitry Andric     CopySize = dyn_cast<ConstantInt>(MCI->getArgOperand(2));
1725fe6060f1SDimitry Andric   } else if (auto *MCI = dyn_cast<MemCpyInlineInst>(&CI)) {
1726fe6060f1SDimitry Andric     DstAlign = MCI->getDestAlign().valueOrOne();
1727fe6060f1SDimitry Andric     SrcAlign = MCI->getSourceAlign().valueOrOne();
1728fcaf7f86SDimitry Andric     CopySize = dyn_cast<ConstantInt>(MCI->getArgOperand(2));
17298bcb0991SDimitry Andric   } else if (auto *MMI = dyn_cast<MemMoveInst>(&CI)) {
17305ffd83dbSDimitry Andric     DstAlign = MMI->getDestAlign().valueOrOne();
17315ffd83dbSDimitry Andric     SrcAlign = MMI->getSourceAlign().valueOrOne();
1732fcaf7f86SDimitry Andric     CopySize = dyn_cast<ConstantInt>(MMI->getArgOperand(2));
17338bcb0991SDimitry Andric   } else {
17348bcb0991SDimitry Andric     auto *MSI = cast<MemSetInst>(&CI);
17355ffd83dbSDimitry Andric     DstAlign = MSI->getDestAlign().valueOrOne();
17360b57cec5SDimitry Andric   }
17370b57cec5SDimitry Andric 
1738fe6060f1SDimitry Andric   if (Opcode != TargetOpcode::G_MEMCPY_INLINE) {
17398bcb0991SDimitry Andric     // We need to propagate the tail call flag from the IR inst as an argument.
17408bcb0991SDimitry Andric     // Otherwise, we have to pessimize and assume later that we cannot tail call
17418bcb0991SDimitry Andric     // any memory intrinsics.
17428bcb0991SDimitry Andric     ICall.addImm(CI.isTailCall() ? 1 : 0);
1743fe6060f1SDimitry Andric   }
17440b57cec5SDimitry Andric 
17458bcb0991SDimitry Andric   // Create mem operands to store the alignment and volatile info.
1746fcaf7f86SDimitry Andric   MachineMemOperand::Flags LoadFlags = MachineMemOperand::MOLoad;
1747fcaf7f86SDimitry Andric   MachineMemOperand::Flags StoreFlags = MachineMemOperand::MOStore;
1748fcaf7f86SDimitry Andric   if (IsVol) {
1749fcaf7f86SDimitry Andric     LoadFlags |= MachineMemOperand::MOVolatile;
1750fcaf7f86SDimitry Andric     StoreFlags |= MachineMemOperand::MOVolatile;
1751fcaf7f86SDimitry Andric   }
1752fcaf7f86SDimitry Andric 
1753fcaf7f86SDimitry Andric   AAMDNodes AAInfo = CI.getAAMetadata();
1754fcaf7f86SDimitry Andric   if (AA && CopySize &&
1755fcaf7f86SDimitry Andric       AA->pointsToConstantMemory(MemoryLocation(
1756fcaf7f86SDimitry Andric           SrcPtr, LocationSize::precise(CopySize->getZExtValue()), AAInfo))) {
1757fcaf7f86SDimitry Andric     LoadFlags |= MachineMemOperand::MOInvariant;
1758fcaf7f86SDimitry Andric 
1759fcaf7f86SDimitry Andric     // FIXME: pointsToConstantMemory probably does not imply dereferenceable,
1760fcaf7f86SDimitry Andric     // but the previous usage implied it did. Probably should check
1761fcaf7f86SDimitry Andric     // isDereferenceableAndAlignedPointer.
1762fcaf7f86SDimitry Andric     LoadFlags |= MachineMemOperand::MODereferenceable;
1763fcaf7f86SDimitry Andric   }
1764fcaf7f86SDimitry Andric 
1765fcaf7f86SDimitry Andric   ICall.addMemOperand(
1766fcaf7f86SDimitry Andric       MF->getMachineMemOperand(MachinePointerInfo(CI.getArgOperand(0)),
1767fcaf7f86SDimitry Andric                                StoreFlags, 1, DstAlign, AAInfo));
1768e8d8bef9SDimitry Andric   if (Opcode != TargetOpcode::G_MEMSET)
17698bcb0991SDimitry Andric     ICall.addMemOperand(MF->getMachineMemOperand(
1770fcaf7f86SDimitry Andric         MachinePointerInfo(SrcPtr), LoadFlags, 1, SrcAlign, AAInfo));
17710b57cec5SDimitry Andric 
17728bcb0991SDimitry Andric   return true;
17730b57cec5SDimitry Andric }
17740b57cec5SDimitry Andric 
getStackGuard(Register DstReg,MachineIRBuilder & MIRBuilder)17750b57cec5SDimitry Andric void IRTranslator::getStackGuard(Register DstReg,
17760b57cec5SDimitry Andric                                  MachineIRBuilder &MIRBuilder) {
17770b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
17780b57cec5SDimitry Andric   MRI->setRegClass(DstReg, TRI->getPointerRegClass(*MF));
17795ffd83dbSDimitry Andric   auto MIB =
17805ffd83dbSDimitry Andric       MIRBuilder.buildInstr(TargetOpcode::LOAD_STACK_GUARD, {DstReg}, {});
17810b57cec5SDimitry Andric 
17820b57cec5SDimitry Andric   auto &TLI = *MF->getSubtarget().getTargetLowering();
17830b57cec5SDimitry Andric   Value *Global = TLI.getSDagStackGuard(*MF->getFunction().getParent());
17840b57cec5SDimitry Andric   if (!Global)
17850b57cec5SDimitry Andric     return;
17860b57cec5SDimitry Andric 
1787fe6060f1SDimitry Andric   unsigned AddrSpace = Global->getType()->getPointerAddressSpace();
1788fe6060f1SDimitry Andric   LLT PtrTy = LLT::pointer(AddrSpace, DL->getPointerSizeInBits(AddrSpace));
1789fe6060f1SDimitry Andric 
17900b57cec5SDimitry Andric   MachinePointerInfo MPInfo(Global);
17910b57cec5SDimitry Andric   auto Flags = MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant |
17920b57cec5SDimitry Andric                MachineMemOperand::MODereferenceable;
1793fe6060f1SDimitry Andric   MachineMemOperand *MemRef = MF->getMachineMemOperand(
1794fe6060f1SDimitry Andric       MPInfo, Flags, PtrTy, DL->getPointerABIAlignment(AddrSpace));
17950b57cec5SDimitry Andric   MIB.setMemRefs({MemRef});
17960b57cec5SDimitry Andric }
17970b57cec5SDimitry Andric 
translateOverflowIntrinsic(const CallInst & CI,unsigned Op,MachineIRBuilder & MIRBuilder)17980b57cec5SDimitry Andric bool IRTranslator::translateOverflowIntrinsic(const CallInst &CI, unsigned Op,
17990b57cec5SDimitry Andric                                               MachineIRBuilder &MIRBuilder) {
18000b57cec5SDimitry Andric   ArrayRef<Register> ResRegs = getOrCreateVRegs(CI);
18015ffd83dbSDimitry Andric   MIRBuilder.buildInstr(
18025ffd83dbSDimitry Andric       Op, {ResRegs[0], ResRegs[1]},
18035ffd83dbSDimitry Andric       {getOrCreateVReg(*CI.getOperand(0)), getOrCreateVReg(*CI.getOperand(1))});
18040b57cec5SDimitry Andric 
18050b57cec5SDimitry Andric   return true;
18060b57cec5SDimitry Andric }
18070b57cec5SDimitry Andric 
translateFixedPointIntrinsic(unsigned Op,const CallInst & CI,MachineIRBuilder & MIRBuilder)1808e8d8bef9SDimitry Andric bool IRTranslator::translateFixedPointIntrinsic(unsigned Op, const CallInst &CI,
1809e8d8bef9SDimitry Andric                                                 MachineIRBuilder &MIRBuilder) {
1810e8d8bef9SDimitry Andric   Register Dst = getOrCreateVReg(CI);
1811e8d8bef9SDimitry Andric   Register Src0 = getOrCreateVReg(*CI.getOperand(0));
1812e8d8bef9SDimitry Andric   Register Src1 = getOrCreateVReg(*CI.getOperand(1));
1813e8d8bef9SDimitry Andric   uint64_t Scale = cast<ConstantInt>(CI.getOperand(2))->getZExtValue();
1814e8d8bef9SDimitry Andric   MIRBuilder.buildInstr(Op, {Dst}, { Src0, Src1, Scale });
1815e8d8bef9SDimitry Andric   return true;
1816e8d8bef9SDimitry Andric }
1817e8d8bef9SDimitry Andric 
getSimpleIntrinsicOpcode(Intrinsic::ID ID)18180b57cec5SDimitry Andric unsigned IRTranslator::getSimpleIntrinsicOpcode(Intrinsic::ID ID) {
18190b57cec5SDimitry Andric   switch (ID) {
18200b57cec5SDimitry Andric     default:
18210b57cec5SDimitry Andric       break;
18220b57cec5SDimitry Andric     case Intrinsic::bswap:
18230b57cec5SDimitry Andric       return TargetOpcode::G_BSWAP;
18248bcb0991SDimitry Andric     case Intrinsic::bitreverse:
18258bcb0991SDimitry Andric       return TargetOpcode::G_BITREVERSE;
18265ffd83dbSDimitry Andric     case Intrinsic::fshl:
18275ffd83dbSDimitry Andric       return TargetOpcode::G_FSHL;
18285ffd83dbSDimitry Andric     case Intrinsic::fshr:
18295ffd83dbSDimitry Andric       return TargetOpcode::G_FSHR;
18300b57cec5SDimitry Andric     case Intrinsic::ceil:
18310b57cec5SDimitry Andric       return TargetOpcode::G_FCEIL;
18320b57cec5SDimitry Andric     case Intrinsic::cos:
18330b57cec5SDimitry Andric       return TargetOpcode::G_FCOS;
18340b57cec5SDimitry Andric     case Intrinsic::ctpop:
18350b57cec5SDimitry Andric       return TargetOpcode::G_CTPOP;
18360b57cec5SDimitry Andric     case Intrinsic::exp:
18370b57cec5SDimitry Andric       return TargetOpcode::G_FEXP;
18380b57cec5SDimitry Andric     case Intrinsic::exp2:
18390b57cec5SDimitry Andric       return TargetOpcode::G_FEXP2;
18405f757f3fSDimitry Andric     case Intrinsic::exp10:
18415f757f3fSDimitry Andric       return TargetOpcode::G_FEXP10;
18420b57cec5SDimitry Andric     case Intrinsic::fabs:
18430b57cec5SDimitry Andric       return TargetOpcode::G_FABS;
18440b57cec5SDimitry Andric     case Intrinsic::copysign:
18450b57cec5SDimitry Andric       return TargetOpcode::G_FCOPYSIGN;
18460b57cec5SDimitry Andric     case Intrinsic::minnum:
18470b57cec5SDimitry Andric       return TargetOpcode::G_FMINNUM;
18480b57cec5SDimitry Andric     case Intrinsic::maxnum:
18490b57cec5SDimitry Andric       return TargetOpcode::G_FMAXNUM;
18500b57cec5SDimitry Andric     case Intrinsic::minimum:
18510b57cec5SDimitry Andric       return TargetOpcode::G_FMINIMUM;
18520b57cec5SDimitry Andric     case Intrinsic::maximum:
18530b57cec5SDimitry Andric       return TargetOpcode::G_FMAXIMUM;
18540b57cec5SDimitry Andric     case Intrinsic::canonicalize:
18550b57cec5SDimitry Andric       return TargetOpcode::G_FCANONICALIZE;
18560b57cec5SDimitry Andric     case Intrinsic::floor:
18570b57cec5SDimitry Andric       return TargetOpcode::G_FFLOOR;
18580b57cec5SDimitry Andric     case Intrinsic::fma:
18590b57cec5SDimitry Andric       return TargetOpcode::G_FMA;
18600b57cec5SDimitry Andric     case Intrinsic::log:
18610b57cec5SDimitry Andric       return TargetOpcode::G_FLOG;
18620b57cec5SDimitry Andric     case Intrinsic::log2:
18630b57cec5SDimitry Andric       return TargetOpcode::G_FLOG2;
18640b57cec5SDimitry Andric     case Intrinsic::log10:
18650b57cec5SDimitry Andric       return TargetOpcode::G_FLOG10;
186606c3fb27SDimitry Andric     case Intrinsic::ldexp:
186706c3fb27SDimitry Andric       return TargetOpcode::G_FLDEXP;
18680b57cec5SDimitry Andric     case Intrinsic::nearbyint:
18690b57cec5SDimitry Andric       return TargetOpcode::G_FNEARBYINT;
18700b57cec5SDimitry Andric     case Intrinsic::pow:
18710b57cec5SDimitry Andric       return TargetOpcode::G_FPOW;
1872e8d8bef9SDimitry Andric     case Intrinsic::powi:
1873e8d8bef9SDimitry Andric       return TargetOpcode::G_FPOWI;
18740b57cec5SDimitry Andric     case Intrinsic::rint:
18750b57cec5SDimitry Andric       return TargetOpcode::G_FRINT;
18760b57cec5SDimitry Andric     case Intrinsic::round:
18770b57cec5SDimitry Andric       return TargetOpcode::G_INTRINSIC_ROUND;
1878e8d8bef9SDimitry Andric     case Intrinsic::roundeven:
1879e8d8bef9SDimitry Andric       return TargetOpcode::G_INTRINSIC_ROUNDEVEN;
18800b57cec5SDimitry Andric     case Intrinsic::sin:
18810b57cec5SDimitry Andric       return TargetOpcode::G_FSIN;
18820b57cec5SDimitry Andric     case Intrinsic::sqrt:
18830b57cec5SDimitry Andric       return TargetOpcode::G_FSQRT;
18840b57cec5SDimitry Andric     case Intrinsic::trunc:
18850b57cec5SDimitry Andric       return TargetOpcode::G_INTRINSIC_TRUNC;
1886480093f4SDimitry Andric     case Intrinsic::readcyclecounter:
1887480093f4SDimitry Andric       return TargetOpcode::G_READCYCLECOUNTER;
18885ffd83dbSDimitry Andric     case Intrinsic::ptrmask:
18895ffd83dbSDimitry Andric       return TargetOpcode::G_PTRMASK;
1890e8d8bef9SDimitry Andric     case Intrinsic::lrint:
1891e8d8bef9SDimitry Andric       return TargetOpcode::G_INTRINSIC_LRINT;
1892e8d8bef9SDimitry Andric     // FADD/FMUL require checking the FMF, so are handled elsewhere.
1893e8d8bef9SDimitry Andric     case Intrinsic::vector_reduce_fmin:
1894e8d8bef9SDimitry Andric       return TargetOpcode::G_VECREDUCE_FMIN;
1895e8d8bef9SDimitry Andric     case Intrinsic::vector_reduce_fmax:
1896e8d8bef9SDimitry Andric       return TargetOpcode::G_VECREDUCE_FMAX;
18975f757f3fSDimitry Andric     case Intrinsic::vector_reduce_fminimum:
18985f757f3fSDimitry Andric       return TargetOpcode::G_VECREDUCE_FMINIMUM;
18995f757f3fSDimitry Andric     case Intrinsic::vector_reduce_fmaximum:
19005f757f3fSDimitry Andric       return TargetOpcode::G_VECREDUCE_FMAXIMUM;
1901e8d8bef9SDimitry Andric     case Intrinsic::vector_reduce_add:
1902e8d8bef9SDimitry Andric       return TargetOpcode::G_VECREDUCE_ADD;
1903e8d8bef9SDimitry Andric     case Intrinsic::vector_reduce_mul:
1904e8d8bef9SDimitry Andric       return TargetOpcode::G_VECREDUCE_MUL;
1905e8d8bef9SDimitry Andric     case Intrinsic::vector_reduce_and:
1906e8d8bef9SDimitry Andric       return TargetOpcode::G_VECREDUCE_AND;
1907e8d8bef9SDimitry Andric     case Intrinsic::vector_reduce_or:
1908e8d8bef9SDimitry Andric       return TargetOpcode::G_VECREDUCE_OR;
1909e8d8bef9SDimitry Andric     case Intrinsic::vector_reduce_xor:
1910e8d8bef9SDimitry Andric       return TargetOpcode::G_VECREDUCE_XOR;
1911e8d8bef9SDimitry Andric     case Intrinsic::vector_reduce_smax:
1912e8d8bef9SDimitry Andric       return TargetOpcode::G_VECREDUCE_SMAX;
1913e8d8bef9SDimitry Andric     case Intrinsic::vector_reduce_smin:
1914e8d8bef9SDimitry Andric       return TargetOpcode::G_VECREDUCE_SMIN;
1915e8d8bef9SDimitry Andric     case Intrinsic::vector_reduce_umax:
1916e8d8bef9SDimitry Andric       return TargetOpcode::G_VECREDUCE_UMAX;
1917e8d8bef9SDimitry Andric     case Intrinsic::vector_reduce_umin:
1918e8d8bef9SDimitry Andric       return TargetOpcode::G_VECREDUCE_UMIN;
1919349cc55cSDimitry Andric     case Intrinsic::lround:
1920349cc55cSDimitry Andric       return TargetOpcode::G_LROUND;
1921349cc55cSDimitry Andric     case Intrinsic::llround:
1922349cc55cSDimitry Andric       return TargetOpcode::G_LLROUND;
1923297eecfbSDimitry Andric     case Intrinsic::get_fpenv:
1924297eecfbSDimitry Andric       return TargetOpcode::G_GET_FPENV;
19255f757f3fSDimitry Andric     case Intrinsic::get_fpmode:
19265f757f3fSDimitry Andric       return TargetOpcode::G_GET_FPMODE;
19270b57cec5SDimitry Andric   }
19280b57cec5SDimitry Andric   return Intrinsic::not_intrinsic;
19290b57cec5SDimitry Andric }
19300b57cec5SDimitry Andric 
translateSimpleIntrinsic(const CallInst & CI,Intrinsic::ID ID,MachineIRBuilder & MIRBuilder)19310b57cec5SDimitry Andric bool IRTranslator::translateSimpleIntrinsic(const CallInst &CI,
19320b57cec5SDimitry Andric                                             Intrinsic::ID ID,
19330b57cec5SDimitry Andric                                             MachineIRBuilder &MIRBuilder) {
19340b57cec5SDimitry Andric 
19350b57cec5SDimitry Andric   unsigned Op = getSimpleIntrinsicOpcode(ID);
19360b57cec5SDimitry Andric 
19370b57cec5SDimitry Andric   // Is this a simple intrinsic?
19380b57cec5SDimitry Andric   if (Op == Intrinsic::not_intrinsic)
19390b57cec5SDimitry Andric     return false;
19400b57cec5SDimitry Andric 
19410b57cec5SDimitry Andric   // Yes. Let's translate it.
19420b57cec5SDimitry Andric   SmallVector<llvm::SrcOp, 4> VRegs;
1943fcaf7f86SDimitry Andric   for (const auto &Arg : CI.args())
19440b57cec5SDimitry Andric     VRegs.push_back(getOrCreateVReg(*Arg));
19450b57cec5SDimitry Andric 
19460b57cec5SDimitry Andric   MIRBuilder.buildInstr(Op, {getOrCreateVReg(CI)}, VRegs,
19470b57cec5SDimitry Andric                         MachineInstr::copyFlagsFromInstruction(CI));
19480b57cec5SDimitry Andric   return true;
19490b57cec5SDimitry Andric }
19500b57cec5SDimitry Andric 
19515ffd83dbSDimitry Andric // TODO: Include ConstainedOps.def when all strict instructions are defined.
getConstrainedOpcode(Intrinsic::ID ID)19525ffd83dbSDimitry Andric static unsigned getConstrainedOpcode(Intrinsic::ID ID) {
19535ffd83dbSDimitry Andric   switch (ID) {
19545ffd83dbSDimitry Andric   case Intrinsic::experimental_constrained_fadd:
19555ffd83dbSDimitry Andric     return TargetOpcode::G_STRICT_FADD;
19565ffd83dbSDimitry Andric   case Intrinsic::experimental_constrained_fsub:
19575ffd83dbSDimitry Andric     return TargetOpcode::G_STRICT_FSUB;
19585ffd83dbSDimitry Andric   case Intrinsic::experimental_constrained_fmul:
19595ffd83dbSDimitry Andric     return TargetOpcode::G_STRICT_FMUL;
19605ffd83dbSDimitry Andric   case Intrinsic::experimental_constrained_fdiv:
19615ffd83dbSDimitry Andric     return TargetOpcode::G_STRICT_FDIV;
19625ffd83dbSDimitry Andric   case Intrinsic::experimental_constrained_frem:
19635ffd83dbSDimitry Andric     return TargetOpcode::G_STRICT_FREM;
19645ffd83dbSDimitry Andric   case Intrinsic::experimental_constrained_fma:
19655ffd83dbSDimitry Andric     return TargetOpcode::G_STRICT_FMA;
19665ffd83dbSDimitry Andric   case Intrinsic::experimental_constrained_sqrt:
19675ffd83dbSDimitry Andric     return TargetOpcode::G_STRICT_FSQRT;
196806c3fb27SDimitry Andric   case Intrinsic::experimental_constrained_ldexp:
196906c3fb27SDimitry Andric     return TargetOpcode::G_STRICT_FLDEXP;
19705ffd83dbSDimitry Andric   default:
19715ffd83dbSDimitry Andric     return 0;
19725ffd83dbSDimitry Andric   }
19735ffd83dbSDimitry Andric }
19745ffd83dbSDimitry Andric 
translateConstrainedFPIntrinsic(const ConstrainedFPIntrinsic & FPI,MachineIRBuilder & MIRBuilder)19755ffd83dbSDimitry Andric bool IRTranslator::translateConstrainedFPIntrinsic(
19765ffd83dbSDimitry Andric   const ConstrainedFPIntrinsic &FPI, MachineIRBuilder &MIRBuilder) {
197781ad6265SDimitry Andric   fp::ExceptionBehavior EB = *FPI.getExceptionBehavior();
19785ffd83dbSDimitry Andric 
19795ffd83dbSDimitry Andric   unsigned Opcode = getConstrainedOpcode(FPI.getIntrinsicID());
19805ffd83dbSDimitry Andric   if (!Opcode)
19815ffd83dbSDimitry Andric     return false;
19825ffd83dbSDimitry Andric 
198306c3fb27SDimitry Andric   uint32_t Flags = MachineInstr::copyFlagsFromInstruction(FPI);
19845ffd83dbSDimitry Andric   if (EB == fp::ExceptionBehavior::ebIgnore)
19855ffd83dbSDimitry Andric     Flags |= MachineInstr::NoFPExcept;
19865ffd83dbSDimitry Andric 
19875ffd83dbSDimitry Andric   SmallVector<llvm::SrcOp, 4> VRegs;
19885ffd83dbSDimitry Andric   VRegs.push_back(getOrCreateVReg(*FPI.getArgOperand(0)));
19895ffd83dbSDimitry Andric   if (!FPI.isUnaryOp())
19905ffd83dbSDimitry Andric     VRegs.push_back(getOrCreateVReg(*FPI.getArgOperand(1)));
19915ffd83dbSDimitry Andric   if (FPI.isTernaryOp())
19925ffd83dbSDimitry Andric     VRegs.push_back(getOrCreateVReg(*FPI.getArgOperand(2)));
19935ffd83dbSDimitry Andric 
19945ffd83dbSDimitry Andric   MIRBuilder.buildInstr(Opcode, {getOrCreateVReg(FPI)}, VRegs, Flags);
19955ffd83dbSDimitry Andric   return true;
19965ffd83dbSDimitry Andric }
19975ffd83dbSDimitry Andric 
getArgPhysReg(Argument & Arg)199806c3fb27SDimitry Andric std::optional<MCRegister> IRTranslator::getArgPhysReg(Argument &Arg) {
199906c3fb27SDimitry Andric   auto VRegs = getOrCreateVRegs(Arg);
200006c3fb27SDimitry Andric   if (VRegs.size() != 1)
200106c3fb27SDimitry Andric     return std::nullopt;
200206c3fb27SDimitry Andric 
200306c3fb27SDimitry Andric   // Arguments are lowered as a copy of a livein physical register.
200406c3fb27SDimitry Andric   auto *VRegDef = MF->getRegInfo().getVRegDef(VRegs[0]);
200506c3fb27SDimitry Andric   if (!VRegDef || !VRegDef->isCopy())
200606c3fb27SDimitry Andric     return std::nullopt;
200706c3fb27SDimitry Andric   return VRegDef->getOperand(1).getReg().asMCReg();
200806c3fb27SDimitry Andric }
200906c3fb27SDimitry Andric 
translateIfEntryValueArgument(bool isDeclare,Value * Val,const DILocalVariable * Var,const DIExpression * Expr,const DebugLoc & DL,MachineIRBuilder & MIRBuilder)20107a6dacacSDimitry Andric bool IRTranslator::translateIfEntryValueArgument(bool isDeclare, Value *Val,
20117a6dacacSDimitry Andric                                                  const DILocalVariable *Var,
20127a6dacacSDimitry Andric                                                  const DIExpression *Expr,
20137a6dacacSDimitry Andric                                                  const DebugLoc &DL,
201406c3fb27SDimitry Andric                                                  MachineIRBuilder &MIRBuilder) {
20157a6dacacSDimitry Andric   auto *Arg = dyn_cast<Argument>(Val);
201606c3fb27SDimitry Andric   if (!Arg)
201706c3fb27SDimitry Andric     return false;
201806c3fb27SDimitry Andric 
201906c3fb27SDimitry Andric   if (!Expr->isEntryValue())
202006c3fb27SDimitry Andric     return false;
202106c3fb27SDimitry Andric 
202206c3fb27SDimitry Andric   std::optional<MCRegister> PhysReg = getArgPhysReg(*Arg);
202306c3fb27SDimitry Andric   if (!PhysReg) {
20247a6dacacSDimitry Andric     LLVM_DEBUG(dbgs() << "Dropping dbg." << (isDeclare ? "declare" : "value")
20257a6dacacSDimitry Andric                       << ": expression is entry_value but "
20267a6dacacSDimitry Andric                       << "couldn't find a physical register\n");
20277a6dacacSDimitry Andric     LLVM_DEBUG(dbgs() << *Var << "\n");
202806c3fb27SDimitry Andric     return true;
202906c3fb27SDimitry Andric   }
203006c3fb27SDimitry Andric 
20317a6dacacSDimitry Andric   if (isDeclare) {
20325f757f3fSDimitry Andric     // Append an op deref to account for the fact that this is a dbg_declare.
20335f757f3fSDimitry Andric     Expr = DIExpression::append(Expr, dwarf::DW_OP_deref);
20347a6dacacSDimitry Andric     MF->setVariableDbgInfo(Var, Expr, *PhysReg, DL);
20357a6dacacSDimitry Andric   } else {
20367a6dacacSDimitry Andric     MIRBuilder.buildDirectDbgValue(*PhysReg, Var, Expr);
20377a6dacacSDimitry Andric   }
20387a6dacacSDimitry Andric 
203906c3fb27SDimitry Andric   return true;
204006c3fb27SDimitry Andric }
204106c3fb27SDimitry Andric 
translateKnownIntrinsic(const CallInst & CI,Intrinsic::ID ID,MachineIRBuilder & MIRBuilder)20420b57cec5SDimitry Andric bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
20430b57cec5SDimitry Andric                                            MachineIRBuilder &MIRBuilder) {
2044fe6060f1SDimitry Andric   if (auto *MI = dyn_cast<AnyMemIntrinsic>(&CI)) {
2045fe6060f1SDimitry Andric     if (ORE->enabled()) {
2046bdd1243dSDimitry Andric       if (MemoryOpRemark::canHandle(MI, *LibInfo)) {
2047bdd1243dSDimitry Andric         MemoryOpRemark R(*ORE, "gisel-irtranslator-memsize", *DL, *LibInfo);
2048fe6060f1SDimitry Andric         R.visit(MI);
2049fe6060f1SDimitry Andric       }
2050fe6060f1SDimitry Andric     }
2051fe6060f1SDimitry Andric   }
20520b57cec5SDimitry Andric 
20530b57cec5SDimitry Andric   // If this is a simple intrinsic (that is, we just need to add a def of
20540b57cec5SDimitry Andric   // a vreg, and uses for each arg operand, then translate it.
20550b57cec5SDimitry Andric   if (translateSimpleIntrinsic(CI, ID, MIRBuilder))
20560b57cec5SDimitry Andric     return true;
20570b57cec5SDimitry Andric 
20580b57cec5SDimitry Andric   switch (ID) {
20590b57cec5SDimitry Andric   default:
20600b57cec5SDimitry Andric     break;
20610b57cec5SDimitry Andric   case Intrinsic::lifetime_start:
20620b57cec5SDimitry Andric   case Intrinsic::lifetime_end: {
20630b57cec5SDimitry Andric     // No stack colouring in O0, discard region information.
20645f757f3fSDimitry Andric     if (MF->getTarget().getOptLevel() == CodeGenOptLevel::None)
20650b57cec5SDimitry Andric       return true;
20660b57cec5SDimitry Andric 
20670b57cec5SDimitry Andric     unsigned Op = ID == Intrinsic::lifetime_start ? TargetOpcode::LIFETIME_START
20680b57cec5SDimitry Andric                                                   : TargetOpcode::LIFETIME_END;
20690b57cec5SDimitry Andric 
20700b57cec5SDimitry Andric     // Get the underlying objects for the location passed on the lifetime
20710b57cec5SDimitry Andric     // marker.
20720b57cec5SDimitry Andric     SmallVector<const Value *, 4> Allocas;
2073e8d8bef9SDimitry Andric     getUnderlyingObjects(CI.getArgOperand(1), Allocas);
20740b57cec5SDimitry Andric 
20750b57cec5SDimitry Andric     // Iterate over each underlying object, creating lifetime markers for each
20760b57cec5SDimitry Andric     // static alloca. Quit if we find a non-static alloca.
20770b57cec5SDimitry Andric     for (const Value *V : Allocas) {
20780b57cec5SDimitry Andric       const AllocaInst *AI = dyn_cast<AllocaInst>(V);
20790b57cec5SDimitry Andric       if (!AI)
20800b57cec5SDimitry Andric         continue;
20810b57cec5SDimitry Andric 
20820b57cec5SDimitry Andric       if (!AI->isStaticAlloca())
20830b57cec5SDimitry Andric         return true;
20840b57cec5SDimitry Andric 
20850b57cec5SDimitry Andric       MIRBuilder.buildInstr(Op).addFrameIndex(getOrCreateFrameIndex(*AI));
20860b57cec5SDimitry Andric     }
20870b57cec5SDimitry Andric     return true;
20880b57cec5SDimitry Andric   }
20890b57cec5SDimitry Andric   case Intrinsic::dbg_declare: {
20900b57cec5SDimitry Andric     const DbgDeclareInst &DI = cast<DbgDeclareInst>(CI);
20910b57cec5SDimitry Andric     assert(DI.getVariable() && "Missing variable");
20927a6dacacSDimitry Andric     translateDbgDeclareRecord(DI.getAddress(), DI.hasArgList(), DI.getVariable(),
20937a6dacacSDimitry Andric                        DI.getExpression(), DI.getDebugLoc(), MIRBuilder);
20940b57cec5SDimitry Andric     return true;
20950b57cec5SDimitry Andric   }
20960b57cec5SDimitry Andric   case Intrinsic::dbg_label: {
20970b57cec5SDimitry Andric     const DbgLabelInst &DI = cast<DbgLabelInst>(CI);
20980b57cec5SDimitry Andric     assert(DI.getLabel() && "Missing label");
20990b57cec5SDimitry Andric 
21000b57cec5SDimitry Andric     assert(DI.getLabel()->isValidLocationForIntrinsic(
21010b57cec5SDimitry Andric                MIRBuilder.getDebugLoc()) &&
21020b57cec5SDimitry Andric            "Expected inlined-at fields to agree");
21030b57cec5SDimitry Andric 
21040b57cec5SDimitry Andric     MIRBuilder.buildDbgLabel(DI.getLabel());
21050b57cec5SDimitry Andric     return true;
21060b57cec5SDimitry Andric   }
21070b57cec5SDimitry Andric   case Intrinsic::vaend:
21080b57cec5SDimitry Andric     // No target I know of cares about va_end. Certainly no in-tree target
21090b57cec5SDimitry Andric     // does. Simplest intrinsic ever!
21100b57cec5SDimitry Andric     return true;
21110b57cec5SDimitry Andric   case Intrinsic::vastart: {
21120b57cec5SDimitry Andric     auto &TLI = *MF->getSubtarget().getTargetLowering();
21130b57cec5SDimitry Andric     Value *Ptr = CI.getArgOperand(0);
21140b57cec5SDimitry Andric     unsigned ListSize = TLI.getVaListSizeInBits(*DL) / 8;
21155f757f3fSDimitry Andric     Align Alignment = getKnownAlignment(Ptr, *DL);
21160b57cec5SDimitry Andric 
21175ffd83dbSDimitry Andric     MIRBuilder.buildInstr(TargetOpcode::G_VASTART, {}, {getOrCreateVReg(*Ptr)})
21185ffd83dbSDimitry Andric         .addMemOperand(MF->getMachineMemOperand(MachinePointerInfo(Ptr),
21195ffd83dbSDimitry Andric                                                 MachineMemOperand::MOStore,
21205f757f3fSDimitry Andric                                                 ListSize, Alignment));
21210b57cec5SDimitry Andric     return true;
21220b57cec5SDimitry Andric   }
21230b57cec5SDimitry Andric   case Intrinsic::dbg_value: {
21240b57cec5SDimitry Andric     // This form of DBG_VALUE is target-independent.
21250b57cec5SDimitry Andric     const DbgValueInst &DI = cast<DbgValueInst>(CI);
21267a6dacacSDimitry Andric     translateDbgValueRecord(DI.getValue(), DI.hasArgList(), DI.getVariable(),
21277a6dacacSDimitry Andric                        DI.getExpression(), DI.getDebugLoc(), MIRBuilder);
21280b57cec5SDimitry Andric     return true;
21290b57cec5SDimitry Andric   }
21300b57cec5SDimitry Andric   case Intrinsic::uadd_with_overflow:
21310b57cec5SDimitry Andric     return translateOverflowIntrinsic(CI, TargetOpcode::G_UADDO, MIRBuilder);
21320b57cec5SDimitry Andric   case Intrinsic::sadd_with_overflow:
21330b57cec5SDimitry Andric     return translateOverflowIntrinsic(CI, TargetOpcode::G_SADDO, MIRBuilder);
21340b57cec5SDimitry Andric   case Intrinsic::usub_with_overflow:
21350b57cec5SDimitry Andric     return translateOverflowIntrinsic(CI, TargetOpcode::G_USUBO, MIRBuilder);
21360b57cec5SDimitry Andric   case Intrinsic::ssub_with_overflow:
21370b57cec5SDimitry Andric     return translateOverflowIntrinsic(CI, TargetOpcode::G_SSUBO, MIRBuilder);
21380b57cec5SDimitry Andric   case Intrinsic::umul_with_overflow:
21390b57cec5SDimitry Andric     return translateOverflowIntrinsic(CI, TargetOpcode::G_UMULO, MIRBuilder);
21400b57cec5SDimitry Andric   case Intrinsic::smul_with_overflow:
21410b57cec5SDimitry Andric     return translateOverflowIntrinsic(CI, TargetOpcode::G_SMULO, MIRBuilder);
21425ffd83dbSDimitry Andric   case Intrinsic::uadd_sat:
21435ffd83dbSDimitry Andric     return translateBinaryOp(TargetOpcode::G_UADDSAT, CI, MIRBuilder);
21445ffd83dbSDimitry Andric   case Intrinsic::sadd_sat:
21455ffd83dbSDimitry Andric     return translateBinaryOp(TargetOpcode::G_SADDSAT, CI, MIRBuilder);
21465ffd83dbSDimitry Andric   case Intrinsic::usub_sat:
21475ffd83dbSDimitry Andric     return translateBinaryOp(TargetOpcode::G_USUBSAT, CI, MIRBuilder);
21485ffd83dbSDimitry Andric   case Intrinsic::ssub_sat:
21495ffd83dbSDimitry Andric     return translateBinaryOp(TargetOpcode::G_SSUBSAT, CI, MIRBuilder);
2150e8d8bef9SDimitry Andric   case Intrinsic::ushl_sat:
2151e8d8bef9SDimitry Andric     return translateBinaryOp(TargetOpcode::G_USHLSAT, CI, MIRBuilder);
2152e8d8bef9SDimitry Andric   case Intrinsic::sshl_sat:
2153e8d8bef9SDimitry Andric     return translateBinaryOp(TargetOpcode::G_SSHLSAT, CI, MIRBuilder);
2154e8d8bef9SDimitry Andric   case Intrinsic::umin:
2155e8d8bef9SDimitry Andric     return translateBinaryOp(TargetOpcode::G_UMIN, CI, MIRBuilder);
2156e8d8bef9SDimitry Andric   case Intrinsic::umax:
2157e8d8bef9SDimitry Andric     return translateBinaryOp(TargetOpcode::G_UMAX, CI, MIRBuilder);
2158e8d8bef9SDimitry Andric   case Intrinsic::smin:
2159e8d8bef9SDimitry Andric     return translateBinaryOp(TargetOpcode::G_SMIN, CI, MIRBuilder);
2160e8d8bef9SDimitry Andric   case Intrinsic::smax:
2161e8d8bef9SDimitry Andric     return translateBinaryOp(TargetOpcode::G_SMAX, CI, MIRBuilder);
2162e8d8bef9SDimitry Andric   case Intrinsic::abs:
2163e8d8bef9SDimitry Andric     // TODO: Preserve "int min is poison" arg in GMIR?
2164e8d8bef9SDimitry Andric     return translateUnaryOp(TargetOpcode::G_ABS, CI, MIRBuilder);
2165e8d8bef9SDimitry Andric   case Intrinsic::smul_fix:
2166e8d8bef9SDimitry Andric     return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIX, CI, MIRBuilder);
2167e8d8bef9SDimitry Andric   case Intrinsic::umul_fix:
2168e8d8bef9SDimitry Andric     return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIX, CI, MIRBuilder);
2169e8d8bef9SDimitry Andric   case Intrinsic::smul_fix_sat:
2170e8d8bef9SDimitry Andric     return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIXSAT, CI, MIRBuilder);
2171e8d8bef9SDimitry Andric   case Intrinsic::umul_fix_sat:
2172e8d8bef9SDimitry Andric     return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIXSAT, CI, MIRBuilder);
2173e8d8bef9SDimitry Andric   case Intrinsic::sdiv_fix:
2174e8d8bef9SDimitry Andric     return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIX, CI, MIRBuilder);
2175e8d8bef9SDimitry Andric   case Intrinsic::udiv_fix:
2176e8d8bef9SDimitry Andric     return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIX, CI, MIRBuilder);
2177e8d8bef9SDimitry Andric   case Intrinsic::sdiv_fix_sat:
2178e8d8bef9SDimitry Andric     return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIXSAT, CI, MIRBuilder);
2179e8d8bef9SDimitry Andric   case Intrinsic::udiv_fix_sat:
2180e8d8bef9SDimitry Andric     return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIXSAT, CI, MIRBuilder);
21810b57cec5SDimitry Andric   case Intrinsic::fmuladd: {
21820b57cec5SDimitry Andric     const TargetMachine &TM = MF->getTarget();
21830b57cec5SDimitry Andric     const TargetLowering &TLI = *MF->getSubtarget().getTargetLowering();
21840b57cec5SDimitry Andric     Register Dst = getOrCreateVReg(CI);
21850b57cec5SDimitry Andric     Register Op0 = getOrCreateVReg(*CI.getArgOperand(0));
21860b57cec5SDimitry Andric     Register Op1 = getOrCreateVReg(*CI.getArgOperand(1));
21870b57cec5SDimitry Andric     Register Op2 = getOrCreateVReg(*CI.getArgOperand(2));
21880b57cec5SDimitry Andric     if (TM.Options.AllowFPOpFusion != FPOpFusion::Strict &&
2189480093f4SDimitry Andric         TLI.isFMAFasterThanFMulAndFAdd(*MF,
2190480093f4SDimitry Andric                                        TLI.getValueType(*DL, CI.getType()))) {
21910b57cec5SDimitry Andric       // TODO: Revisit this to see if we should move this part of the
21920b57cec5SDimitry Andric       // lowering to the combiner.
21935ffd83dbSDimitry Andric       MIRBuilder.buildFMA(Dst, Op0, Op1, Op2,
21940b57cec5SDimitry Andric                           MachineInstr::copyFlagsFromInstruction(CI));
21950b57cec5SDimitry Andric     } else {
21960b57cec5SDimitry Andric       LLT Ty = getLLTForType(*CI.getType(), *DL);
21975ffd83dbSDimitry Andric       auto FMul = MIRBuilder.buildFMul(
21985ffd83dbSDimitry Andric           Ty, Op0, Op1, MachineInstr::copyFlagsFromInstruction(CI));
21995ffd83dbSDimitry Andric       MIRBuilder.buildFAdd(Dst, FMul, Op2,
22000b57cec5SDimitry Andric                            MachineInstr::copyFlagsFromInstruction(CI));
22010b57cec5SDimitry Andric     }
22020b57cec5SDimitry Andric     return true;
22030b57cec5SDimitry Andric   }
2204e8d8bef9SDimitry Andric   case Intrinsic::convert_from_fp16:
2205e8d8bef9SDimitry Andric     // FIXME: This intrinsic should probably be removed from the IR.
2206e8d8bef9SDimitry Andric     MIRBuilder.buildFPExt(getOrCreateVReg(CI),
2207e8d8bef9SDimitry Andric                           getOrCreateVReg(*CI.getArgOperand(0)),
2208e8d8bef9SDimitry Andric                           MachineInstr::copyFlagsFromInstruction(CI));
2209e8d8bef9SDimitry Andric     return true;
2210e8d8bef9SDimitry Andric   case Intrinsic::convert_to_fp16:
2211e8d8bef9SDimitry Andric     // FIXME: This intrinsic should probably be removed from the IR.
2212e8d8bef9SDimitry Andric     MIRBuilder.buildFPTrunc(getOrCreateVReg(CI),
2213e8d8bef9SDimitry Andric                             getOrCreateVReg(*CI.getArgOperand(0)),
2214e8d8bef9SDimitry Andric                             MachineInstr::copyFlagsFromInstruction(CI));
2215e8d8bef9SDimitry Andric     return true;
221606c3fb27SDimitry Andric   case Intrinsic::frexp: {
221706c3fb27SDimitry Andric     ArrayRef<Register> VRegs = getOrCreateVRegs(CI);
221806c3fb27SDimitry Andric     MIRBuilder.buildFFrexp(VRegs[0], VRegs[1],
221906c3fb27SDimitry Andric                            getOrCreateVReg(*CI.getArgOperand(0)),
222006c3fb27SDimitry Andric                            MachineInstr::copyFlagsFromInstruction(CI));
222106c3fb27SDimitry Andric     return true;
222206c3fb27SDimitry Andric   }
2223fe6060f1SDimitry Andric   case Intrinsic::memcpy_inline:
2224fe6060f1SDimitry Andric     return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY_INLINE);
22250b57cec5SDimitry Andric   case Intrinsic::memcpy:
2226e8d8bef9SDimitry Andric     return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY);
22270b57cec5SDimitry Andric   case Intrinsic::memmove:
2228e8d8bef9SDimitry Andric     return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMMOVE);
22290b57cec5SDimitry Andric   case Intrinsic::memset:
2230e8d8bef9SDimitry Andric     return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET);
22310b57cec5SDimitry Andric   case Intrinsic::eh_typeid_for: {
22320b57cec5SDimitry Andric     GlobalValue *GV = ExtractTypeInfo(CI.getArgOperand(0));
22330b57cec5SDimitry Andric     Register Reg = getOrCreateVReg(CI);
22340b57cec5SDimitry Andric     unsigned TypeID = MF->getTypeIDFor(GV);
22350b57cec5SDimitry Andric     MIRBuilder.buildConstant(Reg, TypeID);
22360b57cec5SDimitry Andric     return true;
22370b57cec5SDimitry Andric   }
22388bcb0991SDimitry Andric   case Intrinsic::objectsize:
22398bcb0991SDimitry Andric     llvm_unreachable("llvm.objectsize.* should have been lowered already");
22400b57cec5SDimitry Andric 
22410b57cec5SDimitry Andric   case Intrinsic::is_constant:
22428bcb0991SDimitry Andric     llvm_unreachable("llvm.is.constant.* should have been lowered already");
22438bcb0991SDimitry Andric 
22440b57cec5SDimitry Andric   case Intrinsic::stackguard:
22450b57cec5SDimitry Andric     getStackGuard(getOrCreateVReg(CI), MIRBuilder);
22460b57cec5SDimitry Andric     return true;
22470b57cec5SDimitry Andric   case Intrinsic::stackprotector: {
2248753f127fSDimitry Andric     const TargetLowering &TLI = *MF->getSubtarget().getTargetLowering();
22490b57cec5SDimitry Andric     LLT PtrTy = getLLTForType(*CI.getArgOperand(0)->getType(), *DL);
2250753f127fSDimitry Andric     Register GuardVal;
2251753f127fSDimitry Andric     if (TLI.useLoadStackGuardNode()) {
2252753f127fSDimitry Andric       GuardVal = MRI->createGenericVirtualRegister(PtrTy);
22530b57cec5SDimitry Andric       getStackGuard(GuardVal, MIRBuilder);
2254753f127fSDimitry Andric     } else
2255753f127fSDimitry Andric       GuardVal = getOrCreateVReg(*CI.getArgOperand(0)); // The guard's value.
22560b57cec5SDimitry Andric 
22570b57cec5SDimitry Andric     AllocaInst *Slot = cast<AllocaInst>(CI.getArgOperand(1));
22580b57cec5SDimitry Andric     int FI = getOrCreateFrameIndex(*Slot);
22590b57cec5SDimitry Andric     MF->getFrameInfo().setStackProtectorIndex(FI);
22600b57cec5SDimitry Andric 
22610b57cec5SDimitry Andric     MIRBuilder.buildStore(
22620b57cec5SDimitry Andric         GuardVal, getOrCreateVReg(*Slot),
22630b57cec5SDimitry Andric         *MF->getMachineMemOperand(MachinePointerInfo::getFixedStack(*MF, FI),
22640b57cec5SDimitry Andric                                   MachineMemOperand::MOStore |
22650b57cec5SDimitry Andric                                       MachineMemOperand::MOVolatile,
2266fe6060f1SDimitry Andric                                   PtrTy, Align(8)));
22670b57cec5SDimitry Andric     return true;
22680b57cec5SDimitry Andric   }
22690b57cec5SDimitry Andric   case Intrinsic::stacksave: {
22705f757f3fSDimitry Andric     MIRBuilder.buildInstr(TargetOpcode::G_STACKSAVE, {getOrCreateVReg(CI)}, {});
22710b57cec5SDimitry Andric     return true;
22720b57cec5SDimitry Andric   }
22730b57cec5SDimitry Andric   case Intrinsic::stackrestore: {
22745f757f3fSDimitry Andric     MIRBuilder.buildInstr(TargetOpcode::G_STACKRESTORE, {},
22755f757f3fSDimitry Andric                           {getOrCreateVReg(*CI.getArgOperand(0))});
22760b57cec5SDimitry Andric     return true;
22770b57cec5SDimitry Andric   }
22780b57cec5SDimitry Andric   case Intrinsic::cttz:
22790b57cec5SDimitry Andric   case Intrinsic::ctlz: {
22800b57cec5SDimitry Andric     ConstantInt *Cst = cast<ConstantInt>(CI.getArgOperand(1));
22810b57cec5SDimitry Andric     bool isTrailing = ID == Intrinsic::cttz;
22820b57cec5SDimitry Andric     unsigned Opcode = isTrailing
22830b57cec5SDimitry Andric                           ? Cst->isZero() ? TargetOpcode::G_CTTZ
22840b57cec5SDimitry Andric                                           : TargetOpcode::G_CTTZ_ZERO_UNDEF
22850b57cec5SDimitry Andric                           : Cst->isZero() ? TargetOpcode::G_CTLZ
22860b57cec5SDimitry Andric                                           : TargetOpcode::G_CTLZ_ZERO_UNDEF;
22875ffd83dbSDimitry Andric     MIRBuilder.buildInstr(Opcode, {getOrCreateVReg(CI)},
22885ffd83dbSDimitry Andric                           {getOrCreateVReg(*CI.getArgOperand(0))});
22890b57cec5SDimitry Andric     return true;
22900b57cec5SDimitry Andric   }
22910b57cec5SDimitry Andric   case Intrinsic::invariant_start: {
22920b57cec5SDimitry Andric     LLT PtrTy = getLLTForType(*CI.getArgOperand(0)->getType(), *DL);
22930b57cec5SDimitry Andric     Register Undef = MRI->createGenericVirtualRegister(PtrTy);
22940b57cec5SDimitry Andric     MIRBuilder.buildUndef(Undef);
22950b57cec5SDimitry Andric     return true;
22960b57cec5SDimitry Andric   }
22970b57cec5SDimitry Andric   case Intrinsic::invariant_end:
22980b57cec5SDimitry Andric     return true;
2299e8d8bef9SDimitry Andric   case Intrinsic::expect:
2300e8d8bef9SDimitry Andric   case Intrinsic::annotation:
2301e8d8bef9SDimitry Andric   case Intrinsic::ptr_annotation:
2302e8d8bef9SDimitry Andric   case Intrinsic::launder_invariant_group:
2303e8d8bef9SDimitry Andric   case Intrinsic::strip_invariant_group: {
2304e8d8bef9SDimitry Andric     // Drop the intrinsic, but forward the value.
2305e8d8bef9SDimitry Andric     MIRBuilder.buildCopy(getOrCreateVReg(CI),
2306e8d8bef9SDimitry Andric                          getOrCreateVReg(*CI.getArgOperand(0)));
2307e8d8bef9SDimitry Andric     return true;
2308e8d8bef9SDimitry Andric   }
23090b57cec5SDimitry Andric   case Intrinsic::assume:
2310e8d8bef9SDimitry Andric   case Intrinsic::experimental_noalias_scope_decl:
23110b57cec5SDimitry Andric   case Intrinsic::var_annotation:
23120b57cec5SDimitry Andric   case Intrinsic::sideeffect:
23130b57cec5SDimitry Andric     // Discard annotate attributes, assumptions, and artificial side-effects.
23140b57cec5SDimitry Andric     return true;
23155ffd83dbSDimitry Andric   case Intrinsic::read_volatile_register:
2316480093f4SDimitry Andric   case Intrinsic::read_register: {
2317480093f4SDimitry Andric     Value *Arg = CI.getArgOperand(0);
23185ffd83dbSDimitry Andric     MIRBuilder
23195ffd83dbSDimitry Andric         .buildInstr(TargetOpcode::G_READ_REGISTER, {getOrCreateVReg(CI)}, {})
2320480093f4SDimitry Andric         .addMetadata(cast<MDNode>(cast<MetadataAsValue>(Arg)->getMetadata()));
2321480093f4SDimitry Andric     return true;
2322480093f4SDimitry Andric   }
23235ffd83dbSDimitry Andric   case Intrinsic::write_register: {
23245ffd83dbSDimitry Andric     Value *Arg = CI.getArgOperand(0);
23255ffd83dbSDimitry Andric     MIRBuilder.buildInstr(TargetOpcode::G_WRITE_REGISTER)
23265ffd83dbSDimitry Andric       .addMetadata(cast<MDNode>(cast<MetadataAsValue>(Arg)->getMetadata()))
23275ffd83dbSDimitry Andric       .addUse(getOrCreateVReg(*CI.getArgOperand(1)));
23280b57cec5SDimitry Andric     return true;
23290b57cec5SDimitry Andric   }
2330e8d8bef9SDimitry Andric   case Intrinsic::localescape: {
2331e8d8bef9SDimitry Andric     MachineBasicBlock &EntryMBB = MF->front();
2332e8d8bef9SDimitry Andric     StringRef EscapedName = GlobalValue::dropLLVMManglingEscape(MF->getName());
2333e8d8bef9SDimitry Andric 
2334e8d8bef9SDimitry Andric     // Directly emit some LOCAL_ESCAPE machine instrs. Label assignment emission
2335e8d8bef9SDimitry Andric     // is the same on all targets.
2336349cc55cSDimitry Andric     for (unsigned Idx = 0, E = CI.arg_size(); Idx < E; ++Idx) {
2337e8d8bef9SDimitry Andric       Value *Arg = CI.getArgOperand(Idx)->stripPointerCasts();
2338e8d8bef9SDimitry Andric       if (isa<ConstantPointerNull>(Arg))
2339e8d8bef9SDimitry Andric         continue; // Skip null pointers. They represent a hole in index space.
2340e8d8bef9SDimitry Andric 
2341e8d8bef9SDimitry Andric       int FI = getOrCreateFrameIndex(*cast<AllocaInst>(Arg));
2342e8d8bef9SDimitry Andric       MCSymbol *FrameAllocSym =
2343e8d8bef9SDimitry Andric           MF->getMMI().getContext().getOrCreateFrameAllocSymbol(EscapedName,
2344e8d8bef9SDimitry Andric                                                                 Idx);
2345e8d8bef9SDimitry Andric 
2346e8d8bef9SDimitry Andric       // This should be inserted at the start of the entry block.
2347e8d8bef9SDimitry Andric       auto LocalEscape =
2348e8d8bef9SDimitry Andric           MIRBuilder.buildInstrNoInsert(TargetOpcode::LOCAL_ESCAPE)
2349e8d8bef9SDimitry Andric               .addSym(FrameAllocSym)
2350e8d8bef9SDimitry Andric               .addFrameIndex(FI);
2351e8d8bef9SDimitry Andric 
2352e8d8bef9SDimitry Andric       EntryMBB.insert(EntryMBB.begin(), LocalEscape);
2353e8d8bef9SDimitry Andric     }
2354e8d8bef9SDimitry Andric 
2355e8d8bef9SDimitry Andric     return true;
2356e8d8bef9SDimitry Andric   }
2357e8d8bef9SDimitry Andric   case Intrinsic::vector_reduce_fadd:
2358e8d8bef9SDimitry Andric   case Intrinsic::vector_reduce_fmul: {
2359e8d8bef9SDimitry Andric     // Need to check for the reassoc flag to decide whether we want a
2360e8d8bef9SDimitry Andric     // sequential reduction opcode or not.
2361e8d8bef9SDimitry Andric     Register Dst = getOrCreateVReg(CI);
2362e8d8bef9SDimitry Andric     Register ScalarSrc = getOrCreateVReg(*CI.getArgOperand(0));
2363e8d8bef9SDimitry Andric     Register VecSrc = getOrCreateVReg(*CI.getArgOperand(1));
2364e8d8bef9SDimitry Andric     unsigned Opc = 0;
2365e8d8bef9SDimitry Andric     if (!CI.hasAllowReassoc()) {
2366e8d8bef9SDimitry Andric       // The sequential ordering case.
2367e8d8bef9SDimitry Andric       Opc = ID == Intrinsic::vector_reduce_fadd
2368e8d8bef9SDimitry Andric                 ? TargetOpcode::G_VECREDUCE_SEQ_FADD
2369e8d8bef9SDimitry Andric                 : TargetOpcode::G_VECREDUCE_SEQ_FMUL;
2370e8d8bef9SDimitry Andric       MIRBuilder.buildInstr(Opc, {Dst}, {ScalarSrc, VecSrc},
2371e8d8bef9SDimitry Andric                             MachineInstr::copyFlagsFromInstruction(CI));
2372e8d8bef9SDimitry Andric       return true;
2373e8d8bef9SDimitry Andric     }
2374e8d8bef9SDimitry Andric     // We split the operation into a separate G_FADD/G_FMUL + the reduce,
2375e8d8bef9SDimitry Andric     // since the associativity doesn't matter.
2376e8d8bef9SDimitry Andric     unsigned ScalarOpc;
2377e8d8bef9SDimitry Andric     if (ID == Intrinsic::vector_reduce_fadd) {
2378e8d8bef9SDimitry Andric       Opc = TargetOpcode::G_VECREDUCE_FADD;
2379e8d8bef9SDimitry Andric       ScalarOpc = TargetOpcode::G_FADD;
2380e8d8bef9SDimitry Andric     } else {
2381e8d8bef9SDimitry Andric       Opc = TargetOpcode::G_VECREDUCE_FMUL;
2382e8d8bef9SDimitry Andric       ScalarOpc = TargetOpcode::G_FMUL;
2383e8d8bef9SDimitry Andric     }
2384e8d8bef9SDimitry Andric     LLT DstTy = MRI->getType(Dst);
2385e8d8bef9SDimitry Andric     auto Rdx = MIRBuilder.buildInstr(
2386e8d8bef9SDimitry Andric         Opc, {DstTy}, {VecSrc}, MachineInstr::copyFlagsFromInstruction(CI));
2387e8d8bef9SDimitry Andric     MIRBuilder.buildInstr(ScalarOpc, {Dst}, {ScalarSrc, Rdx},
2388e8d8bef9SDimitry Andric                           MachineInstr::copyFlagsFromInstruction(CI));
2389e8d8bef9SDimitry Andric 
2390e8d8bef9SDimitry Andric     return true;
2391e8d8bef9SDimitry Andric   }
2392349cc55cSDimitry Andric   case Intrinsic::trap:
2393349cc55cSDimitry Andric   case Intrinsic::debugtrap:
2394349cc55cSDimitry Andric   case Intrinsic::ubsantrap: {
2395349cc55cSDimitry Andric     StringRef TrapFuncName =
2396349cc55cSDimitry Andric         CI.getAttributes().getFnAttr("trap-func-name").getValueAsString();
2397349cc55cSDimitry Andric     if (TrapFuncName.empty())
2398349cc55cSDimitry Andric       break; // Use the default handling.
2399349cc55cSDimitry Andric     CallLowering::CallLoweringInfo Info;
2400349cc55cSDimitry Andric     if (ID == Intrinsic::ubsantrap) {
2401349cc55cSDimitry Andric       Info.OrigArgs.push_back({getOrCreateVRegs(*CI.getArgOperand(0)),
2402349cc55cSDimitry Andric                                CI.getArgOperand(0)->getType(), 0});
2403349cc55cSDimitry Andric     }
2404349cc55cSDimitry Andric     Info.Callee = MachineOperand::CreateES(TrapFuncName.data());
2405349cc55cSDimitry Andric     Info.CB = &CI;
2406349cc55cSDimitry Andric     Info.OrigRet = {Register(), Type::getVoidTy(CI.getContext()), 0};
2407349cc55cSDimitry Andric     return CLI->lowerCall(MIRBuilder, Info);
2408349cc55cSDimitry Andric   }
24095f757f3fSDimitry Andric   case Intrinsic::amdgcn_cs_chain:
24105f757f3fSDimitry Andric     return translateCallBase(CI, MIRBuilder);
241181ad6265SDimitry Andric   case Intrinsic::fptrunc_round: {
241206c3fb27SDimitry Andric     uint32_t Flags = MachineInstr::copyFlagsFromInstruction(CI);
241381ad6265SDimitry Andric 
241481ad6265SDimitry Andric     // Convert the metadata argument to a constant integer
241581ad6265SDimitry Andric     Metadata *MD = cast<MetadataAsValue>(CI.getArgOperand(1))->getMetadata();
2416bdd1243dSDimitry Andric     std::optional<RoundingMode> RoundMode =
241781ad6265SDimitry Andric         convertStrToRoundingMode(cast<MDString>(MD)->getString());
241881ad6265SDimitry Andric 
241981ad6265SDimitry Andric     // Add the Rounding mode as an integer
242081ad6265SDimitry Andric     MIRBuilder
242181ad6265SDimitry Andric         .buildInstr(TargetOpcode::G_INTRINSIC_FPTRUNC_ROUND,
242281ad6265SDimitry Andric                     {getOrCreateVReg(CI)},
242381ad6265SDimitry Andric                     {getOrCreateVReg(*CI.getArgOperand(0))}, Flags)
242481ad6265SDimitry Andric         .addImm((int)*RoundMode);
242581ad6265SDimitry Andric 
242681ad6265SDimitry Andric     return true;
242781ad6265SDimitry Andric   }
2428bdd1243dSDimitry Andric   case Intrinsic::is_fpclass: {
2429bdd1243dSDimitry Andric     Value *FpValue = CI.getOperand(0);
2430bdd1243dSDimitry Andric     ConstantInt *TestMaskValue = cast<ConstantInt>(CI.getOperand(1));
2431bdd1243dSDimitry Andric 
2432bdd1243dSDimitry Andric     MIRBuilder
2433bdd1243dSDimitry Andric         .buildInstr(TargetOpcode::G_IS_FPCLASS, {getOrCreateVReg(CI)},
2434bdd1243dSDimitry Andric                     {getOrCreateVReg(*FpValue)})
2435bdd1243dSDimitry Andric         .addImm(TestMaskValue->getZExtValue());
2436bdd1243dSDimitry Andric 
2437bdd1243dSDimitry Andric     return true;
2438bdd1243dSDimitry Andric   }
2439297eecfbSDimitry Andric   case Intrinsic::set_fpenv: {
2440297eecfbSDimitry Andric     Value *FPEnv = CI.getOperand(0);
2441297eecfbSDimitry Andric     MIRBuilder.buildInstr(TargetOpcode::G_SET_FPENV, {},
2442297eecfbSDimitry Andric                           {getOrCreateVReg(*FPEnv)});
2443297eecfbSDimitry Andric     return true;
2444297eecfbSDimitry Andric   }
2445297eecfbSDimitry Andric   case Intrinsic::reset_fpenv: {
2446297eecfbSDimitry Andric     MIRBuilder.buildInstr(TargetOpcode::G_RESET_FPENV, {}, {});
2447297eecfbSDimitry Andric     return true;
2448297eecfbSDimitry Andric   }
24495f757f3fSDimitry Andric   case Intrinsic::set_fpmode: {
24505f757f3fSDimitry Andric     Value *FPState = CI.getOperand(0);
24515f757f3fSDimitry Andric     MIRBuilder.buildInstr(TargetOpcode::G_SET_FPMODE, {},
24525f757f3fSDimitry Andric                           { getOrCreateVReg(*FPState) });
24535f757f3fSDimitry Andric     return true;
24545f757f3fSDimitry Andric   }
24555f757f3fSDimitry Andric   case Intrinsic::reset_fpmode: {
24565f757f3fSDimitry Andric     MIRBuilder.buildInstr(TargetOpcode::G_RESET_FPMODE, {}, {});
24575f757f3fSDimitry Andric     return true;
24585f757f3fSDimitry Andric   }
24595f757f3fSDimitry Andric   case Intrinsic::prefetch: {
24605f757f3fSDimitry Andric     Value *Addr = CI.getOperand(0);
24615f757f3fSDimitry Andric     unsigned RW = cast<ConstantInt>(CI.getOperand(1))->getZExtValue();
24625f757f3fSDimitry Andric     unsigned Locality = cast<ConstantInt>(CI.getOperand(2))->getZExtValue();
24635f757f3fSDimitry Andric     unsigned CacheType = cast<ConstantInt>(CI.getOperand(3))->getZExtValue();
24645f757f3fSDimitry Andric 
24655f757f3fSDimitry Andric     auto Flags = RW ? MachineMemOperand::MOStore : MachineMemOperand::MOLoad;
24665f757f3fSDimitry Andric     auto &MMO = *MF->getMachineMemOperand(MachinePointerInfo(Addr), Flags,
24675f757f3fSDimitry Andric                                           LLT(), Align());
24685f757f3fSDimitry Andric 
24695f757f3fSDimitry Andric     MIRBuilder.buildPrefetch(getOrCreateVReg(*Addr), RW, Locality, CacheType,
24705f757f3fSDimitry Andric                              MMO);
24715f757f3fSDimitry Andric 
24725f757f3fSDimitry Andric     return true;
24735f757f3fSDimitry Andric   }
24745ffd83dbSDimitry Andric #define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC)  \
24755ffd83dbSDimitry Andric   case Intrinsic::INTRINSIC:
24765ffd83dbSDimitry Andric #include "llvm/IR/ConstrainedOps.def"
24775ffd83dbSDimitry Andric     return translateConstrainedFPIntrinsic(cast<ConstrainedFPIntrinsic>(CI),
24785ffd83dbSDimitry Andric                                            MIRBuilder);
24790b57cec5SDimitry Andric 
24805ffd83dbSDimitry Andric   }
24815ffd83dbSDimitry Andric   return false;
24825ffd83dbSDimitry Andric }
24835ffd83dbSDimitry Andric 
translateInlineAsm(const CallBase & CB,MachineIRBuilder & MIRBuilder)24845ffd83dbSDimitry Andric bool IRTranslator::translateInlineAsm(const CallBase &CB,
24858bcb0991SDimitry Andric                                       MachineIRBuilder &MIRBuilder) {
24865ffd83dbSDimitry Andric 
24875ffd83dbSDimitry Andric   const InlineAsmLowering *ALI = MF->getSubtarget().getInlineAsmLowering();
24885ffd83dbSDimitry Andric 
24895ffd83dbSDimitry Andric   if (!ALI) {
24905ffd83dbSDimitry Andric     LLVM_DEBUG(
24915ffd83dbSDimitry Andric         dbgs() << "Inline asm lowering is not supported for this target yet\n");
24925ffd83dbSDimitry Andric     return false;
24935ffd83dbSDimitry Andric   }
24945ffd83dbSDimitry Andric 
24955ffd83dbSDimitry Andric   return ALI->lowerInlineAsm(
24965ffd83dbSDimitry Andric       MIRBuilder, CB, [&](const Value &Val) { return getOrCreateVRegs(Val); });
24975ffd83dbSDimitry Andric }
24985ffd83dbSDimitry Andric 
translateCallBase(const CallBase & CB,MachineIRBuilder & MIRBuilder)24995ffd83dbSDimitry Andric bool IRTranslator::translateCallBase(const CallBase &CB,
25005ffd83dbSDimitry Andric                                      MachineIRBuilder &MIRBuilder) {
25015ffd83dbSDimitry Andric   ArrayRef<Register> Res = getOrCreateVRegs(CB);
25028bcb0991SDimitry Andric 
25038bcb0991SDimitry Andric   SmallVector<ArrayRef<Register>, 8> Args;
25048bcb0991SDimitry Andric   Register SwiftInVReg = 0;
25058bcb0991SDimitry Andric   Register SwiftErrorVReg = 0;
2506fcaf7f86SDimitry Andric   for (const auto &Arg : CB.args()) {
25078bcb0991SDimitry Andric     if (CLI->supportSwiftError() && isSwiftError(Arg)) {
25088bcb0991SDimitry Andric       assert(SwiftInVReg == 0 && "Expected only one swift error argument");
25098bcb0991SDimitry Andric       LLT Ty = getLLTForType(*Arg->getType(), *DL);
25108bcb0991SDimitry Andric       SwiftInVReg = MRI->createGenericVirtualRegister(Ty);
25118bcb0991SDimitry Andric       MIRBuilder.buildCopy(SwiftInVReg, SwiftError.getOrCreateVRegUseAt(
25125ffd83dbSDimitry Andric                                             &CB, &MIRBuilder.getMBB(), Arg));
2513bdd1243dSDimitry Andric       Args.emplace_back(ArrayRef(SwiftInVReg));
25148bcb0991SDimitry Andric       SwiftErrorVReg =
25155ffd83dbSDimitry Andric           SwiftError.getOrCreateVRegDefAt(&CB, &MIRBuilder.getMBB(), Arg);
25168bcb0991SDimitry Andric       continue;
25178bcb0991SDimitry Andric     }
25188bcb0991SDimitry Andric     Args.push_back(getOrCreateVRegs(*Arg));
25198bcb0991SDimitry Andric   }
25208bcb0991SDimitry Andric 
2521fe6060f1SDimitry Andric   if (auto *CI = dyn_cast<CallInst>(&CB)) {
2522fe6060f1SDimitry Andric     if (ORE->enabled()) {
2523bdd1243dSDimitry Andric       if (MemoryOpRemark::canHandle(CI, *LibInfo)) {
2524bdd1243dSDimitry Andric         MemoryOpRemark R(*ORE, "gisel-irtranslator-memsize", *DL, *LibInfo);
2525fe6060f1SDimitry Andric         R.visit(CI);
2526fe6060f1SDimitry Andric       }
2527fe6060f1SDimitry Andric     }
2528fe6060f1SDimitry Andric   }
2529fe6060f1SDimitry Andric 
25308bcb0991SDimitry Andric   // We don't set HasCalls on MFI here yet because call lowering may decide to
25318bcb0991SDimitry Andric   // optimize into tail calls. Instead, we defer that to selection where a final
25328bcb0991SDimitry Andric   // scan is done to check if any instructions are calls.
25338bcb0991SDimitry Andric   bool Success =
25345ffd83dbSDimitry Andric       CLI->lowerCall(MIRBuilder, CB, Res, Args, SwiftErrorVReg,
25355ffd83dbSDimitry Andric                      [&]() { return getOrCreateVReg(*CB.getCalledOperand()); });
25368bcb0991SDimitry Andric 
25378bcb0991SDimitry Andric   // Check if we just inserted a tail call.
25388bcb0991SDimitry Andric   if (Success) {
25398bcb0991SDimitry Andric     assert(!HasTailCall && "Can't tail call return twice from block?");
25408bcb0991SDimitry Andric     const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
25418bcb0991SDimitry Andric     HasTailCall = TII->isTailCall(*std::prev(MIRBuilder.getInsertPt()));
25428bcb0991SDimitry Andric   }
25438bcb0991SDimitry Andric 
25448bcb0991SDimitry Andric   return Success;
25458bcb0991SDimitry Andric }
25468bcb0991SDimitry Andric 
translateCall(const User & U,MachineIRBuilder & MIRBuilder)25470b57cec5SDimitry Andric bool IRTranslator::translateCall(const User &U, MachineIRBuilder &MIRBuilder) {
25480b57cec5SDimitry Andric   const CallInst &CI = cast<CallInst>(U);
25490b57cec5SDimitry Andric   auto TII = MF->getTarget().getIntrinsicInfo();
25500b57cec5SDimitry Andric   const Function *F = CI.getCalledFunction();
25510b57cec5SDimitry Andric 
25525f757f3fSDimitry Andric   // FIXME: support Windows dllimport function calls and calls through
25535f757f3fSDimitry Andric   // weak symbols.
2554480093f4SDimitry Andric   if (F && (F->hasDLLImportStorageClass() ||
2555480093f4SDimitry Andric             (MF->getTarget().getTargetTriple().isOSWindows() &&
2556480093f4SDimitry Andric              F->hasExternalWeakLinkage())))
2557480093f4SDimitry Andric     return false;
2558480093f4SDimitry Andric 
2559480093f4SDimitry Andric   // FIXME: support control flow guard targets.
2560480093f4SDimitry Andric   if (CI.countOperandBundlesOfType(LLVMContext::OB_cfguardtarget))
25610b57cec5SDimitry Andric     return false;
25620b57cec5SDimitry Andric 
2563bdd1243dSDimitry Andric   // FIXME: support statepoints and related.
2564bdd1243dSDimitry Andric   if (isa<GCStatepointInst, GCRelocateInst, GCResultInst>(U))
2565bdd1243dSDimitry Andric     return false;
2566bdd1243dSDimitry Andric 
25670b57cec5SDimitry Andric   if (CI.isInlineAsm())
25680b57cec5SDimitry Andric     return translateInlineAsm(CI, MIRBuilder);
25690b57cec5SDimitry Andric 
2570349cc55cSDimitry Andric   diagnoseDontCall(CI);
2571349cc55cSDimitry Andric 
25720b57cec5SDimitry Andric   Intrinsic::ID ID = Intrinsic::not_intrinsic;
25730b57cec5SDimitry Andric   if (F && F->isIntrinsic()) {
25740b57cec5SDimitry Andric     ID = F->getIntrinsicID();
25750b57cec5SDimitry Andric     if (TII && ID == Intrinsic::not_intrinsic)
25760b57cec5SDimitry Andric       ID = static_cast<Intrinsic::ID>(TII->getIntrinsicID(F));
25770b57cec5SDimitry Andric   }
25780b57cec5SDimitry Andric 
25798bcb0991SDimitry Andric   if (!F || !F->isIntrinsic() || ID == Intrinsic::not_intrinsic)
25805ffd83dbSDimitry Andric     return translateCallBase(CI, MIRBuilder);
25810b57cec5SDimitry Andric 
25820b57cec5SDimitry Andric   assert(ID != Intrinsic::not_intrinsic && "unknown intrinsic");
25830b57cec5SDimitry Andric 
25840b57cec5SDimitry Andric   if (translateKnownIntrinsic(CI, ID, MIRBuilder))
25850b57cec5SDimitry Andric     return true;
25860b57cec5SDimitry Andric 
25870b57cec5SDimitry Andric   ArrayRef<Register> ResultRegs;
25880b57cec5SDimitry Andric   if (!CI.getType()->isVoidTy())
25890b57cec5SDimitry Andric     ResultRegs = getOrCreateVRegs(CI);
25900b57cec5SDimitry Andric 
25910b57cec5SDimitry Andric   // Ignore the callsite attributes. Backend code is most likely not expecting
25920b57cec5SDimitry Andric   // an intrinsic to sometimes have side effects and sometimes not.
25935f757f3fSDimitry Andric   MachineInstrBuilder MIB = MIRBuilder.buildIntrinsic(ID, ResultRegs);
25940b57cec5SDimitry Andric   if (isa<FPMathOperator>(CI))
25950b57cec5SDimitry Andric     MIB->copyIRFlags(CI);
25960b57cec5SDimitry Andric 
2597fcaf7f86SDimitry Andric   for (const auto &Arg : enumerate(CI.args())) {
25988bcb0991SDimitry Andric     // If this is required to be an immediate, don't materialize it in a
25998bcb0991SDimitry Andric     // register.
26008bcb0991SDimitry Andric     if (CI.paramHasAttr(Arg.index(), Attribute::ImmArg)) {
26018bcb0991SDimitry Andric       if (ConstantInt *CI = dyn_cast<ConstantInt>(Arg.value())) {
26028bcb0991SDimitry Andric         // imm arguments are more convenient than cimm (and realistically
26038bcb0991SDimitry Andric         // probably sufficient), so use them.
26048bcb0991SDimitry Andric         assert(CI->getBitWidth() <= 64 &&
26058bcb0991SDimitry Andric                "large intrinsic immediates not handled");
26068bcb0991SDimitry Andric         MIB.addImm(CI->getSExtValue());
26078bcb0991SDimitry Andric       } else {
26088bcb0991SDimitry Andric         MIB.addFPImm(cast<ConstantFP>(Arg.value()));
26098bcb0991SDimitry Andric       }
2610349cc55cSDimitry Andric     } else if (auto *MDVal = dyn_cast<MetadataAsValue>(Arg.value())) {
2611349cc55cSDimitry Andric       auto *MD = MDVal->getMetadata();
2612349cc55cSDimitry Andric       auto *MDN = dyn_cast<MDNode>(MD);
2613349cc55cSDimitry Andric       if (!MDN) {
2614349cc55cSDimitry Andric         if (auto *ConstMD = dyn_cast<ConstantAsMetadata>(MD))
2615349cc55cSDimitry Andric           MDN = MDNode::get(MF->getFunction().getContext(), ConstMD);
2616349cc55cSDimitry Andric         else // This was probably an MDString.
2617e8d8bef9SDimitry Andric           return false;
2618349cc55cSDimitry Andric       }
2619e8d8bef9SDimitry Andric       MIB.addMetadata(MDN);
26208bcb0991SDimitry Andric     } else {
26218bcb0991SDimitry Andric       ArrayRef<Register> VRegs = getOrCreateVRegs(*Arg.value());
26220b57cec5SDimitry Andric       if (VRegs.size() > 1)
26230b57cec5SDimitry Andric         return false;
26240b57cec5SDimitry Andric       MIB.addUse(VRegs[0]);
26250b57cec5SDimitry Andric     }
26268bcb0991SDimitry Andric   }
26270b57cec5SDimitry Andric 
26280b57cec5SDimitry Andric   // Add a MachineMemOperand if it is a target mem intrinsic.
26290b57cec5SDimitry Andric   const TargetLowering &TLI = *MF->getSubtarget().getTargetLowering();
26300b57cec5SDimitry Andric   TargetLowering::IntrinsicInfo Info;
26310b57cec5SDimitry Andric   // TODO: Add a GlobalISel version of getTgtMemIntrinsic.
26320b57cec5SDimitry Andric   if (TLI.getTgtMemIntrinsic(Info, CI, *MF, ID)) {
263381ad6265SDimitry Andric     Align Alignment = Info.align.value_or(
26345ffd83dbSDimitry Andric         DL->getABITypeAlign(Info.memVT.getTypeForEVT(F->getContext())));
2635fe6060f1SDimitry Andric     LLT MemTy = Info.memVT.isSimple()
2636fe6060f1SDimitry Andric                     ? getLLTForMVT(Info.memVT.getSimpleVT())
2637fe6060f1SDimitry Andric                     : LLT::scalar(Info.memVT.getStoreSizeInBits());
2638bdd1243dSDimitry Andric 
2639bdd1243dSDimitry Andric     // TODO: We currently just fallback to address space 0 if getTgtMemIntrinsic
2640bdd1243dSDimitry Andric     //       didn't yield anything useful.
2641bdd1243dSDimitry Andric     MachinePointerInfo MPI;
2642bdd1243dSDimitry Andric     if (Info.ptrVal)
2643bdd1243dSDimitry Andric       MPI = MachinePointerInfo(Info.ptrVal, Info.offset);
2644bdd1243dSDimitry Andric     else if (Info.fallbackAddressSpace)
2645bdd1243dSDimitry Andric       MPI = MachinePointerInfo(*Info.fallbackAddressSpace);
2646bdd1243dSDimitry Andric     MIB.addMemOperand(
2647bdd1243dSDimitry Andric         MF->getMachineMemOperand(MPI, Info.flags, MemTy, Alignment, CI.getAAMetadata()));
26480b57cec5SDimitry Andric   }
26490b57cec5SDimitry Andric 
26500b57cec5SDimitry Andric   return true;
26510b57cec5SDimitry Andric }
26520b57cec5SDimitry Andric 
findUnwindDestinations(const BasicBlock * EHPadBB,BranchProbability Prob,SmallVectorImpl<std::pair<MachineBasicBlock *,BranchProbability>> & UnwindDests)2653e8d8bef9SDimitry Andric bool IRTranslator::findUnwindDestinations(
2654e8d8bef9SDimitry Andric     const BasicBlock *EHPadBB,
2655e8d8bef9SDimitry Andric     BranchProbability Prob,
2656e8d8bef9SDimitry Andric     SmallVectorImpl<std::pair<MachineBasicBlock *, BranchProbability>>
2657e8d8bef9SDimitry Andric         &UnwindDests) {
2658e8d8bef9SDimitry Andric   EHPersonality Personality = classifyEHPersonality(
2659e8d8bef9SDimitry Andric       EHPadBB->getParent()->getFunction().getPersonalityFn());
2660e8d8bef9SDimitry Andric   bool IsMSVCCXX = Personality == EHPersonality::MSVC_CXX;
2661e8d8bef9SDimitry Andric   bool IsCoreCLR = Personality == EHPersonality::CoreCLR;
2662e8d8bef9SDimitry Andric   bool IsWasmCXX = Personality == EHPersonality::Wasm_CXX;
2663e8d8bef9SDimitry Andric   bool IsSEH = isAsynchronousEHPersonality(Personality);
2664e8d8bef9SDimitry Andric 
2665e8d8bef9SDimitry Andric   if (IsWasmCXX) {
2666e8d8bef9SDimitry Andric     // Ignore this for now.
2667e8d8bef9SDimitry Andric     return false;
2668e8d8bef9SDimitry Andric   }
2669e8d8bef9SDimitry Andric 
2670e8d8bef9SDimitry Andric   while (EHPadBB) {
2671e8d8bef9SDimitry Andric     const Instruction *Pad = EHPadBB->getFirstNonPHI();
2672e8d8bef9SDimitry Andric     BasicBlock *NewEHPadBB = nullptr;
2673e8d8bef9SDimitry Andric     if (isa<LandingPadInst>(Pad)) {
2674e8d8bef9SDimitry Andric       // Stop on landingpads. They are not funclets.
2675e8d8bef9SDimitry Andric       UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
2676e8d8bef9SDimitry Andric       break;
2677e8d8bef9SDimitry Andric     }
2678e8d8bef9SDimitry Andric     if (isa<CleanupPadInst>(Pad)) {
2679e8d8bef9SDimitry Andric       // Stop on cleanup pads. Cleanups are always funclet entries for all known
2680e8d8bef9SDimitry Andric       // personalities.
2681e8d8bef9SDimitry Andric       UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
2682e8d8bef9SDimitry Andric       UnwindDests.back().first->setIsEHScopeEntry();
2683e8d8bef9SDimitry Andric       UnwindDests.back().first->setIsEHFuncletEntry();
2684e8d8bef9SDimitry Andric       break;
2685e8d8bef9SDimitry Andric     }
2686e8d8bef9SDimitry Andric     if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(Pad)) {
2687e8d8bef9SDimitry Andric       // Add the catchpad handlers to the possible destinations.
2688e8d8bef9SDimitry Andric       for (const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
2689e8d8bef9SDimitry Andric         UnwindDests.emplace_back(&getMBB(*CatchPadBB), Prob);
2690e8d8bef9SDimitry Andric         // For MSVC++ and the CLR, catchblocks are funclets and need prologues.
2691e8d8bef9SDimitry Andric         if (IsMSVCCXX || IsCoreCLR)
2692e8d8bef9SDimitry Andric           UnwindDests.back().first->setIsEHFuncletEntry();
2693e8d8bef9SDimitry Andric         if (!IsSEH)
2694e8d8bef9SDimitry Andric           UnwindDests.back().first->setIsEHScopeEntry();
2695e8d8bef9SDimitry Andric       }
2696e8d8bef9SDimitry Andric       NewEHPadBB = CatchSwitch->getUnwindDest();
2697e8d8bef9SDimitry Andric     } else {
2698e8d8bef9SDimitry Andric       continue;
2699e8d8bef9SDimitry Andric     }
2700e8d8bef9SDimitry Andric 
2701e8d8bef9SDimitry Andric     BranchProbabilityInfo *BPI = FuncInfo.BPI;
2702e8d8bef9SDimitry Andric     if (BPI && NewEHPadBB)
2703e8d8bef9SDimitry Andric       Prob *= BPI->getEdgeProbability(EHPadBB, NewEHPadBB);
2704e8d8bef9SDimitry Andric     EHPadBB = NewEHPadBB;
2705e8d8bef9SDimitry Andric   }
2706e8d8bef9SDimitry Andric   return true;
2707e8d8bef9SDimitry Andric }
2708e8d8bef9SDimitry Andric 
translateInvoke(const User & U,MachineIRBuilder & MIRBuilder)27090b57cec5SDimitry Andric bool IRTranslator::translateInvoke(const User &U,
27100b57cec5SDimitry Andric                                    MachineIRBuilder &MIRBuilder) {
27110b57cec5SDimitry Andric   const InvokeInst &I = cast<InvokeInst>(U);
27120b57cec5SDimitry Andric   MCContext &Context = MF->getContext();
27130b57cec5SDimitry Andric 
27140b57cec5SDimitry Andric   const BasicBlock *ReturnBB = I.getSuccessor(0);
27150b57cec5SDimitry Andric   const BasicBlock *EHPadBB = I.getSuccessor(1);
27160b57cec5SDimitry Andric 
27175ffd83dbSDimitry Andric   const Function *Fn = I.getCalledFunction();
27180b57cec5SDimitry Andric 
27190b57cec5SDimitry Andric   // FIXME: support invoking patchpoint and statepoint intrinsics.
27200b57cec5SDimitry Andric   if (Fn && Fn->isIntrinsic())
27210b57cec5SDimitry Andric     return false;
27220b57cec5SDimitry Andric 
27230b57cec5SDimitry Andric   // FIXME: support whatever these are.
27240b57cec5SDimitry Andric   if (I.countOperandBundlesOfType(LLVMContext::OB_deopt))
27250b57cec5SDimitry Andric     return false;
27260b57cec5SDimitry Andric 
2727480093f4SDimitry Andric   // FIXME: support control flow guard targets.
2728480093f4SDimitry Andric   if (I.countOperandBundlesOfType(LLVMContext::OB_cfguardtarget))
2729480093f4SDimitry Andric     return false;
2730480093f4SDimitry Andric 
27310b57cec5SDimitry Andric   // FIXME: support Windows exception handling.
2732e8d8bef9SDimitry Andric   if (!isa<LandingPadInst>(EHPadBB->getFirstNonPHI()))
27330b57cec5SDimitry Andric     return false;
27340b57cec5SDimitry Andric 
27355f757f3fSDimitry Andric   // FIXME: support Windows dllimport function calls and calls through
27365f757f3fSDimitry Andric   // weak symbols.
27375f757f3fSDimitry Andric   if (Fn && (Fn->hasDLLImportStorageClass() ||
27385f757f3fSDimitry Andric             (MF->getTarget().getTargetTriple().isOSWindows() &&
27395f757f3fSDimitry Andric              Fn->hasExternalWeakLinkage())))
27405f757f3fSDimitry Andric     return false;
27415f757f3fSDimitry Andric 
2742349cc55cSDimitry Andric   bool LowerInlineAsm = I.isInlineAsm();
2743349cc55cSDimitry Andric   bool NeedEHLabel = true;
2744fe6060f1SDimitry Andric 
27450b57cec5SDimitry Andric   // Emit the actual call, bracketed by EH_LABELs so that the MF knows about
27460b57cec5SDimitry Andric   // the region covered by the try.
2747349cc55cSDimitry Andric   MCSymbol *BeginSymbol = nullptr;
2748349cc55cSDimitry Andric   if (NeedEHLabel) {
2749bdd1243dSDimitry Andric     MIRBuilder.buildInstr(TargetOpcode::G_INVOKE_REGION_START);
2750349cc55cSDimitry Andric     BeginSymbol = Context.createTempSymbol();
27510b57cec5SDimitry Andric     MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(BeginSymbol);
2752349cc55cSDimitry Andric   }
27530b57cec5SDimitry Andric 
2754fe6060f1SDimitry Andric   if (LowerInlineAsm) {
2755fe6060f1SDimitry Andric     if (!translateInlineAsm(I, MIRBuilder))
2756fe6060f1SDimitry Andric       return false;
2757fe6060f1SDimitry Andric   } else if (!translateCallBase(I, MIRBuilder))
27580b57cec5SDimitry Andric     return false;
27590b57cec5SDimitry Andric 
2760349cc55cSDimitry Andric   MCSymbol *EndSymbol = nullptr;
2761349cc55cSDimitry Andric   if (NeedEHLabel) {
2762349cc55cSDimitry Andric     EndSymbol = Context.createTempSymbol();
27630b57cec5SDimitry Andric     MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(EndSymbol);
2764349cc55cSDimitry Andric   }
27650b57cec5SDimitry Andric 
2766e8d8bef9SDimitry Andric   SmallVector<std::pair<MachineBasicBlock *, BranchProbability>, 1> UnwindDests;
2767e8d8bef9SDimitry Andric   BranchProbabilityInfo *BPI = FuncInfo.BPI;
2768e8d8bef9SDimitry Andric   MachineBasicBlock *InvokeMBB = &MIRBuilder.getMBB();
2769e8d8bef9SDimitry Andric   BranchProbability EHPadBBProb =
2770e8d8bef9SDimitry Andric       BPI ? BPI->getEdgeProbability(InvokeMBB->getBasicBlock(), EHPadBB)
2771e8d8bef9SDimitry Andric           : BranchProbability::getZero();
2772e8d8bef9SDimitry Andric 
2773e8d8bef9SDimitry Andric   if (!findUnwindDestinations(EHPadBB, EHPadBBProb, UnwindDests))
2774e8d8bef9SDimitry Andric     return false;
2775e8d8bef9SDimitry Andric 
27760b57cec5SDimitry Andric   MachineBasicBlock &EHPadMBB = getMBB(*EHPadBB),
27770b57cec5SDimitry Andric                     &ReturnMBB = getMBB(*ReturnBB);
2778e8d8bef9SDimitry Andric   // Update successor info.
2779e8d8bef9SDimitry Andric   addSuccessorWithProb(InvokeMBB, &ReturnMBB);
2780e8d8bef9SDimitry Andric   for (auto &UnwindDest : UnwindDests) {
2781e8d8bef9SDimitry Andric     UnwindDest.first->setIsEHPad();
2782e8d8bef9SDimitry Andric     addSuccessorWithProb(InvokeMBB, UnwindDest.first, UnwindDest.second);
2783e8d8bef9SDimitry Andric   }
2784e8d8bef9SDimitry Andric   InvokeMBB->normalizeSuccProbs();
27850b57cec5SDimitry Andric 
2786349cc55cSDimitry Andric   if (NeedEHLabel) {
2787349cc55cSDimitry Andric     assert(BeginSymbol && "Expected a begin symbol!");
2788349cc55cSDimitry Andric     assert(EndSymbol && "Expected an end symbol!");
2789e8d8bef9SDimitry Andric     MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol);
2790349cc55cSDimitry Andric   }
2791349cc55cSDimitry Andric 
2792e8d8bef9SDimitry Andric   MIRBuilder.buildBr(ReturnMBB);
27930b57cec5SDimitry Andric   return true;
27940b57cec5SDimitry Andric }
27950b57cec5SDimitry Andric 
translateCallBr(const User & U,MachineIRBuilder & MIRBuilder)27960b57cec5SDimitry Andric bool IRTranslator::translateCallBr(const User &U,
27970b57cec5SDimitry Andric                                    MachineIRBuilder &MIRBuilder) {
27980b57cec5SDimitry Andric   // FIXME: Implement this.
27990b57cec5SDimitry Andric   return false;
28000b57cec5SDimitry Andric }
28010b57cec5SDimitry Andric 
translateLandingPad(const User & U,MachineIRBuilder & MIRBuilder)28020b57cec5SDimitry Andric bool IRTranslator::translateLandingPad(const User &U,
28030b57cec5SDimitry Andric                                        MachineIRBuilder &MIRBuilder) {
28040b57cec5SDimitry Andric   const LandingPadInst &LP = cast<LandingPadInst>(U);
28050b57cec5SDimitry Andric 
28060b57cec5SDimitry Andric   MachineBasicBlock &MBB = MIRBuilder.getMBB();
28070b57cec5SDimitry Andric 
28080b57cec5SDimitry Andric   MBB.setIsEHPad();
28090b57cec5SDimitry Andric 
28100b57cec5SDimitry Andric   // If there aren't registers to copy the values into (e.g., during SjLj
28110b57cec5SDimitry Andric   // exceptions), then don't bother.
28120b57cec5SDimitry Andric   auto &TLI = *MF->getSubtarget().getTargetLowering();
28130b57cec5SDimitry Andric   const Constant *PersonalityFn = MF->getFunction().getPersonalityFn();
28140b57cec5SDimitry Andric   if (TLI.getExceptionPointerRegister(PersonalityFn) == 0 &&
28150b57cec5SDimitry Andric       TLI.getExceptionSelectorRegister(PersonalityFn) == 0)
28160b57cec5SDimitry Andric     return true;
28170b57cec5SDimitry Andric 
28180b57cec5SDimitry Andric   // If landingpad's return type is token type, we don't create DAG nodes
28190b57cec5SDimitry Andric   // for its exception pointer and selector value. The extraction of exception
28200b57cec5SDimitry Andric   // pointer or selector value from token type landingpads is not currently
28210b57cec5SDimitry Andric   // supported.
28220b57cec5SDimitry Andric   if (LP.getType()->isTokenTy())
28230b57cec5SDimitry Andric     return true;
28240b57cec5SDimitry Andric 
28250b57cec5SDimitry Andric   // Add a label to mark the beginning of the landing pad.  Deletion of the
28260b57cec5SDimitry Andric   // landing pad can thus be detected via the MachineModuleInfo.
28270b57cec5SDimitry Andric   MIRBuilder.buildInstr(TargetOpcode::EH_LABEL)
28280b57cec5SDimitry Andric     .addSym(MF->addLandingPad(&MBB));
28290b57cec5SDimitry Andric 
2830e8d8bef9SDimitry Andric   // If the unwinder does not preserve all registers, ensure that the
2831e8d8bef9SDimitry Andric   // function marks the clobbered registers as used.
2832e8d8bef9SDimitry Andric   const TargetRegisterInfo &TRI = *MF->getSubtarget().getRegisterInfo();
2833e8d8bef9SDimitry Andric   if (auto *RegMask = TRI.getCustomEHPadPreservedMask(*MF))
2834e8d8bef9SDimitry Andric     MF->getRegInfo().addPhysRegsUsedFromRegMask(RegMask);
2835e8d8bef9SDimitry Andric 
28360b57cec5SDimitry Andric   LLT Ty = getLLTForType(*LP.getType(), *DL);
28370b57cec5SDimitry Andric   Register Undef = MRI->createGenericVirtualRegister(Ty);
28380b57cec5SDimitry Andric   MIRBuilder.buildUndef(Undef);
28390b57cec5SDimitry Andric 
28400b57cec5SDimitry Andric   SmallVector<LLT, 2> Tys;
28410b57cec5SDimitry Andric   for (Type *Ty : cast<StructType>(LP.getType())->elements())
28420b57cec5SDimitry Andric     Tys.push_back(getLLTForType(*Ty, *DL));
28430b57cec5SDimitry Andric   assert(Tys.size() == 2 && "Only two-valued landingpads are supported");
28440b57cec5SDimitry Andric 
28450b57cec5SDimitry Andric   // Mark exception register as live in.
28460b57cec5SDimitry Andric   Register ExceptionReg = TLI.getExceptionPointerRegister(PersonalityFn);
28470b57cec5SDimitry Andric   if (!ExceptionReg)
28480b57cec5SDimitry Andric     return false;
28490b57cec5SDimitry Andric 
28500b57cec5SDimitry Andric   MBB.addLiveIn(ExceptionReg);
28510b57cec5SDimitry Andric   ArrayRef<Register> ResRegs = getOrCreateVRegs(LP);
28520b57cec5SDimitry Andric   MIRBuilder.buildCopy(ResRegs[0], ExceptionReg);
28530b57cec5SDimitry Andric 
28540b57cec5SDimitry Andric   Register SelectorReg = TLI.getExceptionSelectorRegister(PersonalityFn);
28550b57cec5SDimitry Andric   if (!SelectorReg)
28560b57cec5SDimitry Andric     return false;
28570b57cec5SDimitry Andric 
28580b57cec5SDimitry Andric   MBB.addLiveIn(SelectorReg);
28590b57cec5SDimitry Andric   Register PtrVReg = MRI->createGenericVirtualRegister(Tys[0]);
28600b57cec5SDimitry Andric   MIRBuilder.buildCopy(PtrVReg, SelectorReg);
28610b57cec5SDimitry Andric   MIRBuilder.buildCast(ResRegs[1], PtrVReg);
28620b57cec5SDimitry Andric 
28630b57cec5SDimitry Andric   return true;
28640b57cec5SDimitry Andric }
28650b57cec5SDimitry Andric 
translateAlloca(const User & U,MachineIRBuilder & MIRBuilder)28660b57cec5SDimitry Andric bool IRTranslator::translateAlloca(const User &U,
28670b57cec5SDimitry Andric                                    MachineIRBuilder &MIRBuilder) {
28680b57cec5SDimitry Andric   auto &AI = cast<AllocaInst>(U);
28690b57cec5SDimitry Andric 
28700b57cec5SDimitry Andric   if (AI.isSwiftError())
28710b57cec5SDimitry Andric     return true;
28720b57cec5SDimitry Andric 
28730b57cec5SDimitry Andric   if (AI.isStaticAlloca()) {
28740b57cec5SDimitry Andric     Register Res = getOrCreateVReg(AI);
28750b57cec5SDimitry Andric     int FI = getOrCreateFrameIndex(AI);
28760b57cec5SDimitry Andric     MIRBuilder.buildFrameIndex(Res, FI);
28770b57cec5SDimitry Andric     return true;
28780b57cec5SDimitry Andric   }
28790b57cec5SDimitry Andric 
28800b57cec5SDimitry Andric   // FIXME: support stack probing for Windows.
28810b57cec5SDimitry Andric   if (MF->getTarget().getTargetTriple().isOSWindows())
28820b57cec5SDimitry Andric     return false;
28830b57cec5SDimitry Andric 
28840b57cec5SDimitry Andric   // Now we're in the harder dynamic case.
28850b57cec5SDimitry Andric   Register NumElts = getOrCreateVReg(*AI.getArraySize());
28860b57cec5SDimitry Andric   Type *IntPtrIRTy = DL->getIntPtrType(AI.getType());
28870b57cec5SDimitry Andric   LLT IntPtrTy = getLLTForType(*IntPtrIRTy, *DL);
28880b57cec5SDimitry Andric   if (MRI->getType(NumElts) != IntPtrTy) {
28890b57cec5SDimitry Andric     Register ExtElts = MRI->createGenericVirtualRegister(IntPtrTy);
28900b57cec5SDimitry Andric     MIRBuilder.buildZExtOrTrunc(ExtElts, NumElts);
28910b57cec5SDimitry Andric     NumElts = ExtElts;
28920b57cec5SDimitry Andric   }
28930b57cec5SDimitry Andric 
28945ffd83dbSDimitry Andric   Type *Ty = AI.getAllocatedType();
28955ffd83dbSDimitry Andric 
28960b57cec5SDimitry Andric   Register AllocSize = MRI->createGenericVirtualRegister(IntPtrTy);
28970b57cec5SDimitry Andric   Register TySize =
28988bcb0991SDimitry Andric       getOrCreateVReg(*ConstantInt::get(IntPtrIRTy, DL->getTypeAllocSize(Ty)));
28990b57cec5SDimitry Andric   MIRBuilder.buildMul(AllocSize, NumElts, TySize);
29000b57cec5SDimitry Andric 
29010b57cec5SDimitry Andric   // Round the size of the allocation up to the stack alignment size
29020b57cec5SDimitry Andric   // by add SA-1 to the size. This doesn't overflow because we're computing
29030b57cec5SDimitry Andric   // an address inside an alloca.
29045ffd83dbSDimitry Andric   Align StackAlign = MF->getSubtarget().getFrameLowering()->getStackAlign();
29055ffd83dbSDimitry Andric   auto SAMinusOne = MIRBuilder.buildConstant(IntPtrTy, StackAlign.value() - 1);
29068bcb0991SDimitry Andric   auto AllocAdd = MIRBuilder.buildAdd(IntPtrTy, AllocSize, SAMinusOne,
29078bcb0991SDimitry Andric                                       MachineInstr::NoUWrap);
29088bcb0991SDimitry Andric   auto AlignCst =
29095ffd83dbSDimitry Andric       MIRBuilder.buildConstant(IntPtrTy, ~(uint64_t)(StackAlign.value() - 1));
29108bcb0991SDimitry Andric   auto AlignedAlloc = MIRBuilder.buildAnd(IntPtrTy, AllocAdd, AlignCst);
29110b57cec5SDimitry Andric 
29125ffd83dbSDimitry Andric   Align Alignment = std::max(AI.getAlign(), DL->getPrefTypeAlign(Ty));
29135ffd83dbSDimitry Andric   if (Alignment <= StackAlign)
29145ffd83dbSDimitry Andric     Alignment = Align(1);
29155ffd83dbSDimitry Andric   MIRBuilder.buildDynStackAlloc(getOrCreateVReg(AI), AlignedAlloc, Alignment);
29160b57cec5SDimitry Andric 
29175ffd83dbSDimitry Andric   MF->getFrameInfo().CreateVariableSizedObject(Alignment, &AI);
29180b57cec5SDimitry Andric   assert(MF->getFrameInfo().hasVarSizedObjects());
29190b57cec5SDimitry Andric   return true;
29200b57cec5SDimitry Andric }
29210b57cec5SDimitry Andric 
translateVAArg(const User & U,MachineIRBuilder & MIRBuilder)29220b57cec5SDimitry Andric bool IRTranslator::translateVAArg(const User &U, MachineIRBuilder &MIRBuilder) {
29230b57cec5SDimitry Andric   // FIXME: We may need more info about the type. Because of how LLT works,
29240b57cec5SDimitry Andric   // we're completely discarding the i64/double distinction here (amongst
29250b57cec5SDimitry Andric   // others). Fortunately the ABIs I know of where that matters don't use va_arg
29260b57cec5SDimitry Andric   // anyway but that's not guaranteed.
29275ffd83dbSDimitry Andric   MIRBuilder.buildInstr(TargetOpcode::G_VAARG, {getOrCreateVReg(U)},
29285ffd83dbSDimitry Andric                         {getOrCreateVReg(*U.getOperand(0)),
29295ffd83dbSDimitry Andric                          DL->getABITypeAlign(U.getType()).value()});
29300b57cec5SDimitry Andric   return true;
29310b57cec5SDimitry Andric }
29320b57cec5SDimitry Andric 
translateUnreachable(const User & U,MachineIRBuilder & MIRBuilder)2933349cc55cSDimitry Andric bool IRTranslator::translateUnreachable(const User &U, MachineIRBuilder &MIRBuilder) {
2934349cc55cSDimitry Andric   if (!MF->getTarget().Options.TrapUnreachable)
2935349cc55cSDimitry Andric     return true;
2936349cc55cSDimitry Andric 
2937349cc55cSDimitry Andric   auto &UI = cast<UnreachableInst>(U);
2938349cc55cSDimitry Andric   // We may be able to ignore unreachable behind a noreturn call.
2939349cc55cSDimitry Andric   if (MF->getTarget().Options.NoTrapAfterNoreturn) {
2940349cc55cSDimitry Andric     const BasicBlock &BB = *UI.getParent();
2941349cc55cSDimitry Andric     if (&UI != &BB.front()) {
2942349cc55cSDimitry Andric       BasicBlock::const_iterator PredI =
2943349cc55cSDimitry Andric         std::prev(BasicBlock::const_iterator(UI));
2944349cc55cSDimitry Andric       if (const CallInst *Call = dyn_cast<CallInst>(&*PredI)) {
2945349cc55cSDimitry Andric         if (Call->doesNotReturn())
2946349cc55cSDimitry Andric           return true;
2947349cc55cSDimitry Andric       }
2948349cc55cSDimitry Andric     }
2949349cc55cSDimitry Andric   }
2950349cc55cSDimitry Andric 
29515f757f3fSDimitry Andric   MIRBuilder.buildIntrinsic(Intrinsic::trap, ArrayRef<Register>());
2952349cc55cSDimitry Andric   return true;
2953349cc55cSDimitry Andric }
2954349cc55cSDimitry Andric 
translateInsertElement(const User & U,MachineIRBuilder & MIRBuilder)29550b57cec5SDimitry Andric bool IRTranslator::translateInsertElement(const User &U,
29560b57cec5SDimitry Andric                                           MachineIRBuilder &MIRBuilder) {
29570b57cec5SDimitry Andric   // If it is a <1 x Ty> vector, use the scalar as it is
29580b57cec5SDimitry Andric   // not a legal vector type in LLT.
29595ffd83dbSDimitry Andric   if (cast<FixedVectorType>(U.getType())->getNumElements() == 1)
29605ffd83dbSDimitry Andric     return translateCopy(U, *U.getOperand(1), MIRBuilder);
29610b57cec5SDimitry Andric 
29620b57cec5SDimitry Andric   Register Res = getOrCreateVReg(U);
29630b57cec5SDimitry Andric   Register Val = getOrCreateVReg(*U.getOperand(0));
29640b57cec5SDimitry Andric   Register Elt = getOrCreateVReg(*U.getOperand(1));
29650b57cec5SDimitry Andric   Register Idx = getOrCreateVReg(*U.getOperand(2));
29660b57cec5SDimitry Andric   MIRBuilder.buildInsertVectorElement(Res, Val, Elt, Idx);
29670b57cec5SDimitry Andric   return true;
29680b57cec5SDimitry Andric }
29690b57cec5SDimitry Andric 
translateExtractElement(const User & U,MachineIRBuilder & MIRBuilder)29700b57cec5SDimitry Andric bool IRTranslator::translateExtractElement(const User &U,
29710b57cec5SDimitry Andric                                            MachineIRBuilder &MIRBuilder) {
29720b57cec5SDimitry Andric   // If it is a <1 x Ty> vector, use the scalar as it is
29730b57cec5SDimitry Andric   // not a legal vector type in LLT.
29745ffd83dbSDimitry Andric   if (cast<FixedVectorType>(U.getOperand(0)->getType())->getNumElements() == 1)
29755ffd83dbSDimitry Andric     return translateCopy(U, *U.getOperand(0), MIRBuilder);
29765ffd83dbSDimitry Andric 
29770b57cec5SDimitry Andric   Register Res = getOrCreateVReg(U);
29780b57cec5SDimitry Andric   Register Val = getOrCreateVReg(*U.getOperand(0));
29790b57cec5SDimitry Andric   const auto &TLI = *MF->getSubtarget().getTargetLowering();
29800b57cec5SDimitry Andric   unsigned PreferredVecIdxWidth = TLI.getVectorIdxTy(*DL).getSizeInBits();
29810b57cec5SDimitry Andric   Register Idx;
29820b57cec5SDimitry Andric   if (auto *CI = dyn_cast<ConstantInt>(U.getOperand(1))) {
29830b57cec5SDimitry Andric     if (CI->getBitWidth() != PreferredVecIdxWidth) {
2984bdd1243dSDimitry Andric       APInt NewIdx = CI->getValue().zextOrTrunc(PreferredVecIdxWidth);
29850b57cec5SDimitry Andric       auto *NewIdxCI = ConstantInt::get(CI->getContext(), NewIdx);
29860b57cec5SDimitry Andric       Idx = getOrCreateVReg(*NewIdxCI);
29870b57cec5SDimitry Andric     }
29880b57cec5SDimitry Andric   }
29890b57cec5SDimitry Andric   if (!Idx)
29900b57cec5SDimitry Andric     Idx = getOrCreateVReg(*U.getOperand(1));
29910b57cec5SDimitry Andric   if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
29925ffd83dbSDimitry Andric     const LLT VecIdxTy = LLT::scalar(PreferredVecIdxWidth);
2993bdd1243dSDimitry Andric     Idx = MIRBuilder.buildZExtOrTrunc(VecIdxTy, Idx).getReg(0);
29940b57cec5SDimitry Andric   }
29950b57cec5SDimitry Andric   MIRBuilder.buildExtractVectorElement(Res, Val, Idx);
29960b57cec5SDimitry Andric   return true;
29970b57cec5SDimitry Andric }
29980b57cec5SDimitry Andric 
translateShuffleVector(const User & U,MachineIRBuilder & MIRBuilder)29990b57cec5SDimitry Andric bool IRTranslator::translateShuffleVector(const User &U,
30000b57cec5SDimitry Andric                                           MachineIRBuilder &MIRBuilder) {
30015ffd83dbSDimitry Andric   ArrayRef<int> Mask;
30025ffd83dbSDimitry Andric   if (auto *SVI = dyn_cast<ShuffleVectorInst>(&U))
30035ffd83dbSDimitry Andric     Mask = SVI->getShuffleMask();
30045ffd83dbSDimitry Andric   else
30055ffd83dbSDimitry Andric     Mask = cast<ConstantExpr>(U).getShuffleMask();
3006480093f4SDimitry Andric   ArrayRef<int> MaskAlloc = MF->allocateShuffleMask(Mask);
30075ffd83dbSDimitry Andric   MIRBuilder
30085ffd83dbSDimitry Andric       .buildInstr(TargetOpcode::G_SHUFFLE_VECTOR, {getOrCreateVReg(U)},
30095ffd83dbSDimitry Andric                   {getOrCreateVReg(*U.getOperand(0)),
30105ffd83dbSDimitry Andric                    getOrCreateVReg(*U.getOperand(1))})
3011480093f4SDimitry Andric       .addShuffleMask(MaskAlloc);
30120b57cec5SDimitry Andric   return true;
30130b57cec5SDimitry Andric }
30140b57cec5SDimitry Andric 
translatePHI(const User & U,MachineIRBuilder & MIRBuilder)30150b57cec5SDimitry Andric bool IRTranslator::translatePHI(const User &U, MachineIRBuilder &MIRBuilder) {
30160b57cec5SDimitry Andric   const PHINode &PI = cast<PHINode>(U);
30170b57cec5SDimitry Andric 
30180b57cec5SDimitry Andric   SmallVector<MachineInstr *, 4> Insts;
30190b57cec5SDimitry Andric   for (auto Reg : getOrCreateVRegs(PI)) {
30200b57cec5SDimitry Andric     auto MIB = MIRBuilder.buildInstr(TargetOpcode::G_PHI, {Reg}, {});
30210b57cec5SDimitry Andric     Insts.push_back(MIB.getInstr());
30220b57cec5SDimitry Andric   }
30230b57cec5SDimitry Andric 
30240b57cec5SDimitry Andric   PendingPHIs.emplace_back(&PI, std::move(Insts));
30250b57cec5SDimitry Andric   return true;
30260b57cec5SDimitry Andric }
30270b57cec5SDimitry Andric 
translateAtomicCmpXchg(const User & U,MachineIRBuilder & MIRBuilder)30280b57cec5SDimitry Andric bool IRTranslator::translateAtomicCmpXchg(const User &U,
30290b57cec5SDimitry Andric                                           MachineIRBuilder &MIRBuilder) {
30300b57cec5SDimitry Andric   const AtomicCmpXchgInst &I = cast<AtomicCmpXchgInst>(U);
30310b57cec5SDimitry Andric 
30325ffd83dbSDimitry Andric   auto &TLI = *MF->getSubtarget().getTargetLowering();
30335ffd83dbSDimitry Andric   auto Flags = TLI.getAtomicMemOperandFlags(I, *DL);
30340b57cec5SDimitry Andric 
30350b57cec5SDimitry Andric   auto Res = getOrCreateVRegs(I);
30360b57cec5SDimitry Andric   Register OldValRes = Res[0];
30370b57cec5SDimitry Andric   Register SuccessRes = Res[1];
30380b57cec5SDimitry Andric   Register Addr = getOrCreateVReg(*I.getPointerOperand());
30390b57cec5SDimitry Andric   Register Cmp = getOrCreateVReg(*I.getCompareOperand());
30400b57cec5SDimitry Andric   Register NewVal = getOrCreateVReg(*I.getNewValOperand());
30410b57cec5SDimitry Andric 
30420b57cec5SDimitry Andric   MIRBuilder.buildAtomicCmpXchgWithSuccess(
30430b57cec5SDimitry Andric       OldValRes, SuccessRes, Addr, Cmp, NewVal,
30445ffd83dbSDimitry Andric       *MF->getMachineMemOperand(
3045fe6060f1SDimitry Andric           MachinePointerInfo(I.getPointerOperand()), Flags, MRI->getType(Cmp),
3046349cc55cSDimitry Andric           getMemOpAlign(I), I.getAAMetadata(), nullptr, I.getSyncScopeID(),
3047fe6060f1SDimitry Andric           I.getSuccessOrdering(), I.getFailureOrdering()));
30480b57cec5SDimitry Andric   return true;
30490b57cec5SDimitry Andric }
30500b57cec5SDimitry Andric 
translateAtomicRMW(const User & U,MachineIRBuilder & MIRBuilder)30510b57cec5SDimitry Andric bool IRTranslator::translateAtomicRMW(const User &U,
30520b57cec5SDimitry Andric                                       MachineIRBuilder &MIRBuilder) {
30530b57cec5SDimitry Andric   const AtomicRMWInst &I = cast<AtomicRMWInst>(U);
30545ffd83dbSDimitry Andric   auto &TLI = *MF->getSubtarget().getTargetLowering();
30555ffd83dbSDimitry Andric   auto Flags = TLI.getAtomicMemOperandFlags(I, *DL);
30560b57cec5SDimitry Andric 
30570b57cec5SDimitry Andric   Register Res = getOrCreateVReg(I);
30580b57cec5SDimitry Andric   Register Addr = getOrCreateVReg(*I.getPointerOperand());
30590b57cec5SDimitry Andric   Register Val = getOrCreateVReg(*I.getValOperand());
30600b57cec5SDimitry Andric 
30610b57cec5SDimitry Andric   unsigned Opcode = 0;
30620b57cec5SDimitry Andric   switch (I.getOperation()) {
30630b57cec5SDimitry Andric   default:
30640b57cec5SDimitry Andric     return false;
30650b57cec5SDimitry Andric   case AtomicRMWInst::Xchg:
30660b57cec5SDimitry Andric     Opcode = TargetOpcode::G_ATOMICRMW_XCHG;
30670b57cec5SDimitry Andric     break;
30680b57cec5SDimitry Andric   case AtomicRMWInst::Add:
30690b57cec5SDimitry Andric     Opcode = TargetOpcode::G_ATOMICRMW_ADD;
30700b57cec5SDimitry Andric     break;
30710b57cec5SDimitry Andric   case AtomicRMWInst::Sub:
30720b57cec5SDimitry Andric     Opcode = TargetOpcode::G_ATOMICRMW_SUB;
30730b57cec5SDimitry Andric     break;
30740b57cec5SDimitry Andric   case AtomicRMWInst::And:
30750b57cec5SDimitry Andric     Opcode = TargetOpcode::G_ATOMICRMW_AND;
30760b57cec5SDimitry Andric     break;
30770b57cec5SDimitry Andric   case AtomicRMWInst::Nand:
30780b57cec5SDimitry Andric     Opcode = TargetOpcode::G_ATOMICRMW_NAND;
30790b57cec5SDimitry Andric     break;
30800b57cec5SDimitry Andric   case AtomicRMWInst::Or:
30810b57cec5SDimitry Andric     Opcode = TargetOpcode::G_ATOMICRMW_OR;
30820b57cec5SDimitry Andric     break;
30830b57cec5SDimitry Andric   case AtomicRMWInst::Xor:
30840b57cec5SDimitry Andric     Opcode = TargetOpcode::G_ATOMICRMW_XOR;
30850b57cec5SDimitry Andric     break;
30860b57cec5SDimitry Andric   case AtomicRMWInst::Max:
30870b57cec5SDimitry Andric     Opcode = TargetOpcode::G_ATOMICRMW_MAX;
30880b57cec5SDimitry Andric     break;
30890b57cec5SDimitry Andric   case AtomicRMWInst::Min:
30900b57cec5SDimitry Andric     Opcode = TargetOpcode::G_ATOMICRMW_MIN;
30910b57cec5SDimitry Andric     break;
30920b57cec5SDimitry Andric   case AtomicRMWInst::UMax:
30930b57cec5SDimitry Andric     Opcode = TargetOpcode::G_ATOMICRMW_UMAX;
30940b57cec5SDimitry Andric     break;
30950b57cec5SDimitry Andric   case AtomicRMWInst::UMin:
30960b57cec5SDimitry Andric     Opcode = TargetOpcode::G_ATOMICRMW_UMIN;
30970b57cec5SDimitry Andric     break;
30988bcb0991SDimitry Andric   case AtomicRMWInst::FAdd:
30998bcb0991SDimitry Andric     Opcode = TargetOpcode::G_ATOMICRMW_FADD;
31008bcb0991SDimitry Andric     break;
31018bcb0991SDimitry Andric   case AtomicRMWInst::FSub:
31028bcb0991SDimitry Andric     Opcode = TargetOpcode::G_ATOMICRMW_FSUB;
31038bcb0991SDimitry Andric     break;
3104753f127fSDimitry Andric   case AtomicRMWInst::FMax:
3105753f127fSDimitry Andric     Opcode = TargetOpcode::G_ATOMICRMW_FMAX;
3106753f127fSDimitry Andric     break;
3107753f127fSDimitry Andric   case AtomicRMWInst::FMin:
3108753f127fSDimitry Andric     Opcode = TargetOpcode::G_ATOMICRMW_FMIN;
3109753f127fSDimitry Andric     break;
3110bdd1243dSDimitry Andric   case AtomicRMWInst::UIncWrap:
3111bdd1243dSDimitry Andric     Opcode = TargetOpcode::G_ATOMICRMW_UINC_WRAP;
3112bdd1243dSDimitry Andric     break;
3113bdd1243dSDimitry Andric   case AtomicRMWInst::UDecWrap:
3114bdd1243dSDimitry Andric     Opcode = TargetOpcode::G_ATOMICRMW_UDEC_WRAP;
3115bdd1243dSDimitry Andric     break;
31160b57cec5SDimitry Andric   }
31170b57cec5SDimitry Andric 
31180b57cec5SDimitry Andric   MIRBuilder.buildAtomicRMW(
31190b57cec5SDimitry Andric       Opcode, Res, Addr, Val,
31200b57cec5SDimitry Andric       *MF->getMachineMemOperand(MachinePointerInfo(I.getPointerOperand()),
3121fe6060f1SDimitry Andric                                 Flags, MRI->getType(Val), getMemOpAlign(I),
3122349cc55cSDimitry Andric                                 I.getAAMetadata(), nullptr, I.getSyncScopeID(),
3123fe6060f1SDimitry Andric                                 I.getOrdering()));
31240b57cec5SDimitry Andric   return true;
31250b57cec5SDimitry Andric }
31260b57cec5SDimitry Andric 
translateFence(const User & U,MachineIRBuilder & MIRBuilder)31270b57cec5SDimitry Andric bool IRTranslator::translateFence(const User &U,
31280b57cec5SDimitry Andric                                   MachineIRBuilder &MIRBuilder) {
31290b57cec5SDimitry Andric   const FenceInst &Fence = cast<FenceInst>(U);
31300b57cec5SDimitry Andric   MIRBuilder.buildFence(static_cast<unsigned>(Fence.getOrdering()),
31310b57cec5SDimitry Andric                         Fence.getSyncScopeID());
31320b57cec5SDimitry Andric   return true;
31330b57cec5SDimitry Andric }
31340b57cec5SDimitry Andric 
translateFreeze(const User & U,MachineIRBuilder & MIRBuilder)31355ffd83dbSDimitry Andric bool IRTranslator::translateFreeze(const User &U,
31365ffd83dbSDimitry Andric                                    MachineIRBuilder &MIRBuilder) {
31375ffd83dbSDimitry Andric   const ArrayRef<Register> DstRegs = getOrCreateVRegs(U);
31385ffd83dbSDimitry Andric   const ArrayRef<Register> SrcRegs = getOrCreateVRegs(*U.getOperand(0));
31395ffd83dbSDimitry Andric 
31405ffd83dbSDimitry Andric   assert(DstRegs.size() == SrcRegs.size() &&
31415ffd83dbSDimitry Andric          "Freeze with different source and destination type?");
31425ffd83dbSDimitry Andric 
31435ffd83dbSDimitry Andric   for (unsigned I = 0; I < DstRegs.size(); ++I) {
31445ffd83dbSDimitry Andric     MIRBuilder.buildFreeze(DstRegs[I], SrcRegs[I]);
31455ffd83dbSDimitry Andric   }
31465ffd83dbSDimitry Andric 
31475ffd83dbSDimitry Andric   return true;
31485ffd83dbSDimitry Andric }
31495ffd83dbSDimitry Andric 
finishPendingPhis()31500b57cec5SDimitry Andric void IRTranslator::finishPendingPhis() {
31510b57cec5SDimitry Andric #ifndef NDEBUG
31520b57cec5SDimitry Andric   DILocationVerifier Verifier;
31530b57cec5SDimitry Andric   GISelObserverWrapper WrapperObserver(&Verifier);
31540b57cec5SDimitry Andric   RAIIDelegateInstaller DelInstall(*MF, &WrapperObserver);
31550b57cec5SDimitry Andric #endif // ifndef NDEBUG
31560b57cec5SDimitry Andric   for (auto &Phi : PendingPHIs) {
31570b57cec5SDimitry Andric     const PHINode *PI = Phi.first;
31587a6dacacSDimitry Andric     if (PI->getType()->isEmptyTy())
31597a6dacacSDimitry Andric       continue;
31600b57cec5SDimitry Andric     ArrayRef<MachineInstr *> ComponentPHIs = Phi.second;
31610b57cec5SDimitry Andric     MachineBasicBlock *PhiMBB = ComponentPHIs[0]->getParent();
31620b57cec5SDimitry Andric     EntryBuilder->setDebugLoc(PI->getDebugLoc());
31630b57cec5SDimitry Andric #ifndef NDEBUG
31640b57cec5SDimitry Andric     Verifier.setCurrentInst(PI);
31650b57cec5SDimitry Andric #endif // ifndef NDEBUG
31660b57cec5SDimitry Andric 
31670b57cec5SDimitry Andric     SmallSet<const MachineBasicBlock *, 16> SeenPreds;
31680b57cec5SDimitry Andric     for (unsigned i = 0; i < PI->getNumIncomingValues(); ++i) {
31690b57cec5SDimitry Andric       auto IRPred = PI->getIncomingBlock(i);
31700b57cec5SDimitry Andric       ArrayRef<Register> ValRegs = getOrCreateVRegs(*PI->getIncomingValue(i));
3171fcaf7f86SDimitry Andric       for (auto *Pred : getMachinePredBBs({IRPred, PI->getParent()})) {
31720b57cec5SDimitry Andric         if (SeenPreds.count(Pred) || !PhiMBB->isPredecessor(Pred))
31730b57cec5SDimitry Andric           continue;
31740b57cec5SDimitry Andric         SeenPreds.insert(Pred);
31750b57cec5SDimitry Andric         for (unsigned j = 0; j < ValRegs.size(); ++j) {
31760b57cec5SDimitry Andric           MachineInstrBuilder MIB(*MF, ComponentPHIs[j]);
31770b57cec5SDimitry Andric           MIB.addUse(ValRegs[j]);
31780b57cec5SDimitry Andric           MIB.addMBB(Pred);
31790b57cec5SDimitry Andric         }
31800b57cec5SDimitry Andric       }
31810b57cec5SDimitry Andric     }
31820b57cec5SDimitry Andric   }
31830b57cec5SDimitry Andric }
31840b57cec5SDimitry Andric 
translateDbgValueRecord(Value * V,bool HasArgList,const DILocalVariable * Variable,const DIExpression * Expression,const DebugLoc & DL,MachineIRBuilder & MIRBuilder)31857a6dacacSDimitry Andric void IRTranslator::translateDbgValueRecord(Value *V, bool HasArgList,
31867a6dacacSDimitry Andric                                      const DILocalVariable *Variable,
31877a6dacacSDimitry Andric                                      const DIExpression *Expression,
31887a6dacacSDimitry Andric                                      const DebugLoc &DL,
31897a6dacacSDimitry Andric                                      MachineIRBuilder &MIRBuilder) {
31907a6dacacSDimitry Andric   assert(Variable->isValidLocationForIntrinsic(DL) &&
31917a6dacacSDimitry Andric          "Expected inlined-at fields to agree");
31927a6dacacSDimitry Andric   // Act as if we're handling a debug intrinsic.
31937a6dacacSDimitry Andric   MIRBuilder.setDebugLoc(DL);
31947a6dacacSDimitry Andric 
31957a6dacacSDimitry Andric   if (!V || HasArgList) {
31967a6dacacSDimitry Andric     // DI cannot produce a valid DBG_VALUE, so produce an undef DBG_VALUE to
31977a6dacacSDimitry Andric     // terminate any prior location.
31987a6dacacSDimitry Andric     MIRBuilder.buildIndirectDbgValue(0, Variable, Expression);
31997a6dacacSDimitry Andric     return;
32007a6dacacSDimitry Andric   }
32017a6dacacSDimitry Andric 
32027a6dacacSDimitry Andric   if (const auto *CI = dyn_cast<Constant>(V)) {
32037a6dacacSDimitry Andric     MIRBuilder.buildConstDbgValue(*CI, Variable, Expression);
32047a6dacacSDimitry Andric     return;
32057a6dacacSDimitry Andric   }
32067a6dacacSDimitry Andric 
32077a6dacacSDimitry Andric   if (auto *AI = dyn_cast<AllocaInst>(V);
32087a6dacacSDimitry Andric       AI && AI->isStaticAlloca() && Expression->startsWithDeref()) {
32097a6dacacSDimitry Andric     // If the value is an alloca and the expression starts with a
32107a6dacacSDimitry Andric     // dereference, track a stack slot instead of a register, as registers
32117a6dacacSDimitry Andric     // may be clobbered.
32127a6dacacSDimitry Andric     auto ExprOperands = Expression->getElements();
32137a6dacacSDimitry Andric     auto *ExprDerefRemoved =
32147a6dacacSDimitry Andric         DIExpression::get(AI->getContext(), ExprOperands.drop_front());
32157a6dacacSDimitry Andric     MIRBuilder.buildFIDbgValue(getOrCreateFrameIndex(*AI), Variable,
32167a6dacacSDimitry Andric                                ExprDerefRemoved);
32177a6dacacSDimitry Andric     return;
32187a6dacacSDimitry Andric   }
32197a6dacacSDimitry Andric   if (translateIfEntryValueArgument(false, V, Variable, Expression, DL,
32207a6dacacSDimitry Andric                                     MIRBuilder))
32217a6dacacSDimitry Andric     return;
32227a6dacacSDimitry Andric   for (Register Reg : getOrCreateVRegs(*V)) {
32237a6dacacSDimitry Andric     // FIXME: This does not handle register-indirect values at offset 0. The
32247a6dacacSDimitry Andric     // direct/indirect thing shouldn't really be handled by something as
32257a6dacacSDimitry Andric     // implicit as reg+noreg vs reg+imm in the first place, but it seems
32267a6dacacSDimitry Andric     // pretty baked in right now.
32277a6dacacSDimitry Andric     MIRBuilder.buildDirectDbgValue(Reg, Variable, Expression);
32287a6dacacSDimitry Andric   }
32297a6dacacSDimitry Andric   return;
32307a6dacacSDimitry Andric }
32317a6dacacSDimitry Andric 
translateDbgDeclareRecord(Value * Address,bool HasArgList,const DILocalVariable * Variable,const DIExpression * Expression,const DebugLoc & DL,MachineIRBuilder & MIRBuilder)32327a6dacacSDimitry Andric void IRTranslator::translateDbgDeclareRecord(Value *Address, bool HasArgList,
32337a6dacacSDimitry Andric                                      const DILocalVariable *Variable,
32347a6dacacSDimitry Andric                                      const DIExpression *Expression,
32357a6dacacSDimitry Andric                                      const DebugLoc &DL,
32367a6dacacSDimitry Andric                                      MachineIRBuilder &MIRBuilder) {
32377a6dacacSDimitry Andric   if (!Address || isa<UndefValue>(Address)) {
32387a6dacacSDimitry Andric     LLVM_DEBUG(dbgs() << "Dropping debug info for " << *Variable << "\n");
32397a6dacacSDimitry Andric     return;
32407a6dacacSDimitry Andric   }
32417a6dacacSDimitry Andric 
32427a6dacacSDimitry Andric   assert(Variable->isValidLocationForIntrinsic(DL) &&
32437a6dacacSDimitry Andric          "Expected inlined-at fields to agree");
32447a6dacacSDimitry Andric   auto AI = dyn_cast<AllocaInst>(Address);
32457a6dacacSDimitry Andric   if (AI && AI->isStaticAlloca()) {
32467a6dacacSDimitry Andric     // Static allocas are tracked at the MF level, no need for DBG_VALUE
32477a6dacacSDimitry Andric     // instructions (in fact, they get ignored if they *do* exist).
32487a6dacacSDimitry Andric     MF->setVariableDbgInfo(Variable, Expression,
32497a6dacacSDimitry Andric                            getOrCreateFrameIndex(*AI), DL);
32507a6dacacSDimitry Andric     return;
32517a6dacacSDimitry Andric   }
32527a6dacacSDimitry Andric 
32537a6dacacSDimitry Andric   if (translateIfEntryValueArgument(true, Address, Variable,
32547a6dacacSDimitry Andric                                     Expression, DL,
32557a6dacacSDimitry Andric                                     MIRBuilder))
32567a6dacacSDimitry Andric     return;
32577a6dacacSDimitry Andric 
32587a6dacacSDimitry Andric   // A dbg.declare describes the address of a source variable, so lower it
32597a6dacacSDimitry Andric   // into an indirect DBG_VALUE.
32607a6dacacSDimitry Andric   MIRBuilder.setDebugLoc(DL);
32617a6dacacSDimitry Andric   MIRBuilder.buildIndirectDbgValue(getOrCreateVReg(*Address),
32627a6dacacSDimitry Andric                                    Variable, Expression);
32637a6dacacSDimitry Andric   return;
32647a6dacacSDimitry Andric }
32657a6dacacSDimitry Andric 
translateDbgInfo(const Instruction & Inst,MachineIRBuilder & MIRBuilder)32667a6dacacSDimitry Andric void IRTranslator::translateDbgInfo(const Instruction &Inst,
32677a6dacacSDimitry Andric                                       MachineIRBuilder &MIRBuilder) {
32687a6dacacSDimitry Andric   for (DPValue &DPV : Inst.getDbgValueRange()) {
32697a6dacacSDimitry Andric     const DILocalVariable *Variable = DPV.getVariable();
32707a6dacacSDimitry Andric     const DIExpression *Expression = DPV.getExpression();
32717a6dacacSDimitry Andric     Value *V = DPV.getVariableLocationOp(0);
32727a6dacacSDimitry Andric     if (DPV.isDbgDeclare())
32737a6dacacSDimitry Andric       translateDbgDeclareRecord(V, DPV.hasArgList(), Variable,
32747a6dacacSDimitry Andric                          Expression, DPV.getDebugLoc(), MIRBuilder);
32757a6dacacSDimitry Andric     else
32767a6dacacSDimitry Andric       translateDbgValueRecord(V, DPV.hasArgList(), Variable,
32777a6dacacSDimitry Andric                          Expression, DPV.getDebugLoc(), MIRBuilder);
32787a6dacacSDimitry Andric   }
32797a6dacacSDimitry Andric }
32807a6dacacSDimitry Andric 
translate(const Instruction & Inst)32810b57cec5SDimitry Andric bool IRTranslator::translate(const Instruction &Inst) {
32820b57cec5SDimitry Andric   CurBuilder->setDebugLoc(Inst.getDebugLoc());
3283bdd1243dSDimitry Andric   CurBuilder->setPCSections(Inst.getMetadata(LLVMContext::MD_pcsections));
32840b57cec5SDimitry Andric 
32855ffd83dbSDimitry Andric   auto &TLI = *MF->getSubtarget().getTargetLowering();
32865ffd83dbSDimitry Andric   if (TLI.fallBackToDAGISel(Inst))
32875ffd83dbSDimitry Andric     return false;
32885ffd83dbSDimitry Andric 
32890b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
32900b57cec5SDimitry Andric #define HANDLE_INST(NUM, OPCODE, CLASS)                                        \
32910b57cec5SDimitry Andric   case Instruction::OPCODE:                                                    \
32920b57cec5SDimitry Andric     return translate##OPCODE(Inst, *CurBuilder.get());
32930b57cec5SDimitry Andric #include "llvm/IR/Instruction.def"
32940b57cec5SDimitry Andric   default:
32950b57cec5SDimitry Andric     return false;
32960b57cec5SDimitry Andric   }
32970b57cec5SDimitry Andric }
32980b57cec5SDimitry Andric 
translate(const Constant & C,Register Reg)32990b57cec5SDimitry Andric bool IRTranslator::translate(const Constant &C, Register Reg) {
3300fe6060f1SDimitry Andric   // We only emit constants into the entry block from here. To prevent jumpy
3301972a253aSDimitry Andric   // debug behaviour remove debug line.
3302fe6060f1SDimitry Andric   if (auto CurrInstDL = CurBuilder->getDL())
3303972a253aSDimitry Andric     EntryBuilder->setDebugLoc(DebugLoc());
3304fe6060f1SDimitry Andric 
33050b57cec5SDimitry Andric   if (auto CI = dyn_cast<ConstantInt>(&C))
33060b57cec5SDimitry Andric     EntryBuilder->buildConstant(Reg, *CI);
33070b57cec5SDimitry Andric   else if (auto CF = dyn_cast<ConstantFP>(&C))
33080b57cec5SDimitry Andric     EntryBuilder->buildFConstant(Reg, *CF);
33090b57cec5SDimitry Andric   else if (isa<UndefValue>(C))
33100b57cec5SDimitry Andric     EntryBuilder->buildUndef(Reg);
33115ffd83dbSDimitry Andric   else if (isa<ConstantPointerNull>(C))
33125ffd83dbSDimitry Andric     EntryBuilder->buildConstant(Reg, 0);
33135ffd83dbSDimitry Andric   else if (auto GV = dyn_cast<GlobalValue>(&C))
33140b57cec5SDimitry Andric     EntryBuilder->buildGlobalValue(Reg, GV);
33150b57cec5SDimitry Andric   else if (auto CAZ = dyn_cast<ConstantAggregateZero>(&C)) {
3316fe6060f1SDimitry Andric     if (!isa<FixedVectorType>(CAZ->getType()))
33170b57cec5SDimitry Andric       return false;
33180b57cec5SDimitry Andric     // Return the scalar if it is a <1 x Ty> vector.
3319fe6060f1SDimitry Andric     unsigned NumElts = CAZ->getElementCount().getFixedValue();
3320fe6060f1SDimitry Andric     if (NumElts == 1)
332181ad6265SDimitry Andric       return translateCopy(C, *CAZ->getElementValue(0u), *EntryBuilder);
33220b57cec5SDimitry Andric     SmallVector<Register, 4> Ops;
3323fe6060f1SDimitry Andric     for (unsigned I = 0; I < NumElts; ++I) {
3324fe6060f1SDimitry Andric       Constant &Elt = *CAZ->getElementValue(I);
33250b57cec5SDimitry Andric       Ops.push_back(getOrCreateVReg(Elt));
33260b57cec5SDimitry Andric     }
33270b57cec5SDimitry Andric     EntryBuilder->buildBuildVector(Reg, Ops);
33280b57cec5SDimitry Andric   } else if (auto CV = dyn_cast<ConstantDataVector>(&C)) {
33290b57cec5SDimitry Andric     // Return the scalar if it is a <1 x Ty> vector.
33300b57cec5SDimitry Andric     if (CV->getNumElements() == 1)
333181ad6265SDimitry Andric       return translateCopy(C, *CV->getElementAsConstant(0), *EntryBuilder);
33320b57cec5SDimitry Andric     SmallVector<Register, 4> Ops;
33330b57cec5SDimitry Andric     for (unsigned i = 0; i < CV->getNumElements(); ++i) {
33340b57cec5SDimitry Andric       Constant &Elt = *CV->getElementAsConstant(i);
33350b57cec5SDimitry Andric       Ops.push_back(getOrCreateVReg(Elt));
33360b57cec5SDimitry Andric     }
33370b57cec5SDimitry Andric     EntryBuilder->buildBuildVector(Reg, Ops);
33380b57cec5SDimitry Andric   } else if (auto CE = dyn_cast<ConstantExpr>(&C)) {
33390b57cec5SDimitry Andric     switch(CE->getOpcode()) {
33400b57cec5SDimitry Andric #define HANDLE_INST(NUM, OPCODE, CLASS)                                        \
33410b57cec5SDimitry Andric   case Instruction::OPCODE:                                                    \
33420b57cec5SDimitry Andric     return translate##OPCODE(*CE, *EntryBuilder.get());
33430b57cec5SDimitry Andric #include "llvm/IR/Instruction.def"
33440b57cec5SDimitry Andric     default:
33450b57cec5SDimitry Andric       return false;
33460b57cec5SDimitry Andric     }
33470b57cec5SDimitry Andric   } else if (auto CV = dyn_cast<ConstantVector>(&C)) {
33480b57cec5SDimitry Andric     if (CV->getNumOperands() == 1)
334981ad6265SDimitry Andric       return translateCopy(C, *CV->getOperand(0), *EntryBuilder);
33500b57cec5SDimitry Andric     SmallVector<Register, 4> Ops;
33510b57cec5SDimitry Andric     for (unsigned i = 0; i < CV->getNumOperands(); ++i) {
33520b57cec5SDimitry Andric       Ops.push_back(getOrCreateVReg(*CV->getOperand(i)));
33530b57cec5SDimitry Andric     }
33540b57cec5SDimitry Andric     EntryBuilder->buildBuildVector(Reg, Ops);
33550b57cec5SDimitry Andric   } else if (auto *BA = dyn_cast<BlockAddress>(&C)) {
33560b57cec5SDimitry Andric     EntryBuilder->buildBlockAddress(Reg, BA);
33570b57cec5SDimitry Andric   } else
33580b57cec5SDimitry Andric     return false;
33590b57cec5SDimitry Andric 
33600b57cec5SDimitry Andric   return true;
33610b57cec5SDimitry Andric }
33620b57cec5SDimitry Andric 
finalizeBasicBlock(const BasicBlock & BB,MachineBasicBlock & MBB)3363349cc55cSDimitry Andric bool IRTranslator::finalizeBasicBlock(const BasicBlock &BB,
3364349cc55cSDimitry Andric                                       MachineBasicBlock &MBB) {
3365e8d8bef9SDimitry Andric   for (auto &BTB : SL->BitTestCases) {
3366e8d8bef9SDimitry Andric     // Emit header first, if it wasn't already emitted.
3367e8d8bef9SDimitry Andric     if (!BTB.Emitted)
3368e8d8bef9SDimitry Andric       emitBitTestHeader(BTB, BTB.Parent);
3369e8d8bef9SDimitry Andric 
3370e8d8bef9SDimitry Andric     BranchProbability UnhandledProb = BTB.Prob;
3371e8d8bef9SDimitry Andric     for (unsigned j = 0, ej = BTB.Cases.size(); j != ej; ++j) {
3372e8d8bef9SDimitry Andric       UnhandledProb -= BTB.Cases[j].ExtraProb;
3373e8d8bef9SDimitry Andric       // Set the current basic block to the mbb we wish to insert the code into
3374e8d8bef9SDimitry Andric       MachineBasicBlock *MBB = BTB.Cases[j].ThisBB;
3375e8d8bef9SDimitry Andric       // If all cases cover a contiguous range, it is not necessary to jump to
3376e8d8bef9SDimitry Andric       // the default block after the last bit test fails. This is because the
3377e8d8bef9SDimitry Andric       // range check during bit test header creation has guaranteed that every
3378e8d8bef9SDimitry Andric       // case here doesn't go outside the range. In this case, there is no need
3379e8d8bef9SDimitry Andric       // to perform the last bit test, as it will always be true. Instead, make
3380e8d8bef9SDimitry Andric       // the second-to-last bit-test fall through to the target of the last bit
3381e8d8bef9SDimitry Andric       // test, and delete the last bit test.
3382e8d8bef9SDimitry Andric 
3383e8d8bef9SDimitry Andric       MachineBasicBlock *NextMBB;
3384349cc55cSDimitry Andric       if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
3385e8d8bef9SDimitry Andric         // Second-to-last bit-test with contiguous range: fall through to the
3386e8d8bef9SDimitry Andric         // target of the final bit test.
3387e8d8bef9SDimitry Andric         NextMBB = BTB.Cases[j + 1].TargetBB;
3388e8d8bef9SDimitry Andric       } else if (j + 1 == ej) {
3389e8d8bef9SDimitry Andric         // For the last bit test, fall through to Default.
3390e8d8bef9SDimitry Andric         NextMBB = BTB.Default;
3391e8d8bef9SDimitry Andric       } else {
3392e8d8bef9SDimitry Andric         // Otherwise, fall through to the next bit test.
3393e8d8bef9SDimitry Andric         NextMBB = BTB.Cases[j + 1].ThisBB;
3394e8d8bef9SDimitry Andric       }
3395e8d8bef9SDimitry Andric 
3396e8d8bef9SDimitry Andric       emitBitTestCase(BTB, NextMBB, UnhandledProb, BTB.Reg, BTB.Cases[j], MBB);
3397e8d8bef9SDimitry Andric 
3398349cc55cSDimitry Andric       if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
3399fe6060f1SDimitry Andric         // We need to record the replacement phi edge here that normally
3400fe6060f1SDimitry Andric         // happens in emitBitTestCase before we delete the case, otherwise the
3401fe6060f1SDimitry Andric         // phi edge will be lost.
3402fe6060f1SDimitry Andric         addMachineCFGPred({BTB.Parent->getBasicBlock(),
3403fe6060f1SDimitry Andric                            BTB.Cases[ej - 1].TargetBB->getBasicBlock()},
3404fe6060f1SDimitry Andric                           MBB);
3405e8d8bef9SDimitry Andric         // Since we're not going to use the final bit test, remove it.
3406e8d8bef9SDimitry Andric         BTB.Cases.pop_back();
3407e8d8bef9SDimitry Andric         break;
3408e8d8bef9SDimitry Andric       }
3409e8d8bef9SDimitry Andric     }
3410e8d8bef9SDimitry Andric     // This is "default" BB. We have two jumps to it. From "header" BB and from
3411e8d8bef9SDimitry Andric     // last "case" BB, unless the latter was skipped.
3412e8d8bef9SDimitry Andric     CFGEdge HeaderToDefaultEdge = {BTB.Parent->getBasicBlock(),
3413e8d8bef9SDimitry Andric                                    BTB.Default->getBasicBlock()};
3414e8d8bef9SDimitry Andric     addMachineCFGPred(HeaderToDefaultEdge, BTB.Parent);
3415e8d8bef9SDimitry Andric     if (!BTB.ContiguousRange) {
3416e8d8bef9SDimitry Andric       addMachineCFGPred(HeaderToDefaultEdge, BTB.Cases.back().ThisBB);
3417e8d8bef9SDimitry Andric     }
3418e8d8bef9SDimitry Andric   }
3419e8d8bef9SDimitry Andric   SL->BitTestCases.clear();
3420e8d8bef9SDimitry Andric 
34210b57cec5SDimitry Andric   for (auto &JTCase : SL->JTCases) {
34220b57cec5SDimitry Andric     // Emit header first, if it wasn't already emitted.
34230b57cec5SDimitry Andric     if (!JTCase.first.Emitted)
34240b57cec5SDimitry Andric       emitJumpTableHeader(JTCase.second, JTCase.first, JTCase.first.HeaderBB);
34250b57cec5SDimitry Andric 
34260b57cec5SDimitry Andric     emitJumpTable(JTCase.second, JTCase.second.MBB);
34270b57cec5SDimitry Andric   }
34280b57cec5SDimitry Andric   SL->JTCases.clear();
3429e8d8bef9SDimitry Andric 
3430e8d8bef9SDimitry Andric   for (auto &SwCase : SL->SwitchCases)
3431e8d8bef9SDimitry Andric     emitSwitchCase(SwCase, &CurBuilder->getMBB(), *CurBuilder);
3432e8d8bef9SDimitry Andric   SL->SwitchCases.clear();
3433349cc55cSDimitry Andric 
3434349cc55cSDimitry Andric   // Check if we need to generate stack-protector guard checks.
3435349cc55cSDimitry Andric   StackProtector &SP = getAnalysis<StackProtector>();
3436349cc55cSDimitry Andric   if (SP.shouldEmitSDCheck(BB)) {
3437349cc55cSDimitry Andric     const TargetLowering &TLI = *MF->getSubtarget().getTargetLowering();
3438349cc55cSDimitry Andric     bool FunctionBasedInstrumentation =
3439349cc55cSDimitry Andric         TLI.getSSPStackGuardCheck(*MF->getFunction().getParent());
3440349cc55cSDimitry Andric     SPDescriptor.initialize(&BB, &MBB, FunctionBasedInstrumentation);
3441349cc55cSDimitry Andric   }
3442349cc55cSDimitry Andric   // Handle stack protector.
3443349cc55cSDimitry Andric   if (SPDescriptor.shouldEmitFunctionBasedCheckStackProtector()) {
3444349cc55cSDimitry Andric     LLVM_DEBUG(dbgs() << "Unimplemented stack protector case\n");
3445349cc55cSDimitry Andric     return false;
3446349cc55cSDimitry Andric   } else if (SPDescriptor.shouldEmitStackProtector()) {
3447349cc55cSDimitry Andric     MachineBasicBlock *ParentMBB = SPDescriptor.getParentMBB();
3448349cc55cSDimitry Andric     MachineBasicBlock *SuccessMBB = SPDescriptor.getSuccessMBB();
3449349cc55cSDimitry Andric 
3450349cc55cSDimitry Andric     // Find the split point to split the parent mbb. At the same time copy all
3451349cc55cSDimitry Andric     // physical registers used in the tail of parent mbb into virtual registers
3452349cc55cSDimitry Andric     // before the split point and back into physical registers after the split
3453349cc55cSDimitry Andric     // point. This prevents us needing to deal with Live-ins and many other
3454349cc55cSDimitry Andric     // register allocation issues caused by us splitting the parent mbb. The
3455349cc55cSDimitry Andric     // register allocator will clean up said virtual copies later on.
3456349cc55cSDimitry Andric     MachineBasicBlock::iterator SplitPoint = findSplitPointForStackProtector(
3457349cc55cSDimitry Andric         ParentMBB, *MF->getSubtarget().getInstrInfo());
3458349cc55cSDimitry Andric 
3459349cc55cSDimitry Andric     // Splice the terminator of ParentMBB into SuccessMBB.
3460349cc55cSDimitry Andric     SuccessMBB->splice(SuccessMBB->end(), ParentMBB, SplitPoint,
3461349cc55cSDimitry Andric                        ParentMBB->end());
3462349cc55cSDimitry Andric 
3463349cc55cSDimitry Andric     // Add compare/jump on neq/jump to the parent BB.
3464349cc55cSDimitry Andric     if (!emitSPDescriptorParent(SPDescriptor, ParentMBB))
3465349cc55cSDimitry Andric       return false;
3466349cc55cSDimitry Andric 
3467349cc55cSDimitry Andric     // CodeGen Failure MBB if we have not codegened it yet.
3468349cc55cSDimitry Andric     MachineBasicBlock *FailureMBB = SPDescriptor.getFailureMBB();
3469349cc55cSDimitry Andric     if (FailureMBB->empty()) {
3470349cc55cSDimitry Andric       if (!emitSPDescriptorFailure(SPDescriptor, FailureMBB))
3471349cc55cSDimitry Andric         return false;
3472349cc55cSDimitry Andric     }
3473349cc55cSDimitry Andric 
3474349cc55cSDimitry Andric     // Clear the Per-BB State.
3475349cc55cSDimitry Andric     SPDescriptor.resetPerBBState();
3476349cc55cSDimitry Andric   }
3477349cc55cSDimitry Andric   return true;
3478349cc55cSDimitry Andric }
3479349cc55cSDimitry Andric 
emitSPDescriptorParent(StackProtectorDescriptor & SPD,MachineBasicBlock * ParentBB)3480349cc55cSDimitry Andric bool IRTranslator::emitSPDescriptorParent(StackProtectorDescriptor &SPD,
3481349cc55cSDimitry Andric                                           MachineBasicBlock *ParentBB) {
3482349cc55cSDimitry Andric   CurBuilder->setInsertPt(*ParentBB, ParentBB->end());
3483349cc55cSDimitry Andric   // First create the loads to the guard/stack slot for the comparison.
3484349cc55cSDimitry Andric   const TargetLowering &TLI = *MF->getSubtarget().getTargetLowering();
34855f757f3fSDimitry Andric   Type *PtrIRTy = PointerType::getUnqual(MF->getFunction().getContext());
3486349cc55cSDimitry Andric   const LLT PtrTy = getLLTForType(*PtrIRTy, *DL);
3487349cc55cSDimitry Andric   LLT PtrMemTy = getLLTForMVT(TLI.getPointerMemTy(*DL));
3488349cc55cSDimitry Andric 
3489349cc55cSDimitry Andric   MachineFrameInfo &MFI = ParentBB->getParent()->getFrameInfo();
3490349cc55cSDimitry Andric   int FI = MFI.getStackProtectorIndex();
3491349cc55cSDimitry Andric 
3492349cc55cSDimitry Andric   Register Guard;
3493349cc55cSDimitry Andric   Register StackSlotPtr = CurBuilder->buildFrameIndex(PtrTy, FI).getReg(0);
3494349cc55cSDimitry Andric   const Module &M = *ParentBB->getParent()->getFunction().getParent();
34955f757f3fSDimitry Andric   Align Align = DL->getPrefTypeAlign(PointerType::getUnqual(M.getContext()));
3496349cc55cSDimitry Andric 
3497349cc55cSDimitry Andric   // Generate code to load the content of the guard slot.
3498349cc55cSDimitry Andric   Register GuardVal =
3499349cc55cSDimitry Andric       CurBuilder
3500349cc55cSDimitry Andric           ->buildLoad(PtrMemTy, StackSlotPtr,
3501349cc55cSDimitry Andric                       MachinePointerInfo::getFixedStack(*MF, FI), Align,
3502349cc55cSDimitry Andric                       MachineMemOperand::MOLoad | MachineMemOperand::MOVolatile)
3503349cc55cSDimitry Andric           .getReg(0);
3504349cc55cSDimitry Andric 
3505349cc55cSDimitry Andric   if (TLI.useStackGuardXorFP()) {
3506349cc55cSDimitry Andric     LLVM_DEBUG(dbgs() << "Stack protector xor'ing with FP not yet implemented");
3507349cc55cSDimitry Andric     return false;
3508349cc55cSDimitry Andric   }
3509349cc55cSDimitry Andric 
3510349cc55cSDimitry Andric   // Retrieve guard check function, nullptr if instrumentation is inlined.
3511349cc55cSDimitry Andric   if (const Function *GuardCheckFn = TLI.getSSPStackGuardCheck(M)) {
3512349cc55cSDimitry Andric     // This path is currently untestable on GlobalISel, since the only platform
3513349cc55cSDimitry Andric     // that needs this seems to be Windows, and we fall back on that currently.
3514349cc55cSDimitry Andric     // The code still lives here in case that changes.
3515349cc55cSDimitry Andric     // Silence warning about unused variable until the code below that uses
3516349cc55cSDimitry Andric     // 'GuardCheckFn' is enabled.
3517349cc55cSDimitry Andric     (void)GuardCheckFn;
3518349cc55cSDimitry Andric     return false;
3519349cc55cSDimitry Andric #if 0
3520349cc55cSDimitry Andric     // The target provides a guard check function to validate the guard value.
3521349cc55cSDimitry Andric     // Generate a call to that function with the content of the guard slot as
3522349cc55cSDimitry Andric     // argument.
3523349cc55cSDimitry Andric     FunctionType *FnTy = GuardCheckFn->getFunctionType();
3524349cc55cSDimitry Andric     assert(FnTy->getNumParams() == 1 && "Invalid function signature");
3525349cc55cSDimitry Andric     ISD::ArgFlagsTy Flags;
3526349cc55cSDimitry Andric     if (GuardCheckFn->hasAttribute(1, Attribute::AttrKind::InReg))
3527349cc55cSDimitry Andric       Flags.setInReg();
3528349cc55cSDimitry Andric     CallLowering::ArgInfo GuardArgInfo(
3529349cc55cSDimitry Andric         {GuardVal, FnTy->getParamType(0), {Flags}});
3530349cc55cSDimitry Andric 
3531349cc55cSDimitry Andric     CallLowering::CallLoweringInfo Info;
3532349cc55cSDimitry Andric     Info.OrigArgs.push_back(GuardArgInfo);
3533349cc55cSDimitry Andric     Info.CallConv = GuardCheckFn->getCallingConv();
3534349cc55cSDimitry Andric     Info.Callee = MachineOperand::CreateGA(GuardCheckFn, 0);
3535349cc55cSDimitry Andric     Info.OrigRet = {Register(), FnTy->getReturnType()};
3536349cc55cSDimitry Andric     if (!CLI->lowerCall(MIRBuilder, Info)) {
3537349cc55cSDimitry Andric       LLVM_DEBUG(dbgs() << "Failed to lower call to stack protector check\n");
3538349cc55cSDimitry Andric       return false;
3539349cc55cSDimitry Andric     }
3540349cc55cSDimitry Andric     return true;
3541349cc55cSDimitry Andric #endif
3542349cc55cSDimitry Andric   }
3543349cc55cSDimitry Andric 
3544349cc55cSDimitry Andric   // If useLoadStackGuardNode returns true, generate LOAD_STACK_GUARD.
3545349cc55cSDimitry Andric   // Otherwise, emit a volatile load to retrieve the stack guard value.
3546349cc55cSDimitry Andric   if (TLI.useLoadStackGuardNode()) {
3547349cc55cSDimitry Andric     Guard =
3548349cc55cSDimitry Andric         MRI->createGenericVirtualRegister(LLT::scalar(PtrTy.getSizeInBits()));
3549349cc55cSDimitry Andric     getStackGuard(Guard, *CurBuilder);
3550349cc55cSDimitry Andric   } else {
3551349cc55cSDimitry Andric     // TODO: test using android subtarget when we support @llvm.thread.pointer.
3552349cc55cSDimitry Andric     const Value *IRGuard = TLI.getSDagStackGuard(M);
3553349cc55cSDimitry Andric     Register GuardPtr = getOrCreateVReg(*IRGuard);
3554349cc55cSDimitry Andric 
3555349cc55cSDimitry Andric     Guard = CurBuilder
3556349cc55cSDimitry Andric                 ->buildLoad(PtrMemTy, GuardPtr,
3557349cc55cSDimitry Andric                             MachinePointerInfo::getFixedStack(*MF, FI), Align,
3558349cc55cSDimitry Andric                             MachineMemOperand::MOLoad |
3559349cc55cSDimitry Andric                                 MachineMemOperand::MOVolatile)
3560349cc55cSDimitry Andric                 .getReg(0);
3561349cc55cSDimitry Andric   }
3562349cc55cSDimitry Andric 
3563349cc55cSDimitry Andric   // Perform the comparison.
3564349cc55cSDimitry Andric   auto Cmp =
3565349cc55cSDimitry Andric       CurBuilder->buildICmp(CmpInst::ICMP_NE, LLT::scalar(1), Guard, GuardVal);
3566349cc55cSDimitry Andric   // If the guard/stackslot do not equal, branch to failure MBB.
3567349cc55cSDimitry Andric   CurBuilder->buildBrCond(Cmp, *SPD.getFailureMBB());
3568349cc55cSDimitry Andric   // Otherwise branch to success MBB.
3569349cc55cSDimitry Andric   CurBuilder->buildBr(*SPD.getSuccessMBB());
3570349cc55cSDimitry Andric   return true;
3571349cc55cSDimitry Andric }
3572349cc55cSDimitry Andric 
emitSPDescriptorFailure(StackProtectorDescriptor & SPD,MachineBasicBlock * FailureBB)3573349cc55cSDimitry Andric bool IRTranslator::emitSPDescriptorFailure(StackProtectorDescriptor &SPD,
3574349cc55cSDimitry Andric                                            MachineBasicBlock *FailureBB) {
3575349cc55cSDimitry Andric   CurBuilder->setInsertPt(*FailureBB, FailureBB->end());
3576349cc55cSDimitry Andric   const TargetLowering &TLI = *MF->getSubtarget().getTargetLowering();
3577349cc55cSDimitry Andric 
3578349cc55cSDimitry Andric   const RTLIB::Libcall Libcall = RTLIB::STACKPROTECTOR_CHECK_FAIL;
3579349cc55cSDimitry Andric   const char *Name = TLI.getLibcallName(Libcall);
3580349cc55cSDimitry Andric 
3581349cc55cSDimitry Andric   CallLowering::CallLoweringInfo Info;
3582349cc55cSDimitry Andric   Info.CallConv = TLI.getLibcallCallingConv(Libcall);
3583349cc55cSDimitry Andric   Info.Callee = MachineOperand::CreateES(Name);
3584349cc55cSDimitry Andric   Info.OrigRet = {Register(), Type::getVoidTy(MF->getFunction().getContext()),
3585349cc55cSDimitry Andric                   0};
3586349cc55cSDimitry Andric   if (!CLI->lowerCall(*CurBuilder, Info)) {
3587349cc55cSDimitry Andric     LLVM_DEBUG(dbgs() << "Failed to lower call to stack protector fail\n");
3588349cc55cSDimitry Andric     return false;
3589349cc55cSDimitry Andric   }
3590349cc55cSDimitry Andric 
359181ad6265SDimitry Andric   // On PS4/PS5, the "return address" must still be within the calling
359281ad6265SDimitry Andric   // function, even if it's at the very end, so emit an explicit TRAP here.
3593349cc55cSDimitry Andric   // WebAssembly needs an unreachable instruction after a non-returning call,
3594349cc55cSDimitry Andric   // because the function return type can be different from __stack_chk_fail's
3595349cc55cSDimitry Andric   // return type (void).
3596349cc55cSDimitry Andric   const TargetMachine &TM = MF->getTarget();
359781ad6265SDimitry Andric   if (TM.getTargetTriple().isPS() || TM.getTargetTriple().isWasm()) {
3598349cc55cSDimitry Andric     LLVM_DEBUG(dbgs() << "Unhandled trap emission for stack protector fail\n");
3599349cc55cSDimitry Andric     return false;
3600349cc55cSDimitry Andric   }
3601349cc55cSDimitry Andric   return true;
36020b57cec5SDimitry Andric }
36030b57cec5SDimitry Andric 
finalizeFunction()36040b57cec5SDimitry Andric void IRTranslator::finalizeFunction() {
36050b57cec5SDimitry Andric   // Release the memory used by the different maps we
36060b57cec5SDimitry Andric   // needed during the translation.
36070b57cec5SDimitry Andric   PendingPHIs.clear();
36080b57cec5SDimitry Andric   VMap.reset();
36090b57cec5SDimitry Andric   FrameIndices.clear();
36100b57cec5SDimitry Andric   MachinePreds.clear();
36110b57cec5SDimitry Andric   // MachineIRBuilder::DebugLoc can outlive the DILocation it holds. Clear it
36120b57cec5SDimitry Andric   // to avoid accessing free’d memory (in runOnMachineFunction) and to avoid
36130b57cec5SDimitry Andric   // destroying it twice (in ~IRTranslator() and ~LLVMContext())
36140b57cec5SDimitry Andric   EntryBuilder.reset();
36150b57cec5SDimitry Andric   CurBuilder.reset();
36160b57cec5SDimitry Andric   FuncInfo.clear();
3617349cc55cSDimitry Andric   SPDescriptor.resetPerFunctionState();
36180b57cec5SDimitry Andric }
36190b57cec5SDimitry Andric 
36208bcb0991SDimitry Andric /// Returns true if a BasicBlock \p BB within a variadic function contains a
36218bcb0991SDimitry Andric /// variadic musttail call.
checkForMustTailInVarArgFn(bool IsVarArg,const BasicBlock & BB)36228bcb0991SDimitry Andric static bool checkForMustTailInVarArgFn(bool IsVarArg, const BasicBlock &BB) {
36238bcb0991SDimitry Andric   if (!IsVarArg)
36248bcb0991SDimitry Andric     return false;
36258bcb0991SDimitry Andric 
36268bcb0991SDimitry Andric   // Walk the block backwards, because tail calls usually only appear at the end
36278bcb0991SDimitry Andric   // of a block.
3628349cc55cSDimitry Andric   return llvm::any_of(llvm::reverse(BB), [](const Instruction &I) {
36298bcb0991SDimitry Andric     const auto *CI = dyn_cast<CallInst>(&I);
36308bcb0991SDimitry Andric     return CI && CI->isMustTailCall();
36318bcb0991SDimitry Andric   });
36328bcb0991SDimitry Andric }
36338bcb0991SDimitry Andric 
runOnMachineFunction(MachineFunction & CurMF)36340b57cec5SDimitry Andric bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
36350b57cec5SDimitry Andric   MF = &CurMF;
36360b57cec5SDimitry Andric   const Function &F = MF->getFunction();
36370b57cec5SDimitry Andric   GISelCSEAnalysisWrapper &Wrapper =
36380b57cec5SDimitry Andric       getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
36390b57cec5SDimitry Andric   // Set the CSEConfig and run the analysis.
36400b57cec5SDimitry Andric   GISelCSEInfo *CSEInfo = nullptr;
36410b57cec5SDimitry Andric   TPC = &getAnalysis<TargetPassConfig>();
36420b57cec5SDimitry Andric   bool EnableCSE = EnableCSEInIRTranslator.getNumOccurrences()
36430b57cec5SDimitry Andric                        ? EnableCSEInIRTranslator
36440b57cec5SDimitry Andric                        : TPC->isGISelCSEEnabled();
36450b57cec5SDimitry Andric 
36460b57cec5SDimitry Andric   if (EnableCSE) {
36478bcb0991SDimitry Andric     EntryBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
36480b57cec5SDimitry Andric     CSEInfo = &Wrapper.get(TPC->getCSEConfig());
36490b57cec5SDimitry Andric     EntryBuilder->setCSEInfo(CSEInfo);
36508bcb0991SDimitry Andric     CurBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
36510b57cec5SDimitry Andric     CurBuilder->setCSEInfo(CSEInfo);
36520b57cec5SDimitry Andric   } else {
36538bcb0991SDimitry Andric     EntryBuilder = std::make_unique<MachineIRBuilder>();
36548bcb0991SDimitry Andric     CurBuilder = std::make_unique<MachineIRBuilder>();
36550b57cec5SDimitry Andric   }
36560b57cec5SDimitry Andric   CLI = MF->getSubtarget().getCallLowering();
36570b57cec5SDimitry Andric   CurBuilder->setMF(*MF);
36580b57cec5SDimitry Andric   EntryBuilder->setMF(*MF);
36590b57cec5SDimitry Andric   MRI = &MF->getRegInfo();
36600b57cec5SDimitry Andric   DL = &F.getParent()->getDataLayout();
36618bcb0991SDimitry Andric   ORE = std::make_unique<OptimizationRemarkEmitter>(&F);
36620b57cec5SDimitry Andric   const TargetMachine &TM = MF->getTarget();
3663e8d8bef9SDimitry Andric   TM.resetTargetOptions(F);
36645f757f3fSDimitry Andric   EnableOpts = OptLevel != CodeGenOptLevel::None && !skipFunction(F);
3665e8d8bef9SDimitry Andric   FuncInfo.MF = MF;
3666fcaf7f86SDimitry Andric   if (EnableOpts) {
3667fcaf7f86SDimitry Andric     AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
3668e8d8bef9SDimitry Andric     FuncInfo.BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
3669fcaf7f86SDimitry Andric   } else {
3670fcaf7f86SDimitry Andric     AA = nullptr;
3671e8d8bef9SDimitry Andric     FuncInfo.BPI = nullptr;
3672fcaf7f86SDimitry Andric   }
3673e8d8bef9SDimitry Andric 
3674bdd1243dSDimitry Andric   AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
3675bdd1243dSDimitry Andric       MF->getFunction());
3676bdd1243dSDimitry Andric   LibInfo = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
3677e8d8bef9SDimitry Andric   FuncInfo.CanLowerReturn = CLI->checkReturnTypeForCallConv(*MF);
3678e8d8bef9SDimitry Andric 
3679e8d8bef9SDimitry Andric   const auto &TLI = *MF->getSubtarget().getTargetLowering();
3680e8d8bef9SDimitry Andric 
36818bcb0991SDimitry Andric   SL = std::make_unique<GISelSwitchLowering>(this, FuncInfo);
36820b57cec5SDimitry Andric   SL->init(TLI, TM, *DL);
36830b57cec5SDimitry Andric 
3684e8d8bef9SDimitry Andric 
36850b57cec5SDimitry Andric 
36860b57cec5SDimitry Andric   assert(PendingPHIs.empty() && "stale PHIs");
36870b57cec5SDimitry Andric 
3688fe6060f1SDimitry Andric   // Targets which want to use big endian can enable it using
3689fe6060f1SDimitry Andric   // enableBigEndian()
3690fe6060f1SDimitry Andric   if (!DL->isLittleEndian() && !CLI->enableBigEndian()) {
36910b57cec5SDimitry Andric     // Currently we don't properly handle big endian code.
36920b57cec5SDimitry Andric     OptimizationRemarkMissed R("gisel-irtranslator", "GISelFailure",
36930b57cec5SDimitry Andric                                F.getSubprogram(), &F.getEntryBlock());
36940b57cec5SDimitry Andric     R << "unable to translate in big endian mode";
36950b57cec5SDimitry Andric     reportTranslationError(*MF, *TPC, *ORE, R);
36960b57cec5SDimitry Andric   }
36970b57cec5SDimitry Andric 
36980b57cec5SDimitry Andric   // Release the per-function state when we return, whether we succeeded or not.
36990b57cec5SDimitry Andric   auto FinalizeOnReturn = make_scope_exit([this]() { finalizeFunction(); });
37000b57cec5SDimitry Andric 
37010b57cec5SDimitry Andric   // Setup a separate basic-block for the arguments and constants
37020b57cec5SDimitry Andric   MachineBasicBlock *EntryBB = MF->CreateMachineBasicBlock();
37030b57cec5SDimitry Andric   MF->push_back(EntryBB);
37040b57cec5SDimitry Andric   EntryBuilder->setMBB(*EntryBB);
37050b57cec5SDimitry Andric 
37060b57cec5SDimitry Andric   DebugLoc DbgLoc = F.getEntryBlock().getFirstNonPHI()->getDebugLoc();
37070b57cec5SDimitry Andric   SwiftError.setFunction(CurMF);
37080b57cec5SDimitry Andric   SwiftError.createEntriesInEntryBlock(DbgLoc);
37090b57cec5SDimitry Andric 
37108bcb0991SDimitry Andric   bool IsVarArg = F.isVarArg();
37118bcb0991SDimitry Andric   bool HasMustTailInVarArgFn = false;
37128bcb0991SDimitry Andric 
37130b57cec5SDimitry Andric   // Create all blocks, in IR order, to preserve the layout.
37140b57cec5SDimitry Andric   for (const BasicBlock &BB: F) {
37150b57cec5SDimitry Andric     auto *&MBB = BBToMBB[&BB];
37160b57cec5SDimitry Andric 
37170b57cec5SDimitry Andric     MBB = MF->CreateMachineBasicBlock(&BB);
37180b57cec5SDimitry Andric     MF->push_back(MBB);
37190b57cec5SDimitry Andric 
37200b57cec5SDimitry Andric     if (BB.hasAddressTaken())
3721bdd1243dSDimitry Andric       MBB->setAddressTakenIRBlock(const_cast<BasicBlock *>(&BB));
37228bcb0991SDimitry Andric 
37238bcb0991SDimitry Andric     if (!HasMustTailInVarArgFn)
37248bcb0991SDimitry Andric       HasMustTailInVarArgFn = checkForMustTailInVarArgFn(IsVarArg, BB);
37250b57cec5SDimitry Andric   }
37260b57cec5SDimitry Andric 
37278bcb0991SDimitry Andric   MF->getFrameInfo().setHasMustTailInVarArgFunc(HasMustTailInVarArgFn);
37288bcb0991SDimitry Andric 
37290b57cec5SDimitry Andric   // Make our arguments/constants entry block fallthrough to the IR entry block.
37300b57cec5SDimitry Andric   EntryBB->addSuccessor(&getMBB(F.front()));
37310b57cec5SDimitry Andric 
3732fe6060f1SDimitry Andric   if (CLI->fallBackToDAGISel(*MF)) {
37335ffd83dbSDimitry Andric     OptimizationRemarkMissed R("gisel-irtranslator", "GISelFailure",
37345ffd83dbSDimitry Andric                                F.getSubprogram(), &F.getEntryBlock());
37355ffd83dbSDimitry Andric     R << "unable to lower function: " << ore::NV("Prototype", F.getType());
37365ffd83dbSDimitry Andric     reportTranslationError(*MF, *TPC, *ORE, R);
37375ffd83dbSDimitry Andric     return false;
37385ffd83dbSDimitry Andric   }
37395ffd83dbSDimitry Andric 
37400b57cec5SDimitry Andric   // Lower the actual args into this basic block.
37410b57cec5SDimitry Andric   SmallVector<ArrayRef<Register>, 8> VRegArgs;
37420b57cec5SDimitry Andric   for (const Argument &Arg: F.args()) {
37435ffd83dbSDimitry Andric     if (DL->getTypeStoreSize(Arg.getType()).isZero())
37440b57cec5SDimitry Andric       continue; // Don't handle zero sized types.
37450b57cec5SDimitry Andric     ArrayRef<Register> VRegs = getOrCreateVRegs(Arg);
37460b57cec5SDimitry Andric     VRegArgs.push_back(VRegs);
37470b57cec5SDimitry Andric 
37480b57cec5SDimitry Andric     if (Arg.hasSwiftErrorAttr()) {
37490b57cec5SDimitry Andric       assert(VRegs.size() == 1 && "Too many vregs for Swift error");
37500b57cec5SDimitry Andric       SwiftError.setCurrentVReg(EntryBB, SwiftError.getFunctionArg(), VRegs[0]);
37510b57cec5SDimitry Andric     }
37520b57cec5SDimitry Andric   }
37530b57cec5SDimitry Andric 
375481ad6265SDimitry Andric   if (!CLI->lowerFormalArguments(*EntryBuilder, F, VRegArgs, FuncInfo)) {
37550b57cec5SDimitry Andric     OptimizationRemarkMissed R("gisel-irtranslator", "GISelFailure",
37560b57cec5SDimitry Andric                                F.getSubprogram(), &F.getEntryBlock());
37570b57cec5SDimitry Andric     R << "unable to lower arguments: " << ore::NV("Prototype", F.getType());
37580b57cec5SDimitry Andric     reportTranslationError(*MF, *TPC, *ORE, R);
37590b57cec5SDimitry Andric     return false;
37600b57cec5SDimitry Andric   }
37610b57cec5SDimitry Andric 
37620b57cec5SDimitry Andric   // Need to visit defs before uses when translating instructions.
37630b57cec5SDimitry Andric   GISelObserverWrapper WrapperObserver;
37640b57cec5SDimitry Andric   if (EnableCSE && CSEInfo)
37650b57cec5SDimitry Andric     WrapperObserver.addObserver(CSEInfo);
37660b57cec5SDimitry Andric   {
37670b57cec5SDimitry Andric     ReversePostOrderTraversal<const Function *> RPOT(&F);
37680b57cec5SDimitry Andric #ifndef NDEBUG
37690b57cec5SDimitry Andric     DILocationVerifier Verifier;
37700b57cec5SDimitry Andric     WrapperObserver.addObserver(&Verifier);
37710b57cec5SDimitry Andric #endif // ifndef NDEBUG
37720b57cec5SDimitry Andric     RAIIDelegateInstaller DelInstall(*MF, &WrapperObserver);
37735ffd83dbSDimitry Andric     RAIIMFObserverInstaller ObsInstall(*MF, WrapperObserver);
37740b57cec5SDimitry Andric     for (const BasicBlock *BB : RPOT) {
37750b57cec5SDimitry Andric       MachineBasicBlock &MBB = getMBB(*BB);
37760b57cec5SDimitry Andric       // Set the insertion point of all the following translations to
37770b57cec5SDimitry Andric       // the end of this basic block.
37780b57cec5SDimitry Andric       CurBuilder->setMBB(MBB);
37798bcb0991SDimitry Andric       HasTailCall = false;
37800b57cec5SDimitry Andric       for (const Instruction &Inst : *BB) {
37818bcb0991SDimitry Andric         // If we translated a tail call in the last step, then we know
37828bcb0991SDimitry Andric         // everything after the call is either a return, or something that is
37838bcb0991SDimitry Andric         // handled by the call itself. (E.g. a lifetime marker or assume
37848bcb0991SDimitry Andric         // intrinsic.) In this case, we should stop translating the block and
37858bcb0991SDimitry Andric         // move on.
37868bcb0991SDimitry Andric         if (HasTailCall)
37878bcb0991SDimitry Andric           break;
37880b57cec5SDimitry Andric #ifndef NDEBUG
37890b57cec5SDimitry Andric         Verifier.setCurrentInst(&Inst);
37900b57cec5SDimitry Andric #endif // ifndef NDEBUG
37917a6dacacSDimitry Andric 
37927a6dacacSDimitry Andric         // Translate any debug-info attached to the instruction.
37937a6dacacSDimitry Andric         translateDbgInfo(Inst, *CurBuilder.get());
37947a6dacacSDimitry Andric 
37950b57cec5SDimitry Andric         if (translate(Inst))
37960b57cec5SDimitry Andric           continue;
37970b57cec5SDimitry Andric 
37980b57cec5SDimitry Andric         OptimizationRemarkMissed R("gisel-irtranslator", "GISelFailure",
37990b57cec5SDimitry Andric                                    Inst.getDebugLoc(), BB);
38000b57cec5SDimitry Andric         R << "unable to translate instruction: " << ore::NV("Opcode", &Inst);
38010b57cec5SDimitry Andric 
38020b57cec5SDimitry Andric         if (ORE->allowExtraAnalysis("gisel-irtranslator")) {
38030b57cec5SDimitry Andric           std::string InstStrStorage;
38040b57cec5SDimitry Andric           raw_string_ostream InstStr(InstStrStorage);
38050b57cec5SDimitry Andric           InstStr << Inst;
38060b57cec5SDimitry Andric 
38070b57cec5SDimitry Andric           R << ": '" << InstStr.str() << "'";
38080b57cec5SDimitry Andric         }
38090b57cec5SDimitry Andric 
38100b57cec5SDimitry Andric         reportTranslationError(*MF, *TPC, *ORE, R);
38110b57cec5SDimitry Andric         return false;
38120b57cec5SDimitry Andric       }
38130b57cec5SDimitry Andric 
38142a66634dSDimitry Andric       if (!finalizeBasicBlock(*BB, MBB)) {
38152a66634dSDimitry Andric         OptimizationRemarkMissed R("gisel-irtranslator", "GISelFailure",
38162a66634dSDimitry Andric                                    BB->getTerminator()->getDebugLoc(), BB);
38172a66634dSDimitry Andric         R << "unable to translate basic block";
38182a66634dSDimitry Andric         reportTranslationError(*MF, *TPC, *ORE, R);
3819349cc55cSDimitry Andric         return false;
38200b57cec5SDimitry Andric       }
38212a66634dSDimitry Andric     }
38220b57cec5SDimitry Andric #ifndef NDEBUG
38230b57cec5SDimitry Andric     WrapperObserver.removeObserver(&Verifier);
38240b57cec5SDimitry Andric #endif
38250b57cec5SDimitry Andric   }
38260b57cec5SDimitry Andric 
38270b57cec5SDimitry Andric   finishPendingPhis();
38280b57cec5SDimitry Andric 
38290b57cec5SDimitry Andric   SwiftError.propagateVRegs();
38300b57cec5SDimitry Andric 
38310b57cec5SDimitry Andric   // Merge the argument lowering and constants block with its single
38320b57cec5SDimitry Andric   // successor, the LLVM-IR entry block.  We want the basic block to
38330b57cec5SDimitry Andric   // be maximal.
38340b57cec5SDimitry Andric   assert(EntryBB->succ_size() == 1 &&
38350b57cec5SDimitry Andric          "Custom BB used for lowering should have only one successor");
38360b57cec5SDimitry Andric   // Get the successor of the current entry block.
38370b57cec5SDimitry Andric   MachineBasicBlock &NewEntryBB = **EntryBB->succ_begin();
38380b57cec5SDimitry Andric   assert(NewEntryBB.pred_size() == 1 &&
38390b57cec5SDimitry Andric          "LLVM-IR entry block has a predecessor!?");
38400b57cec5SDimitry Andric   // Move all the instruction from the current entry block to the
38410b57cec5SDimitry Andric   // new entry block.
38420b57cec5SDimitry Andric   NewEntryBB.splice(NewEntryBB.begin(), EntryBB, EntryBB->begin(),
38430b57cec5SDimitry Andric                     EntryBB->end());
38440b57cec5SDimitry Andric 
38450b57cec5SDimitry Andric   // Update the live-in information for the new entry block.
38460b57cec5SDimitry Andric   for (const MachineBasicBlock::RegisterMaskPair &LiveIn : EntryBB->liveins())
38470b57cec5SDimitry Andric     NewEntryBB.addLiveIn(LiveIn);
38480b57cec5SDimitry Andric   NewEntryBB.sortUniqueLiveIns();
38490b57cec5SDimitry Andric 
38500b57cec5SDimitry Andric   // Get rid of the now empty basic block.
38510b57cec5SDimitry Andric   EntryBB->removeSuccessor(&NewEntryBB);
38520b57cec5SDimitry Andric   MF->remove(EntryBB);
38530eae32dcSDimitry Andric   MF->deleteMachineBasicBlock(EntryBB);
38540b57cec5SDimitry Andric 
38550b57cec5SDimitry Andric   assert(&MF->front() == &NewEntryBB &&
38560b57cec5SDimitry Andric          "New entry wasn't next in the list of basic block!");
38570b57cec5SDimitry Andric 
38580b57cec5SDimitry Andric   // Initialize stack protector information.
38590b57cec5SDimitry Andric   StackProtector &SP = getAnalysis<StackProtector>();
38600b57cec5SDimitry Andric   SP.copyToMachineFrameInfo(MF->getFrameInfo());
38610b57cec5SDimitry Andric 
38620b57cec5SDimitry Andric   return false;
38630b57cec5SDimitry Andric }
3864