64#include "llvm/IR/IntrinsicsAMDGPU.h"
93#define DEBUG_TYPE "irtranslator"
99 cl::desc(
"Should enable CSE in irtranslator"),
116 MF.getProperties().setFailedISel();
117 bool IsGlobalISelAbortEnabled =
122 if (!R.getLocation().isValid() || IsGlobalISelAbortEnabled)
123 R << (
" (in function: " + MF.getName() +
")").str();
125 if (IsGlobalISelAbortEnabled)
142 DILocationVerifier() =
default;
143 ~DILocationVerifier()
override =
default;
145 const Instruction *getCurrentInst()
const {
return CurrInst; }
146 void setCurrentInst(
const Instruction *Inst) { CurrInst = Inst; }
148 void erasingInstr(MachineInstr &
MI)
override {}
149 void changingInstr(MachineInstr &
MI)
override {}
150 void changedInstr(MachineInstr &
MI)
override {}
152 void createdInstr(MachineInstr &
MI)
override {
153 assert(getCurrentInst() &&
"Inserted instruction without a current MI");
158 <<
" was copied to " <<
MI);
164 (
MI.getParent()->isEntryBlock() && !
MI.getDebugLoc()) ||
165 (
MI.isDebugInstr())) &&
166 "Line info was not transferred to all instructions");
190IRTranslator::ValueToVRegInfo::VRegListT &
191IRTranslator::allocateVRegs(
const Value &Val) {
192 auto VRegsIt = VMap.findVRegs(Val);
193 if (VRegsIt != VMap.vregs_end())
194 return *VRegsIt->second;
195 auto *Regs = VMap.getVRegs(Val);
196 auto *Offsets = VMap.getOffsets(Val);
199 Offsets->empty() ? Offsets :
nullptr);
200 for (
unsigned i = 0; i < SplitTys.
size(); ++i)
206 auto VRegsIt = VMap.findVRegs(Val);
207 if (VRegsIt != VMap.vregs_end())
208 return *VRegsIt->second;
211 return *VMap.getVRegs(Val);
214 auto *VRegs = VMap.getVRegs(Val);
215 auto *Offsets = VMap.getOffsets(Val);
219 "Don't know how to create an empty vreg");
224 if (Offsets->empty())
225 Offsets->push_back(0);
233 R <<
"unable to translate constant: " <<
ore::NV(
"Type", Val.
getType());
242 Offsets->empty() ? Offsets :
nullptr);
245 for (
auto Ty : SplitTys)
246 VRegs->push_back(MRI->createGenericVirtualRegister(Ty));
253 while (
auto Elt =
C.getAggregateElement(Idx++)) {
254 auto EltRegs = getOrCreateVRegs(*Elt);
261int IRTranslator::getOrCreateFrameIndex(
const AllocaInst &AI) {
262 auto [MapEntry,
Inserted] = FrameIndices.try_emplace(&AI);
264 return MapEntry->second;
270 Size = std::max<uint64_t>(
Size, 1u);
272 int &FI = MapEntry->second;
273 FI = MF->getFrameInfo().CreateStackObject(
Size, AI.
getAlign(),
false, &AI);
280 MF->getSubtarget().getFrameLowering()->getStackIDForScalableVectors();
281 MF->getFrameInfo().setStackID(FI, StackID);
289 return SI->getAlign();
291 return LI->getAlign();
297 OptimizationRemarkMissed
R(
"gisel-irtranslator",
"", &
I);
298 R <<
"unable to translate memop: " <<
ore::NV(
"Opcode", &
I);
304 MachineBasicBlock *
MBB = FuncInfo.getMBB(&BB);
305 assert(
MBB &&
"BasicBlock was not encountered before");
310 assert(NewPred &&
"new predecessor must be a real MachineBasicBlock");
311 MachinePreds[
Edge].push_back(NewPred);
314bool IRTranslator::translateBinaryOp(
unsigned Opcode,
const User &U,
316 if (!mayTranslateUserTypes(U))
323 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
324 Register Op1 = getOrCreateVReg(*
U.getOperand(1));
336bool IRTranslator::translateUnaryOp(
unsigned Opcode,
const User &U,
338 if (!mayTranslateUserTypes(U))
341 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
353 return translateUnaryOp(TargetOpcode::G_FNEG, U, MIRBuilder);
356bool IRTranslator::translateCompare(
const User &U,
358 if (!mayTranslateUserTypes(U))
362 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
363 Register Op1 = getOrCreateVReg(*
U.getOperand(1));
368 MIRBuilder.
buildICmp(Pred, Res, Op0, Op1, Flags);
376 MIRBuilder.
buildFCmp(Pred, Res, Op0, Op1, Flags);
384 if (Ret && DL->getTypeStoreSize(Ret->
getType()).isZero())
389 VRegs = getOrCreateVRegs(*Ret);
392 if (CLI->supportSwiftError() && SwiftError.getFunctionArg()) {
393 SwiftErrorVReg = SwiftError.getOrCreateVRegUseAt(
394 &RI, &MIRBuilder.
getMBB(), SwiftError.getFunctionArg());
400 return CLI->lowerReturn(MIRBuilder, Ret, VRegs, FuncInfo, SwiftErrorVReg);
403void IRTranslator::emitBranchForMergedCondition(
412 Condition = InvertCond ? IC->getInversePredicate() : IC->getPredicate();
415 Condition = InvertCond ?
FC->getInversePredicate() :
FC->getPredicate();
418 SwitchCG::CaseBlock CB(Condition,
false, BOp->getOperand(0),
419 BOp->getOperand(1),
nullptr,
TBB, FBB, CurBB,
420 CurBuilder->getDebugLoc(), TProb, FProb);
421 SL->SwitchCases.push_back(CB);
427 SwitchCG::CaseBlock CB(
429 nullptr,
TBB, FBB, CurBB, CurBuilder->getDebugLoc(), TProb, FProb);
430 SL->SwitchCases.push_back(CB);
435 return I->getParent() == BB;
439void IRTranslator::findMergedConditions(
444 using namespace PatternMatch;
445 assert((
Opc == Instruction::And ||
Opc == Instruction::Or) &&
446 "Expected Opc to be AND/OR");
452 findMergedConditions(NotCond,
TBB, FBB, CurBB, SwitchBB,
Opc, TProb, FProb,
458 const Value *BOpOp0, *BOpOp1;
472 if (BOpc == Instruction::And)
473 BOpc = Instruction::Or;
474 else if (BOpc == Instruction::Or)
475 BOpc = Instruction::And;
481 bool BOpIsInOrAndTree = BOpc && BOpc ==
Opc && BOp->
hasOneUse();
485 emitBranchForMergedCondition(
Cond,
TBB, FBB, CurBB, SwitchBB, TProb, FProb,
492 MachineBasicBlock *TmpBB =
496 if (
Opc == Instruction::Or) {
517 auto NewTrueProb = TProb / 2;
518 auto NewFalseProb = TProb / 2 + FProb;
520 findMergedConditions(BOpOp0,
TBB, TmpBB, CurBB, SwitchBB,
Opc, NewTrueProb,
521 NewFalseProb, InvertCond);
527 findMergedConditions(BOpOp1,
TBB, FBB, TmpBB, SwitchBB,
Opc, Probs[0],
528 Probs[1], InvertCond);
530 assert(
Opc == Instruction::And &&
"Unknown merge op!");
550 auto NewTrueProb = TProb + FProb / 2;
551 auto NewFalseProb = FProb / 2;
553 findMergedConditions(BOpOp0, TmpBB, FBB, CurBB, SwitchBB,
Opc, NewTrueProb,
554 NewFalseProb, InvertCond);
560 findMergedConditions(BOpOp1,
TBB, FBB, TmpBB, SwitchBB,
Opc, Probs[0],
561 Probs[1], InvertCond);
565bool IRTranslator::shouldEmitAsBranches(
566 const std::vector<SwitchCG::CaseBlock> &Cases) {
568 if (Cases.size() != 2)
573 if ((Cases[0].CmpLHS == Cases[1].CmpLHS &&
574 Cases[0].CmpRHS == Cases[1].CmpRHS) ||
575 (Cases[0].CmpRHS == Cases[1].CmpLHS &&
576 Cases[0].CmpLHS == Cases[1].CmpRHS)) {
582 if (Cases[0].CmpRHS == Cases[1].CmpRHS &&
583 Cases[0].PredInfo.Pred == Cases[1].PredInfo.Pred &&
587 Cases[0].TrueBB == Cases[1].ThisBB)
590 Cases[0].FalseBB == Cases[1].ThisBB)
597bool IRTranslator::translateUncondBr(
const User &U,
600 auto &CurMBB = MIRBuilder.
getMBB();
608 for (
const BasicBlock *Succ :
successors(&BrInst))
609 CurMBB.addSuccessor(&getMBB(*Succ));
613bool IRTranslator::translateCondBr(
const User &U,
616 auto &CurMBB = MIRBuilder.
getMBB();
622 MachineBasicBlock *Succ1MBB = &getMBB(*BrInst.
getSuccessor(1));
641 using namespace PatternMatch;
643 if (!TLI->isJumpExpensive() && CondI && CondI->
hasOneUse() &&
644 !BrInst.
hasMetadata(LLVMContext::MD_unpredictable)) {
647 const Value *BOp0, *BOp1;
649 Opcode = Instruction::And;
651 Opcode = Instruction::Or;
655 findMergedConditions(CondI, Succ0MBB, Succ1MBB, &CurMBB, &CurMBB, Opcode,
656 getEdgeProbability(&CurMBB, Succ0MBB),
657 getEdgeProbability(&CurMBB, Succ1MBB),
659 assert(SL->SwitchCases[0].ThisBB == &CurMBB &&
"Unexpected lowering!");
662 if (shouldEmitAsBranches(SL->SwitchCases)) {
664 emitSwitchCase(SL->SwitchCases[0], &CurMBB, *CurBuilder);
665 SL->SwitchCases.erase(SL->SwitchCases.begin());
671 for (
unsigned I = 1,
E = SL->SwitchCases.size();
I !=
E; ++
I)
672 MF->erase(SL->SwitchCases[
I].ThisBB);
674 SL->SwitchCases.clear();
681 nullptr, Succ0MBB, Succ1MBB, &CurMBB,
682 CurBuilder->getDebugLoc());
686 emitSwitchCase(CB, &CurMBB, *CurBuilder);
694 Src->addSuccessorWithoutProb(Dst);
698 Prob = getEdgeProbability(Src, Dst);
699 Src->addSuccessor(Dst, Prob);
705 const BasicBlock *SrcBB = Src->getBasicBlock();
706 const BasicBlock *DstBB = Dst->getBasicBlock();
710 auto SuccSize = std::max<uint32_t>(
succ_size(SrcBB), 1);
711 return BranchProbability(1, SuccSize);
713 return FuncInfo.BPI->getEdgeProbability(SrcBB, DstBB);
717 using namespace SwitchCG;
720 BranchProbabilityInfo *BPI = FuncInfo.BPI;
722 Clusters.reserve(
SI.getNumCases());
723 for (
const auto &
I :
SI.cases()) {
724 MachineBasicBlock *Succ = &getMBB(*
I.getCaseSuccessor());
725 assert(Succ &&
"Could not find successor mbb in mapping");
726 const ConstantInt *CaseVal =
I.getCaseValue();
727 BranchProbability Prob =
729 : BranchProbability(1,
SI.getNumCases() + 1);
730 Clusters.push_back(CaseCluster::range(CaseVal, CaseVal, Succ, Prob));
733 MachineBasicBlock *DefaultMBB = &getMBB(*
SI.getDefaultDest());
740 MachineBasicBlock *SwitchMBB = &getMBB(*
SI.getParent());
743 if (Clusters.empty()) {
750 SL->findJumpTables(Clusters, &SI, std::nullopt, DefaultMBB,
nullptr,
nullptr);
751 SL->findBitTestClusters(Clusters, &SI);
754 dbgs() <<
"Case clusters: ";
755 for (
const CaseCluster &
C : Clusters) {
756 if (
C.Kind == CC_JumpTable)
758 if (
C.Kind == CC_BitTests)
761 C.Low->getValue().print(
dbgs(),
true);
762 if (
C.Low !=
C.High) {
764 C.High->getValue().print(
dbgs(),
true);
771 assert(!Clusters.empty());
775 auto DefaultProb = getEdgeProbability(SwitchMBB, DefaultMBB);
776 WorkList.push_back({SwitchMBB,
First,
Last,
nullptr,
nullptr, DefaultProb});
778 while (!WorkList.empty()) {
779 SwitchWorkListItem
W = WorkList.pop_back_val();
781 unsigned NumClusters =
W.LastCluster -
W.FirstCluster + 1;
783 if (NumClusters > 3 &&
786 splitWorkItem(WorkList, W,
SI.getCondition(), SwitchMBB, MIB);
790 if (!lowerSwitchWorkItem(W,
SI.getCondition(), SwitchMBB, DefaultMBB, MIB))
800 using namespace SwitchCG;
801 assert(
W.FirstCluster->Low->getValue().slt(
W.LastCluster->Low->getValue()) &&
802 "Clusters not sorted?");
803 assert(
W.LastCluster -
W.FirstCluster + 1 >= 2 &&
"Too small to split!");
805 auto [LastLeft, FirstRight, LeftProb, RightProb] =
806 SL->computeSplitWorkItemInfo(W);
811 assert(PivotCluster >
W.FirstCluster);
812 assert(PivotCluster <=
W.LastCluster);
817 const ConstantInt *Pivot = PivotCluster->Low;
826 MachineBasicBlock *LeftMBB;
827 if (FirstLeft == LastLeft && FirstLeft->Kind == CC_Range &&
828 FirstLeft->Low ==
W.GE &&
829 (FirstLeft->High->getValue() + 1LL) == Pivot->
getValue()) {
830 LeftMBB = FirstLeft->MBB;
832 LeftMBB = FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
833 FuncInfo.MF->
insert(BBI, LeftMBB);
835 {LeftMBB, FirstLeft, LastLeft,
W.GE, Pivot,
W.DefaultProb / 2});
841 MachineBasicBlock *RightMBB;
842 if (FirstRight == LastRight && FirstRight->Kind == CC_Range &&
W.LT &&
843 (FirstRight->High->getValue() + 1ULL) ==
W.LT->getValue()) {
844 RightMBB = FirstRight->MBB;
846 RightMBB = FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
847 FuncInfo.MF->
insert(BBI, RightMBB);
849 {RightMBB, FirstRight, LastRight, Pivot,
W.LT,
W.DefaultProb / 2});
857 if (
W.MBB == SwitchMBB)
858 emitSwitchCase(CB, SwitchMBB, MIB);
860 SL->SwitchCases.push_back(CB);
866 assert(JT.
Reg &&
"Should lower JT Header first!");
881 MachineIRBuilder MIB(*HeaderBB->
getParent());
888 Register SwitchOpReg = getOrCreateVReg(SValue);
890 auto Sub = MIB.
buildSub({SwitchTy}, SwitchOpReg, FirstCst);
895 const LLT PtrScalarTy =
LLT::integer(DL->getTypeSizeInBits(PtrIRTy));
909 auto Cst = getOrCreateVReg(
950 if (MRI->getType(CondLHS).getSizeInBits() == 1 && CI && CI->isOne() &&
964 "Can only handle SLE ranges");
975 const LLT CmpTy = MRI->getType(CmpOpReg);
976 auto Sub = MIB.
buildSub({CmpTy}, CmpOpReg, CondLHS);
1011 bool FallthroughUnreachable) {
1012 using namespace SwitchCG;
1013 MachineFunction *CurMF = SwitchMBB->
getParent();
1015 JumpTableHeader *JTH = &SL->JTCases[
I->JTCasesIndex].first;
1016 SwitchCG::JumpTable *JT = &SL->JTCases[
I->JTCasesIndex].second;
1017 BranchProbability DefaultProb =
W.DefaultProb;
1020 MachineBasicBlock *JumpMBB = JT->
MBB;
1021 CurMF->
insert(BBI, JumpMBB);
1031 auto JumpProb =
I->Prob;
1032 auto FallthroughProb = UnhandledProbs;
1040 if (*SI == DefaultMBB) {
1041 JumpProb += DefaultProb / 2;
1042 FallthroughProb -= DefaultProb / 2;
1047 addMachineCFGPred({SwitchMBB->
getBasicBlock(), (*SI)->getBasicBlock()},
1052 if (FallthroughUnreachable)
1053 JTH->FallthroughUnreachable =
true;
1055 if (!JTH->FallthroughUnreachable)
1056 addSuccessorWithProb(CurMBB, Fallthrough, FallthroughProb);
1057 addSuccessorWithProb(CurMBB, JumpMBB, JumpProb);
1062 JTH->HeaderBB = CurMBB;
1066 if (CurMBB == SwitchMBB) {
1067 if (!emitJumpTableHeader(*JT, *JTH, CurMBB))
1069 JTH->Emitted =
true;
1076 bool FallthroughUnreachable,
1081 using namespace SwitchCG;
1084 if (
I->Low ==
I->High) {
1100 CaseBlock CB(Pred, FallthroughUnreachable,
LHS,
RHS, MHS,
I->MBB, Fallthrough,
1103 emitSwitchCase(CB, SwitchMBB, MIB);
1109 MachineIRBuilder &MIB = *CurBuilder;
1113 Register SwitchOpReg = getOrCreateVReg(*
B.SValue);
1115 LLT SwitchOpTy = MRI->getType(SwitchOpReg);
1117 auto RangeSub = MIB.
buildSub(SwitchOpTy, SwitchOpReg, MinValReg);
1122 LLT MaskTy = SwitchOpTy;
1128 for (
const SwitchCG::BitTestCase &Case :
B.Cases) {
1137 Register SubReg = RangeSub.getReg(0);
1138 if (SwitchOpTy != MaskTy)
1144 MachineBasicBlock *
MBB =
B.Cases[0].ThisBB;
1146 if (!
B.FallthroughUnreachable)
1147 addSuccessorWithProb(SwitchBB,
B.Default,
B.DefaultProb);
1148 addSuccessorWithProb(SwitchBB,
MBB,
B.Prob);
1152 if (!
B.FallthroughUnreachable) {
1156 RangeSub, RangeCst);
1170 MachineIRBuilder &MIB = *CurBuilder;
1176 if (PopCount == 1) {
1179 auto MaskTrailingZeros =
1184 }
else if (PopCount == BB.
Range) {
1186 auto MaskTrailingOnes =
1194 auto SwitchVal = MIB.
buildShl(SwitchTy, CstOne,
Reg);
1198 auto AndOp = MIB.
buildAnd(SwitchTy, SwitchVal, CstMask);
1205 addSuccessorWithProb(SwitchBB,
B.TargetBB,
B.ExtraProb);
1207 addSuccessorWithProb(SwitchBB, NextMBB, BranchProbToNext);
1225bool IRTranslator::lowerBitTestWorkItem(
1231 bool FallthroughUnreachable) {
1232 using namespace SwitchCG;
1233 MachineFunction *CurMF = SwitchMBB->
getParent();
1235 BitTestBlock *BTB = &SL->BitTestCases[
I->BTCasesIndex];
1237 for (BitTestCase &BTC : BTB->Cases)
1238 CurMF->
insert(BBI, BTC.ThisBB);
1241 BTB->Parent = CurMBB;
1242 BTB->Default = Fallthrough;
1244 BTB->DefaultProb = UnhandledProbs;
1248 if (!BTB->ContiguousRange) {
1249 BTB->Prob += DefaultProb / 2;
1250 BTB->DefaultProb -= DefaultProb / 2;
1253 if (FallthroughUnreachable)
1254 BTB->FallthroughUnreachable =
true;
1257 if (CurMBB == SwitchMBB) {
1258 emitBitTestHeader(*BTB, SwitchMBB);
1259 BTB->Emitted =
true;
1269 using namespace SwitchCG;
1270 MachineFunction *CurMF = FuncInfo.MF;
1271 MachineBasicBlock *NextMBB =
nullptr;
1273 if (++BBI != FuncInfo.MF->end())
1282 [](
const CaseCluster &a,
const CaseCluster &b) {
1283 return a.Prob != b.Prob
1285 : a.Low->getValue().slt(b.Low->getValue());
1290 for (CaseClusterIt
I =
W.LastCluster;
I >
W.FirstCluster;) {
1292 if (
I->Prob >
W.LastCluster->Prob)
1294 if (
I->Kind == CC_Range &&
I->MBB == NextMBB) {
1302 BranchProbability DefaultProb =
W.DefaultProb;
1303 BranchProbability UnhandledProbs = DefaultProb;
1304 for (CaseClusterIt
I =
W.FirstCluster;
I <=
W.LastCluster; ++
I)
1305 UnhandledProbs +=
I->Prob;
1307 MachineBasicBlock *CurMBB =
W.MBB;
1308 for (CaseClusterIt
I =
W.FirstCluster,
E =
W.LastCluster;
I <=
E; ++
I) {
1309 bool FallthroughUnreachable =
false;
1310 MachineBasicBlock *Fallthrough;
1311 if (
I ==
W.LastCluster) {
1313 Fallthrough = DefaultMBB;
1318 CurMF->
insert(BBI, Fallthrough);
1320 UnhandledProbs -=
I->Prob;
1324 if (!lowerBitTestWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
1325 DefaultProb, UnhandledProbs,
I, Fallthrough,
1326 FallthroughUnreachable)) {
1334 if (!lowerJumpTableWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
1335 UnhandledProbs,
I, Fallthrough,
1336 FallthroughUnreachable)) {
1343 if (!lowerSwitchRangeWorkItem(
I,
Cond, Fallthrough,
1344 FallthroughUnreachable, UnhandledProbs,
1345 CurMBB, MIB, SwitchMBB)) {
1352 CurMBB = Fallthrough;
1358bool IRTranslator::translateIndirectBr(
const User &U,
1366 SmallPtrSet<const BasicBlock *, 32> AddedSuccessors;
1367 MachineBasicBlock &CurBB = MIRBuilder.
getMBB();
1368 for (
const BasicBlock *Succ :
successors(&BrInst)) {
1372 if (!AddedSuccessors.
insert(Succ).second)
1382 return Arg->hasSwiftErrorAttr();
1390 TypeSize StoreSize = DL->getTypeStoreSize(LI.
getType());
1401 assert(Regs.
size() == 1 &&
"swifterror should be single pointer");
1403 SwiftError.getOrCreateVRegUseAt(&LI, &MIRBuilder.
getMBB(), Ptr);
1409 TLI->getLoadMemOperandFlags(LI, *DL, AC, LibInfo, OptLevel);
1411 if (AA->pointsToConstantMemory(
1418 if (Regs.
size() == 1) {
1419 auto *MMO = MF->getMachineMemOperand(
1421 MRI->getType(Regs[0]), getMemOpAlign(LI),
1422 MMOMetadata(AAInfo, LI.
getMetadata(LLVMContext::MD_range)),
1428 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(LI);
1429 Type *OffsetIRTy = DL->getIndexType(Ptr->
getType());
1431 for (
unsigned i = 0; i < Regs.
size(); ++i) {
1436 Align BaseAlign = getMemOpAlign(LI);
1438 MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Regs[i]),
1441 MIRBuilder.
buildLoad(Regs[i], Addr, *MMO);
1449 if (DL->getTypeStoreSize(
SI.getValueOperand()->getType()).isZero())
1455 if (CLI->supportSwiftError() &&
isSwiftError(
SI.getPointerOperand())) {
1456 assert(Vals.
size() == 1 &&
"swifterror should be single pointer");
1458 Register VReg = SwiftError.getOrCreateVRegDefAt(&SI, &MIRBuilder.
getMBB(),
1459 SI.getPointerOperand());
1466 if (Vals.
size() == 1) {
1467 auto *MMO = MF->getMachineMemOperand(
1468 MachinePointerInfo(
SI.getPointerOperand()), Flags,
1469 MRI->getType(Vals[0]), getMemOpAlign(SI),
SI.getAAMetadata(),
1470 SI.getSyncScopeID(),
SI.getOrdering());
1475 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(*
SI.getValueOperand());
1476 Type *OffsetIRTy = DL->getIndexType(
SI.getPointerOperandType());
1478 for (
unsigned i = 0; i < Vals.
size(); ++i) {
1482 MachinePointerInfo Ptr(
SI.getPointerOperand(), Offsets[i]);
1483 Align BaseAlign = getMemOpAlign(SI);
1484 auto *MMO = MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Vals[i]),
1487 SI.getSyncScopeID(),
SI.getOrdering());
1494 const Value *Src = U.getOperand(0);
1500 Indices.
push_back(ConstantInt::get(Int32Ty, 0));
1503 for (
auto Idx : EVI->indices())
1504 Indices.
push_back(ConstantInt::get(Int32Ty, Idx));
1506 for (
auto Idx : IVI->indices())
1507 Indices.
push_back(ConstantInt::get(Int32Ty, Idx));
1513 DL.getIndexedOffsetInType(Src->getType(), Indices));
1516bool IRTranslator::translateExtractValue(
const User &U,
1518 const Value *Src =
U.getOperand(0);
1521 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(*Src);
1523 auto &DstRegs = allocateVRegs(U);
1525 for (
unsigned i = 0; i < DstRegs.size(); ++i)
1526 DstRegs[i] = SrcRegs[Idx++];
1531bool IRTranslator::translateInsertValue(
const User &U,
1533 const Value *Src =
U.getOperand(0);
1535 auto &DstRegs = allocateVRegs(U);
1536 ArrayRef<uint64_t> DstOffsets = *VMap.getOffsets(U);
1539 auto *InsertedIt = InsertedRegs.
begin();
1541 for (
unsigned i = 0; i < DstRegs.size(); ++i) {
1542 if (DstOffsets[i] >=
Offset && InsertedIt != InsertedRegs.
end())
1543 DstRegs[i] = *InsertedIt++;
1545 DstRegs[i] = SrcRegs[i];
1551bool IRTranslator::translateSelect(
const User &U,
1553 Register Tst = getOrCreateVReg(*
U.getOperand(0));
1562 for (
unsigned i = 0; i < ResRegs.
size(); ++i) {
1563 MIRBuilder.
buildSelect(ResRegs[i], Tst, Op0Regs[i], Op1Regs[i], Flags);
1569bool IRTranslator::translateCopy(
const User &U,
const Value &V,
1572 auto &Regs = *VMap.getVRegs(U);
1574 Regs.push_back(Src);
1575 VMap.getOffsets(U)->push_back(0);
1584bool IRTranslator::translateBitCast(
const User &U,
1586 Type *SrcTy =
U.getOperand(0)->getType();
1587 Type *DstTy =
U.getType();
1594 return translateCast(TargetOpcode::G_CONSTANT_FOLD_BARRIER, U,
1596 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
1606 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
1608 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
1610 return translateCast(TargetOpcode::G_BITCAST, U, MIRBuilder);
1613bool IRTranslator::translateCast(
unsigned Opcode,
const User &U,
1615 if (!mayTranslateUserTypes(U))
1628bool IRTranslator::translateGetElementPtr(
const User &U,
1630 Value &Op0 = *
U.getOperand(0);
1634 Type *OffsetIRTy = DL->getIndexType(PtrIRTy);
1637 uint32_t PtrAddFlags = 0;
1643 auto PtrAddFlagsWithConst = [&](int64_t
Offset) {
1653 unsigned VectorWidth = 0;
1657 bool WantSplatVector =
false;
1661 WantSplatVector = VectorWidth > 1;
1665 return translateCopy(U, Op0, MIRBuilder);
1669 if (WantSplatVector && !PtrTy.
isVector()) {
1676 OffsetIRTy = DL->getIndexType(PtrIRTy);
1683 const Value *Idx = GTI.getOperand();
1684 if (StructType *StTy = GTI.getStructTypeOrNull()) {
1686 Offset += DL->getStructLayout(StTy)->getElementOffset(
Field);
1689 uint64_t ElementSize = GTI.getSequentialElementStride(*DL);
1694 if (std::optional<int64_t> Val = CI->getValue().trySExtValue()) {
1695 Offset += ElementSize * *Val;
1704 PtrAddFlagsWithConst(
Offset))
1709 Register IdxReg = getOrCreateVReg(*Idx);
1710 LLT IdxTy = MRI->getType(IdxReg);
1711 if (IdxTy != OffsetTy) {
1712 if (!IdxTy.
isVector() && WantSplatVector) {
1725 if (ElementSize != 1) {
1736 MIRBuilder.
buildMul(OffsetTy, IdxReg, ElementSizeMIB, ScaleFlags)
1739 GepOffsetReg = IdxReg;
1743 MIRBuilder.
buildPtrAdd(PtrTy, BaseReg, GepOffsetReg, PtrAddFlags)
1752 MIRBuilder.
buildPtrAdd(getOrCreateVReg(U), BaseReg, OffsetMIB.getReg(0),
1753 PtrAddFlagsWithConst(
Offset));
1757 MIRBuilder.
buildCopy(getOrCreateVReg(U), BaseReg);
1761bool IRTranslator::translateMemFunc(
const CallInst &CI,
1771 unsigned MinPtrSize = UINT_MAX;
1772 for (
auto AI = CI.
arg_begin(), AE = CI.
arg_end(); std::next(AI) != AE; ++AI) {
1773 Register SrcReg = getOrCreateVReg(**AI);
1774 LLT SrcTy = MRI->getType(SrcReg);
1776 MinPtrSize = std::min<unsigned>(SrcTy.
getSizeInBits(), MinPtrSize);
1784 if (MRI->getType(SizeOpReg) != SizeTy)
1796 ConstantInt *CopySize =
nullptr;
1799 DstAlign = MCI->getDestAlign().valueOrOne();
1800 SrcAlign = MCI->getSourceAlign().valueOrOne();
1803 DstAlign = MMI->getDestAlign().valueOrOne();
1804 SrcAlign = MMI->getSourceAlign().valueOrOne();
1808 DstAlign = MSI->getDestAlign().valueOrOne();
1811 if (Opcode != TargetOpcode::G_MEMCPY_INLINE &&
1812 Opcode != TargetOpcode::G_MEMSET_INLINE) {
1828 if (AA && CopySize &&
1829 AA->pointsToConstantMemory(MemoryLocation(
1839 ICall.addMemOperand(
1840 MF->getMachineMemOperand(MachinePointerInfo(CI.
getArgOperand(0)),
1841 StoreFlags, 1, DstAlign, AAInfo));
1842 if (Opcode != TargetOpcode::G_MEMSET &&
1843 Opcode != TargetOpcode::G_MEMSET_INLINE)
1844 ICall.addMemOperand(MF->getMachineMemOperand(
1845 MachinePointerInfo(SrcPtr), LoadFlags, 1, SrcAlign, AAInfo));
1850bool IRTranslator::translateTrap(
const CallInst &CI,
1853 StringRef TrapFuncName =
1854 CI.
getAttributes().getFnAttr(
"trap-func-name").getValueAsString();
1855 if (TrapFuncName.
empty()) {
1856 if (Opcode == TargetOpcode::G_UBSANTRAP) {
1865 CallLowering::CallLoweringInfo
Info;
1866 if (Opcode == TargetOpcode::G_UBSANTRAP)
1873 return CLI->lowerCall(MIRBuilder, Info);
1876bool IRTranslator::translateVectorInterleave2Intrinsic(
1879 "This function can only be called on the interleave2 intrinsic!");
1883 Register Res = getOrCreateVReg(CI);
1885 LLT OpTy = MRI->getType(Op0);
1892bool IRTranslator::translateVectorDeinterleave2Intrinsic(
1895 "This function can only be called on the deinterleave2 intrinsic!");
1902 LLT ResTy = MRI->getType(Res[0]);
1919void IRTranslator::getStackGuard(
Register DstReg,
1922 TLI->getSDagStackGuard(*MF->getFunction().getParent(), *Libcalls);
1925 Ctx.
diagnose(DiagnosticInfoGeneric(
"unable to lower stackguard"));
1930 const TargetRegisterInfo *
TRI = MF->getSubtarget().getRegisterInfo();
1931 MRI->setRegClass(DstReg,
TRI->getPointerRegClass());
1933 MIRBuilder.
buildInstr(TargetOpcode::LOAD_STACK_GUARD, {DstReg}, {});
1935 unsigned AddrSpace =
Global->getType()->getPointerAddressSpace();
1936 LLT PtrTy =
LLT::pointer(AddrSpace, DL->getPointerSizeInBits(AddrSpace));
1938 MachinePointerInfo MPInfo(
Global);
1941 MachineMemOperand *MemRef = MF->getMachineMemOperand(
1942 MPInfo, Flags, PtrTy, DL->getPointerABIAlignment(AddrSpace));
1943 MIB.setMemRefs({MemRef});
1946bool IRTranslator::translateOverflowIntrinsic(
const CallInst &CI,
unsigned Op,
1950 Op, {ResRegs[0], ResRegs[1]},
1956bool IRTranslator::translateFixedPointIntrinsic(
unsigned Op,
const CallInst &CI,
1958 Register Dst = getOrCreateVReg(CI);
1962 MIRBuilder.
buildInstr(
Op, {Dst}, { Src0, Src1, Scale });
1966unsigned IRTranslator::getSimpleIntrinsicOpcode(
Intrinsic::ID ID) {
1970 case Intrinsic::acos:
1971 return TargetOpcode::G_FACOS;
1972 case Intrinsic::asin:
1973 return TargetOpcode::G_FASIN;
1974 case Intrinsic::atan:
1975 return TargetOpcode::G_FATAN;
1976 case Intrinsic::atan2:
1977 return TargetOpcode::G_FATAN2;
1978 case Intrinsic::bswap:
1979 return TargetOpcode::G_BSWAP;
1980 case Intrinsic::bitreverse:
1981 return TargetOpcode::G_BITREVERSE;
1982 case Intrinsic::fshl:
1983 return TargetOpcode::G_FSHL;
1984 case Intrinsic::fshr:
1985 return TargetOpcode::G_FSHR;
1986 case Intrinsic::ceil:
1987 return TargetOpcode::G_FCEIL;
1988 case Intrinsic::cos:
1989 return TargetOpcode::G_FCOS;
1990 case Intrinsic::cosh:
1991 return TargetOpcode::G_FCOSH;
1992 case Intrinsic::ctpop:
1993 return TargetOpcode::G_CTPOP;
1994 case Intrinsic::exp:
1995 return TargetOpcode::G_FEXP;
1996 case Intrinsic::exp2:
1997 return TargetOpcode::G_FEXP2;
1998 case Intrinsic::exp10:
1999 return TargetOpcode::G_FEXP10;
2000 case Intrinsic::fabs:
2001 return TargetOpcode::G_FABS;
2002 case Intrinsic::copysign:
2003 return TargetOpcode::G_FCOPYSIGN;
2004 case Intrinsic::minnum:
2005 return TargetOpcode::G_FMINNUM;
2006 case Intrinsic::maxnum:
2007 return TargetOpcode::G_FMAXNUM;
2008 case Intrinsic::minimum:
2009 return TargetOpcode::G_FMINIMUM;
2010 case Intrinsic::maximum:
2011 return TargetOpcode::G_FMAXIMUM;
2012 case Intrinsic::minimumnum:
2013 return TargetOpcode::G_FMINIMUMNUM;
2014 case Intrinsic::maximumnum:
2015 return TargetOpcode::G_FMAXIMUMNUM;
2016 case Intrinsic::canonicalize:
2017 return TargetOpcode::G_FCANONICALIZE;
2018 case Intrinsic::floor:
2019 return TargetOpcode::G_FFLOOR;
2020 case Intrinsic::fma:
2021 return TargetOpcode::G_FMA;
2022 case Intrinsic::log:
2023 return TargetOpcode::G_FLOG;
2024 case Intrinsic::log2:
2025 return TargetOpcode::G_FLOG2;
2026 case Intrinsic::log10:
2027 return TargetOpcode::G_FLOG10;
2028 case Intrinsic::ldexp:
2029 return TargetOpcode::G_FLDEXP;
2030 case Intrinsic::nearbyint:
2031 return TargetOpcode::G_FNEARBYINT;
2032 case Intrinsic::pow:
2033 return TargetOpcode::G_FPOW;
2034 case Intrinsic::powi:
2035 return TargetOpcode::G_FPOWI;
2036 case Intrinsic::rint:
2037 return TargetOpcode::G_FRINT;
2038 case Intrinsic::round:
2039 return TargetOpcode::G_INTRINSIC_ROUND;
2040 case Intrinsic::roundeven:
2041 return TargetOpcode::G_INTRINSIC_ROUNDEVEN;
2042 case Intrinsic::sin:
2043 return TargetOpcode::G_FSIN;
2044 case Intrinsic::sinh:
2045 return TargetOpcode::G_FSINH;
2046 case Intrinsic::sqrt:
2047 return TargetOpcode::G_FSQRT;
2048 case Intrinsic::tan:
2049 return TargetOpcode::G_FTAN;
2050 case Intrinsic::tanh:
2051 return TargetOpcode::G_FTANH;
2052 case Intrinsic::trunc:
2053 return TargetOpcode::G_INTRINSIC_TRUNC;
2054 case Intrinsic::readcyclecounter:
2055 return TargetOpcode::G_READCYCLECOUNTER;
2056 case Intrinsic::readsteadycounter:
2057 return TargetOpcode::G_READSTEADYCOUNTER;
2058 case Intrinsic::ptrmask:
2059 return TargetOpcode::G_PTRMASK;
2060 case Intrinsic::lrint:
2061 return TargetOpcode::G_INTRINSIC_LRINT;
2062 case Intrinsic::llrint:
2063 return TargetOpcode::G_INTRINSIC_LLRINT;
2065 case Intrinsic::vector_reduce_fmin:
2066 return TargetOpcode::G_VECREDUCE_FMIN;
2067 case Intrinsic::vector_reduce_fmax:
2068 return TargetOpcode::G_VECREDUCE_FMAX;
2069 case Intrinsic::vector_reduce_fminimum:
2070 return TargetOpcode::G_VECREDUCE_FMINIMUM;
2071 case Intrinsic::vector_reduce_fmaximum:
2072 return TargetOpcode::G_VECREDUCE_FMAXIMUM;
2073 case Intrinsic::vector_reduce_add:
2074 return TargetOpcode::G_VECREDUCE_ADD;
2075 case Intrinsic::vector_reduce_mul:
2076 return TargetOpcode::G_VECREDUCE_MUL;
2077 case Intrinsic::vector_reduce_and:
2078 return TargetOpcode::G_VECREDUCE_AND;
2079 case Intrinsic::vector_reduce_or:
2080 return TargetOpcode::G_VECREDUCE_OR;
2081 case Intrinsic::vector_reduce_xor:
2082 return TargetOpcode::G_VECREDUCE_XOR;
2083 case Intrinsic::vector_reduce_smax:
2084 return TargetOpcode::G_VECREDUCE_SMAX;
2085 case Intrinsic::vector_reduce_smin:
2086 return TargetOpcode::G_VECREDUCE_SMIN;
2087 case Intrinsic::vector_reduce_umax:
2088 return TargetOpcode::G_VECREDUCE_UMAX;
2089 case Intrinsic::vector_reduce_umin:
2090 return TargetOpcode::G_VECREDUCE_UMIN;
2091 case Intrinsic::experimental_vector_compress:
2092 return TargetOpcode::G_VECTOR_COMPRESS;
2093 case Intrinsic::lround:
2094 return TargetOpcode::G_LROUND;
2095 case Intrinsic::llround:
2096 return TargetOpcode::G_LLROUND;
2097 case Intrinsic::get_fpenv:
2098 return TargetOpcode::G_GET_FPENV;
2099 case Intrinsic::get_fpmode:
2100 return TargetOpcode::G_GET_FPMODE;
2105bool IRTranslator::translateSimpleIntrinsic(
const CallInst &CI,
2109 unsigned Op = getSimpleIntrinsicOpcode(
ID);
2117 for (
const auto &Arg : CI.
args())
2120 MIRBuilder.
buildInstr(
Op, {getOrCreateVReg(CI)}, VRegs,
2128 case Intrinsic::experimental_constrained_fadd:
2129 return TargetOpcode::G_STRICT_FADD;
2130 case Intrinsic::experimental_constrained_fsub:
2131 return TargetOpcode::G_STRICT_FSUB;
2132 case Intrinsic::experimental_constrained_fmul:
2133 return TargetOpcode::G_STRICT_FMUL;
2134 case Intrinsic::experimental_constrained_fdiv:
2135 return TargetOpcode::G_STRICT_FDIV;
2136 case Intrinsic::experimental_constrained_frem:
2137 return TargetOpcode::G_STRICT_FREM;
2138 case Intrinsic::experimental_constrained_fma:
2139 return TargetOpcode::G_STRICT_FMA;
2140 case Intrinsic::experimental_constrained_sqrt:
2141 return TargetOpcode::G_STRICT_FSQRT;
2142 case Intrinsic::experimental_constrained_ldexp:
2143 return TargetOpcode::G_STRICT_FLDEXP;
2144 case Intrinsic::experimental_constrained_fcmp:
2145 return TargetOpcode::G_STRICT_FCMP;
2146 case Intrinsic::experimental_constrained_fcmps:
2147 return TargetOpcode::G_STRICT_FCMPS;
2153bool IRTranslator::translateConstrainedFPIntrinsic(
2165 if (Opcode == TargetOpcode::G_STRICT_FCMP ||
2166 Opcode == TargetOpcode::G_STRICT_FCMPS) {
2168 Register Operand0 = getOrCreateVReg(*FPCmp->getArgOperand(0));
2169 Register Operand1 = getOrCreateVReg(*FPCmp->getArgOperand(1));
2172 .addPredicate(FPCmp->getPredicate())
2186std::optional<MCRegister> IRTranslator::getArgPhysReg(
Argument &Arg) {
2187 auto VRegs = getOrCreateVRegs(Arg);
2188 if (VRegs.
size() != 1)
2189 return std::nullopt;
2192 auto *VRegDef = MF->getRegInfo().getVRegDef(VRegs[0]);
2193 if (!VRegDef || !VRegDef->isCopy())
2194 return std::nullopt;
2195 return VRegDef->getOperand(1).getReg().asMCReg();
2198bool IRTranslator::translateIfEntryValueArgument(
bool isDeclare,
Value *Val,
2210 std::optional<MCRegister> PhysReg = getArgPhysReg(*Arg);
2212 LLVM_DEBUG(
dbgs() <<
"Dropping dbg." << (isDeclare ?
"declare" :
"value")
2213 <<
": expression is entry_value but "
2214 <<
"couldn't find a physical register\n");
2222 MF->setVariableDbgInfo(Var, Expr, *PhysReg, DL);
2234 case Intrinsic::experimental_convergence_anchor:
2235 return TargetOpcode::CONVERGENCECTRL_ANCHOR;
2236 case Intrinsic::experimental_convergence_entry:
2237 return TargetOpcode::CONVERGENCECTRL_ENTRY;
2238 case Intrinsic::experimental_convergence_loop:
2239 return TargetOpcode::CONVERGENCECTRL_LOOP;
2243bool IRTranslator::translateConvergenceControlIntrinsic(
2246 Register OutputReg = getOrCreateConvergenceTokenVReg(CI);
2249 if (
ID == Intrinsic::experimental_convergence_loop) {
2251 assert(Bundle &&
"Expected a convergence control token.");
2253 getOrCreateConvergenceTokenVReg(*Bundle->Inputs[0].get());
2263 if (ORE->enabled()) {
2265 MemoryOpRemark
R(*ORE,
"gisel-irtranslator-memsize", *DL, *LibInfo);
2273 if (translateSimpleIntrinsic(CI,
ID, MIRBuilder))
2279 case Intrinsic::lifetime_start:
2280 case Intrinsic::lifetime_end: {
2283 MF->getFunction().hasOptNone())
2286 unsigned Op =
ID == Intrinsic::lifetime_start ? TargetOpcode::LIFETIME_START
2287 : TargetOpcode::LIFETIME_END;
2296 case Intrinsic::fake_use: {
2298 for (
const auto &Arg : CI.
args())
2300 MIRBuilder.
buildInstr(TargetOpcode::FAKE_USE, {}, VRegs);
2301 MF->setHasFakeUses(
true);
2304 case Intrinsic::dbg_declare: {
2311 case Intrinsic::dbg_label: {
2317 "Expected inlined-at fields to agree");
2322 case Intrinsic::vaend:
2326 case Intrinsic::vastart: {
2328 unsigned ListSize = TLI->getVaListSizeInBits(*DL) / 8;
2331 MIRBuilder.
buildInstr(TargetOpcode::G_VASTART, {}, {getOrCreateVReg(*Ptr)})
2332 .addMemOperand(MF->getMachineMemOperand(MachinePointerInfo(Ptr),
2334 ListSize, Alignment));
2337 case Intrinsic::dbg_assign:
2344 case Intrinsic::dbg_value: {
2351 case Intrinsic::uadd_with_overflow:
2352 return translateOverflowIntrinsic(CI, TargetOpcode::G_UADDO, MIRBuilder);
2353 case Intrinsic::sadd_with_overflow:
2354 return translateOverflowIntrinsic(CI, TargetOpcode::G_SADDO, MIRBuilder);
2355 case Intrinsic::usub_with_overflow:
2356 return translateOverflowIntrinsic(CI, TargetOpcode::G_USUBO, MIRBuilder);
2357 case Intrinsic::ssub_with_overflow:
2358 return translateOverflowIntrinsic(CI, TargetOpcode::G_SSUBO, MIRBuilder);
2359 case Intrinsic::umul_with_overflow:
2360 return translateOverflowIntrinsic(CI, TargetOpcode::G_UMULO, MIRBuilder);
2361 case Intrinsic::smul_with_overflow:
2362 return translateOverflowIntrinsic(CI, TargetOpcode::G_SMULO, MIRBuilder);
2363 case Intrinsic::uadd_sat:
2364 return translateBinaryOp(TargetOpcode::G_UADDSAT, CI, MIRBuilder);
2365 case Intrinsic::sadd_sat:
2366 return translateBinaryOp(TargetOpcode::G_SADDSAT, CI, MIRBuilder);
2367 case Intrinsic::usub_sat:
2368 return translateBinaryOp(TargetOpcode::G_USUBSAT, CI, MIRBuilder);
2369 case Intrinsic::ssub_sat:
2370 return translateBinaryOp(TargetOpcode::G_SSUBSAT, CI, MIRBuilder);
2371 case Intrinsic::ushl_sat:
2372 return translateBinaryOp(TargetOpcode::G_USHLSAT, CI, MIRBuilder);
2373 case Intrinsic::sshl_sat:
2374 return translateBinaryOp(TargetOpcode::G_SSHLSAT, CI, MIRBuilder);
2375 case Intrinsic::umin:
2376 return translateBinaryOp(TargetOpcode::G_UMIN, CI, MIRBuilder);
2377 case Intrinsic::umax:
2378 return translateBinaryOp(TargetOpcode::G_UMAX, CI, MIRBuilder);
2379 case Intrinsic::smin:
2380 return translateBinaryOp(TargetOpcode::G_SMIN, CI, MIRBuilder);
2381 case Intrinsic::smax:
2382 return translateBinaryOp(TargetOpcode::G_SMAX, CI, MIRBuilder);
2383 case Intrinsic::abs:
2385 return translateUnaryOp(TargetOpcode::G_ABS, CI, MIRBuilder);
2386 case Intrinsic::smul_fix:
2387 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIX, CI, MIRBuilder);
2388 case Intrinsic::umul_fix:
2389 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIX, CI, MIRBuilder);
2390 case Intrinsic::smul_fix_sat:
2391 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIXSAT, CI, MIRBuilder);
2392 case Intrinsic::umul_fix_sat:
2393 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIXSAT, CI, MIRBuilder);
2394 case Intrinsic::sdiv_fix:
2395 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIX, CI, MIRBuilder);
2396 case Intrinsic::udiv_fix:
2397 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIX, CI, MIRBuilder);
2398 case Intrinsic::sdiv_fix_sat:
2399 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIXSAT, CI, MIRBuilder);
2400 case Intrinsic::udiv_fix_sat:
2401 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIXSAT, CI, MIRBuilder);
2402 case Intrinsic::fmuladd: {
2403 const TargetMachine &TM = MF->getTarget();
2404 Register Dst = getOrCreateVReg(CI);
2409 TLI->isFMAFasterThanFMulAndFAdd(*MF,
2410 TLI->getValueType(*DL, CI.
getType()))) {
2413 MIRBuilder.
buildFMA(Dst, Op0, Op1, Op2,
2424 case Intrinsic::frexp: {
2431 case Intrinsic::modf: {
2433 MIRBuilder.
buildModf(VRegs[0], VRegs[1],
2438 case Intrinsic::sincos: {
2445 case Intrinsic::fptosi_sat:
2449 case Intrinsic::fptoui_sat:
2453 case Intrinsic::memcpy_inline:
2454 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY_INLINE);
2455 case Intrinsic::memcpy:
2456 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY);
2457 case Intrinsic::memmove:
2458 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMMOVE);
2459 case Intrinsic::memset:
2460 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET);
2461 case Intrinsic::memset_inline:
2462 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET_INLINE);
2463 case Intrinsic::eh_typeid_for: {
2466 unsigned TypeID = MF->getTypeIDFor(GV);
2470 case Intrinsic::objectsize:
2473 case Intrinsic::is_constant:
2476 case Intrinsic::stackguard:
2477 getStackGuard(getOrCreateVReg(CI), MIRBuilder);
2479 case Intrinsic::stackprotector: {
2482 if (TLI->useLoadStackGuardNode(*CI.
getModule())) {
2483 GuardVal = MRI->createGenericVirtualRegister(PtrTy);
2484 getStackGuard(GuardVal, MIRBuilder);
2489 int FI = getOrCreateFrameIndex(*Slot);
2490 MF->getFrameInfo().setStackProtectorIndex(FI);
2493 GuardVal, getOrCreateVReg(*Slot),
2500 case Intrinsic::stacksave: {
2501 MIRBuilder.
buildInstr(TargetOpcode::G_STACKSAVE, {getOrCreateVReg(CI)}, {});
2504 case Intrinsic::stackrestore: {
2505 MIRBuilder.
buildInstr(TargetOpcode::G_STACKRESTORE, {},
2509 case Intrinsic::cttz:
2510 case Intrinsic::ctlz: {
2512 bool isTrailing =
ID == Intrinsic::cttz;
2513 unsigned Opcode = isTrailing ? Cst->
isZero()
2514 ? TargetOpcode::G_CTTZ
2515 : TargetOpcode::G_CTTZ_ZERO_POISON
2516 : Cst->
isZero() ? TargetOpcode::G_CTLZ
2517 : TargetOpcode::G_CTLZ_ZERO_POISON;
2518 MIRBuilder.
buildInstr(Opcode, {getOrCreateVReg(CI)},
2522 case Intrinsic::invariant_start: {
2526 case Intrinsic::invariant_end:
2528 case Intrinsic::expect:
2529 case Intrinsic::expect_with_probability:
2530 case Intrinsic::annotation:
2531 case Intrinsic::ptr_annotation:
2532 case Intrinsic::launder_invariant_group:
2533 case Intrinsic::strip_invariant_group:
2534 case Intrinsic::threadlocal_address: {
2536 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
2540 case Intrinsic::assume:
2541 case Intrinsic::experimental_noalias_scope_decl:
2542 case Intrinsic::var_annotation:
2543 case Intrinsic::sideeffect:
2546 case Intrinsic::read_volatile_register:
2547 case Intrinsic::read_register: {
2550 .
buildInstr(TargetOpcode::G_READ_REGISTER, {getOrCreateVReg(CI)}, {})
2554 case Intrinsic::write_register: {
2556 MIRBuilder.
buildInstr(TargetOpcode::G_WRITE_REGISTER)
2561 case Intrinsic::localescape: {
2562 MachineBasicBlock &EntryMBB = MF->front();
2567 for (
unsigned Idx = 0,
E = CI.
arg_size(); Idx <
E; ++Idx) {
2574 MF->getContext().getOrCreateFrameAllocSymbol(EscapedName, Idx);
2587 case Intrinsic::vector_reduce_fadd:
2588 case Intrinsic::vector_reduce_fmul: {
2591 Register Dst = getOrCreateVReg(CI);
2597 Opc =
ID == Intrinsic::vector_reduce_fadd
2598 ? TargetOpcode::G_VECREDUCE_SEQ_FADD
2599 : TargetOpcode::G_VECREDUCE_SEQ_FMUL;
2600 if (!MRI->getType(VecSrc).isVector())
2601 Opc =
ID == Intrinsic::vector_reduce_fadd ? TargetOpcode::G_FADD
2602 : TargetOpcode::G_FMUL;
2610 if (
ID == Intrinsic::vector_reduce_fadd) {
2611 Opc = TargetOpcode::G_VECREDUCE_FADD;
2612 ScalarOpc = TargetOpcode::G_FADD;
2614 Opc = TargetOpcode::G_VECREDUCE_FMUL;
2615 ScalarOpc = TargetOpcode::G_FMUL;
2617 LLT DstTy = MRI->getType(Dst);
2620 MIRBuilder.
buildInstr(ScalarOpc, {Dst}, {ScalarSrc, Rdx},
2625 case Intrinsic::trap:
2626 return translateTrap(CI, MIRBuilder, TargetOpcode::G_TRAP);
2627 case Intrinsic::debugtrap:
2628 return translateTrap(CI, MIRBuilder, TargetOpcode::G_DEBUGTRAP);
2629 case Intrinsic::ubsantrap:
2630 return translateTrap(CI, MIRBuilder, TargetOpcode::G_UBSANTRAP);
2631 case Intrinsic::allow_runtime_check:
2632 case Intrinsic::allow_ubsan_check:
2633 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
2636 case Intrinsic::amdgcn_cs_chain:
2637 case Intrinsic::amdgcn_call_whole_wave:
2638 return translateCallBase(CI, MIRBuilder);
2639 case Intrinsic::fptrunc_round: {
2644 std::optional<RoundingMode> RoundMode =
2649 .
buildInstr(TargetOpcode::G_INTRINSIC_FPTRUNC_ROUND,
2650 {getOrCreateVReg(CI)},
2652 .addImm((
int)*RoundMode);
2656 case Intrinsic::is_fpclass: {
2661 .
buildInstr(TargetOpcode::G_IS_FPCLASS, {getOrCreateVReg(CI)},
2662 {getOrCreateVReg(*FpValue)})
2667 case Intrinsic::set_fpenv: {
2672 case Intrinsic::reset_fpenv:
2675 case Intrinsic::set_fpmode: {
2680 case Intrinsic::reset_fpmode:
2683 case Intrinsic::get_rounding:
2686 case Intrinsic::set_rounding:
2689 case Intrinsic::vscale: {
2693 case Intrinsic::scmp:
2694 MIRBuilder.
buildSCmp(getOrCreateVReg(CI),
2698 case Intrinsic::ucmp:
2699 MIRBuilder.
buildUCmp(getOrCreateVReg(CI),
2703 case Intrinsic::vector_extract:
2704 return translateExtractVector(CI, MIRBuilder);
2705 case Intrinsic::vector_insert:
2706 return translateInsertVector(CI, MIRBuilder);
2707 case Intrinsic::stepvector: {
2711 case Intrinsic::prefetch: {
2718 auto &MMO = *MF->getMachineMemOperand(MachinePointerInfo(Addr), Flags,
2721 MIRBuilder.
buildPrefetch(getOrCreateVReg(*Addr), RW, Locality, CacheType,
2727 case Intrinsic::vector_interleave2:
2728 case Intrinsic::vector_deinterleave2: {
2736 return translateVectorInterleave2Intrinsic(CI, MIRBuilder);
2738 return translateVectorDeinterleave2Intrinsic(CI, MIRBuilder);
2741#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
2742 case Intrinsic::INTRINSIC:
2743#include "llvm/IR/ConstrainedOps.def"
2746 case Intrinsic::experimental_convergence_anchor:
2747 case Intrinsic::experimental_convergence_entry:
2748 case Intrinsic::experimental_convergence_loop:
2749 return translateConvergenceControlIntrinsic(CI,
ID, MIRBuilder);
2750 case Intrinsic::reloc_none: {
2753 MIRBuilder.
buildInstr(TargetOpcode::RELOC_NONE)
2761bool IRTranslator::translateInlineAsm(
const CallBase &CB,
2763 if (!mayTranslateUserTypes(CB))
2766 const InlineAsmLowering *ALI = MF->getSubtarget().getInlineAsmLowering();
2770 dbgs() <<
"Inline asm lowering is not supported for this target yet\n");
2775 MIRBuilder, CB, [&](
const Value &Val) {
return getOrCreateVRegs(Val); });
2778bool IRTranslator::translateCallBase(
const CallBase &CB,
2785 for (
const auto &Arg : CB.
args()) {
2787 assert(SwiftInVReg == 0 &&
"Expected only one swift error argument");
2789 SwiftInVReg = MRI->createGenericVirtualRegister(Ty);
2790 MIRBuilder.
buildCopy(SwiftInVReg, SwiftError.getOrCreateVRegUseAt(
2791 &CB, &MIRBuilder.
getMBB(), Arg));
2794 SwiftError.getOrCreateVRegDefAt(&CB, &MIRBuilder.
getMBB(), Arg);
2797 Args.push_back(getOrCreateVRegs(*Arg));
2801 if (ORE->enabled()) {
2803 MemoryOpRemark
R(*ORE,
"gisel-irtranslator-memsize", *DL, *LibInfo);
2809 std::optional<CallLowering::PtrAuthInfo> PAI;
2814 const Value *
Key = Bundle->Inputs[0];
2821 if (!CalleeCPA || !
isa<Function>(CalleeCPA->getPointer()) ||
2822 !CalleeCPA->isKnownCompatibleWith(
Key, Discriminator, *DL)) {
2824 Register DiscReg = getOrCreateVReg(*Discriminator);
2832 const auto &Token = *Bundle->Inputs[0].get();
2833 ConvergenceCtrlToken = getOrCreateConvergenceTokenVReg(Token);
2839 bool Success = CLI->lowerCall(
2840 MIRBuilder, CB, Res, Args, SwiftErrorVReg, PAI, ConvergenceCtrlToken,
2845 assert(!HasTailCall &&
"Can't tail call return twice from block?");
2846 const TargetInstrInfo *
TII = MF->getSubtarget().getInstrInfo();
2854 if (!mayTranslateUserTypes(U))
2862 if (
F && (
F->hasDLLImportStorageClass() ||
2863 (MF->getTarget().getTargetTriple().isOSWindows() &&
2864 F->hasExternalWeakLinkage())))
2876 return translateInlineAsm(CI, MIRBuilder);
2880 if (translateCallBase(CI, MIRBuilder)) {
2889 if (!MF->getSubtarget().isIntrinsicSupported(
ID)) {
2890 const Function &Fn = MF->getFunction();
2892 DiagnosticInfoUnsupportedTargetIntrinsic(Fn,
ID, CI.
getDebugLoc()));
2895 if (translateKnownIntrinsic(CI,
ID, MIRBuilder))
2899 TLI->getTgtMemIntrinsic(Infos, CI, *MF,
ID);
2901 return translateIntrinsic(CI,
ID, MIRBuilder, Infos);
2905bool IRTranslator::translateIntrinsic(
2908 if (!MF->getSubtarget().isIntrinsicSupported(
ID)) {
2910 F.getContext().diagnose(
2911 DiagnosticInfoUnsupportedTargetIntrinsic(
F,
ID, CB.
getDebugLoc()));
2916 ResultRegs = getOrCreateVRegs(CB);
2931 assert(CI->getBitWidth() <= 64 &&
2932 "large intrinsic immediates not handled");
2933 MIB.
addImm(CI->getSExtValue());
2938 auto *MD = MDVal->getMetadata();
2942 MDN =
MDNode::get(MF->getFunction().getContext(), ConstMD);
2949 if (VRegs.
size() > 1)
2956 for (
const auto &Info : TgtMemIntrinsicInfos) {
2959 LLT MemTy =
Info.memVT.isSimple()
2961 : LLT::scalar(
Info.memVT.getStoreSizeInBits());
2965 MachinePointerInfo MPI;
2967 MPI = MachinePointerInfo(Info.ptrVal, Info.offset);
2968 }
else if (
Info.fallbackAddressSpace) {
2969 MPI = MachinePointerInfo(*Info.fallbackAddressSpace);
2978 auto *Token = Bundle->Inputs[0].get();
2979 Register TokenReg = getOrCreateVReg(*Token);
2990bool IRTranslator::findUnwindDestinations(
3012 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3018 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3019 UnwindDests.back().first->setIsEHScopeEntry();
3020 UnwindDests.back().first->setIsEHFuncletEntry();
3025 for (
const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
3026 UnwindDests.emplace_back(&getMBB(*CatchPadBB), Prob);
3028 if (IsMSVCCXX || IsCoreCLR)
3029 UnwindDests.back().first->setIsEHFuncletEntry();
3031 UnwindDests.back().first->setIsEHScopeEntry();
3033 NewEHPadBB = CatchSwitch->getUnwindDest();
3038 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3039 if (BPI && NewEHPadBB)
3041 EHPadBB = NewEHPadBB;
3046bool IRTranslator::translateInvoke(
const User &U,
3049 MCContext &
Context = MF->getContext();
3054 const Function *Fn =
I.getCalledFunction();
3061 if (
I.hasDeoptState())
3075 (MF->getTarget().getTargetTriple().isOSWindows() &&
3079 bool LowerInlineAsm =
I.isInlineAsm();
3080 bool NeedEHLabel =
true;
3086 MIRBuilder.
buildInstr(TargetOpcode::G_INVOKE_REGION_START);
3087 BeginSymbol =
Context.createTempSymbol();
3091 if (LowerInlineAsm) {
3092 if (!translateInlineAsm(
I, MIRBuilder))
3094 }
else if (!translateCallBase(
I, MIRBuilder))
3099 EndSymbol =
Context.createTempSymbol();
3104 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3105 MachineBasicBlock *InvokeMBB = &MIRBuilder.
getMBB();
3106 BranchProbability EHPadBBProb =
3110 if (!findUnwindDestinations(EHPadBB, EHPadBBProb, UnwindDests))
3113 MachineBasicBlock &EHPadMBB = getMBB(*EHPadBB),
3114 &ReturnMBB = getMBB(*ReturnBB);
3116 addSuccessorWithProb(InvokeMBB, &ReturnMBB);
3117 for (
auto &UnwindDest : UnwindDests) {
3118 UnwindDest.first->setIsEHPad();
3119 addSuccessorWithProb(InvokeMBB, UnwindDest.first, UnwindDest.second);
3124 assert(BeginSymbol &&
"Expected a begin symbol!");
3125 assert(EndSymbol &&
"Expected an end symbol!");
3126 MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol);
3129 MIRBuilder.
buildBr(ReturnMBB);
3135bool IRTranslator::translateCallBr(
const User &U,
3137 if (!mayTranslateUserTypes(U))
3141 MachineBasicBlock *CallBrMBB = &MIRBuilder.
getMBB();
3144 if (
I.isInlineAsm()) {
3150 if (!translateIntrinsic(
I, IID, MIRBuilder))
3154 SmallPtrSet<BasicBlock *, 8> Dests = {
I.getDefaultDest()};
3155 MachineBasicBlock *
Return = &getMBB(*
I.getDefaultDest());
3164 for (BasicBlock *Dest :
I.getIndirectDests()) {
3165 MachineBasicBlock &
Target = getMBB(*Dest);
3166 Target.setIsInlineAsmBrIndirectTarget();
3167 Target.setLabelMustBeEmitted();
3169 if (Dests.
insert(Dest).second)
3181bool IRTranslator::translateLandingPad(
const User &U,
3185 MachineBasicBlock &
MBB = MIRBuilder.
getMBB();
3191 const Constant *PersonalityFn = MF->getFunction().getPersonalityFn();
3192 if (TLI->getExceptionPointerRegister(PersonalityFn) == 0 &&
3193 TLI->getExceptionSelectorRegister(PersonalityFn) == 0)
3205 MIRBuilder.
buildInstr(TargetOpcode::EH_LABEL)
3210 const TargetRegisterInfo &
TRI = *MF->getSubtarget().getRegisterInfo();
3211 if (
auto *RegMask =
TRI.getCustomEHPadPreservedMask(*MF))
3212 MF->getRegInfo().addPhysRegsUsedFromRegMask(RegMask);
3221 assert(Tys.
size() == 2 &&
"Only two-valued landingpads are supported");
3224 Register ExceptionReg = TLI->getExceptionPointerRegister(PersonalityFn);
3230 MIRBuilder.
buildCopy(ResRegs[0], ExceptionReg);
3232 Register SelectorReg = TLI->getExceptionSelectorRegister(PersonalityFn);
3237 Register PtrVReg = MRI->createGenericVirtualRegister(Tys[0]);
3238 MIRBuilder.
buildCopy(PtrVReg, SelectorReg);
3239 MIRBuilder.
buildCast(ResRegs[1], PtrVReg);
3244bool IRTranslator::translateAlloca(
const User &U,
3252 Register Res = getOrCreateVReg(AI);
3253 int FI = getOrCreateFrameIndex(AI);
3259 if (MF->getTarget().getTargetTriple().isOSWindows())
3264 Type *IntPtrIRTy = DL->getIntPtrType(AI.
getType());
3266 if (MRI->getType(NumElts) !=
IntPtrTy) {
3273 TypeSize TySize = DL->getTypeAllocSize(Ty);
3279 TySizeReg = MRI->createGenericVirtualRegister(
IntPtrTy);
3284 getOrCreateVReg(*ConstantInt::get(IntPtrIRTy, TySize.
getFixedValue()));
3286 MIRBuilder.
buildMul(AllocSize, NumElts, TySizeReg);
3291 Align StackAlign = MF->getSubtarget().getFrameLowering()->getStackAlign();
3300 if (Alignment <= StackAlign)
3301 Alignment =
Align(1);
3304 MF->getFrameInfo().CreateVariableSizedObject(Alignment, &AI);
3305 assert(MF->getFrameInfo().hasVarSizedObjects());
3314 MIRBuilder.
buildInstr(TargetOpcode::G_VAARG, {getOrCreateVReg(U)},
3315 {getOrCreateVReg(*
U.getOperand(0)),
3316 DL->getABITypeAlign(
U.getType()).value()});
3320bool IRTranslator::translateUnreachable(
const User &U,
3323 if (!UI.shouldLowerToTrap(MF->getTarget().Options.TrapUnreachable,
3324 MF->getTarget().Options.NoTrapAfterNoreturn))
3331bool IRTranslator::translateInsertElement(
const User &U,
3336 FVT && FVT->getNumElements() == 1)
3337 return translateCopy(U, *
U.getOperand(1), MIRBuilder);
3340 Register Val = getOrCreateVReg(*
U.getOperand(0));
3341 Register Elt = getOrCreateVReg(*
U.getOperand(1));
3342 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
3345 if (CI->getBitWidth() != PreferredVecIdxWidth) {
3346 APInt NewIdx = CI->getValue().zextOrTrunc(PreferredVecIdxWidth);
3347 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
3348 Idx = getOrCreateVReg(*NewIdxCI);
3352 Idx = getOrCreateVReg(*
U.getOperand(2));
3353 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
3354 const LLT VecIdxTy =
3355 MRI->getType(Idx).changeElementSize(PreferredVecIdxWidth);
3362bool IRTranslator::translateInsertVector(
const User &U,
3365 Register Vec = getOrCreateVReg(*
U.getOperand(0));
3366 Register Elt = getOrCreateVReg(*
U.getOperand(1));
3369 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
3374 CI = ConstantInt::get(CI->
getContext(), NewIdx);
3379 ResultType && ResultType->getNumElements() == 1) {
3381 InputType && InputType->getNumElements() == 1) {
3385 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
3391 Register Idx = getOrCreateVReg(*CI);
3399 Register Idx = getOrCreateVReg(*CI);
3400 auto ScaledIndex = MIRBuilder.
buildMul(
3401 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
3408 getOrCreateVReg(U), getOrCreateVReg(*
U.getOperand(0)),
3413bool IRTranslator::translateExtractElement(
const User &U,
3417 if (
const FixedVectorType *FVT =
3419 if (FVT->getNumElements() == 1)
3420 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
3423 Register Val = getOrCreateVReg(*
U.getOperand(0));
3424 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
3429 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
3430 Idx = getOrCreateVReg(*NewIdxCI);
3434 Idx = getOrCreateVReg(*
U.getOperand(1));
3435 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
3436 const LLT VecIdxTy =
3444bool IRTranslator::translateExtractVector(
const User &U,
3447 Register Vec = getOrCreateVReg(*
U.getOperand(0));
3449 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
3454 CI = ConstantInt::get(CI->
getContext(), NewIdx);
3459 ResultType && ResultType->getNumElements() == 1) {
3461 InputType && InputType->getNumElements() == 1) {
3464 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
3470 Register Idx = getOrCreateVReg(*CI);
3478 Register Idx = getOrCreateVReg(*CI);
3479 auto ScaledIndex = MIRBuilder.
buildMul(
3480 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
3487 getOrCreateVReg(*
U.getOperand(0)),
3492bool IRTranslator::translateShuffleVector(
const User &U,
3498 if (
U.getOperand(0)->getType()->isScalableTy()) {
3499 Register Val = getOrCreateVReg(*
U.getOperand(0));
3501 MRI->getType(Val).getElementType(), Val, 0);
3508 Mask = SVI->getShuffleMask();
3519 unsigned M =
Mask[0];
3521 if (M == 0 || M == 1)
3522 return translateCopy(U, *
U.getOperand(M), MIRBuilder);
3528 Dst, getOrCreateVReg(*
U.getOperand(0)), M);
3529 }
else if (M < SrcElts * 2) {
3531 Dst, getOrCreateVReg(*
U.getOperand(1)), M - SrcElts);
3543 for (
int M : Mask) {
3545 if (M == 0 || M == 1) {
3546 Ops.push_back(getOrCreateVReg(*
U.getOperand(M)));
3548 if (!
Undef.isValid()) {
3549 Undef = MRI->createGenericVirtualRegister(SrcTy);
3559 ArrayRef<int> MaskAlloc = MF->allocateShuffleMask(Mask);
3561 .
buildInstr(TargetOpcode::G_SHUFFLE_VECTOR, {getOrCreateVReg(U)},
3562 {getOrCreateVReg(*
U.getOperand(0)),
3563 getOrCreateVReg(*
U.getOperand(1))})
3564 .addShuffleMask(MaskAlloc);
3571 SmallVector<MachineInstr *, 4> Insts;
3572 for (
auto Reg : getOrCreateVRegs(PI)) {
3573 auto MIB = MIRBuilder.
buildInstr(TargetOpcode::G_PHI, {
Reg}, {});
3577 PendingPHIs.emplace_back(&PI, std::move(Insts));
3581bool IRTranslator::translateAtomicCmpXchg(
const User &U,
3585 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
3587 auto Res = getOrCreateVRegs(
I);
3590 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
3591 Register Cmp = getOrCreateVReg(*
I.getCompareOperand());
3592 Register NewVal = getOrCreateVReg(*
I.getNewValOperand());
3595 OldValRes, SuccessRes, Addr, Cmp, NewVal,
3596 *MF->getMachineMemOperand(
3597 MachinePointerInfo(
I.getPointerOperand()), Flags, MRI->getType(Cmp),
3598 getMemOpAlign(
I),
I.getAAMetadata(),
I.getSyncScopeID(),
3599 I.getSuccessOrdering(),
I.getFailureOrdering()));
3603bool IRTranslator::translateAtomicRMW(
const User &U,
3605 if (!mayTranslateUserTypes(U))
3609 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
3612 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
3613 Register Val = getOrCreateVReg(*
I.getValOperand());
3615 unsigned Opcode = 0;
3616 switch (
I.getOperation()) {
3620 Opcode = TargetOpcode::G_ATOMICRMW_XCHG;
3623 Opcode = TargetOpcode::G_ATOMICRMW_ADD;
3626 Opcode = TargetOpcode::G_ATOMICRMW_SUB;
3629 Opcode = TargetOpcode::G_ATOMICRMW_AND;
3632 Opcode = TargetOpcode::G_ATOMICRMW_NAND;
3635 Opcode = TargetOpcode::G_ATOMICRMW_OR;
3638 Opcode = TargetOpcode::G_ATOMICRMW_XOR;
3641 Opcode = TargetOpcode::G_ATOMICRMW_MAX;
3644 Opcode = TargetOpcode::G_ATOMICRMW_MIN;
3647 Opcode = TargetOpcode::G_ATOMICRMW_UMAX;
3650 Opcode = TargetOpcode::G_ATOMICRMW_UMIN;
3653 Opcode = TargetOpcode::G_ATOMICRMW_FADD;
3656 Opcode = TargetOpcode::G_ATOMICRMW_FSUB;
3659 Opcode = TargetOpcode::G_ATOMICRMW_FMAX;
3662 Opcode = TargetOpcode::G_ATOMICRMW_FMIN;
3665 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUM;
3668 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUM;
3671 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUMNUM;
3674 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUMNUM;
3677 Opcode = TargetOpcode::G_ATOMICRMW_UINC_WRAP;
3680 Opcode = TargetOpcode::G_ATOMICRMW_UDEC_WRAP;
3683 Opcode = TargetOpcode::G_ATOMICRMW_USUB_COND;
3686 Opcode = TargetOpcode::G_ATOMICRMW_USUB_SAT;
3691 Opcode, Res, Addr, Val,
3692 *MF->getMachineMemOperand(MachinePointerInfo(
I.getPointerOperand()),
3693 Flags, MRI->getType(Val), getMemOpAlign(
I),
3694 I.getAAMetadata(),
I.getSyncScopeID(),
3699bool IRTranslator::translateFence(
const User &U,
3703 Fence.getSyncScopeID());
3707bool IRTranslator::translateFreeze(
const User &U,
3713 "Freeze with different source and destination type?");
3715 for (
unsigned I = 0;
I < DstRegs.
size(); ++
I) {
3722void IRTranslator::finishPendingPhis() {
3725 GISelObserverWrapper WrapperObserver(&
Verifier);
3726 RAIIMFObsDelInstaller ObsInstall(*MF, WrapperObserver);
3728 for (
auto &Phi : PendingPHIs) {
3729 const PHINode *PI =
Phi.first;
3733 MachineBasicBlock *PhiMBB = ComponentPHIs[0]->getParent();
3739 SmallPtrSet<const MachineBasicBlock *, 16> SeenPreds;
3743 for (
auto *Pred : getMachinePredBBs({IRPred, PI->
getParent()})) {
3747 for (
unsigned j = 0;
j < ValRegs.
size(); ++
j) {
3748 MachineInstrBuilder MIB(*MF, ComponentPHIs[j]);
3757void IRTranslator::translateDbgValueRecord(
Value *V,
bool HasArgList,
3763 "Expected inlined-at fields to agree");
3767 if (!V || HasArgList) {
3785 auto *ExprDerefRemoved =
3791 if (translateIfEntryValueArgument(
false, V, Variable, Expression, DL,
3803void IRTranslator::translateDbgDeclareRecord(
Value *
Address,
bool HasArgList,
3809 LLVM_DEBUG(
dbgs() <<
"Dropping debug info for " << *Variable <<
"\n");
3814 "Expected inlined-at fields to agree");
3819 MF->setVariableDbgInfo(Variable, Expression,
3820 getOrCreateFrameIndex(*AI), DL);
3824 if (translateIfEntryValueArgument(
true,
Address, Variable,
3836void IRTranslator::translateDbgInfo(
const Instruction &Inst,
3841 assert(DLR->getLabel() &&
"Missing label");
3842 assert(DLR->getLabel()->isValidLocationForIntrinsic(
3844 "Expected inlined-at fields to agree");
3853 translateDbgDeclareRecord(V, DVR.
hasArgList(), Variable, Expression,
3856 translateDbgValueRecord(V, DVR.
hasArgList(), Variable, Expression,
3861bool IRTranslator::translate(
const Instruction &Inst) {
3863 CurBuilder->setPCSections(Inst.
getMetadata(LLVMContext::MD_pcsections));
3864 CurBuilder->setMMRAMetadata(Inst.
getMetadata(LLVMContext::MD_mmra));
3866 if (TLI->fallBackToDAGISel(Inst))
3870#define HANDLE_INST(NUM, OPCODE, CLASS) \
3871 case Instruction::OPCODE: \
3872 return translate##OPCODE(Inst, *CurBuilder.get());
3873#include "llvm/IR/Instruction.def"
3882 if (
auto CurrInstDL = CurBuilder->getDL())
3883 EntryBuilder->setDebugLoc(
DebugLoc());
3889 EntryBuilder->buildConstant(
Reg, *CI);
3893 EntryBuilder->buildConstant(
Reg, CB->getValue());
3897 CF = ConstantFP::get(CF->getContext(), CF->getValue());
3898 EntryBuilder->buildFConstant(
Reg, *CF);
3900 EntryBuilder->buildUndef(
Reg);
3902 EntryBuilder->buildConstant(
Reg, 0);
3904 EntryBuilder->buildGlobalValue(
Reg, GV);
3906 Register Addr = getOrCreateVReg(*CPA->getPointer());
3907 Register AddrDisc = getOrCreateVReg(*CPA->getAddrDiscriminator());
3908 EntryBuilder->buildConstantPtrAuth(
Reg, CPA, Addr, AddrDisc);
3910 Constant &Elt = *CAZ->getElementValue(0u);
3912 EntryBuilder->buildSplatVector(
Reg, getOrCreateVReg(Elt));
3916 unsigned NumElts = CAZ->getElementCount().getFixedValue();
3918 return translateCopy(
C, Elt, *EntryBuilder);
3920 EntryBuilder->buildSplatBuildVector(
Reg, getOrCreateVReg(Elt));
3923 if (CV->getNumElements() == 1)
3924 return translateCopy(
C, *CV->getElementAsConstant(0), *EntryBuilder);
3926 for (
unsigned i = 0; i < CV->getNumElements(); ++i) {
3927 Constant &Elt = *CV->getElementAsConstant(i);
3928 Ops.push_back(getOrCreateVReg(Elt));
3930 EntryBuilder->buildBuildVector(
Reg,
Ops);
3932 switch(
CE->getOpcode()) {
3933#define HANDLE_INST(NUM, OPCODE, CLASS) \
3934 case Instruction::OPCODE: \
3935 return translate##OPCODE(*CE, *EntryBuilder.get());
3936#include "llvm/IR/Instruction.def"
3941 if (CV->getNumOperands() == 1)
3942 return translateCopy(
C, *CV->getOperand(0), *EntryBuilder);
3944 for (
unsigned i = 0; i < CV->getNumOperands(); ++i) {
3945 Ops.push_back(getOrCreateVReg(*CV->getOperand(i)));
3947 EntryBuilder->buildBuildVector(
Reg,
Ops);
3949 EntryBuilder->buildBlockAddress(
Reg, BA);
3956bool IRTranslator::mayTranslateUserTypes(
const User &U)
const {
3957 const TargetMachine &TM = TLI->getTargetMachine();
3966 (!
U.getType()->getScalarType()->isBFloatTy() &&
3968 return V->getType()->getScalarType()->isBFloatTy();
3972bool IRTranslator::finalizeBasicBlock(
const BasicBlock &BB,
3974 for (
auto &BTB : SL->BitTestCases) {
3977 emitBitTestHeader(BTB, BTB.Parent);
3979 BranchProbability UnhandledProb = BTB.Prob;
3980 for (
unsigned j = 0, ej = BTB.Cases.size(); j != ej; ++j) {
3981 UnhandledProb -= BTB.Cases[
j].ExtraProb;
3983 MachineBasicBlock *
MBB = BTB.Cases[
j].ThisBB;
3992 MachineBasicBlock *NextMBB;
3993 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
3996 NextMBB = BTB.Cases[
j + 1].TargetBB;
3997 }
else if (j + 1 == ej) {
3999 NextMBB = BTB.Default;
4002 NextMBB = BTB.Cases[
j + 1].ThisBB;
4005 emitBitTestCase(BTB, NextMBB, UnhandledProb, BTB.Reg, BTB.Cases[j],
MBB);
4007 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
4011 addMachineCFGPred({BTB.Parent->getBasicBlock(),
4012 BTB.Cases[ej - 1].TargetBB->getBasicBlock()},
4015 BTB.Cases.pop_back();
4021 CFGEdge HeaderToDefaultEdge = {BTB.Parent->getBasicBlock(),
4022 BTB.Default->getBasicBlock()};
4023 addMachineCFGPred(HeaderToDefaultEdge, BTB.Parent);
4024 if (!BTB.ContiguousRange) {
4025 addMachineCFGPred(HeaderToDefaultEdge, BTB.Cases.back().ThisBB);
4028 SL->BitTestCases.clear();
4030 for (
auto &JTCase : SL->JTCases) {
4032 if (!JTCase.first.Emitted)
4033 emitJumpTableHeader(JTCase.second, JTCase.first, JTCase.first.HeaderBB);
4035 emitJumpTable(JTCase.second, JTCase.second.MBB);
4037 SL->JTCases.clear();
4039 for (
auto &SwCase : SL->SwitchCases)
4040 emitSwitchCase(SwCase, &CurBuilder->getMBB(), *CurBuilder);
4041 SL->SwitchCases.clear();
4045 if (
SP.shouldEmitSDCheck(BB)) {
4046 bool FunctionBasedInstrumentation =
4047 TLI->getSSPStackGuardCheck(*MF->getFunction().getParent(), *Libcalls);
4048 SPDescriptor.initialize(&BB, &
MBB, FunctionBasedInstrumentation);
4051 if (SPDescriptor.shouldEmitFunctionBasedCheckStackProtector()) {
4054 }
else if (SPDescriptor.shouldEmitStackProtector()) {
4055 MachineBasicBlock *ParentMBB = SPDescriptor.getParentMBB();
4056 MachineBasicBlock *SuccessMBB = SPDescriptor.getSuccessMBB();
4065 ParentMBB, *MF->getSubtarget().getInstrInfo());
4068 SuccessMBB->
splice(SuccessMBB->
end(), ParentMBB, SplitPoint,
4072 if (!emitSPDescriptorParent(SPDescriptor, ParentMBB))
4076 MachineBasicBlock *FailureMBB = SPDescriptor.getFailureMBB();
4077 if (FailureMBB->
empty()) {
4078 if (!emitSPDescriptorFailure(SPDescriptor, FailureMBB))
4083 SPDescriptor.resetPerBBState();
4090 CurBuilder->setInsertPt(*ParentBB, ParentBB->
end());
4094 LLT PtrMemTy =
getLLTForMVT(TLI->getPointerMemTy(*DL));
4100 Register StackSlotPtr = CurBuilder->buildFrameIndex(PtrTy, FI).getReg(0);
4107 ->buildLoad(PtrMemTy, StackSlotPtr,
4113 if (
const Function *GuardCheckFn = TLI->getSSPStackGuardCheck(M, *Libcalls)) {
4125 FunctionType *FnTy = GuardCheckFn->getFunctionType();
4126 assert(FnTy->getNumParams() == 1 &&
"Invalid function signature");
4127 ISD::ArgFlagsTy
Flags;
4128 if (GuardCheckFn->hasAttribute(1, Attribute::AttrKind::InReg))
4130 CallLowering::ArgInfo GuardArgInfo(
4131 {GuardVal, FnTy->getParamType(0), {
Flags}});
4133 CallLowering::CallLoweringInfo
Info;
4134 Info.OrigArgs.push_back(GuardArgInfo);
4135 Info.CallConv = GuardCheckFn->getCallingConv();
4138 if (!CLI->lowerCall(MIRBuilder, Info)) {
4139 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector check\n");
4149 Guard = MRI->createGenericVirtualRegister(PtrMemTy);
4150 getStackGuard(Guard, *CurBuilder);
4153 const Value *IRGuard = TLI->getSDagStackGuard(M, *Libcalls);
4154 Register GuardPtr = getOrCreateVReg(*IRGuard);
4157 ->buildLoad(PtrMemTy, GuardPtr,
4176 const RTLIB::LibcallImpl LibcallImpl =
4177 Libcalls->getLibcallImpl(RTLIB::STACKPROTECTOR_CHECK_FAIL);
4178 if (LibcallImpl == RTLIB::Unsupported)
4181 CurBuilder->setInsertPt(*FailureBB, FailureBB->
end());
4183 CallLowering::CallLoweringInfo
Info;
4184 Info.CallConv = Libcalls->getLibcallImplCallingConv(LibcallImpl);
4186 StringRef LibcallName =
4191 if (!CLI->lowerCall(*CurBuilder, Info)) {
4192 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector fail\n");
4197 const TargetOptions &TargetOpts = TLI->getTargetMachine().Options;
4199 CurBuilder->buildInstr(TargetOpcode::G_TRAP);
4204void IRTranslator::finalizeFunction() {
4207 PendingPHIs.clear();
4209 FrameIndices.clear();
4210 MachinePreds.clear();
4214 EntryBuilder.reset();
4217 SPDescriptor.resetPerFunctionState();
4230 return CI && CI->isMustTailCall();
4237 ORE = std::make_unique<OptimizationRemarkEmitter>(&
F);
4238 CLI = MF->getSubtarget().getCallLowering();
4240 if (CLI->fallBackToDAGISel(*MF)) {
4242 F.getSubprogram(), &
F.getEntryBlock());
4243 R <<
"unable to lower function: "
4244 <<
ore::NV(
"Prototype",
F.getFunctionType());
4258 : TPC->isGISelCSEEnabled();
4264 EntryBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
4265 CSEInfo = &
Wrapper.get(TPC->getCSEConfig());
4266 EntryBuilder->setCSEInfo(CSEInfo);
4267 CurBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
4268 CurBuilder->setCSEInfo(CSEInfo);
4270 EntryBuilder = std::make_unique<MachineIRBuilder>();
4271 CurBuilder = std::make_unique<MachineIRBuilder>();
4274 CurBuilder->setMF(*MF);
4275 EntryBuilder->setMF(*MF);
4276 MRI = &MF->getRegInfo();
4277 DL = &
F.getDataLayout();
4288 FuncInfo.BPI =
nullptr;
4293 *
F.getParent(), Subtarget);
4295 FuncInfo.CanLowerReturn = CLI->checkReturnTypeForCallConv(*MF);
4297 SL = std::make_unique<GISelSwitchLowering>(
this, FuncInfo);
4298 SL->init(*TLI, TM, *DL);
4300 assert(PendingPHIs.empty() &&
"stale PHIs");
4304 if (!DL->isLittleEndian() && !CLI->enableBigEndian()) {
4307 F.getSubprogram(), &
F.getEntryBlock());
4308 R <<
"unable to translate in big endian mode";
4319 EntryBuilder->setMBB(*EntryBB);
4321 DebugLoc DbgLoc =
F.getEntryBlock().getFirstNonPHIIt()->getDebugLoc();
4322 SwiftError.setFunction(CurMF);
4323 SwiftError.createEntriesInEntryBlock(DbgLoc);
4325 bool IsVarArg =
F.isVarArg();
4326 bool HasMustTailInVarArgFn =
false;
4329 FuncInfo.MBBMap.resize(
F.getMaxBlockNumber());
4333 MBB = MF->CreateMachineBasicBlock(&BB);
4341 if (!BA->hasZeroLiveUses())
4345 if (!HasMustTailInVarArgFn)
4349 MF->getFrameInfo().setHasMustTailInVarArgFunc(HasMustTailInVarArgFn);
4352 EntryBB->addSuccessor(&getMBB(
F.front()));
4357 if (DL->getTypeStoreSize(Arg.
getType()).isZero())
4362 if (CLI->supportSwiftError() && Arg.hasSwiftErrorAttr()) {
4363 assert(VRegs.
size() == 1 &&
"Too many vregs for Swift error");
4364 SwiftError.setCurrentVReg(EntryBB, SwiftError.getFunctionArg(), VRegs[0]);
4368 if (!CLI->lowerFormalArguments(*EntryBuilder,
F, VRegArgs, FuncInfo)) {
4370 F.getSubprogram(), &
F.getEntryBlock());
4371 R <<
"unable to lower arguments: "
4372 <<
ore::NV(
"Prototype",
F.getFunctionType());
4379 if (EnableCSE && CSEInfo)
4384 DILocationVerifier Verifier;
4392 CurBuilder->setMBB(
MBB);
4393 HasTailCall =
false;
4403 Verifier.setCurrentInst(&Inst);
4407 translateDbgInfo(Inst, *CurBuilder);
4409 if (translate(Inst))
4414 R <<
"unable to translate instruction: " <<
ore::NV(
"Opcode", &Inst);
4416 if (ORE->allowExtraAnalysis(
"gisel-irtranslator")) {
4417 std::string InstStrStorage;
4421 R <<
": '" << InstStrStorage <<
"'";
4428 if (!finalizeBasicBlock(*BB,
MBB)) {
4430 BB->getTerminator()->getDebugLoc(), BB);
4431 R <<
"unable to translate basic block";
4441 finishPendingPhis();
4443 SwiftError.propagateVRegs();
4448 assert(EntryBB->succ_size() == 1 &&
4449 "Custom BB used for lowering should have only one successor");
4453 "LLVM-IR entry block has a predecessor!?");
4456 NewEntryBB.
splice(NewEntryBB.
begin(), EntryBB, EntryBB->begin(),
4465 EntryBB->removeSuccessor(&NewEntryBB);
4466 MF->remove(EntryBB);
4467 MF->deleteMachineBasicBlock(EntryBB);
4469 assert(&MF->front() == &NewEntryBB &&
4470 "New entry wasn't next in the list of basic block!");
4474 SP.copyToMachineFrameInfo(MF->getFrameInfo());
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.
Machine Check Debug Module
This file declares the MachineIRBuilder class.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
OptimizedStructLayoutField Field
#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
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 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.
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.
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.
An immutable pass that tracks lazily created AssumptionCache objects.
@ 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.
Legacy analysis pass which computes BranchProbabilityInfo.
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 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
Class representing an expression and its matching format.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
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.".
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
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
IRTranslator(CodeGenOptLevel OptLevel=CodeGenOptLevel::None)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
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.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
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 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.
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.
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.
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)
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
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).
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.
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).
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.
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
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.
#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.
@ 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.
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.
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)
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.
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.