79#include "llvm/IR/IntrinsicsAArch64.h"
80#include "llvm/IR/IntrinsicsAMDGPU.h"
81#include "llvm/IR/IntrinsicsWebAssembly.h"
116#define DEBUG_TYPE "isel"
124 cl::desc(
"Insert the experimental `assertalign` node."),
129 cl::desc(
"Generate low-precision inline sequences "
130 "for some float libcalls"),
136 cl::desc(
"Set the case probability threshold for peeling the case from a "
137 "switch statement. A value greater than 100 will void this "
157 const SDValue *Parts,
unsigned NumParts,
160 std::optional<CallingConv::ID>
CC);
169 unsigned NumParts,
MVT PartVT,
EVT ValueVT,
const Value *V,
171 std::optional<CallingConv::ID>
CC = std::nullopt,
172 std::optional<ISD::NodeType> AssertOp = std::nullopt) {
176 PartVT, ValueVT,
CC))
183 assert(NumParts > 0 &&
"No parts to assemble!");
194 unsigned RoundBits = PartBits * RoundParts;
195 EVT RoundVT = RoundBits == ValueBits ?
201 if (RoundParts > 2) {
205 PartVT, HalfVT, V, InChain);
216 if (RoundParts < NumParts) {
218 unsigned OddParts = NumParts - RoundParts;
221 OddVT, V, InChain,
CC);
237 assert(ValueVT ==
EVT(MVT::ppcf128) && PartVT == MVT::f64 &&
248 !PartVT.
isVector() &&
"Unexpected split");
260 if (PartEVT == ValueVT)
264 ValueVT.
bitsLT(PartEVT)) {
277 if (ValueVT.
bitsLT(PartEVT)) {
282 Val = DAG.
getNode(*AssertOp,
DL, PartEVT, Val,
297 llvm::Attribute::StrictFP)) {
299 DAG.
getVTList(ValueVT, MVT::Other), InChain, Val,
311 if (PartEVT == MVT::x86mmx && ValueVT.
isInteger() &&
312 ValueVT.
bitsLT(PartEVT)) {
321 const Twine &ErrMsg) {
324 return Ctx.emitError(ErrMsg);
327 if (CI->isInlineAsm()) {
329 *CI, ErrMsg +
", possible invalid constraint for vector type"));
332 return Ctx.emitError(
I, ErrMsg);
338 MVT RegisterVT,
MVT PartVT) {
339 if (NumRegs == NumParts && RegisterVT == PartVT)
343 Twine(
"Part count doesn't match vector breakdown! ") +
Twine(NumRegs) +
344 " registers, " +
Twine(NumParts) +
" parts, " + RegisterVT.
getString() +
345 " RegisterVT, " + PartVT.
getString() +
" PartVT");
354 const SDValue *Parts,
unsigned NumParts,
357 std::optional<CallingConv::ID> CallConv) {
359 assert(NumParts > 0 &&
"No parts to assemble!");
360 const bool IsABIRegCopy = CallConv.has_value();
369 unsigned NumIntermediates;
374 *DAG.
getContext(), *CallConv, ValueVT, IntermediateVT,
375 NumIntermediates, RegisterVT);
379 NumIntermediates, RegisterVT);
385 "Part type sizes don't match!");
389 if (NumIntermediates == NumParts) {
392 for (
unsigned i = 0; i != NumParts; ++i)
394 V, InChain, CallConv);
395 }
else if (NumParts > 0) {
398 assert(NumParts % NumIntermediates == 0 &&
399 "Must expand into a divisible number of parts!");
400 unsigned Factor = NumParts / NumIntermediates;
401 for (
unsigned i = 0; i != NumIntermediates; ++i)
403 IntermediateVT, V, InChain, CallConv);
418 DL, BuiltVectorTy,
Ops);
424 if (PartEVT == ValueVT)
440 "Cannot narrow, it would be a lossy transformation");
446 if (PartEVT == ValueVT)
471 }
else if (ValueVT.
bitsLT(PartEVT)) {
480 *DAG.
getContext(), V,
"non-trivial scalar-to-vector conversion");
511 std::optional<CallingConv::ID> CallConv);
518 unsigned NumParts,
MVT PartVT,
const Value *V,
519 std::optional<CallingConv::ID> CallConv = std::nullopt,
533 unsigned OrigNumParts = NumParts;
535 "Copying to an illegal type!");
541 EVT PartEVT = PartVT;
542 if (PartEVT == ValueVT) {
543 assert(NumParts == 1 &&
"No-op copy with multiple parts!");
552 assert(NumParts == 1 &&
"Do not know what to promote to!");
563 "Unknown mismatch!");
566 if (PartVT == MVT::x86mmx)
571 assert(NumParts == 1 && PartEVT != ValueVT);
577 "Unknown mismatch!");
580 if (PartVT == MVT::x86mmx)
587 "Failed to tile the value with PartVT!");
590 if (PartEVT != ValueVT) {
592 "scalar-to-vector conversion failed");
601 if (NumParts & (NumParts - 1)) {
604 "Do not know what to expand to!");
606 unsigned RoundBits = RoundParts * PartBits;
607 unsigned OddParts = NumParts - RoundParts;
616 std::reverse(Parts + RoundParts, Parts + NumParts);
618 NumParts = RoundParts;
630 for (
unsigned StepSize = NumParts; StepSize > 1; StepSize /= 2) {
631 for (
unsigned i = 0; i < NumParts; i += StepSize) {
632 unsigned ThisBits = StepSize * PartBits / 2;
635 SDValue &Part1 = Parts[i+StepSize/2];
642 if (ThisBits == PartBits && ThisVT != PartVT) {
650 std::reverse(Parts, Parts + OrigNumParts);
672 if (ValueEVT == MVT::bf16 && PartEVT == MVT::f16) {
674 "Cannot widen to illegal type");
678 }
else if (PartEVT != ValueEVT) {
693 Ops.append((PartNumElts - ValueNumElts).getFixedValue(), EltUndef);
704 std::optional<CallingConv::ID> CallConv) {
708 const bool IsABIRegCopy = CallConv.has_value();
711 EVT PartEVT = PartVT;
712 if (PartEVT == ValueVT) {
758 "lossy conversion of vector to scalar type");
773 unsigned NumIntermediates;
777 *DAG.
getContext(), *CallConv, ValueVT, IntermediateVT, NumIntermediates,
782 NumIntermediates, RegisterVT);
787 "Mixing scalable and fixed vectors when copying in parts");
789 std::optional<ElementCount> DestEltCnt;
799 if (ValueVT == BuiltVectorTy) {
823 for (
unsigned i = 0; i != NumIntermediates; ++i) {
838 if (NumParts == NumIntermediates) {
841 for (
unsigned i = 0; i != NumParts; ++i)
843 }
else if (NumParts > 0) {
846 assert(NumIntermediates != 0 &&
"division by zero");
847 assert(NumParts % NumIntermediates == 0 &&
848 "Must expand into a divisible number of parts!");
849 unsigned Factor = NumParts / NumIntermediates;
850 for (
unsigned i = 0; i != NumIntermediates; ++i)
858 if (
I.hasOperandBundlesOtherThan(AllowedBundles)) {
862 for (
unsigned i = 0, e =
I.getNumOperandBundles(); i != e; ++i) {
865 OS << LS << U.getTagName();
868 Twine(
"cannot lower ", Name)
874 EVT valuevt, std::optional<CallingConv::ID>
CC)
880 std::optional<CallingConv::ID>
CC) {
894 for (
unsigned i = 0; i != NumRegs; ++i)
895 Regs.push_back(Reg + i);
896 RegVTs.push_back(RegisterVT);
898 Reg = Reg.id() + NumRegs;
925 for (
unsigned i = 0; i != NumRegs; ++i) {
931 *Glue =
P.getValue(2);
934 Chain =
P.getValue(1);
962 EVT FromVT(MVT::Other);
966 }
else if (NumSignBits > 1) {
974 assert(FromVT != MVT::Other);
980 RegisterVT, ValueVT, V, Chain,
CallConv);
996 unsigned NumRegs =
Regs.size();
1017 for (
unsigned i = 0; i != NumRegs; ++i) {
1029 if (NumRegs == 1 || Glue)
1040 Chain = Chains[NumRegs-1];
1046 unsigned MatchingIdx,
const SDLoc &dl,
1048 std::vector<SDValue> &
Ops)
const {
1053 Flag.setMatchingOp(MatchingIdx);
1054 else if (!
Regs.empty() &&
Regs.front().isVirtual()) {
1062 Flag.setRegClass(RC->
getID());
1073 "No 1:1 mapping from clobbers to regs?");
1076 for (
unsigned I = 0, E =
ValueVTs.size();
I != E; ++
I) {
1081 "If we clobbered the stack pointer, MFI should know about it.");
1090 for (
unsigned i = 0; i != NumRegs; ++i) {
1091 assert(Reg <
Regs.size() &&
"Mismatch in # registers expected");
1103 unsigned RegCount = std::get<0>(CountAndVT);
1104 MVT RegisterVT = std::get<1>(CountAndVT);
1122 SL->init(
DAG.getTargetLoweringInfo(), TM,
DAG.getDataLayout());
1124 *
DAG.getMachineFunction().getFunction().getParent());
1125 CanDescribeGlobalAddressInLocationList =
1131 UnusedArgNodeMap.clear();
1133 PendingExports.clear();
1134 PendingConstrainedFP.clear();
1135 PendingConstrainedFPStrict.clear();
1143 DanglingDebugInfoMap.clear();
1150 if (Pending.
empty())
1156 unsigned i = 0, e = Pending.
size();
1157 for (; i != e; ++i) {
1159 if (Pending[i].
getNode()->getOperand(0) == Root)
1167 if (Pending.
size() == 1)
1194 if (!PendingConstrainedFPStrict.empty()) {
1195 assert(PendingConstrainedFP.empty());
1196 updateRoot(PendingConstrainedFPStrict);
1209 if (!PendingConstrainedFP.empty()) {
1210 assert(PendingConstrainedFPStrict.empty());
1211 updateRoot(PendingConstrainedFP);
1215 return DAG.getRoot();
1223 PendingConstrainedFP.size() +
1224 PendingConstrainedFPStrict.size());
1226 PendingConstrainedFP.end());
1227 PendingLoads.append(PendingConstrainedFPStrict.begin(),
1228 PendingConstrainedFPStrict.end());
1229 PendingConstrainedFP.clear();
1230 PendingConstrainedFPStrict.clear();
1237 PendingExports.append(PendingConstrainedFPStrict.begin(),
1238 PendingConstrainedFPStrict.end());
1239 PendingConstrainedFPStrict.clear();
1240 return updateRoot(PendingExports);
1247 assert(Variable &&
"Missing variable");
1254 <<
"dbg_declare: Dropping debug info (bad/undef/unused-arg address)\n");
1270 if (IsParameter && FINode) {
1272 SDV =
DAG.getFrameIndexDbgValue(Variable,
Expression, FINode->getIndex(),
1273 true,
DL, SDNodeOrder);
1278 FuncArgumentDbgValueKind::Declare,
N);
1281 SDV =
DAG.getDbgValue(Variable,
Expression,
N.getNode(),
N.getResNo(),
1282 true,
DL, SDNodeOrder);
1284 DAG.AddDbgValue(SDV, IsParameter);
1289 FuncArgumentDbgValueKind::Declare,
N)) {
1291 <<
" (could not emit func-arg dbg_value)\n");
1302 for (
auto It = FnVarLocs->locs_begin(&
I),
End = FnVarLocs->locs_end(&
I);
1304 auto *Var = FnVarLocs->getDILocalVariable(It->VariableID);
1306 if (It->Values.isKillLocation(It->Expr)) {
1312 It->Values.hasArgList())) {
1315 FnVarLocs->getDILocalVariable(It->VariableID),
1316 It->Expr, Vals.
size() > 1, It->DL, SDNodeOrder);
1329 bool SkipDbgVariableRecords =
DAG.getFunctionVarLocs();
1332 for (
DbgRecord &DR :
I.getDbgRecordRange()) {
1334 assert(DLR->getLabel() &&
"Missing label");
1336 DAG.getDbgLabel(DLR->getLabel(), DLR->getDebugLoc(), SDNodeOrder);
1337 DAG.AddDbgLabel(SDV);
1341 if (SkipDbgVariableRecords)
1349 if (
FuncInfo.PreprocessedDVRDeclares.contains(&DVR))
1351 LLVM_DEBUG(
dbgs() <<
"SelectionDAG visiting dbg_declare: " << DVR
1377 SDNodeOrder, IsVariadic)) {
1388 if (
I.isTerminator()) {
1389 HandlePHINodesInSuccessorBlocks(
I.getParent());
1396 bool NodeInserted =
false;
1397 std::unique_ptr<SelectionDAG::DAGNodeInsertedListener> InsertedListener;
1398 MDNode *PCSectionsMD =
I.getMetadata(LLVMContext::MD_pcsections);
1399 MDNode *MMRA =
I.getMetadata(LLVMContext::MD_mmra);
1400 if (PCSectionsMD || MMRA) {
1401 InsertedListener = std::make_unique<SelectionDAG::DAGNodeInsertedListener>(
1402 DAG, [&](
SDNode *) { NodeInserted =
true; });
1412 if (PCSectionsMD || MMRA) {
1413 auto It = NodeMap.find(&
I);
1414 if (It != NodeMap.end()) {
1416 DAG.addPCSections(It->second.getNode(), PCSectionsMD);
1418 DAG.addMMRAMetadata(It->second.getNode(), MMRA);
1419 }
else if (NodeInserted) {
1422 errs() <<
"warning: loosing !pcsections and/or !mmra metadata ["
1423 <<
I.getModule()->getName() <<
"]\n";
1432void SelectionDAGBuilder::visitPHI(
const PHINode &) {
1442#define HANDLE_INST(NUM, OPCODE, CLASS) \
1443 case Instruction::OPCODE: visit##OPCODE((const CLASS&)I); break;
1444#include "llvm/IR/Instruction.def"
1481 DanglingDebugInfoMap[
Values[0]].emplace_back(Var, Expr,
DL, Order);
1486 auto isMatchingDbgValue = [&](DanglingDebugInfo &DDI) {
1487 DIVariable *DanglingVariable = DDI.getVariable();
1489 if (DanglingVariable == Variable && Expr->
fragmentsOverlap(DanglingExpr)) {
1491 << printDDI(
nullptr, DDI) <<
"\n");
1497 for (
auto &DDIMI : DanglingDebugInfoMap) {
1498 DanglingDebugInfoVector &DDIV = DDIMI.second;
1502 for (
auto &DDI : DDIV)
1503 if (isMatchingDbgValue(DDI))
1506 erase_if(DDIV, isMatchingDbgValue);
1514 auto DanglingDbgInfoIt = DanglingDebugInfoMap.find(V);
1515 if (DanglingDbgInfoIt == DanglingDebugInfoMap.end())
1518 DanglingDebugInfoVector &DDIV = DanglingDbgInfoIt->second;
1519 for (
auto &DDI : DDIV) {
1521 unsigned DbgSDNodeOrder = DDI.getSDNodeOrder();
1524 assert(Variable->isValidLocationForIntrinsic(
DL) &&
1525 "Expected inlined-at fields to agree");
1535 if (!EmitFuncArgumentDbgValue(V, Variable, Expr,
DL,
1536 FuncArgumentDbgValueKind::Value, Val)) {
1538 << printDDI(V, DDI) <<
"\n");
1545 <<
"changing SDNodeOrder from " << DbgSDNodeOrder <<
" to "
1546 << ValSDNodeOrder <<
"\n");
1547 SDV = getDbgValue(Val, Variable, Expr,
DL,
1548 std::max(DbgSDNodeOrder, ValSDNodeOrder));
1549 DAG.AddDbgValue(SDV,
false);
1553 <<
" in EmitFuncArgumentDbgValue\n");
1555 LLVM_DEBUG(
dbgs() <<
"Dropping debug info for " << printDDI(V, DDI)
1559 DAG.getConstantDbgValue(Variable, Expr, Poison,
DL, DbgSDNodeOrder);
1560 DAG.AddDbgValue(SDV,
false);
1587 DanglingDebugInfo &DDI) {
1592 const Value *OrigV = V;
1596 unsigned SDOrder = DDI.getSDNodeOrder();
1605 auto HandleGlobalAddress = [&] {
1613 false,
DL, SDOrder,
false);
1614 DAG.AddDbgValue(SDV,
false);
1620 HandleGlobalAddress())
1642 if (!AdditionalValues.
empty())
1651 HandleGlobalAddress()) {
1653 dbgs() <<
"Salvaged debug location info for:\n " << *Var <<
"\n"
1654 << *OrigV <<
"\nBy stripping back to:\n " << *V <<
"\n");
1662 assert(OrigV &&
"V shouldn't be null");
1664 auto *SDV =
DAG.getConstantDbgValue(Var, Expr, Poison,
DL, SDNodeOrder);
1665 DAG.AddDbgValue(SDV,
false);
1667 << printDDI(OrigV, DDI) <<
"\n");
1684 unsigned Order,
bool IsVariadic) {
1689 if (visitEntryValueDbgValue(
Values, Var, Expr, DbgLoc))
1704 if (CE->getOpcode() == Instruction::IntToPtr) {
1714 if (CanDescribeGlobalAddressInLocationList)
1716 V, Expr, OpIdx,
DAG.getMachineFunction())) {
1735 N = UnusedArgNodeMap[V];
1740 EmitFuncArgumentDbgValue(V, Var, Expr, DbgLoc,
1741 FuncArgumentDbgValueKind::Value,
N))
1768 bool IsParamOfFunc =
1776 auto VMI =
FuncInfo.ValueMap.find(V);
1777 if (VMI !=
FuncInfo.ValueMap.end()) {
1782 V->getType(), std::nullopt);
1788 unsigned BitsToDescribe = 0;
1790 BitsToDescribe = *VarSize;
1792 BitsToDescribe =
Fragment->SizeInBits;
1795 if (
Offset >= BitsToDescribe)
1798 unsigned RegisterSize = RegAndSize.second;
1799 unsigned FragmentSize = (
Offset + RegisterSize > BitsToDescribe)
1800 ? BitsToDescribe -
Offset
1803 Expr,
Offset, FragmentSize);
1807 Var, *FragmentExpr, RegAndSize.first,
false, DbgLoc, Order);
1808 DAG.AddDbgValue(SDV,
false);
1824 DAG.getDbgValueList(Var, Expr, LocationOps, Dependencies,
1825 false, DbgLoc, Order, IsVariadic);
1826 DAG.AddDbgValue(SDV,
false);
1832 for (
auto &Pair : DanglingDebugInfoMap)
1833 for (
auto &DDI : Pair.second)
1841 auto It =
FuncInfo.ValueMap.find(V);
1844 if (It !=
FuncInfo.ValueMap.end()) {
1848 DAG.getDataLayout(), InReg, Ty,
1865 if (
N.getNode())
return N;
1880 if (V->getType()->isVoidTy())
1885 V->getType(), ValueVTs);
1886 if (ValueVTs.
empty())
1937 return DAG.getSplatBuildVector(
1940 return DAG.getConstant(*CI,
DL, VT);
1952 getValue(CPA->getAddrDiscriminator()),
1953 getValue(CPA->getDiscriminator()));
1969 visit(CE->getOpcode(), *CE);
1971 assert(N1.
getNode() &&
"visit didn't populate the NodeMap!");
1977 for (
const Use &U :
C->operands()) {
1983 for (
unsigned i = 0, e = Val->
getNumValues(); i != e; ++i)
1984 Constants.push_back(
SDValue(Val, i));
1993 for (uint64_t i = 0, e = CDS->getNumElements(); i != e; ++i) {
1997 for (
unsigned i = 0, e = Val->
getNumValues(); i != e; ++i)
2006 if (
C->getType()->isStructTy() ||
C->getType()->isArrayTy()) {
2008 "Unknown struct or array constant!");
2012 unsigned NumElts = ValueVTs.
size();
2016 for (
unsigned i = 0; i != NumElts; ++i) {
2017 EVT EltVT = ValueVTs[i];
2019 Constants[i] =
DAG.getUNDEF(EltVT);
2030 return DAG.getBlockAddress(BA, VT);
2033 return getValue(Equiv->getGlobalValue());
2038 if (VT == MVT::aarch64svcount) {
2039 assert(
C->isNullValue() &&
"Can only zero this target type!");
2045 assert(
C->isNullValue() &&
"Can only zero this target type!");
2055 if (VT == MVT::externref || VT == MVT::funcref) {
2056 assert(
C->isNullValue() &&
"Can only zero this target type!");
2059 Intrinsic::ID IID = VT == MVT::externref ? Intrinsic::wasm_ref_null_extern
2060 : Intrinsic::wasm_ref_null_func;
2072 for (
unsigned i = 0; i != NumElements; ++i)
2099 return DAG.getFrameIndex(
2107 Inst->getType(), std::nullopt);
2121void SelectionDAGBuilder::visitCatchPad(
const CatchPadInst &
I) {
2134 if (IsMSVCCXX || IsCoreCLR)
2140 MachineBasicBlock *TargetMBB =
FuncInfo.getMBB(
I.getSuccessor());
2141 FuncInfo.MBB->addSuccessor(TargetMBB);
2148 if (TargetMBB != NextBlock(
FuncInfo.MBB) ||
2157 DAG.getMachineFunction().setHasEHContTarget(
true);
2163 Value *ParentPad =
I.getCatchSwitchParentPad();
2166 SuccessorColor = &
FuncInfo.Fn->getEntryBlock();
2169 assert(SuccessorColor &&
"No parent funclet for catchret!");
2170 MachineBasicBlock *SuccessorColorMBB =
FuncInfo.getMBB(SuccessorColor);
2171 assert(SuccessorColorMBB &&
"No MBB for SuccessorColor!");
2176 DAG.getBasicBlock(SuccessorColorMBB));
2180void SelectionDAGBuilder::visitCleanupPad(
const CleanupPadInst &CPI) {
2186 FuncInfo.MBB->setIsEHFuncletEntry();
2187 FuncInfo.MBB->setIsCleanupFuncletEntry();
2217 UnwindDests.emplace_back(FuncInfo.
getMBB(EHPadBB), Prob);
2223 UnwindDests.emplace_back(FuncInfo.
getMBB(EHPadBB), Prob);
2224 UnwindDests.back().first->setIsEHScopeEntry();
2226 if (!IsWasmCXX && !IsWasmD)
2227 UnwindDests.back().first->setIsEHFuncletEntry();
2231 for (
const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
2232 UnwindDests.emplace_back(FuncInfo.
getMBB(CatchPadBB), Prob);
2234 if (IsMSVCCXX || IsCoreCLR)
2235 UnwindDests.back().first->setIsEHFuncletEntry();
2237 UnwindDests.back().first->setIsEHScopeEntry();
2239 NewEHPadBB = CatchSwitch->getUnwindDest();
2245 if (BPI && NewEHPadBB)
2247 EHPadBB = NewEHPadBB;
2254 auto UnwindDest =
I.getUnwindDest();
2255 BranchProbabilityInfo *BPI =
FuncInfo.BPI;
2256 BranchProbability UnwindDestProb =
2261 for (
auto &UnwindDest : UnwindDests) {
2262 UnwindDest.first->setIsEHPad();
2263 addSuccessorWithProb(
FuncInfo.MBB, UnwindDest.first, UnwindDest.second);
2265 FuncInfo.MBB->normalizeSuccProbs();
2268 MachineBasicBlock *CleanupPadMBB =
2269 FuncInfo.getMBB(
I.getCleanupPad()->getParent());
2275void SelectionDAGBuilder::visitCatchSwitch(
const CatchSwitchInst &CSI) {
2279void SelectionDAGBuilder::visitRet(
const ReturnInst &
I) {
2280 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
2281 auto &
DL =
DAG.getDataLayout();
2293 if (
I.getParent()->getTerminatingDeoptimizeCall()) {
2307 Type *RetTy =
I.getOperand(0)->getType();
2308 Align BaseAlign =
DL.getPrefTypeAlign(RetTy);
2311 SDValue RetOp =
getValue(
I.getOperand(0));
2314 SmallVector<uint64_t, 4>
Offsets;
2316 unsigned NumValues = ValueVTs.
size();
2319 for (
unsigned i = 0; i != NumValues; ++i) {
2326 if (MemVTs[i] != ValueVTs[i])
2328 Chains[i] =
DAG.getStore(
2336 MVT::Other, Chains);
2337 }
else if (
I.getNumOperands() != 0) {
2340 unsigned NumValues =
Types.size();
2342 SDValue RetOp =
getValue(
I.getOperand(0));
2344 const Function *
F =
I.getParent()->getParent();
2347 I.getOperand(0)->getType(),
F->getCallingConv(),
2351 if (
F->getAttributes().hasRetAttr(Attribute::SExt))
2353 else if (
F->getAttributes().hasRetAttr(Attribute::ZExt))
2356 LLVMContext &
Context =
F->getContext();
2357 bool RetInReg =
F->getAttributes().hasRetAttr(Attribute::InReg);
2359 for (
unsigned j = 0;
j != NumValues; ++
j) {
2375 ISD::ArgFlagsTy
Flags = ISD::ArgFlagsTy();
2379 if (
I.getOperand(0)->getType()->isPointerTy()) {
2381 Flags.setPointerAddrSpace(
2385 if (NeedsRegBlock) {
2386 Flags.setInConsecutiveRegs();
2387 if (j == NumValues - 1)
2388 Flags.setInConsecutiveRegsLast();
2396 else if (
F->getAttributes().hasRetAttr(Attribute::NoExt))
2399 for (
unsigned i = 0; i < NumParts; ++i) {
2402 VT, Types[j], 0, 0));
2412 const Function *
F =
I.getParent()->getParent();
2414 F->getAttributes().hasAttrSomewhere(Attribute::SwiftError)) {
2416 ISD::ArgFlagsTy
Flags = ISD::ArgFlagsTy();
2417 Flags.setSwiftError();
2429 bool isVarArg =
DAG.getMachineFunction().getFunction().isVarArg();
2431 DAG.getMachineFunction().getFunction().getCallingConv();
2432 Chain =
DAG.getTargetLoweringInfo().LowerReturn(
2437 "LowerReturn didn't return a valid chain!");
2448 if (V->getType()->isEmptyTy())
2451 auto VMI =
FuncInfo.ValueMap.find(V);
2452 if (VMI !=
FuncInfo.ValueMap.end()) {
2454 "Unused value assigned virtual registers!");
2467 if (
FuncInfo.isExportedInst(V))
return;
2479 if (VI->getParent() == FromBB)
2505 const BasicBlock *SrcBB = Src->getBasicBlock();
2506 const BasicBlock *DstBB = Dst->getBasicBlock();
2510 auto SuccSize = std::max<uint32_t>(
succ_size(SrcBB), 1);
2520 Src->addSuccessorWithoutProb(Dst);
2523 Prob = getEdgeProbability(Src, Dst);
2524 Src->addSuccessor(Dst, Prob);
2530 return I->getParent() == BB;
2554 if (CurBB == SwitchBB ||
2560 InvertCond ? IC->getInversePredicate() : IC->getPredicate();
2565 InvertCond ? FC->getInversePredicate() : FC->getPredicate();
2567 if (FC->hasNoNaNs() ||
2575 CaseBlock CB(Condition, BOp->getOperand(0), BOp->getOperand(1),
nullptr,
2577 SL->SwitchCases.push_back(CB);
2586 SL->SwitchCases.push_back(CB);
2594 unsigned Depth = 0) {
2603 if (Necessary !=
nullptr) {
2606 if (Necessary->contains(
I))
2614 for (
unsigned OpIdx = 0,
E =
I->getNumOperands(); OpIdx <
E; ++OpIdx)
2634 if (BPI !=
nullptr) {
2642 std::optional<bool> Likely;
2645 else if (BPI->
isEdgeHot(
I.getParent(), IfFalse))
2649 if (
Opc == (*Likely ? Instruction::And : Instruction::Or))
2661 if (CostThresh <= 0)
2682 Value *BrCond =
I.getCondition();
2683 auto ShouldCountInsn = [&RhsDeps, &BrCond](
const Instruction *Ins) {
2684 for (
const auto *U : Ins->users()) {
2687 if (UIns != BrCond && !RhsDeps.
contains(UIns))
2700 for (
unsigned PruneIters = 0; PruneIters < MaxPruneIters; ++PruneIters) {
2702 for (
const auto &InsPair : RhsDeps) {
2703 if (!ShouldCountInsn(InsPair.first)) {
2704 ToDrop = InsPair.first;
2708 if (ToDrop ==
nullptr)
2710 RhsDeps.erase(ToDrop);
2713 for (
const auto &InsPair : RhsDeps) {
2718 CostOfIncluding +=
TTI->getInstructionCost(
2721 if (CostOfIncluding > CostThresh)
2747 const Value *BOpOp0, *BOpOp1;
2761 if (BOpc == Instruction::And)
2762 BOpc = Instruction::Or;
2763 else if (BOpc == Instruction::Or)
2764 BOpc = Instruction::And;
2770 bool BOpIsInOrAndTree = BOpc && BOpc ==
Opc && BOp->
hasOneUse();
2775 TProb, FProb, InvertCond);
2785 if (
Opc == Instruction::Or) {
2806 auto NewTrueProb = TProb / 2;
2807 auto NewFalseProb = TProb / 2 + FProb;
2810 NewFalseProb, InvertCond);
2817 Probs[1], InvertCond);
2819 assert(
Opc == Instruction::And &&
"Unknown merge op!");
2839 auto NewTrueProb = TProb + FProb / 2;
2840 auto NewFalseProb = FProb / 2;
2843 NewFalseProb, InvertCond);
2850 Probs[1], InvertCond);
2859 if (Cases.size() != 2)
return true;
2863 if ((Cases[0].CmpLHS == Cases[1].CmpLHS &&
2864 Cases[0].CmpRHS == Cases[1].CmpRHS) ||
2865 (Cases[0].CmpRHS == Cases[1].CmpLHS &&
2866 Cases[0].CmpLHS == Cases[1].CmpRHS)) {
2872 if (Cases[0].CmpRHS == Cases[1].CmpRHS &&
2873 Cases[0].
CC == Cases[1].
CC &&
2876 if (Cases[0].
CC ==
ISD::SETEQ && Cases[0].TrueBB == Cases[1].ThisBB)
2878 if (Cases[0].
CC ==
ISD::SETNE && Cases[0].FalseBB == Cases[1].ThisBB)
2885void SelectionDAGBuilder::visitUncondBr(
const UncondBrInst &
I) {
2895 if (Succ0MBB != NextBlock(BrMBB) ||
2904void SelectionDAGBuilder::visitCondBr(
const CondBrInst &
I) {
2905 MachineBasicBlock *BrMBB =
FuncInfo.MBB;
2907 MachineBasicBlock *Succ0MBB =
FuncInfo.getMBB(
I.getSuccessor(0));
2911 const Value *CondVal =
I.getCondition();
2912 MachineBasicBlock *Succ1MBB =
FuncInfo.getMBB(
I.getSuccessor(1));
2931 bool IsUnpredictable =
I.hasMetadata(LLVMContext::MD_unpredictable);
2933 if (!
DAG.getTargetLoweringInfo().isJumpExpensive() && BOp &&
2936 const Value *BOp0, *BOp1;
2939 Opcode = Instruction::And;
2941 Opcode = Instruction::Or;
2948 DAG.getTargetLoweringInfo().getJumpConditionMergingParams(
2949 Opcode, BOp0, BOp1,
FuncInfo.Fn))) {
2951 getEdgeProbability(BrMBB, Succ0MBB),
2952 getEdgeProbability(BrMBB, Succ1MBB),
2957 assert(
SL->SwitchCases[0].ThisBB == BrMBB &&
"Unexpected lowering!");
2961 for (
unsigned i = 1, e =
SL->SwitchCases.size(); i != e; ++i) {
2968 SL->SwitchCases.erase(
SL->SwitchCases.begin());
2974 for (
unsigned i = 1, e =
SL->SwitchCases.size(); i != e; ++i)
2975 FuncInfo.MF->erase(
SL->SwitchCases[i].ThisBB);
2977 SL->SwitchCases.clear();
2983 nullptr, Succ0MBB, Succ1MBB, BrMBB,
getCurSDLoc(),
3004 if (CB.
TrueBB != NextBlock(SwitchBB)) {
3011 auto &TLI =
DAG.getTargetLoweringInfo();
3035 Cond =
DAG.getSetCC(dl, MVT::i1, CondLHS, CondRHS, CB.
CC);
3047 Cond =
DAG.getSetCC(dl, MVT::i1, CmpOp,
DAG.getConstant(
High, dl, VT),
3051 VT, CmpOp,
DAG.getConstant(
Low, dl, VT));
3052 Cond =
DAG.getSetCC(dl, MVT::i1, SUB,
3067 if (CB.
TrueBB == NextBlock(SwitchBB)) {
3083 BrCond =
DAG.getNode(
ISD::BR, dl, MVT::Other, BrCond,
3086 DAG.setRoot(BrCond);
3092 assert(JT.
SL &&
"Should set SDLoc for SelectionDAG!");
3093 assert(JT.
Reg &&
"Should lower JT Header first!");
3094 EVT PTy =
DAG.getTargetLoweringInfo().getJumpTableRegTy(
DAG.getDataLayout());
3098 Index.getValue(1),
Table, Index);
3099 DAG.setRoot(BrJumpTable);
3107 assert(JT.
SL &&
"Should set SDLoc for SelectionDAG!");
3114 DAG.getConstant(JTH.
First, dl, VT));
3129 JT.
Reg = JumpTableReg;
3137 Sub.getValueType()),
3141 MVT::Other, CopyTo, CMP,
3145 if (JT.
MBB != NextBlock(SwitchBB))
3146 BrCond =
DAG.getNode(
ISD::BR, dl, MVT::Other, BrCond,
3147 DAG.getBasicBlock(JT.
MBB));
3149 DAG.setRoot(BrCond);
3152 if (JT.
MBB != NextBlock(SwitchBB))
3154 DAG.getBasicBlock(JT.
MBB)));
3156 DAG.setRoot(CopyTo);
3180 if (PtrTy != PtrMemTy)
3196 auto &
DL =
DAG.getDataLayout();
3205 SDValue StackSlotPtr =
DAG.getFrameIndex(FI, PtrTy);
3212 PtrMemTy, dl,
DAG.getEntryNode(), StackSlotPtr,
3230 assert(GuardCheckFn &&
"Guard check function is null");
3241 Entry.IsInReg =
true;
3242 Args.push_back(Entry);
3248 getValue(GuardCheckFn), std::move(Args));
3250 std::pair<SDValue, SDValue> Result = TLI.
LowerCallTo(CLI);
3251 DAG.setRoot(Result.second);
3263 Guard =
DAG.getLoad(PtrMemTy, dl, Chain, GuardPtr,
3269 Guard =
DAG.getPOISON(PtrMemTy);
3278 Guard =
DAG.getLoad(PtrMemTy, dl, Chain, GuardPtr,
3284 Guard =
DAG.getPOISON(PtrMemTy);
3330 auto &
DL =
DAG.getDataLayout();
3338 SDValue StackSlotPtr =
DAG.getFrameIndex(FI, PtrTy);
3344 PtrMemTy, dl,
DAG.getEntryNode(), StackSlotPtr,
3359 if (GuardCheckFn->hasParamAttribute(0, Attribute::AttrKind::InReg))
3360 Entry.IsInReg =
true;
3361 Args.push_back(Entry);
3367 getValue(GuardCheckFn), std::move(Args));
3373 Chain = TLI.
makeLibCall(
DAG, RTLIB::STACKPROTECTOR_CHECK_FAIL, MVT::isVoid,
3396 DAG.getNode(
ISD::SUB, dl, VT, SwitchOp,
DAG.getConstant(
B.First, dl, VT));
3400 bool UsePtrType =
false;
3424 if (!
B.FallthroughUnreachable)
3425 addSuccessorWithProb(SwitchBB,
B.Default,
B.DefaultProb);
3426 addSuccessorWithProb(SwitchBB,
MBB,
B.Prob);
3430 if (!
B.FallthroughUnreachable) {
3439 DAG.getBasicBlock(
B.Default));
3443 if (
MBB != NextBlock(SwitchBB))
3461 if (PopCount == 1) {
3468 }
else if (PopCount == BB.
Range) {
3476 DAG.getConstant(1, dl, VT), ShiftOp);
3480 VT, SwitchVal,
DAG.getConstant(
B.Mask, dl, VT));
3487 addSuccessorWithProb(SwitchBB,
B.TargetBB,
B.ExtraProb);
3489 addSuccessorWithProb(SwitchBB, NextMBB, BranchProbToNext);
3497 Cmp,
DAG.getBasicBlock(
B.TargetBB));
3500 if (NextMBB != NextBlock(SwitchBB))
3501 BrAnd =
DAG.getNode(
ISD::BR, dl, MVT::Other, BrAnd,
3502 DAG.getBasicBlock(NextMBB));
3507void SelectionDAGBuilder::visitInvoke(
const InvokeInst &
I) {
3525 const Value *Callee(
I.getCalledOperand());
3528 visitInlineAsm(
I, EHPadBB);
3533 case Intrinsic::donothing:
3535 case Intrinsic::seh_try_begin:
3536 case Intrinsic::seh_scope_begin:
3537 case Intrinsic::seh_try_end:
3538 case Intrinsic::seh_scope_end:
3544 case Intrinsic::experimental_patchpoint_void:
3545 case Intrinsic::experimental_patchpoint:
3546 visitPatchpoint(
I, EHPadBB);
3548 case Intrinsic::experimental_gc_statepoint:
3554 case Intrinsic::wasm_throw: {
3556 std::array<SDValue, 4>
Ops = {
3567 case Intrinsic::wasm_rethrow: {
3568 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
3569 std::array<SDValue, 2>
Ops = {
3578 }
else if (
I.hasDeoptState()) {
3599 BranchProbabilityInfo *BPI =
FuncInfo.BPI;
3600 BranchProbability EHPadBBProb =
3606 addSuccessorWithProb(InvokeMBB, Return);
3607 for (
auto &UnwindDest : UnwindDests) {
3608 UnwindDest.first->setIsEHPad();
3609 addSuccessorWithProb(InvokeMBB, UnwindDest.first, UnwindDest.second);
3615 DAG.getBasicBlock(Return)));
3624void SelectionDAGBuilder::visitCallBrIntrinsic(
const CallBrInst &
I) {
3627 DAG.getTargetLoweringInfo().getTgtMemIntrinsic(
3628 Infos,
I,
DAG.getMachineFunction(),
I.getIntrinsicID());
3629 assert(Infos.
empty() &&
"Intrinsic touches memory");
3632 auto [HasChain, OnlyLoad] = getTargetIntrinsicCallProperties(
I);
3635 getTargetIntrinsicOperands(
I, HasChain, OnlyLoad);
3636 SDVTList VTs = getTargetIntrinsicVTList(
I, HasChain);
3640 getTargetNonMemIntrinsicNode(*
I.getType(), HasChain,
Ops, VTs);
3641 Result = handleTargetIntrinsicRet(
I, HasChain, OnlyLoad, Result);
3646void SelectionDAGBuilder::visitCallBr(
const CallBrInst &
I) {
3647 MachineBasicBlock *CallBrMBB =
FuncInfo.MBB;
3649 if (
I.isInlineAsm()) {
3656 assert(!
I.hasOperandBundles() &&
3657 "Can't have operand bundles for intrinsics");
3658 visitCallBrIntrinsic(
I);
3663 SmallPtrSet<BasicBlock *, 8> Dests;
3664 Dests.
insert(
I.getDefaultDest());
3674 if (
I.isInlineAsm()) {
3675 for (BasicBlock *Dest :
I.getIndirectDests()) {
3677 Target->setIsInlineAsmBrIndirectTarget();
3683 Target->setLabelMustBeEmitted();
3685 if (Dests.
insert(Dest).second)
3694 DAG.getBasicBlock(Return)));
3697void SelectionDAGBuilder::visitResume(
const ResumeInst &RI) {
3698 llvm_unreachable(
"SelectionDAGBuilder shouldn't visit resume instructions!");
3701void SelectionDAGBuilder::visitLandingPad(
const LandingPadInst &LP) {
3703 "Call to landingpad not in landing pad!");
3707 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
3712 PersonalityFn) == 0)
3726 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
3728 "landingpad result type must be a struct of an exception pointer and "
3729 "an integer selector",
3737 assert(ValueVTs.
size() == 2 &&
"Only two-valued landingpads are supported");
3742 if (
FuncInfo.ExceptionPointerVirtReg) {
3743 Ops[0] =
DAG.getZExtOrTrunc(
3744 DAG.getCopyFromReg(
DAG.getEntryNode(), dl,
3751 Ops[1] =
DAG.getZExtOrTrunc(
3752 DAG.getCopyFromReg(
DAG.getEntryNode(), dl,
3759 DAG.getVTList(ValueVTs),
Ops);
3767 if (JTB.first.HeaderBB ==
First)
3768 JTB.first.HeaderBB =
Last;
3781 for (
unsigned i = 0, e =
I.getNumSuccessors(); i != e; ++i) {
3783 bool Inserted =
Done.insert(BB).second;
3788 addSuccessorWithProb(IndirectBrMBB, Succ);
3798 if (!
I.shouldLowerToTrap(
DAG.getTarget().Options.TrapUnreachable,
3799 DAG.getTarget().Options.NoTrapAfterNoreturn))
3805void SelectionDAGBuilder::visitUnary(
const User &
I,
unsigned Opcode) {
3808 Flags.copyFMF(*FPOp);
3811 SDValue UnNodeValue =
DAG.getNode(Opcode,
getCurSDLoc(),
Op.getValueType(),
3816void SelectionDAGBuilder::visitBinary(
const User &
I,
unsigned Opcode) {
3819 Flags.setNoSignedWrap(OFBinOp->hasNoSignedWrap());
3820 Flags.setNoUnsignedWrap(OFBinOp->hasNoUnsignedWrap());
3823 Flags.setExact(ExactOp->isExact());
3825 Flags.setDisjoint(DisjointOp->isDisjoint());
3827 Flags.copyFMF(*FPOp);
3829 SDValue Op1 =
getValue(
I.getOperand(0));
3830 SDValue Op2 =
getValue(
I.getOperand(1));
3836void SelectionDAGBuilder::visitShift(
const User &
I,
unsigned Opcode) {
3837 SDValue Op1 =
getValue(
I.getOperand(0));
3838 SDValue Op2 =
getValue(
I.getOperand(1));
3840 EVT ShiftTy =
DAG.getTargetLoweringInfo().getShiftAmountTy(
3845 if (!
I.getType()->isVectorTy() && Op2.
getValueType() != ShiftTy) {
3847 "Unexpected shift type");
3857 if (
const OverflowingBinaryOperator *OFBinOp =
3859 nuw = OFBinOp->hasNoUnsignedWrap();
3860 nsw = OFBinOp->hasNoSignedWrap();
3862 if (
const PossiblyExactOperator *ExactOp =
3864 exact = ExactOp->isExact();
3867 Flags.setExact(exact);
3868 Flags.setNoSignedWrap(nsw);
3869 Flags.setNoUnsignedWrap(nuw);
3875void SelectionDAGBuilder::visitSDiv(
const User &
I) {
3876 SDValue Op1 =
getValue(
I.getOperand(0));
3877 SDValue Op2 =
getValue(
I.getOperand(1));
3886void SelectionDAGBuilder::visitICmp(
const ICmpInst &
I) {
3888 SDValue Op1 =
getValue(
I.getOperand(0));
3889 SDValue Op2 =
getValue(
I.getOperand(1));
3892 auto &TLI =
DAG.getTargetLoweringInfo();
3905 Flags.setSameSign(
I.hasSameSign());
3907 EVT DestVT =
DAG.getTargetLoweringInfo().getValueType(
DAG.getDataLayout(),
3913void SelectionDAGBuilder::visitFCmp(
const FCmpInst &
I) {
3915 SDValue Op1 =
getValue(
I.getOperand(0));
3916 SDValue Op2 =
getValue(
I.getOperand(1));
3920 if (FPMO->hasNoNaNs() ||
3921 (
DAG.isKnownNeverNaN(Op1) &&
DAG.isKnownNeverNaN(Op2)))
3925 Flags.copyFMF(*FPMO);
3927 EVT DestVT =
DAG.getTargetLoweringInfo().getValueType(
DAG.getDataLayout(),
3937 return isa<SelectInst>(V);
3941void SelectionDAGBuilder::visitSelect(
const User &
I) {
3945 unsigned NumValues = ValueVTs.
size();
3946 if (NumValues == 0)
return;
3950 SDValue LHSVal =
getValue(
I.getOperand(1));
3951 SDValue RHSVal =
getValue(
I.getOperand(2));
3956 bool IsUnaryAbs =
false;
3957 bool Negate =
false;
3961 Flags.copyFMF(*FPOp);
3963 Flags.setUnpredictable(
3968 EVT VT = ValueVTs[0];
3969 LLVMContext &Ctx = *
DAG.getContext();
3970 auto &TLI =
DAG.getTargetLoweringInfo();
3980 bool UseScalarMinMax = VT.
isVector() &&
3989 switch (SPR.Flavor) {
3998 switch (SPR.NaNBehavior) {
4005 Flags.setNoSignedZeros(
true);
4013 switch (SPR.NaNBehavior) {
4020 Flags.setNoSignedZeros(
true);
4056 for (
unsigned i = 0; i != NumValues; ++i) {
4065 for (
unsigned i = 0; i != NumValues; ++i) {
4079void SelectionDAGBuilder::visitTrunc(
const User &
I) {
4082 EVT DestVT =
DAG.getTargetLoweringInfo().getValueType(
DAG.getDataLayout(),
4086 Flags.setNoSignedWrap(Trunc->hasNoSignedWrap());
4087 Flags.setNoUnsignedWrap(Trunc->hasNoUnsignedWrap());
4093void SelectionDAGBuilder::visitZExt(
const User &
I) {
4097 auto &TLI =
DAG.getTargetLoweringInfo();
4102 Flags.setNonNeg(PNI->hasNonNeg());
4107 if (
Flags.hasNonNeg() &&
4116void SelectionDAGBuilder::visitSExt(
const User &
I) {
4120 EVT DestVT =
DAG.getTargetLoweringInfo().getValueType(
DAG.getDataLayout(),
4125void SelectionDAGBuilder::visitFPTrunc(
const User &
I) {
4131 Flags.copyFMF(*FPOp);
4132 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
4135 DAG.getTargetConstant(
4140void SelectionDAGBuilder::visitFPExt(
const User &
I) {
4143 EVT DestVT =
DAG.getTargetLoweringInfo().getValueType(
DAG.getDataLayout(),
4147 Flags.copyFMF(*FPOp);
4151void SelectionDAGBuilder::visitFPToUI(
const User &
I) {
4154 EVT DestVT =
DAG.getTargetLoweringInfo().getValueType(
DAG.getDataLayout(),
4159void SelectionDAGBuilder::visitFPToSI(
const User &
I) {
4162 EVT DestVT =
DAG.getTargetLoweringInfo().getValueType(
DAG.getDataLayout(),
4167void SelectionDAGBuilder::visitUIToFP(
const User &
I) {
4170 EVT DestVT =
DAG.getTargetLoweringInfo().getValueType(
DAG.getDataLayout(),
4179void SelectionDAGBuilder::visitSIToFP(
const User &
I) {
4182 EVT DestVT =
DAG.getTargetLoweringInfo().getValueType(
DAG.getDataLayout(),
4190void SelectionDAGBuilder::visitPtrToAddr(
const User &
I) {
4193 const auto &TLI =
DAG.getTargetLoweringInfo();
4201void SelectionDAGBuilder::visitPtrToInt(
const User &
I) {
4205 auto &TLI =
DAG.getTargetLoweringInfo();
4206 EVT DestVT =
DAG.getTargetLoweringInfo().getValueType(
DAG.getDataLayout(),
4215void SelectionDAGBuilder::visitIntToPtr(
const User &
I) {
4219 auto &TLI =
DAG.getTargetLoweringInfo();
4227void SelectionDAGBuilder::visitBitCast(
const User &
I) {
4230 EVT DestVT =
DAG.getTargetLoweringInfo().getValueType(
DAG.getDataLayout(),
4235 if (DestVT !=
N.getValueType())
4243 setValue(&
I,
DAG.getConstant(
C->getValue(), dl, DestVT,
false,
4249void SelectionDAGBuilder::visitAddrSpaceCast(
const User &
I) {
4250 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
4251 const Value *
SV =
I.getOperand(0);
4255 unsigned SrcAS =
SV->getType()->getPointerAddressSpace();
4256 unsigned DestAS =
I.getType()->getPointerAddressSpace();
4258 if (!TM.isNoopAddrSpaceCast(
DAG.getDataLayout(), SrcAS, DestAS)) {
4261 Flags.setNonNull(ASC->hasNonNull());
4268void SelectionDAGBuilder::visitInsertElement(
const User &
I) {
4269 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
4270 SDValue InVec =
getValue(
I.getOperand(0));
4271 SDValue InVal =
getValue(
I.getOperand(1));
4276 InVec, InVal, InIdx));
4279void SelectionDAGBuilder::visitBitInsert(
const User &
I) {
4281 SDValue Val =
getValue(
I.getOperand(1));
4283 EVT BaseVT =
Base.getValueType();
4285 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
4289 "bitinsert val wider than base should be rejected by verifier");
4295 Val =
DAG.getBitcast(ValVT, Val);
4300 SDValue LegalShiftAmount =
DAG.getZExtOrTrunc(
Offset, dl, ShiftAmtTy);
4305 SDValue ShiftedMask =
4306 DAG.getNode(
ISD::SHL, dl, BaseVT,
DAG.getConstant(InsertMask, dl, BaseVT),
4308 SDValue ClearMask =
DAG.getNOT(dl, ShiftedMask, BaseVT);
4309 SDValue ClearedBase =
DAG.getNode(
ISD::AND, dl, BaseVT,
Base, ClearMask);
4311 SDValue ExtVal =
DAG.getZExtOrTrunc(Val, dl, BaseVT);
4312 SDValue ShiftedVal =
4313 DAG.getNode(
ISD::SHL, dl, BaseVT, ExtVal, LegalShiftAmount);
4314 SDValue
Result =
DAG.getNode(
ISD::OR, dl, BaseVT, ClearedBase, ShiftedVal);
4318void SelectionDAGBuilder::visitBitExtract(
const User &
I) {
4319 SDValue Src =
getValue(
I.getOperand(0));
4321 EVT SrcVT = Src.getValueType();
4322 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
4327 "bitextract result wider than source should be rejected by verifier");
4331 SDValue LegalShiftAmount =
DAG.getZExtOrTrunc(
Offset, dl, ShiftAmtTy);
4334 SDValue Shifted =
DAG.getNode(
ISD::SRL, dl, SrcVT, Src, LegalShiftAmount);
4341 Result =
DAG.getBitcast(ResultVT, Result);
4350void SelectionDAGBuilder::visitExtractElement(
const User &
I) {
4351 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
4352 SDValue InVec =
getValue(
I.getOperand(0));
4360void SelectionDAGBuilder::visitShuffleVector(
const User &
I) {
4365 Mask = SVI->getShuffleMask();
4369 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
4371 EVT SrcVT =
Src1.getValueType();
4377 DAG.getVectorIdxConstant(0,
DL));
4388 unsigned MaskNumElts =
Mask.size();
4390 if (SrcNumElts == MaskNumElts) {
4396 if (SrcNumElts < MaskNumElts) {
4400 if (MaskNumElts % SrcNumElts == 0) {
4404 unsigned NumConcat = MaskNumElts / SrcNumElts;
4405 bool IsConcat =
true;
4406 SmallVector<int, 8> ConcatSrcs(NumConcat, -1);
4407 for (
unsigned i = 0; i != MaskNumElts; ++i) {
4413 if ((Idx % SrcNumElts != (i % SrcNumElts)) ||
4414 (ConcatSrcs[i / SrcNumElts] >= 0 &&
4415 ConcatSrcs[i / SrcNumElts] != (
int)(Idx / SrcNumElts))) {
4420 ConcatSrcs[i / SrcNumElts] =
Idx / SrcNumElts;
4427 for (
auto Src : ConcatSrcs) {
4440 unsigned PaddedMaskNumElts =
alignTo(MaskNumElts, SrcNumElts);
4441 unsigned NumConcat = PaddedMaskNumElts / SrcNumElts;
4446 SDValue UndefVal =
DAG.getUNDEF(SrcVT);
4457 SmallVector<int, 8> MappedOps(PaddedMaskNumElts, -1);
4458 for (
unsigned i = 0; i != MaskNumElts; ++i) {
4460 if (Idx >= (
int)SrcNumElts)
4461 Idx -= SrcNumElts - PaddedMaskNumElts;
4465 SDValue
Result =
DAG.getVectorShuffle(PaddedVT,
DL, Src1, Src2, MappedOps);
4469 if (MaskNumElts != PaddedMaskNumElts)
4471 DAG.getVectorIdxConstant(0,
DL));
4477 assert(SrcNumElts > MaskNumElts);
4481 int StartIdx[2] = {-1, -1};
4482 bool CanExtract =
true;
4483 for (
int Idx : Mask) {
4488 if (Idx >= (
int)SrcNumElts) {
4496 int NewStartIdx =
alignDown(Idx, MaskNumElts);
4497 if (NewStartIdx + MaskNumElts > SrcNumElts ||
4498 (StartIdx[Input] >= 0 && StartIdx[Input] != NewStartIdx))
4502 StartIdx[
Input] = NewStartIdx;
4505 if (StartIdx[0] < 0 && StartIdx[1] < 0) {
4511 for (
unsigned Input = 0;
Input < 2; ++
Input) {
4513 if (StartIdx[Input] < 0)
4514 Src =
DAG.getUNDEF(VT);
4517 DAG.getVectorIdxConstant(StartIdx[Input],
DL));
4522 SmallVector<int, 8> MappedOps(Mask);
4523 for (
int &Idx : MappedOps) {
4524 if (Idx >= (
int)SrcNumElts)
4525 Idx -= SrcNumElts + StartIdx[1] - MaskNumElts;
4530 setValue(&
I,
DAG.getVectorShuffle(VT,
DL, Src1, Src2, MappedOps));
4539 for (
int Idx : Mask) {
4543 Res =
DAG.getUNDEF(EltVT);
4545 SDValue &Src =
Idx < (int)SrcNumElts ? Src1 :
Src2;
4546 if (Idx >= (
int)SrcNumElts)
Idx -= SrcNumElts;
4549 DAG.getVectorIdxConstant(Idx,
DL));
4559 ArrayRef<unsigned> Indices =
I.getIndices();
4560 const Value *Op0 =
I.getOperand(0);
4562 Type *AggTy =
I.getType();
4569 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
4575 unsigned NumAggValues = AggValueVTs.
size();
4576 unsigned NumValValues = ValValueVTs.
size();
4580 if (!NumAggValues) {
4588 for (; i != LinearIndex; ++i)
4589 Values[i] = IntoUndef ?
DAG.getUNDEF(AggValueVTs[i]) :
4594 for (; i != LinearIndex + NumValValues; ++i)
4595 Values[i] = FromUndef ?
DAG.getUNDEF(AggValueVTs[i]) :
4599 for (; i != NumAggValues; ++i)
4600 Values[i] = IntoUndef ?
DAG.getUNDEF(AggValueVTs[i]) :
4608 ArrayRef<unsigned> Indices =
I.getIndices();
4609 const Value *Op0 =
I.getOperand(0);
4611 Type *ValTy =
I.getType();
4616 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
4620 unsigned NumValValues = ValValueVTs.
size();
4623 if (!NumValValues) {
4632 for (
unsigned i = LinearIndex; i != LinearIndex + NumValValues; ++i)
4633 Values[i - LinearIndex] =
4642void SelectionDAGBuilder::visitGetElementPtr(
const User &
I) {
4643 Value *Op0 =
I.getOperand(0);
4649 auto &TLI =
DAG.getTargetLoweringInfo();
4654 bool IsVectorGEP =
I.getType()->isVectorTy();
4655 ElementCount VectorElementCount =
4661 const Value *
Idx = GTI.getOperand();
4662 if (StructType *StTy = GTI.getStructTypeOrNull()) {
4667 DAG.getDataLayout().getStructLayout(StTy)->getElementOffset(
Field);
4677 N =
DAG.getMemBasePlusOffset(
4678 N,
DAG.getConstant(
Offset, dl,
N.getValueType()), dl, Flags);
4684 unsigned IdxSize =
DAG.getDataLayout().getIndexSizeInBits(AS);
4686 TypeSize ElementSize =
4687 GTI.getSequentialElementStride(
DAG.getDataLayout());
4692 bool ElementScalable = ElementSize.
isScalable();
4698 C =
C->getSplatValue();
4701 if (CI && CI->isZero())
4703 if (CI && !ElementScalable) {
4704 APInt Offs = ElementMul * CI->getValue().sextOrTrunc(IdxSize);
4707 if (
N.getValueType().isVector())
4708 OffsVal =
DAG.getConstant(
4711 OffsVal =
DAG.getConstant(Offs, dl, IdxTy);
4718 Flags.setNoUnsignedWrap(
true);
4721 OffsVal =
DAG.getSExtOrTrunc(OffsVal, dl,
N.getValueType());
4723 N =
DAG.getMemBasePlusOffset(
N, OffsVal, dl, Flags);
4731 if (
N.getValueType().isVector()) {
4733 VectorElementCount);
4734 IdxN =
DAG.getSplat(VT, dl, IdxN);
4738 N =
DAG.getSplat(VT, dl,
N);
4744 IdxN =
DAG.getSExtOrTrunc(IdxN, dl,
N.getValueType());
4746 SDNodeFlags ScaleFlags;
4755 if (ElementScalable) {
4756 EVT VScaleTy =
N.getValueType().getScalarType();
4757 SDValue VScale =
DAG.getNode(
4759 DAG.getConstant(ElementMul.getZExtValue(), dl, VScaleTy));
4760 if (
N.getValueType().isVector())
4761 VScale =
DAG.getSplatVector(
N.getValueType(), dl, VScale);
4762 IdxN =
DAG.getNode(
ISD::MUL, dl,
N.getValueType(), IdxN, VScale,
4767 if (ElementMul != 1) {
4768 if (ElementMul.isPowerOf2()) {
4769 unsigned Amt = ElementMul.logBase2();
4772 DAG.getShiftAmountConstant(Amt,
N.getValueType(), dl),
4775 SDValue Scale =
DAG.getConstant(ElementMul.getZExtValue(), dl,
4777 IdxN =
DAG.getNode(
ISD::MUL, dl,
N.getValueType(), IdxN, Scale,
4787 SDNodeFlags AddFlags;
4791 N =
DAG.getMemBasePlusOffset(
N, IdxN, dl, AddFlags);
4795 if (IsVectorGEP && !
N.getValueType().isVector()) {
4797 N =
DAG.getSplat(VT, dl,
N);
4808 N =
DAG.getPtrExtendInReg(
N, dl, PtrMemTy);
4813void SelectionDAGBuilder::visitAlloca(
const AllocaInst &
I) {
4820 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
4821 auto &
DL =
DAG.getDataLayout();
4822 TypeSize TySize =
I.getAllocationBaseSize(
DL);
4825 SDValue AllocSize =
getValue(
I.getArraySize());
4829 AllocSize =
DAG.getZExtOrTrunc(AllocSize, dl, IntPtr);
4831 AllocSize =
DAG.getNode(
4833 DAG.getZExtOrTrunc(
DAG.getTypeSize(dl, MVT::i64, TySize), dl, IntPtr));
4838 Align StackAlign =
DAG.getSubtarget().getFrameLowering()->getStackAlign();
4839 if (*Alignment <= StackAlign)
4847 DAG.getConstant(StackAlignMask, dl, IntPtr),
4852 DAG.getSignedConstant(~StackAlignMask, dl, IntPtr));
4856 DAG.getConstant(Alignment ?
Alignment->value() : 0, dl, IntPtr)};
4866 return I.getMetadata(LLVMContext::MD_range);
4871 if (std::optional<ConstantRange> CR = CB->getRange())
4875 return std::nullopt;
4880 return CB->getRetNoFPClass();
4884void SelectionDAGBuilder::visitLoad(
const LoadInst &
I) {
4886 return visitAtomicLoad(
I);
4888 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
4889 const Value *
SV =
I.getOperand(0);
4894 if (Arg->hasSwiftErrorAttr())
4895 return visitLoadFromSwiftError(
I);
4899 if (Alloca->isSwiftError())
4900 return visitLoadFromSwiftError(
I);
4906 Type *Ty =
I.getType();
4910 unsigned NumValues = ValueVTs.
size();
4915 AAMDNodes AAInfo =
I.getAAMetadata();
4918 bool isVolatile =
I.isVolatile();
4923 bool ConstantMemory =
false;
4930 BatchAA->pointsToConstantMemory(MemoryLocation(
4935 Root =
DAG.getEntryNode();
4936 ConstantMemory =
true;
4940 Root =
DAG.getRoot();
4951 unsigned ChainI = 0;
4952 for (
unsigned i = 0; i != NumValues; ++i, ++ChainI) {
4968 MachinePointerInfo PtrInfo =
4970 ? MachinePointerInfo(SV, Offsets[i].getKnownMinValue())
4971 : MachinePointerInfo();
4973 SDValue
A =
DAG.getObjectPtrOffset(dl, Ptr, Offsets[i]);
4975 DAG.getLoad(MemVTs[i], dl, Root,
A, PtrInfo, Alignment, MMOFlags,
4976 MMOMetadata(AAInfo, Ranges, MemCacheHint));
4977 Chains[ChainI] =
L.getValue(1);
4979 if (MemVTs[i] != ValueVTs[i])
4980 L =
DAG.getPtrExtOrTrunc(L, dl, ValueVTs[i]);
4982 if (MDNode *NoFPClassMD =
I.getMetadata(LLVMContext::MD_nofpclass)) {
4983 uint64_t FPTestInt =
4985 cast<ConstantAsMetadata>(NoFPClassMD->getOperand(0))->getValue())
4987 if (FPTestInt != fcNone) {
4988 SDValue FPTestConst =
4989 DAG.getTargetConstant(FPTestInt, SDLoc(), MVT::i32);
4990 L = DAG.getNode(ISD::AssertNoFPClass, dl, L.getValueType(), L,
4997 if (!ConstantMemory) {
5003 PendingLoads.push_back(Chain);
5007 DAG.getVTList(ValueVTs),
Values));
5010void SelectionDAGBuilder::visitStoreToSwiftError(
const StoreInst &
I) {
5011 assert(
DAG.getTargetLoweringInfo().supportSwiftError() &&
5012 "call visitStoreToSwiftError when backend supports swifterror");
5015 SmallVector<uint64_t, 4>
Offsets;
5016 const Value *SrcV =
I.getOperand(0);
5018 SrcV->
getType(), ValueVTs,
nullptr, &Offsets, 0);
5019 assert(ValueVTs.
size() == 1 && Offsets[0] == 0 &&
5020 "expect a single EVT for swifterror");
5029 SDValue(Src.getNode(), Src.getResNo()));
5030 DAG.setRoot(CopyNode);
5033void SelectionDAGBuilder::visitLoadFromSwiftError(
const LoadInst &
I) {
5034 assert(
DAG.getTargetLoweringInfo().supportSwiftError() &&
5035 "call visitLoadFromSwiftError when backend supports swifterror");
5038 !
I.hasMetadata(LLVMContext::MD_nontemporal) &&
5039 !
I.hasMetadata(LLVMContext::MD_invariant_load) &&
5040 "Support volatile, non temporal, invariant for load_from_swift_error");
5042 const Value *
SV =
I.getOperand(0);
5043 Type *Ty =
I.getType();
5046 !
BatchAA->pointsToConstantMemory(MemoryLocation(
5048 I.getAAMetadata()))) &&
5049 "load_from_swift_error should not be constant memory");
5052 SmallVector<uint64_t, 4>
Offsets;
5054 ValueVTs,
nullptr, &Offsets, 0);
5055 assert(ValueVTs.
size() == 1 && Offsets[0] == 0 &&
5056 "expect a single EVT for swifterror");
5059 SDValue
L =
DAG.getCopyFromReg(
5066void SelectionDAGBuilder::visitStore(
const StoreInst &
I) {
5068 return visitAtomicStore(
I);
5070 const Value *SrcV =
I.getOperand(0);
5071 const Value *PtrV =
I.getOperand(1);
5073 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
5078 if (Arg->hasSwiftErrorAttr())
5079 return visitStoreToSwiftError(
I);
5083 if (Alloca->isSwiftError())
5084 return visitStoreToSwiftError(
I);
5091 SrcV->
getType(), ValueVTs, &MemVTs, &Offsets);
5092 unsigned NumValues = ValueVTs.
size();
5106 AAMDNodes AAInfo =
I.getAAMetadata();
5107 const MDNode *MemCacheHint =
5112 unsigned ChainI = 0;
5113 for (
unsigned i = 0; i != NumValues; ++i, ++ChainI) {
5123 MachinePointerInfo PtrInfo =
5125 ? MachinePointerInfo(PtrV, Offsets[i].getKnownMinValue())
5126 : MachinePointerInfo();
5128 SDValue
Add =
DAG.getObjectPtrOffset(dl, Ptr, Offsets[i]);
5129 SDValue Val = SDValue(Src.getNode(), Src.getResNo() + i);
5130 if (MemVTs[i] != ValueVTs[i])
5131 Val =
DAG.getPtrExtOrTrunc(Val, dl, MemVTs[i]);
5133 DAG.getStore(Root, dl, Val,
Add, PtrInfo, Alignment, MMOFlags,
5134 MMOMetadata(AAInfo,
nullptr, MemCacheHint));
5135 Chains[ChainI] = St;
5141 DAG.setRoot(StoreNode);
5144void SelectionDAGBuilder::visitMaskedStore(
const CallInst &
I,
5145 bool IsCompressing) {
5148 Value *Src0Operand =
I.getArgOperand(0);
5149 Value *PtrOperand =
I.getArgOperand(1);
5150 Value *MaskOperand =
I.getArgOperand(2);
5153 SDValue Ptr =
getValue(PtrOperand);
5158 EVT VT =
Src0.getValueType();
5160 const auto &TLI =
DAG.getTargetLoweringInfo();
5164 if (
I.hasMetadata(LLVMContext::MD_nontemporal))
5169 MachineMemOperand *MMO =
DAG.getMachineFunction().getMachineMemOperand(
5170 MachinePointerInfo(PtrOperand), MMOFlags,
5172 MMOMetadata(
I.getAAMetadata(),
nullptr, MemCacheHint));
5175 !IsCompressing &&
TTI->hasConditionalLoadStoreForType(
5176 I.getArgOperand(0)->getType(),
true)
5182 DAG.setRoot(StoreNode);
5212 C =
C->getSplatValue();
5226 if (!
GEP ||
GEP->getParent() != CurBB)
5229 if (
GEP->getNumOperands() != 2)
5232 const Value *BasePtr =
GEP->getPointerOperand();
5233 const Value *IndexVal =
GEP->getOperand(
GEP->getNumOperands() - 1);
5239 TypeSize ScaleVal =
DL.getTypeAllocSize(
GEP->getResultElementType());
5244 if (ScaleVal != 1 &&
5256void SelectionDAGBuilder::visitMaskedScatter(
const CallInst &
I) {
5260 const Value *Ptr =
I.getArgOperand(1);
5263 EVT VT =
Src0.getValueType();
5265 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
5274 MachineMemOperand *MMO =
DAG.getMachineFunction().getMachineMemOperand(
5284 EVT IdxVT =
Index.getValueType();
5292 SDValue Scatter =
DAG.getMaskedScatter(
DAG.getVTList(MVT::Other), VT, sdl,
5294 DAG.setRoot(Scatter);
5298void SelectionDAGBuilder::visitMaskedLoad(
const CallInst &
I,
bool IsExpanding) {
5301 Value *PtrOperand =
I.getArgOperand(0);
5302 Value *MaskOperand =
I.getArgOperand(1);
5303 Value *Src0Operand =
I.getArgOperand(2);
5306 SDValue Ptr =
getValue(PtrOperand);
5311 EVT VT =
Src0.getValueType();
5312 AAMDNodes AAInfo =
I.getAAMetadata();
5320 SDValue InChain = AddToChain ?
DAG.getRoot() :
DAG.getEntryNode();
5322 const auto &TLI =
DAG.getTargetLoweringInfo();
5326 if (
I.hasMetadata(LLVMContext::MD_nontemporal))
5328 if (
I.hasMetadata(LLVMContext::MD_invariant_load))
5331 MachineMemOperand *MMO =
DAG.getMachineFunction().getMachineMemOperand(
5332 MachinePointerInfo(PtrOperand), MMOFlags,
5334 MMOMetadata(AAInfo, Ranges, MemCacheHint));
5341 TTI->hasConditionalLoadStoreForType(Src0Operand->
getType(),
5346 DAG.getMaskedLoad(VT, sdl, InChain, Ptr,
Offset, Mask, Src0, VT, MMO,
5353void SelectionDAGBuilder::visitSpeculativeLoad(
const CallInst &
I) {
5355 Value *PtrOperand =
I.getArgOperand(0);
5358 SDValue Ptr =
getValue(PtrOperand);
5360 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
5363 AAMDNodes AAInfo =
I.getAAMetadata();
5365 SDValue InChain =
DAG.getRoot();
5371 if (
I.hasMetadata(LLVMContext::MD_nontemporal))
5373 if (
I.hasMetadata(LLVMContext::MD_invariant_load))
5376 MachineMemOperand *MMO =
DAG.getMachineFunction().getMachineMemOperand(
5377 MachinePointerInfo(PtrOperand), MMOFlags,
5380 SDValue
Load =
DAG.getLoad(VT, sdl, InChain, Ptr, MMO);
5385void SelectionDAGBuilder::visitMaskedGather(
const CallInst &
I) {
5389 const Value *Ptr =
I.getArgOperand(0);
5393 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
5399 SDValue Root =
DAG.getRoot();
5406 MachineMemOperand *MMO =
DAG.getMachineFunction().getMachineMemOperand(
5409 MMOMetadata(
I.getAAMetadata(), Ranges));
5418 EVT IdxVT =
Index.getValueType();
5427 DAG.getMaskedGather(
DAG.getVTList(VT, MVT::Other), VT, sdl,
Ops, MMO,
5443 SDVTList VTs =
DAG.getVTList(MemVT, MVT::i1, MVT::Other);
5445 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
5451 MachinePointerInfo(
I.getPointerOperand()), Flags, MemVT.
getStoreSize(),
5452 I.getAlign(), MMOMetadata(AAMDNodes(),
nullptr, MemCacheHint),
5453 SSID, SuccessOrdering, FailureOrdering);
5456 dl, MemVT, VTs, InChain,
5461 SDValue OutChain =
L.getValue(2);
5464 DAG.setRoot(OutChain);
5467void SelectionDAGBuilder::visitAtomicRMW(
const AtomicRMWInst &
I) {
5470 switch (
I.getOperation()) {
5518 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
5524 MachinePointerInfo(
I.getPointerOperand()), Flags, MemVT.
getStoreSize(),
5525 I.getAlign(), MMOMetadata(AAMDNodes(),
nullptr, MemCacheHint),
5529 DAG.getAtomic(NT, dl, MemVT, InChain,
5533 SDValue OutChain =
L.getValue(1);
5536 DAG.setRoot(OutChain);
5539void SelectionDAGBuilder::visitFence(
const FenceInst &
I) {
5541 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
5544 Ops[1] =
DAG.getTargetConstant((
unsigned)
I.getOrdering(), dl,
5546 Ops[2] =
DAG.getTargetConstant(
I.getSyncScopeID(), dl,
5553void SelectionDAGBuilder::visitAtomicLoad(
const LoadInst &
I) {
5560 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
5571 MachineMemOperand *MMO =
DAG.getMachineFunction().getMachineMemOperand(
5572 MachinePointerInfo(
I.getPointerOperand()), Flags, MemVT.
getStoreSize(),
5573 I.getAlign(), MMOMetadata(AAMDNodes(), Ranges, MemCacheHint), SSID,
5578 SDValue Ptr =
getValue(
I.getPointerOperand());
5582 SDValue OutChain =
L.getValue(1);
5584 L =
DAG.getPtrExtOrTrunc(L, dl, VT);
5587 DAG.setRoot(OutChain);
5590void SelectionDAGBuilder::visitAtomicStore(
const StoreInst &
I) {
5598 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
5608 const MDNode *MemCacheHint =
5611 MachinePointerInfo(
I.getPointerOperand()), Flags, MemVT.
getStoreSize(),
5612 I.getAlign(), MMOMetadata(AAMDNodes(),
nullptr, MemCacheHint),
5615 SDValue Val =
getValue(
I.getValueOperand());
5617 Val =
DAG.getPtrExtOrTrunc(Val, dl, MemVT);
5618 SDValue Ptr =
getValue(
I.getPointerOperand());
5624 DAG.setRoot(OutChain);
5632std::pair<bool, bool>
5633SelectionDAGBuilder::getTargetIntrinsicCallProperties(
const CallBase &
I) {
5635 bool HasChain = !
F->doesNotAccessMemory();
5637 HasChain &&
F->onlyReadsMemory() &&
F->willReturn() &&
F->doesNotThrow();
5639 return {HasChain, OnlyLoad};
5643 const CallBase &
I,
bool HasChain,
bool OnlyLoad,
5645 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
5652 Ops.push_back(
DAG.getRoot());
5665 for (
unsigned i = 0, e =
I.arg_size(); i != e; ++i) {
5666 const Value *Arg =
I.getArgOperand(i);
5667 if (!
I.paramHasAttr(i, Attribute::ImmArg)) {
5675 assert(CI->getBitWidth() <= 64 &&
5676 "large intrinsic immediates not handled");
5677 Ops.push_back(
DAG.getTargetConstant(*CI, SDLoc(), VT));
5684 if (std::optional<OperandBundleUse> Bundle =
5686 auto *Sym = Bundle->Inputs[0].get();
5689 Ops.push_back(SDSym);
5692 if (std::optional<OperandBundleUse> Bundle =
5694 Value *Token = Bundle->Inputs[0].get();
5695 SDValue ConvControlToken =
getValue(Token);
5696 assert(
Ops.back().getValueType() != MVT::Glue &&
5697 "Did not expect another glue node here.");
5700 Ops.push_back(ConvControlToken);
5708 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
5716 return DAG.getVTList(ValueVTs);
5720SDValue SelectionDAGBuilder::getTargetNonMemIntrinsicNode(
5736 SDValue Chain =
Result.getValue(
Result.getNode()->getNumValues() - 1);
5743 if (
I.getType()->isVoidTy())
5758void SelectionDAGBuilder::visitTargetIntrinsic(
const CallInst &
I,
5760 auto [HasChain, OnlyLoad] = getTargetIntrinsicCallProperties(
I);
5763 if (!
DAG.getMachineFunction().getSubtarget().isIntrinsicSupported(
5766 DAG.getContext()->diagnose(DiagnosticInfoUnsupportedTargetIntrinsic(
5767 *
I.getFunction(), IntrinsicID,
DL.getDebugLoc()));
5772 if (HasChain && !OnlyLoad)
5781 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
5784 TargetLowering::IntrinsicInfo *
Info = !Infos.
empty() ? &Infos[0] :
nullptr;
5787 getTargetIntrinsicOperands(
I, HasChain, OnlyLoad, Info);
5788 SDVTList VTs = getTargetIntrinsicVTList(
I, HasChain);
5793 Flags.copyFMF(*FPMO);
5794 SelectionDAG::FlagInserter FlagsInserter(
DAG, Flags);
5801 if (!Infos.
empty()) {
5806 for (
const auto &Info : Infos) {
5809 MachinePointerInfo MPI;
5811 MPI = MachinePointerInfo(
Info.ptrVal,
Info.offset);
5812 else if (
Info.fallbackAddressSpace)
5813 MPI = MachinePointerInfo(*
Info.fallbackAddressSpace);
5814 EVT MemVT =
Info.memVT;
5816 if (
Size.hasValue() && !
Size.getValue())
5820 MPI,
Info.flags,
Size, Alignment,
I.getAAMetadata(),
Info.ssid,
5828 Result = getTargetNonMemIntrinsicNode(*
I.getType(), HasChain,
Ops, VTs);
5831 Result = handleTargetIntrinsicRet(
I, HasChain, OnlyLoad, Result);
5888 SDValue TwoToFractionalPartOfX;
5965 if (
Op.getValueType() == MVT::f32 &&
5989 if (
Op.getValueType() == MVT::f32 &&
6088 if (
Op.getValueType() == MVT::f32 &&
6172 return DAG.
getNode(
ISD::FADD, dl, MVT::f32, LogOfExponent, Log2ofMantissa);
6185 if (
Op.getValueType() == MVT::f32 &&
6262 return DAG.
getNode(
ISD::FADD, dl, MVT::f32, LogOfExponent, Log10ofMantissa);
6273 if (
Op.getValueType() == MVT::f32 &&
6286 bool IsExp10 =
false;
6287 if (
LHS.getValueType() == MVT::f32 &&
RHS.getValueType() == MVT::f32 &&
6291 IsExp10 = LHSC->isExactlyValue(Ten);
6318 unsigned Val = RHSC->getSExtValue();
6347 CurSquare, CurSquare);
6352 if (RHSC->getSExtValue() < 0)
6366 EVT VT =
LHS.getValueType();
6389 if ((ScaleInt > 0 || (Saturating &&
Signed)) &&
6393 Opcode, VT, ScaleInt);
6428 switch (
N.getOpcode()) {
6432 Op.getValueType().getSizeInBits());
6457bool SelectionDAGBuilder::EmitFuncArgumentDbgValue(
6465 const TargetInstrInfo *
TII =
DAG.getSubtarget().getInstrInfo();
6469 auto MakeVRegDbgValue = [&](
Register Reg, DIExpression *FragExpr,
6474 auto &Inst =
TII->get(TargetOpcode::DBG_INSTR_REF);
6481 auto *NewDIExpr = FragExpr;
6488 return BuildMI(MF,
DL, Inst,
false, MOs, Variable, NewDIExpr);
6491 auto &Inst =
TII->get(TargetOpcode::DBG_VALUE);
6492 return BuildMI(MF,
DL, Inst, Indirect,
Reg, Variable, FragExpr);
6496 if (Kind == FuncArgumentDbgValueKind::Value) {
6501 if (!IsInEntryBlock)
6517 bool VariableIsFunctionInputArg =
Variable->isParameter() &&
6518 !
DL->getInlinedAt();
6520 if (!IsInPrologue && !VariableIsFunctionInputArg)
6554 if (VariableIsFunctionInputArg) {
6556 if (ArgNo >=
FuncInfo.DescribedArgs.size())
6557 FuncInfo.DescribedArgs.resize(ArgNo + 1,
false);
6558 else if (!IsInPrologue &&
FuncInfo.DescribedArgs.test(ArgNo))
6559 return !NodeMap[
V].getNode();
6564 bool IsIndirect =
false;
6565 std::optional<MachineOperand>
Op;
6567 int FI =
FuncInfo.getArgumentFrameIndex(Arg);
6568 if (FI != std::numeric_limits<int>::max())
6572 if (!
Op &&
N.getNode()) {
6575 if (ArgRegsAndSizes.
size() == 1)
6576 Reg = ArgRegsAndSizes.
front().first;
6579 MachineRegisterInfo &RegInfo = MF.
getRegInfo();
6586 IsIndirect =
Kind != FuncArgumentDbgValueKind::Value;
6590 if (!
Op &&
N.getNode()) {
6594 if (FrameIndexSDNode *FINode =
6601 auto splitMultiRegDbgValue =
6614 uint64_t ExprFragmentSizeInBits = ExprFragmentInfo->SizeInBits;
6617 if (
Offset >= ExprFragmentSizeInBits)
6621 if (
Offset + RegFragmentSizeInBits > ExprFragmentSizeInBits) {
6622 RegFragmentSizeInBits = ExprFragmentSizeInBits -
Offset;
6627 Expr,
Offset, RegFragmentSizeInBits);
6631 if (!FragmentExpr) {
6632 SDDbgValue *SDV =
DAG.getConstantDbgValue(
6634 DAG.AddDbgValue(SDV,
false);
6637 MachineInstr *NewMI = MakeVRegDbgValue(
6638 Reg, *FragmentExpr, Kind != FuncArgumentDbgValueKind::Value);
6639 FuncInfo.ArgDbgValues.push_back(NewMI);
6648 if (VMI !=
FuncInfo.ValueMap.end()) {
6649 const auto &TLI =
DAG.getTargetLoweringInfo();
6650 RegsForValue RFV(
V->getContext(), TLI,
DAG.getDataLayout(), VMI->second,
6651 V->getType(), std::nullopt);
6652 if (RFV.occupiesMultipleRegs())
6653 return splitMultiRegDbgValue(RFV.getRegsAndSizes());
6656 IsIndirect =
Kind != FuncArgumentDbgValueKind::Value;
6657 }
else if (ArgRegsAndSizes.
size() > 1) {
6660 return splitMultiRegDbgValue(ArgRegsAndSizes);
6668 "Expected inlined-at fields to agree");
6669 MachineInstr *NewMI =
nullptr;
6672 NewMI = MakeVRegDbgValue(
Op->getReg(), Expr, IsIndirect);
6674 NewMI =
BuildMI(MF,
DL,
TII->get(TargetOpcode::DBG_VALUE),
true, *
Op,
6678 FuncInfo.ArgDbgValues.push_back(NewMI);
6687 unsigned DbgSDNodeOrder) {
6699 return DAG.getFrameIndexDbgValue(Variable, Expr, FISDN->getIndex(),
6700 false, dl, DbgSDNodeOrder);
6702 return DAG.getDbgValue(Variable, Expr,
N.getNode(),
N.getResNo(),
6703 false, dl, DbgSDNodeOrder);
6708 case Intrinsic::smul_fix:
6710 case Intrinsic::umul_fix:
6712 case Intrinsic::smul_fix_sat:
6714 case Intrinsic::umul_fix_sat:
6716 case Intrinsic::sdiv_fix:
6718 case Intrinsic::udiv_fix:
6720 case Intrinsic::sdiv_fix_sat:
6722 case Intrinsic::udiv_fix_sat:
6735 "expected call_preallocated_setup Value");
6736 for (
const auto *U : PreallocatedSetup->
users()) {
6738 const Function *Fn = UseCall->getCalledFunction();
6739 if (!Fn || Fn->
getIntrinsicID() != Intrinsic::call_preallocated_arg) {
6749bool SelectionDAGBuilder::visitEntryValueDbgValue(
6759 auto ArgIt =
FuncInfo.ValueMap.find(Arg);
6760 if (ArgIt ==
FuncInfo.ValueMap.end()) {
6762 dbgs() <<
"Dropping dbg.value: expression is entry_value but "
6763 "couldn't find an associated register for the Argument\n");
6766 Register ArgVReg = ArgIt->getSecond();
6768 for (
auto [PhysReg, VirtReg] :
FuncInfo.RegInfo->liveins())
6769 if (ArgVReg == VirtReg || ArgVReg == PhysReg) {
6770 SDDbgValue *SDV =
DAG.getVRegDbgValue(
6771 Variable, Expr, PhysReg,
false , DbgLoc, SDNodeOrder);
6772 DAG.AddDbgValue(SDV,
false );
6775 LLVM_DEBUG(
dbgs() <<
"Dropping dbg.value: expression is entry_value but "
6776 "couldn't find a physical register\n");
6781void SelectionDAGBuilder::visitConvergenceControl(
const CallInst &
I,
6784 switch (Intrinsic) {
6785 case Intrinsic::experimental_convergence_anchor:
6788 case Intrinsic::experimental_convergence_entry:
6791 case Intrinsic::experimental_convergence_loop: {
6793 auto *Token = Bundle->Inputs[0].get();
6801void SelectionDAGBuilder::visitVectorHistogram(
const CallInst &
I,
6802 unsigned IntrinsicID) {
6805 assert(IntrinsicID == Intrinsic::experimental_vector_histogram_add &&
6806 "Tried to lower unsupported histogram type");
6809 SDValue Inc =
getValue(
I.getOperand(1));
6812 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
6818 SDValue Root =
DAG.getRoot();
6827 MachineMemOperand *MMO =
DAG.getMachineFunction().getMachineMemOperand(
6828 MachinePointerInfo(AS),
6831 MMOMetadata(
I.getAAMetadata(), Ranges));
6840 EVT IdxVT =
Index.getValueType();
6851 SDValue
ID =
DAG.getTargetConstant(IntrinsicID, sdl, MVT::i32);
6854 SDValue Histogram =
DAG.getMaskedHistogram(
DAG.getVTList(MVT::Other), VT, sdl,
6858 DAG.setRoot(Histogram);
6861void SelectionDAGBuilder::visitVectorExtractLastActive(
const CallInst &
I,
6863 assert(Intrinsic == Intrinsic::experimental_vector_extract_last_active &&
6864 "Tried lowering invalid vector extract last");
6866 const DataLayout &Layout =
DAG.getDataLayout();
6870 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
6880 EVT BoolVT =
Mask.getValueType().getScalarType();
6882 Result =
DAG.getSelect(sdl, ResVT, AnyActive, Result, PassThru);
6889void SelectionDAGBuilder::visitIntrinsicCall(
const CallInst &
I,
6891 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
6898 Flags.copyFMF(*FPOp);
6900 switch (Intrinsic) {
6903 visitTargetIntrinsic(
I, Intrinsic);
6905 case Intrinsic::vscale: {
6910 case Intrinsic::vastart: visitVAStart(
I);
return;
6911 case Intrinsic::vaend: visitVAEnd(
I);
return;
6912 case Intrinsic::vacopy: visitVACopy(
I);
return;
6913 case Intrinsic::returnaddress:
6918 case Intrinsic::addressofreturnaddress:
6923 case Intrinsic::sponentry:
6928 case Intrinsic::frameaddress:
6933 case Intrinsic::read_volatile_register:
6934 case Intrinsic::read_register: {
6935 Value *
Reg =
I.getArgOperand(0);
6941 DAG.getVTList(VT, MVT::Other), Chain,
RegName);
6946 case Intrinsic::write_register: {
6947 Value *
Reg =
I.getArgOperand(0);
6948 Value *RegValue =
I.getArgOperand(1);
6956 case Intrinsic::write_volatile_register: {
6957 Value *
Reg =
I.getArgOperand(0);
6958 Value *RegValue =
I.getArgOperand(1);
6975 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
6976 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(PhysReg);
6977 MVT RegVT = *TRI->legalclasstypes_begin(*RC);
6978 DAG.setRoot(DAG.getNode(ISD::FAKE_USE, sdl, MVT::Other,
6979 {WriteChain, DAG.getRegister(PhysReg, RegVT)}));
6981 DAG.setRoot(WriteChain);
6985 case Intrinsic::memcpy:
6986 case Intrinsic::memcpy_inline: {
6988 SDValue Dst =
getValue(
I.getArgOperand(0));
6989 SDValue Src =
getValue(
I.getArgOperand(1));
6992 "memcpy_inline needs constant size");
6994 Align DstAlign = MCI.getDestAlign().valueOrOne();
6995 Align SrcAlign = MCI.getSourceAlign().valueOrOne();
6996 bool isVol = MCI.isVolatile();
6998 SDValue MC =
DAG.getMemcpy(Root, sdl, Dst, Src,
Size, DstAlign, SrcAlign,
6999 isVol, MCI.isForceInlined(), &
I, std::nullopt,
7000 MachinePointerInfo(
I.getArgOperand(0)),
7001 MachinePointerInfo(
I.getArgOperand(1)),
7003 updateDAGForMaybeTailCall(MC);
7006 case Intrinsic::memset:
7007 case Intrinsic::memset_inline: {
7009 SDValue Dst =
getValue(
I.getArgOperand(0));
7010 SDValue Value =
getValue(
I.getArgOperand(1));
7013 "memset_inline needs constant size");
7015 Align DstAlign = MSII.getDestAlign().valueOrOne();
7016 bool isVol = MSII.isVolatile();
7018 SDValue MC =
DAG.getMemset(
7019 Root, sdl, Dst, Value,
Size, DstAlign, isVol, MSII.isForceInlined(),
7020 &
I, MachinePointerInfo(
I.getArgOperand(0)),
I.getAAMetadata());
7021 updateDAGForMaybeTailCall(MC);
7024 case Intrinsic::memmove: {
7026 SDValue Op1 =
getValue(
I.getArgOperand(0));
7027 SDValue Op2 =
getValue(
I.getArgOperand(1));
7028 SDValue Op3 =
getValue(
I.getArgOperand(2));
7030 Align DstAlign = MMI.getDestAlign().valueOrOne();
7031 Align SrcAlign = MMI.getSourceAlign().valueOrOne();
7032 bool isVol = MMI.isVolatile();
7034 SDValue MM =
DAG.getMemmove(
7035 Root, sdl, Op1, Op2, Op3, DstAlign, SrcAlign, isVol, &
I,
7037 MachinePointerInfo(
I.getArgOperand(0)),
7038 MachinePointerInfo(
I.getArgOperand(1)),
I.getAAMetadata(),
BatchAA);
7039 updateDAGForMaybeTailCall(MM);
7042 case Intrinsic::memcpy_element_unordered_atomic: {
7048 Type *LengthTy =
MI.getLength()->getType();
7049 unsigned ElemSz =
MI.getElementSizeInBytes();
7053 isTC, MachinePointerInfo(
MI.getRawDest()),
7054 MachinePointerInfo(
MI.getRawSource()));
7055 updateDAGForMaybeTailCall(MC);
7058 case Intrinsic::memmove_element_unordered_atomic: {
7064 Type *LengthTy =
MI.getLength()->getType();
7065 unsigned ElemSz =
MI.getElementSizeInBytes();
7069 isTC, MachinePointerInfo(
MI.getRawDest()),
7070 MachinePointerInfo(
MI.getRawSource()));
7071 updateDAGForMaybeTailCall(MC);
7074 case Intrinsic::memset_element_unordered_atomic: {
7080 Type *LengthTy =
MI.getLength()->getType();
7081 unsigned ElemSz =
MI.getElementSizeInBytes();
7085 isTC, MachinePointerInfo(
MI.getRawDest()));
7086 updateDAGForMaybeTailCall(MC);
7089 case Intrinsic::call_preallocated_setup: {
7091 SDValue SrcValue =
DAG.getSrcValue(PreallocatedCall);
7098 case Intrinsic::call_preallocated_arg: {
7100 SDValue SrcValue =
DAG.getSrcValue(PreallocatedCall);
7106 SDValue Res =
DAG.getNode(
7114 case Intrinsic::eh_typeid_for: {
7117 unsigned TypeID =
DAG.getMachineFunction().getTypeIDFor(GV);
7118 Res =
DAG.getConstant(
TypeID, sdl, MVT::i32);
7123 case Intrinsic::eh_return_i32:
7124 case Intrinsic::eh_return_i64:
7125 DAG.getMachineFunction().setCallsEHReturn(
true);
7132 case Intrinsic::eh_unwind_init:
7133 DAG.getMachineFunction().setCallsUnwindInit(
true);
7135 case Intrinsic::eh_dwarf_cfa:
7140 case Intrinsic::eh_sjlj_callsite: {
7142 assert(
FuncInfo.getCurrentCallSite() == 0 &&
"Overlapping call sites!");
7147 case Intrinsic::eh_sjlj_functioncontext: {
7149 MachineFrameInfo &MFI =
DAG.getMachineFunction().getFrameInfo();
7152 int FI =
FuncInfo.StaticAllocaMap[FnCtx];
7156 case Intrinsic::eh_sjlj_setjmp: {
7161 DAG.getVTList(MVT::i32, MVT::Other),
Ops);
7163 DAG.setRoot(
Op.getValue(1));
7166 case Intrinsic::eh_sjlj_longjmp:
7170 case Intrinsic::eh_sjlj_setup_dispatch:
7174 case Intrinsic::masked_gather:
7175 visitMaskedGather(
I);
7177 case Intrinsic::masked_load:
7180 case Intrinsic::masked_scatter:
7181 visitMaskedScatter(
I);
7183 case Intrinsic::masked_store:
7184 visitMaskedStore(
I);
7186 case Intrinsic::masked_expandload:
7187 visitMaskedLoad(
I,
true );
7189 case Intrinsic::masked_compressstore:
7190 visitMaskedStore(
I,
true );
7192 case Intrinsic::speculative_load:
7193 visitSpeculativeLoad(
I);
7195 case Intrinsic::powi:
7199 case Intrinsic::log:
7202 case Intrinsic::log2:
7206 case Intrinsic::log10:
7210 case Intrinsic::exp:
7213 case Intrinsic::exp2:
7217 case Intrinsic::pow:
7221 case Intrinsic::sqrt:
7222 case Intrinsic::fabs:
7223 case Intrinsic::sin:
7224 case Intrinsic::cos:
7225 case Intrinsic::tan:
7226 case Intrinsic::asin:
7227 case Intrinsic::acos:
7228 case Intrinsic::atan:
7229 case Intrinsic::sinh:
7230 case Intrinsic::cosh:
7231 case Intrinsic::tanh:
7232 case Intrinsic::exp10:
7233 case Intrinsic::floor:
7234 case Intrinsic::ceil:
7235 case Intrinsic::trunc:
7236 case Intrinsic::rint:
7237 case Intrinsic::nearbyint:
7238 case Intrinsic::round:
7239 case Intrinsic::roundeven:
7240 case Intrinsic::canonicalize: {
7243 switch (Intrinsic) {
7245 case Intrinsic::sqrt: Opcode =
ISD::FSQRT;
break;
7246 case Intrinsic::fabs: Opcode =
ISD::FABS;
break;
7247 case Intrinsic::sin: Opcode =
ISD::FSIN;
break;
7248 case Intrinsic::cos: Opcode =
ISD::FCOS;
break;
7249 case Intrinsic::tan: Opcode =
ISD::FTAN;
break;
7250 case Intrinsic::asin: Opcode =
ISD::FASIN;
break;
7251 case Intrinsic::acos: Opcode =
ISD::FACOS;
break;
7252 case Intrinsic::atan: Opcode =
ISD::FATAN;
break;
7253 case Intrinsic::sinh: Opcode =
ISD::FSINH;
break;
7254 case Intrinsic::cosh: Opcode =
ISD::FCOSH;
break;
7255 case Intrinsic::tanh: Opcode =
ISD::FTANH;
break;
7256 case Intrinsic::exp10: Opcode =
ISD::FEXP10;
break;
7257 case Intrinsic::floor: Opcode =
ISD::FFLOOR;
break;
7258 case Intrinsic::ceil: Opcode =
ISD::FCEIL;
break;
7259 case Intrinsic::trunc: Opcode =
ISD::FTRUNC;
break;
7260 case Intrinsic::rint: Opcode =
ISD::FRINT;
break;
7262 case Intrinsic::round: Opcode =
ISD::FROUND;
break;
7269 getValue(
I.getArgOperand(0)).getValueType(),
7273 case Intrinsic::atan2:
7275 getValue(
I.getArgOperand(0)).getValueType(),
7279 case Intrinsic::lround:
7280 case Intrinsic::llround:
7281 case Intrinsic::lrint:
7282 case Intrinsic::llrint: {
7285 switch (Intrinsic) {
7287 case Intrinsic::lround: Opcode =
ISD::LROUND;
break;
7289 case Intrinsic::lrint: Opcode =
ISD::LRINT;
break;
7290 case Intrinsic::llrint: Opcode =
ISD::LLRINT;
break;
7299 case Intrinsic::minnum:
7301 getValue(
I.getArgOperand(0)).getValueType(),
7305 case Intrinsic::maxnum:
7307 getValue(
I.getArgOperand(0)).getValueType(),
7311 case Intrinsic::minimum:
7313 getValue(
I.getArgOperand(0)).getValueType(),
7317 case Intrinsic::maximum:
7319 getValue(
I.getArgOperand(0)).getValueType(),
7323 case Intrinsic::minimumnum:
7325 getValue(
I.getArgOperand(0)).getValueType(),
7329 case Intrinsic::maximumnum:
7331 getValue(
I.getArgOperand(0)).getValueType(),
7335 case Intrinsic::copysign:
7337 getValue(
I.getArgOperand(0)).getValueType(),
7341 case Intrinsic::ldexp:
7343 getValue(
I.getArgOperand(0)).getValueType(),
7347 case Intrinsic::modf:
7348 case Intrinsic::sincos:
7349 case Intrinsic::sincospi:
7350 case Intrinsic::frexp: {
7352 switch (Intrinsic) {
7355 case Intrinsic::sincos:
7358 case Intrinsic::sincospi:
7361 case Intrinsic::modf:
7364 case Intrinsic::frexp:
7370 SDVTList VTs =
DAG.getVTList(ValueVTs);
7372 &
I,
DAG.getNode(Opcode, sdl, VTs,
getValue(
I.getArgOperand(0)), Flags));
7375 case Intrinsic::arithmetic_fence: {
7377 getValue(
I.getArgOperand(0)).getValueType(),
7381 case Intrinsic::fma:
7387#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
7388 case Intrinsic::INTRINSIC:
7389#include "llvm/IR/ConstrainedOps.def"
7392#define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID:
7393#include "llvm/IR/VPIntrinsics.def"
7396 case Intrinsic::fptrunc_round: {
7400 std::optional<RoundingMode> RoundMode =
7408 SelectionDAG::FlagInserter FlagsInserter(
DAG, Flags);
7413 DAG.getTargetConstant((
int)*RoundMode, sdl, MVT::i32));
7418 case Intrinsic::fmuladd: {
7422 getValue(
I.getArgOperand(0)).getValueType(),
7429 getValue(
I.getArgOperand(0)).getValueType(),
7435 SDValue
Mul =
DAG.getNode(
7445 case Intrinsic::fptosi_sat: {
7452 case Intrinsic::fptoui_sat: {
7459 case Intrinsic::convert_from_arbitrary_fp: {
7464 const fltSemantics *SrcSem =
7467 DAG.getContext()->emitError(
7468 "convert_from_arbitrary_fp: not implemented format '" + FormatStr +
7479 DAG.getTargetConstant(
static_cast<int>(SemEnum), sdl, MVT::i32);
7484 case Intrinsic::convert_to_arbitrary_fp: {
7489 const fltSemantics *DstSem =
7492 DAG.getContext()->emitError(
7493 "convert_to_arbitrary_fp: not implemented format '" + FormatStr +
7505 "Dynamic rounding mode should have been rejected by the verifier");
7510 SDValue FloatVal =
getValue(
I.getArgOperand(0));
7513 DAG.getTargetConstant(
static_cast<int>(SemEnum), sdl, MVT::i32);
7514 SDValue RoundConst =
7515 DAG.getTargetConstant(
static_cast<int>(*RoundMode), sdl, MVT::i32);
7516 SDValue SatConst =
DAG.getTargetConstant(Saturate, sdl, MVT::i32);
7518 SemConst, RoundConst, SatConst));
7521 case Intrinsic::set_rounding:
7527 case Intrinsic::is_fpclass: {
7528 const DataLayout DLayout =
DAG.getDataLayout();
7530 EVT ArgVT = TLI.
getValueType(DLayout,
I.getArgOperand(0)->getType());
7537 Flags.setNoFPExcept(
7538 !
F.getAttributes().hasFnAttr(llvm::Attribute::StrictFP));
7549 SDValue
Check =
DAG.getTargetConstant(
Test, sdl, MVT::i32);
7554 case Intrinsic::get_fpenv: {
7555 const DataLayout DLayout =
DAG.getDataLayout();
7557 Align TempAlign =
DAG.getEVTAlign(EnvVT);
7568 SDValue Temp =
DAG.CreateStackTemporary(EnvVT, TempAlign.
value());
7572 MachineMemOperand *MMO =
DAG.getMachineFunction().getMachineMemOperand(
7575 Chain =
DAG.getGetFPEnv(Chain, sdl, Temp, EnvVT, MMO);
7576 Res =
DAG.getLoad(EnvVT, sdl, Chain, Temp, MPI);
7582 case Intrinsic::set_fpenv: {
7583 SDValue Env =
getValue(
I.getArgOperand(0));
7585 Align TempAlign =
DAG.getEVTAlign(EnvVT);
7594 SDValue Temp =
DAG.CreateStackTemporary(EnvVT, TempAlign.
value());
7598 Chain =
DAG.getStore(Chain, sdl, Env, Temp, MPI, TempAlign,
7600 MachineMemOperand *MMO =
DAG.getMachineFunction().getMachineMemOperand(
7603 Chain =
DAG.getSetFPEnv(Chain, sdl, Temp, EnvVT, MMO);
7608 case Intrinsic::reset_fpenv:
7611 case Intrinsic::get_fpmode:
7620 case Intrinsic::set_fpmode:
7625 case Intrinsic::reset_fpmode: {
7630 case Intrinsic::pcmarker: {
7631 SDValue Tmp =
getValue(
I.getArgOperand(0));
7635 case Intrinsic::readcyclecounter: {
7638 DAG.getVTList(MVT::i64, MVT::Other),
Op);
7643 case Intrinsic::readsteadycounter: {
7646 DAG.getVTList(MVT::i64, MVT::Other),
Op);
7651 case Intrinsic::bitreverse:
7653 getValue(
I.getArgOperand(0)).getValueType(),
7656 case Intrinsic::bswap:
7658 getValue(
I.getArgOperand(0)).getValueType(),
7661 case Intrinsic::cttz: {
7662 SDValue Arg =
getValue(
I.getArgOperand(0));
7669 case Intrinsic::ctlz: {
7670 SDValue Arg =
getValue(
I.getArgOperand(0));
7677 case Intrinsic::ctpop: {
7678 SDValue Arg =
getValue(
I.getArgOperand(0));
7683 case Intrinsic::fshl:
7684 case Intrinsic::fshr: {
7685 bool IsFSHL =
Intrinsic == Intrinsic::fshl;
7689 EVT VT =
X.getValueType();
7700 case Intrinsic::clmul: {
7706 case Intrinsic::pext: {
7712 case Intrinsic::pdep: {
7718 case Intrinsic::smulh:
7719 case Intrinsic::umulh: {
7726 case Intrinsic::sadd_sat: {
7727 SDValue Op1 =
getValue(
I.getArgOperand(0));
7728 SDValue Op2 =
getValue(
I.getArgOperand(1));
7732 case Intrinsic::uadd_sat: {
7733 SDValue Op1 =
getValue(
I.getArgOperand(0));
7734 SDValue Op2 =
getValue(
I.getArgOperand(1));
7738 case Intrinsic::ssub_sat: {
7739 SDValue Op1 =
getValue(
I.getArgOperand(0));
7740 SDValue Op2 =
getValue(
I.getArgOperand(1));
7744 case Intrinsic::usub_sat: {
7745 SDValue Op1 =
getValue(
I.getArgOperand(0));
7746 SDValue Op2 =
getValue(
I.getArgOperand(1));
7750 case Intrinsic::sshl_sat:
7751 case Intrinsic::ushl_sat: {
7752 SDValue Op1 =
getValue(
I.getArgOperand(0));
7753 SDValue Op2 =
getValue(
I.getArgOperand(1));
7755 EVT ShiftTy =
DAG.getTargetLoweringInfo().getShiftAmountTy(
7760 if (!
I.getType()->isVectorTy() && Op2.
getValueType() != ShiftTy) {
7763 "Unexpected shift type");
7772 case Intrinsic::smul_fix:
7773 case Intrinsic::umul_fix:
7774 case Intrinsic::smul_fix_sat:
7775 case Intrinsic::umul_fix_sat: {
7776 SDValue Op1 =
getValue(
I.getArgOperand(0));
7777 SDValue Op2 =
getValue(
I.getArgOperand(1));
7778 SDValue Op3 =
getValue(
I.getArgOperand(2));
7783 case Intrinsic::sdiv_fix:
7784 case Intrinsic::udiv_fix:
7785 case Intrinsic::sdiv_fix_sat:
7786 case Intrinsic::udiv_fix_sat: {
7787 SDValue Op1 =
getValue(
I.getArgOperand(0));
7788 SDValue Op2 =
getValue(
I.getArgOperand(1));
7789 SDValue Op3 =
getValue(
I.getArgOperand(2));
7791 Op1, Op2, Op3,
DAG, TLI));
7794 case Intrinsic::smax: {
7795 SDValue Op1 =
getValue(
I.getArgOperand(0));
7796 SDValue Op2 =
getValue(
I.getArgOperand(1));
7800 case Intrinsic::smin: {
7801 SDValue Op1 =
getValue(
I.getArgOperand(0));
7802 SDValue Op2 =
getValue(
I.getArgOperand(1));
7806 case Intrinsic::umax: {
7807 SDValue Op1 =
getValue(
I.getArgOperand(0));
7808 SDValue Op2 =
getValue(
I.getArgOperand(1));
7812 case Intrinsic::umin: {
7813 SDValue Op1 =
getValue(
I.getArgOperand(0));
7814 SDValue Op2 =
getValue(
I.getArgOperand(1));
7818 case Intrinsic::abs: {
7819 SDValue Op1 =
getValue(
I.getArgOperand(0));
7825 case Intrinsic::scmp: {
7826 SDValue Op1 =
getValue(
I.getArgOperand(0));
7827 SDValue Op2 =
getValue(
I.getArgOperand(1));
7832 case Intrinsic::ucmp: {
7833 SDValue Op1 =
getValue(
I.getArgOperand(0));
7834 SDValue Op2 =
getValue(
I.getArgOperand(1));
7839 case Intrinsic::stackaddress:
7840 case Intrinsic::stacksave: {
7845 Res =
DAG.getNode(SDOpcode, sdl,
DAG.getVTList(VT, MVT::Other),
Op);
7850 case Intrinsic::stackrestore:
7854 case Intrinsic::get_dynamic_area_offset: {
7863 case Intrinsic::stackguard: {
7870 Res =
DAG.getPtrExtOrTrunc(Res, sdl, PtrTy);
7874 LLVMContext &Ctx = *
DAG.getContext();
7875 Ctx.
diagnose(DiagnosticInfoGeneric(
"unable to lower stackguard"));
7882 MachinePointerInfo(
Global, 0), Align,
7894 case Intrinsic::stackprotector: {
7899 SDValue Src, Chain =
getRoot();
7912 SDValue FIN =
DAG.getFrameIndex(FI, PtrTy);
7916 Chain, sdl, Src, FIN,
7923 case Intrinsic::objectsize:
7926 case Intrinsic::is_constant:
7929 case Intrinsic::annotation:
7930 case Intrinsic::ptr_annotation:
7931 case Intrinsic::launder_invariant_group:
7936 case Intrinsic::type_test:
7937 case Intrinsic::public_type_test:
7938 case Intrinsic::type_checked_load:
7939 case Intrinsic::type_checked_load_relative: {
7944 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
7947 " intrinsic must be lowered by the LowerTypeTests pass "
7948 "before code generation",
7957 case Intrinsic::assume:
7958 case Intrinsic::experimental_noalias_scope_decl:
7959 case Intrinsic::var_annotation:
7960 case Intrinsic::sideeffect:
7965 case Intrinsic::codeview_annotation: {
7976 case Intrinsic::init_trampoline: {
7984 Ops[4] =
DAG.getSrcValue(
I.getArgOperand(0));
7992 case Intrinsic::adjust_trampoline:
7997 case Intrinsic::gcroot: {
7998 assert(
DAG.getMachineFunction().getFunction().hasGC() &&
7999 "only valid in functions with gc specified, enforced by Verifier");
8001 const Value *Alloca =
I.getArgOperand(0)->stripPointerCasts();
8008 case Intrinsic::gcread:
8009 case Intrinsic::gcwrite:
8011 case Intrinsic::get_rounding:
8017 case Intrinsic::expect:
8018 case Intrinsic::expect_with_probability:
8024 case Intrinsic::ubsantrap:
8025 case Intrinsic::debugtrap:
8026 case Intrinsic::trap: {
8027 StringRef TrapFuncName =
8028 I.getAttributes().getFnAttr(
"trap-func-name").getValueAsString();
8029 if (TrapFuncName.
empty()) {
8030 switch (Intrinsic) {
8031 case Intrinsic::trap:
8034 case Intrinsic::debugtrap:
8037 case Intrinsic::ubsantrap:
8040 DAG.getTargetConstant(
8046 DAG.addNoMergeSiteInfo(
DAG.getRoot().getNode(),
8047 I.hasFnAttr(Attribute::NoMerge));
8051 if (Intrinsic == Intrinsic::ubsantrap) {
8052 Value *Arg =
I.getArgOperand(0);
8054 LibInfo->getExtAttrForI8Param(
false));
8057 TargetLowering::CallLoweringInfo CLI(
DAG);
8058 CLI.setDebugLoc(sdl).setChain(
getRoot()).setLibCallee(
8060 DAG.getExternalSymbol(TrapFuncName.
data(),
8063 CLI.NoMerge =
I.hasFnAttr(Attribute::NoMerge);
8069 case Intrinsic::allow_runtime_check:
8070 case Intrinsic::allow_ubsan_check:
8074 case Intrinsic::uadd_with_overflow:
8075 case Intrinsic::sadd_with_overflow:
8076 case Intrinsic::usub_with_overflow:
8077 case Intrinsic::ssub_with_overflow:
8078 case Intrinsic::umul_with_overflow:
8079 case Intrinsic::smul_with_overflow: {
8081 switch (Intrinsic) {
8083 case Intrinsic::uadd_with_overflow:
Op =
ISD::UADDO;
break;
8084 case Intrinsic::sadd_with_overflow:
Op =
ISD::SADDO;
break;
8085 case Intrinsic::usub_with_overflow:
Op =
ISD::USUBO;
break;
8086 case Intrinsic::ssub_with_overflow:
Op =
ISD::SSUBO;
break;
8087 case Intrinsic::umul_with_overflow:
Op =
ISD::UMULO;
break;
8088 case Intrinsic::smul_with_overflow:
Op =
ISD::SMULO;
break;
8090 SDValue Op1 =
getValue(
I.getArgOperand(0));
8091 SDValue Op2 =
getValue(
I.getArgOperand(1));
8096 SDVTList VTs =
DAG.getVTList(ResultVT, OverflowVT);
8100 case Intrinsic::prefetch: {
8112 SDValue
Result =
DAG.getMemIntrinsicNode(
8115 std::nullopt, Flags);
8121 DAG.setRoot(Result);
8124 case Intrinsic::lifetime_start:
8125 case Intrinsic::lifetime_end: {
8126 bool IsStart = (
Intrinsic == Intrinsic::lifetime_start);
8132 if (!LifetimeObject)
8137 auto SI =
FuncInfo.StaticAllocaMap.find(LifetimeObject);
8138 if (SI ==
FuncInfo.StaticAllocaMap.end())
8142 Res =
DAG.getLifetimeNode(IsStart, sdl,
getRoot(), FrameIndex);
8146 case Intrinsic::pseudoprobe: {
8154 case Intrinsic::invariant_start:
8159 case Intrinsic::invariant_end:
8162 case Intrinsic::clear_cache: {
8163 SDValue InputChain =
DAG.getRoot();
8164 SDValue StartVal =
getValue(
I.getArgOperand(0));
8165 SDValue EndVal =
getValue(
I.getArgOperand(1));
8167 {InputChain, StartVal, EndVal});
8172 case Intrinsic::donothing:
8173 case Intrinsic::seh_try_begin:
8174 case Intrinsic::seh_scope_begin:
8175 case Intrinsic::seh_try_end:
8176 case Intrinsic::seh_scope_end:
8179 case Intrinsic::experimental_stackmap:
8182 case Intrinsic::experimental_patchpoint_void:
8183 case Intrinsic::experimental_patchpoint:
8186 case Intrinsic::experimental_gc_statepoint:
8189 case Intrinsic::experimental_gc_result:
8192 case Intrinsic::experimental_gc_relocate:
8195 case Intrinsic::instrprof_cover:
8197 case Intrinsic::instrprof_increment:
8199 case Intrinsic::instrprof_timestamp:
8201 case Intrinsic::instrprof_value_profile:
8203 case Intrinsic::instrprof_mcdc_parameters:
8205 case Intrinsic::instrprof_mcdc_tvbitmap_update:
8207 case Intrinsic::localescape: {
8209 const TargetInstrInfo *
TII =
DAG.getSubtarget().getInstrInfo();
8213 for (
unsigned Idx = 0,
E =
I.arg_size(); Idx <
E; ++Idx) {
8219 "can only escape static allocas");
8224 TII->get(TargetOpcode::LOCAL_ESCAPE))
8232 case Intrinsic::localrecover: {
8240 unsigned(
Idx->getLimitedValue(std::numeric_limits<int>::max()));
8244 Value *
FP =
I.getArgOperand(1);
8250 SDValue OffsetSym =
DAG.getMCSymbol(FrameAllocSym, PtrVT);
8255 SDValue
Add =
DAG.getMemBasePlusOffset(FPVal, OffsetVal, sdl);
8261 case Intrinsic::fake_use: {
8262 Value *
V =
I.getArgOperand(0);
8267 auto FakeUseValue = [&]() -> SDValue {
8268 SDValue &
N = NodeMap[
V];
8281 if (!FakeUseValue || FakeUseValue.isUndef())
8284 Ops[1] = FakeUseValue;
8293 case Intrinsic::reloc_none: {
8298 DAG.getTargetExternalSymbol(
8304 case Intrinsic::cond_loop: {
8305 SDValue InputChain =
DAG.getRoot();
8314 case Intrinsic::eh_exceptionpointer:
8315 case Intrinsic::eh_exceptioncode: {
8321 SDValue
N =
DAG.getCopyFromReg(
DAG.getEntryNode(), sdl, VReg, PtrVT);
8322 if (Intrinsic == Intrinsic::eh_exceptioncode)
8323 N =
DAG.getZExtOrTrunc(
N, sdl, MVT::i32);
8327 case Intrinsic::xray_customevent: {
8330 const auto &Triple =
DAG.getTarget().getTargetTriple();
8331 if (!Triple.isAArch64(64) && Triple.getArch() !=
Triple::x86_64 &&
8338 SDValue LogEntryVal =
getValue(
I.getArgOperand(0));
8339 SDValue StrSizeVal =
getValue(
I.getArgOperand(1));
8340 SDVTList NodeTys =
DAG.getVTList(MVT::Other, MVT::Glue);
8342 Ops.push_back(LogEntryVal);
8343 Ops.push_back(StrSizeVal);
8344 Ops.push_back(Chain);
8350 MachineSDNode *MN =
DAG.getMachineNode(TargetOpcode::PATCHABLE_EVENT_CALL,
8352 SDValue patchableNode = SDValue(MN, 0);
8353 DAG.setRoot(patchableNode);
8357 case Intrinsic::xray_typedevent: {
8360 const auto &Triple =
DAG.getTarget().getTargetTriple();
8361 if (!Triple.isAArch64(64) && Triple.getArch() !=
Triple::x86_64 &&
8370 SDValue LogTypeId =
getValue(
I.getArgOperand(0));
8371 SDValue LogEntryVal =
getValue(
I.getArgOperand(1));
8372 SDValue StrSizeVal =
getValue(
I.getArgOperand(2));
8373 SDVTList NodeTys =
DAG.getVTList(MVT::Other, MVT::Glue);
8375 Ops.push_back(LogTypeId);
8376 Ops.push_back(LogEntryVal);
8377 Ops.push_back(StrSizeVal);
8378 Ops.push_back(Chain);
8384 MachineSDNode *MN =
DAG.getMachineNode(
8385 TargetOpcode::PATCHABLE_TYPED_EVENT_CALL, sdl, NodeTys,
Ops);
8386 SDValue patchableNode = SDValue(MN, 0);
8387 DAG.setRoot(patchableNode);
8391 case Intrinsic::experimental_deoptimize:
8394 case Intrinsic::stepvector:
8397 case Intrinsic::vector_reduce_fadd:
8398 case Intrinsic::vector_reduce_fmul:
8399 case Intrinsic::vector_reduce_add:
8400 case Intrinsic::vector_reduce_mul:
8401 case Intrinsic::vector_reduce_and:
8402 case Intrinsic::vector_reduce_or:
8403 case Intrinsic::vector_reduce_xor:
8404 case Intrinsic::vector_reduce_smax:
8405 case Intrinsic::vector_reduce_smin:
8406 case Intrinsic::vector_reduce_umax:
8407 case Intrinsic::vector_reduce_umin:
8408 case Intrinsic::vector_reduce_fmax:
8409 case Intrinsic::vector_reduce_fmin:
8410 case Intrinsic::vector_reduce_fmaximum:
8411 case Intrinsic::vector_reduce_fminimum:
8412 case Intrinsic::vector_reduce_fmaximumnum:
8413 case Intrinsic::vector_reduce_fminimumnum:
8414 visitVectorReduce(
I, Intrinsic);
8417 case Intrinsic::icall_branch_funnel: {
8423 I.getArgOperand(1),
Offset,
DAG.getDataLayout()));
8426 "llvm.icall.branch.funnel operand must be a GlobalValue");
8427 Ops.push_back(
DAG.getTargetGlobalAddress(
Base, sdl, MVT::i64, 0));
8429 struct BranchFunnelTarget {
8435 for (
unsigned Op = 1,
N =
I.arg_size();
Op !=
N;
Op += 2) {
8438 if (ElemBase !=
Base)
8440 "to the same GlobalValue");
8446 "llvm.icall.branch.funnel operand must be a GlobalValue");
8452 [](
const BranchFunnelTarget &
T1,
const BranchFunnelTarget &T2) {
8453 return T1.Offset < T2.Offset;
8456 for (
auto &
T : Targets) {
8457 Ops.push_back(
DAG.getTargetConstant(
T.Offset, sdl, MVT::i32));
8458 Ops.push_back(
T.Target);
8461 Ops.push_back(
DAG.getRoot());
8462 SDValue
N(
DAG.getMachineNode(TargetOpcode::ICALL_BRANCH_FUNNEL, sdl,
8471 case Intrinsic::wasm_landingpad_index:
8477 case Intrinsic::aarch64_settag:
8478 case Intrinsic::aarch64_settag_zero: {
8479 const SelectionDAGTargetInfo &TSI =
DAG.getSelectionDAGInfo();
8480 bool ZeroMemory =
Intrinsic == Intrinsic::aarch64_settag_zero;
8483 getValue(
I.getArgOperand(1)), MachinePointerInfo(
I.getArgOperand(0)),
8489 case Intrinsic::amdgcn_cs_chain: {
8494 Type *RetTy =
I.getType();
8504 for (
unsigned Idx : {2, 3, 1}) {
8505 TargetLowering::ArgListEntry Arg(
getValue(
I.getOperand(Idx)),
8507 Arg.setAttributes(&
I, Idx);
8508 Args.push_back(Arg);
8511 assert(Args[0].IsInReg &&
"SGPR args should be marked inreg");
8512 assert(!Args[1].IsInReg &&
"VGPR args should not be marked inreg");
8513 Args[2].IsInReg =
true;
8516 for (
unsigned Idx = 4;
Idx <
I.arg_size(); ++
Idx) {
8517 TargetLowering::ArgListEntry Arg(
getValue(
I.getOperand(Idx)),
8519 Arg.setAttributes(&
I, Idx);
8520 Args.push_back(Arg);
8523 TargetLowering::CallLoweringInfo CLI(
DAG);
8526 .setCallee(
CC, RetTy, Callee, std::move(Args))
8529 .setConvergent(
I.isConvergent());
8531 std::pair<SDValue, SDValue>
Result =
8535 "Should've lowered as tail call");
8540 case Intrinsic::amdgcn_call_whole_wave: {
8542 bool isTailCall =
I.isTailCall();
8545 for (
unsigned Idx = 1;
Idx <
I.arg_size(); ++
Idx) {
8546 TargetLowering::ArgListEntry Arg(
getValue(
I.getArgOperand(Idx)),
8547 I.getArgOperand(Idx)->getType());
8548 Arg.setAttributes(&
I, Idx);
8555 Args.push_back(Arg);
8558 SDValue ConvControlToken;
8560 auto *Token = Bundle->Inputs[0].get();
8561 ConvControlToken =
getValue(Token);
8564 TargetLowering::CallLoweringInfo CLI(
DAG);
8568 getValue(
I.getArgOperand(0)), std::move(Args))
8572 .setConvergent(
I.isConvergent())
8573 .setConvergenceControlToken(ConvControlToken);
8576 std::pair<SDValue, SDValue>
Result =
8579 if (
Result.first.getNode())
8583 case Intrinsic::ptrmask: {
8584 SDValue Ptr =
getValue(
I.getOperand(0));
8599 auto HighOnes =
DAG.getNode(
8600 ISD::SHL, sdl, PtrVT,
DAG.getAllOnesConstant(sdl, PtrVT),
8601 DAG.getShiftAmountConstant(
Mask.getValueType().getFixedSizeInBits(),
8604 DAG.getZExtOrTrunc(Mask, sdl, PtrVT), HighOnes);
8605 }
else if (
Mask.getValueType() != PtrVT)
8606 Mask =
DAG.getPtrExtOrTrunc(Mask, sdl, PtrVT);
8612 case Intrinsic::threadlocal_address: {
8616 case Intrinsic::get_active_lane_mask: {
8619 SDValue TripCount =
getValue(
I.getOperand(1));
8620 EVT ElementVT =
Index.getValueType();
8631 SDValue VectorIndex =
DAG.getSplat(VecTy, sdl, Index);
8632 SDValue VectorTripCount =
DAG.getSplat(VecTy, sdl, TripCount);
8633 SDValue VectorStep =
DAG.getStepVector(sdl, VecTy);
8634 SDValue VectorInduction =
DAG.getNode(
8636 SDValue SetCC =
DAG.getSetCC(sdl, CCVT, VectorInduction,
8641 case Intrinsic::mask_beforefirst: {
8647 case Intrinsic::experimental_get_vector_length: {
8649 "Expected positive VF");
8654 EVT CountVT =
Count.getValueType();
8657 visitTargetIntrinsic(
I, Intrinsic);
8666 if (CountVT.
bitsLT(VT)) {
8671 SDValue MaxEVL =
DAG.getElementCount(sdl, CountVT,
8681 case Intrinsic::vector_partial_reduce_add: {
8682 SDValue Acc =
getValue(
I.getOperand(0));
8686 Input,
DAG.getConstant(1, sdl,
Input.getValueType())));
8689 case Intrinsic::vector_partial_reduce_fadd: {
8692 Flags.copyFMF(*FPOp);
8693 SDValue Acc =
getValue(
I.getOperand(0));
8697 DAG.getConstantFP(1.0, sdl,
Input.getValueType()),
8701 case Intrinsic::experimental_cttz_elts: {
8703 EVT OpVT =
Op.getValueType();
8710 SDValue AllZero =
DAG.getConstant(0, sdl, OpVT);
8719 case Intrinsic::vector_insert: {
8720 SDValue Vec =
getValue(
I.getOperand(0));
8721 SDValue SubVec =
getValue(
I.getOperand(1));
8727 if (
Index.getValueType() != VectorIdxTy)
8728 Index =
DAG.getVectorIdxConstant(
Index->getAsZExtVal(), sdl);
8735 case Intrinsic::vector_extract: {
8736 SDValue Vec =
getValue(
I.getOperand(0));
8743 if (
Index.getValueType() != VectorIdxTy)
8744 Index =
DAG.getVectorIdxConstant(
Index->getAsZExtVal(), sdl);
8750 case Intrinsic::experimental_vector_match: {
8751 SDValue Op1 =
getValue(
I.getOperand(0));
8752 SDValue Op2 =
getValue(
I.getOperand(1));
8754 EVT ResVT =
Mask.getValueType();
8758 case Intrinsic::vector_reverse:
8759 visitVectorReverse(
I);
8761 case Intrinsic::vector_splice_left:
8762 case Intrinsic::vector_splice_right:
8763 visitVectorSplice(
I);
8765 case Intrinsic::callbr_landingpad:
8766 visitCallBrLandingPad(
I);
8768 case Intrinsic::vector_interleave2:
8769 visitVectorInterleave(
I, 2);
8771 case Intrinsic::vector_interleave3:
8772 visitVectorInterleave(
I, 3);
8774 case Intrinsic::vector_interleave4:
8775 visitVectorInterleave(
I, 4);
8777 case Intrinsic::vector_interleave5:
8778 visitVectorInterleave(
I, 5);
8780 case Intrinsic::vector_interleave6:
8781 visitVectorInterleave(
I, 6);
8783 case Intrinsic::vector_interleave7:
8784 visitVectorInterleave(
I, 7);
8786 case Intrinsic::vector_interleave8:
8787 visitVectorInterleave(
I, 8);
8789 case Intrinsic::vector_deinterleave2:
8790 visitVectorDeinterleave(
I, 2);
8792 case Intrinsic::vector_deinterleave3:
8793 visitVectorDeinterleave(
I, 3);
8795 case Intrinsic::vector_deinterleave4:
8796 visitVectorDeinterleave(
I, 4);
8798 case Intrinsic::vector_deinterleave5:
8799 visitVectorDeinterleave(
I, 5);
8801 case Intrinsic::vector_deinterleave6:
8802 visitVectorDeinterleave(
I, 6);
8804 case Intrinsic::vector_deinterleave7:
8805 visitVectorDeinterleave(
I, 7);
8807 case Intrinsic::vector_deinterleave8:
8808 visitVectorDeinterleave(
I, 8);
8810 case Intrinsic::vector_repeat: {
8811 SDValue Vec =
getValue(
I.getOperand(0));
8816 case Intrinsic::experimental_vector_compress:
8818 getValue(
I.getArgOperand(0)).getValueType(),
8823 case Intrinsic::experimental_convergence_anchor:
8824 case Intrinsic::experimental_convergence_entry:
8825 case Intrinsic::experimental_convergence_loop:
8826 visitConvergenceControl(
I, Intrinsic);
8828 case Intrinsic::experimental_vector_histogram_add: {
8829 visitVectorHistogram(
I, Intrinsic);
8832 case Intrinsic::experimental_vector_extract_last_active: {
8833 visitVectorExtractLastActive(
I, Intrinsic);
8836 case Intrinsic::loop_dependence_war_mask:
8841 DAG.getConstant(0, sdl, MVT::i64)));
8843 case Intrinsic::loop_dependence_raw_mask:
8848 DAG.getConstant(0, sdl, MVT::i64)));
8850 case Intrinsic::masked_udiv:
8856 case Intrinsic::masked_sdiv:
8862 case Intrinsic::masked_urem:
8868 case Intrinsic::masked_srem:
8877void SelectionDAGBuilder::pushFPOpOutChain(
SDValue Result,
8880 SDValue OutChain =
Result.getValue(1);
8893 PendingConstrainedFP.push_back(OutChain);
8896 PendingConstrainedFPStrict.push_back(OutChain);
8901void SelectionDAGBuilder::visitConstrainedFPIntrinsic(
8915 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
8917 SDVTList VTs =
DAG.getVTList(VT, MVT::Other);
8921 Flags.setNoFPExcept(
true);
8924 Flags.copyFMF(*FPOp);
8929#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
8930 case Intrinsic::INTRINSIC: \
8931 Opcode = ISD::STRICT_##DAGN; \
8933#include "llvm/IR/ConstrainedOps.def"
8934 case Intrinsic::experimental_constrained_fmuladd: {
8940 pushFPOpOutChain(
Mul, EB);
8963 if (
DAG.isKnownNeverNaN(Opers[1]) &&
DAG.isKnownNeverNaN(Opers[2]))
8970 SDValue
Result =
DAG.getNode(Opcode, sdl, VTs, Opers, Flags);
8971 pushFPOpOutChain(Result, EB);
8973 SDValue FPResult =
Result.getValue(0);
8978 std::optional<unsigned> ResOPC;
8980 case Intrinsic::vp_cttz_elts: {
8982 ResOPC = IsZeroPoison ? ISD::VP_CTTZ_ELTS_ZERO_POISON : ISD::VP_CTTZ_ELTS;
8985#define HELPER_MAP_VPID_TO_VPSD(VPID, VPSD) \
8986 case Intrinsic::VPID: \
8987 ResOPC = ISD::VPSD; \
8989#include "llvm/IR/VPIntrinsics.def"
8994 "Inconsistency: no SDNode available for this VPIntrinsic!");
8996 if (*ResOPC == ISD::VP_REDUCE_SEQ_FADD ||
8997 *ResOPC == ISD::VP_REDUCE_SEQ_FMUL) {
8999 return *ResOPC == ISD::VP_REDUCE_SEQ_FADD ? ISD::VP_REDUCE_FADD
9000 : ISD::VP_REDUCE_FMUL;
9006void SelectionDAGBuilder::visitVPLoad(
9021 SDValue InChain = AddToChain ?
DAG.getRoot() :
DAG.getEntryNode();
9022 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
9025 MachineMemOperand *MMO =
DAG.getMachineFunction().getMachineMemOperand(
9026 MachinePointerInfo(PtrOperand), MMOFlags,
9028 MMOMetadata(AAInfo, Ranges));
9029 LD =
DAG.getLoadVP(VT,
DL, InChain, OpValues[0], OpValues[1], OpValues[2],
9036void SelectionDAGBuilder::visitVPLoadFF(
9039 assert(OpValues.
size() == 3 &&
"Unexpected number of operands");
9052 SDValue InChain = AddToChain ?
DAG.getRoot() :
DAG.getEntryNode();
9053 MachineMemOperand *MMO =
DAG.getMachineFunction().getMachineMemOperand(
9056 MMOMetadata(AAInfo, Ranges));
9057 LD =
DAG.getLoadFFVP(VT,
DL, InChain, OpValues[0], OpValues[1], OpValues[2],
9062 setValue(&VPIntrin,
DAG.getMergeValues({LD.getValue(0), Trunc},
DL));
9065void SelectionDAGBuilder::visitVPGather(
9069 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
9081 MachineMemOperand *MMO =
DAG.getMachineFunction().getMachineMemOperand(
9083 *Alignment, MMOMetadata(AAInfo, Ranges));
9093 EVT IdxVT =
Index.getValueType();
9099 LD =
DAG.getGatherVP(
9100 DAG.getVTList(VT, MVT::Other), VT,
DL,
9101 {DAG.getRoot(), Base, Index, Scale, OpValues[1], OpValues[2]}, MMO,
9107void SelectionDAGBuilder::visitVPStore(
9111 EVT VT = OpValues[0].getValueType();
9117 SDValue Ptr = OpValues[1];
9119 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
9122 MachineMemOperand *MMO =
DAG.getMachineFunction().getMachineMemOperand(
9123 MachinePointerInfo(PtrOperand), MMOFlags,
9132void SelectionDAGBuilder::visitVPScatter(
9135 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
9137 EVT VT = OpValues[0].getValueType();
9147 MachineMemOperand *MMO =
DAG.getMachineFunction().getMachineMemOperand(
9149 *Alignment, AAInfo);
9159 EVT IdxVT =
Index.getValueType();
9165 ST =
DAG.getScatterVP(
DAG.getVTList(MVT::Other), VT,
DL,
9166 {getMemoryRoot(), OpValues[0], Base, Index, Scale,
9167 OpValues[2], OpValues[3]},
9173void SelectionDAGBuilder::visitVPStridedLoad(
9185 SDValue InChain = AddToChain ?
DAG.getRoot() :
DAG.getEntryNode();
9187 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
9190 MachineMemOperand *MMO =
DAG.getMachineFunction().getMachineMemOperand(
9192 *Alignment, MMOMetadata(AAInfo, Ranges));
9194 SDValue
LD =
DAG.getStridedLoadVP(VT,
DL, InChain, OpValues[0], OpValues[1],
9195 OpValues[2], OpValues[3], MMO,
9203void SelectionDAGBuilder::visitVPStridedStore(
9207 EVT VT = OpValues[0].getValueType();
9213 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
9216 MachineMemOperand *MMO =
DAG.getMachineFunction().getMachineMemOperand(
9218 *Alignment, AAInfo);
9220 SDValue
ST =
DAG.getStridedStoreVP(
9222 DAG.getPOISON(OpValues[1].getValueType()), OpValues[2], OpValues[3],
9230void SelectionDAGBuilder::visitVectorPredicationIntrinsic(
9238 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
9240 SDVTList VTs =
DAG.getVTList(ValueVTs);
9246 "Unexpected target EVL type");
9250 for (
unsigned I = 0;
I < VPIntrin.
arg_size(); ++
I) {
9252 if (
I == EVLParamPos)
9259 SDNodeFlags SDFlags;
9262 SDValue
Result =
DAG.getNode(Opcode,
DL, VTs, OpValues, SDFlags);
9267 visitVPLoad(VPIntrin, ValueVTs[0], OpValues);
9269 case ISD::VP_LOAD_FF:
9270 visitVPLoadFF(VPIntrin, ValueVTs[0], ValueVTs[1], OpValues);
9272 case ISD::VP_GATHER:
9273 visitVPGather(VPIntrin, ValueVTs[0], OpValues);
9275 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
9276 visitVPStridedLoad(VPIntrin, ValueVTs[0], OpValues);
9279 visitVPStore(VPIntrin, OpValues);
9281 case ISD::VP_SCATTER:
9282 visitVPScatter(VPIntrin, OpValues);
9284 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
9285 visitVPStridedStore(VPIntrin, OpValues);
9287 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
9288 case ISD::VP_CTTZ_ELTS: {
9290 DAG.getNode(Opcode,
DL, VTs, {OpValues[0], OpValues[2], OpValues[3]});
9306 BeginLabel =
nullptr;
9316 unsigned CallSiteIndex =
FuncInfo.getCurrentCallSite();
9317 if (CallSiteIndex) {
9347 assert(
II &&
"II should've been set");
9358std::pair<SDValue, SDValue>
9372 std::pair<SDValue, SDValue> Result = TLI.
LowerCallTo(CLI);
9375 "Non-null chain expected with non-tail call!");
9376 assert((Result.second.getNode() || !Result.first.getNode()) &&
9377 "Null value expected with tail call!");
9379 if (!Result.second.getNode()) {
9386 PendingExports.clear();
9388 DAG.setRoot(Result.second);
9406 if (!isMustTailCall &&
9407 Caller->getFnAttribute(
"disable-tail-calls").getValueAsBool())
9413 if (
DAG.hasSwiftErrorArg())
9422 bool isTailCall,
bool isMustTailCall,
9425 auto &
DL =
DAG.getDataLayout();
9432 const Value *SwiftErrorVal =
nullptr;
9439 const Value *V = *
I;
9442 if (V->getType()->isEmptyTy())
9447 Entry.setAttributes(&CB,
I - CB.
arg_begin());
9459 Args.push_back(Entry);
9470 Value *V = Bundle->Inputs[0];
9472 Entry.IsCFGuardTarget =
true;
9473 Args.push_back(Entry);
9486 "Target doesn't support calls with kcfi operand bundles.");
9494 auto *Token = Bundle->Inputs[0].get();
9495 ConvControlToken =
getValue(Token);
9506 .
setCallee(RetTy, FTy, Callee, std::move(Args), CB)
9519 "This target doesn't support calls with ptrauth operand bundles.");
9523 std::pair<SDValue, SDValue> Result =
lowerInvokable(CLI, EHPadBB);
9525 if (Result.first.getNode()) {
9540 DAG.setRoot(CopyNode);
9556 LoadTy, Builder.DAG.getDataLayout()))
9557 return Builder.getValue(LoadCst);
9563 bool ConstantMemory =
false;
9566 if (Builder.BatchAA && Builder.BatchAA->pointsToConstantMemory(PtrVal)) {
9567 Root = Builder.DAG.getEntryNode();
9568 ConstantMemory =
true;
9571 Root = Builder.DAG.getRoot();
9576 Builder.DAG.getLoad(LoadVT, Builder.getCurSDLoc(), Root, Ptr,
9579 if (!ConstantMemory)
9580 Builder.PendingLoads.push_back(LoadVal.
getValue(1));
9586void SelectionDAGBuilder::processIntegerCallValue(
const Instruction &
I,
9589 EVT VT =
DAG.getTargetLoweringInfo().getValueType(
DAG.getDataLayout(),
9600bool SelectionDAGBuilder::visitMemCmpBCmpCall(
const CallInst &
I) {
9601 const Value *
LHS =
I.getArgOperand(0), *
RHS =
I.getArgOperand(1);
9602 const Value *
Size =
I.getArgOperand(2);
9605 EVT CallVT =
DAG.getTargetLoweringInfo().getValueType(
DAG.getDataLayout(),
9611 const SelectionDAGTargetInfo &TSI =
DAG.getSelectionDAGInfo();
9615 if (Res.first.getNode()) {
9616 processIntegerCallValue(
I, Res.first,
true);
9630 auto hasFastLoadsAndCompare = [&](
unsigned NumBits) {
9631 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
9653 switch (NumBitsToCompare) {
9665 LoadVT = hasFastLoadsAndCompare(NumBitsToCompare);
9678 LoadL =
DAG.getBitcast(CmpVT, LoadL);
9679 LoadR =
DAG.getBitcast(CmpVT, LoadR);
9683 processIntegerCallValue(
I, Cmp,
false);
9692bool SelectionDAGBuilder::visitMemChrCall(
const CallInst &
I) {
9693 const Value *Src =
I.getArgOperand(0);
9694 const Value *
Char =
I.getArgOperand(1);
9695 const Value *
Length =
I.getArgOperand(2);
9697 const SelectionDAGTargetInfo &TSI =
DAG.getSelectionDAGInfo();
9698 std::pair<SDValue, SDValue> Res =
9701 MachinePointerInfo(Src));
9702 if (Res.first.getNode()) {
9716bool SelectionDAGBuilder::visitMemCCpyCall(
const CallInst &
I) {
9717 const SelectionDAGTargetInfo &TSI =
DAG.getSelectionDAGInfo();
9724 processIntegerCallValue(
I, Res.first,
true);
9736bool SelectionDAGBuilder::visitMemPCpyCall(
const CallInst &
I) {
9737 SDValue Dst =
getValue(
I.getArgOperand(0));
9738 SDValue Src =
getValue(
I.getArgOperand(1));
9741 Align DstAlign =
DAG.InferPtrAlign(Dst).valueOrOne();
9742 Align SrcAlign =
DAG.InferPtrAlign(Src).valueOrOne();
9750 SDValue MC =
DAG.getMemcpy(
9751 Root, sdl, Dst, Src,
Size, DstAlign, SrcAlign,
false,
false,
9752 nullptr, std::nullopt, MachinePointerInfo(
I.getArgOperand(0)),
9753 MachinePointerInfo(
I.getArgOperand(1)),
I.getAAMetadata());
9755 "** memcpy should not be lowered as TailCall in mempcpy context **");
9759 Size =
DAG.getSExtOrTrunc(
Size, sdl, Dst.getValueType());
9762 SDValue DstPlusSize =
DAG.getMemBasePlusOffset(Dst,
Size, sdl);
9772bool SelectionDAGBuilder::visitStrCpyCall(
const CallInst &
I,
bool isStpcpy) {
9773 const Value *Arg0 =
I.getArgOperand(0), *Arg1 =
I.getArgOperand(1);
9775 const SelectionDAGTargetInfo &TSI =
DAG.getSelectionDAGInfo();
9778 MachinePointerInfo(Arg0), MachinePointerInfo(Arg1), isStpcpy, &
I);
9779 if (Res.first.getNode()) {
9781 DAG.setRoot(Res.second);
9793bool SelectionDAGBuilder::visitStrCmpCall(
const CallInst &
I) {
9794 const Value *Arg0 =
I.getArgOperand(0), *Arg1 =
I.getArgOperand(1);
9796 const SelectionDAGTargetInfo &TSI =
DAG.getSelectionDAGInfo();
9799 MachinePointerInfo(Arg0), MachinePointerInfo(Arg1), &
I);
9800 if (Res.first.getNode()) {
9801 processIntegerCallValue(
I, Res.first,
true);
9814bool SelectionDAGBuilder::visitStrLenCall(
const CallInst &
I) {
9815 const Value *Arg0 =
I.getArgOperand(0);
9817 const SelectionDAGTargetInfo &TSI =
DAG.getSelectionDAGInfo();
9820 if (Res.first.getNode()) {
9821 processIntegerCallValue(
I, Res.first,
false);
9834bool SelectionDAGBuilder::visitStrNLenCall(
const CallInst &
I) {
9835 const Value *Arg0 =
I.getArgOperand(0), *Arg1 =
I.getArgOperand(1);
9837 const SelectionDAGTargetInfo &TSI =
DAG.getSelectionDAGInfo();
9838 std::pair<SDValue, SDValue> Res =
9841 MachinePointerInfo(Arg0));
9842 if (Res.first.getNode()) {
9843 processIntegerCallValue(
I, Res.first,
false);
9856bool SelectionDAGBuilder::visitStrstrCall(
const CallInst &
I) {
9857 const SelectionDAGTargetInfo &TSI =
DAG.getSelectionDAGInfo();
9858 const Value *Arg0 =
I.getArgOperand(0), *Arg1 =
I.getArgOperand(1);
9862 processIntegerCallValue(
I, Res.first,
false);
9874bool SelectionDAGBuilder::visitUnaryFloatCall(
const CallInst &
I,
9879 if (!
I.onlyReadsMemory() ||
I.isStrictFP())
9885 SDValue Tmp =
getValue(
I.getArgOperand(0));
9896bool SelectionDAGBuilder::visitBinaryFloatCall(
const CallInst &
I,
9901 if (!
I.onlyReadsMemory() ||
I.isStrictFP())
9907 SDValue Tmp0 =
getValue(
I.getArgOperand(0));
9908 SDValue Tmp1 =
getValue(
I.getArgOperand(1));
9914void SelectionDAGBuilder::visitCall(
const CallInst &
I) {
9916 if (
I.isInlineAsm()) {
9924 if (
F->isDeclaration()) {
9926 if (
unsigned IID =
F->getIntrinsicID()) {
9927 visitIntrinsicCall(
I, IID);
9937 LibFunc
Func = !
I.isNoBuiltin() && !
F->hasLocalLinkage() &&
F->hasName()
9940 if (
LibInfo->hasOptimizedCodeGen(Func)) {
9944 if (visitMemCmpBCmpCall(
I))
9947 case LibFunc_copysign:
9948 case LibFunc_copysignf:
9949 case LibFunc_copysignl:
9952 if (
I.onlyReadsMemory()) {
9997 case LibFunc_atan2f:
9998 case LibFunc_atan2l:
10003 case LibFunc_sinhf:
10004 case LibFunc_sinhl:
10009 case LibFunc_coshf:
10010 case LibFunc_coshl:
10015 case LibFunc_tanhf:
10016 case LibFunc_tanhl:
10021 case LibFunc_sqrtf:
10022 case LibFunc_sqrtl:
10023 case LibFunc_sqrt_finite:
10024 case LibFunc_sqrtf_finite:
10025 case LibFunc_sqrtl_finite:
10030 case LibFunc_log2f:
10031 case LibFunc_log2l:
10036 case LibFunc_exp2f:
10037 case LibFunc_exp2l:
10041 case LibFunc_exp10:
10042 case LibFunc_exp10f:
10043 case LibFunc_exp10l:
10047 case LibFunc_ldexp:
10048 case LibFunc_ldexpf:
10049 case LibFunc_ldexpl:
10053 case LibFunc_strstr:
10054 if (visitStrstrCall(
I))
10057 case LibFunc_memcmp:
10058 if (visitMemCmpBCmpCall(
I))
10061 case LibFunc_memccpy:
10062 if (visitMemCCpyCall(
I))
10065 case LibFunc_mempcpy:
10066 if (visitMemPCpyCall(
I))
10069 case LibFunc_memchr:
10070 if (visitMemChrCall(
I))
10073 case LibFunc_strcpy:
10074 if (visitStrCpyCall(
I,
false))
10077 case LibFunc_stpcpy:
10078 if (visitStrCpyCall(
I,
true))
10081 case LibFunc_strcmp:
10082 if (visitStrCmpCall(
I))
10085 case LibFunc_strlen:
10086 if (visitStrLenCall(
I))
10089 case LibFunc_strnlen:
10090 if (visitStrNLenCall(
I))
10114 if (
I.hasDeoptState())
10131 const Value *Discriminator = PAB->Inputs[1];
10133 assert(
Key->getType()->isIntegerTy(32) &&
"Invalid ptrauth key");
10134 assert(Discriminator->getType()->isIntegerTy(64) &&
10135 "Invalid ptrauth discriminator");
10140 if (CalleeCPA->isKnownCompatibleWith(
Key, Discriminator,
10141 DAG.getDataLayout()))
10181 for (
const auto &Code : Codes)
10196 SDISelAsmOperandInfo &MatchingOpInfo,
10198 if (OpInfo.ConstraintVT == MatchingOpInfo.ConstraintVT)
10204 std::pair<unsigned, const TargetRegisterClass *> MatchRC =
10206 OpInfo.ConstraintVT);
10207 std::pair<unsigned, const TargetRegisterClass *> InputRC =
10209 MatchingOpInfo.ConstraintVT);
10210 const bool OutOpIsIntOrFP =
10211 OpInfo.ConstraintVT.isInteger() || OpInfo.ConstraintVT.isFloatingPoint();
10212 const bool InOpIsIntOrFP = MatchingOpInfo.ConstraintVT.isInteger() ||
10213 MatchingOpInfo.ConstraintVT.isFloatingPoint();
10214 if ((OutOpIsIntOrFP != InOpIsIntOrFP) || (MatchRC.second != InputRC.second)) {
10217 " with a matching output constraint of"
10218 " incompatible type!");
10220 MatchingOpInfo.ConstraintVT = OpInfo.ConstraintVT;
10227 SDISelAsmOperandInfo &OpInfo,
10240 const Value *OpVal = OpInfo.CallOperandVal;
10258 DL.getPrefTypeAlign(Ty),
false,
10261 Chain = DAG.
getTruncStore(Chain, Location, OpInfo.CallOperand, StackSlot,
10264 OpInfo.CallOperand = StackSlot;
10277static std::optional<unsigned>
10279 SDISelAsmOperandInfo &OpInfo,
10280 SDISelAsmOperandInfo &RefOpInfo) {
10291 return std::nullopt;
10295 unsigned AssignedReg;
10298 &
TRI, RefOpInfo.ConstraintCode, RefOpInfo.ConstraintVT);
10301 return std::nullopt;
10306 const MVT RegVT = *
TRI.legalclasstypes_begin(*RC);
10308 if (OpInfo.ConstraintVT != MVT::Other && RegVT != MVT::Untyped) {
10317 !
TRI.isTypeLegalForClass(*RC, OpInfo.ConstraintVT)) {
10322 if (RegVT.
getSizeInBits() == OpInfo.ConstraintVT.getSizeInBits()) {
10327 OpInfo.CallOperand =
10329 OpInfo.ConstraintVT = RegVT;
10333 }
else if (RegVT.
isInteger() && OpInfo.ConstraintVT.isFloatingPoint()) {
10337 return std::nullopt;
10339 OpInfo.CallOperand =
10341 OpInfo.ConstraintVT = VT;
10348 if (OpInfo.isMatchingInputConstraint())
10349 return std::nullopt;
10351 EVT ValueVT = OpInfo.ConstraintVT;
10352 if (OpInfo.ConstraintVT == MVT::Other)
10356 unsigned NumRegs = 1;
10357 if (OpInfo.ConstraintVT != MVT::Other)
10372 I = std::find(
I, RC->
end(), AssignedReg);
10373 if (
I == RC->
end()) {
10376 return {AssignedReg};
10380 for (; NumRegs; --NumRegs, ++
I) {
10381 assert(
I != RC->
end() &&
"Ran out of registers to allocate!");
10386 OpInfo.AssignedRegs =
RegsForValue(Regs, RegVT, ValueVT);
10387 return std::nullopt;
10392 const std::vector<SDValue> &AsmNodeOperands) {
10395 for (; OperandNo; --OperandNo) {
10397 unsigned OpFlag = AsmNodeOperands[CurOp]->getAsZExtVal();
10400 (
F.isRegDefKind() ||
F.isRegDefEarlyClobberKind() ||
F.isMemKind()) &&
10401 "Skipped past definitions?");
10402 CurOp +=
F.getNumOperandRegisters() + 1;
10410 unsigned Flags = 0;
10413 explicit ExtraFlags(
const CallBase &
Call) {
10415 if (
IA->hasSideEffects())
10417 if (
IA->isAlignStack())
10419 if (
IA->canThrow())
10426 void update(
const TargetLowering::AsmOperandInfo &OpInfo) {
10442 unsigned get()
const {
return Flags; }
10466struct ConstraintDecisionInfo {
10468 std::vector<SDValue> AsmNodeOperands;
10469 SDValue Glue, Chain;
10470 bool HasSideEffect =
false;
10473 SmallVector<char> Buffer;
10474 raw_svector_ostream ErrorMsg;
10476 ConstraintDecisionInfo() : ErrorMsg(Buffer) {}
10486 ExtraFlags &ExtraInfo) {
10487 for (
auto &
T : TargetConstraints) {
10488 Info.ConstraintOperands.push_back(SDISelAsmOperandInfo(
T));
10489 SDISelAsmOperandInfo &OpInfo = Info.ConstraintOperands.back();
10491 if (OpInfo.CallOperandVal)
10492 OpInfo.CallOperand = Builder.getValue(OpInfo.CallOperandVal);
10494 if (!Info.HasSideEffect)
10495 Info.HasSideEffect = OpInfo.hasMemory(TLI);
10507 Info.ErrorMsg <<
"constraint '" <<
T.ConstraintCode
10508 <<
"' expects an integer constant expression";
10512 ExtraInfo.update(
T);
10526 IA->collectAsmStrs(AsmStrs);
10529 for (SDISelAsmOperandInfo &OpInfo : Info.ConstraintOperands) {
10537 if (OpInfo.hasMatchingInput()) {
10538 SDISelAsmOperandInfo &
Input =
10539 Info.ConstraintOperands[OpInfo.MatchingInput];
10570 if (OpInfo.isIndirect &&
isFunction(OpInfo.CallOperand) &&
10573 OpInfo.isIndirect =
false;
10580 !OpInfo.isIndirect) {
10581 assert((OpInfo.isMultipleAlternative ||
10583 "Can only indirectify direct input operands!");
10590 OpInfo.CallOperandVal =
nullptr;
10593 OpInfo.isIndirect =
true;
10605 SDLoc DL = Builder.getCurSDLoc();
10606 for (SDISelAsmOperandInfo &OpInfo : Info.ConstraintOperands) {
10608 SDISelAsmOperandInfo &RefOpInfo =
10609 OpInfo.isMatchingInputConstraint()
10610 ? Info.ConstraintOperands[OpInfo.getMatchedOperand()]
10616 const char *
RegName =
TRI.getName(*RegError);
10617 Info.ErrorMsg <<
"register '" <<
RegName <<
"' allocated for constraint '"
10618 << OpInfo.ConstraintCode
10619 <<
"' does not match required type";
10623 auto DetectWriteToReservedRegister = [&]() {
10628 if (
Reg.isPhysical() &&
TRI.isInlineAsmReadOnlyReg(MF,
Reg)) {
10629 Info.ErrorMsg <<
"write to reserved register '"
10630 <<
TRI.getRegAsmName(
Reg) <<
"'";
10639 !OpInfo.isMatchingInputConstraint())) &&
10640 "Only address as input operand is allowed.");
10642 switch (OpInfo.Type) {
10648 "Failed to convert memory constraint code to constraint id.");
10653 Info.AsmNodeOperands.push_back(
10655 Info.AsmNodeOperands.push_back(OpInfo.CallOperand);
10660 if (OpInfo.AssignedRegs.Regs.empty()) {
10661 Info.ErrorMsg <<
"could not allocate output register for "
10662 <<
"constraint '" << OpInfo.ConstraintCode <<
"'";
10666 if (DetectWriteToReservedRegister())
10671 OpInfo.AssignedRegs.AddInlineAsmOperands(
10674 false, 0,
DL, DAG, Info.AsmNodeOperands);
10680 SDValue InOperandVal = OpInfo.CallOperand;
10682 if (OpInfo.isMatchingInputConstraint()) {
10686 Info.AsmNodeOperands);
10688 if (Flag.isRegDefKind() || Flag.isRegDefEarlyClobberKind()) {
10689 if (OpInfo.isIndirect) {
10691 Info.ErrorMsg <<
"inline asm not supported yet: cannot handle "
10692 <<
"tied indirect register inputs";
10702 MVT RegVT = R->getSimpleValueType(0);
10706 :
TRI.getMinimalPhysRegClass(TiedReg);
10707 for (
unsigned I = 0,
E = Flag.getNumOperandRegisters();
I !=
E; ++
I)
10714 &Info.Glue, &
Call);
10716 OpInfo.getMatchedOperand(),
DL, DAG,
10717 Info.AsmNodeOperands);
10721 assert(Flag.isMemKind() &&
"Unknown matching constraint!");
10722 assert(Flag.getNumOperandRegisters() == 1 &&
10723 "Unexpected number of operands");
10727 Flag.clearMemConstraint();
10728 Flag.setMatchingOp(OpInfo.getMatchedOperand());
10731 Info.AsmNodeOperands.push_back(Info.AsmNodeOperands[CurOp + 1]);
10742 std::vector<SDValue>
Ops;
10748 Info.ErrorMsg <<
"value out of range for constraint '"
10749 << OpInfo.ConstraintCode <<
"'";
10753 Info.ErrorMsg <<
"invalid operand for inline asm constraint '"
10754 << OpInfo.ConstraintCode <<
"'";
10767 assert((OpInfo.isIndirect ||
10769 "Operand must be indirect to be a mem!");
10772 "Memory operands expect pointer values");
10777 "Failed to convert memory constraint code to constraint id.");
10782 Info.AsmNodeOperands.push_back(
10784 Info.AsmNodeOperands.push_back(InOperandVal);
10792 "Failed to convert memory constraint code to constraint id.");
10796 SDValue AsmOp = InOperandVal;
10808 Info.AsmNodeOperands.push_back(
10810 Info.AsmNodeOperands.push_back(AsmOp);
10816 Info.ErrorMsg <<
"unknown asm constraint '" << OpInfo.ConstraintCode
10822 if (OpInfo.isIndirect) {
10823 Info.ErrorMsg <<
"cannot handle indirect register inputs yet for "
10824 <<
"constraint '" << OpInfo.ConstraintCode <<
"'";
10829 if (OpInfo.AssignedRegs.Regs.empty()) {
10830 Info.ErrorMsg <<
"could not allocate input reg for constraint '"
10831 << OpInfo.ConstraintCode <<
"'";
10835 if (DetectWriteToReservedRegister())
10838 OpInfo.AssignedRegs.getCopyToRegs(InOperandVal, DAG,
DL, Info.Chain,
10839 &Info.Glue, &
Call);
10840 OpInfo.AssignedRegs.AddInlineAsmOperands(
10848 if (!OpInfo.AssignedRegs.Regs.empty())
10849 OpInfo.AssignedRegs.AddInlineAsmOperands(
10866 ExtraFlags ExtraInfo(
Call);
10869 Info.HasSideEffect = IA->hasSideEffects();
10875 Info.Chain = Info.HasSideEffect ? Builder.getRoot() : DAG.
getRoot();
10879 if (IsCallBr || EmitEHLabels)
10883 Info.Chain = Builder.getControlRoot();
10886 Info.Chain = Builder.lowerStartEH(Info.Chain, EHPadBB, Info.BeginLabel);
10892 Info.AsmNodeOperands.push_back(
SDValue());
10899 const MDNode *SrcLoc =
Call.getMetadata(
"srcloc");
10900 Info.AsmNodeOperands.push_back(DAG.
getMDNode(SrcLoc));
10904 Info.AsmNodeOperands.push_back(
10913void SelectionDAGBuilder::visitInlineAsm(
const CallBase &
Call,
10915 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
10917 DAG.getDataLayout(),
DAG.getSubtarget().getRegisterInfo(),
Call);
10920 "InvokeInst must have an EHPadBB");
10922 ConstraintDecisionInfo
Info;
10925 return emitInlineAsmError(
Call,
Info.ErrorMsg.str());
10927 SDValue Glue =
Info.Glue;
10928 SDValue Chain =
Info.Chain;
10933 Info.AsmNodeOperands.push_back(Glue);
10939 Info.AsmNodeOperands);
10951 ResultTypes = StructResult->elements();
10952 else if (!CallResultType->
isVoidTy())
10953 ResultTypes =
ArrayRef(CallResultType);
10955 auto CurResultType = ResultTypes.
begin();
10956 auto handleRegAssign = [&](SDValue
V) {
10957 assert(CurResultType != ResultTypes.
end() &&
"Unexpected value");
10958 assert((*CurResultType)->isSized() &&
"Unexpected unsized type");
10959 EVT ResultVT = TLI.
getValueType(
DAG.getDataLayout(), *CurResultType);
10971 if (ResultVT !=
V.getValueType() &&
10974 else if (ResultVT !=
V.getValueType() && ResultVT.
isInteger() &&
10975 V.getValueType().isInteger()) {
10981 assert(ResultVT ==
V.getValueType() &&
"Asm result value mismatch!");
10987 for (SDISelAsmOperandInfo &OpInfo :
Info.ConstraintOperands) {
10991 if (OpInfo.AssignedRegs.
Regs.empty())
10994 switch (OpInfo.ConstraintType) {
10998 Chain, &Glue, &
Call);
11010 assert(
false &&
"Unexpected unknown constraint");
11014 if (OpInfo.isIndirect) {
11015 const Value *Ptr = OpInfo.CallOperandVal;
11016 assert(Ptr &&
"Expected value CallOperandVal for indirect asm operand");
11018 MachinePointerInfo(Ptr));
11024 for (
const SDValue &V : Val->
op_values())
11025 handleRegAssign(V);
11027 handleRegAssign(Val);
11033 if (!ResultValues.
empty()) {
11034 assert(CurResultType == ResultTypes.
end() &&
11035 "Mismatch in number of ResultTypes");
11037 "Mismatch in number of output operands in asm result");
11040 DAG.getVTList(ResultVTs), ResultValues);
11045 if (!OutChains.
empty())
11049 Chain = lowerEndEH(Chain,
II, EHPadBB,
Info.BeginLabel);
11052 if (ResultValues.
empty() ||
Info.HasSideEffect || !OutChains.
empty() ||
11054 DAG.setRoot(Chain);
11057void SelectionDAGBuilder::emitInlineAsmError(
const CallBase &
Call,
11058 const Twine &Message) {
11059 LLVMContext &Ctx = *
DAG.getContext();
11063 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
11067 if (ValueVTs.
empty())
11071 for (
const EVT &VT : ValueVTs)
11072 Ops.push_back(
DAG.getUNDEF(VT));
11077void SelectionDAGBuilder::visitVAStart(
const CallInst &
I) {
11081 DAG.getSrcValue(
I.getArgOperand(0))));
11084void SelectionDAGBuilder::visitVAArg(
const VAArgInst &
I) {
11085 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
11086 const DataLayout &
DL =
DAG.getDataLayout();
11087 SDValue
V =
DAG.getVAArg(
11090 DL.getABITypeAlign(
I.getType()).value());
11091 DAG.setRoot(
V.getValue(1));
11093 if (
I.getType()->isPointerTy())
11094 V =
DAG.getPtrExtOrTrunc(
11099void SelectionDAGBuilder::visitVAEnd(
const CallInst &
I) {
11103 DAG.getSrcValue(
I.getArgOperand(0))));
11106void SelectionDAGBuilder::visitVACopy(
const CallInst &
I) {
11111 DAG.getSrcValue(
I.getArgOperand(0)),
11112 DAG.getSrcValue(
I.getArgOperand(1))));
11118 std::optional<ConstantRange> CR =
getRange(
I);
11120 if (!CR || CR->isFullSet() || CR->isEmptySet() || CR->isUpperWrapped())
11123 APInt Hi = CR->getUnsignedMax();
11124 unsigned Bits = std::max(
Hi.getActiveBits(),
11132 DAG.getValueType(SmallVT));
11133 unsigned NumVals =
Op.getNode()->getNumValues();
11139 Ops.push_back(ZExt);
11140 for (
unsigned I = 1;
I != NumVals; ++
I)
11141 Ops.push_back(
Op.getValue(
I));
11143 return DAG.getMergeValues(
Ops,
SL);
11153 SDValue TestConst =
DAG.getTargetConstant(Classes,
SDLoc(), MVT::i32);
11161 for (
unsigned I = 0, E =
Ops.size();
I != E; ++
I) {
11164 MergeOp, TestConst);
11167 return DAG.getMergeValues(
Ops,
SL);
11178 unsigned ArgIdx,
unsigned NumArgs,
SDValue Callee,
Type *ReturnTy,
11181 Args.reserve(NumArgs);
11185 for (
unsigned ArgI = ArgIdx, ArgE = ArgIdx + NumArgs;
11186 ArgI != ArgE; ++ArgI) {
11187 const Value *V =
Call->getOperand(ArgI);
11189 assert(!V->getType()->isEmptyTy() &&
"Empty type passed to intrinsic.");
11192 Entry.setAttributes(
Call, ArgI);
11193 Args.push_back(Entry);
11198 .
setCallee(
Call->getCallingConv(), ReturnTy, Callee, std::move(Args),
11227 for (
unsigned I = StartIdx;
I <
Call.arg_size();
I++) {
11236 Ops.push_back(Builder.getValue(
Call.getArgOperand(
I)));
11242void SelectionDAGBuilder::visitStackmap(
const CallInst &CI) {
11248 SDValue Chain, InGlue,
Callee;
11268 Ops.push_back(Chain);
11269 Ops.push_back(InGlue);
11276 assert(
ID.getValueType() == MVT::i64);
11278 DAG.getTargetConstant(
ID->getAsZExtVal(),
DL,
ID.getValueType());
11279 Ops.push_back(IDConst);
11283 SDValue ShadConst =
11285 Ops.push_back(ShadConst);
11291 SDVTList NodeTys =
DAG.getVTList(MVT::Other, MVT::Glue);
11295 Chain =
DAG.getCALLSEQ_END(Chain, 0, 0, InGlue,
DL);
11300 DAG.setRoot(Chain);
11303 FuncInfo.MF->getFrameInfo().setHasStackMap();
11307void SelectionDAGBuilder::visitPatchpoint(
const CallBase &CB,
11324 Callee =
DAG.getIntPtrConstant(ConstCallee->getZExtValue(), dl,
11327 Callee =
DAG.getTargetGlobalAddress(SymbolicCallee->getGlobal(),
11328 SDLoc(SymbolicCallee),
11329 SymbolicCallee->getValueType(0));
11339 "Not enough arguments provided to the patchpoint intrinsic");
11342 unsigned NumCallArgs = IsAnyRegCC ? 0 : NumArgs;
11346 TargetLowering::CallLoweringInfo CLI(
DAG);
11351 SDNode *CallEnd =
Result.second.getNode();
11360 "Expected a callseq node.");
11362 bool HasGlue =
Call->getGluedNode();
11387 Ops.push_back(Callee);
11393 NumCallRegArgs = IsAnyRegCC ? NumArgs : NumCallRegArgs;
11394 Ops.push_back(
DAG.getTargetConstant(NumCallRegArgs, dl, MVT::i32));
11397 Ops.push_back(
DAG.getTargetConstant((
unsigned)
CC, dl, MVT::i32));
11402 for (
unsigned i = NumMetaOpers, e = NumMetaOpers + NumArgs; i !=
e; ++i)
11413 if (IsAnyRegCC && HasDef) {
11415 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
11418 assert(ValueVTs.
size() == 1 &&
"Expected only one return value type.");
11423 NodeTys =
DAG.getVTList(ValueVTs);
11425 NodeTys =
DAG.getVTList(MVT::Other, MVT::Glue);
11442 if (IsAnyRegCC && HasDef) {
11443 SDValue From[] = {SDValue(
Call, 0), SDValue(
Call, 1)};
11445 DAG.ReplaceAllUsesOfValuesWith(From, To, 2);
11451 FuncInfo.MF->getFrameInfo().setHasPatchPoint();
11454void SelectionDAGBuilder::visitVectorReduce(
const CallInst &
I,
11456 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
11457 SDValue Op1 =
getValue(
I.getArgOperand(0));
11459 if (
I.arg_size() > 1)
11464 SDNodeFlags SDFlags;
11468 switch (Intrinsic) {
11469 case Intrinsic::vector_reduce_fadd:
11477 case Intrinsic::vector_reduce_fmul:
11485 case Intrinsic::vector_reduce_add:
11488 case Intrinsic::vector_reduce_mul:
11491 case Intrinsic::vector_reduce_and:
11494 case Intrinsic::vector_reduce_or:
11497 case Intrinsic::vector_reduce_xor:
11500 case Intrinsic::vector_reduce_smax:
11503 case Intrinsic::vector_reduce_smin:
11506 case Intrinsic::vector_reduce_umax:
11509 case Intrinsic::vector_reduce_umin:
11512 case Intrinsic::vector_reduce_fmax:
11515 case Intrinsic::vector_reduce_fmin:
11518 case Intrinsic::vector_reduce_fmaximum:
11521 case Intrinsic::vector_reduce_fminimum:
11524 case Intrinsic::vector_reduce_fmaximumnum:
11527 case Intrinsic::vector_reduce_fminimumnum:
11541 Attrs.push_back(Attribute::SExt);
11543 Attrs.push_back(Attribute::ZExt);
11545 Attrs.push_back(Attribute::InReg);
11547 return AttributeList::get(CLI.
RetTy->
getContext(), AttributeList::ReturnIndex,
11555std::pair<SDValue, SDValue>
11569 "Only supported for non-aggregate returns");
11572 for (
Type *Ty : RetOrigTys)
11581 RetOrigTys.
swap(OldRetOrigTys);
11582 RetVTs.
swap(OldRetVTs);
11583 Offsets.swap(OldOffsets);
11585 for (
size_t i = 0, e = OldRetVTs.
size(); i != e; ++i) {
11586 EVT RetVT = OldRetVTs[i];
11587 uint64_t
Offset = OldOffsets[i];
11590 unsigned RegisterVTByteSZ = RegisterVT.
getSizeInBits() / 8;
11591 RetOrigTys.
append(NumRegs, OldRetOrigTys[i]);
11592 RetVTs.
append(NumRegs, RegisterVT);
11593 for (
unsigned j = 0; j != NumRegs; ++j)
11606 int DemoteStackIdx = -100;
11611 uint64_t TySize =
DL.getTypeAllocSize(CLI.
RetTy);
11619 ArgListEntry Entry(DemoteStackSlot, StackSlotPtrType);
11620 Entry.IsSRet =
true;
11621 Entry.Alignment = Alignment;
11633 for (
unsigned I = 0, E = RetVTs.
size();
I != E; ++
I) {
11635 if (NeedsRegBlock) {
11636 Flags.setInConsecutiveRegs();
11637 if (
I == RetVTs.
size() - 1)
11638 Flags.setInConsecutiveRegsLast();
11640 EVT VT = RetVTs[
I];
11644 for (
unsigned i = 0; i != NumRegs; ++i) {
11658 CLI.
Ins.push_back(Ret);
11667 if (Arg.IsSwiftError) {
11673 CLI.
Ins.push_back(Ret);
11681 for (
unsigned i = 0, e = Args.size(); i != e; ++i) {
11685 Type *FinalType = Args[i].Ty;
11686 if (Args[i].IsByVal)
11687 FinalType = Args[i].IndirectType;
11690 for (
unsigned Value = 0, NumValues = OrigArgTys.
size();
Value != NumValues;
11693 Type *ArgTy = OrigArgTy;
11694 if (Args[i].Ty != Args[i].OrigTy) {
11695 assert(
Value == 0 &&
"Only supported for non-aggregate arguments");
11696 ArgTy = Args[i].Ty;
11701 Args[i].Node.getResNo() +
Value);
11708 Flags.setOrigAlign(OriginalAlignment);
11713 Flags.setPointer();
11716 if (Args[i].IsZExt)
11718 if (Args[i].IsSExt)
11720 if (Args[i].IsNoExt)
11722 if (Args[i].IsInReg) {
11729 Flags.setHvaStart();
11735 if (Args[i].IsSRet)
11737 if (Args[i].IsSwiftSelf)
11738 Flags.setSwiftSelf();
11739 if (Args[i].IsSwiftAsync)
11740 Flags.setSwiftAsync();
11741 if (Args[i].IsSwiftError)
11742 Flags.setSwiftError();
11743 if (Args[i].IsCFGuardTarget)
11744 Flags.setCFGuardTarget();
11745 if (Args[i].IsByVal)
11747 if (Args[i].IsByRef)
11749 if (Args[i].IsPreallocated) {
11750 Flags.setPreallocated();
11758 if (Args[i].IsInAlloca) {
11759 Flags.setInAlloca();
11768 if (Args[i].IsByVal || Args[i].IsInAlloca || Args[i].IsPreallocated) {
11769 unsigned FrameSize =
DL.getTypeAllocSize(Args[i].IndirectType);
11770 Flags.setByValSize(FrameSize);
11773 if (
auto MA = Args[i].Alignment)
11777 }
else if (
auto MA = Args[i].Alignment) {
11780 MemAlign = OriginalAlignment;
11782 Flags.setMemAlign(MemAlign);
11783 if (Args[i].IsNest)
11786 Flags.setInConsecutiveRegs();
11789 unsigned NumParts =
11794 if (Args[i].IsSExt)
11796 else if (Args[i].IsZExt)
11801 if (Args[i].IsReturned && !
Op.getValueType().isVector() &&
11806 Args[i].Ty->getPointerAddressSpace())) &&
11807 RetVTs.
size() == NumValues &&
"unexpected use of 'returned'");
11820 CLI.
RetZExt == Args[i].IsZExt))
11821 Flags.setReturned();
11827 for (
unsigned j = 0; j != NumParts; ++j) {
11833 j * Parts[j].
getValueType().getStoreSize().getKnownMinValue());
11834 if (NumParts > 1 && j == 0)
11838 if (j == NumParts - 1)
11842 CLI.
Outs.push_back(MyFlags);
11843 CLI.
OutVals.push_back(Parts[j]);
11846 if (NeedsRegBlock &&
Value == NumValues - 1)
11847 CLI.
Outs[CLI.
Outs.size() - 1].Flags.setInConsecutiveRegsLast();
11859 "LowerCall didn't return a valid chain!");
11861 "LowerCall emitted a return value for a tail call!");
11863 "LowerCall didn't emit the correct number of values!");
11875 for (
unsigned i = 0, e = CLI.
Ins.size(); i != e; ++i) {
11876 assert(InVals[i].
getNode() &&
"LowerCall emitted a null value!");
11877 assert(
EVT(CLI.
Ins[i].VT) == InVals[i].getValueType() &&
11878 "LowerCall emitted a value with the wrong type!");
11888 unsigned NumValues = RetVTs.
size();
11889 ReturnValues.
resize(NumValues);
11896 for (
unsigned i = 0; i < NumValues; ++i) {
11903 DemoteStackIdx, Offsets[i]),
11905 ReturnValues[i] = L;
11906 Chains[i] = L.getValue(1);
11913 std::optional<ISD::NodeType> AssertOp;
11918 unsigned CurReg = 0;
11919 for (
EVT VT : RetVTs) {
11925 CLI.
DAG, CLI.
DL, &InVals[CurReg], NumRegs, RegisterVT, VT,
nullptr,
11933 if (ReturnValues.
empty())
11939 return std::make_pair(Res, CLI.
Chain);
11956 if (
N->getNumValues() == 1) {
11964 "Lowering returned the wrong number of results!");
11967 for (
unsigned I = 0, E =
N->getNumValues();
I != E; ++
I)
11981 "Copy from a reg to the same reg!");
11982 assert(!Reg.isPhysical() &&
"Is a physreg");
11988 RegsForValue RFV(V->getContext(), TLI,
DAG.getDataLayout(), Reg, V->getType(),
11993 auto PreferredExtendIt =
FuncInfo.PreferredExtendType.find(V);
11994 if (PreferredExtendIt !=
FuncInfo.PreferredExtendType.end())
11995 ExtendType = PreferredExtendIt->second;
11998 PendingExports.push_back(Chain);
12010 return A->use_empty();
12012 const BasicBlock &Entry =
A->getParent()->front();
12013 for (
const User *U :
A->users())
12022 std::pair<const AllocaInst *, const StoreInst *>>;
12034 enum StaticAllocaInfo {
Unknown, Clobbered, Elidable };
12036 unsigned NumArgs = FuncInfo->
Fn->
arg_size();
12037 StaticAllocas.
reserve(NumArgs * 2);
12039 auto GetInfoIfStaticAlloca = [&](
const Value *V) -> StaticAllocaInfo * {
12042 V = V->stripPointerCasts();
12044 if (!AI || !AI->isStaticAlloca() || !FuncInfo->
StaticAllocaMap.count(AI))
12047 return &Iter.first->second;
12067 for (
const Use &U :
I.operands()) {
12068 if (StaticAllocaInfo *Info = GetInfoIfStaticAlloca(U))
12069 *Info = StaticAllocaInfo::Clobbered;
12075 if (StaticAllocaInfo *Info = GetInfoIfStaticAlloca(
SI->getValueOperand()))
12076 *Info = StaticAllocaInfo::Clobbered;
12079 const Value *Dst =
SI->getPointerOperand()->stripPointerCasts();
12080 StaticAllocaInfo *Info = GetInfoIfStaticAlloca(Dst);
12086 if (*Info != StaticAllocaInfo::Unknown)
12094 const Value *Val =
SI->getValueOperand()->stripPointerCasts();
12097 if (!Arg || Arg->hasPassPointeeByValueCopyAttr() ||
12099 DL.getTypeStoreSize(Arg->
getType()) != *AllocaSize ||
12100 !
DL.typeSizeEqualsStoreSize(Arg->
getType()) ||
12101 ArgCopyElisionCandidates.count(Arg)) {
12102 *Info = StaticAllocaInfo::Clobbered;
12106 LLVM_DEBUG(
dbgs() <<
"Found argument copy elision candidate: " << *AI
12110 *Info = StaticAllocaInfo::Elidable;
12111 ArgCopyElisionCandidates.insert({Arg, {AI,
SI}});
12116 if (ArgCopyElisionCandidates.size() == NumArgs)
12140 auto ArgCopyIter = ArgCopyElisionCandidates.find(&Arg);
12141 assert(ArgCopyIter != ArgCopyElisionCandidates.end());
12142 const AllocaInst *AI = ArgCopyIter->second.first;
12143 int FixedIndex = FINode->getIndex();
12145 int OldIndex = AllocaIndex;
12149 dbgs() <<
" argument copy elision failed due to bad fixed stack "
12155 LLVM_DEBUG(
dbgs() <<
" argument copy elision failed: alignment of alloca "
12156 "greater than stack argument alignment ("
12157 <<
DebugStr(RequiredAlignment) <<
" vs "
12165 dbgs() <<
"Eliding argument copy from " << Arg <<
" to " << *AI <<
'\n'
12166 <<
" Replacing frame index " << OldIndex <<
" with " << FixedIndex
12172 AllocaIndex = FixedIndex;
12173 ArgCopyElisionFrameIndexMap.
insert({OldIndex, FixedIndex});
12174 for (
SDValue ArgVal : ArgVals)
12178 const StoreInst *
SI = ArgCopyIter->second.second;
12192 SelectionDAG &DAG =
SDB->DAG;
12193 SDLoc dl =
SDB->getCurSDLoc();
12198 if (
F.hasFnAttribute(Attribute::Naked))
12203 MVT ValueVT =
TLI->getPointerTy(
DL,
DL.getAllocaAddrSpace());
12205 ISD::ArgFlagsTy
Flags;
12207 MVT RegisterVT =
TLI->getRegisterType(*DAG.
getContext(), ValueVT);
12208 ISD::InputArg RetArg(Flags, RegisterVT, ValueVT,
F.getReturnType(),
true,
12218 ArgCopyElisionCandidates);
12221 for (
const Argument &Arg :
F.args()) {
12222 unsigned ArgNo = Arg.getArgNo();
12225 bool isArgValueUsed = !Arg.
use_empty();
12227 if (Arg.hasAttribute(Attribute::ByVal))
12228 FinalType = Arg.getParamByValType();
12229 bool NeedsRegBlock =
TLI->functionArgumentNeedsConsecutiveRegisters(
12230 FinalType,
F.getCallingConv(),
F.isVarArg(),
DL);
12231 for (
unsigned Value = 0, NumValues =
Types.size();
Value != NumValues;
12234 EVT VT =
TLI->getValueType(
DL, ArgTy);
12235 ISD::ArgFlagsTy
Flags;
12238 Flags.setPointer();
12241 if (Arg.hasAttribute(Attribute::ZExt))
12243 if (Arg.hasAttribute(Attribute::SExt))
12245 if (Arg.hasAttribute(Attribute::InReg)) {
12252 Flags.setHvaStart();
12258 if (Arg.hasAttribute(Attribute::StructRet))
12260 if (Arg.hasAttribute(Attribute::SwiftSelf))
12261 Flags.setSwiftSelf();
12262 if (Arg.hasAttribute(Attribute::SwiftAsync))
12263 Flags.setSwiftAsync();
12264 if (Arg.hasAttribute(Attribute::SwiftError))
12265 Flags.setSwiftError();
12266 if (Arg.hasAttribute(Attribute::ByVal))
12268 if (Arg.hasAttribute(Attribute::ByRef))
12270 if (Arg.hasAttribute(Attribute::InAlloca)) {
12271 Flags.setInAlloca();
12279 if (Arg.hasAttribute(Attribute::Preallocated)) {
12280 Flags.setPreallocated();
12292 const Align OriginalAlignment(
12293 TLI->getABIAlignmentForCallingConv(ArgTy,
DL));
12294 Flags.setOrigAlign(OriginalAlignment);
12297 Type *ArgMemTy =
nullptr;
12298 if (
Flags.isByVal() ||
Flags.isInAlloca() ||
Flags.isPreallocated() ||
12301 ArgMemTy = Arg.getPointeeInMemoryValueType();
12303 uint64_t MemSize =
DL.getTypeAllocSize(ArgMemTy);
12308 if (
auto ParamAlign = Arg.getParamStackAlign())
12309 MemAlign = *ParamAlign;
12310 else if ((ParamAlign = Arg.getParamAlign()))
12311 MemAlign = *ParamAlign;
12313 MemAlign =
TLI->getByValTypeAlignment(ArgMemTy,
DL);
12314 if (
Flags.isByRef())
12315 Flags.setByRefSize(MemSize);
12317 Flags.setByValSize(MemSize);
12318 }
else if (
auto ParamAlign = Arg.getParamStackAlign()) {
12319 MemAlign = *ParamAlign;
12321 MemAlign = OriginalAlignment;
12323 Flags.setMemAlign(MemAlign);
12325 if (Arg.hasAttribute(Attribute::Nest))
12328 Flags.setInConsecutiveRegs();
12329 if (ArgCopyElisionCandidates.count(&Arg))
12330 Flags.setCopyElisionCandidate();
12331 if (Arg.hasAttribute(Attribute::Returned))
12332 Flags.setReturned();
12334 MVT RegisterVT =
TLI->getRegisterTypeForCallingConv(
12335 *
CurDAG->getContext(),
F.getCallingConv(), VT);
12336 unsigned NumRegs =
TLI->getNumRegistersForCallingConv(
12337 *
CurDAG->getContext(),
F.getCallingConv(), VT);
12338 for (
unsigned i = 0; i != NumRegs; ++i) {
12342 ISD::InputArg MyFlags(
12343 Flags, RegisterVT, VT, ArgTy, isArgValueUsed, ArgNo,
12345 if (NumRegs > 1 && i == 0)
12346 MyFlags.Flags.setSplit();
12349 MyFlags.Flags.setOrigAlign(
Align(1));
12350 if (i == NumRegs - 1)
12351 MyFlags.Flags.setSplitEnd();
12355 if (NeedsRegBlock &&
Value == NumValues - 1)
12356 Ins[Ins.
size() - 1].Flags.setInConsecutiveRegsLast();
12362 SDValue NewRoot =
TLI->LowerFormalArguments(
12363 DAG.
getRoot(),
F.getCallingConv(),
F.isVarArg(), Ins, dl, DAG, InVals);
12367 "LowerFormalArguments didn't return a valid chain!");
12369 "LowerFormalArguments didn't emit the correct number of values!");
12371 "LowerFormalArguments emitted a null value!");
12381 MVT VT =
TLI->getPointerTy(
DL,
DL.getAllocaAddrSpace());
12382 MVT RegVT =
TLI->getRegisterType(*
CurDAG->getContext(), VT);
12383 std::optional<ISD::NodeType> AssertOp;
12386 F.getCallingConv(), AssertOp);
12389 MachineRegisterInfo&
RegInfo =
MF.getRegInfo();
12391 RegInfo.createVirtualRegister(
TLI->getRegClassFor(RegVT));
12392 FuncInfo->DemoteRegister = SRetReg;
12394 SDB->DAG.getCopyToReg(NewRoot,
SDB->getCurSDLoc(), SRetReg, ArgValue);
12402 DenseMap<int, int> ArgCopyElisionFrameIndexMap;
12403 for (
const Argument &Arg :
F.args()) {
12407 unsigned NumValues = ValueVTs.
size();
12408 if (NumValues == 0)
12415 if (Ins[i].
Flags.isCopyElisionCandidate()) {
12416 unsigned NumParts = 0;
12417 for (EVT VT : ValueVTs)
12418 NumParts +=
TLI->getNumRegistersForCallingConv(*
CurDAG->getContext(),
12419 F.getCallingConv(), VT);
12423 ArrayRef(&InVals[i], NumParts), ArgHasUses);
12428 bool isSwiftErrorArg =
12429 TLI->supportSwiftError() &&
12430 Arg.hasAttribute(Attribute::SwiftError);
12431 if (!ArgHasUses && !isSwiftErrorArg) {
12432 SDB->setUnusedArgValue(&Arg, InVals[i]);
12435 if (FrameIndexSDNode *FI =
12437 FuncInfo->setArgumentFrameIndex(&Arg, FI->getIndex());
12440 for (
unsigned Val = 0; Val != NumValues; ++Val) {
12441 EVT VT = ValueVTs[Val];
12442 MVT PartVT =
TLI->getRegisterTypeForCallingConv(*
CurDAG->getContext(),
12443 F.getCallingConv(), VT);
12444 unsigned NumParts =
TLI->getNumRegistersForCallingConv(
12445 *
CurDAG->getContext(),
F.getCallingConv(), VT);
12450 if (ArgHasUses || isSwiftErrorArg) {
12451 std::optional<ISD::NodeType> AssertOp;
12452 if (Arg.hasAttribute(Attribute::SExt))
12454 else if (Arg.hasAttribute(Attribute::ZExt))
12459 NewRoot,
F.getCallingConv(), AssertOp);
12462 if (NoFPClass !=
fcNone) {
12464 static_cast<uint64_t>(NoFPClass), dl, MVT::i32);
12466 OutVal, SDNoFPClass);
12475 if (ArgValues.
empty())
12479 if (FrameIndexSDNode *FI =
12481 FuncInfo->setArgumentFrameIndex(&Arg, FI->getIndex());
12484 SDB->getCurSDLoc());
12486 SDB->setValue(&Arg, Res);
12496 if (LoadSDNode *LNode =
12498 if (FrameIndexSDNode *FI =
12500 FuncInfo->setArgumentFrameIndex(&Arg, FI->getIndex());
12528 FuncInfo->InitializeRegForValue(&Arg);
12529 SDB->CopyToExportRegsIfNeeded(&Arg);
12533 if (!Chains.
empty()) {
12540 assert(i == InVals.
size() &&
"Argument register count mismatch!");
12544 if (!ArgCopyElisionFrameIndexMap.
empty()) {
12545 for (MachineFunction::VariableDbgInfo &VI :
12546 MF->getInStackSlotVariableDbgInfo()) {
12547 auto I = ArgCopyElisionFrameIndexMap.
find(
VI.getStackSlot());
12548 if (
I != ArgCopyElisionFrameIndexMap.
end())
12549 VI.updateStackSlot(
I->second);
12564SelectionDAGBuilder::HandlePHINodesInSuccessorBlocks(
const BasicBlock *LLVMBB) {
12565 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
12567 SmallPtrSet<MachineBasicBlock *, 4> SuccsHandled;
12573 MachineBasicBlock *SuccMBB =
FuncInfo.getMBB(SuccBB);
12577 if (!SuccsHandled.
insert(SuccMBB).second)
12585 for (
const PHINode &PN : SuccBB->phis()) {
12587 if (PN.use_empty())
12591 if (PN.getType()->isEmptyTy())
12595 const Value *PHIOp = PN.getIncomingValueForBlock(LLVMBB);
12600 RegOut =
FuncInfo.CreateRegs(PHIOp);
12611 auto I =
FuncInfo.ValueMap.find(PHIOp);
12617 "Didn't codegen value into a register!??");
12627 for (EVT VT : ValueVTs) {
12629 for (
unsigned i = 0; i != NumRegisters; ++i)
12631 Reg += NumRegisters;
12651void SelectionDAGBuilder::updateDAGForMaybeTailCall(
SDValue MaybeTC) {
12653 if (MaybeTC.
getNode() !=
nullptr)
12654 DAG.setRoot(MaybeTC);
12659void SelectionDAGBuilder::lowerWorkItem(SwitchWorkListItem W,
Value *
Cond,
12663 MachineBasicBlock *NextMBB =
nullptr;
12668 unsigned Size =
W.LastCluster -
W.FirstCluster + 1;
12670 BranchProbabilityInfo *BPI =
FuncInfo.BPI;
12672 if (
Size == 2 &&
W.MBB == SwitchMBB) {
12680 CaseCluster &
Small = *
W.FirstCluster;
12681 CaseCluster &
Big = *
W.LastCluster;
12685 const APInt &SmallValue =
Small.Low->getValue();
12686 const APInt &BigValue =
Big.Low->getValue();
12689 APInt CommonBit = BigValue ^ SmallValue;
12696 DAG.getConstant(CommonBit,
DL, VT));
12698 DL, MVT::i1,
Or,
DAG.getConstant(BigValue | SmallValue,
DL, VT),
12704 addSuccessorWithProb(SwitchMBB,
Small.MBB,
Small.Prob +
Big.Prob);
12706 addSuccessorWithProb(
12707 SwitchMBB, DefaultMBB,
12711 addSuccessorWithProb(SwitchMBB, DefaultMBB);
12719 DAG.getBasicBlock(DefaultMBB));
12721 DAG.setRoot(BrCond);
12733 [](
const CaseCluster &a,
const CaseCluster &b) {
12734 return a.Prob != b.Prob ?
12736 a.Low->getValue().slt(b.Low->getValue());
12743 if (
I->Prob >
W.LastCluster->Prob)
12745 if (
I->Kind ==
CC_Range &&
I->MBB == NextMBB) {
12753 BranchProbability DefaultProb =
W.DefaultProb;
12754 BranchProbability UnhandledProbs = DefaultProb;
12756 UnhandledProbs +=
I->Prob;
12758 MachineBasicBlock *CurMBB =
W.MBB;
12760 bool FallthroughUnreachable =
false;
12761 MachineBasicBlock *Fallthrough;
12762 if (
I ==
W.LastCluster) {
12764 Fallthrough = DefaultMBB;
12765 FallthroughUnreachable =
12769 CurMF->
insert(BBI, Fallthrough);
12773 UnhandledProbs -=
I->Prob;
12778 JumpTableHeader *JTH = &
SL->JTCases[
I->JTCasesIndex].first;
12779 SwitchCG::JumpTable *JT = &
SL->JTCases[
I->JTCasesIndex].second;
12782 MachineBasicBlock *JumpMBB = JT->
MBB;
12783 CurMF->
insert(BBI, JumpMBB);
12785 auto JumpProb =
I->Prob;
12786 auto FallthroughProb = UnhandledProbs;
12794 if (*SI == DefaultMBB) {
12795 JumpProb += DefaultProb / 2;
12796 FallthroughProb -= DefaultProb / 2;
12815 if (FallthroughUnreachable) {
12817 bool HasCFBranch =
false;
12820 HasCFBranch = !CFBranch->isZero();
12821 if (!HasCFBranch &&
12827 addSuccessorWithProb(CurMBB, Fallthrough, FallthroughProb);
12828 addSuccessorWithProb(CurMBB, JumpMBB, JumpProb);
12837 if (CurMBB == SwitchMBB) {
12845 BitTestBlock *BTB = &
SL->BitTestCases[
I->BTCasesIndex];
12848 for (BitTestCase &BTC : BTB->
Cases)
12860 BTB->
Prob += DefaultProb / 2;
12864 if (FallthroughUnreachable)
12868 if (CurMBB == SwitchMBB) {
12875 const Value *
RHS, *
LHS, *MHS;
12877 if (
I->Low ==
I->High) {
12892 if (FallthroughUnreachable)
12896 CaseBlock CB(
CC,
LHS,
RHS, MHS,
I->MBB, Fallthrough, CurMBB,
12899 if (CurMBB == SwitchMBB)
12902 SL->SwitchCases.push_back(CB);
12907 CurMBB = Fallthrough;
12911void SelectionDAGBuilder::splitWorkItem(
SwitchWorkList &WorkList,
12912 const SwitchWorkListItem &W,
12915 assert(
W.FirstCluster->Low->getValue().slt(
W.LastCluster->Low->getValue()) &&
12916 "Clusters not sorted?");
12917 assert(
W.LastCluster -
W.FirstCluster + 1 >= 2 &&
"Too small to split!");
12919 auto [LastLeft, FirstRight, LeftProb, RightProb] =
12920 SL->computeSplitWorkItemInfo(W);
12925 assert(PivotCluster >
W.FirstCluster);
12926 assert(PivotCluster <=
W.LastCluster);
12931 const ConstantInt *Pivot = PivotCluster->Low;
12940 MachineBasicBlock *LeftMBB;
12941 if (FirstLeft == LastLeft && FirstLeft->Kind ==
CC_Range &&
12942 FirstLeft->Low ==
W.GE &&
12943 (FirstLeft->High->getValue() + 1LL) == Pivot->
getValue()) {
12944 LeftMBB = FirstLeft->MBB;
12946 LeftMBB =
FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
12947 FuncInfo.MF->insert(BBI, LeftMBB);
12949 {LeftMBB, FirstLeft, LastLeft,
W.GE, Pivot,
W.DefaultProb / 2});
12957 MachineBasicBlock *RightMBB;
12958 if (FirstRight == LastRight && FirstRight->Kind ==
CC_Range &&
12959 W.LT && (FirstRight->High->getValue() + 1ULL) ==
W.LT->getValue()) {
12960 RightMBB = FirstRight->MBB;
12962 RightMBB =
FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
12963 FuncInfo.MF->insert(BBI, RightMBB);
12965 {RightMBB, FirstRight, LastRight, Pivot,
W.LT,
W.DefaultProb / 2});
12971 CaseBlock CB(
ISD::SETLT,
Cond, Pivot,
nullptr, LeftMBB, RightMBB,
W.MBB,
12974 if (
W.MBB == SwitchMBB)
12977 SL->SwitchCases.push_back(CB);
13002 MachineBasicBlock *SwitchMBB =
FuncInfo.MBB;
13010 unsigned PeeledCaseIndex = 0;
13011 bool SwitchPeeled =
false;
13012 for (
unsigned Index = 0;
Index < Clusters.size(); ++
Index) {
13013 CaseCluster &
CC = Clusters[
Index];
13014 if (
CC.Prob < TopCaseProb)
13016 TopCaseProb =
CC.Prob;
13017 PeeledCaseIndex =
Index;
13018 SwitchPeeled =
true;
13023 LLVM_DEBUG(
dbgs() <<
"Peeled one top case in switch stmt, prob: "
13024 << TopCaseProb <<
"\n");
13029 MachineBasicBlock *PeeledSwitchMBB =
13031 FuncInfo.MF->insert(BBI, PeeledSwitchMBB);
13034 auto PeeledCaseIt = Clusters.begin() + PeeledCaseIndex;
13035 SwitchWorkListItem
W = {SwitchMBB, PeeledCaseIt, PeeledCaseIt,
13036 nullptr,
nullptr, TopCaseProb.
getCompl()};
13037 lowerWorkItem(W,
SI.getCondition(), SwitchMBB, PeeledSwitchMBB);
13039 Clusters.erase(PeeledCaseIt);
13040 for (CaseCluster &
CC : Clusters) {
13042 dbgs() <<
"Scale the probablity for one cluster, before scaling: "
13043 <<
CC.Prob <<
"\n");
13047 PeeledCaseProb = TopCaseProb;
13048 return PeeledSwitchMBB;
13051void SelectionDAGBuilder::visitSwitch(
const SwitchInst &
SI) {
13053 BranchProbabilityInfo *BPI =
FuncInfo.BPI;
13055 Clusters.reserve(
SI.getNumCases());
13056 for (
auto I :
SI.cases()) {
13057 MachineBasicBlock *Succ =
FuncInfo.getMBB(
I.getCaseSuccessor());
13058 const ConstantInt *CaseVal =
I.getCaseValue();
13059 BranchProbability Prob =
13061 : BranchProbability(1,
SI.getNumCases() + 1);
13065 MachineBasicBlock *DefaultMBB =
FuncInfo.getMBB(
SI.getDefaultDest());
13074 MachineBasicBlock *PeeledSwitchMBB =
13075 peelDominantCaseCluster(SI, Clusters, PeeledCaseProb);
13078 MachineBasicBlock *SwitchMBB =
FuncInfo.MBB;
13079 if (Clusters.empty()) {
13080 assert(PeeledSwitchMBB == SwitchMBB);
13082 if (DefaultMBB != NextBlock(SwitchMBB)) {
13089 SL->findJumpTables(Clusters, &SI,
getCurSDLoc(), DefaultMBB,
DAG.getPSI(),
13091 SL->findBitTestClusters(Clusters, &SI);
13094 dbgs() <<
"Case clusters: ";
13095 for (
const CaseCluster &
C : Clusters) {
13101 C.Low->getValue().print(
dbgs(),
true);
13102 if (
C.Low !=
C.High) {
13104 C.High->getValue().print(
dbgs(),
true);
13111 assert(!Clusters.empty());
13115 auto DefaultProb = getEdgeProbability(PeeledSwitchMBB, DefaultMBB);
13119 DefaultMBB ==
FuncInfo.getMBB(
SI.getDefaultDest()))
13122 {PeeledSwitchMBB,
First,
Last,
nullptr,
nullptr, DefaultProb});
13124 while (!WorkList.
empty()) {
13126 unsigned NumClusters =
W.LastCluster -
W.FirstCluster + 1;
13131 splitWorkItem(WorkList, W,
SI.getCondition(), SwitchMBB);
13135 lowerWorkItem(W,
SI.getCondition(), SwitchMBB, DefaultMBB);
13139void SelectionDAGBuilder::visitStepVector(
const CallInst &
I) {
13140 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
13146void SelectionDAGBuilder::visitVectorReverse(
const CallInst &
I) {
13147 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
13152 assert(VT ==
V.getValueType() &&
"Malformed vector.reverse!");
13161 SmallVector<int, 8>
Mask;
13163 for (
unsigned i = 0; i != NumElts; ++i)
13164 Mask.push_back(NumElts - 1 - i);
13169void SelectionDAGBuilder::visitVectorDeinterleave(
const CallInst &
I,
13172 SDValue InVec =
getValue(
I.getOperand(0));
13178 EVT OutVT = ValueVTs[0];
13182 for (
unsigned i = 0; i != Factor; ++i) {
13183 assert(ValueVTs[i] == OutVT &&
"Expected VTs to be the same");
13185 DAG.getVectorIdxConstant(OutNumElts * i,
DL));
13189 DAG.getVTList(ValueVTs), SubVecs);
13193void SelectionDAGBuilder::visitVectorInterleave(
const CallInst &
I,
13196 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
13201 for (
unsigned i = 0; i < Factor; ++i) {
13204 "Expected VTs to be the same");
13212 for (
unsigned i = 0; i < Factor; ++i)
13219void SelectionDAGBuilder::visitFreeze(
const FreezeInst &
I) {
13223 unsigned NumValues = ValueVTs.
size();
13224 if (NumValues == 0)
return;
13229 for (
unsigned i = 0; i != NumValues; ++i)
13231 SDValue(
Op.getNode(),
Op.getResNo() + i));
13237void SelectionDAGBuilder::visitVectorSplice(
const CallInst &
I) {
13238 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
13243 SDValue V2 =
getValue(
I.getOperand(1));
13244 const bool IsLeft =
I.getIntrinsicID() == Intrinsic::vector_splice_left;
13262 SmallVector<int, 8>
Mask;
13263 for (
unsigned i = 0; i < NumElts; ++i)
13264 Mask.push_back(Idx + i);
13292 assert(
MI->getOpcode() == TargetOpcode::COPY &&
13293 "start of copy chain MUST be COPY");
13294 Reg =
MI->getOperand(1).getReg();
13297 assert(
Reg.isVirtual() &&
"expected COPY of virtual register");
13298 MI =
MRI.def_begin(
Reg)->getParent();
13301 if (
MI->getOpcode() == TargetOpcode::COPY) {
13302 assert(
Reg.isVirtual() &&
"expected COPY of virtual register");
13303 Reg =
MI->getOperand(1).getReg();
13304 assert(
Reg.isPhysical() &&
"expected COPY of physical register");
13307 assert(
MI->getOpcode() == TargetOpcode::INLINEASM_BR &&
13308 "end of copy chain MUST be INLINEASM_BR");
13318void SelectionDAGBuilder::visitCallBrLandingPad(
const CallInst &
I) {
13324 const TargetLowering &TLI =
DAG.getTargetLoweringInfo();
13325 const TargetRegisterInfo *
TRI =
DAG.getSubtarget().getRegisterInfo();
13326 MachineRegisterInfo &
MRI =
DAG.getMachineFunction().getRegInfo();
13329 SDValue Chain =
DAG.getRoot();
13334 for (
auto &
T : TargetConstraints) {
13335 SDISelAsmOperandInfo OpInfo(
T);
13343 switch (OpInfo.ConstraintType) {
13354 FuncInfo.MBB->addLiveIn(OriginalDef);
13362 ResultVTs.
push_back(OpInfo.ConstraintVT);
13371 ResultVTs.
push_back(OpInfo.ConstraintVT);
13379 DAG.getVTList(ResultVTs), ResultValues);
static unsigned getIntrinsicID(const SDNode *N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
Function Alias Analysis Results
Atomic ordering constants.
This file contains the simple types necessary to represent the attributes associated with functions a...
static const Function * getParent(const Value *V)
This file implements the BitVector class.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static AttributeList getReturnAttrs(FastISel::CallLoweringInfo &CLI)
Returns an AttributeList representing the attributes applied to the return value of the given call.
static Value * getCondition(Instruction *I)
const HexagonInstrInfo * TII
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
Module.h This file contains the declarations for the Module class.
static void getRegistersForValue(MachineFunction &MF, MachineIRBuilder &MIRBuilder, GISelAsmOperandInfo &OpInfo, GISelAsmOperandInfo &RefOpInfo)
Assign virtual/physical registers for the specified register operand.
static void computeConstraintToUse(const TargetLowering *TLI, TargetLowering::AsmOperandInfo &OpInfo)
This file defines an InstructionCost class that is used when calculating the cost of an instruction,...
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool isUndef(const MachineInstr &MI)
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static const Function * getCalledFunction(const Value *V)
This file provides utility analysis objects describing memory locations.
This file provides utility for Memory Model Relaxation Annotations (MMRAs).
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static unsigned getAddressSpace(const Value *V, unsigned MaxLookup)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
OptimizedStructLayoutField Field
This file contains the declarations for profiling metadata utility functions.
SmallVector< MachineOperand, 4 > Cond
MachineRegisterInfo & MRI
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
static bool hasOnlySelectUsers(const Value *Cond)
static SDValue getLoadStackGuard(SelectionDAG &DAG, const SDLoc &DL, SDValue &Chain)
Create a LOAD_STACK_GUARD node, and let it carry the target specific global variable if there exists ...
static bool getUniformBase(const Value *Ptr, SDValue &Base, SDValue &Index, SDValue &Scale, SelectionDAGBuilder *SDB, const BasicBlock *CurBB, uint64_t ElemSize)
static void failForInvalidBundles(const CallBase &I, StringRef Name, ArrayRef< uint32_t > AllowedBundles)
static void addStackMapLiveVars(const CallBase &Call, unsigned StartIdx, const SDLoc &DL, SmallVectorImpl< SDValue > &Ops, SelectionDAGBuilder &Builder)
Add a stack map intrinsic call's live variable operands to a stackmap or patchpoint target node's ope...
static const unsigned MaxParallelChains
static SDValue expandPow(const SDLoc &dl, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const TargetLowering &TLI, SDNodeFlags Flags)
visitPow - Lower a pow intrinsic.
static const CallBase * FindPreallocatedCall(const Value *PreallocatedSetup)
Given a @llvm.call.preallocated.setup, return the corresponding preallocated call.
static cl::opt< unsigned > SwitchPeelThreshold("switch-peel-threshold", cl::Hidden, cl::init(66), cl::desc("Set the case probability threshold for peeling the case from a " "switch statement. A value greater than 100 will void this " "optimization"))
static cl::opt< bool > InsertAssertAlign("insert-assert-align", cl::init(true), cl::desc("Insert the experimental `assertalign` node."), cl::ReallyHidden)
static unsigned getISDForVPIntrinsic(const VPIntrinsic &VPIntrin)
static bool handleDanglingVariadicDebugInfo(SelectionDAG &DAG, DILocalVariable *Variable, DebugLoc DL, unsigned Order, SmallVectorImpl< Value * > &Values, DIExpression *Expression)
static bool prepareDAGLevelOperands(ConstraintDecisionInfo &Info, const CallBase &Call, SelectionDAGBuilder &Builder, const TargetLowering &TLI, SelectionDAG &DAG)
Prepare DAG-level operands.
static unsigned findMatchingInlineAsmOperand(unsigned OperandNo, const std::vector< SDValue > &AsmNodeOperands)
static void patchMatchingInput(const SDISelAsmOperandInfo &OpInfo, SDISelAsmOperandInfo &MatchingOpInfo, SelectionDAG &DAG)
Make sure that the output operand OpInfo and its corresponding input operand MatchingOpInfo have comp...
static void findUnwindDestinations(FunctionLoweringInfo &FuncInfo, const BasicBlock *EHPadBB, BranchProbability Prob, SmallVectorImpl< std::pair< MachineBasicBlock *, BranchProbability > > &UnwindDests)
When an invoke or a cleanupret unwinds to the next EH pad, there are many places it could ultimately ...
static unsigned FixedPointIntrinsicToOpcode(unsigned Intrinsic)
static BranchProbability scaleCaseProbality(BranchProbability CaseProb, BranchProbability PeeledCaseProb)
static SDValue expandExp2(const SDLoc &dl, SDValue Op, SelectionDAG &DAG, const TargetLowering &TLI, SDNodeFlags Flags)
expandExp2 - Lower an exp2 intrinsic.
static SDValue expandDivFix(unsigned Opcode, const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue Scale, SelectionDAG &DAG, const TargetLowering &TLI)
static const GlobalValue * getGlobalAddressDbgOperand(const Value *V, DIExpression *&Expr, unsigned OpIdx, const MachineFunction &MF)
If V is the address of a describable global, possibly displaced by a constant, return the global and ...
static SDValue getF32Constant(SelectionDAG &DAG, unsigned Flt, const SDLoc &dl)
getF32Constant - Get 32-bit floating point constant.
static SDValue widenVectorToPartType(SelectionDAG &DAG, SDValue Val, const SDLoc &DL, EVT PartVT)
static SDValue expandLog10(const SDLoc &dl, SDValue Op, SelectionDAG &DAG, const TargetLowering &TLI, SDNodeFlags Flags)
expandLog10 - Lower a log10 intrinsic.
DenseMap< const Argument *, std::pair< const AllocaInst *, const StoreInst * > > ArgCopyElisionMapTy
static void getCopyToPartsVector(SelectionDAG &DAG, const SDLoc &dl, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, const Value *V, std::optional< CallingConv::ID > CallConv)
getCopyToPartsVector - Create a series of nodes that contain the specified value split into legal par...
static void getUnderlyingArgRegs(SmallVectorImpl< std::pair< Register, TypeSize > > &Regs, const SDValue &N)
static void getCopyToParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, const Value *V, std::optional< CallingConv::ID > CallConv=std::nullopt, ISD::NodeType ExtendKind=ISD::ANY_EXTEND)
getCopyToParts - Create a series of nodes that contain the specified value split into legal parts.
static SDValue getMemCmpLoad(const Value *PtrVal, MVT LoadVT, SelectionDAGBuilder &Builder)
static SDValue expandLog2(const SDLoc &dl, SDValue Op, SelectionDAG &DAG, const TargetLowering &TLI, SDNodeFlags Flags)
expandLog2 - Lower a log2 intrinsic.
static SDValue getAddressForMemoryInput(SDValue Chain, const SDLoc &Location, SDISelAsmOperandInfo &OpInfo, SelectionDAG &DAG)
Get a direct memory input to behave well as an indirect operand.
static bool isOnlyUsedInEntryBlock(const Argument *A, bool FastISel)
isOnlyUsedInEntryBlock - If the specified argument is only used in the entry block,...
static void diagnosePossiblyInvalidConstraint(LLVMContext &Ctx, const Value *V, const Twine &ErrMsg)
static bool collectInstructionDeps(SmallMapVector< const Instruction *, bool, 8 > *Deps, const Value *V, SmallMapVector< const Instruction *, bool, 8 > *Necessary=nullptr, unsigned Depth=0)
static void findArgumentCopyElisionCandidates(const DataLayout &DL, FunctionLoweringInfo *FuncInfo, ArgCopyElisionMapTy &ArgCopyElisionCandidates)
Scan the entry block of the function in FuncInfo for arguments that look like copies into a local all...
static bool isFunction(SDValue Op)
static SDValue GetExponent(SelectionDAG &DAG, SDValue Op, const TargetLowering &TLI, const SDLoc &dl)
GetExponent - Get the exponent:
static Register FollowCopyChain(MachineRegisterInfo &MRI, Register Reg)
static SDValue ExpandPowI(const SDLoc &DL, SDValue LHS, SDValue RHS, SelectionDAG &DAG)
ExpandPowI - Expand a llvm.powi intrinsic.
static SDValue expandLog(const SDLoc &dl, SDValue Op, SelectionDAG &DAG, const TargetLowering &TLI, SDNodeFlags Flags)
expandLog - Lower a log intrinsic.
static SDValue getCopyFromParts(SelectionDAG &DAG, const SDLoc &DL, const SDValue *Parts, unsigned NumParts, MVT PartVT, EVT ValueVT, const Value *V, SDValue InChain, std::optional< CallingConv::ID > CC=std::nullopt, std::optional< ISD::NodeType > AssertOp=std::nullopt)
getCopyFromParts - Create a value that contains the specified legal parts combined into the value the...
static SDValue getLimitedPrecisionExp2(SDValue t0, const SDLoc &dl, SelectionDAG &DAG)
static bool determineConstraints(ConstraintDecisionInfo &Info, TargetLowering::AsmOperandInfoVector &TargetConstraints, const CallBase &Call, SelectionDAGBuilder &Builder, const TargetLowering &TLI, const TargetMachine &TM, SelectionDAG &DAG, const BasicBlock *EHPadBB)
DetermineConstraints - Find the constraints to use for inline asm operands.
static bool constructOperandInfo(ConstraintDecisionInfo &Info, TargetLowering::AsmOperandInfoVector &TargetConstraints, SelectionDAGBuilder &Builder, const TargetLowering &TLI, ExtraFlags &ExtraInfo)
Construct operand info objects.
static SDValue GetSignificand(SelectionDAG &DAG, SDValue Op, const SDLoc &dl)
GetSignificand - Get the significand and build it into a floating-point number with exponent of 1:
static SDValue expandExp(const SDLoc &dl, SDValue Op, SelectionDAG &DAG, const TargetLowering &TLI, SDNodeFlags Flags)
expandExp - Lower an exp intrinsic.
static const MDNode * getRangeMetadata(const Instruction &I)
static cl::opt< unsigned, true > LimitFPPrecision("limit-float-precision", cl::desc("Generate low-precision inline sequences " "for some float libcalls"), cl::location(LimitFloatPrecision), cl::Hidden, cl::init(0))
static void tryToElideArgumentCopy(FunctionLoweringInfo &FuncInfo, SmallVectorImpl< SDValue > &Chains, DenseMap< int, int > &ArgCopyElisionFrameIndexMap, SmallPtrSetImpl< const Instruction * > &ElidedArgCopyInstrs, ArgCopyElisionMapTy &ArgCopyElisionCandidates, const Argument &Arg, ArrayRef< SDValue > ArgVals, bool &ArgHasUses)
Try to elide argument copies from memory into a local alloca.
static void ensureMatchedVecRegParts(unsigned NumRegs, unsigned NumParts, MVT RegisterVT, MVT PartVT)
Emit a fatal error if the broken down registers don't match part type or count.
static unsigned LimitFloatPrecision
LimitFloatPrecision - Generate low-precision inline sequences for some float libcalls (6,...
static SDValue getCopyFromPartsVector(SelectionDAG &DAG, const SDLoc &DL, const SDValue *Parts, unsigned NumParts, MVT PartVT, EVT ValueVT, const Value *V, SDValue InChain, std::optional< CallingConv::ID > CC)
getCopyFromPartsVector - Create a value that contains the specified legal parts combined into the val...
static bool InBlock(const Value *V, const BasicBlock *BB)
static FPClassTest getNoFPClass(const Instruction &I)
static LLVM_ATTRIBUTE_ALWAYS_INLINE MVT::SimpleValueType getSimpleVT(const uint8_t *MatcherTable, size_t &MatcherIndex)
getSimpleVT - Decode a value in MatcherTable, if it's a VBR encoded value, use GetVBR to decode it.
This file defines the SmallPtrSet class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static SymbolRef::Type getType(const Symbol *Sym)
uint16_t RegSizeInBits(const MCRegisterInfo &MRI, MCRegister RegNo)
static const fltSemantics & IEEEsingle()
static LLVM_ABI Semantics SemanticsToEnum(const llvm::fltSemantics &Sem)
static LLVM_ABI const fltSemantics * getArbitraryFPSemantics(StringRef Format)
Returns the fltSemantics for a given arbitrary FP format string, or nullptr if invalid.
Class for arbitrary precision integers.
bool isNonNegative() const
Determine if this APInt Value is non-negative (>= 0)
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
an instruction to allocate memory on the stack
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
This class represents an incoming formal argument to a Function.
LLVM_ABI bool hasAttribute(Attribute::AttrKind Kind) const
Check if an argument has a given attribute.
unsigned getArgNo() const
Return the index of this formal argument in its containing function.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
A cache of @llvm.assume calls within a function.
An instruction that atomically checks whether a specified value is in a memory location,...
an instruction that atomically reads a memory location, combines it with another value,...
@ 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.
This class holds the attributes for a particular argument, parameter, function, or return value.
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
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 bool isEntryBlock() const
Return true if this is the entry block of the containing function.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
This class represents a no-op cast from one type to another.
The address of a basic block.
Analysis providing branch probability information.
LLVM_ABI BranchProbability getEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors) const
Get an edge's probability, relative to other out-edges of the Src.
LLVM_ABI bool isEdgeHot(const BasicBlock *Src, const BasicBlock *Dst) const
Test if an edge is hot relative to other out-edges of the Src.
static constexpr BranchProbability getOne()
static uint32_t getDenominator()
static constexpr BranchProbability getUnknown()
static constexpr BranchProbability getZero()
uint32_t getNumerator() const
LLVM_ABI uint64_t scale(uint64_t Num) const
Scale a large integer.
BranchProbability getCompl() const
static void normalizeProbabilities(ProbabilityIter Begin, ProbabilityIter End)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
std::optional< OperandBundleUse > getOperandBundle(StringRef Name) const
Return an operand bundle by name, if present.
CallingConv::ID getCallingConv() const
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
LLVM_ABI bool isIndirectCall() const
Return true if the callsite is an indirect call.
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.
FunctionType * getFunctionType() const
unsigned arg_size() const
AttributeList getAttributes() const
Return the attributes for this call.
LLVM_ABI bool isTailCall() const
Tests if this call site is marked as a tail call.
CallBr instruction, tracking function calls that may not return control but instead transfer it to a ...
This class represents a function call, abstracting a target machine's calling convention.
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Conditional Branch instruction.
Class for constant bytes.
ConstantDataSequential - A vector or array constant whose element type is a simple 1/2/4/8-byte integ...
A constant value that is initialized with an expression using other constant values.
ConstantFP - Floating Point Values [float, double].
This is the shared class of boolean and integer constants.
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.
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
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.
A signed pointer, in the ptrauth sense.
uint64_t getZExtValue() const
Constant Vector Declarations.
This is an important base class in LLVM.
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 void appendOffset(SmallVectorImpl< uint64_t > &Ops, int64_t Offset)
Append Ops with operations to apply the Offset.
static bool fragmentsOverlap(const FragmentInfo &A, const FragmentInfo &B)
Check if fragments overlap between a pair of FragmentInfos.
static LLVM_ABI DIExpression * appendOpsToArg(const DIExpression *Expr, ArrayRef< uint64_t > Ops, unsigned ArgNo, bool StackValue=false)
Create a copy of Expr by appending the given list of Ops to each instance of the operand DW_OP_LLVM_a...
static LLVM_ABI std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
LLVM_ABI uint64_t getNumLocationOperands() const
Return the number of unique location operands referred to (via DW_OP_LLVM_arg) in this expression; th...
static LLVM_ABI std::optional< DIExpression * > createFragmentExpression(const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits)
Create a DIExpression to describe one part of an aggregate variable that is fragmented across multipl...
static LLVM_ABI const DIExpression * convertToUndefExpression(const DIExpression *Expr)
Removes all elements from Expr that do not apply to an undef debug value, which includes every operat...
static LLVM_ABI DIExpression * prepend(const DIExpression *Expr, uint8_t Flags, int64_t Offset=0)
Prepend DIExpr with a deref and offset operation and optionally turn it into a stack value or/and an ...
static LLVM_ABI DIExpression * prependOpcodes(const DIExpression *Expr, SmallVectorImpl< uint64_t > &Ops, bool StackValue=false, bool EntryValue=false)
Prepend DIExpr with the given opcodes and optionally turn it into a stack value.
Base class for variables.
LLVM_ABI std::optional< uint64_t > getSizeInBits() const
Determines the size of the variable's type.
A parsed version of the target data layout string in and methods for querying it.
Records a position in IR for a source label (DILabel).
Base class for non-instruction debug metadata records that have positions within IR.
DebugLoc getDebugLoc() const
Record of a variable value-assignment, aka a non instruction representation of the dbg....
LocationType getType() const
LLVM_ABI Value * getVariableLocationOp(unsigned OpIdx) const
DIExpression * getExpression() const
DILocalVariable * getVariable() const
LLVM_ABI iterator_range< location_op_iterator > location_ops() const
Get the locations corresponding to the variable referenced by the debug info intrinsic.
LLVM_ABI DILocation * getInlinedAt() const
iterator find(const_arg_type_t< KeyT > Val)
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT, true > const_iterator
void reserve(size_type NumEntries)
Grow the DenseMap so that it can contain at least NumEntries items before resizing again.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Diagnostic information for inline asm reporting.
static constexpr ElementCount getFixed(ScalarTy MinVal)
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
constexpr bool isScalar() const
Exactly one element.
Lightweight error class with error context and mandatory checking.
Class representing an expression and its matching format.
This instruction compares its operands according to the predicate given to the constructor.
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
bool allowReassoc() const
Flag queries.
An instruction for ordering other memory operations.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
This class represents a freeze function that returns random concrete value if an operand is either a ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
BranchProbabilityInfo * BPI
MachineBasicBlock * getMBB(const BasicBlock *BB) const
DenseMap< const AllocaInst *, int > StaticAllocaMap
StaticAllocaMap - Keep track of frame indices for fixed sized allocas in the entry block.
const LiveOutInfo * GetLiveOutRegInfo(Register Reg)
GetLiveOutRegInfo - Gets LiveOutInfo for a register, returning NULL if the register is a PHI destinat...
MachineBasicBlock * MBB
MBB - The current block.
Class to represent function types.
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Type * getParamType(unsigned i) const
Parameter type accessors.
Type * getReturnType() const
Data structure describing the variable locations in a function.
const BasicBlock & getEntryBlock() const
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
bool hasParamAttribute(unsigned ArgNo, Attribute::AttrKind Kind) const
check if an attributes is in the list of attributes.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Constant * getPersonalityFn() const
Get the personality function associated with this function.
AttributeList getAttributes() const
Return the attribute list for this Function.
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Garbage collection metadata for a single function.
bool hasNoUnsignedSignedWrap() const
bool hasNoUnsignedWrap() const
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
bool hasDLLImportStorageClass() const
Module * getParent()
Get the module that this global value is contained inside of...
This instruction compares its operands according to the predicate given to the constructor.
Indirect Branch Instruction.
void setMemConstraint(ConstraintCode C)
setMemConstraint - Augment an existing flag with the constraint code for a memory constraint.
This instruction inserts a struct field of array element value into an aggregate value.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
LLVM_ABI AAMDNodes getAAMetadata() const
Returns the AA metadata for this instruction.
@ MIN_INT_BITS
Minimum number of bits that can be specified.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
This is an important class for using LLVM in a threaded context.
@ OB_clang_arc_attachedcall
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
The landingpad instruction holds all of the information necessary to generate correct exception handl...
A helper class to return the specified delimiter string after the first invocation of operator String...
An instruction for reading from memory.
static LocationSize precise(uint64_t Value)
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
static LocationSize upperBound(uint64_t Value)
bool usesPerInvokeEHLabels(ExceptionHandling EH) const
Returns true if the exception tables reference the per-invoke EH labels emitted around invokes.
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
LLVM_ABI MCSymbol * getOrCreateFrameAllocSymbol(const Twine &FuncName, unsigned Idx)
Gets a symbol that will be defined to the final stack offset of a local variable after codegen.
const MCAsmInfo & getAsmInfo() const
unsigned getID() const
getID() - Return the register class ID number.
const MCPhysReg * iterator
iterator begin() const
begin/end - Return all of the registers in this class.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
const MDOperand & getOperand(unsigned I) const
LLVM_ABI StringRef getString() const
@ INVALID_SIMPLE_VALUE_TYPE
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
std::string getString() const
Return the value type as a string, e.g. i32.
ElementCount getVectorElementCount() const
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool bitsGE(MVT VT) const
Return true if this has no less bits than VT.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
static MVT getVectorVT(MVT VT, unsigned NumElements)
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
bool isValid() const
Return true if this is a valid simple valuetype.
static MVT getIntegerVT(unsigned BitWidth)
void normalizeSuccProbs()
Normalize probabilities of all successors so that the sum of them becomes one.
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
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void setIsEHContTarget(bool V=true)
Indicates if this is a target of Windows EH Continuation Guard.
void setIsEHFuncletEntry(bool V=true)
Indicates if this is the entry block of an EH funclet.
MachineInstrBundleIterator< MachineInstr > iterator
void setIsEHScopeEntry(bool V=true)
Indicates if this is the entry block of an EH scope, i.e., the block that that used to have a catchpa...
void setMachineBlockAddressTaken()
Set this block to indicate that its address is used as something other than the target of a terminato...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setIsImmutableObjectIndex(int ObjectIdx, bool IsImmutable)
Marks the immutability of an object.
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
bool hasOpaqueSPAdjustment() const
Returns true if the function contains opaque dynamic stack adjustments.
int getStackProtectorIndex() const
Return the index for the stack protector object.
void setStackProtectorIndex(int I)
void setIsAliasedObjectIndex(int ObjectIdx, bool IsAliased)
Set "maybe pointed to by an LLVM IR value" for an object.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
void RemoveStackObject(int ObjectIdx)
Remove or mark dead a statically sized stack object.
void setFunctionContextIndex(int I)
const WinEHFuncInfo * getWinEHFuncInfo() const
getWinEHFuncInfo - Return information about how the current function uses Windows exception handling.
bool useDebugInstrRef() const
Returns true if the function's variable locations are tracked with instruction referencing.
void setCallSiteBeginLabel(MCSymbol *BeginLabel, unsigned Site)
Map the begin label for a call site.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
void addCodeViewAnnotation(MCSymbol *Label, MDNode *MD)
Record annotations associated with a particular label.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
bool hasEHFunclets() const
void setHasEHContTarget(bool V)
void addInvoke(MachineBasicBlock *LandingPad, MCSymbol *BeginLabel, MCSymbol *EndLabel)
Provide the begin and end labels of an invoke style call and associate it with a try landing pad bloc...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
Representation of each machine instruction.
A description of a memory reference used in the backend.
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.
@ MONonTemporal
The memory access is non-temporal.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
static MachineOperand CreateFI(int Idx)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI MCRegister getLiveInPhysReg(Register VReg) const
getLiveInPhysReg - If VReg is a live-in virtual register, return the corresponding live-in physical r...
An SDNode that represents everything that will be needed to construct a MachineInstr.
std::pair< iterator, bool > try_emplace(const KeyT &Key, Ts &&...Args)
bool contains(const KeyT &Key) const
static MemoryLocation getAfter(const Value *Ptr, const AAMDNodes &AATags=AAMDNodes())
Return a location that may access any location after Ptr, while remaining within the underlying objec...
A Module instance is used to store all the information related to an LLVM module.
Metadata * getModuleFlag(StringRef Key) const
Return the corresponding value if Key appears in module flags, otherwise return null.
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Resume the propagation of an exception.
Return a value (possibly void), from a function.
Holds the information from a dbg_label node through SDISel.
static SDDbgOperand fromNode(SDNode *Node, unsigned ResNo)
static SDDbgOperand fromFrameIdx(unsigned FrameIdx)
static SDDbgOperand fromVReg(Register VReg)
static SDDbgOperand fromConst(const Value *Const)
static SDDbgOperand fromGlobalAddr(const GlobalValue *GV)
Holds the information from a dbg_value node through SDISel.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
const DebugLoc & getDebugLoc() const
Represents one node in the SelectionDAG.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
iterator_range< value_op_iterator > op_values() const
unsigned getIROrder() const
Return the node ordering.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
const SDValue & getOperand(unsigned Num) const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
unsigned getResNo() const
get the index which selects a specific result in the SDNode
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getOpcode() const
SelectionDAGBuilder - This is the common target-independent lowering implementation that is parameter...
SDValue getValue(const Value *V)
getValue - Return an SDValue for the given Value.
bool shouldKeepJumpConditionsTogether(const FunctionLoweringInfo &FuncInfo, const CondBrInst &I, Instruction::BinaryOps Opc, const Value *Lhs, const Value *Rhs, TargetLoweringBase::CondMergingParams Params) const
DenseMap< const Constant *, Register > ConstantsOut
void addDanglingDebugInfo(SmallVectorImpl< Value * > &Values, DILocalVariable *Var, DIExpression *Expr, bool IsVariadic, DebugLoc DL, unsigned Order)
Register a dbg_value which relies on a Value which we have not yet seen.
void visitDbgInfo(const Instruction &I)
void clearDanglingDebugInfo()
Clear the dangling debug information map.
SDValue lowerStartEH(SDValue Chain, const BasicBlock *EHPadBB, MCSymbol *&BeginLabel)
void LowerCallTo(const CallBase &CB, SDValue Callee, bool IsTailCall, bool IsMustTailCall, const BasicBlock *EHPadBB=nullptr, const TargetLowering::PtrAuthInfo *PAI=nullptr)
void clear()
Clear out the current SelectionDAG and the associated state and prepare this SelectionDAGBuilder obje...
void visitBitTestHeader(SwitchCG::BitTestBlock &B, MachineBasicBlock *SwitchBB)
visitBitTestHeader - This function emits necessary code to produce value suitable for "bit tests"
void LowerStatepoint(const GCStatepointInst &I, const BasicBlock *EHPadBB=nullptr)
std::unique_ptr< SDAGSwitchLowering > SL
SDValue lowerRangeToAssertZExt(SelectionDAG &DAG, const Instruction &I, SDValue Op)
bool HasTailCall
This is set to true if a call in the current block has been translated as a tail call.
bool ShouldEmitAsBranches(const std::vector< SwitchCG::CaseBlock > &Cases)
If the set of cases should be emitted as a series of branches, return true.
void EmitBranchForMergedCondition(const Value *Cond, MachineBasicBlock *TBB, MachineBasicBlock *FBB, MachineBasicBlock *CurBB, MachineBasicBlock *SwitchBB, BranchProbability TProb, BranchProbability FProb, bool InvertCond)
EmitBranchForMergedCondition - Helper method for FindMergedConditions.
void LowerDeoptimizeCall(const CallInst *CI)
void LowerCallSiteWithDeoptBundle(const CallBase *Call, SDValue Callee, const BasicBlock *EHPadBB)
SwiftErrorValueTracking & SwiftError
Information about the swifterror values used throughout the function.
SDValue getNonRegisterValue(const Value *V)
getNonRegisterValue - Return an SDValue for the given Value, but don't look in FuncInfo....
const TargetTransformInfo * TTI
DenseMap< MachineBasicBlock *, SmallVector< unsigned, 4 > > LPadToCallSiteMap
Map a landing pad to the call site indexes.
SDValue lowerNoFPClassToAssertNoFPClass(SelectionDAG &DAG, const Instruction &I, SDValue Op)
void handleDebugDeclare(Value *Address, DILocalVariable *Variable, DIExpression *Expression, DebugLoc DL)
StatepointLoweringState StatepointLowering
State used while lowering a statepoint sequence (gc_statepoint, gc_relocate, and gc_result).
void setValueToPoison(const Value *V, const SDLoc &dl)
void visitBitTestCase(SwitchCG::BitTestBlock &BB, MachineBasicBlock *NextMBB, BranchProbability BranchProbToNext, Register Reg, SwitchCG::BitTestCase &B, MachineBasicBlock *SwitchBB)
visitBitTestCase - this function produces one "bit test"
bool canTailCall(const CallBase &CB) const
void populateCallLoweringInfo(TargetLowering::CallLoweringInfo &CLI, const CallBase *Call, unsigned ArgIdx, unsigned NumArgs, SDValue Callee, Type *ReturnTy, AttributeSet RetAttrs, bool IsPatchPoint)
Populate a CallLowerinInfo (into CLI) based on the properties of the call being lowered.
void CopyValueToVirtualRegister(const Value *V, Register Reg, ISD::NodeType ExtendType=ISD::ANY_EXTEND)
void salvageUnresolvedDbgValue(const Value *V, DanglingDebugInfo &DDI)
For the given dangling debuginfo record, perform last-ditch efforts to resolve the debuginfo to somet...
SmallVector< SDValue, 8 > PendingLoads
Loads are not emitted to the program immediately.
GCFunctionInfo * GFI
Garbage collection metadata for the function.
void init(GCFunctionInfo *gfi, BatchAAResults *BatchAA, AssumptionCache *AC, const TargetLibraryInfo *li, const TargetTransformInfo &TTI)
SDValue getRoot()
Similar to getMemoryRoot, but also flushes PendingConstrainedFP(Strict) items.
void ExportFromCurrentBlock(const Value *V)
ExportFromCurrentBlock - If this condition isn't known to be exported from the current basic block,...
DebugLoc getCurDebugLoc() const
void resolveOrClearDbgInfo()
Evict any dangling debug information, attempting to salvage it first.
std::pair< SDValue, SDValue > lowerInvokable(TargetLowering::CallLoweringInfo &CLI, const BasicBlock *EHPadBB=nullptr)
SDValue getMemoryRoot()
Return the current virtual root of the Selection DAG, flushing any PendingLoad items.
void resolveDanglingDebugInfo(const Value *V, SDValue Val)
If we saw an earlier dbg_value referring to V, generate the debug data structures now that we've seen...
SDLoc getCurSDLoc() const
void visit(const Instruction &I)
void dropDanglingDebugInfo(const DILocalVariable *Variable, const DIExpression *Expr)
If we have dangling debug info that describes Variable, or an overlapping part of variable considerin...
SDValue getCopyFromRegs(const Value *V, Type *Ty)
If there was virtual register allocated for the value V emit CopyFromReg of the specified type Ty.
void CopyToExportRegsIfNeeded(const Value *V)
CopyToExportRegsIfNeeded - If the given value has virtual registers created for it,...
void handleKillDebugValue(DILocalVariable *Var, DIExpression *Expr, DebugLoc DbgLoc, unsigned Order)
Create a record for a kill location debug intrinsic.
void visitJumpTable(SwitchCG::JumpTable &JT)
visitJumpTable - Emit JumpTable node in the current MBB
SDValue getFPOperationRoot(fp::ExceptionBehavior EB)
Return the current virtual root of the Selection DAG, flushing PendingConstrainedFP or PendingConstra...
void visitJumpTableHeader(SwitchCG::JumpTable &JT, SwitchCG::JumpTableHeader &JTH, MachineBasicBlock *SwitchBB)
visitJumpTableHeader - This function emits necessary code to produce index in the JumpTable from swit...
void LowerCallSiteWithPtrAuthBundle(const CallBase &CB, const BasicBlock *EHPadBB)
static const unsigned LowestSDNodeOrder
Lowest valid SDNodeOrder.
void LowerDeoptimizingReturn()
FunctionLoweringInfo & FuncInfo
Information about the function as a whole.
void setValue(const Value *V, SDValue NewN)
void FindMergedConditions(const Value *Cond, MachineBasicBlock *TBB, MachineBasicBlock *FBB, MachineBasicBlock *CurBB, MachineBasicBlock *SwitchBB, Instruction::BinaryOps Opc, BranchProbability TProb, BranchProbability FProb, bool InvertCond)
const TargetLibraryInfo * LibInfo
bool isExportableFromCurrentBlock(const Value *V, const BasicBlock *FromBB)
void visitSPDescriptorParent(StackProtectorDescriptor &SPD, MachineBasicBlock *ParentBB)
Codegen a new tail for a stack protector check ParentMBB which has had its tail spliced into a stack ...
bool handleDebugValue(ArrayRef< const Value * > Values, DILocalVariable *Var, DIExpression *Expr, DebugLoc DbgLoc, unsigned Order, bool IsVariadic)
For a given list of Values, attempt to create and record a SDDbgValue in the SelectionDAG.
SDValue getControlRoot()
Similar to getRoot, but instead of flushing all the PendingLoad items, flush all the PendingExports (...
void UpdateSplitBlock(MachineBasicBlock *First, MachineBasicBlock *Last)
When an MBB was split during scheduling, update the references that need to refer to the last resulti...
SDValue getValueImpl(const Value *V)
getValueImpl - Helper function for getValue and getNonRegisterValue.
void visitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB)
visitSwitchCase - Emits the necessary code to represent a single node in the binary search tree resul...
void visitSPDescriptorFailure(StackProtectorDescriptor &SPD)
Codegen the failure basic block for a stack protector check.
std::unique_ptr< FunctionLoweringInfo > FuncInfo
SmallPtrSet< const Instruction *, 4 > ElidedArgCopyInstrs
const TargetLowering * TLI
MachineRegisterInfo * RegInfo
std::unique_ptr< SwiftErrorValueTracking > SwiftError
virtual void emitFunctionEntryCode()
std::unique_ptr< SelectionDAGBuilder > SDB
virtual std::pair< SDValue, SDValue > EmitTargetCodeForMemccpy(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src, SDValue C, SDValue Size, const CallInst *CI) const
Emit target-specific code that performs a memccpy, in cases where that is faster than a libcall.
virtual std::pair< SDValue, SDValue > EmitTargetCodeForStrnlen(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Src, SDValue MaxLength, MachinePointerInfo SrcPtrInfo) const
virtual std::pair< SDValue, SDValue > EmitTargetCodeForStrlen(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Src, const CallInst *CI) const
virtual std::pair< SDValue, SDValue > EmitTargetCodeForStrstr(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Op1, SDValue Op2, const CallInst *CI) const
Emit target-specific code that performs a strstr, in cases where that is faster than a libcall.
virtual std::pair< SDValue, SDValue > EmitTargetCodeForMemchr(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Src, SDValue Char, SDValue Length, MachinePointerInfo SrcPtrInfo) const
Emit target-specific code that performs a memchr, in cases where that is faster than a libcall.
virtual std::pair< SDValue, SDValue > EmitTargetCodeForStrcmp(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Op1, SDValue Op2, MachinePointerInfo Op1PtrInfo, MachinePointerInfo Op2PtrInfo, const CallInst *CI) const
Emit target-specific code that performs a strcmp, in cases where that is faster than a libcall.
virtual std::pair< SDValue, SDValue > EmitTargetCodeForMemcmp(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Op1, SDValue Op2, SDValue Op3, const CallInst *CI) const
Emit target-specific code that performs a memcmp/bcmp, in cases where that is faster than a libcall.
virtual SDValue EmitTargetCodeForSetTag(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Addr, SDValue Size, MachinePointerInfo DstPtrInfo, bool ZeroData) const
virtual std::pair< SDValue, SDValue > EmitTargetCodeForStrcpy(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Dest, SDValue Src, MachinePointerInfo DestPtrInfo, MachinePointerInfo SrcPtrInfo, bool isStpcpy, const CallInst *CI) const
Emit target-specific code that performs a strcpy or stpcpy, in cases where that is faster than a libc...
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT, unsigned Opcode)
Convert Op, which must be of integer type, to the integer type VT, by either any/sign/zero-extending ...
const SDValue & getRoot() const
Return the root tag of the SelectionDAG.
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getShiftAmountConstant(uint64_t Val, EVT VT, const SDLoc &DL)
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI void ExtractVectorElements(SDValue Op, SmallVectorImpl< SDValue > &Args, unsigned Start=0, unsigned Count=0, EVT EltVT=EVT())
Append the extracted elements from Start to Count out of the vector Op in Args.
LLVM_ABI SDValue getConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offs=0, bool isT=false, unsigned TargetFlags=0)
LLVM_ABI SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI Align getEVTAlign(EVT MemoryVT) const
Compute the default alignment value for the given type.
LLVM_ABI bool shouldOptForSize() const
const TargetLowering & getTargetLoweringInfo() const
static constexpr unsigned MaxRecursionDepth
LLVM_ABI void AddDbgValue(SDDbgValue *DB, bool isParameter)
Add a dbg_value SDNode.
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, SDValue Offset, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
LLVM_ABI SDDbgValue * getDbgValueList(DIVariable *Var, DIExpression *Expr, ArrayRef< SDDbgOperand > Locs, ArrayRef< SDNode * > Dependencies, bool IsIndirect, const DebugLoc &DL, unsigned O, bool IsVariadic)
Creates a SDDbgValue node from a list of locations.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
LLVM_ABI void setNodeMemRefs(MachineSDNode *N, ArrayRef< MachineMemOperand * > NewMemRefs)
Mutate the specified machine node's memory references to the provided list.
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
LLVM_ABI SDValue getMemBasePlusOffset(SDValue Base, TypeSize Offset, const SDLoc &DL, const SDNodeFlags Flags=SDNodeFlags())
Returns sum of the base pointer and offset.
LLVM_ABI SDValue getMDNode(const MDNode *MD)
Return an MDNodeSDNode which holds an MDNode.
LLVM_ABI SDValue getBasicBlock(MachineBasicBlock *MBB)
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI SDValue getEHLabel(const SDLoc &dl, SDValue Root, MCSymbol *Label)
LLVM_ABI SDValue getPtrExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either truncating it or perform...
LLVM_ABI SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
const LibcallLoweringInfo & getLibcalls() const
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
LLVM_ABI SDValue getFPExtendOrRound(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of float type, to the float type VT, by either extending or rounding (by tr...
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
MachineFunction & getMachineFunction() const
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVMContext * getContext() const
const SDValue & setRoot(SDValue N)
Set the current root tag of the SelectionDAG.
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void swap(SmallVectorImpl &RHS)
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
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()
MachineBasicBlock * getParentMBB()
bool shouldEmitFunctionBasedCheckStackProtector() const
An instruction for storing to memory.
Represent a constant reference to a string, i.e.
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).
Information about stack frame layout on the target.
virtual TargetStackID::Value getStackIDForScalableVectors() const
Returns the StackID that scalable vectors should be associated with.
Provides information about what library functions are available for the current target.
virtual Align getByValTypeAlignment(Type *Ty, const DataLayout &DL) const
Returns the desired alignment for ByVal or InAlloca aggregate function arguments in the caller parame...
virtual bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT) const
Return true if an FMA operation is faster than a pair of fmul and fadd instructions.
EVT getMemValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
virtual bool isAtomicAlignmentSupported(Align Alignment, uint64_t SizeInBytes) const
Return true if the target supports an atomic access of SizeInBytes bytes at the given Alignment.
Function * getSSPStackGuardCheck(const Module &M, const LibcallLoweringInfo &Libcalls) const
If the target has a standard stack protection check function that performs validation and error handl...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
LegalizeAction
This enum indicates whether operations are valid for a target, and if not, what action should be used...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
virtual bool isLegalScaleForGatherScatter(uint64_t Scale, uint64_t ElemSize) const
virtual bool isSExtCheaperThanZExt(EVT FromTy, EVT ToTy) const
Return true if sign-extension from FromTy to ToTy is cheaper than zero-extension.
MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
virtual unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain targets require unusual breakdowns of certain types.
virtual MachineMemOperand::Flags getTargetMMOFlags(const Instruction &I) const
This callback is used to inspect load/store instructions and add target-specific MachineMemOperand fl...
virtual Register getExceptionSelectorRegister(ExceptionHandling EH, const Constant *PersonalityFn) const
If a physical register, this returns the register that receives the exception typeid on entry to a la...
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
virtual MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
virtual bool useStackGuardMixFP() const
If this function returns true, stack protection checks should mix the frame pointer (or whichever poi...
MVT getRegisterType(LLVMContext &Context, EVT VT) const
Return the type of registers that this ValueType will eventually require.
virtual unsigned getNumRegisters(LLVMContext &Context, EVT VT, std::optional< MVT > RegisterVT=std::nullopt) const
Return the number of registers that this ValueType will eventually require.
MachineMemOperand::Flags getLoadMemOperandFlags(const LoadInst &LI, const DataLayout &DL, AssumptionCache *AC=nullptr, const TargetLibraryInfo *LibInfo=nullptr, CodeGenOptLevel OptLevel=CodeGenOptLevel::Default) const
virtual bool shouldExtendGSIndex(EVT VT, EVT &EltTy) const
Returns true if the index type for a masked gather/scatter requires extending.
virtual unsigned getVectorTypeBreakdownForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT, unsigned &NumIntermediates, MVT &RegisterVT) const
Certain targets such as MIPS require that some types such as vectors are always broken down into scal...
Register getStackPointerRegisterToSaveRestore() const
If a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save...
LegalizeAction getFixedPointOperationAction(unsigned Op, EVT VT, unsigned Scale) const
Some fixed point operations may be natively supported by the target but only for specific scales.
MachineMemOperand::Flags getAtomicMemOperandFlags(const Instruction &AI, const DataLayout &DL) const
virtual bool allowsMisalignedMemoryAccesses(EVT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *=nullptr) const
Determine if the target supports unaligned memory accesses.
bool isOperationCustom(unsigned Op, EVT VT) const
Return true if the operation uses custom lowering, regardless of whether the type is legal or not.
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const
When splitting a value of the specified type into parts, does the Lo or Hi part come first?
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const
Returns the type for the shift amount of a shift opcode.
virtual Align getABIAlignmentForCallingConv(Type *ArgTy, const DataLayout &DL) const
Certain targets have context sensitive alignment requirements, where one type has the alignment requi...
MachineMemOperand::Flags getVPIntrinsicMemOperandFlags(const VPIntrinsic &VPIntrin) const
virtual bool shouldExpandGetActiveLaneMask(EVT VT, EVT OpVT) const
Return true if the @llvm.get.active.lane.mask intrinsic should be expanded using generic code in Sele...
virtual EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const
Return the ValueType of the result of SETCC operations.
virtual EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const
For types supported by the target, this is an identity function.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
MVT getProgramPointerTy(const DataLayout &DL) const
Return the type for code pointers, which is determined by the program address space specified through...
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
virtual bool isProfitableToCombineMinNumMaxNum(EVT VT) const
virtual MVT getFenceOperandTy(const DataLayout &DL) const
Return the type for operands of fence.
virtual bool shouldExpandGetVectorLength(EVT CountVT, unsigned VF, bool IsScalable) const
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
unsigned getVectorTypeBreakdown(LLVMContext &Context, EVT VT, EVT &IntermediateVT, unsigned &NumIntermediates, MVT &RegisterVT) const
Vector types are broken down into some number of legal first class types.
virtual MVT hasFastEqualityCompare(unsigned NumBits) const
Return the preferred operand type if the target has a quick way to compare integer values of the give...
MachineMemOperand::Flags getStoreMemOperandFlags(const StoreInst &SI, const DataLayout &DL) const
virtual void getTgtMemIntrinsic(SmallVectorImpl< IntrinsicInfo > &Infos, const CallBase &I, MachineFunction &MF, unsigned Intrinsic) const
Given an intrinsic, checks if on the target the intrinsic will need to map to a MemIntrinsicNode (tou...
virtual bool signExtendConstant(const ConstantInt *C) const
Return true if this constant should be sign extended when promoting to a larger type.
virtual Value * getSDagStackGuard(const Module &M, const LibcallLoweringInfo &Libcalls) const
Return the variable that's previously inserted by insertSSPDeclarations, if any, otherwise return nul...
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
std::vector< ArgListEntry > ArgListTy
virtual Register getExceptionPointerRegister(ExceptionHandling EH, const Constant *PersonalityFn) const
If a physical register, this returns the register that receives the exception address on entry to an ...
bool isBeneficialToExpandPowI(int64_t Exponent, bool OptForSize) const
Return true if it is beneficial to expand an @llvm.powi.
MVT getFrameIndexTy(const DataLayout &DL) const
Return the type for frame index, which is determined by the alloca address space specified through th...
virtual MVT getPointerMemTy(const DataLayout &DL, uint32_t AS=0) const
Return the in-memory pointer type for the given address space, defaults to the pointer type from the ...
virtual MVT getVPExplicitVectorLengthTy() const
Returns the type to be used for the EVL/AVL operand of VP nodes: ISD::VP_UDIV, ISD::VP_SDIV,...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual bool supportKCFIBundles() const
Return true if the target supports kcfi operand bundles.
virtual bool supportPtrAuthBundles() const
Return true if the target supports ptrauth operand bundles.
virtual bool supportSwiftError() const
Return true if the target supports swifterror attribute.
virtual SDValue visitMaskedLoad(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, MachineMemOperand *MMO, SDValue &NewLoad, SDValue Ptr, SDValue PassThru, SDValue Mask) const
virtual EVT getTypeForExtReturn(LLVMContext &Context, EVT VT, ISD::NodeType) const
Return the type that should be used to zero or sign extend a zeroext/signext integer return value.
virtual Register getRegisterByName(const char *RegName, LLT Ty, const MachineFunction &MF) const
Return the register ID of the name passed in.
virtual InlineAsm::ConstraintCode getInlineAsmMemConstraint(StringRef ConstraintCode) const
std::vector< AsmOperandInfo > AsmOperandInfoVector
SDValue expandIS_FPCLASS(EVT ResultVT, SDValue Op, FPClassTest Test, SDNodeFlags Flags, const SDLoc &DL, SelectionDAG &DAG) const
Expand check for floating point class.
virtual SDValue prepareVolatileOrAtomicLoad(SDValue Chain, const SDLoc &DL, SelectionDAG &DAG) const
This callback is used to prepare for a volatile or atomic load.
virtual SDValue emitStackGuardMixFP(SelectionDAG &DAG, SDValue Val, const SDLoc &DL) const
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, std::optional< CallingConv::ID > CC) const
Target-specific splitting of values into parts that fit a register storing a legal type.
virtual SDValue joinRegisterPartsIntoValue(SelectionDAG &DAG, const SDLoc &DL, const SDValue *Parts, unsigned NumParts, MVT PartVT, EVT ValueVT, std::optional< CallingConv::ID > CC) const
Target-specific combining of register parts into its original value.
virtual SDValue LowerCall(CallLoweringInfo &, SmallVectorImpl< SDValue > &) const
This hook must be implemented to lower calls into the specified DAG.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
virtual bool supportsInlineAsmFuncOperands() const
Return true if a function used as an inline asm address operand (e.g.
virtual SDValue LowerAsmOutputForConstraint(SDValue &Chain, SDValue &Glue, const SDLoc &DL, const AsmOperandInfo &OpInfo, SelectionDAG &DAG) const
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
virtual AsmOperandInfoVector ParseConstraints(const DataLayout &DL, const TargetRegisterInfo *TRI, const CallBase &Call) const
Split up the constraint string from the inline assembly value into the specific constraints and their...
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const
This callback is invoked for operations that are unsupported by the target, which are registered to u...
virtual bool functionArgumentNeedsConsecutiveRegisters(Type *Ty, CallingConv::ID CallConv, bool isVarArg, const DataLayout &DL) const
For some targets, an LLVM struct type must be broken down into multiple simple types,...
virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo, SDValue Op, SelectionDAG *DAG=nullptr) const
Determines the constraint code and constraint type to use for the specific AsmOperandInfo,...
virtual void CollectTargetIntrinsicOperands(const CallInst &I, SmallVectorImpl< SDValue > &Ops, SelectionDAG &DAG) const
virtual SDValue visitMaskedStore(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, MachineMemOperand *MMO, SDValue Ptr, SDValue Val, SDValue Mask) const
virtual bool useLoadStackGuardNode(const Module &M) const
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
SDValue annotateStackObjectPointer(SDValue Ptr, SelectionDAG &DAG, const SDLoc &DL, Align Alignment) const
Annotate a stack object pointer with known-bits assertions.
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::LibcallImpl LibcallImpl, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
virtual void LowerOperationWrapper(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const
This callback is invoked by the type legalizer to legalize nodes with an illegal operand type but leg...
virtual bool isInlineAsmTargetBranch(const SmallVectorImpl< StringRef > &AsmStrs, unsigned OpNo) const
On x86, return true if the operand with index OpNo is a CALL or JUMP instruction, which can use eithe...
virtual MVT getJumpTableRegTy(const DataLayout &DL) const
virtual bool CanLowerReturn(CallingConv::ID, MachineFunction &, bool, const SmallVectorImpl< ISD::OutputArg > &, LLVMContext &, const Type *RetTy) const
This hook should be implemented to check whether the return values described by the Outs array can fi...
Primary interface to the complete machine description for the target machine.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
CodeModel::Model getCodeModel() const
Returns the code model.
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.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetFrameLowering * getFrameLowering() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
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 isVectorTy() const
True if this is an instance of VectorType.
bool isPointerTy() const
True if this is an instance of PointerType.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isTokenTy() const
Return true if this is 'token'.
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
bool isVoidTy() const
Return true if this is 'void'.
Unconditional Branch instruction.
This function has undefined behavior.
A Use represents the edge between a Value definition and its users.
unsigned getNumOperands() const
This class represents the va_arg llvm instruction, which returns an argument of the specified type gi...
This is the common base class for vector predication intrinsics.
static LLVM_ABI std::optional< unsigned > getVectorLengthParamPos(Intrinsic::ID IntrinsicID)
LLVM_ABI MaybeAlign getPointerAlignment() 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.
iterator_range< user_iterator > users()
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Base class of all SIMD vector types.
Type * getElementType() const
constexpr ScalarTy getFixedValue() const
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
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.
const ParentTy * getParent() const
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ AnyReg
OBSOLETED - Used for stack based JavaScript calls.
@ AMDGPU_CS_Chain
Used on AMDGPUs to give the middle-end more control over argument placement.
@ X86_VectorCall
MSVC calling convention that passes vectors and vector aggregates in SSE registers.
@ C
The default llvm calling convention, compatible with C.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ CONVERGENCECTRL_ANCHOR
The llvm.experimental.convergence.* intrinsics.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ SET_FPENV
Sets the current floating-point environment.
@ ATOMIC_LOAD_FMINIMUMNUM
@ LOOP_DEPENDENCE_RAW_MASK
@ MASK_BEFOREFIRST
Has one mask vector operand.
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ COND_LOOP
COND_LOOP is a conditional branch to self, used for implementing efficient conditional traps.
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ STACKADDRESS
STACKADDRESS - Represents the llvm.stackaddress intrinsic.
@ BSWAP
Byte Swap and Counting operators.
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ RESET_FPENV
Set floating-point environment to default state.
@ ADD
Simple integer binary arithmetic operators.
@ SMULFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ SET_FPMODE
Sets the current dynamic floating-point control modes.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ CTTZ_ELTS
Returns the number of number of trailing (least significant) zero elements in a vector.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ VECTOR_FIND_LAST_ACTIVE
Finds the index of the last active mask element Operands: Mask.
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FATAN2
FATAN2 - atan2, inspired by libm.
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ EH_SJLJ_SETUP_DISPATCH
OUTCHAIN = EH_SJLJ_SETUP_DISPATCH(INCHAIN) The target initializes the dispatch table here.
@ ATOMIC_CMP_SWAP_WITH_SUCCESS
Val, Success, OUTCHAIN = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap) N.b.
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
@ VECREDUCE_FMAXIMUM
FMINIMUM/FMAXIMUM nodes propatate NaNs and signed zeroes using the llvm.minimum and llvm....
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
@ RESET_FPMODE
Sets default dynamic floating-point control modes.
@ FMULADD
FMULADD - Performs a * b + c, with, or without, intermediate rounding.
@ FPTRUNC_ROUND
FPTRUNC_ROUND - This corresponds to the fptrunc_round intrinsic.
@ FAKE_USE
FAKE_USE represents a use of the operand but does not do anything.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ CLMUL
Carry-less multiplication operations.
@ INIT_TRAMPOLINE
INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ SDIVFIX
RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on 2 integers with the same width...
@ CONVERT_FROM_ARBITRARY_FP
CONVERT_FROM_ARBITRARY_FP - This operator converts from an arbitrary floating-point represented as an...
@ EH_LABEL
EH_LABEL - Represents a label in mid basic block used to track locations needed for debug and excepti...
@ EH_RETURN
OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents 'eh_return' gcc dwarf builtin,...
@ ANNOTATION_LABEL
ANNOTATION_LABEL - Represents a mid basic block label used by annotations.
@ SET_ROUNDING
Set rounding mode.
@ CONVERGENCECTRL_GLUE
This does not correspond to any convergence control intrinsic.
@ SIGN_EXTEND
Conversion operators.
@ PREALLOCATED_SETUP
PREALLOCATED_SETUP - This has 2 operands: an input chain and a SRCVALUE with the preallocated call Va...
@ READSTEADYCOUNTER
READSTEADYCOUNTER - This corresponds to the readfixedcounter intrinsic.
@ ADDROFRETURNADDR
ADDROFRETURNADDR - Represents the llvm.addressofreturnaddress intrinsic.
@ BR
Control flow instructions. These all have token chains.
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ VECREDUCE_FMAXIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM nodes do not propagate NaNs and order signed zeroes using the llvm....
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ SSUBO
Same for subtraction.
@ PREALLOCATED_ARG
PREALLOCATED_ARG - This has 3 operands: an input chain, a SRCVALUE with the preallocated call Value,...
@ BRIND
BRIND - Indirect branch.
@ BR_JT
BR_JT - Jumptable branch.
@ VECTOR_INTERLEAVE
VECTOR_INTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor to...
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ GET_ACTIVE_LANE_MASK
GET_ACTIVE_LANE_MASK - this corrosponds to the llvm.get.active.lane.mask intrinsic.
@ BasicBlock
Various leaf nodes.
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ ARITH_FENCE
ARITH_FENCE - This corresponds to a arithmetic fence intrinsic.
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ CLEANUPRET
CLEANUPRET - Represents a return from a cleanup block funclet.
@ GET_FPMODE
Reads the current dynamic floating-point control modes.
@ GET_FPENV
Gets the current floating-point environment.
@ SHL
Shift and rotation operations.
@ AssertNoFPClass
AssertNoFPClass - These nodes record if a register contains a float value that is known to be not som...
@ PtrAuthGlobalAddress
A ptrauth constant.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ EntryToken
EntryToken - This is the marker used to indicate the start of a region.
@ READ_REGISTER
READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on the DAG, which implements the n...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ DEBUGTRAP
DEBUGTRAP - Trap intended to get the attention of a debugger.
@ VSCALE
VSCALE(IMM) - Returns the runtime scaling factor used to calculate the number of elements within a sc...
@ LOCAL_RECOVER
LOCAL_RECOVER - Represents the llvm.localrecover intrinsic.
@ FMINNUM
FMINNUM/FMAXNUM - Same semantics as the llvm.minnum/maxnum intrinsics.
@ UBSANTRAP
UBSANTRAP - Trap with an immediate describing the kind of sanitizer failure.
@ SSHLSAT
RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift.
@ PATCHPOINT
The llvm.experimental.patchpoint.
@ SMULO
Same for multiplication.
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ VECTOR_SPLICE_LEFT
VECTOR_SPLICE_LEFT(VEC1, VEC2, OFFSET) - Shifts CONCAT_VECTORS(VEC1, VEC2) left by OFFSET elements an...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ MASKED_UDIV
Masked vector arithmetic that returns poison on disabled lanes.
@ VECTOR_REVERSE
VECTOR_REVERSE(VECTOR) - Returns a vector, of the same type as VECTOR, whose elements are shuffled us...
@ SDIVFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ PCMARKER
PCMARKER - This corresponds to the pcmarker intrinsic.
@ INLINEASM_BR
INLINEASM_BR - Branching version of inline asm. Used by asm-goto.
@ ATOMIC_LOAD_FMAXIMUMNUM
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ PEXT
Parallel bit extract (compress) and parallel bit deposit (expand).
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ FMINIMUM
FMINIMUM/FMAXIMUM - Same semantics as the llvm.minimum/maximum intrinsics.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ RELOC_NONE
Issue a no-op relocation against a given symbol at the current location.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
@ VECTOR_MATCH
VECTOR_MATCH - this corresponds to the llvm.experimental.vector.match intrinsic.
@ VECTOR_SPLICE_RIGHT
VECTOR_SPLICE_RIGHT(VEC1, VEC2, OFFSET) - Shifts CONCAT_VECTORS(VEC1,VEC2) right by OFFSET elements a...
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ STACKMAP
The llvm.experimental.stackmap intrinsic.
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ VECTOR_COMPRESS
VECTOR_COMPRESS(Vec, Mask, Passthru) consecutively place vector elements based on mask e....
@ SPONENTRY
SPONENTRY - Represents the llvm.sponentry intrinsic.
@ CLEAR_CACHE
llvm.clear_cache intrinsic Operands: Input Chain, Start Addres, End Address Outputs: Output Chain
@ INLINEASM
INLINEASM - Represents an inline asm block.
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ BRCOND
BRCOND - Conditional branch.
@ CONVERT_TO_ARBITRARY_FP
CONVERT_TO_ARBITRARY_FP - Converts a native FP value to an arbitrary floating-point format,...
@ CATCHRET
CATCHRET - Represents a return from a catch block funclet.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ VECTOR_REPEAT
VECTOR_REPEAT(FIXED_LENGTH_VECTOR) Repeatedly copies the elements of the source fixed-length vector t...
@ VECTOR_DEINTERLEAVE
VECTOR_DEINTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor ...
@ GET_DYNAMIC_AREA_OFFSET
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca.
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - Same semantics as the llvm.minimumnum/maximumnum intrinsics.
@ ADJUST_TRAMPOLINE
ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ ABS_MIN_POISON
ABS with a poison result for INT_MIN.
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
@ LOOP_DEPENDENCE_WAR_MASK
The llvm.loop.dependence.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
LLVM_ABI StringRef getBaseName(ID id)
Return the LLVM name for an intrinsic, without encoded types for overloading, such as "llvm....
Flag
These should be considered private to the implementation of the MCInstrDesc class.
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_VScale()
Matches a call to llvm.vscale().
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
std::pair< JumpTableHeader, JumpTable > JumpTableBlock
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
initializer< Ty > init(const Ty &Val)
LocationClass< Ty > location(Ty &L)
@ DW_OP_LLVM_arg
Only used in LLVM metadata.
ExceptionBehavior
Exception behavior used for floating point operations.
@ ebStrict
This corresponds to "fpexcept.strict".
@ ebMayTrap
This corresponds to "fpexcept.maytrap".
@ ebIgnore
This corresponds to "fpexcept.ignore".
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract_or_null(Y &&MD)
Extract a Value from Metadata, allowing null.
NodeAddr< FuncNode * > Func
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Type * getValueType(Value *V, bool ReVec, bool LookThroughCmp)
Returns the "element type" of the given value/instruction V.
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
LLVM_ABI bool canDescribeGlobalAddressInLocationList(const MachineFunction &MF)
Test if the debug info for MF can name a describable global address in a location list too,...
LLVM_ABI ISD::CondCode getICmpCondCode(ICmpInst::Predicate Pred)
getICmpCondCode - Return the ISD condition code corresponding to the given LLVM IR integer condition ...
LLVM_ABI cl::opt< bool > ProfcheckDisableMetadataFixes
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
SDValue peekThroughFreeze(SDValue V)
Return the non-frozen source operand of V if it exists.
LLVM_ABI void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
RelativeUniformCounterPtr Values
@ Unknown
Not known to have no common set bits.
LLVM_ABI void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, SmallVectorImpl< EVT > &ValueVTs, SmallVectorImpl< EVT > *MemVTs=nullptr, SmallVectorImpl< TypeSize > *Offsets=nullptr, TypeSize StartingOffset=TypeSize::getZero())
ComputeValueVTs - Given an LLVM IR type, compute a sequence of EVTs that represent all the individual...
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
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 bool isExceptionPointerAndSelectorType(Type *Ty)
Return true if landingpad result type Ty is a struct of an exception pointer (pointer or integer) and...
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
bool isIntOrFPConstant(SDValue V)
Return true if V is either a integer or FP constant.
static ConstantRange getRange(Value *Op, SCCPSolver &Solver, const SmallPtrSetImpl< Value * > &InsertedValues)
Helper for getting ranges from Solver.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL, bool AllowNonInbounds=true)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset.
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
auto cast_or_null(const Y &Val)
constexpr T alignDown(U Value, V Align, W Skew=0)
Returns the largest unsigned integer less than or equal to Value and is Skew mod Align.
gep_type_iterator gep_type_end(const User *GEP)
LLVM_ABI LLT getLLTForMVT(MVT Ty)
Get a rough equivalent of an LLT for a given MVT.
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
LLVM_ABI void reportFatalInternalError(Error Err)
Report a fatal error that indicates a bug in LLVM.
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
LLVM_ABI ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)
Returns a concatenated range across two or more ranges.
bool isScopedEHPersonality(EHPersonality Pers)
Returns true if this personality uses scope-style EH IR instructions: catchswitch,...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
LLVM_ABI void ComputeValueTypes(const DataLayout &DL, Type *Ty, SmallVectorImpl< Type * > &Types, SmallVectorImpl< TypeSize > *Offsets=nullptr, TypeSize StartingOffset=TypeSize::getZero())
Given an LLVM IR type, compute non-aggregate subtypes.
auto dyn_cast_or_null(const Y &Val)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
@ SPF_ABS
Floating point maxnum.
@ SPF_NABS
Absolute value.
@ SPF_FMAXNUM
Floating point minnum.
@ SPF_UMIN
Signed minimum.
@ SPF_UMAX
Signed maximum.
@ SPF_SMAX
Unsigned minimum.
@ SPF_FMINNUM
Unsigned maximum.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
detail::zippy< detail::zip_first, T, U, Args... > zip_first(T &&t, U &&u, Args &&...args)
zip iterator that, for the sake of efficiency, assumes the first iteratee to be the shortest.
void sort(IteratorTy Start, IteratorTy End)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
LLVM_ABI const MDNode * getMemCacheHintMetadata(const Instruction &I, unsigned OperandNo=0)
Return the cache hint metadata node for memory operand OperandNo on I, or nullptr when the instructio...
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)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
generic_gep_type_iterator<> gep_type_iterator
auto succ_size(const MachineBasicBlock *BB)
bool hasSingleElement(ContainerTy &&C)
Returns true if the given container only contains a single element.
LLVM_ABI ISD::CondCode getFCmpCondCode(FCmpInst::Predicate Pred)
getFCmpCondCode - Return the ISD condition code corresponding to the given LLVM IR floating-point con...
LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
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...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI Value * salvageDebugInfoImpl(Instruction &I, uint64_t CurrentLocOps, SmallVectorImpl< uint64_t > &Ops, SmallVectorImpl< Value * > &AdditionalValues)
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Global
Append to llvm.global_dtors.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
bool isFuncletEHPersonality(EHPersonality Pers)
Returns true if this is a personality function that invokes handler funclets (which must return to it...
LLVM_ABI bool isAssignmentTrackingEnabled(const Module &M)
Return true if assignment tracking is enabled for module M.
@ UMin
Unsigned integer min implemented in terms of select(cmp()).
@ Or
Bitwise or logical OR of integers.
@ Mul
Product of integers.
@ Sub
Subtraction of integers.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
LLVM_ABI bool isOnlyUsedInZeroEqualityComparison(const Instruction *CtxI)
@ SPNB_RETURNS_NAN
NaN behavior not applicable.
@ SPNB_RETURNS_OTHER
Given one NaN input, returns the NaN.
@ SPNB_RETURNS_ANY
Given one NaN input, returns the non-NaN.
LLVM_ABI bool isInTailCallPosition(const CallBase &Call, const TargetMachine &TM, bool ReturnsFirstArg=false)
Test if the given instruction is in a position to be optimized with a tail-call.
DWARFExpression::Operation Op
@ Dynamic
Denotes mode unknown at compile time.
LLVM_ABI ISD::CondCode getFCmpCodeWithoutNaN(ISD::CondCode CC)
getFCmpCodeWithoutNaN - Given an ISD condition code comparing floats, return the equivalent code if w...
LLVM_ABI const GlobalValue * getDescribableGlobalAddress(const Constant *C, int64_t &Offset, const MachineFunction &MF)
If C is the address of a global, possibly displaced by a constant, return that global and set Offset ...
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 bool isKnownNeverNaN(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point scalar value is not a NaN or if the floating-point vector value has...
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)
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
LLVM_ABI GlobalValue * ExtractTypeInfo(Value *V)
ExtractTypeInfo - Returns the type info, possibly bitcast, encoded in V.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.
LLVM_ABI Constant * ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, APInt Offset, const DataLayout &DL)
Return the value that a load from C with offset Offset would produce if it is constant and determinab...
LLVM_ABI unsigned ComputeLinearIndex(Type *Ty, const unsigned *Indices, const unsigned *IndicesEnd, unsigned CurIndex=0)
Compute the linearized index of a member in a nested aggregate/struct/array.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
@ End
Run the machine verifier once, at the end of the pipeline.
LLVM_ABI SelectPatternResult matchSelectPattern(Value *V, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr)
Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind and providing the out param...
MCRegisterClass TargetRegisterClass
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
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.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
EVT changeTypeToInteger() const
Return the type converted to an equivalently sized integer or vector with integer element type.
uint64_t getScalarStoreSize() const
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
ElementCount getVectorElementCount() const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
static LLVM_ABI EVT getEVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
EVT changeVectorElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
bool isRISCVVectorTuple() const
Return true if this is a vector value type.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isFixedLengthVector() const
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool bitsGE(EVT VT) const
Return true if this has no less bits than VT.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
EVT changeElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a type whose attributes match ourselves with the exception of the element type that i...
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool isInteger() const
Return true if this is an integer or a vector integer type.
void setPointerAddrSpace(unsigned AS)
void setOrigAlign(Align A)
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
ConstraintPrefix Type
Type - The basic type of the constraint: input/output/clobber/label.
unsigned countMinLeadingZeros() const
Returns the minimum number of leading zero bits.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getUnknownStack(MachineFunction &MF)
Stack memory without other information.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
A lightweight accessor for an operand bundle meant to be passed around by value.
This struct represents the registers (physical or virtual) that a particular set of values is assigne...
SmallVector< std::pair< Register, TypeSize >, 4 > getRegsAndSizes() const
Return a list of registers and their sizes.
SmallVector< unsigned, 4 > RegCount
This list holds the number of registers for each value.
bool isABIMangled() const
SmallVector< EVT, 4 > ValueVTs
The value types of the values, which may not be legal, and may need be promoted or synthesized from o...
SmallVector< Register, 4 > Regs
This list holds the registers assigned to the values.
void AddInlineAsmOperands(InlineAsm::Kind Code, bool HasMatching, unsigned MatchingIdx, const SDLoc &dl, SelectionDAG &DAG, std::vector< SDValue > &Ops) const
Add this value to the specified inlineasm node operand list.
SDValue getCopyFromRegs(SelectionDAG &DAG, FunctionLoweringInfo &FuncInfo, const SDLoc &dl, SDValue &Chain, SDValue *Glue, const Value *V=nullptr) const
Emit a series of CopyFromReg nodes that copies from this value and returns the result as a ValueVTs v...
SmallVector< MVT, 4 > RegVTs
The value types of the registers.
void getCopyToRegs(SDValue Val, SelectionDAG &DAG, const SDLoc &dl, SDValue &Chain, SDValue *Glue, const Value *V=nullptr, ISD::NodeType PreferredExtendType=ISD::ANY_EXTEND) const
Emit a series of CopyToReg nodes that copies the specified value into the registers specified by this...
std::optional< CallingConv::ID > CallConv
Records if this value needs to be treated in an ABI dependant manner, different to normal type legali...
bool occupiesMultipleRegs() const
Check if the total RegCount is greater than one.
These are IR-level optimization flags that may be propagated to SDNodes.
void copyFMF(const FPMathOperator &FPMO)
Propagate the fast-math-flags from an IR FPMathOperator.
void setUnpredictable(bool b)
bool hasAllowReassociation() const
void setNoUnsignedWrap(bool b)
void setNoSignedWrap(bool b)
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
A MapVector that performs no allocations if smaller than a certain size.
MachineBasicBlock * Default
BranchProbability DefaultProb
MachineBasicBlock * Parent
bool FallthroughUnreachable
MachineBasicBlock * ThisBB
This structure is used to communicate between SelectionDAGBuilder and SDISel for the code generation ...
BranchProbability TrueProb
BranchProbability FalseProb
MachineBasicBlock * TrueBB
MachineBasicBlock * FalseBB
SDLoc DL
The debug location of the instruction this CaseBlock was produced from.
static CaseCluster range(const ConstantInt *Low, const ConstantInt *High, MachineBasicBlock *MBB, BranchProbability Prob)
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.
std::optional< SDLoc > SL
The debug location of the instruction this JumpTable was produced from.
This contains information for each constraint that we are lowering.
TargetLowering::ConstraintType ConstraintType
Information about the constraint code, e.g.
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setConvergent(bool Value=true)
CallLoweringInfo & setDeactivationSymbol(GlobalValue *Sym)
CallLoweringInfo & setCFIType(const ConstantInt *Type)
SmallVector< ISD::InputArg, 32 > Ins
bool IsPostTypeLegalization
SmallVector< SDValue, 4 > InVals
Type * OrigRetTy
Original unlegalized return type.
CallLoweringInfo & setDiscardResult(bool Value=true)
CallLoweringInfo & setIsPatchPoint(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setTailCall(bool Value=true)
CallLoweringInfo & setIsPreallocated(bool Value=true)
CallLoweringInfo & setConvergenceControlToken(SDValue Token)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
Type * RetTy
Same as OrigRetTy, or partially legalized for soft float libcalls.
CallLoweringInfo & setChain(SDValue InChain)
CallLoweringInfo & setPtrAuth(PtrAuthInfo Value)
CallLoweringInfo & setCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList, AttributeSet ResultAttrs={})
This structure is used to pass arguments to makeLibCall function.
MakeLibCallOptions & setDiscardResult(bool Value=true)
This structure contains the information necessary for lowering pointer-authenticating indirect calls.
LLVM_ABI void addIPToStateRange(const InvokeInst *II, MCSymbol *InvokeBegin, MCSymbol *InvokeEnd)