70#include "llvm/IR/IntrinsicsAMDGPU.h"
99#define DEBUG_TYPE "irtranslator"
105 cl::desc(
"Should enable CSE in irtranslator"),
117 class ValueToVRegInfo {
119 ValueToVRegInfo() =
default;
124 using const_vreg_iterator =
126 using const_offset_iterator =
129 inline const_vreg_iterator vregs_end()
const {
return ValToVRegs.end(); }
131 VRegListT *getVRegs(
const Value &V) {
132 auto It = ValToVRegs.find(&V);
133 if (It != ValToVRegs.end())
136 return insertVRegs(V);
139 OffsetListT *getOffsets(
const Value &V) {
140 auto It = TypeToOffsets.find(V.getType());
141 if (It != TypeToOffsets.end())
144 return insertOffsets(V);
147 const_vreg_iterator findVRegs(
const Value &V)
const {
148 return ValToVRegs.find(&V);
151 bool contains(
const Value &V)
const {
return ValToVRegs.contains(&V); }
155 TypeToOffsets.clear();
156 VRegAlloc.DestroyAll();
157 OffsetAlloc.DestroyAll();
161 VRegListT *insertVRegs(
const Value &V) {
162 assert(!ValToVRegs.contains(&V) &&
"Value already exists");
166 auto *VRegList =
new (VRegAlloc.Allocate()) VRegListT();
167 ValToVRegs[&V] = VRegList;
171 OffsetListT *insertOffsets(
const Value &V) {
172 assert(!TypeToOffsets.contains(V.getType()) &&
"Type already exists");
174 auto *OffsetList =
new (OffsetAlloc.Allocate()) OffsetListT();
175 TypeToOffsets[V.getType()] = OffsetList;
189 ValueToVRegInfo VMap;
196 using CFGEdge = std::pair<const BasicBlock *, const BasicBlock *>;
251 void translateDbgValueRecord(
Value *V,
bool HasArgList,
260 void translateDbgDeclareRecord(
Value *
Address,
bool HasArgList,
267 bool translateCopy(
const User &U,
const Value &V,
292 bool translateVectorInterleave2Intrinsic(
const CallInst &CI,
294 bool translateVectorDeinterleave2Intrinsic(
const CallInst &CI,
299 bool translateOverflowIntrinsic(
const CallInst &CI,
unsigned Op,
301 bool translateFixedPointIntrinsic(
unsigned Op,
const CallInst &CI,
323 std::optional<MCRegister> getArgPhysReg(
Argument &Arg);
329 bool translateIfEntryValueArgument(
bool isDeclare,
Value *Arg,
344 bool translateIntrinsic(
356 bool findUnwindDestinations(
369 bool translateCast(
unsigned Opcode,
const User &U,
380 return translateCompare(U, MIRBuilder);
385 return translateCompare(U, MIRBuilder);
390 void finishPendingPhis();
394 bool translateUnaryOp(
unsigned Opcode,
const User &U,
399 bool translateBinaryOp(
unsigned Opcode,
const User &U,
405 bool shouldEmitAsBranches(
const std::vector<SwitchCG::CaseBlock> &Cases);
450 bool lowerJumpTableWorkItem(
459 bool FallthroughUnreachable,
465 bool lowerBitTestWorkItem(
471 bool FallthroughUnreachable);
502 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
505 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
508 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
511 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
514 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
517 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
521 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
524 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
527 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
530 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
533 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
536 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
540 return translatePtrToInt(U, MIRBuilder);
543 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
546 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
549 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
552 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
555 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
558 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
561 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
566 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
570 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
574 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
577 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
580 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
584 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
587 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
590 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
593 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
596 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
629 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
644 bool translateConvergenceControlIntrinsic(
const CallInst &CI,
655 std::unique_ptr<MachineIRBuilder> CurBuilder;
660 std::unique_ptr<MachineIRBuilder> EntryBuilder;
673 std::unique_ptr<OptimizationRemarkEmitter> ORE;
684 bool EnableOpts =
false;
688 bool HasTailCall =
false;
692 bool mayTranslateUserTypes(
const User &U)
const;
699 assert(irt &&
"irt is null!");
702 void addSuccessorWithProb(
705 IRT->addSuccessorWithProb(Src, Dst, Prob);
708 ~GISelSwitchLowering()
override =
default;
714 std::unique_ptr<GISelSwitchLowering> SL;
720 void finalizeFunction();
758 auto Regs = getOrCreateVRegs(Val);
761 assert(Regs.size() == 1 &&
762 "attempt to get single VReg for aggregate or void");
766 Register getOrCreateConvergenceTokenVReg(
const Value &Token) {
768 auto &Regs = *VMap.getVRegs(Token);
770 assert(Regs.size() == 1 &&
771 "Expected a single register for convergence tokens.");
775 auto Reg = MRI->createGenericVirtualRegister(
LLT::token());
777 auto &Offsets = *VMap.getOffsets(Token);
779 Offsets.push_back(0);
785 ValueToVRegInfo::VRegListT &allocateVRegs(
const Value &Val);
789 int getOrCreateFrameIndex(
const AllocaInst &AI);
812 auto RemappedEdge = MachinePreds.find(Edge);
813 if (RemappedEdge != MachinePreds.end())
814 return RemappedEdge->second;
823 void addSuccessorWithProb(
829 : OptLevel(OptLevel) {}
859 "IRTranslator LLVM IR -> MI",
false,
false)
871 MF.getProperties().setFailedISel();
872 bool IsGlobalISelAbortEnabled =
877 if (!R.getLocation().isValid() || IsGlobalISelAbortEnabled)
878 R << (
" (in function: " + MF.getName() +
")").str();
880 if (IsGlobalISelAbortEnabled)
900 DILocationVerifier() =
default;
901 ~DILocationVerifier()
override =
default;
903 const Instruction *getCurrentInst()
const {
return CurrInst; }
904 void setCurrentInst(
const Instruction *Inst) { CurrInst = Inst; }
906 void erasingInstr(MachineInstr &
MI)
override {}
907 void changingInstr(MachineInstr &
MI)
override {}
908 void changedInstr(MachineInstr &
MI)
override {}
910 void createdInstr(MachineInstr &
MI)
override {
911 assert(getCurrentInst() &&
"Inserted instruction without a current MI");
916 <<
" was copied to " <<
MI);
922 (
MI.getParent()->isEntryBlock() && !
MI.getDebugLoc()) ||
923 (
MI.isDebugInstr())) &&
924 "Line info was not transferred to all instructions");
947IRTranslatorImpl::ValueToVRegInfo::VRegListT &
948IRTranslatorImpl::allocateVRegs(
const Value &Val) {
949 auto VRegsIt = VMap.findVRegs(Val);
950 if (VRegsIt != VMap.vregs_end())
951 return *VRegsIt->second;
952 auto *Regs = VMap.getVRegs(Val);
953 auto *Offsets = VMap.getOffsets(Val);
956 Offsets->empty() ? Offsets :
nullptr);
957 for (
unsigned i = 0; i < SplitTys.
size(); ++i)
963 auto VRegsIt = VMap.findVRegs(Val);
964 if (VRegsIt != VMap.vregs_end())
965 return *VRegsIt->second;
968 return *VMap.getVRegs(Val);
971 auto *VRegs = VMap.getVRegs(Val);
972 auto *Offsets = VMap.getOffsets(Val);
976 "Don't know how to create an empty vreg");
981 if (Offsets->empty())
982 Offsets->push_back(0);
990 R <<
"unable to translate constant: " <<
ore::NV(
"Type", Val.
getType());
999 Offsets->empty() ? Offsets :
nullptr);
1002 for (
auto Ty : SplitTys)
1003 VRegs->push_back(MRI->createGenericVirtualRegister(Ty));
1010 while (
auto Elt =
C.getAggregateElement(Idx++)) {
1011 auto EltRegs = getOrCreateVRegs(*Elt);
1018int IRTranslatorImpl::getOrCreateFrameIndex(
const AllocaInst &AI) {
1019 auto [MapEntry,
Inserted] = FrameIndices.try_emplace(&AI);
1021 return MapEntry->second;
1027 Size = std::max<uint64_t>(
Size, 1u);
1029 int &FI = MapEntry->second;
1030 FI = MF->getFrameInfo().CreateStackObject(
Size, AI.
getAlign(),
false, &AI);
1037 MF->getSubtarget().getFrameLowering()->getStackIDForScalableVectors();
1038 MF->getFrameInfo().setStackID(FI, StackID);
1046 return SI->getAlign();
1048 return LI->getAlign();
1054 OptimizationRemarkMissed
R(
"gisel-irtranslator",
"", &
I);
1055 R <<
"unable to translate memop: " <<
ore::NV(
"Opcode", &
I);
1061 MachineBasicBlock *
MBB = FuncInfo.getMBB(&BB);
1062 assert(
MBB &&
"BasicBlock was not encountered before");
1066void IRTranslatorImpl::addMachineCFGPred(CFGEdge
Edge,
1068 assert(NewPred &&
"new predecessor must be a real MachineBasicBlock");
1069 MachinePreds[
Edge].push_back(NewPred);
1072bool IRTranslatorImpl::translateBinaryOp(
unsigned Opcode,
const User &U,
1074 if (!mayTranslateUserTypes(U))
1081 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1082 Register Op1 = getOrCreateVReg(*
U.getOperand(1));
1094bool IRTranslatorImpl::translateUnaryOp(
unsigned Opcode,
const User &U,
1096 if (!mayTranslateUserTypes(U))
1099 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1110bool IRTranslatorImpl::translateFNeg(
const User &U,
1112 return translateUnaryOp(TargetOpcode::G_FNEG, U, MIRBuilder);
1115bool IRTranslatorImpl::translateCompare(
const User &U,
1117 if (!mayTranslateUserTypes(U))
1121 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1122 Register Op1 = getOrCreateVReg(*
U.getOperand(1));
1127 MIRBuilder.
buildICmp(Pred, Res, Op0, Op1, Flags);
1135 MIRBuilder.
buildFCmp(Pred, Res, Op0, Op1, Flags);
1140bool IRTranslatorImpl::translateRet(
const User &U,
1144 if (Ret && DL->getTypeStoreSize(Ret->
getType()).isZero())
1149 VRegs = getOrCreateVRegs(*Ret);
1152 if (CLI->supportSwiftError() && SwiftError.getFunctionArg()) {
1153 SwiftErrorVReg = SwiftError.getOrCreateVRegUseAt(
1154 &RI, &MIRBuilder.
getMBB(), SwiftError.getFunctionArg());
1160 return CLI->lowerReturn(MIRBuilder, Ret, VRegs, FuncInfo, SwiftErrorVReg);
1163void IRTranslatorImpl::emitBranchForMergedCondition(
1172 Condition = InvertCond ? IC->getInversePredicate() : IC->getPredicate();
1175 Condition = InvertCond ?
FC->getInversePredicate() :
FC->getPredicate();
1178 SwitchCG::CaseBlock CB(Condition,
false, BOp->getOperand(0),
1179 BOp->getOperand(1),
nullptr,
TBB, FBB, CurBB,
1180 CurBuilder->getDebugLoc(), TProb, FProb);
1181 SL->SwitchCases.push_back(CB);
1187 SwitchCG::CaseBlock CB(
1189 nullptr,
TBB, FBB, CurBB, CurBuilder->getDebugLoc(), TProb, FProb);
1190 SL->SwitchCases.push_back(CB);
1195 return I->getParent() == BB;
1199void IRTranslatorImpl::findMergedConditions(
1204 using namespace PatternMatch;
1205 assert((
Opc == Instruction::And ||
Opc == Instruction::Or) &&
1206 "Expected Opc to be AND/OR");
1212 findMergedConditions(NotCond,
TBB, FBB, CurBB, SwitchBB,
Opc, TProb, FProb,
1218 const Value *BOpOp0, *BOpOp1;
1232 if (BOpc == Instruction::And)
1233 BOpc = Instruction::Or;
1234 else if (BOpc == Instruction::Or)
1235 BOpc = Instruction::And;
1241 bool BOpIsInOrAndTree = BOpc && BOpc ==
Opc && BOp->
hasOneUse();
1245 emitBranchForMergedCondition(
Cond,
TBB, FBB, CurBB, SwitchBB, TProb, FProb,
1252 MachineBasicBlock *TmpBB =
1256 if (
Opc == Instruction::Or) {
1277 auto NewTrueProb = TProb / 2;
1278 auto NewFalseProb = TProb / 2 + FProb;
1280 findMergedConditions(BOpOp0,
TBB, TmpBB, CurBB, SwitchBB,
Opc, NewTrueProb,
1281 NewFalseProb, InvertCond);
1287 findMergedConditions(BOpOp1,
TBB, FBB, TmpBB, SwitchBB,
Opc, Probs[0],
1288 Probs[1], InvertCond);
1290 assert(
Opc == Instruction::And &&
"Unknown merge op!");
1310 auto NewTrueProb = TProb + FProb / 2;
1311 auto NewFalseProb = FProb / 2;
1313 findMergedConditions(BOpOp0, TmpBB, FBB, CurBB, SwitchBB,
Opc, NewTrueProb,
1314 NewFalseProb, InvertCond);
1320 findMergedConditions(BOpOp1,
TBB, FBB, TmpBB, SwitchBB,
Opc, Probs[0],
1321 Probs[1], InvertCond);
1325bool IRTranslatorImpl::shouldEmitAsBranches(
1326 const std::vector<SwitchCG::CaseBlock> &Cases) {
1328 if (Cases.size() != 2)
1333 if ((Cases[0].CmpLHS == Cases[1].CmpLHS &&
1334 Cases[0].CmpRHS == Cases[1].CmpRHS) ||
1335 (Cases[0].CmpRHS == Cases[1].CmpLHS &&
1336 Cases[0].CmpLHS == Cases[1].CmpRHS)) {
1342 if (Cases[0].CmpRHS == Cases[1].CmpRHS &&
1343 Cases[0].PredInfo.Pred == Cases[1].PredInfo.Pred &&
1347 Cases[0].TrueBB == Cases[1].ThisBB)
1350 Cases[0].FalseBB == Cases[1].ThisBB)
1357bool IRTranslatorImpl::translateUncondBr(
const User &U,
1360 auto &CurMBB = MIRBuilder.
getMBB();
1365 MIRBuilder.
buildBr(*Succ0MBB);
1368 for (
const BasicBlock *Succ :
successors(&BrInst))
1373bool IRTranslatorImpl::translateCondBr(
const User &U,
1376 auto &CurMBB = MIRBuilder.
getMBB();
1382 MachineBasicBlock *Succ1MBB = &getMBB(*BrInst.
getSuccessor(1));
1401 using namespace PatternMatch;
1403 if (!TLI->isJumpExpensive() && CondI && CondI->
hasOneUse() &&
1404 !BrInst.
hasMetadata(LLVMContext::MD_unpredictable)) {
1407 const Value *BOp0, *BOp1;
1409 Opcode = Instruction::And;
1411 Opcode = Instruction::Or;
1415 findMergedConditions(CondI, Succ0MBB, Succ1MBB, &CurMBB, &CurMBB, Opcode,
1416 getEdgeProbability(&CurMBB, Succ0MBB),
1417 getEdgeProbability(&CurMBB, Succ1MBB),
1419 assert(SL->SwitchCases[0].ThisBB == &CurMBB &&
"Unexpected lowering!");
1422 if (shouldEmitAsBranches(SL->SwitchCases)) {
1424 emitSwitchCase(SL->SwitchCases[0], &CurMBB, *CurBuilder);
1425 SL->SwitchCases.erase(SL->SwitchCases.begin());
1431 for (
unsigned I = 1,
E = SL->SwitchCases.size();
I !=
E; ++
I)
1432 MF->erase(SL->SwitchCases[
I].ThisBB);
1434 SL->SwitchCases.clear();
1441 nullptr, Succ0MBB, Succ1MBB, &CurMBB,
1442 CurBuilder->getDebugLoc());
1446 emitSwitchCase(CB, &CurMBB, *CurBuilder);
1453 if (!FuncInfo.BPI) {
1454 Src->addSuccessorWithoutProb(Dst);
1458 Prob = getEdgeProbability(Src, Dst);
1459 Src->addSuccessor(Dst, Prob);
1465 const BasicBlock *SrcBB = Src->getBasicBlock();
1466 const BasicBlock *DstBB = Dst->getBasicBlock();
1467 if (!FuncInfo.BPI) {
1470 auto SuccSize = std::max<uint32_t>(
succ_size(SrcBB), 1);
1471 return BranchProbability(1, SuccSize);
1473 return FuncInfo.BPI->getEdgeProbability(SrcBB, DstBB);
1477 using namespace SwitchCG;
1480 BranchProbabilityInfo *BPI = FuncInfo.BPI;
1482 Clusters.reserve(
SI.getNumCases());
1483 for (
const auto &
I :
SI.cases()) {
1484 MachineBasicBlock *Succ = &getMBB(*
I.getCaseSuccessor());
1485 assert(Succ &&
"Could not find successor mbb in mapping");
1486 const ConstantInt *CaseVal =
I.getCaseValue();
1487 BranchProbability Prob =
1489 : BranchProbability(1,
SI.getNumCases() + 1);
1490 Clusters.push_back(CaseCluster::range(CaseVal, CaseVal, Succ, Prob));
1493 MachineBasicBlock *DefaultMBB = &getMBB(*
SI.getDefaultDest());
1500 MachineBasicBlock *SwitchMBB = &getMBB(*
SI.getParent());
1503 if (Clusters.empty()) {
1510 SL->findJumpTables(Clusters, &SI, std::nullopt, DefaultMBB,
nullptr,
nullptr);
1511 SL->findBitTestClusters(Clusters, &SI);
1514 dbgs() <<
"Case clusters: ";
1515 for (
const CaseCluster &
C : Clusters) {
1516 if (
C.Kind == CC_JumpTable)
1518 if (
C.Kind == CC_BitTests)
1521 C.Low->getValue().print(
dbgs(),
true);
1522 if (
C.Low !=
C.High) {
1524 C.High->getValue().print(
dbgs(),
true);
1531 assert(!Clusters.empty());
1535 auto DefaultProb = getEdgeProbability(SwitchMBB, DefaultMBB);
1536 WorkList.push_back({SwitchMBB,
First,
Last,
nullptr,
nullptr, DefaultProb});
1538 while (!WorkList.empty()) {
1539 SwitchWorkListItem
W = WorkList.pop_back_val();
1541 unsigned NumClusters =
W.LastCluster -
W.FirstCluster + 1;
1543 if (NumClusters > 3 &&
1546 splitWorkItem(WorkList, W,
SI.getCondition(), SwitchMBB, MIB);
1550 if (!lowerSwitchWorkItem(W,
SI.getCondition(), SwitchMBB, DefaultMBB, MIB))
1560 using namespace SwitchCG;
1561 assert(
W.FirstCluster->Low->getValue().slt(
W.LastCluster->Low->getValue()) &&
1562 "Clusters not sorted?");
1563 assert(
W.LastCluster -
W.FirstCluster + 1 >= 2 &&
"Too small to split!");
1565 auto [LastLeft, FirstRight, LeftProb, RightProb] =
1566 SL->computeSplitWorkItemInfo(W);
1571 assert(PivotCluster >
W.FirstCluster);
1572 assert(PivotCluster <=
W.LastCluster);
1577 const ConstantInt *Pivot = PivotCluster->Low;
1586 MachineBasicBlock *LeftMBB;
1587 if (FirstLeft == LastLeft && FirstLeft->Kind == CC_Range &&
1588 FirstLeft->Low ==
W.GE &&
1589 (FirstLeft->High->getValue() + 1LL) == Pivot->
getValue()) {
1590 LeftMBB = FirstLeft->MBB;
1592 LeftMBB = FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
1593 FuncInfo.MF->
insert(BBI, LeftMBB);
1595 {LeftMBB, FirstLeft, LastLeft,
W.GE, Pivot,
W.DefaultProb / 2});
1601 MachineBasicBlock *RightMBB;
1602 if (FirstRight == LastRight && FirstRight->Kind == CC_Range &&
W.LT &&
1603 (FirstRight->High->getValue() + 1ULL) ==
W.LT->getValue()) {
1604 RightMBB = FirstRight->MBB;
1606 RightMBB = FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
1607 FuncInfo.MF->
insert(BBI, RightMBB);
1609 {RightMBB, FirstRight, LastRight, Pivot,
W.LT,
W.DefaultProb / 2});
1617 if (
W.MBB == SwitchMBB)
1618 emitSwitchCase(CB, SwitchMBB, MIB);
1620 SL->SwitchCases.push_back(CB);
1626 assert(JT.
Reg &&
"Should lower JT Header first!");
1641 MachineIRBuilder MIB(*HeaderBB->
getParent());
1648 Register SwitchOpReg = getOrCreateVReg(SValue);
1650 auto Sub = MIB.
buildSub({SwitchTy}, SwitchOpReg, FirstCst);
1655 const LLT PtrScalarTy =
LLT::integer(DL->getTypeSizeInBits(PtrIRTy));
1669 auto Cst = getOrCreateVReg(
1710 if (MRI->getType(CondLHS).getSizeInBits() == 1 && CI && CI->isOne() &&
1724 "Can only handle SLE ranges");
1735 const LLT CmpTy = MRI->getType(CmpOpReg);
1736 auto Sub = MIB.
buildSub({CmpTy}, CmpOpReg, CondLHS);
1762bool IRTranslatorImpl::lowerJumpTableWorkItem(
1768 using namespace SwitchCG;
1771 JumpTableHeader *JTH = &SL->JTCases[
I->JTCasesIndex].first;
1772 SwitchCG::JumpTable *JT = &SL->JTCases[
I->JTCasesIndex].second;
1773 BranchProbability DefaultProb =
W.DefaultProb;
1776 MachineBasicBlock *JumpMBB = JT->
MBB;
1777 CurMF->
insert(BBI, JumpMBB);
1787 auto JumpProb =
I->Prob;
1788 auto FallthroughProb = UnhandledProbs;
1796 if (*SI == DefaultMBB) {
1797 JumpProb += DefaultProb / 2;
1798 FallthroughProb -= DefaultProb / 2;
1803 addMachineCFGPred({SwitchMBB->
getBasicBlock(), (*SI)->getBasicBlock()},
1808 if (FallthroughUnreachable)
1809 JTH->FallthroughUnreachable =
true;
1811 if (!JTH->FallthroughUnreachable)
1812 addSuccessorWithProb(CurMBB, Fallthrough, FallthroughProb);
1813 addSuccessorWithProb(CurMBB, JumpMBB, JumpProb);
1818 JTH->HeaderBB = CurMBB;
1822 if (CurMBB == SwitchMBB) {
1823 if (!emitJumpTableHeader(*JT, *JTH, CurMBB))
1825 JTH->Emitted =
true;
1829bool IRTranslatorImpl::lowerSwitchRangeWorkItem(
1834 using namespace SwitchCG;
1837 if (
I->Low ==
I->High) {
1853 CaseBlock CB(Pred, FallthroughUnreachable,
LHS,
RHS, MHS,
I->MBB, Fallthrough,
1856 emitSwitchCase(CB, SwitchMBB, MIB);
1862 MachineIRBuilder &MIB = *CurBuilder;
1866 Register SwitchOpReg = getOrCreateVReg(*
B.SValue);
1868 LLT SwitchOpTy = MRI->getType(SwitchOpReg);
1870 auto RangeSub = MIB.
buildSub(SwitchOpTy, SwitchOpReg, MinValReg);
1875 LLT MaskTy = SwitchOpTy;
1881 for (
const SwitchCG::BitTestCase &Case :
B.Cases) {
1890 Register SubReg = RangeSub.getReg(0);
1891 if (SwitchOpTy != MaskTy)
1897 MachineBasicBlock *
MBB =
B.Cases[0].ThisBB;
1899 if (!
B.FallthroughUnreachable)
1900 addSuccessorWithProb(SwitchBB,
B.Default,
B.DefaultProb);
1901 addSuccessorWithProb(SwitchBB,
MBB,
B.Prob);
1905 if (!
B.FallthroughUnreachable) {
1909 RangeSub, RangeCst);
1923 MachineIRBuilder &MIB = *CurBuilder;
1929 if (PopCount == 1) {
1932 auto MaskTrailingZeros =
1937 }
else if (PopCount == BB.
Range) {
1939 auto MaskTrailingOnes =
1947 auto SwitchVal = MIB.
buildShl(SwitchTy, CstOne,
Reg);
1951 auto AndOp = MIB.
buildAnd(SwitchTy, SwitchVal, CstMask);
1958 addSuccessorWithProb(SwitchBB,
B.TargetBB,
B.ExtraProb);
1960 addSuccessorWithProb(SwitchBB, NextMBB, BranchProbToNext);
1978bool IRTranslatorImpl::lowerBitTestWorkItem(
1984 bool FallthroughUnreachable) {
1985 using namespace SwitchCG;
1988 BitTestBlock *BTB = &SL->BitTestCases[
I->BTCasesIndex];
1990 for (BitTestCase &BTC : BTB->Cases)
1991 CurMF->
insert(BBI, BTC.ThisBB);
1994 BTB->Parent = CurMBB;
1995 BTB->Default = Fallthrough;
1997 BTB->DefaultProb = UnhandledProbs;
2001 if (!BTB->ContiguousRange) {
2002 BTB->Prob += DefaultProb / 2;
2003 BTB->DefaultProb -= DefaultProb / 2;
2006 if (FallthroughUnreachable)
2007 BTB->FallthroughUnreachable =
true;
2010 if (CurMBB == SwitchMBB) {
2011 emitBitTestHeader(*BTB, SwitchMBB);
2012 BTB->Emitted =
true;
2022 using namespace SwitchCG;
2024 MachineBasicBlock *NextMBB =
nullptr;
2026 if (++BBI != FuncInfo.MF->end())
2035 [](
const CaseCluster &a,
const CaseCluster &b) {
2036 return a.Prob != b.Prob
2038 : a.Low->getValue().slt(b.Low->getValue());
2043 for (CaseClusterIt
I =
W.LastCluster;
I >
W.FirstCluster;) {
2045 if (
I->Prob >
W.LastCluster->Prob)
2047 if (
I->Kind == CC_Range &&
I->MBB == NextMBB) {
2055 BranchProbability DefaultProb =
W.DefaultProb;
2056 BranchProbability UnhandledProbs = DefaultProb;
2057 for (CaseClusterIt
I =
W.FirstCluster;
I <=
W.LastCluster; ++
I)
2058 UnhandledProbs +=
I->Prob;
2060 MachineBasicBlock *CurMBB =
W.MBB;
2061 for (CaseClusterIt
I =
W.FirstCluster,
E =
W.LastCluster;
I <=
E; ++
I) {
2062 bool FallthroughUnreachable =
false;
2063 MachineBasicBlock *Fallthrough;
2064 if (
I ==
W.LastCluster) {
2066 Fallthrough = DefaultMBB;
2071 CurMF->
insert(BBI, Fallthrough);
2073 UnhandledProbs -=
I->Prob;
2077 if (!lowerBitTestWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
2078 DefaultProb, UnhandledProbs,
I, Fallthrough,
2079 FallthroughUnreachable)) {
2087 if (!lowerJumpTableWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
2088 UnhandledProbs,
I, Fallthrough,
2089 FallthroughUnreachable)) {
2096 if (!lowerSwitchRangeWorkItem(
I,
Cond, Fallthrough,
2097 FallthroughUnreachable, UnhandledProbs,
2098 CurMBB, MIB, SwitchMBB)) {
2105 CurMBB = Fallthrough;
2111bool IRTranslatorImpl::translateIndirectBr(
const User &U,
2119 SmallPtrSet<const BasicBlock *, 32> AddedSuccessors;
2120 MachineBasicBlock &CurBB = MIRBuilder.
getMBB();
2121 for (
const BasicBlock *Succ :
successors(&BrInst)) {
2125 if (!AddedSuccessors.
insert(Succ).second)
2141bool IRTranslatorImpl::translateLoad(
const User &U,
2144 TypeSize StoreSize = DL->getTypeStoreSize(LI.
getType());
2155 assert(Regs.
size() == 1 &&
"swifterror should be single pointer");
2157 SwiftError.getOrCreateVRegUseAt(&LI, &MIRBuilder.
getMBB(), Ptr);
2163 TLI->getLoadMemOperandFlags(LI, *DL, AC, LibInfo, OptLevel);
2165 if (AA->pointsToConstantMemory(
2172 if (Regs.
size() == 1) {
2173 auto *MMO = MF->getMachineMemOperand(
2175 MRI->getType(Regs[0]), getMemOpAlign(LI),
2176 MMOMetadata(AAInfo, LI.
getMetadata(LLVMContext::MD_range)),
2182 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(LI);
2183 Type *OffsetIRTy = DL->getIndexType(Ptr->
getType());
2185 for (
unsigned i = 0; i < Regs.
size(); ++i) {
2190 Align BaseAlign = getMemOpAlign(LI);
2192 MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Regs[i]),
2195 MIRBuilder.
buildLoad(Regs[i], Addr, *MMO);
2201bool IRTranslatorImpl::translateStore(
const User &U,
2204 if (DL->getTypeStoreSize(
SI.getValueOperand()->getType()).isZero())
2210 if (CLI->supportSwiftError() &&
isSwiftError(
SI.getPointerOperand())) {
2211 assert(Vals.
size() == 1 &&
"swifterror should be single pointer");
2213 Register VReg = SwiftError.getOrCreateVRegDefAt(&SI, &MIRBuilder.
getMBB(),
2214 SI.getPointerOperand());
2221 if (Vals.
size() == 1) {
2222 auto *MMO = MF->getMachineMemOperand(
2223 MachinePointerInfo(
SI.getPointerOperand()), Flags,
2224 MRI->getType(Vals[0]), getMemOpAlign(SI),
SI.getAAMetadata(),
2225 SI.getSyncScopeID(),
SI.getOrdering());
2230 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(*
SI.getValueOperand());
2231 Type *OffsetIRTy = DL->getIndexType(
SI.getPointerOperandType());
2233 for (
unsigned i = 0; i < Vals.
size(); ++i) {
2237 MachinePointerInfo Ptr(
SI.getPointerOperand(), Offsets[i]);
2238 Align BaseAlign = getMemOpAlign(SI);
2239 auto *MMO = MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Vals[i]),
2242 SI.getSyncScopeID(),
SI.getOrdering());
2249 const Value *Src = U.getOperand(0);
2255 Indices.
push_back(ConstantInt::get(Int32Ty, 0));
2258 for (
auto Idx : EVI->indices())
2259 Indices.
push_back(ConstantInt::get(Int32Ty, Idx));
2261 for (
auto Idx : IVI->indices())
2262 Indices.
push_back(ConstantInt::get(Int32Ty, Idx));
2268 DL.getIndexedOffsetInType(Src->getType(), Indices));
2271bool IRTranslatorImpl::translateExtractValue(
const User &U,
2273 const Value *Src =
U.getOperand(0);
2276 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(*Src);
2278 auto &DstRegs = allocateVRegs(U);
2280 for (
unsigned i = 0; i < DstRegs.size(); ++i)
2281 DstRegs[i] = SrcRegs[Idx++];
2286bool IRTranslatorImpl::translateInsertValue(
const User &U,
2288 const Value *Src =
U.getOperand(0);
2290 auto &DstRegs = allocateVRegs(U);
2291 ArrayRef<uint64_t> DstOffsets = *VMap.getOffsets(U);
2294 auto *InsertedIt = InsertedRegs.
begin();
2296 for (
unsigned i = 0; i < DstRegs.size(); ++i) {
2297 if (DstOffsets[i] >=
Offset && InsertedIt != InsertedRegs.
end())
2298 DstRegs[i] = *InsertedIt++;
2300 DstRegs[i] = SrcRegs[i];
2306bool IRTranslatorImpl::translateSelect(
const User &U,
2308 Register Tst = getOrCreateVReg(*
U.getOperand(0));
2317 for (
unsigned i = 0; i < ResRegs.
size(); ++i) {
2318 MIRBuilder.
buildSelect(ResRegs[i], Tst, Op0Regs[i], Op1Regs[i], Flags);
2324bool IRTranslatorImpl::translateCopy(
const User &U,
const Value &V,
2326 return translateCopy(U, getOrCreateVReg(V), MIRBuilder);
2329bool IRTranslatorImpl::translateCopy(
const User &U,
Register Src,
2331 auto &Regs = *VMap.getVRegs(U);
2333 Regs.push_back(Src);
2334 VMap.getOffsets(U)->push_back(0);
2343bool IRTranslatorImpl::translateBitCast(
const User &U,
2345 Type *SrcTy =
U.getOperand(0)->getType();
2346 Type *DstTy =
U.getType();
2353 return translateCast(TargetOpcode::G_CONSTANT_FOLD_BARRIER, U,
2355 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
2365 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
2367 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
2369 return translateCast(TargetOpcode::G_BITCAST, U, MIRBuilder);
2372bool IRTranslatorImpl::translateCast(
unsigned Opcode,
const User &U,
2374 if (!mayTranslateUserTypes(U))
2387bool IRTranslatorImpl::translateGetElementPtr(
const User &U,
2389 Value &Op0 = *
U.getOperand(0);
2393 Type *OffsetIRTy = DL->getIndexType(PtrIRTy);
2396 uint32_t PtrAddFlags = 0;
2402 auto PtrAddFlagsWithConst = [&](int64_t
Offset) {
2412 unsigned VectorWidth = 0;
2416 bool WantSplatVector =
false;
2420 WantSplatVector = VectorWidth > 1;
2424 return translateCopy(U, BaseReg, MIRBuilder);
2428 if (WantSplatVector && !PtrTy.
isVector()) {
2435 OffsetIRTy = DL->getIndexType(PtrIRTy);
2442 const Value *Idx = GTI.getOperand();
2443 if (StructType *StTy = GTI.getStructTypeOrNull()) {
2445 Offset += DL->getStructLayout(StTy)->getElementOffset(
Field);
2448 uint64_t ElementSize = GTI.getSequentialElementStride(*DL);
2453 if (std::optional<int64_t> Val = CI->getValue().trySExtValue()) {
2454 Offset += ElementSize * *Val;
2463 PtrAddFlagsWithConst(
Offset))
2468 Register IdxReg = getOrCreateVReg(*Idx);
2469 LLT IdxTy = MRI->getType(IdxReg);
2470 if (IdxTy != OffsetTy) {
2471 if (!IdxTy.
isVector() && WantSplatVector) {
2484 if (ElementSize != 1) {
2495 MIRBuilder.
buildMul(OffsetTy, IdxReg, ElementSizeMIB, ScaleFlags)
2498 GepOffsetReg = IdxReg;
2502 MIRBuilder.
buildPtrAdd(PtrTy, BaseReg, GepOffsetReg, PtrAddFlags)
2511 MIRBuilder.
buildPtrAdd(getOrCreateVReg(U), BaseReg, OffsetMIB.getReg(0),
2512 PtrAddFlagsWithConst(
Offset));
2516 return translateCopy(U, BaseReg, MIRBuilder);
2519bool IRTranslatorImpl::translateMemFunc(
const CallInst &CI,
2529 unsigned MinPtrSize = UINT_MAX;
2530 for (
auto AI = CI.
arg_begin(), AE = CI.
arg_end(); std::next(AI) != AE; ++AI) {
2531 Register SrcReg = getOrCreateVReg(**AI);
2532 LLT SrcTy = MRI->getType(SrcReg);
2534 MinPtrSize = std::min<unsigned>(SrcTy.
getSizeInBits(), MinPtrSize);
2542 if (MRI->getType(SizeOpReg) != SizeTy)
2554 ConstantInt *CopySize =
nullptr;
2557 DstAlign = MCI->getDestAlign().valueOrOne();
2558 SrcAlign = MCI->getSourceAlign().valueOrOne();
2561 DstAlign = MMI->getDestAlign().valueOrOne();
2562 SrcAlign = MMI->getSourceAlign().valueOrOne();
2566 DstAlign = MSI->getDestAlign().valueOrOne();
2569 if (Opcode != TargetOpcode::G_MEMCPY_INLINE &&
2570 Opcode != TargetOpcode::G_MEMSET_INLINE) {
2586 if (AA && CopySize &&
2587 AA->pointsToConstantMemory(MemoryLocation(
2597 ICall.addMemOperand(
2598 MF->getMachineMemOperand(MachinePointerInfo(CI.
getArgOperand(0)),
2599 StoreFlags, 1, DstAlign, AAInfo));
2600 if (Opcode != TargetOpcode::G_MEMSET &&
2601 Opcode != TargetOpcode::G_MEMSET_INLINE)
2602 ICall.addMemOperand(MF->getMachineMemOperand(
2603 MachinePointerInfo(SrcPtr), LoadFlags, 1, SrcAlign, AAInfo));
2608bool IRTranslatorImpl::translateTrap(
const CallInst &CI,
2611 StringRef TrapFuncName =
2612 CI.
getAttributes().getFnAttr(
"trap-func-name").getValueAsString();
2613 if (TrapFuncName.
empty()) {
2614 if (Opcode == TargetOpcode::G_UBSANTRAP) {
2623 CallLowering::CallLoweringInfo
Info;
2624 if (Opcode == TargetOpcode::G_UBSANTRAP)
2631 return CLI->lowerCall(MIRBuilder, Info);
2634bool IRTranslatorImpl::translateVectorInterleave2Intrinsic(
2637 "This function can only be called on the interleave2 intrinsic!");
2641 Register Res = getOrCreateVReg(CI);
2643 LLT OpTy = MRI->getType(Op0);
2650bool IRTranslatorImpl::translateVectorDeinterleave2Intrinsic(
2653 "This function can only be called on the deinterleave2 intrinsic!");
2660 LLT ResTy = MRI->getType(Res[0]);
2677void IRTranslatorImpl::getStackGuard(
Register DstReg,
2680 TLI->getSDagStackGuard(*MF->getFunction().getParent(), *Libcalls);
2683 Ctx.
diagnose(DiagnosticInfoGeneric(
"unable to lower stackguard"));
2688 const TargetRegisterInfo *
TRI = MF->getSubtarget().getRegisterInfo();
2689 MRI->setRegClass(DstReg,
TRI->getPointerRegClass());
2691 MIRBuilder.
buildInstr(TargetOpcode::LOAD_STACK_GUARD, {DstReg}, {});
2693 unsigned AddrSpace =
Global->getType()->getPointerAddressSpace();
2694 LLT PtrTy =
LLT::pointer(AddrSpace, DL->getPointerSizeInBits(AddrSpace));
2696 MachinePointerInfo MPInfo(
Global);
2699 MachineMemOperand *MemRef = MF->getMachineMemOperand(
2700 MPInfo, Flags, PtrTy, DL->getPointerABIAlignment(AddrSpace));
2701 MIB.setMemRefs({MemRef});
2704bool IRTranslatorImpl::translateOverflowIntrinsic(
2708 Op, {ResRegs[0], ResRegs[1]},
2714bool IRTranslatorImpl::translateFixedPointIntrinsic(
2716 Register Dst = getOrCreateVReg(CI);
2720 MIRBuilder.
buildInstr(
Op, {Dst}, { Src0, Src1, Scale });
2724unsigned IRTranslatorImpl::getSimpleIntrinsicOpcode(
Intrinsic::ID ID) {
2728 case Intrinsic::acos:
2729 return TargetOpcode::G_FACOS;
2730 case Intrinsic::asin:
2731 return TargetOpcode::G_FASIN;
2732 case Intrinsic::atan:
2733 return TargetOpcode::G_FATAN;
2734 case Intrinsic::atan2:
2735 return TargetOpcode::G_FATAN2;
2736 case Intrinsic::bswap:
2737 return TargetOpcode::G_BSWAP;
2738 case Intrinsic::bitreverse:
2739 return TargetOpcode::G_BITREVERSE;
2740 case Intrinsic::fshl:
2741 return TargetOpcode::G_FSHL;
2742 case Intrinsic::fshr:
2743 return TargetOpcode::G_FSHR;
2744 case Intrinsic::ceil:
2745 return TargetOpcode::G_FCEIL;
2746 case Intrinsic::cos:
2747 return TargetOpcode::G_FCOS;
2748 case Intrinsic::cosh:
2749 return TargetOpcode::G_FCOSH;
2750 case Intrinsic::ctpop:
2751 return TargetOpcode::G_CTPOP;
2752 case Intrinsic::exp:
2753 return TargetOpcode::G_FEXP;
2754 case Intrinsic::exp2:
2755 return TargetOpcode::G_FEXP2;
2756 case Intrinsic::exp10:
2757 return TargetOpcode::G_FEXP10;
2758 case Intrinsic::fabs:
2759 return TargetOpcode::G_FABS;
2760 case Intrinsic::copysign:
2761 return TargetOpcode::G_FCOPYSIGN;
2762 case Intrinsic::minnum:
2763 return TargetOpcode::G_FMINNUM;
2764 case Intrinsic::maxnum:
2765 return TargetOpcode::G_FMAXNUM;
2766 case Intrinsic::minimum:
2767 return TargetOpcode::G_FMINIMUM;
2768 case Intrinsic::maximum:
2769 return TargetOpcode::G_FMAXIMUM;
2770 case Intrinsic::minimumnum:
2771 return TargetOpcode::G_FMINIMUMNUM;
2772 case Intrinsic::maximumnum:
2773 return TargetOpcode::G_FMAXIMUMNUM;
2774 case Intrinsic::canonicalize:
2775 return TargetOpcode::G_FCANONICALIZE;
2776 case Intrinsic::floor:
2777 return TargetOpcode::G_FFLOOR;
2778 case Intrinsic::fma:
2779 return TargetOpcode::G_FMA;
2780 case Intrinsic::log:
2781 return TargetOpcode::G_FLOG;
2782 case Intrinsic::log2:
2783 return TargetOpcode::G_FLOG2;
2784 case Intrinsic::log10:
2785 return TargetOpcode::G_FLOG10;
2786 case Intrinsic::ldexp:
2787 return TargetOpcode::G_FLDEXP;
2788 case Intrinsic::nearbyint:
2789 return TargetOpcode::G_FNEARBYINT;
2790 case Intrinsic::pow:
2791 return TargetOpcode::G_FPOW;
2792 case Intrinsic::powi:
2793 return TargetOpcode::G_FPOWI;
2794 case Intrinsic::rint:
2795 return TargetOpcode::G_FRINT;
2796 case Intrinsic::round:
2797 return TargetOpcode::G_INTRINSIC_ROUND;
2798 case Intrinsic::roundeven:
2799 return TargetOpcode::G_INTRINSIC_ROUNDEVEN;
2800 case Intrinsic::sin:
2801 return TargetOpcode::G_FSIN;
2802 case Intrinsic::sinh:
2803 return TargetOpcode::G_FSINH;
2804 case Intrinsic::sqrt:
2805 return TargetOpcode::G_FSQRT;
2806 case Intrinsic::tan:
2807 return TargetOpcode::G_FTAN;
2808 case Intrinsic::tanh:
2809 return TargetOpcode::G_FTANH;
2810 case Intrinsic::trunc:
2811 return TargetOpcode::G_INTRINSIC_TRUNC;
2812 case Intrinsic::readcyclecounter:
2813 return TargetOpcode::G_READCYCLECOUNTER;
2814 case Intrinsic::readsteadycounter:
2815 return TargetOpcode::G_READSTEADYCOUNTER;
2816 case Intrinsic::ptrmask:
2817 return TargetOpcode::G_PTRMASK;
2818 case Intrinsic::lrint:
2819 return TargetOpcode::G_INTRINSIC_LRINT;
2820 case Intrinsic::llrint:
2821 return TargetOpcode::G_INTRINSIC_LLRINT;
2823 case Intrinsic::vector_reduce_fmin:
2824 return TargetOpcode::G_VECREDUCE_FMIN;
2825 case Intrinsic::vector_reduce_fmax:
2826 return TargetOpcode::G_VECREDUCE_FMAX;
2827 case Intrinsic::vector_reduce_fminimum:
2828 return TargetOpcode::G_VECREDUCE_FMINIMUM;
2829 case Intrinsic::vector_reduce_fmaximum:
2830 return TargetOpcode::G_VECREDUCE_FMAXIMUM;
2831 case Intrinsic::vector_reduce_add:
2832 return TargetOpcode::G_VECREDUCE_ADD;
2833 case Intrinsic::vector_reduce_mul:
2834 return TargetOpcode::G_VECREDUCE_MUL;
2835 case Intrinsic::vector_reduce_and:
2836 return TargetOpcode::G_VECREDUCE_AND;
2837 case Intrinsic::vector_reduce_or:
2838 return TargetOpcode::G_VECREDUCE_OR;
2839 case Intrinsic::vector_reduce_xor:
2840 return TargetOpcode::G_VECREDUCE_XOR;
2841 case Intrinsic::vector_reduce_smax:
2842 return TargetOpcode::G_VECREDUCE_SMAX;
2843 case Intrinsic::vector_reduce_smin:
2844 return TargetOpcode::G_VECREDUCE_SMIN;
2845 case Intrinsic::vector_reduce_umax:
2846 return TargetOpcode::G_VECREDUCE_UMAX;
2847 case Intrinsic::vector_reduce_umin:
2848 return TargetOpcode::G_VECREDUCE_UMIN;
2849 case Intrinsic::experimental_vector_compress:
2850 return TargetOpcode::G_VECTOR_COMPRESS;
2851 case Intrinsic::lround:
2852 return TargetOpcode::G_LROUND;
2853 case Intrinsic::llround:
2854 return TargetOpcode::G_LLROUND;
2855 case Intrinsic::get_fpenv:
2856 return TargetOpcode::G_GET_FPENV;
2857 case Intrinsic::get_fpmode:
2858 return TargetOpcode::G_GET_FPMODE;
2863bool IRTranslatorImpl::translateSimpleIntrinsic(
const CallInst &CI,
2867 unsigned Op = getSimpleIntrinsicOpcode(ID);
2875 for (
const auto &Arg : CI.
args())
2878 MIRBuilder.
buildInstr(
Op, {getOrCreateVReg(CI)}, VRegs,
2886 case Intrinsic::experimental_constrained_fadd:
2887 return TargetOpcode::G_STRICT_FADD;
2888 case Intrinsic::experimental_constrained_fsub:
2889 return TargetOpcode::G_STRICT_FSUB;
2890 case Intrinsic::experimental_constrained_fmul:
2891 return TargetOpcode::G_STRICT_FMUL;
2892 case Intrinsic::experimental_constrained_fdiv:
2893 return TargetOpcode::G_STRICT_FDIV;
2894 case Intrinsic::experimental_constrained_frem:
2895 return TargetOpcode::G_STRICT_FREM;
2896 case Intrinsic::experimental_constrained_fma:
2897 return TargetOpcode::G_STRICT_FMA;
2898 case Intrinsic::experimental_constrained_sqrt:
2899 return TargetOpcode::G_STRICT_FSQRT;
2900 case Intrinsic::experimental_constrained_ldexp:
2901 return TargetOpcode::G_STRICT_FLDEXP;
2902 case Intrinsic::experimental_constrained_fcmp:
2903 return TargetOpcode::G_STRICT_FCMP;
2904 case Intrinsic::experimental_constrained_fcmps:
2905 return TargetOpcode::G_STRICT_FCMPS;
2911bool IRTranslatorImpl::translateConstrainedFPIntrinsic(
2923 if (Opcode == TargetOpcode::G_STRICT_FCMP ||
2924 Opcode == TargetOpcode::G_STRICT_FCMPS) {
2926 Register Operand0 = getOrCreateVReg(*FPCmp->getArgOperand(0));
2927 Register Operand1 = getOrCreateVReg(*FPCmp->getArgOperand(1));
2930 .addPredicate(FPCmp->getPredicate())
2944std::optional<MCRegister> IRTranslatorImpl::getArgPhysReg(
Argument &Arg) {
2945 auto VRegs = getOrCreateVRegs(Arg);
2946 if (VRegs.
size() != 1)
2947 return std::nullopt;
2950 auto *VRegDef = MF->getRegInfo().getVRegDef(VRegs[0]);
2951 if (!VRegDef || !VRegDef->isCopy())
2952 return std::nullopt;
2953 return VRegDef->getOperand(1).getReg().asMCReg();
2956bool IRTranslatorImpl::translateIfEntryValueArgument(
2967 std::optional<MCRegister> PhysReg = getArgPhysReg(*Arg);
2969 LLVM_DEBUG(
dbgs() <<
"Dropping dbg." << (isDeclare ?
"declare" :
"value")
2970 <<
": expression is entry_value but "
2971 <<
"couldn't find a physical register\n");
2979 MF->setVariableDbgInfo(Var, Expr, *PhysReg, DL);
2991 case Intrinsic::experimental_convergence_anchor:
2992 return TargetOpcode::CONVERGENCECTRL_ANCHOR;
2993 case Intrinsic::experimental_convergence_entry:
2994 return TargetOpcode::CONVERGENCECTRL_ENTRY;
2995 case Intrinsic::experimental_convergence_loop:
2996 return TargetOpcode::CONVERGENCECTRL_LOOP;
3000bool IRTranslatorImpl::translateConvergenceControlIntrinsic(
3003 Register OutputReg = getOrCreateConvergenceTokenVReg(CI);
3006 if (ID == Intrinsic::experimental_convergence_loop) {
3008 assert(Bundle &&
"Expected a convergence control token.");
3010 getOrCreateConvergenceTokenVReg(*Bundle->Inputs[0].get());
3017bool IRTranslatorImpl::translateKnownIntrinsic(
const CallInst &CI,
3021 if (ORE->enabled()) {
3023 MemoryOpRemark
R(*ORE,
"gisel-irtranslator-memsize", *DL, *LibInfo);
3031 if (translateSimpleIntrinsic(CI, ID, MIRBuilder))
3037 case Intrinsic::lifetime_start:
3038 case Intrinsic::lifetime_end: {
3041 MF->getFunction().hasOptNone())
3044 unsigned Op =
ID == Intrinsic::lifetime_start ? TargetOpcode::LIFETIME_START
3045 : TargetOpcode::LIFETIME_END;
3054 case Intrinsic::fake_use: {
3056 for (
const auto &Arg : CI.
args())
3058 MIRBuilder.
buildInstr(TargetOpcode::FAKE_USE, {}, VRegs);
3059 MF->setHasFakeUses(
true);
3062 case Intrinsic::dbg_declare: {
3069 case Intrinsic::dbg_label: {
3075 "Expected inlined-at fields to agree");
3080 case Intrinsic::vaend:
3084 case Intrinsic::vastart: {
3086 unsigned ListSize = TLI->getVaListSizeInBits(*DL) / 8;
3089 MIRBuilder.
buildInstr(TargetOpcode::G_VASTART, {}, {getOrCreateVReg(*Ptr)})
3090 .addMemOperand(MF->getMachineMemOperand(MachinePointerInfo(Ptr),
3092 ListSize, Alignment));
3095 case Intrinsic::dbg_assign:
3102 case Intrinsic::dbg_value: {
3109 case Intrinsic::uadd_with_overflow:
3110 return translateOverflowIntrinsic(CI, TargetOpcode::G_UADDO, MIRBuilder);
3111 case Intrinsic::sadd_with_overflow:
3112 return translateOverflowIntrinsic(CI, TargetOpcode::G_SADDO, MIRBuilder);
3113 case Intrinsic::usub_with_overflow:
3114 return translateOverflowIntrinsic(CI, TargetOpcode::G_USUBO, MIRBuilder);
3115 case Intrinsic::ssub_with_overflow:
3116 return translateOverflowIntrinsic(CI, TargetOpcode::G_SSUBO, MIRBuilder);
3117 case Intrinsic::umul_with_overflow:
3118 return translateOverflowIntrinsic(CI, TargetOpcode::G_UMULO, MIRBuilder);
3119 case Intrinsic::smul_with_overflow:
3120 return translateOverflowIntrinsic(CI, TargetOpcode::G_SMULO, MIRBuilder);
3121 case Intrinsic::uadd_sat:
3122 return translateBinaryOp(TargetOpcode::G_UADDSAT, CI, MIRBuilder);
3123 case Intrinsic::sadd_sat:
3124 return translateBinaryOp(TargetOpcode::G_SADDSAT, CI, MIRBuilder);
3125 case Intrinsic::usub_sat:
3126 return translateBinaryOp(TargetOpcode::G_USUBSAT, CI, MIRBuilder);
3127 case Intrinsic::ssub_sat:
3128 return translateBinaryOp(TargetOpcode::G_SSUBSAT, CI, MIRBuilder);
3129 case Intrinsic::ushl_sat:
3130 return translateBinaryOp(TargetOpcode::G_USHLSAT, CI, MIRBuilder);
3131 case Intrinsic::sshl_sat:
3132 return translateBinaryOp(TargetOpcode::G_SSHLSAT, CI, MIRBuilder);
3133 case Intrinsic::umin:
3134 return translateBinaryOp(TargetOpcode::G_UMIN, CI, MIRBuilder);
3135 case Intrinsic::umax:
3136 return translateBinaryOp(TargetOpcode::G_UMAX, CI, MIRBuilder);
3137 case Intrinsic::smin:
3138 return translateBinaryOp(TargetOpcode::G_SMIN, CI, MIRBuilder);
3139 case Intrinsic::smax:
3140 return translateBinaryOp(TargetOpcode::G_SMAX, CI, MIRBuilder);
3141 case Intrinsic::abs:
3143 return translateUnaryOp(TargetOpcode::G_ABS, CI, MIRBuilder);
3144 case Intrinsic::smul_fix:
3145 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIX, CI, MIRBuilder);
3146 case Intrinsic::umul_fix:
3147 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIX, CI, MIRBuilder);
3148 case Intrinsic::smul_fix_sat:
3149 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIXSAT, CI, MIRBuilder);
3150 case Intrinsic::umul_fix_sat:
3151 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIXSAT, CI, MIRBuilder);
3152 case Intrinsic::sdiv_fix:
3153 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIX, CI, MIRBuilder);
3154 case Intrinsic::udiv_fix:
3155 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIX, CI, MIRBuilder);
3156 case Intrinsic::sdiv_fix_sat:
3157 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIXSAT, CI, MIRBuilder);
3158 case Intrinsic::udiv_fix_sat:
3159 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIXSAT, CI, MIRBuilder);
3160 case Intrinsic::fmuladd: {
3161 const TargetMachine &TM = MF->getTarget();
3162 Register Dst = getOrCreateVReg(CI);
3167 TLI->isFMAFasterThanFMulAndFAdd(*MF,
3168 TLI->getValueType(*DL, CI.
getType()))) {
3171 MIRBuilder.
buildFMA(Dst, Op0, Op1, Op2,
3182 case Intrinsic::frexp: {
3189 case Intrinsic::modf: {
3191 MIRBuilder.
buildModf(VRegs[0], VRegs[1],
3196 case Intrinsic::sincos: {
3203 case Intrinsic::fptosi_sat:
3207 case Intrinsic::fptoui_sat:
3211 case Intrinsic::memcpy_inline:
3212 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY_INLINE);
3213 case Intrinsic::memcpy:
3214 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY);
3215 case Intrinsic::memmove:
3216 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMMOVE);
3217 case Intrinsic::memset:
3218 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET);
3219 case Intrinsic::memset_inline:
3220 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET_INLINE);
3221 case Intrinsic::eh_typeid_for: {
3224 unsigned TypeID = MF->getTypeIDFor(GV);
3228 case Intrinsic::objectsize:
3231 case Intrinsic::is_constant:
3234 case Intrinsic::stackguard:
3235 getStackGuard(getOrCreateVReg(CI), MIRBuilder);
3237 case Intrinsic::stackprotector: {
3240 if (TLI->useLoadStackGuardNode(*CI.
getModule())) {
3241 GuardVal = MRI->createGenericVirtualRegister(PtrTy);
3242 getStackGuard(GuardVal, MIRBuilder);
3247 int FI = getOrCreateFrameIndex(*Slot);
3248 MF->getFrameInfo().setStackProtectorIndex(FI);
3251 GuardVal, getOrCreateVReg(*Slot),
3258 case Intrinsic::stacksave: {
3259 MIRBuilder.
buildInstr(TargetOpcode::G_STACKSAVE, {getOrCreateVReg(CI)}, {});
3262 case Intrinsic::stackrestore: {
3263 MIRBuilder.
buildInstr(TargetOpcode::G_STACKRESTORE, {},
3267 case Intrinsic::cttz:
3268 case Intrinsic::ctlz: {
3270 bool isTrailing =
ID == Intrinsic::cttz;
3271 unsigned Opcode = isTrailing ? Cst->
isZero()
3272 ? TargetOpcode::G_CTTZ
3273 : TargetOpcode::G_CTTZ_ZERO_POISON
3274 : Cst->
isZero() ? TargetOpcode::G_CTLZ
3275 : TargetOpcode::G_CTLZ_ZERO_POISON;
3276 MIRBuilder.
buildInstr(Opcode, {getOrCreateVReg(CI)},
3280 case Intrinsic::invariant_start: {
3284 case Intrinsic::invariant_end:
3286 case Intrinsic::expect:
3287 case Intrinsic::expect_with_probability:
3288 case Intrinsic::annotation:
3289 case Intrinsic::ptr_annotation:
3290 case Intrinsic::launder_invariant_group:
3291 case Intrinsic::strip_invariant_group:
3292 case Intrinsic::threadlocal_address: {
3294 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
3298 case Intrinsic::assume:
3299 case Intrinsic::experimental_noalias_scope_decl:
3300 case Intrinsic::var_annotation:
3301 case Intrinsic::sideeffect:
3304 case Intrinsic::read_volatile_register:
3305 case Intrinsic::read_register: {
3308 .
buildInstr(TargetOpcode::G_READ_REGISTER, {getOrCreateVReg(CI)}, {})
3312 case Intrinsic::write_register: {
3314 MIRBuilder.
buildInstr(TargetOpcode::G_WRITE_REGISTER)
3319 case Intrinsic::localescape: {
3320 MachineBasicBlock &EntryMBB = MF->front();
3325 for (
unsigned Idx = 0,
E = CI.
arg_size(); Idx <
E; ++Idx) {
3332 MF->getContext().getOrCreateFrameAllocSymbol(EscapedName, Idx);
3345 case Intrinsic::vector_reduce_fadd:
3346 case Intrinsic::vector_reduce_fmul: {
3349 Register Dst = getOrCreateVReg(CI);
3355 Opc =
ID == Intrinsic::vector_reduce_fadd
3356 ? TargetOpcode::G_VECREDUCE_SEQ_FADD
3357 : TargetOpcode::G_VECREDUCE_SEQ_FMUL;
3358 if (!MRI->getType(VecSrc).isVector())
3359 Opc =
ID == Intrinsic::vector_reduce_fadd ? TargetOpcode::G_FADD
3360 : TargetOpcode::G_FMUL;
3368 if (ID == Intrinsic::vector_reduce_fadd) {
3369 Opc = TargetOpcode::G_VECREDUCE_FADD;
3370 ScalarOpc = TargetOpcode::G_FADD;
3372 Opc = TargetOpcode::G_VECREDUCE_FMUL;
3373 ScalarOpc = TargetOpcode::G_FMUL;
3375 LLT DstTy = MRI->getType(Dst);
3378 MIRBuilder.
buildInstr(ScalarOpc, {Dst}, {ScalarSrc, Rdx},
3383 case Intrinsic::trap:
3384 return translateTrap(CI, MIRBuilder, TargetOpcode::G_TRAP);
3385 case Intrinsic::debugtrap:
3386 return translateTrap(CI, MIRBuilder, TargetOpcode::G_DEBUGTRAP);
3387 case Intrinsic::ubsantrap:
3388 return translateTrap(CI, MIRBuilder, TargetOpcode::G_UBSANTRAP);
3389 case Intrinsic::allow_runtime_check:
3390 case Intrinsic::allow_ubsan_check:
3391 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
3394 case Intrinsic::amdgcn_cs_chain:
3395 case Intrinsic::amdgcn_call_whole_wave:
3396 return translateCallBase(CI, MIRBuilder);
3397 case Intrinsic::fptrunc_round: {
3402 std::optional<RoundingMode> RoundMode =
3407 .
buildInstr(TargetOpcode::G_INTRINSIC_FPTRUNC_ROUND,
3408 {getOrCreateVReg(CI)},
3410 .addImm((
int)*RoundMode);
3414 case Intrinsic::is_fpclass: {
3419 .
buildInstr(TargetOpcode::G_IS_FPCLASS, {getOrCreateVReg(CI)},
3420 {getOrCreateVReg(*FpValue)})
3425 case Intrinsic::set_fpenv: {
3430 case Intrinsic::reset_fpenv:
3433 case Intrinsic::set_fpmode: {
3438 case Intrinsic::reset_fpmode:
3441 case Intrinsic::get_rounding:
3444 case Intrinsic::set_rounding:
3447 case Intrinsic::vscale: {
3451 case Intrinsic::scmp:
3452 MIRBuilder.
buildSCmp(getOrCreateVReg(CI),
3456 case Intrinsic::ucmp:
3457 MIRBuilder.
buildUCmp(getOrCreateVReg(CI),
3461 case Intrinsic::vector_extract:
3462 return translateExtractVector(CI, MIRBuilder);
3463 case Intrinsic::vector_insert:
3464 return translateInsertVector(CI, MIRBuilder);
3465 case Intrinsic::stepvector: {
3469 case Intrinsic::prefetch: {
3476 auto &MMO = *MF->getMachineMemOperand(MachinePointerInfo(Addr), Flags,
3479 MIRBuilder.
buildPrefetch(getOrCreateVReg(*Addr), RW, Locality, CacheType,
3485 case Intrinsic::vector_interleave2:
3486 case Intrinsic::vector_deinterleave2: {
3494 return translateVectorInterleave2Intrinsic(CI, MIRBuilder);
3496 return translateVectorDeinterleave2Intrinsic(CI, MIRBuilder);
3499#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
3500 case Intrinsic::INTRINSIC:
3501#include "llvm/IR/ConstrainedOps.def"
3504 case Intrinsic::experimental_convergence_anchor:
3505 case Intrinsic::experimental_convergence_entry:
3506 case Intrinsic::experimental_convergence_loop:
3507 return translateConvergenceControlIntrinsic(CI, ID, MIRBuilder);
3508 case Intrinsic::reloc_none: {
3511 MIRBuilder.
buildInstr(TargetOpcode::RELOC_NONE)
3519bool IRTranslatorImpl::translateInlineAsm(
const CallBase &CB,
3521 if (!mayTranslateUserTypes(CB))
3524 const InlineAsmLowering *ALI = MF->getSubtarget().getInlineAsmLowering();
3528 dbgs() <<
"Inline asm lowering is not supported for this target yet\n");
3533 MIRBuilder, CB, [&](
const Value &Val) {
return getOrCreateVRegs(Val); });
3536bool IRTranslatorImpl::translateCallBase(
const CallBase &CB,
3543 for (
const auto &Arg : CB.
args()) {
3545 assert(SwiftInVReg == 0 &&
"Expected only one swift error argument");
3547 SwiftInVReg = MRI->createGenericVirtualRegister(Ty);
3548 MIRBuilder.
buildCopy(SwiftInVReg, SwiftError.getOrCreateVRegUseAt(
3549 &CB, &MIRBuilder.
getMBB(), Arg));
3552 SwiftError.getOrCreateVRegDefAt(&CB, &MIRBuilder.
getMBB(), Arg);
3555 Args.push_back(getOrCreateVRegs(*Arg));
3559 if (ORE->enabled()) {
3561 MemoryOpRemark
R(*ORE,
"gisel-irtranslator-memsize", *DL, *LibInfo);
3567 std::optional<CallLowering::PtrAuthInfo> PAI;
3572 const Value *
Key = Bundle->Inputs[0];
3579 if (!CalleeCPA || !
isa<Function>(CalleeCPA->getPointer()) ||
3580 !CalleeCPA->isKnownCompatibleWith(
Key, Discriminator, *DL)) {
3582 Register DiscReg = getOrCreateVReg(*Discriminator);
3590 const auto &Token = *Bundle->Inputs[0].get();
3591 ConvergenceCtrlToken = getOrCreateConvergenceTokenVReg(Token);
3597 bool Success = CLI->lowerCall(
3598 MIRBuilder, CB, Res, Args, SwiftErrorVReg, PAI, ConvergenceCtrlToken,
3603 assert(!HasTailCall &&
"Can't tail call return twice from block?");
3604 const TargetInstrInfo *
TII = MF->getSubtarget().getInstrInfo();
3611bool IRTranslatorImpl::translateCall(
const User &U,
3613 if (!mayTranslateUserTypes(U))
3621 if (
F && (
F->hasDLLImportStorageClass() ||
3622 (MF->getTarget().getTargetTriple().isOSWindows() &&
3623 F->hasExternalWeakLinkage())))
3635 return translateInlineAsm(CI, MIRBuilder);
3639 if (translateCallBase(CI, MIRBuilder)) {
3648 if (!MF->getSubtarget().isIntrinsicSupported(ID)) {
3649 const Function &Fn = MF->getFunction();
3651 DiagnosticInfoUnsupportedTargetIntrinsic(Fn, ID, CI.
getDebugLoc()));
3654 if (translateKnownIntrinsic(CI, ID, MIRBuilder))
3658 TLI->getTgtMemIntrinsic(Infos, CI, *MF, ID);
3660 return translateIntrinsic(CI, ID, MIRBuilder, Infos);
3664bool IRTranslatorImpl::translateIntrinsic(
3667 if (!MF->getSubtarget().isIntrinsicSupported(ID)) {
3669 F.getContext().diagnose(
3670 DiagnosticInfoUnsupportedTargetIntrinsic(
F, ID, CB.
getDebugLoc()));
3675 ResultRegs = getOrCreateVRegs(CB);
3679 MachineInstrBuilder MIB = MIRBuilder.
buildIntrinsic(ID, ResultRegs);
3690 assert(CI->getBitWidth() <= 64 &&
3691 "large intrinsic immediates not handled");
3692 MIB.
addImm(CI->getSExtValue());
3697 auto *MD = MDVal->getMetadata();
3701 MDN =
MDNode::get(MF->getFunction().getContext(), ConstMD);
3708 if (VRegs.
size() > 1)
3715 for (
const auto &Info : TgtMemIntrinsicInfos) {
3718 LLT MemTy =
Info.memVT.isSimple()
3720 : LLT::scalar(
Info.memVT.getStoreSizeInBits());
3724 MachinePointerInfo MPI;
3726 MPI = MachinePointerInfo(Info.ptrVal, Info.offset);
3727 }
else if (
Info.fallbackAddressSpace) {
3728 MPI = MachinePointerInfo(*Info.fallbackAddressSpace);
3737 auto *Token = Bundle->Inputs[0].get();
3738 Register TokenReg = getOrCreateVReg(*Token);
3749bool IRTranslatorImpl::findUnwindDestinations(
3770 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3776 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3777 UnwindDests.back().first->setIsEHScopeEntry();
3778 UnwindDests.back().first->setIsEHFuncletEntry();
3783 for (
const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
3784 UnwindDests.emplace_back(&getMBB(*CatchPadBB), Prob);
3786 if (IsMSVCCXX || IsCoreCLR)
3787 UnwindDests.back().first->setIsEHFuncletEntry();
3789 UnwindDests.back().first->setIsEHScopeEntry();
3791 NewEHPadBB = CatchSwitch->getUnwindDest();
3796 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3797 if (BPI && NewEHPadBB)
3799 EHPadBB = NewEHPadBB;
3804bool IRTranslatorImpl::translateInvoke(
const User &U,
3807 MCContext &
Context = MF->getContext();
3812 const Function *Fn =
I.getCalledFunction();
3819 if (
I.hasDeoptState())
3833 (MF->getTarget().getTargetTriple().isOSWindows() &&
3837 bool LowerInlineAsm =
I.isInlineAsm();
3838 bool NeedEHLabel =
true;
3844 MIRBuilder.
buildInstr(TargetOpcode::G_INVOKE_REGION_START);
3845 BeginSymbol =
Context.createTempSymbol();
3849 if (LowerInlineAsm) {
3850 if (!translateInlineAsm(
I, MIRBuilder))
3852 }
else if (!translateCallBase(
I, MIRBuilder))
3857 EndSymbol =
Context.createTempSymbol();
3862 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3863 MachineBasicBlock *InvokeMBB = &MIRBuilder.
getMBB();
3864 BranchProbability EHPadBBProb =
3868 if (!findUnwindDestinations(EHPadBB, EHPadBBProb, UnwindDests))
3871 MachineBasicBlock &EHPadMBB = getMBB(*EHPadBB),
3872 &ReturnMBB = getMBB(*ReturnBB);
3874 addSuccessorWithProb(InvokeMBB, &ReturnMBB);
3875 for (
auto &UnwindDest : UnwindDests) {
3876 UnwindDest.first->setIsEHPad();
3877 addSuccessorWithProb(InvokeMBB, UnwindDest.first, UnwindDest.second);
3882 assert(BeginSymbol &&
"Expected a begin symbol!");
3883 assert(EndSymbol &&
"Expected an end symbol!");
3884 MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol);
3887 MIRBuilder.
buildBr(ReturnMBB);
3893bool IRTranslatorImpl::translateCallBr(
const User &U,
3895 if (!mayTranslateUserTypes(U))
3899 MachineBasicBlock *CallBrMBB = &MIRBuilder.
getMBB();
3902 if (
I.isInlineAsm()) {
3908 if (!translateIntrinsic(
I, IID, MIRBuilder))
3912 SmallPtrSet<BasicBlock *, 8> Dests = {
I.getDefaultDest()};
3913 MachineBasicBlock *
Return = &getMBB(*
I.getDefaultDest());
3922 for (BasicBlock *Dest :
I.getIndirectDests()) {
3923 MachineBasicBlock &
Target = getMBB(*Dest);
3924 Target.setIsInlineAsmBrIndirectTarget();
3925 Target.setLabelMustBeEmitted();
3927 if (Dests.
insert(Dest).second)
3939bool IRTranslatorImpl::translateLandingPad(
const User &U,
3943 MachineBasicBlock &
MBB = MIRBuilder.
getMBB();
3949 const Constant *PersonalityFn = MF->getFunction().getPersonalityFn();
3950 if (TLI->getExceptionPointerRegister(
3951 TLI->getTargetMachine().getExceptionModel(), PersonalityFn) == 0 &&
3952 TLI->getExceptionSelectorRegister(
3953 TLI->getTargetMachine().getExceptionModel(), PersonalityFn) == 0)
3965 MIRBuilder.
buildInstr(TargetOpcode::EH_LABEL)
3970 const TargetRegisterInfo &
TRI = *MF->getSubtarget().getRegisterInfo();
3971 if (
auto *RegMask =
TRI.getCustomEHPadPreservedMask(*MF))
3972 MF->getRegInfo().addPhysRegsUsedFromRegMask(RegMask);
3981 assert(Tys.
size() == 2 &&
"Only two-valued landingpads are supported");
3984 Register ExceptionReg = TLI->getExceptionPointerRegister(
3985 TLI->getTargetMachine().getExceptionModel(), PersonalityFn);
3991 MIRBuilder.
buildCopy(ResRegs[0], ExceptionReg);
3993 Register SelectorReg = TLI->getExceptionSelectorRegister(
3994 TLI->getTargetMachine().getExceptionModel(), PersonalityFn);
3999 Register PtrVReg = MRI->createGenericVirtualRegister(Tys[0]);
4000 MIRBuilder.
buildCopy(PtrVReg, SelectorReg);
4001 MIRBuilder.
buildCast(ResRegs[1], PtrVReg);
4006bool IRTranslatorImpl::translateAlloca(
const User &U,
4014 Register Res = getOrCreateVReg(AI);
4015 int FI = getOrCreateFrameIndex(AI);
4021 if (MF->getTarget().getTargetTriple().isOSWindows())
4026 Type *IntPtrIRTy = DL->getIntPtrType(AI.
getType());
4028 if (MRI->getType(NumElts) !=
IntPtrTy) {
4035 TypeSize TySize = DL->getTypeAllocSize(Ty);
4041 TySizeReg = MRI->createGenericVirtualRegister(
IntPtrTy);
4046 getOrCreateVReg(*ConstantInt::get(IntPtrIRTy, TySize.
getFixedValue()));
4048 MIRBuilder.
buildMul(AllocSize, NumElts, TySizeReg);
4053 Align StackAlign = MF->getSubtarget().getFrameLowering()->getStackAlign();
4062 if (Alignment <= StackAlign)
4066 MF->getFrameInfo().CreateVariableSizedObject(Alignment, &AI);
4067 assert(MF->getFrameInfo().hasVarSizedObjects());
4071bool IRTranslatorImpl::translateVAArg(
const User &U,
4077 MIRBuilder.
buildInstr(TargetOpcode::G_VAARG, {getOrCreateVReg(U)},
4078 {getOrCreateVReg(*
U.getOperand(0)),
4079 DL->getABITypeAlign(
U.getType()).value()});
4083bool IRTranslatorImpl::translateUnreachable(
const User &U,
4086 if (!UI.shouldLowerToTrap(MF->getTarget().Options.TrapUnreachable,
4087 MF->getTarget().Options.NoTrapAfterNoreturn))
4094bool IRTranslatorImpl::translateInsertElement(
const User &U,
4099 FVT && FVT->getNumElements() == 1)
4100 return translateCopy(U, *
U.getOperand(1), MIRBuilder);
4103 Register Val = getOrCreateVReg(*
U.getOperand(0));
4104 Register Elt = getOrCreateVReg(*
U.getOperand(1));
4105 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4108 if (CI->getBitWidth() != PreferredVecIdxWidth) {
4109 APInt NewIdx = CI->getValue().zextOrTrunc(PreferredVecIdxWidth);
4110 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
4111 Idx = getOrCreateVReg(*NewIdxCI);
4115 Idx = getOrCreateVReg(*
U.getOperand(2));
4116 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
4117 const LLT VecIdxTy =
4118 MRI->getType(Idx).changeElementSize(PreferredVecIdxWidth);
4125bool IRTranslatorImpl::translateInsertVector(
const User &U,
4128 Register Vec = getOrCreateVReg(*
U.getOperand(0));
4129 Register Elt = getOrCreateVReg(*
U.getOperand(1));
4132 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4137 CI = ConstantInt::get(CI->
getContext(), NewIdx);
4142 ResultType && ResultType->getNumElements() == 1) {
4144 InputType && InputType->getNumElements() == 1) {
4148 return translateCopy(U, Vec, MIRBuilder);
4154 Register Idx = getOrCreateVReg(*CI);
4162 Register Idx = getOrCreateVReg(*CI);
4163 auto ScaledIndex = MIRBuilder.
buildMul(
4164 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
4174bool IRTranslatorImpl::translateExtractElement(
const User &U,
4178 if (
const FixedVectorType *FVT =
4180 if (FVT->getNumElements() == 1)
4181 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
4184 Register Val = getOrCreateVReg(*
U.getOperand(0));
4185 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4190 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
4191 Idx = getOrCreateVReg(*NewIdxCI);
4195 Idx = getOrCreateVReg(*
U.getOperand(1));
4196 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
4197 const LLT VecIdxTy =
4205bool IRTranslatorImpl::translateExtractVector(
const User &U,
4208 Register Vec = getOrCreateVReg(*
U.getOperand(0));
4210 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4215 CI = ConstantInt::get(CI->
getContext(), NewIdx);
4220 ResultType && ResultType->getNumElements() == 1) {
4222 InputType && InputType->getNumElements() == 1) {
4225 return translateCopy(U, Vec, MIRBuilder);
4231 Register Idx = getOrCreateVReg(*CI);
4239 Register Idx = getOrCreateVReg(*CI);
4240 auto ScaledIndex = MIRBuilder.
buildMul(
4241 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
4251bool IRTranslatorImpl::translateShuffleVector(
const User &U,
4257 if (
U.getOperand(0)->getType()->isScalableTy()) {
4258 Register Val = getOrCreateVReg(*
U.getOperand(0));
4260 MRI->getType(Val).getElementType(), Val, 0);
4267 Mask = SVI->getShuffleMask();
4278 unsigned M =
Mask[0];
4280 if (M == 0 || M == 1)
4281 return translateCopy(U, *
U.getOperand(M), MIRBuilder);
4287 Dst, getOrCreateVReg(*
U.getOperand(0)), M);
4288 }
else if (M < SrcElts * 2) {
4290 Dst, getOrCreateVReg(*
U.getOperand(1)), M - SrcElts);
4302 for (
int M : Mask) {
4304 if (M == 0 || M == 1) {
4305 Ops.push_back(getOrCreateVReg(*
U.getOperand(M)));
4307 if (!
Undef.isValid()) {
4308 Undef = MRI->createGenericVirtualRegister(SrcTy);
4318 ArrayRef<int> MaskAlloc = MF->allocateShuffleMask(Mask);
4320 .
buildInstr(TargetOpcode::G_SHUFFLE_VECTOR, {getOrCreateVReg(U)},
4321 {getOrCreateVReg(*
U.getOperand(0)),
4322 getOrCreateVReg(*
U.getOperand(1))})
4323 .addShuffleMask(MaskAlloc);
4327bool IRTranslatorImpl::translatePHI(
const User &U,
4331 SmallVector<MachineInstr *, 4> Insts;
4332 for (
auto Reg : getOrCreateVRegs(PI)) {
4333 auto MIB = MIRBuilder.
buildInstr(TargetOpcode::G_PHI, {
Reg}, {});
4337 PendingPHIs.emplace_back(&PI, std::move(Insts));
4341bool IRTranslatorImpl::translateAtomicCmpXchg(
const User &U,
4345 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
4347 auto Res = getOrCreateVRegs(
I);
4350 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
4351 Register Cmp = getOrCreateVReg(*
I.getCompareOperand());
4352 Register NewVal = getOrCreateVReg(*
I.getNewValOperand());
4355 OldValRes, SuccessRes, Addr, Cmp, NewVal,
4356 *MF->getMachineMemOperand(
4357 MachinePointerInfo(
I.getPointerOperand()), Flags, MRI->getType(Cmp),
4358 getMemOpAlign(
I),
I.getAAMetadata(),
I.getSyncScopeID(),
4359 I.getSuccessOrdering(),
I.getFailureOrdering()));
4363bool IRTranslatorImpl::translateAtomicRMW(
const User &U,
4365 if (!mayTranslateUserTypes(U))
4369 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
4372 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
4373 Register Val = getOrCreateVReg(*
I.getValOperand());
4375 unsigned Opcode = 0;
4376 switch (
I.getOperation()) {
4380 Opcode = TargetOpcode::G_ATOMICRMW_XCHG;
4383 Opcode = TargetOpcode::G_ATOMICRMW_ADD;
4386 Opcode = TargetOpcode::G_ATOMICRMW_SUB;
4389 Opcode = TargetOpcode::G_ATOMICRMW_AND;
4392 Opcode = TargetOpcode::G_ATOMICRMW_NAND;
4395 Opcode = TargetOpcode::G_ATOMICRMW_OR;
4398 Opcode = TargetOpcode::G_ATOMICRMW_XOR;
4401 Opcode = TargetOpcode::G_ATOMICRMW_MAX;
4404 Opcode = TargetOpcode::G_ATOMICRMW_MIN;
4407 Opcode = TargetOpcode::G_ATOMICRMW_UMAX;
4410 Opcode = TargetOpcode::G_ATOMICRMW_UMIN;
4413 Opcode = TargetOpcode::G_ATOMICRMW_FADD;
4416 Opcode = TargetOpcode::G_ATOMICRMW_FSUB;
4419 Opcode = TargetOpcode::G_ATOMICRMW_FMAX;
4422 Opcode = TargetOpcode::G_ATOMICRMW_FMIN;
4425 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUM;
4428 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUM;
4431 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUMNUM;
4434 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUMNUM;
4437 Opcode = TargetOpcode::G_ATOMICRMW_UINC_WRAP;
4440 Opcode = TargetOpcode::G_ATOMICRMW_UDEC_WRAP;
4443 Opcode = TargetOpcode::G_ATOMICRMW_USUB_COND;
4446 Opcode = TargetOpcode::G_ATOMICRMW_USUB_SAT;
4451 Opcode, Res, Addr, Val,
4452 *MF->getMachineMemOperand(MachinePointerInfo(
I.getPointerOperand()),
4453 Flags, MRI->getType(Val), getMemOpAlign(
I),
4454 I.getAAMetadata(),
I.getSyncScopeID(),
4459bool IRTranslatorImpl::translateFence(
const User &U,
4463 Fence.getSyncScopeID());
4467bool IRTranslatorImpl::translateFreeze(
const User &U,
4473 "Freeze with different source and destination type?");
4475 for (
unsigned I = 0;
I < DstRegs.
size(); ++
I) {
4482void IRTranslatorImpl::finishPendingPhis() {
4485 GISelObserverWrapper WrapperObserver(&
Verifier);
4486 RAIIMFObsDelInstaller ObsInstall(*MF, WrapperObserver);
4488 for (
auto &Phi : PendingPHIs) {
4489 const PHINode *PI =
Phi.first;
4493 MachineBasicBlock *PhiMBB = ComponentPHIs[0]->getParent();
4499 SmallPtrSet<const MachineBasicBlock *, 16> SeenPreds;
4503 for (
auto *Pred : getMachinePredBBs({IRPred, PI->
getParent()})) {
4507 for (
unsigned j = 0;
j < ValRegs.
size(); ++
j) {
4508 MachineInstrBuilder MIB(*MF, ComponentPHIs[j]);
4517void IRTranslatorImpl::translateDbgValueRecord(
Value *V,
bool HasArgList,
4523 "Expected inlined-at fields to agree");
4527 if (!V || HasArgList) {
4545 auto *ExprDerefRemoved =
4551 if (translateIfEntryValueArgument(
false, V, Variable, Expression, DL,
4563void IRTranslatorImpl::translateDbgDeclareRecord(
4568 LLVM_DEBUG(
dbgs() <<
"Dropping debug info for " << *Variable <<
"\n");
4573 "Expected inlined-at fields to agree");
4578 MF->setVariableDbgInfo(Variable, Expression,
4579 getOrCreateFrameIndex(*AI), DL);
4583 if (translateIfEntryValueArgument(
true,
Address, Variable,
4595void IRTranslatorImpl::translateDbgInfo(
const Instruction &Inst,
4600 assert(DLR->getLabel() &&
"Missing label");
4601 assert(DLR->getLabel()->isValidLocationForIntrinsic(
4603 "Expected inlined-at fields to agree");
4612 translateDbgDeclareRecord(V, DVR.
hasArgList(), Variable, Expression,
4615 translateDbgValueRecord(V, DVR.
hasArgList(), Variable, Expression,
4620bool IRTranslatorImpl::translate(
const Instruction &Inst) {
4622 CurBuilder->setPCSections(Inst.
getMetadata(LLVMContext::MD_pcsections));
4623 CurBuilder->setMMRAMetadata(Inst.
getMetadata(LLVMContext::MD_mmra));
4625 if (TLI->fallBackToDAGISel(Inst))
4629#define HANDLE_INST(NUM, OPCODE, CLASS) \
4630 case Instruction::OPCODE: \
4631 return translate##OPCODE(Inst, *CurBuilder.get());
4632#include "llvm/IR/Instruction.def"
4641 if (
auto CurrInstDL = CurBuilder->getDL())
4642 EntryBuilder->setDebugLoc(
DebugLoc());
4648 EntryBuilder->buildConstant(
Reg, *CI);
4652 EntryBuilder->buildConstant(
Reg, CB->getValue());
4656 CF = ConstantFP::get(CF->getContext(), CF->getValue());
4657 EntryBuilder->buildFConstant(
Reg, *CF);
4659 EntryBuilder->buildUndef(
Reg);
4661 EntryBuilder->buildConstant(
Reg, 0);
4663 EntryBuilder->buildGlobalValue(
Reg, GV);
4665 Register Addr = getOrCreateVReg(*CPA->getPointer());
4666 Register AddrDisc = getOrCreateVReg(*CPA->getAddrDiscriminator());
4667 EntryBuilder->buildConstantPtrAuth(
Reg, CPA, Addr, AddrDisc);
4669 Constant &Elt = *CAZ->getElementValue(0u);
4671 EntryBuilder->buildSplatVector(
Reg, getOrCreateVReg(Elt));
4675 unsigned NumElts = CAZ->getElementCount().getFixedValue();
4677 return translateCopy(
C, Elt, *EntryBuilder);
4679 EntryBuilder->buildSplatBuildVector(
Reg, getOrCreateVReg(Elt));
4682 if (CV->getNumElements() == 1)
4683 return translateCopy(
C, *CV->getElementAsConstant(0), *EntryBuilder);
4685 for (
unsigned i = 0; i < CV->getNumElements(); ++i) {
4686 Constant &Elt = *CV->getElementAsConstant(i);
4687 Ops.push_back(getOrCreateVReg(Elt));
4689 EntryBuilder->buildBuildVector(
Reg,
Ops);
4691 switch(
CE->getOpcode()) {
4692#define HANDLE_INST(NUM, OPCODE, CLASS) \
4693 case Instruction::OPCODE: \
4694 return translate##OPCODE(*CE, *EntryBuilder.get());
4695#include "llvm/IR/Instruction.def"
4700 if (CV->getNumOperands() == 1)
4701 return translateCopy(
C, *CV->getOperand(0), *EntryBuilder);
4703 for (
unsigned i = 0; i < CV->getNumOperands(); ++i) {
4704 Ops.push_back(getOrCreateVReg(*CV->getOperand(i)));
4706 EntryBuilder->buildBuildVector(
Reg,
Ops);
4708 EntryBuilder->buildBlockAddress(
Reg, BA);
4715bool IRTranslatorImpl::mayTranslateUserTypes(
const User &U)
const {
4716 const TargetMachine &TM = TLI->getTargetMachine();
4725 (!
U.getType()->getScalarType()->isBFloatTy() &&
4727 return V->getType()->getScalarType()->isBFloatTy();
4731bool IRTranslatorImpl::finalizeBasicBlock(
const BasicBlock &BB,
4733 for (
auto &BTB : SL->BitTestCases) {
4736 emitBitTestHeader(BTB, BTB.Parent);
4738 BranchProbability UnhandledProb = BTB.Prob;
4739 for (
unsigned j = 0, ej = BTB.Cases.size(); j != ej; ++j) {
4740 UnhandledProb -= BTB.Cases[
j].ExtraProb;
4742 MachineBasicBlock *
MBB = BTB.Cases[
j].ThisBB;
4751 MachineBasicBlock *NextMBB;
4752 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
4755 NextMBB = BTB.Cases[
j + 1].TargetBB;
4756 }
else if (j + 1 == ej) {
4758 NextMBB = BTB.Default;
4761 NextMBB = BTB.Cases[
j + 1].ThisBB;
4764 emitBitTestCase(BTB, NextMBB, UnhandledProb, BTB.Reg, BTB.Cases[j],
MBB);
4766 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
4770 addMachineCFGPred({BTB.Parent->getBasicBlock(),
4771 BTB.Cases[ej - 1].TargetBB->getBasicBlock()},
4774 BTB.Cases.pop_back();
4780 CFGEdge HeaderToDefaultEdge = {BTB.Parent->getBasicBlock(),
4781 BTB.Default->getBasicBlock()};
4782 addMachineCFGPred(HeaderToDefaultEdge, BTB.Parent);
4783 if (!BTB.ContiguousRange) {
4784 addMachineCFGPred(HeaderToDefaultEdge, BTB.Cases.back().ThisBB);
4787 SL->BitTestCases.clear();
4789 for (
auto &JTCase : SL->JTCases) {
4791 if (!JTCase.first.Emitted)
4792 emitJumpTableHeader(JTCase.second, JTCase.first, JTCase.first.HeaderBB);
4794 emitJumpTable(JTCase.second, JTCase.second.MBB);
4796 SL->JTCases.clear();
4798 for (
auto &SwCase : SL->SwitchCases)
4799 emitSwitchCase(SwCase, &CurBuilder->getMBB(), *CurBuilder);
4800 SL->SwitchCases.clear();
4803 if (SPInfo->shouldEmitSDCheck(BB)) {
4804 bool FunctionBasedInstrumentation =
4805 TLI->getSSPStackGuardCheck(*MF->getFunction().getParent(), *Libcalls);
4806 SPDescriptor.initialize(&BB, &
MBB, FunctionBasedInstrumentation);
4809 if (SPDescriptor.shouldEmitFunctionBasedCheckStackProtector()) {
4812 }
else if (SPDescriptor.shouldEmitStackProtector()) {
4813 MachineBasicBlock *ParentMBB = SPDescriptor.getParentMBB();
4814 MachineBasicBlock *SuccessMBB = SPDescriptor.getSuccessMBB();
4823 ParentMBB, *MF->getSubtarget().getInstrInfo());
4826 SuccessMBB->
splice(SuccessMBB->
end(), ParentMBB, SplitPoint,
4830 if (!emitSPDescriptorParent(SPDescriptor, ParentMBB))
4834 MachineBasicBlock *FailureMBB = SPDescriptor.getFailureMBB();
4835 if (FailureMBB->
empty()) {
4836 if (!emitSPDescriptorFailure(SPDescriptor, FailureMBB))
4841 SPDescriptor.resetPerBBState();
4848 CurBuilder->setInsertPt(*ParentBB, ParentBB->
end());
4852 LLT PtrMemTy =
getLLTForMVT(TLI->getPointerMemTy(*DL));
4858 Register StackSlotPtr = CurBuilder->buildFrameIndex(PtrTy, FI).getReg(0);
4865 ->buildLoad(PtrMemTy, StackSlotPtr,
4871 if (
const Function *GuardCheckFn = TLI->getSSPStackGuardCheck(M, *Libcalls)) {
4883 FunctionType *FnTy = GuardCheckFn->getFunctionType();
4884 assert(FnTy->getNumParams() == 1 &&
"Invalid function signature");
4885 ISD::ArgFlagsTy
Flags;
4886 if (GuardCheckFn->hasAttribute(1, Attribute::AttrKind::InReg))
4888 CallLowering::ArgInfo GuardArgInfo(
4889 {GuardVal, FnTy->getParamType(0), {
Flags}});
4891 CallLowering::CallLoweringInfo
Info;
4892 Info.OrigArgs.push_back(GuardArgInfo);
4893 Info.CallConv = GuardCheckFn->getCallingConv();
4896 if (!CLI->lowerCall(MIRBuilder, Info)) {
4897 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector check\n");
4907 Guard = MRI->createGenericVirtualRegister(PtrMemTy);
4908 getStackGuard(Guard, *CurBuilder);
4911 const Value *IRGuard = TLI->getSDagStackGuard(M, *Libcalls);
4912 Register GuardPtr = getOrCreateVReg(*IRGuard);
4915 ->buildLoad(PtrMemTy, GuardPtr,
4934 const RTLIB::LibcallImpl LibcallImpl =
4935 Libcalls->getLibcallImpl(RTLIB::STACKPROTECTOR_CHECK_FAIL);
4936 if (LibcallImpl == RTLIB::Unsupported)
4939 CurBuilder->setInsertPt(*FailureBB, FailureBB->
end());
4941 CallLowering::CallLoweringInfo
Info;
4942 Info.CallConv = Libcalls->getLibcallImplCallingConv(LibcallImpl);
4944 StringRef LibcallName =
4949 if (!CLI->lowerCall(*CurBuilder, Info)) {
4950 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector fail\n");
4955 const TargetOptions &TargetOpts = TLI->getTargetMachine().Options;
4957 CurBuilder->buildInstr(TargetOpcode::G_TRAP);
4962void IRTranslatorImpl::finalizeFunction() {
4965 PendingPHIs.clear();
4967 FrameIndices.clear();
4968 MachinePreds.clear();
4972 EntryBuilder.reset();
4975 SPDescriptor.resetPerFunctionState();
4988 return CI && CI->isMustTailCall();
5000 ORE = std::make_unique<OptimizationRemarkEmitter>(&
F);
5001 CLI = MF->getSubtarget().getCallLowering();
5002 SPInfo = StackProtectorInfo;
5004 if (CLI->fallBackToDAGISel(*MF)) {
5006 F.getSubprogram(), &
F.getEntryBlock());
5007 R <<
"unable to lower function: "
5008 <<
ore::NV(
"Prototype",
F.getFunctionType());
5025 EntryBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
5026 CSEInfo = GetCSEInfo();
5027 EntryBuilder->setCSEInfo(CSEInfo);
5028 CurBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
5029 CurBuilder->setCSEInfo(CSEInfo);
5031 EntryBuilder = std::make_unique<MachineIRBuilder>();
5032 CurBuilder = std::make_unique<MachineIRBuilder>();
5035 CurBuilder->setMF(*MF);
5036 EntryBuilder->setMF(*MF);
5037 MRI = &MF->getRegInfo();
5038 DL = &
F.getDataLayout();
5043 AA = GetAAResults();
5044 FuncInfo.BPI = GetBPI();
5048 FuncInfo.BPI =
nullptr;
5051 LibInfo = LibraryInfo;
5052 Libcalls = LibcallInfo;
5054 FuncInfo.CanLowerReturn = CLI->checkReturnTypeForCallConv(*MF);
5056 SL = std::make_unique<GISelSwitchLowering>(
this, FuncInfo);
5057 SL->init(*TLI, TM, *DL);
5059 assert(PendingPHIs.empty() &&
"stale PHIs");
5063 if (!DL->isLittleEndian() && !CLI->enableBigEndian()) {
5066 F.getSubprogram(), &
F.getEntryBlock());
5067 R <<
"unable to translate in big endian mode";
5078 EntryBuilder->setMBB(*EntryBB);
5080 DebugLoc DbgLoc =
F.getEntryBlock().getFirstNonPHIIt()->getDebugLoc();
5081 SwiftError.setFunction(CurMF);
5082 SwiftError.createEntriesInEntryBlock(DbgLoc);
5084 bool IsVarArg =
F.isVarArg();
5085 bool HasMustTailInVarArgFn =
false;
5088 FuncInfo.MBBMap.resize(
F.getMaxBlockNumber());
5092 MBB = MF->CreateMachineBasicBlock(&BB);
5100 if (!BA->hasZeroLiveUses())
5104 if (!HasMustTailInVarArgFn)
5108 MF->getFrameInfo().setHasMustTailInVarArgFunc(HasMustTailInVarArgFn);
5111 EntryBB->addSuccessor(&getMBB(
F.front()));
5116 if (DL->getTypeStoreSize(Arg.
getType()).isZero())
5121 if (CLI->supportSwiftError() && Arg.hasSwiftErrorAttr()) {
5122 assert(VRegs.
size() == 1 &&
"Too many vregs for Swift error");
5123 SwiftError.setCurrentVReg(EntryBB, SwiftError.getFunctionArg(), VRegs[0]);
5127 if (!CLI->lowerFormalArguments(*EntryBuilder,
F, VRegArgs, FuncInfo)) {
5129 F.getSubprogram(), &
F.getEntryBlock());
5130 R <<
"unable to lower arguments: "
5131 <<
ore::NV(
"Prototype",
F.getFunctionType());
5138 if (EnableCSE && CSEInfo)
5143 DILocationVerifier Verifier;
5151 CurBuilder->setMBB(
MBB);
5152 HasTailCall =
false;
5162 Verifier.setCurrentInst(&Inst);
5166 translateDbgInfo(Inst, *CurBuilder);
5168 if (translate(Inst))
5173 R <<
"unable to translate instruction: " <<
ore::NV(
"Opcode", &Inst);
5175 if (ORE->allowExtraAnalysis(
"gisel-irtranslator")) {
5176 std::string InstStrStorage;
5180 R <<
": '" << InstStrStorage <<
"'";
5187 if (!finalizeBasicBlock(*BB,
MBB)) {
5189 BB->getTerminator()->getDebugLoc(), BB);
5190 R <<
"unable to translate basic block";
5200 finishPendingPhis();
5202 SwiftError.propagateVRegs();
5207 assert(EntryBB->succ_size() == 1 &&
5208 "Custom BB used for lowering should have only one successor");
5212 "LLVM-IR entry block has a predecessor!?");
5215 NewEntryBB.
splice(NewEntryBB.
begin(), EntryBB, EntryBB->begin(),
5224 EntryBB->removeSuccessor(&NewEntryBB);
5225 MF->remove(EntryBB);
5226 MF->deleteMachineBasicBlock(EntryBB);
5228 assert(&MF->front() == &NewEntryBB &&
5229 "New entry wasn't next in the list of basic block!");
5232 SPInfo->copyToMachineFrameInfo(MF->getFrameInfo());
5242 return Impl->runOnMachineFunction(
5261 *
F.getParent(), Subtarget),
5285 "LibcallLoweringModuleAnalysis must be available for IRTranslator");
5286 Impl->runOnMachineFunction(
5288 ShouldSkipOpts, [&]() {
return &
FAM.getResult<
AAManager>(
F); },
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Provides analysis for continuously CSEing during GISel passes.
This file implements a version of MachineIRBuilder which CSEs insts within a MachineBasicBlock.
This file describes how to lower LLVM calls to machine code calls.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This contains common code to allow clients to notify changes to machine instr.
const HexagonInstrInfo * TII
static bool checkForMustTailInVarArgFn(bool IsVarArg, const BasicBlock &BB)
Returns true if a BasicBlock BB within a variadic function contains a variadic musttail call.
static unsigned getConvOpcode(Intrinsic::ID ID)
static uint64_t getOffsetFromIndices(const User &U, const DataLayout &DL)
static unsigned getConstrainedOpcode(Intrinsic::ID ID)
IRTranslator LLVM IR static false void reportTranslationError(MachineFunction &MF, OptimizationRemarkEmitter &ORE, OptimizationRemarkMissed &R)
static cl::opt< bool > EnableCSEInIRTranslator("enable-cse-in-irtranslator", cl::desc("Should enable CSE in irtranslator"), cl::Optional, cl::init(false))
static bool isValInBlock(const Value *V, const BasicBlock *BB)
static bool isSwiftError(const Value *V)
This file declares the IRTranslator pass.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
This file describes how to lower LLVM inline asm to machine code INLINEASM.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Implement a low-level type suitable for MachineInstr level instruction selection.
Implement a low-level type suitable for MachineInstr level instruction selection.
This file declares the MachineIRBuilder class.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
OptimizedStructLayoutField Field
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
std::pair< BasicBlock *, BasicBlock * > Edge
verify safepoint Safepoint IR Verifier
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the scope_exit class, which executes user-defined cleanup logic at scope exit.
This file defines the SmallVector class.
This file describes how to lower LLVM code to machine code.
Target-Independent Code Generator Pass Configuration Options pass.
A manager for alias analyses.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
an instruction to allocate memory on the stack
bool isSwiftError() const
Return true if this alloca is used as a swifterror argument to a call.
LLVM_ABI bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
PointerType * getType() const
Overload to return most specific pointer type.
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
const Value * getArraySize() const
Get the number of elements allocated.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
This class represents an incoming formal argument to a Function.
LLVM_ABI bool hasSwiftErrorAttr() const
Return true if this argument has the swifterror attribute.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
@ USubCond
Subtract only if no unsigned overflow.
@ FMinimum
*p = minimum(old, v) minimum matches the behavior of llvm.minimum.
@ Min
*p = old <signed v ? old : v
@ USubSat
*p = usub.sat(old, v) usub.sat matches the behavior of llvm.usub.sat.
@ FMaximum
*p = maximum(old, v) maximum matches the behavior of llvm.maximum.
@ UIncWrap
Increment one up to a maximum value.
@ Max
*p = old >signed v ? old : v
@ UMin
*p = old <unsigned v ? old : v
@ FMin
*p = minnum(old, v) minnum matches the behavior of llvm.minnum.
@ UMax
*p = old >unsigned v ? old : v
@ FMaximumNum
*p = maximumnum(old, v) maximumnum matches the behavior of llvm.maximumnum.
@ FMax
*p = maxnum(old, v) maxnum matches the behavior of llvm.maxnum.
@ UDecWrap
Decrement one until a minimum value or zero.
@ FMinimumNum
*p = minimumnum(old, v) minimumnum matches the behavior of llvm.minimumnum.
LLVM Basic Block Representation.
unsigned getNumber() const
const Function * getParent() const
Return the enclosing method, or null if none.
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches,...
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
InstListType::const_iterator const_iterator
LLVM_ABI InstListType::const_iterator getFirstNonPHIOrDbg(bool SkipPseudoOp=true) const
Returns a pointer to the first instruction in this block that is not a PHINode or a debug intrinsic,...
LLVM_ABI const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr if the function does no...
The address of a basic block.
static LLVM_ABI BlockAddress * lookup(const BasicBlock *BB)
Lookup an existing BlockAddress constant for the given BasicBlock.
Legacy analysis pass which computes BlockFrequencyInfo.
Analysis pass which computes BranchProbabilityInfo.
Legacy analysis pass which computes BranchProbabilityInfo.
Analysis providing branch probability information.
LLVM_ABI BranchProbability getEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors) const
Get an edge's probability, relative to other out-edges of the Src.
static constexpr BranchProbability getOne()
static constexpr BranchProbability getUnknown()
static constexpr BranchProbability getZero()
static void normalizeProbabilities(ProbabilityIter Begin, ProbabilityIter End)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
bool isInlineAsm() const
Check if this call is an inline asm statement.
std::optional< OperandBundleUse > getOperandBundle(StringRef Name) const
Return an operand bundle by name, if present.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
LLVM_ABI bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
unsigned countOperandBundlesOfType(StringRef Name) const
Return the number of operand bundles with the tag Name attached to this instruction.
Value * getCalledOperand() const
Value * getArgOperand(unsigned i) const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
bool isConvergent() const
Determine if the invoke is convergent.
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned arg_size() const
AttributeList getAttributes() const
Return the attributes for this call.
This class represents a function call, abstracting a target machine's calling convention.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_ULE
unsigned less or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
bool isFPPredicate() const
bool isIntPredicate() const
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
unsigned getBitWidth() const
getBitWidth - Return the scalar bitwidth of this constant.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
const APInt & getValue() const
Return the constant as an APInt value reference.
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
This is the common base class for constrained floating point intrinsics.
LLVM_ABI std::optional< fp::ExceptionBehavior > getExceptionBehavior() const
LLVM_ABI unsigned getNonMetadataArgCount() const
LLVM_ABI bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
static LLVM_ABI DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
LLVM_ABI bool startsWithDeref() const
Return whether the first element a DW_OP_deref.
ArrayRef< uint64_t > getElements() const
bool isValidLocationForIntrinsic(const DILocation *DL) const
Check that a location is valid for this label.
A parsed version of the target data layout string in and methods for querying it.
Value * getAddress() const
DILabel * getLabel() const
DebugLoc getDebugLoc() const
Value * getValue(unsigned OpIdx=0) const
DILocalVariable * getVariable() const
DIExpression * getExpression() const
LLVM_ABI Value * getVariableLocationOp(unsigned OpIdx) const
DIExpression * getExpression() const
DILocalVariable * getVariable() const
bool isDbgDeclare() const
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT, true > const_iterator
Class representing an expression and its matching format.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
const BasicBlock & getEntryBlock() const
DISubprogram * getSubprogram() const
Get the attached subprogram.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
Constant * getPersonalityFn() const
Get the personality function associated with this function.
const Function & getFunction() const
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
bool hasOptNone() const
Do not optimize this function (-O0).
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
The actual analysis pass wrapper.
Simple wrapper that does the following.
Abstract class that contains various methods for clients to notify about changes.
Simple wrapper observer that takes several observers, and calls each one for each event.
void removeObserver(GISelChangeObserver *O)
void addObserver(GISelChangeObserver *O)
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
bool hasExternalWeakLinkage() const
bool hasDLLImportStorageClass() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isTailCall(const MachineInstr &MI) const override
IRTranslatorImpl(CodeGenOptLevel OptLevel=CodeGenOptLevel::None)
bool runOnMachineFunction(MachineFunction &MF, function_ref< GISelCSEInfo *()> GetCSEInfo, bool ShouldSkipOpts, function_ref< AAResults *()> GetAAResults, function_ref< BranchProbabilityInfo *()> GetBPI, function_ref< AssumptionCache *()> GetAC, TargetLibraryInfo *LibraryInfo, const LibcallLoweringInfo *LibcallInfo, SSPLayoutInfo *StackProtectorInfo)
IRTranslatorLegacy(CodeGenOptLevel OptLevel=CodeGenOptLevel::None)
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
~IRTranslatorLegacy() override
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
IRTranslatorPass(CodeGenOptLevel OptLevel)
bool lowerInlineAsm(MachineIRBuilder &MIRBuilder, const CallBase &CB, std::function< ArrayRef< Register >(const Value &Val)> GetOrCreateVRegs) const
Lower the given inline asm call instruction GetOrCreateVRegs is a callback to materialize a register ...
This instruction inserts a struct field of array element value into an aggregate value.
iterator_range< simple_ilist< DbgRecord >::iterator > getDbgRecordRange() const
Return a range over the DbgRecords attached to this instruction.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
LLVM_ABI AAMDNodes getAAMetadata() const
Returns the AA metadata for this instruction.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI bool hasAllowReassoc() const LLVM_READONLY
Determine whether the allow-reassociation flag is set.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
static bool getUseExtended()
constexpr bool isScalar() const
constexpr LLT changeElementType(LLT NewEltTy) const
If this type is a vector, return a vector with the same number of elements but the new element type.
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr bool isVector() const
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr bool isPointer() const
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
constexpr bool isFixedVector() const
Returns true if the LLT is a fixed vector.
static constexpr LLT token()
Get a low-level token; just a scalar with zero bits (or no size).
static LLT integer(unsigned SizeInBits)
LLT changeElementSize(unsigned NewEltSize) const
If this type is a vector, return a vector with the same number of elements but the new element size.
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Tracks which library functions to use for a particular subtarget or function.
Value * getPointerOperand()
AtomicOrdering getOrdering() const
Returns the ordering constraint of this load instruction.
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID of this load instruction.
static LocationSize precise(uint64_t Value)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
unsigned pred_size() const
void normalizeSuccProbs()
Normalize probabilities of all successors so that the sum of them becomes one.
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
void push_back(MachineInstr *MI)
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void setSuccProbability(succ_iterator I, BranchProbability Prob)
Set successor probability of a given iterator.
succ_iterator succ_begin()
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
SmallVectorImpl< MachineBasicBlock * >::iterator succ_iterator
LLVM_ABI void sortUniqueLiveIns()
Sorts and uniques the LiveIns vector.
LLVM_ABI bool isPredecessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a predecessor of this block.
LLVM_ABI bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
void setIsEHPad(bool V=true)
Indicates the block is a landing pad.
int getStackProtectorIndex() const
Return the index for the stack protector object.
MachineFunctionPass(char &ID)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
Helper class to build MachineInstr.
MachineInstrBuilder buildFPTOUI_SAT(const DstOp &Dst, const SrcOp &Src0)
Build and insert Res = G_FPTOUI_SAT Src0.
MachineInstrBuilder buildFMul(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
MachineInstrBuilder buildFreeze(const DstOp &Dst, const SrcOp &Src)
Build and insert Dst = G_FREEZE Src.
MachineInstrBuilder buildBr(MachineBasicBlock &Dest)
Build and insert G_BR Dest.
MachineInstrBuilder buildModf(const DstOp &Fract, const DstOp &Int, const SrcOp &Src, std::optional< unsigned > Flags=std::nullopt)
Build and insert Fract, Int = G_FMODF Src.
LLVMContext & getContext() const
MachineInstrBuilder buildAdd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_ADD Op0, Op1.
MachineInstrBuilder buildUndef(const DstOp &Res)
Build and insert Res = IMPLICIT_DEF.
MachineInstrBuilder buildResetFPMode()
Build and insert G_RESET_FPMODE.
MachineInstrBuilder buildFPTOSI_SAT(const DstOp &Dst, const SrcOp &Src0)
Build and insert Res = G_FPTOSI_SAT Src0.
MachineInstrBuilder buildUCmp(const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1)
Build and insert a Res = G_UCMP Op0, Op1.
MachineInstrBuilder buildJumpTable(const LLT PtrTy, unsigned JTI)
Build and insert Res = G_JUMP_TABLE JTI.
MachineInstrBuilder buildGetRounding(const DstOp &Dst)
Build and insert Dst = G_GET_ROUNDING.
MachineInstrBuilder buildSCmp(const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1)
Build and insert a Res = G_SCMP Op0, Op1.
MachineInstrBuilder buildFence(unsigned Ordering, unsigned Scope)
Build and insert G_FENCE Ordering, Scope.
MachineInstrBuilder buildSelect(const DstOp &Res, const SrcOp &Tst, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert a Res = G_SELECT Tst, Op0, Op1.
MachineInstrBuilder buildFMA(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, const SrcOp &Src2, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_FMA Op0, Op1, Op2.
MachineInstrBuilder buildMul(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_MUL Op0, Op1.
MachineInstrBuilder buildInsertSubvector(const DstOp &Res, const SrcOp &Src0, const SrcOp &Src1, unsigned Index)
Build and insert Res = G_INSERT_SUBVECTOR Src0, Src1, Idx.
MachineInstrBuilder buildAnd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1)
Build and insert Res = G_AND Op0, Op1.
MachineInstrBuilder buildCast(const DstOp &Dst, const SrcOp &Src)
Build and insert an appropriate cast between two registers of equal size.
MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert a Res = G_ICMP Pred, Op0, Op1.
MachineBasicBlock::iterator getInsertPt()
Current insertion point for new instructions.
MachineInstrBuilder buildSExtOrTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_SEXT Op, Res = G_TRUNC Op, or Res = COPY Op depending on the differing sizes...
MachineInstrBuilder buildAtomicRMW(unsigned Opcode, const DstOp &OldValRes, const SrcOp &Addr, const SrcOp &Val, MachineMemOperand &MMO)
Build and insert OldValRes<def> = G_ATOMICRMW_<Opcode> Addr, Val, MMO.
MachineInstrBuilder buildSub(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_SUB Op0, Op1.
MachineInstrBuilder buildIntrinsic(Intrinsic::ID ID, ArrayRef< Register > Res, bool HasSideEffects, bool isConvergent)
Build and insert a G_INTRINSIC instruction.
MachineInstrBuilder buildVScale(const DstOp &Res, unsigned MinElts)
Build and insert Res = G_VSCALE MinElts.
MachineInstrBuilder buildSplatBuildVector(const DstOp &Res, const SrcOp &Src)
Build and insert Res = G_BUILD_VECTOR with Src replicated to fill the number of elements.
MachineInstrBuilder buildSetFPMode(const SrcOp &Src)
Build and insert G_SET_FPMODE Src.
MachineInstrBuilder buildIndirectDbgValue(Register Reg, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instruction expressing the fact that the associated Variable lives in me...
MachineInstrBuilder buildBuildVector(const DstOp &Res, ArrayRef< Register > Ops)
Build and insert Res = G_BUILD_VECTOR Op0, ...
MachineInstrBuilder buildConstDbgValue(const Constant &C, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instructions specifying that Variable is given by C (suitably modified b...
MachineInstrBuilder buildBrCond(const SrcOp &Tst, MachineBasicBlock &Dest)
Build and insert G_BRCOND Tst, Dest.
std::optional< MachineInstrBuilder > materializeObjectPtrOffset(Register &Res, Register Op0, const LLT ValueTy, uint64_t Value)
Materialize and insert an instruction with appropriate flags for addressing some offset of an object,...
MachineInstrBuilder buildSetRounding(const SrcOp &Src)
Build and insert G_SET_ROUNDING.
MachineInstrBuilder buildExtractVectorElement(const DstOp &Res, const SrcOp &Val, const SrcOp &Idx)
Build and insert Res = G_EXTRACT_VECTOR_ELT Val, Idx.
MachineInstrBuilder buildLoad(const DstOp &Res, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
MachineInstrBuilder buildPtrAdd(const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_PTR_ADD Op0, Op1.
MachineInstrBuilder buildZExtOrTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ZEXT Op, Res = G_TRUNC Op, or Res = COPY Op depending on the differing sizes...
MachineInstrBuilder buildExtractVectorElementConstant(const DstOp &Res, const SrcOp &Val, const int Idx)
Build and insert Res = G_EXTRACT_VECTOR_ELT Val, Idx.
MachineInstrBuilder buildShl(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
MachineInstrBuilder buildStore(const SrcOp &Val, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineInstrBuilder buildFrameIndex(const DstOp &Res, int Idx)
Build and insert Res = G_FRAME_INDEX Idx.
MachineInstrBuilder buildDirectDbgValue(Register Reg, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instruction expressing the fact that the associated Variable lives in Re...
MachineInstrBuilder buildDbgLabel(const MDNode *Label)
Build and insert a DBG_LABEL instructions specifying that Label is given.
MachineInstrBuilder buildBrJT(Register TablePtr, unsigned JTI, Register IndexReg)
Build and insert G_BRJT TablePtr, JTI, IndexReg.
MachineInstrBuilder buildDynStackAlloc(const DstOp &Res, const SrcOp &Size, Align Alignment)
Build and insert Res = G_DYN_STACKALLOC Size, Align.
MachineInstrBuilder buildFIDbgValue(int FI, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instruction expressing the fact that the associated Variable lives in th...
MachineInstrBuilder buildResetFPEnv()
Build and insert G_RESET_FPENV.
void setDebugLoc(const DebugLoc &DL)
Set the debug location to DL for all the next build instructions.
const MachineBasicBlock & getMBB() const
Getter for the basic block we currently build.
MachineInstrBuilder buildInsertVectorElement(const DstOp &Res, const SrcOp &Val, const SrcOp &Elt, const SrcOp &Idx)
Build and insert Res = G_INSERT_VECTOR_ELT Val, Elt, Idx.
MachineInstrBuilder buildAtomicCmpXchgWithSuccess(const DstOp &OldValRes, const DstOp &SuccessRes, const SrcOp &Addr, const SrcOp &CmpVal, const SrcOp &NewVal, MachineMemOperand &MMO)
Build and insert OldValRes<def>, SuccessRes<def> = / G_ATOMIC_CMPXCHG_WITH_SUCCESS Addr,...
void setMBB(MachineBasicBlock &MBB)
Set the insertion point to the end of MBB.
const DebugLoc & getDebugLoc()
Get the current instruction's debug location.
MachineInstrBuilder buildTrap(bool Debug=false)
Build and insert G_TRAP or G_DEBUGTRAP.
MachineInstrBuilder buildFFrexp(const DstOp &Fract, const DstOp &Exp, const SrcOp &Src, std::optional< unsigned > Flags=std::nullopt)
Build and insert Fract, Exp = G_FFREXP Src.
MachineInstrBuilder buildFSincos(const DstOp &Sin, const DstOp &Cos, const SrcOp &Src, std::optional< unsigned > Flags=std::nullopt)
Build and insert Sin, Cos = G_FSINCOS Src.
MachineInstrBuilder buildShuffleVector(const DstOp &Res, const SrcOp &Src1, const SrcOp &Src2, ArrayRef< int > Mask)
Build and insert Res = G_SHUFFLE_VECTOR Src1, Src2, Mask.
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don't insert <empty> = Opcode <empty>.
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
MachineInstrBuilder buildPrefetch(const SrcOp &Addr, unsigned RW, unsigned Locality, unsigned CacheType, MachineMemOperand &MMO)
Build and insert G_PREFETCH Addr, RW, Locality, CacheType.
MachineInstrBuilder buildExtractSubvector(const DstOp &Res, const SrcOp &Src, unsigned Index)
Build and insert Res = G_EXTRACT_SUBVECTOR Src, Idx0.
const DataLayout & getDataLayout() const
MachineInstrBuilder buildBrIndirect(Register Tgt)
Build and insert G_BRINDIRECT Tgt.
MachineInstrBuilder buildSplatVector(const DstOp &Res, const SrcOp &Val)
Build and insert Res = G_SPLAT_VECTOR Val.
MachineInstrBuilder buildStepVector(const DstOp &Res, unsigned Step)
Build and insert Res = G_STEP_VECTOR Step.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
MachineInstrBuilder buildFCmp(CmpInst::Predicate Pred, const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert a Res = G_FCMP PredOp0, Op1.
MachineInstrBuilder buildFAdd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_FADD Op0, Op1.
MachineInstrBuilder buildSetFPEnv(const SrcOp &Src)
Build and insert G_SET_FPENV Src.
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addMetadata(const MDNode *MD) const
const MachineInstrBuilder & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addFPImm(const ConstantFP *Val) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
LLVM_ABI void copyIRFlags(const Instruction &I)
Copy all flags to MachineInst MIFlags.
static LLVM_ABI uint32_t copyFlagsFromInstruction(const Instruction &I)
LLVM_ABI void setDeactivationSymbol(MachineFunction &MF, Value *DS)
void setDebugLoc(DebugLoc DL)
Replace current source information with new such.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
static MachineOperand CreateES(const char *SymName, unsigned TargetFlags=0)
static MachineOperand CreateGA(const GlobalValue *GV, int64_t Offset, unsigned TargetFlags=0)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
Records a mapping from an opaque lowering context to its LibcallLoweringInfo.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
A set of analyses that are preserved following a run of a transformation pass.
Class to install both of the above.
Wrapper class representing virtual and physical registers.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A BumpPtrAllocator that allows only elements of a specific type to be allocated.
Encapsulates all of the information needed to generate a stack protector check, and signals to isel w...
MachineBasicBlock * getSuccessMBB()
MachineBasicBlock * getFailureMBB()
constexpr bool empty() const
Check if the string is empty.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
SwitchLowering(FunctionLoweringInfo &funcinfo)
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
const Triple & getTargetTriple() const
const Target & getTarget() const
unsigned NoTrapAfterNoreturn
Do not emit a trap instruction for 'unreachable' IR instructions behind noreturn calls,...
unsigned TrapUnreachable
Emit target-specific trap instruction for 'unreachable' IR instructions.
FPOpFusion::FPOpFusionMode AllowFPOpFusion
AllowFPOpFusion - This flag is set by the -fp-contract=xxx option.
Target-Independent Code Generator Pass Configuration Options.
virtual std::unique_ptr< CSEConfigBase > getCSEConfig() const
Returns the CSEConfig object to use for the current optimization level.
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const CallLowering * getCallLowering() const
virtual const TargetLowering * getTargetLowering() const
bool isSPIRV() const
Tests whether the target is SPIR-V (32/64-bit/Logical).
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static constexpr TypeSize getZero()
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI bool isEmptyTy() const
Return true if this type is empty, that is, it has no elements or all of its elements are empty.
bool isByteTy() const
True if this is an instance of ByteType.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
bool isPointerTy() const
True if this is an instance of PointerType.
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
bool isAggregateType() const
Return true if the type is an aggregate type.
bool isTokenTy() const
Return true if this is 'token'.
bool isVoidTy() const
Return true if this is 'void'.
BasicBlock * getSuccessor(unsigned i=0) const
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
constexpr bool isZero() const
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
A raw_ostream that writes to an std::string.
Pass manager infrastructure for declaring and invalidating analyses.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
TwoOps_match< Val_t, Idx_t, Instruction::ExtractElement > m_ExtractElt(const Val_t &Val, const Idx_t &Idx)
Matches ExtractElementInst.
auto m_Value()
Match an arbitrary value and ignore it.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
LLVM_ABI void sortAndRangeify(CaseClusterVector &Clusters)
Sort Clusters and merge adjacent cases.
std::vector< CaseCluster > CaseClusterVector
@ CC_Range
A cluster of adjacent case labels with the same destination, or just one case.
@ CC_JumpTable
A cluster of cases suitable for jump table lowering.
@ CC_BitTests
A cluster of cases suitable for bit test lowering.
SmallVector< SwitchWorkListItem, 4 > SwitchWorkList
CaseClusterVector::iterator CaseClusterIt
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
ExceptionBehavior
Exception behavior used for floating point operations.
@ ebIgnore
This corresponds to "fpexcept.ignore".
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< PhiNode * > Phi
NodeAddr< CodeNode * > Code
friend class Instruction
Iterator for Instructions in a `BasicBlock.
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Undef
Value of the register doesn't matter.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
LLVM_ABI void diagnoseDontCall(const CallInst &CI)
auto successors(const MachineBasicBlock *BB)
LLVM_ABI MVT getMVTForLLT(LLT Ty)
Get a rough equivalent of an MVT for a given LLT.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
gep_type_iterator gep_type_end(const User *GEP)
LLVM_ABI MachineBasicBlock::iterator findSplitPointForStackProtector(MachineBasicBlock *BB, const TargetInstrInfo &TII)
Find the split point at which to splice the end of BB into its success stack protector check machine ...
LLVM_ABI LLT getLLTForMVT(MVT Ty)
Get a rough equivalent of an LLT for a given MVT.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
Align getKnownAlignment(Value *V, const DataLayout &DL, const Instruction *CxtI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr)
Try to infer an alignment for the specified pointer.
constexpr bool has_single_bit(T Value) noexcept
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI llvm::SmallVector< int, 16 > createStrideMask(unsigned Start, unsigned Stride, unsigned VF)
Create a stride shuffle mask.
auto reverse(ContainerTy &&C)
LLVM_ABI const LibcallLoweringInfo & getLibcallLowering(const ModuleLibcallLoweringInfo &ModuleInfo, const TargetSubtargetInfo &Subtarget)
Resolve the LibcallLoweringInfo for Subtarget from the module-level ModuleInfo, applying the subtarge...
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
generic_gep_type_iterator<> gep_type_iterator
auto succ_size(const MachineBasicBlock *BB)
LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Success
The lock was released successfully.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
@ Global
Append to llvm.global_dtors.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
LLVM_ABI llvm::SmallVector< int, 16 > createInterleaveMask(unsigned VF, unsigned NumVecs)
Create an interleave shuffle mask.
@ Sub
Subtraction of integers.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
bool isAsynchronousEHPersonality(EHPersonality Pers)
Returns true if this personality function catches asynchronous exceptions.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI std::optional< RoundingMode > convertStrToRoundingMode(StringRef)
Returns a valid RoundingMode enumerator when given a string that is valid as input in constrained int...
gep_type_iterator gep_type_begin(const User *GEP)
LLVM_ABI void computeValueLLTs(const DataLayout &DL, Type &Ty, SmallVectorImpl< LLT > &ValueLLTs, SmallVectorImpl< TypeSize > *Offsets=nullptr, TypeSize StartingOffset=TypeSize::getZero())
computeValueLLTs - Given an LLVM IR type, compute a sequence of LLTs that represent all the individua...
LLVM_ABI GlobalValue * ExtractTypeInfo(Value *V)
ExtractTypeInfo - Returns the type info, possibly bitcast, encoded in V.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
LLVM_ABI LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Pair of physical register and lane mask.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl)
Get the libcall routine name for the specified libcall implementation.
MachineBasicBlock * Parent
This structure is used to communicate between SelectionDAGBuilder and SDISel for the code generation ...
BranchProbability TrueProb
MachineBasicBlock * ThisBB
struct PredInfoPair PredInfo
BranchProbability FalseProb
MachineBasicBlock * TrueBB
MachineBasicBlock * FalseBB
Register Reg
The virtual register containing the index of the jump table entry to jump to.
MachineBasicBlock * Default
The MBB of the default bb, which is a successor of the range check MBB.
unsigned JTI
The JumpTableIndex for this jump table in the function.
MachineBasicBlock * MBB
The MBB into which to emit the code for the indirect jump.