58#define DEBUG_TYPE "legalizedag"
64struct FloatSignAsInt {
87class SelectionDAGLegalize {
99 EVT getSetCCResultType(
EVT VT)
const {
110 LegalizedNodes(LegalizedNodes), UpdatedNodes(UpdatedNodes) {}
166 void getSignAsIntValue(FloatSignAsInt &State,
const SDLoc &
DL,
168 SDValue modifySignAsInt(
const FloatSignAsInt &State,
const SDLoc &
DL,
215 dbgs() <<
" with: "; New->dump(&DAG));
218 "Replacing one node with another that produces a different number "
222 UpdatedNodes->
insert(New);
228 dbgs() <<
" with: "; New->dump(&DAG));
232 UpdatedNodes->
insert(New.getNode());
233 ReplacedNode(Old.getNode());
240 for (
unsigned i = 0, e = Old->
getNumValues(); i != e; ++i) {
251 dbgs() <<
" with: "; New->dump(&DAG));
255 UpdatedNodes->
insert(New.getNode());
256 ReplacedNode(Old.getNode());
266 bool isObjectScalable) {
268 int FI = cast<FrameIndexSDNode>(StackPtr)->getIndex();
274 ObjectSize, MFI.getObjectAlign(FI));
281SDValue SelectionDAGLegalize::ShuffleWithNarrowerEltType(
286 unsigned NumEltsGrowth = NumDestElts / NumMaskElts;
288 assert(NumEltsGrowth &&
"Cannot promote to vector type with fewer elts!");
290 if (NumEltsGrowth == 1)
291 return DAG.getVectorShuffle(NVT, dl, N1, N2, Mask);
294 for (
unsigned i = 0; i != NumMaskElts; ++i) {
296 for (
unsigned j = 0;
j != NumEltsGrowth; ++
j) {
303 assert(NewMask.
size() == NumDestElts &&
"Non-integer NumEltsGrowth?");
304 assert(TLI.isShuffleMaskLegal(NewMask, NVT) &&
"Shuffle not legal?");
305 return DAG.getVectorShuffle(NVT, dl, N1, N2, NewMask);
324 assert((VT == MVT::f64 || VT == MVT::f32) &&
"Invalid type expansion");
326 (VT == MVT::f64) ? MVT::i64 : MVT::i32);
336 while (SVT != MVT::f32 && SVT != MVT::f16 && SVT != MVT::bf16) {
342 TLI.ShouldShrinkFPConstant(OrigVT)) {
345 Instruction::FPTrunc, LLVMC, SType, DAG.getDataLayout()));
353 DAG.getConstantPool(LLVMC, TLI.getPointerTy(DAG.getDataLayout()));
354 Align Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlign();
363 OrigVT, dl, DAG.getEntryNode(), CPIdx,
371 EVT VT =
CP->getValueType(0);
372 SDValue CPIdx = DAG.getConstantPool(
CP->getConstantIntValue(),
373 TLI.getPointerTy(DAG.getDataLayout()));
374 Align Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlign();
376 VT, dl, DAG.getEntryNode(), CPIdx,
402 for (
unsigned i = 0; i != NumElts; ++i)
403 ShufOps.
push_back(i != InsertPos->getZExtValue() ? i : NumElts);
405 return DAG.getVectorShuffle(Vec.
getValueType(), dl, Vec, ScVec, ShufOps);
408 return ExpandInsertToVectorThroughStack(
Op);
435 TLI.isTypeLegal(MVT::i32)) {
437 bitcastToAPInt().zextOrTrunc(32),
438 SDLoc(CFP), MVT::i32);
439 return DAG.getStore(Chain, dl, Con,
Ptr,
ST->getPointerInfo(),
440 ST->getOriginalAlign(), MMOFlags, AAInfo);
446 if (TLI.isTypeLegal(MVT::i64)) {
448 zextOrTrunc(64),
SDLoc(CFP), MVT::i64);
449 return DAG.getStore(Chain, dl, Con,
Ptr,
ST->getPointerInfo(),
450 ST->getOriginalAlign(), MMOFlags, AAInfo);
453 if (TLI.isTypeLegal(MVT::i32) && !
ST->isVolatile()) {
460 if (DAG.getDataLayout().isBigEndian())
463 Lo = DAG.getStore(Chain, dl,
Lo,
Ptr,
ST->getPointerInfo(),
464 ST->getOriginalAlign(), MMOFlags, AAInfo);
466 Hi = DAG.getStore(Chain, dl,
Hi,
Ptr,
467 ST->getPointerInfo().getWithOffset(4),
468 ST->getOriginalAlign(), MMOFlags, AAInfo);
477void SelectionDAGLegalize::LegalizeStoreOps(
SDNode *
Node) {
486 if (!
ST->isTruncatingStore()) {
489 ReplaceNode(ST, OptStore);
494 MVT VT =
Value.getSimpleValueType();
495 switch (TLI.getOperationAction(
ISD::STORE, VT)) {
497 case TargetLowering::Legal: {
500 EVT MemVT =
ST->getMemoryVT();
502 if (!TLI.allowsMemoryAccessForAlignment(*DAG.getContext(),
DL, MemVT,
503 *
ST->getMemOperand())) {
506 ReplaceNode(
SDValue(ST, 0), Result);
511 case TargetLowering::Custom: {
518 case TargetLowering::Promote: {
521 "Can only promote stores to same size type");
524 ST->getOriginalAlign(), MMOFlags, AAInfo);
534 EVT StVT =
ST->getMemoryVT();
537 auto &
DL = DAG.getDataLayout();
539 if (StWidth != StSize) {
544 Value = DAG.getZeroExtendInReg(
Value, dl, StVT);
546 DAG.getTruncStore(Chain, dl,
Value,
Ptr,
ST->getPointerInfo(), NVT,
547 ST->getOriginalAlign(), MMOFlags, AAInfo);
553 unsigned LogStWidth =
Log2_32(StWidthBits);
555 unsigned RoundWidth = 1 << LogStWidth;
556 assert(RoundWidth < StWidthBits);
557 unsigned ExtraWidth = StWidthBits - RoundWidth;
558 assert(ExtraWidth < RoundWidth);
559 assert(!(RoundWidth % 8) && !(ExtraWidth % 8) &&
560 "Store size not an integral number of bytes!");
564 unsigned IncrementSize;
566 if (
DL.isLittleEndian()) {
569 Lo = DAG.getTruncStore(Chain, dl,
Value,
Ptr,
ST->getPointerInfo(),
570 RoundVT,
ST->getOriginalAlign(), MMOFlags, AAInfo);
573 IncrementSize = RoundWidth / 8;
578 DAG.getConstant(RoundWidth, dl,
579 TLI.getShiftAmountTy(
Value.getValueType(),
DL)));
580 Hi = DAG.getTruncStore(Chain, dl,
Hi,
Ptr,
581 ST->getPointerInfo().getWithOffset(IncrementSize),
582 ExtraVT,
ST->getOriginalAlign(), MMOFlags, AAInfo);
589 DAG.getConstant(ExtraWidth, dl,
590 TLI.getShiftAmountTy(
Value.getValueType(),
DL)));
591 Hi = DAG.getTruncStore(Chain, dl,
Hi,
Ptr,
ST->getPointerInfo(), RoundVT,
592 ST->getOriginalAlign(), MMOFlags, AAInfo);
595 IncrementSize = RoundWidth / 8;
597 DAG.getConstant(IncrementSize, dl,
598 Ptr.getValueType()));
600 ST->getPointerInfo().getWithOffset(IncrementSize),
601 ExtraVT,
ST->getOriginalAlign(), MMOFlags, AAInfo);
608 switch (TLI.getTruncStoreAction(
ST->getValue().getValueType(), StVT)) {
610 case TargetLowering::Legal: {
611 EVT MemVT =
ST->getMemoryVT();
614 if (!TLI.allowsMemoryAccessForAlignment(*DAG.getContext(),
DL, MemVT,
615 *
ST->getMemOperand())) {
617 ReplaceNode(
SDValue(ST, 0), Result);
621 case TargetLowering::Custom: {
627 case TargetLowering::Expand:
629 "Vector Stores are handled in LegalizeVectorOps");
634 if (TLI.isTypeLegal(StVT)) {
637 ST->getOriginalAlign(), MMOFlags, AAInfo);
642 TLI.getTypeToTransformTo(*DAG.getContext(), StVT),
645 DAG.getTruncStore(Chain, dl,
Value,
Ptr,
ST->getPointerInfo(), StVT,
646 ST->getOriginalAlign(), MMOFlags, AAInfo);
655void SelectionDAGLegalize::LegalizeLoadOps(
SDNode *
Node) {
664 LLVM_DEBUG(
dbgs() <<
"Legalizing non-extending load operation\n");
665 MVT VT =
Node->getSimpleValueType(0);
669 switch (TLI.getOperationAction(
Node->getOpcode(), VT)) {
671 case TargetLowering::Legal: {
672 EVT MemVT =
LD->getMemoryVT();
676 if (!TLI.allowsMemoryAccessForAlignment(*DAG.getContext(),
DL, MemVT,
677 *
LD->getMemOperand())) {
678 std::tie(RVal, RChain) = TLI.expandUnalignedLoad(LD, DAG);
682 case TargetLowering::Custom:
683 if (
SDValue Res = TLI.LowerOperation(RVal, DAG)) {
689 case TargetLowering::Promote: {
690 MVT NVT = TLI.getTypeToPromoteTo(
Node->getOpcode(), VT);
692 "Can only promote loads to same size type");
694 SDValue Res = DAG.getLoad(NVT, dl, Chain,
Ptr,
LD->getMemOperand());
702 DAG.ReplaceAllUsesOfValueWith(
SDValue(
Node, 0), RVal);
703 DAG.ReplaceAllUsesOfValueWith(
SDValue(
Node, 1), RChain);
705 UpdatedNodes->insert(RVal.
getNode());
706 UpdatedNodes->insert(RChain.
getNode());
714 EVT SrcVT =
LD->getMemoryVT();
728 TLI.getLoadExtAction(ExtType,
Node->getValueType(0), MVT::i1) ==
729 TargetLowering::Promote)) {
743 Chain,
Ptr,
LD->getPointerInfo(), NVT,
744 LD->getOriginalAlign(), MMOFlags, AAInfo);
752 Result, DAG.getValueType(SrcVT));
756 Result.getValueType(), Result,
757 DAG.getValueType(SrcVT));
765 unsigned LogSrcWidth =
Log2_32(SrcWidthBits);
767 unsigned RoundWidth = 1 << LogSrcWidth;
768 assert(RoundWidth < SrcWidthBits);
769 unsigned ExtraWidth = SrcWidthBits - RoundWidth;
770 assert(ExtraWidth < RoundWidth);
771 assert(!(RoundWidth % 8) && !(ExtraWidth % 8) &&
772 "Load size not an integral number of bytes!");
776 unsigned IncrementSize;
777 auto &
DL = DAG.getDataLayout();
779 if (
DL.isLittleEndian()) {
783 LD->getPointerInfo(), RoundVT,
LD->getOriginalAlign(),
787 IncrementSize = RoundWidth / 8;
790 Hi = DAG.getExtLoad(ExtType, dl,
Node->getValueType(0), Chain,
Ptr,
791 LD->getPointerInfo().getWithOffset(IncrementSize),
792 ExtraVT,
LD->getOriginalAlign(), MMOFlags, AAInfo);
802 DAG.getConstant(RoundWidth, dl,
803 TLI.getShiftAmountTy(
Hi.getValueType(),
DL)));
811 Hi = DAG.getExtLoad(ExtType, dl,
Node->getValueType(0), Chain,
Ptr,
812 LD->getPointerInfo(), RoundVT,
LD->getOriginalAlign(),
816 IncrementSize = RoundWidth / 8;
820 LD->getPointerInfo().getWithOffset(IncrementSize),
821 ExtraVT,
LD->getOriginalAlign(), MMOFlags, AAInfo);
831 DAG.getConstant(ExtraWidth, dl,
832 TLI.getShiftAmountTy(
Hi.getValueType(),
DL)));
840 bool isCustom =
false;
841 switch (TLI.getLoadExtAction(ExtType,
Node->getValueType(0),
844 case TargetLowering::Custom:
847 case TargetLowering::Legal:
859 EVT MemVT =
LD->getMemoryVT();
861 if (!TLI.allowsMemoryAccess(*DAG.getContext(),
DL, MemVT,
862 *
LD->getMemOperand())) {
863 std::tie(
Value, Chain) = TLI.expandUnalignedLoad(LD, DAG);
868 case TargetLowering::Expand: {
869 EVT DestVT =
Node->getValueType(0);
875 (TLI.isTypeLegal(SrcVT) ||
876 TLI.isLoadExtLegal(ExtType, LoadVT, SrcVT))) {
883 SrcVT,
LD->getMemOperand());
886 Value = DAG.getNode(ExtendOp, dl,
Node->getValueType(0), Load);
887 Chain =
Load.getValue(1);
896 if (SVT == MVT::f16 || SVT == MVT::bf16) {
902 Ptr, ISrcVT,
LD->getMemOperand());
906 Chain =
Result.getValue(1);
912 "Vector Loads are handled in LegalizeVectorOps");
919 "EXTLOAD should always be supported!");
923 Node->getValueType(0),
925 LD->getMemOperand());
930 Result, DAG.getValueType(SrcVT));
932 ValRes = DAG.getZeroExtendInReg(Result, dl, SrcVT);
934 Chain =
Result.getValue(1);
945 DAG.ReplaceAllUsesOfValueWith(
SDValue(
Node, 1), Chain);
947 UpdatedNodes->insert(
Value.getNode());
948 UpdatedNodes->insert(Chain.
getNode());
955void SelectionDAGLegalize::LegalizeOp(
SDNode *
Node) {
964 for (
unsigned i = 0, e =
Node->getNumValues(); i != e; ++i)
965 assert(TLI.getTypeAction(*DAG.getContext(),
Node->getValueType(i)) ==
966 TargetLowering::TypeLegal &&
967 "Unexpected illegal type!");
970 assert((TLI.getTypeAction(*DAG.getContext(),
Op.getValueType()) ==
971 TargetLowering::TypeLegal ||
974 "Unexpected illegal type!");
979 bool SimpleFinishLegalizing =
true;
980 switch (
Node->getOpcode()) {
985 Action = TLI.getOperationAction(
Node->getOpcode(), MVT::Other);
988 Action = TLI.getOperationAction(
Node->getOpcode(),
989 Node->getValueType(0));
992 Action = TLI.getOperationAction(
Node->getOpcode(),
993 Node->getValueType(0));
994 if (Action != TargetLowering::Promote)
995 Action = TLI.getOperationAction(
Node->getOpcode(), MVT::Other);
999 Action = TLI.getOperationAction(
Node->getOpcode(),
1000 Node->getOperand(1).getValueType());
1011 Action = TLI.getOperationAction(
Node->getOpcode(),
1012 Node->getOperand(0).getValueType());
1025 Action = TLI.getOperationAction(
Node->getOpcode(),
1026 Node->getOperand(1).getValueType());
1029 EVT InnerType = cast<VTSDNode>(
Node->getOperand(1))->getVT();
1030 Action = TLI.getOperationAction(
Node->getOpcode(), InnerType);
1034 Action = TLI.getOperationAction(
Node->getOpcode(),
1035 Node->getOperand(1).getValueType());
1044 unsigned Opc =
Node->getOpcode();
1049 : (Opc ==
ISD::SETCC || Opc == ISD::VP_SETCC) ? 2
1051 unsigned CompareOperand = Opc ==
ISD::BR_CC ? 2
1055 MVT OpVT =
Node->getOperand(CompareOperand).getSimpleValueType();
1057 cast<CondCodeSDNode>(
Node->getOperand(CCOperand))->get();
1058 Action = TLI.getCondCodeAction(CCCode, OpVT);
1059 if (Action == TargetLowering::Legal) {
1061 Action = TLI.getOperationAction(
Node->getOpcode(),
1062 Node->getValueType(0));
1064 Action = TLI.getOperationAction(
Node->getOpcode(), OpVT);
1072 SimpleFinishLegalizing =
false;
1079 SimpleFinishLegalizing =
false;
1092 Action = TLI.getOperationAction(
Node->getOpcode(),
Node->getValueType(0));
1093 if (Action == TargetLowering::Legal)
1094 Action = TargetLowering::Expand;
1104 Action = TLI.getOperationAction(
Node->getOpcode(),
Node->getValueType(0));
1105 if (Action == TargetLowering::Legal)
1106 Action = TargetLowering::Custom;
1111 Action = TLI.getOperationAction(
Node->getOpcode(),
Node->getValueType(0));
1117 Action = TLI.getOperationAction(
Node->getOpcode(), MVT::i64);
1124 Action = TargetLowering::Legal;
1127 Action = TLI.getOperationAction(
Node->getOpcode(),
Node->getValueType(0));
1128 if (Action == TargetLowering::Expand) {
1132 Node->getOperand(0));
1139 Action = TLI.getOperationAction(
Node->getOpcode(),
Node->getValueType(0));
1140 if (Action == TargetLowering::Expand) {
1144 Node->getOperand(0));
1160 Action = TLI.getOperationAction(
Node->getOpcode(),
Node->getValueType(0));
1170 unsigned Scale =
Node->getConstantOperandVal(2);
1171 Action = TLI.getFixedPointOperationAction(
Node->getOpcode(),
1172 Node->getValueType(0), Scale);
1176 Action = TLI.getOperationAction(
Node->getOpcode(),
1177 cast<MaskedScatterSDNode>(
Node)->getValue().getValueType());
1180 Action = TLI.getOperationAction(
Node->getOpcode(),
1181 cast<MaskedStoreSDNode>(
Node)->getValue().getValueType());
1183 case ISD::VP_SCATTER:
1184 Action = TLI.getOperationAction(
1186 cast<VPScatterSDNode>(
Node)->getValue().getValueType());
1189 Action = TLI.getOperationAction(
1191 cast<VPStoreSDNode>(
Node)->getValue().getValueType());
1193 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
1194 Action = TLI.getOperationAction(
1196 cast<VPStridedStoreSDNode>(
Node)->getValue().getValueType());
1214 Action = TLI.getOperationAction(
1215 Node->getOpcode(),
Node->getOperand(0).getValueType());
1219 case ISD::VP_REDUCE_FADD:
1220 case ISD::VP_REDUCE_FMUL:
1221 case ISD::VP_REDUCE_ADD:
1222 case ISD::VP_REDUCE_MUL:
1223 case ISD::VP_REDUCE_AND:
1224 case ISD::VP_REDUCE_OR:
1225 case ISD::VP_REDUCE_XOR:
1226 case ISD::VP_REDUCE_SMAX:
1227 case ISD::VP_REDUCE_SMIN:
1228 case ISD::VP_REDUCE_UMAX:
1229 case ISD::VP_REDUCE_UMIN:
1230 case ISD::VP_REDUCE_FMAX:
1231 case ISD::VP_REDUCE_FMIN:
1232 case ISD::VP_REDUCE_FMAXIMUM:
1233 case ISD::VP_REDUCE_FMINIMUM:
1234 case ISD::VP_REDUCE_SEQ_FADD:
1235 case ISD::VP_REDUCE_SEQ_FMUL:
1236 Action = TLI.getOperationAction(
1237 Node->getOpcode(),
Node->getOperand(1).getValueType());
1239 case ISD::VP_CTTZ_ELTS:
1240 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
1241 Action = TLI.getOperationAction(
Node->getOpcode(),
1242 Node->getOperand(0).getValueType());
1246 Action = TLI.getCustomOperationAction(*
Node);
1248 Action = TLI.getOperationAction(
Node->getOpcode(),
Node->getValueType(0));
1253 if (SimpleFinishLegalizing) {
1255 switch (
Node->getOpcode()) {
1274 NewNode = DAG.UpdateNodeOperands(
Node, Op0, SAO);
1294 NewNode = DAG.UpdateNodeOperands(
Node, Op0, Op1, SAO);
1300 if (NewNode !=
Node) {
1301 ReplaceNode(
Node, NewNode);
1305 case TargetLowering::Legal:
1308 case TargetLowering::Custom:
1316 if (
Node->getNumValues() == 1) {
1320 Node->getValueType(0) == MVT::Glue) &&
1321 "Type mismatch for custom legalized operation");
1329 for (
unsigned i = 0, e =
Node->getNumValues(); i != e; ++i) {
1333 Node->getValueType(i) == MVT::Glue) &&
1334 "Type mismatch for custom legalized operation");
1338 ReplaceNode(
Node, ResultVals.
data());
1343 case TargetLowering::Expand:
1344 if (ExpandNode(
Node))
1347 case TargetLowering::LibCall:
1348 ConvertNodeToLibcall(
Node);
1350 case TargetLowering::Promote:
1356 switch (
Node->getOpcode()) {
1369 return LegalizeLoadOps(
Node);
1371 return LegalizeStoreOps(
Node);
1375SDValue SelectionDAGLegalize::ExpandExtractFromVectorThroughStack(
SDValue Op) {
1395 if (
ST->isIndexed() ||
ST->isTruncatingStore() ||
1396 ST->getValue() != Vec)
1401 if (!
ST->getChain().reachesChainWithoutSideEffects(DAG.getEntryNode()))
1410 ST->hasPredecessor(
Op.getNode()))
1423 StackPtr = DAG.CreateStackTemporary(VecVT);
1426 Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, StoreMMO);
1430 Align ElementAlignment =
1431 std::min(cast<StoreSDNode>(Ch)->
getAlign(),
1432 DAG.getDataLayout().getPrefTypeAlign(
1433 Op.getValueType().getTypeForEVT(*DAG.getContext())));
1435 if (
Op.getValueType().isVector()) {
1436 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT,
1437 Op.getValueType(),
Idx);
1438 NewLoad = DAG.getLoad(
Op.getValueType(), dl, Ch, StackPtr,
1441 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Idx);
1442 NewLoad = DAG.getExtLoad(
ISD::EXTLOAD, dl,
Op.getValueType(), Ch, StackPtr,
1448 DAG.ReplaceAllUsesOfValueWith(Ch,
SDValue(NewLoad.
getNode(), 1));
1453 NewLoadOperands[0] = Ch;
1455 SDValue(DAG.UpdateNodeOperands(NewLoad.
getNode(), NewLoadOperands), 0);
1459SDValue SelectionDAGLegalize::ExpandInsertToVectorThroughStack(
SDValue Op) {
1460 assert(
Op.getValueType().isVector() &&
"Non-vector insert subvector!");
1471 int FI = cast<FrameIndexSDNode>(
StackPtr.getNode())->getIndex();
1476 Align BaseVecAlignment =
1477 DAG.getMachineFunction().getFrameInfo().getObjectAlign(FI);
1478 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
1482 Idx = DAG.getFreeze(
Idx);
1485 Align PartAlignment = DAG.getDataLayout().getPrefTypeAlign(PartTy);
1490 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, PartVT,
Idx);
1494 Ch, dl, Part, SubStackPtr,
1499 TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Idx);
1502 Ch = DAG.getTruncStore(
1503 Ch, dl, Part, SubStackPtr,
1509 "ElementAlignment does not match!");
1512 return DAG.getLoad(
Op.getValueType(), dl, Ch, StackPtr, PtrInfo,
1519 "Unexpected opcode!");
1525 EVT VT =
Node->getValueType(0);
1527 :
Node->getOperand(0).getValueType();
1529 SDValue FIPtr = DAG.CreateStackTemporary(VT);
1530 int FI = cast<FrameIndexSDNode>(FIPtr.
getNode())->getIndex();
1537 assert(TypeByteSize > 0 &&
"Vector element type too small for stack store!");
1541 bool Truncate = isa<BuildVectorSDNode>(
Node) &&
1542 MemVT.
bitsLT(
Node->getOperand(0).getValueType());
1545 for (
unsigned i = 0, e =
Node->getNumOperands(); i != e; ++i) {
1547 if (
Node->getOperand(i).isUndef())
continue;
1549 unsigned Offset = TypeByteSize*i;
1555 Stores.
push_back(DAG.getTruncStore(DAG.getEntryNode(), dl,
1559 Stores.
push_back(DAG.getStore(DAG.getEntryNode(), dl,
Node->getOperand(i),
1564 if (!Stores.
empty())
1567 StoreChain = DAG.getEntryNode();
1570 return DAG.getLoad(VT, dl, StoreChain, FIPtr, PtrInfo);
1576void SelectionDAGLegalize::getSignAsIntValue(FloatSignAsInt &State,
1579 EVT FloatVT =
Value.getValueType();
1581 State.FloatVT = FloatVT;
1584 if (TLI.isTypeLegal(IVT)) {
1587 State.SignBit = NumBits - 1;
1593 MVT LoadTy = TLI.getRegisterType(MVT::i8);
1596 int FI = cast<FrameIndexSDNode>(
StackPtr.getNode())->getIndex();
1601 State.Chain = DAG.getStore(DAG.getEntryNode(),
DL,
Value, State.FloatPtr,
1602 State.FloatPointerInfo);
1609 State.IntPointerInfo = State.FloatPointerInfo;
1612 unsigned ByteOffset = (NumBits / 8) - 1;
1619 State.IntPtr = IntPtr;
1620 State.IntValue = DAG.getExtLoad(
ISD::EXTLOAD,
DL, LoadTy, State.Chain, IntPtr,
1621 State.IntPointerInfo, MVT::i8);
1628SDValue SelectionDAGLegalize::modifySignAsInt(
const FloatSignAsInt &State,
1635 SDValue Chain = DAG.getTruncStore(State.Chain,
DL, NewIntValue, State.IntPtr,
1636 State.IntPointerInfo, MVT::i8);
1637 return DAG.getLoad(State.FloatVT,
DL, Chain, State.FloatPtr,
1638 State.FloatPointerInfo);
1647 FloatSignAsInt SignAsInt;
1648 getSignAsIntValue(SignAsInt,
DL, Sign);
1650 EVT IntVT = SignAsInt.IntValue.getValueType();
1651 SDValue SignMask = DAG.getConstant(SignAsInt.SignMask,
DL, IntVT);
1657 if (TLI.isOperationLegalOrCustom(
ISD::FABS, FloatVT) &&
1658 TLI.isOperationLegalOrCustom(
ISD::FNEG, FloatVT)) {
1661 SDValue Cond = DAG.getSetCC(
DL, getSetCCResultType(IntVT), SignBit,
1663 return DAG.getSelect(
DL, FloatVT,
Cond, NegValue, AbsValue);
1667 FloatSignAsInt MagAsInt;
1668 getSignAsIntValue(MagAsInt,
DL, Mag);
1669 EVT MagVT = MagAsInt.IntValue.getValueType();
1670 SDValue ClearSignMask = DAG.getConstant(~MagAsInt.SignMask,
DL, MagVT);
1675 int ShiftAmount = SignAsInt.SignBit - MagAsInt.SignBit;
1676 EVT ShiftVT = IntVT;
1682 if (ShiftAmount > 0) {
1683 SDValue ShiftCnst = DAG.getConstant(ShiftAmount,
DL, ShiftVT);
1685 }
else if (ShiftAmount < 0) {
1686 SDValue ShiftCnst = DAG.getConstant(-ShiftAmount,
DL, ShiftVT);
1695 Flags.setDisjoint(
true);
1701 return modifySignAsInt(MagAsInt,
DL, CopiedSign);
1707 FloatSignAsInt SignAsInt;
1708 getSignAsIntValue(SignAsInt,
DL,
Node->getOperand(0));
1709 EVT IntVT = SignAsInt.IntValue.getValueType();
1712 SDValue SignMask = DAG.getConstant(SignAsInt.SignMask,
DL, IntVT);
1717 return modifySignAsInt(SignAsInt,
DL, SignFlip);
1725 EVT FloatVT =
Value.getValueType();
1732 FloatSignAsInt ValueAsInt;
1733 getSignAsIntValue(ValueAsInt,
DL,
Value);
1734 EVT IntVT = ValueAsInt.IntValue.getValueType();
1735 SDValue ClearSignMask = DAG.getConstant(~ValueAsInt.SignMask,
DL, IntVT);
1738 return modifySignAsInt(ValueAsInt,
DL, ClearedSign);
1741void SelectionDAGLegalize::ExpandDYNAMIC_STACKALLOC(
SDNode*
Node,
1743 Register SPReg = TLI.getStackPointerRegisterToSaveRestore();
1744 assert(SPReg &&
"Target cannot require DYNAMIC_STACKALLOC expansion and"
1745 " not tell us which reg is the stack pointer!");
1747 EVT VT =
Node->getValueType(0);
1755 Chain = DAG.getCALLSEQ_START(Chain, 0, 0, dl);
1758 SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, VT);
1760 Align Alignment = cast<ConstantSDNode>(Tmp3)->getAlignValue();
1768 if (Alignment > StackAlign)
1770 DAG.getConstant(-Alignment.
value(), dl, VT));
1771 Chain = DAG.getCopyToReg(Chain, dl, SPReg, Tmp1);
1773 Tmp2 = DAG.getCALLSEQ_END(Chain, 0, 0,
SDValue(), dl);
1785 return EmitStackConvert(
SrcOp, SlotVT, DestVT, dl, DAG.getEntryNode());
1793 Align DestAlign = DAG.getDataLayout().getPrefTypeAlign(DestType);
1796 if ((SrcVT.
bitsGT(SlotVT) &&
1797 !TLI.isTruncStoreLegalOrCustom(
SrcOp.getValueType(), SlotVT)) ||
1798 (SlotVT.
bitsLT(DestVT) &&
1799 !TLI.isLoadExtLegalOrCustom(
ISD::EXTLOAD, DestVT, SlotVT)))
1803 Align SrcAlign = DAG.getDataLayout().getPrefTypeAlign(
1804 SrcOp.getValueType().getTypeForEVT(*DAG.getContext()));
1816 if (SrcVT.
bitsGT(SlotVT))
1817 Store = DAG.getTruncStore(Chain, dl,
SrcOp, FIPtr, PtrInfo,
1821 Store = DAG.getStore(Chain, dl,
SrcOp, FIPtr, PtrInfo, SrcAlign);
1825 if (SlotVT.
bitsEq(DestVT))
1826 return DAG.getLoad(DestVT, dl, Store, FIPtr, PtrInfo, DestAlign);
1829 return DAG.getExtLoad(
ISD::EXTLOAD, dl, DestVT, Store, FIPtr, PtrInfo, SlotVT,
1842 SDValue Ch = DAG.getTruncStore(
1843 DAG.getEntryNode(), dl,
Node->getOperand(0), StackPtr,
1845 Node->getValueType(0).getVectorElementType());
1847 Node->getValueType(0), dl, Ch, StackPtr,
1854 unsigned NumElems =
Node->getNumOperands();
1856 EVT VT =
Node->getValueType(0);
1868 for (
unsigned i = 0; i < NumElems; ++i) {
1879 while (IntermedVals.
size() > 2) {
1880 NewIntermedVals.
clear();
1881 for (
unsigned i = 0, e = (IntermedVals.
size() & ~1u); i < e; i += 2) {
1887 FinalIndices.
reserve(IntermedVals[i].second.
size() +
1888 IntermedVals[i+1].second.
size());
1891 for (
unsigned j = 0, f = IntermedVals[i].second.
size(); j != f;
1894 FinalIndices.
push_back(IntermedVals[i].second[j]);
1896 for (
unsigned j = 0, f = IntermedVals[i+1].second.
size(); j != f;
1898 ShuffleVec[k] = NumElems + j;
1899 FinalIndices.
push_back(IntermedVals[i+1].second[j]);
1905 IntermedVals[i+1].first,
1910 std::make_pair(Shuffle, std::move(FinalIndices)));
1915 if ((IntermedVals.
size() & 1) != 0)
1918 IntermedVals.
swap(NewIntermedVals);
1922 "Invalid number of intermediate vectors");
1923 SDValue Vec1 = IntermedVals[0].first;
1925 if (IntermedVals.
size() > 1)
1926 Vec2 = IntermedVals[1].first;
1931 for (
unsigned i = 0, e = IntermedVals[0].second.
size(); i != e; ++i)
1932 ShuffleVec[IntermedVals[0].second[i]] = i;
1933 for (
unsigned i = 0, e = IntermedVals[1].second.
size(); i != e; ++i)
1934 ShuffleVec[IntermedVals[1].second[i]] = NumElems + i;
1948 unsigned NumElems =
Node->getNumOperands();
1951 EVT VT =
Node->getValueType(0);
1952 EVT OpVT =
Node->getOperand(0).getValueType();
1957 bool isOnlyLowElement =
true;
1958 bool MoreThanTwoValues =
false;
1960 for (
unsigned i = 0; i < NumElems; ++i) {
1965 isOnlyLowElement =
false;
1966 if (!isa<ConstantFPSDNode>(V) && !isa<ConstantSDNode>(V))
1971 }
else if (!Value2.
getNode()) {
1974 }
else if (V != Value1 && V != Value2) {
1975 MoreThanTwoValues =
true;
1980 return DAG.getUNDEF(VT);
1982 if (isOnlyLowElement)
1988 for (
unsigned i = 0, e = NumElems; i !=
e; ++i) {
1990 dyn_cast<ConstantFPSDNode>(
Node->getOperand(i))) {
1993 dyn_cast<ConstantSDNode>(
Node->getOperand(i))) {
2012 DAG.getConstantPool(CP, TLI.getPointerTy(DAG.getDataLayout()));
2013 Align Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlign();
2015 VT, dl, DAG.getEntryNode(), CPIdx,
2021 for (
unsigned i = 0; i < NumElems; ++i) {
2022 if (
Node->getOperand(i).isUndef())
2027 if (TLI.shouldExpandBuildVectorWithShuffles(VT, DefinedValues.
size())) {
2028 if (!MoreThanTwoValues) {
2030 for (
unsigned i = 0; i < NumElems; ++i) {
2034 ShuffleVec[i] =
V == Value1 ? 0 : NumElems;
2036 if (TLI.isShuffleMaskLegal(ShuffleVec,
Node->getValueType(0))) {
2043 Vec2 = DAG.getUNDEF(VT);
2046 return DAG.getVectorShuffle(VT, dl, Vec1, Vec2, ShuffleVec);
2056 return ExpandVectorBuildThroughStack(
Node);
2061 EVT VT =
Node->getValueType(0);
2064 return DAG.getSplatBuildVector(VT,
DL, SplatVal);
2075 EVT CodePtrTy = TLI.getPointerTy(DAG.getDataLayout());
2077 if (
const char *LibcallName = TLI.getLibcallName(LC))
2078 Callee = DAG.getExternalSymbol(LibcallName, CodePtrTy);
2080 Callee = DAG.getUNDEF(CodePtrTy);
2081 DAG.getContext()->emitError(
Twine(
"no libcall available for ") +
2082 Node->getOperationName(&DAG));
2085 EVT RetVT =
Node->getValueType(0);
2092 SDValue InChain = DAG.getEntryNode();
2097 const Function &
F = DAG.getMachineFunction().getFunction();
2099 TLI.isInTailCallPosition(DAG,
Node, TCChain) &&
2100 (
RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
2105 bool signExtend = TLI.shouldSignExtendTypeInLibCall(RetVT,
isSigned);
2108 .setLibCallee(TLI.getLibcallCallingConv(LC),
RetTy, Callee,
2110 .setTailCall(isTailCall)
2111 .setSExtResult(signExtend)
2112 .setZExtResult(!signExtend)
2113 .setIsPostTypeLegalization(
true);
2115 std::pair<SDValue, SDValue>
CallInfo = TLI.LowerCallTo(CLI);
2120 return {DAG.getRoot(), DAG.getRoot()};
2132 EVT ArgVT =
Op.getValueType();
2136 Entry.IsSExt = TLI.shouldSignExtendTypeInLibCall(ArgVT,
isSigned);
2138 Args.push_back(Entry);
2141 return ExpandLibCall(LC,
Node, std::move(Args),
isSigned);
2144void SelectionDAGLegalize::ExpandFrexpLibCall(
2147 EVT VT =
Node->getValueType(0);
2148 EVT ExpVT =
Node->getValueType(1);
2156 FPArgEntry.
Node = FPOp;
2157 FPArgEntry.
Ty = ArgTy;
2159 SDValue StackSlot = DAG.CreateStackTemporary(ExpVT);
2161 PtrArgEntry.
Node = StackSlot;
2162 PtrArgEntry.
Ty = PointerType::get(*DAG.getContext(),
2163 DAG.getDataLayout().getAllocaAddrSpace());
2168 auto [
Call, Chain] = ExpandLibCall(LC,
Node, std::move(Args),
false);
2172 int FrameIdx = cast<FrameIndexSDNode>(StackSlot)->getIndex();
2176 SDValue LoadExp = DAG.getLoad(ExpVT, dl, Chain, StackSlot, PtrInfo);
2178 LoadExp.
getValue(1), DAG.getRoot());
2179 DAG.setRoot(OutputChain);
2185void SelectionDAGLegalize::ExpandFPLibCall(
SDNode*
Node,
2188 if (LC == RTLIB::UNKNOWN_LIBCALL)
2191 if (
Node->isStrictFPOpcode()) {
2192 EVT RetVT =
Node->getValueType(0);
2196 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, RetVT,
2199 Node->getOperand(0));
2201 Results.push_back(Tmp.second);
2203 SDValue Tmp = ExpandLibCall(LC,
Node,
false).first;
2209void SelectionDAGLegalize::ExpandFPLibCall(
SDNode*
Node,
2217 Call_F32, Call_F64, Call_F80,
2218 Call_F128, Call_PPCF128);
2229 switch (
Node->getSimpleValueType(0).SimpleTy) {
2231 case MVT::i8: LC = Call_I8;
break;
2232 case MVT::i16: LC = Call_I16;
break;
2233 case MVT::i32: LC = Call_I32;
break;
2234 case MVT::i64: LC = Call_I64;
break;
2235 case MVT::i128: LC = Call_I128;
break;
2242void SelectionDAGLegalize::ExpandArgFPLibCall(
SDNode*
Node,
2249 EVT InVT =
Node->getOperand(
Node->isStrictFPOpcode() ? 1 : 0).getValueType();
2251 Call_F32, Call_F64, Call_F80,
2252 Call_F128, Call_PPCF128);
2258SelectionDAGLegalize::ExpandDivRemLibCall(
SDNode *
Node,
2260 unsigned Opcode =
Node->getOpcode();
2264 switch (
Node->getSimpleValueType(0).SimpleTy) {
2266 case MVT::i8: LC=
isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8;
break;
2267 case MVT::i16: LC=
isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16;
break;
2268 case MVT::i32: LC=
isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32;
break;
2269 case MVT::i64: LC=
isSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64;
break;
2270 case MVT::i128: LC=
isSigned ? RTLIB::SDIVREM_I128:RTLIB::UDIVREM_I128;
break;
2276 SDValue InChain = DAG.getEntryNode();
2278 EVT RetVT =
Node->getValueType(0);
2284 EVT ArgVT =
Op.getValueType();
2290 Args.push_back(Entry);
2294 SDValue FIPtr = DAG.CreateStackTemporary(RetVT);
2296 Entry.Ty = PointerType::getUnqual(
RetTy->getContext());
2299 Args.push_back(Entry);
2301 SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
2302 TLI.getPointerTy(DAG.getDataLayout()));
2308 .setLibCallee(TLI.getLibcallCallingConv(LC),
RetTy, Callee,
2313 std::pair<SDValue, SDValue>
CallInfo = TLI.LowerCallTo(CLI);
2325 switch (
Node->getSimpleValueType(0).SimpleTy) {
2327 case MVT::f32: LC = RTLIB::SINCOS_F32;
break;
2328 case MVT::f64: LC = RTLIB::SINCOS_F64;
break;
2329 case MVT::f80: LC = RTLIB::SINCOS_F80;
break;
2330 case MVT::f128: LC = RTLIB::SINCOS_F128;
break;
2331 case MVT::ppcf128: LC = RTLIB::SINCOS_PPCF128;
break;
2354SelectionDAGLegalize::ExpandSinCosLibCall(
SDNode *
Node,
2357 switch (
Node->getSimpleValueType(0).SimpleTy) {
2359 case MVT::f32: LC = RTLIB::SINCOS_F32;
break;
2360 case MVT::f64: LC = RTLIB::SINCOS_F64;
break;
2361 case MVT::f80: LC = RTLIB::SINCOS_F80;
break;
2362 case MVT::f128: LC = RTLIB::SINCOS_F128;
break;
2363 case MVT::ppcf128: LC = RTLIB::SINCOS_PPCF128;
break;
2369 SDValue InChain = DAG.getEntryNode();
2371 EVT RetVT =
Node->getValueType(0);
2380 Entry.IsSExt =
false;
2381 Entry.IsZExt =
false;
2382 Args.push_back(Entry);
2385 SDValue SinPtr = DAG.CreateStackTemporary(RetVT);
2386 Entry.Node = SinPtr;
2387 Entry.Ty = PointerType::getUnqual(
RetTy->getContext());
2388 Entry.IsSExt =
false;
2389 Entry.IsZExt =
false;
2390 Args.push_back(Entry);
2393 SDValue CosPtr = DAG.CreateStackTemporary(RetVT);
2394 Entry.Node = CosPtr;
2395 Entry.Ty = PointerType::getUnqual(
RetTy->getContext());
2396 Entry.IsSExt =
false;
2397 Entry.IsZExt =
false;
2398 Args.push_back(Entry);
2400 SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
2401 TLI.getPointerTy(DAG.getDataLayout()));
2405 CLI.setDebugLoc(dl).setChain(InChain).setLibCallee(
2406 TLI.getLibcallCallingConv(LC),
Type::getVoidTy(*DAG.getContext()), Callee,
2409 std::pair<SDValue, SDValue>
CallInfo = TLI.LowerCallTo(CLI);
2419 EVT VT =
Node->getValueType(0);
2422 EVT ExpVT =
N.getValueType();
2424 if (AsIntVT ==
EVT())
2437 TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), ExpVT);
2442 const int Precision = APFloat::semanticsPrecision(FltSem);
2444 const SDValue MaxExp = DAG.getConstant(MaxExpVal, dl, ExpVT);
2445 const SDValue MinExp = DAG.getConstant(MinExpVal, dl, ExpVT);
2447 const SDValue DoubleMaxExp = DAG.getConstant(2 * MaxExpVal, dl, ExpVT);
2449 const APFloat One(FltSem,
"1.0");
2450 APFloat ScaleUpK =
scalbn(One, MaxExpVal, APFloat::rmNearestTiesToEven);
2454 scalbn(One, MinExpVal + Precision, APFloat::rmNearestTiesToEven);
2463 SDValue ClampMaxVal = DAG.getConstant(3 * MaxExpVal, dl, ExpVT);
2469 DAG.getSetCC(dl, SetCCVT,
N, DoubleMaxExp,
ISD::SETUGT);
2471 const SDValue ScaleUpVal = DAG.getConstantFP(ScaleUpK, dl, VT);
2483 SDValue Increment0 = DAG.getConstant(-(MinExpVal + Precision), dl, ExpVT);
2484 SDValue Increment1 = DAG.getConstant(-2 * (MinExpVal + Precision), dl, ExpVT);
2489 DAG.getConstant(3 * MinExpVal + 2 * Precision, dl, ExpVT);
2494 const SDValue ScaleDownVal = DAG.getConstantFP(ScaleDownK, dl, VT);
2498 SDValue ScaleDownTwice = DAG.getSetCC(
2499 dl, SetCCVT,
N, DAG.getConstant(2 * MinExpVal + Precision, dl, ExpVT),
2511 DAG.getNode(
ISD::SELECT, dl, VT, NLtMinExp, SelectX_Small,
X));
2515 DAG.getNode(
ISD::SELECT, dl, ExpVT, NLtMinExp, SelectN_Small,
N));
2520 DAG.getShiftAmountConstant(Precision - 1, ExpVT, dl);
2521 SDValue CastExpToValTy = DAG.getZExtOrTrunc(BiasedN, dl, AsIntVT);
2524 ExponentShiftAmt, NUW_NSW);
2526 return DAG.getNode(
ISD::FMUL, dl, VT, NewX, AsFP);
2533 EVT ExpVT =
Node->getValueType(1);
2535 if (AsIntVT ==
EVT())
2540 const unsigned Precision = APFloat::semanticsPrecision(FltSem);
2557 SDValue NegSmallestNormalizedInt = DAG.getConstant(
2561 SDValue SmallestNormalizedInt = DAG.getConstant(
2567 DAG.getConstant(
APFloat::getInf(FltSem).bitcastToAPInt(), dl, AsIntVT);
2573 FractSignMaskVal.
setBit(BitSize - 1);
2576 SDValue SignMask = DAG.getConstant(SignMaskVal, dl, AsIntVT);
2578 SDValue FractSignMask = DAG.getConstant(FractSignMaskVal, dl, AsIntVT);
2580 const APFloat One(FltSem,
"1.0");
2584 scalbn(One, Precision + 1, APFloat::rmNearestTiesToEven);
2586 SDValue ScaleUpK = DAG.getConstantFP(ScaleUpKVal, dl, VT);
2590 TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
2596 SDValue AddNegSmallestNormal =
2598 SDValue DenormOrZero = DAG.getSetCC(dl, SetCCVT, AddNegSmallestNormal,
2602 DAG.getSetCC(dl, SetCCVT, Abs, SmallestNormalizedInt,
ISD::SETULT);
2604 SDValue MinExp = DAG.getSignedConstant(MinExpVal, dl, ExpVT);
2619 DAG.getShiftAmountConstant(Precision - 1, AsIntVT, dl);
2622 SDValue Exp = DAG.getSExtOrTrunc(ShiftedExp, dl, ExpVT);
2625 SDValue DenormalOffset = DAG.getConstant(-Precision - 1, dl, ExpVT);
2631 const APFloat Half(FltSem,
"0.5");
2632 SDValue FPHalf = DAG.getConstant(Half.bitcastToAPInt(), dl, AsIntVT);
2645 return DAG.getMergeValues({Result0, Result1}, dl);
2656 EVT DestVT =
Node->getValueType(0);
2658 unsigned OpNo =
Node->isStrictFPOpcode() ? 1 : 0;
2664 if (SrcVT == MVT::i32 && TLI.isTypeLegal(MVT::f64) &&
2665 (DestVT.
bitsLE(MVT::f64) ||
2669 LLVM_DEBUG(
dbgs() <<
"32-bit [signed|unsigned] integer to float/double "
2673 SDValue StackSlot = DAG.CreateStackTemporary(MVT::f64);
2680 DAG.getConstant(0x80000000u, dl, MVT::i32));
2683 SDValue Hi = DAG.getConstant(0x43300000u, dl, MVT::i32);
2686 if (DAG.getDataLayout().isBigEndian())
2689 SDValue MemChain = DAG.getEntryNode();
2692 SDValue Store1 = DAG.getStore(MemChain, dl,
Lo, StackSlot,
2705 SDValue Bias = DAG.getConstantFP(
2706 isSigned ? llvm::bit_cast<double>(0x4330000080000000ULL)
2707 : llvm::bit_cast<double>(0x4330000000000000ULL),
2712 if (
Node->isStrictFPOpcode()) {
2714 {
Node->getOperand(0), Load, Bias});
2717 std::pair<SDValue, SDValue> ResultPair;
2719 DAG.getStrictFPExtendOrRound(Sub, Chain, dl, DestVT);
2720 Result = ResultPair.first;
2721 Chain = ResultPair.second;
2727 Result = DAG.getFPExtendOrRound(Sub, dl, DestVT);
2736 if (((SrcVT == MVT::i32 || SrcVT == MVT::i64) && DestVT == MVT::f32) ||
2737 (SrcVT == MVT::i64 && DestVT == MVT::f64)) {
2738 LLVM_DEBUG(
dbgs() <<
"Converting unsigned i32/i64 to f32/f64\n");
2753 EVT SetCCVT = getSetCCResultType(SrcVT);
2755 SDValue SignBitTest = DAG.getSetCC(
2756 dl, SetCCVT, Op0, DAG.getConstant(0, dl, SrcVT),
ISD::SETLT);
2758 EVT ShiftVT = TLI.getShiftAmountTy(SrcVT, DAG.getDataLayout());
2759 SDValue ShiftConst = DAG.getConstant(1, dl, ShiftVT);
2761 SDValue AndConst = DAG.getConstant(1, dl, SrcVT);
2766 if (
Node->isStrictFPOpcode()) {
2769 SDValue InCvt = DAG.getSelect(dl, SrcVT, SignBitTest,
Or, Op0);
2771 {
Node->getOperand(0), InCvt });
2779 Flags.setNoFPExcept(
Node->getFlags().hasNoFPExcept());
2780 Fast->setFlags(Flags);
2781 Flags.setNoFPExcept(
true);
2789 return DAG.getSelect(dl, DestVT, SignBitTest, Slow,
Fast);
2793 if (!TLI.isOperationLegalOrCustom(
2802 "Cannot perform lossless SINT_TO_FP!");
2805 if (
Node->isStrictFPOpcode()) {
2807 {
Node->getOperand(0), Op0 });
2811 SDValue SignSet = DAG.getSetCC(dl, getSetCCResultType(SrcVT), Op0,
2814 Four = DAG.getIntPtrConstant(4, dl);
2815 SDValue CstOffset = DAG.getSelect(dl,
Zero.getValueType(),
2816 SignSet, Four, Zero);
2825 case MVT::i8 : FF = 0x43800000ULL;
break;
2826 case MVT::i16: FF = 0x47800000ULL;
break;
2827 case MVT::i32: FF = 0x4F800000ULL;
break;
2828 case MVT::i64: FF = 0x5F800000ULL;
break;
2830 if (DAG.getDataLayout().isLittleEndian())
2832 Constant *FudgeFactor = ConstantInt::get(
2836 DAG.getConstantPool(FudgeFactor, TLI.getPointerTy(DAG.getDataLayout()));
2837 Align Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlign();
2841 if (DestVT == MVT::f32)
2842 FudgeInReg = DAG.getLoad(
2843 MVT::f32, dl, DAG.getEntryNode(), CPIdx,
2852 LegalizeOp(
Load.getNode());
2856 if (
Node->isStrictFPOpcode()) {
2858 { Tmp1.
getValue(1), Tmp1, FudgeInReg });
2859 Chain =
Result.getValue(1);
2863 return DAG.getNode(
ISD::FADD, dl, DestVT, Tmp1, FudgeInReg);
2871void SelectionDAGLegalize::PromoteLegalINT_TO_FP(
2873 bool IsStrict =
N->isStrictFPOpcode();
2876 EVT DestVT =
N->getValueType(0);
2877 SDValue LegalOp =
N->getOperand(IsStrict ? 1 : 0);
2884 unsigned OpToUse = 0;
2892 if (TLI.isOperationLegalOrCustom(SIntOp, NewInTy)) {
2900 if (TLI.isOperationLegalOrCustom(UIntOp, NewInTy)) {
2912 DAG.
getNode(OpToUse, dl, {DestVT, MVT::Other},
2915 dl, NewInTy, LegalOp)});
2922 DAG.getNode(OpToUse, dl, DestVT,
2924 dl, NewInTy, LegalOp)));
2932void SelectionDAGLegalize::PromoteLegalFP_TO_INT(
SDNode *
N,
const SDLoc &dl,
2934 bool IsStrict =
N->isStrictFPOpcode();
2937 EVT DestVT =
N->getValueType(0);
2938 SDValue LegalOp =
N->getOperand(IsStrict ? 1 : 0);
2940 EVT NewOutTy = DestVT;
2942 unsigned OpToUse = 0;
2952 if (TLI.isOperationLegalOrCustom(OpToUse, NewOutTy))
2957 if (!IsSigned && TLI.isOperationLegalOrCustom(OpToUse, NewOutTy))
2966 SDVTList VTs = DAG.getVTList(NewOutTy, MVT::Other);
2967 Operation = DAG.getNode(OpToUse, dl, VTs,
N->getOperand(0), LegalOp);
2969 Operation = DAG.getNode(OpToUse, dl, NewOutTy, LegalOp);
2984 unsigned Opcode =
Node->getOpcode();
2987 EVT NewOutTy =
Node->getValueType(0);
2992 if (TLI.isOperationLegalOrCustom(Opcode, NewOutTy))
2999 Node->getOperand(1));
3005 EVT VT =
Op.getValueType();
3006 EVT ShVT = TLI.getShiftAmountTy(VT, DAG.getDataLayout());
3011 if (TLI.isOperationLegalOrPromote(
ISD::CTPOP, VT)) {
3017 DAG.getConstant(1ULL << (--i), dl, ShVT));
3022 return DAG.getNode(
ISD::AND, dl, VT, Result, DAG.getConstant(1, dl, VT));
3026 MVT VecVT =
Node->getOperand(1).getSimpleValueType();
3027 MVT NewVecVT = TLI.getTypeToPromoteTo(
Node->getOpcode(), VecVT);
3028 MVT ScalarVT =
Node->getSimpleValueType(0);
3036 assert(
Node->getOperand(0).getValueType().isFloatingPoint() &&
3037 "Only FP promotion is supported");
3041 for (
unsigned j = 1;
j !=
Node->getNumOperands(); ++
j)
3042 if (
Node->getOperand(j).getValueType().isVector() &&
3047 assert(
Node->getOperand(j).getValueType().isFloatingPoint() &&
3048 "Only FP promotion is supported");
3060 DAG.getIntPtrConstant(0,
DL,
true));
3063bool SelectionDAGLegalize::ExpandNode(
SDNode *
Node) {
3067 SDValue Tmp1, Tmp2, Tmp3, Tmp4;
3069 switch (
Node->getOpcode()) {
3071 if ((Tmp1 = TLI.expandABS(
Node, DAG)))
3076 if ((Tmp1 = TLI.expandABD(
Node, DAG)))
3083 if ((Tmp1 = TLI.expandAVG(
Node, DAG)))
3087 if ((Tmp1 = TLI.expandCTPOP(
Node, DAG)))
3092 if ((Tmp1 = TLI.expandCTLZ(
Node, DAG)))
3097 if ((Tmp1 = TLI.expandCTTZ(
Node, DAG)))
3101 if ((Tmp1 = TLI.expandBITREVERSE(
Node, DAG)))
3105 if ((Tmp1 = TLI.expandBSWAP(
Node, DAG)))
3109 Results.push_back(ExpandPARITY(
Node->getOperand(0), dl));
3114 Results.push_back(DAG.getConstant(0, dl,
Node->getValueType(0)));
3117 SDValue CfaArg = DAG.getSExtOrTrunc(
Node->getOperand(0), dl,
3118 TLI.getPointerTy(DAG.getDataLayout()));
3126 DAG.getConstant(0, dl, TLI.getPointerTy(DAG.getDataLayout())));
3132 Results.push_back(DAG.getConstant(1, dl,
Node->getValueType(0)));
3149 DAG.getConstant(0, dl,
Node->getValueType(0)));
3155 Results.push_back(DAG.getConstant(0, dl, MVT::i32));
3161 SDVTList VTs = DAG.getVTList(
Node->getValueType(0), MVT::Other);
3162 SDValue Swap = DAG.getAtomicCmpSwap(
3164 Node->getOperand(0),
Node->getOperand(1), Zero, Zero,
3165 cast<AtomicSDNode>(
Node)->getMemOperand());
3174 Node->getOperand(0),
Node->getOperand(2),
Node->getOperand(1),
3175 cast<AtomicSDNode>(
Node)->getMemOperand());
3183 SDVTList VTs = DAG.getVTList(
Node->getValueType(0), MVT::Other);
3184 SDValue Res = DAG.getAtomicCmpSwap(
3186 Node->getOperand(0),
Node->getOperand(1),
Node->getOperand(2),
3187 Node->getOperand(3), cast<MemSDNode>(
Node)->getMemOperand());
3193 EVT AtomicType = cast<AtomicSDNode>(
Node)->getMemoryVT();
3194 EVT OuterType =
Node->getValueType(0);
3195 switch (TLI.getExtendForAtomicOps()) {
3198 DAG.getValueType(AtomicType));
3200 Node->getOperand(2), DAG.getValueType(AtomicType));
3205 DAG.getValueType(AtomicType));
3206 RHS = DAG.getZeroExtendInReg(
Node->getOperand(2), dl, AtomicType);
3210 LHS = DAG.getZeroExtendInReg(Res, dl, AtomicType);
3211 RHS = DAG.getZeroExtendInReg(
Node->getOperand(2), dl, AtomicType);
3227 EVT VT =
Node->getValueType(0);
3231 cast<VTSDNode>(
RHS->getOperand(1))->getVT() == AN->
getMemoryVT())
3232 RHS =
RHS->getOperand(0);
3236 Node->getOperand(0),
Node->getOperand(1),
3246 for (
unsigned i = 0; i <
Node->getNumValues(); i++)
3250 EVT VT =
Node->getValueType(0);
3252 Results.push_back(DAG.getConstant(0, dl, VT));
3255 Results.push_back(DAG.getConstantFP(0, dl, VT));
3262 if (TLI.isStrictFPEnabled())
3266 if (TLI.getStrictFPOperationAction(
Node->getOpcode(),
3267 Node->getValueType(0))
3268 == TargetLowering::Legal)
3272 if ((Tmp1 = EmitStackConvert(
Node->getOperand(1),
Node->getValueType(0),
3273 Node->getValueType(0), dl,
3274 Node->getOperand(0)))) {
3276 LLVM_DEBUG(
dbgs() <<
"Successfully expanded STRICT_FP_ROUND node\n");
3281 if ((Tmp1 = TLI.expandFP_ROUND(
Node, DAG))) {
3289 if ((Tmp1 = EmitStackConvert(
Node->getOperand(0),
Node->getValueType(0),
3290 Node->getValueType(0), dl)))
3296 if (TLI.isStrictFPEnabled())
3300 if (TLI.getStrictFPOperationAction(
Node->getOpcode(),
3301 Node->getValueType(0))
3302 == TargetLowering::Legal)
3306 if ((Tmp1 = EmitStackConvert(
3307 Node->getOperand(1),
Node->getOperand(1).getValueType(),
3308 Node->getValueType(0), dl,
Node->getOperand(0)))) {
3310 LLVM_DEBUG(
dbgs() <<
"Successfully expanded STRICT_FP_EXTEND node\n");
3316 EVT SrcVT =
Op.getValueType();
3317 EVT DstVT =
Node->getValueType(0);
3323 if ((Tmp1 = EmitStackConvert(
Op, SrcVT, DstVT, dl)))
3333 if (
Op.getValueType() == MVT::bf16) {
3337 Op = DAG.getAnyExtOrTrunc(
Op, dl, MVT::i32);
3341 DAG.getConstant(16, dl,
3342 TLI.getShiftAmountTy(MVT::i32, DAG.getDataLayout())));
3345 if (
Node->getValueType(0) != MVT::f32)
3352 if (
Op.getValueType() != MVT::f32)
3354 DAG.getIntPtrConstant(0, dl,
true));
3356 if (!DAG.isKnownNeverSNaN(
Op)) {
3361 DAG.getConstant(16, dl,
3362 TLI.getShiftAmountTy(MVT::i32, DAG.getDataLayout())));
3365 if (
Node->getValueType(0) == MVT::bf16) {
3369 Op = DAG.getAnyExtOrTrunc(
Op, dl,
Node->getValueType(0));
3375 EVT ExtraVT = cast<VTSDNode>(
Node->getOperand(1))->getVT();
3376 EVT VT =
Node->getValueType(0);
3386 SDValue One = DAG.getConstant(1, dl, VT);
3396 EVT ShiftAmountTy = TLI.getShiftAmountTy(VT, DAG.getDataLayout());
3399 SDValue ShiftCst = DAG.getConstant(BitsDiff, dl, ShiftAmountTy);
3401 Node->getOperand(0), ShiftCst);
3408 if (TLI.expandUINT_TO_FP(
Node, Tmp1, Tmp2, DAG)) {
3410 if (
Node->isStrictFPOpcode())
3417 if ((Tmp1 = ExpandLegalINT_TO_FP(
Node, Tmp2))) {
3419 if (
Node->isStrictFPOpcode())
3424 if (TLI.expandFP_TO_SINT(
Node, Tmp1, DAG))
3428 if (TLI.expandFP_TO_SINT(
Node, Tmp1, DAG)) {
3430 LLVM_DEBUG(
dbgs() <<
"Successfully expanded STRICT_FP_TO_SINT node\n");
3435 if (TLI.expandFP_TO_UINT(
Node, Tmp1, Tmp2, DAG))
3439 if (TLI.expandFP_TO_UINT(
Node, Tmp1, Tmp2, DAG)) {
3441 DAG.ReplaceAllUsesOfValueWith(
SDValue(
Node,1), Tmp2);
3444 LLVM_DEBUG(
dbgs() <<
"Successfully expanded STRICT_FP_TO_UINT node\n");
3450 Results.push_back(TLI.expandFP_TO_INT_SAT(
Node, DAG));
3456 EVT ResVT =
Node->getValueType(0);
3470 if (
Node->getOperand(0).getValueType().getVectorElementCount().isScalar())
3473 Node->getOperand(0));
3475 Tmp1 = ExpandExtractFromVectorThroughStack(
SDValue(
Node, 0));
3485 Results.push_back(ExpandVectorBuildThroughStack(
Node));
3497 EVT VT =
Node->getValueType(0);
3501 if (!TLI.isTypeLegal(EltVT)) {
3502 EVT NewEltVT = TLI.getTypeToTransformTo(*DAG.getContext(), EltVT);
3507 if (NewEltVT.
bitsLT(EltVT)) {
3523 unsigned int factor =
3531 for (
unsigned fi = 0; fi < factor; ++fi)
3535 for (
unsigned fi = 0; fi < factor; ++fi)
3546 for (
unsigned i = 0; i != NumElems; ++i) {
3554 DAG.getVectorIdxConstant(
Idx, dl)));
3558 DAG.getVectorIdxConstant(
Idx - NumElems, dl)));
3561 Tmp1 = DAG.getBuildVector(VT, dl, Ops);
3568 Results.push_back(TLI.expandVectorSplice(
Node, DAG));
3572 EVT OpTy =
Node->getOperand(0).getValueType();
3573 if (
Node->getConstantOperandVal(1)) {
3577 TLI.getShiftAmountTy(
3578 Node->getOperand(0).getValueType(),
3579 DAG.getDataLayout())));
3584 Node->getOperand(0));
3592 if (
Register SP = TLI.getStackPointerRegisterToSaveRestore()) {
3593 Results.push_back(DAG.getCopyFromReg(
Node->getOperand(0), dl, SP,
3594 Node->getValueType(0)));
3597 Results.push_back(DAG.getUNDEF(
Node->getValueType(0)));
3604 if (
Register SP = TLI.getStackPointerRegisterToSaveRestore()) {
3605 Results.push_back(DAG.getCopyToReg(
Node->getOperand(0), dl, SP,
3606 Node->getOperand(1)));
3612 Results.push_back(DAG.getConstant(0, dl,
Node->getValueType(0)));
3627 TLI.expandIS_FPCLASS(
Node->getValueType(0),
Node->getOperand(0),
3638 switch (
Node->getOpcode()) {
3645 Tmp1 =
Node->getOperand(0);
3646 Tmp2 =
Node->getOperand(1);
3647 Tmp1 = DAG.getSelectCC(dl, Tmp1, Tmp2, Tmp1, Tmp2, Pred);
3653 if (
SDValue Expanded = TLI.expandFMINNUM_FMAXNUM(
Node, DAG))
3659 if (
SDValue Expanded = TLI.expandFMINIMUM_FMAXIMUM(
Node, DAG))
3665 Results.push_back(TLI.expandFMINIMUMNUM_FMAXIMUMNUM(
Node, DAG));
3670 EVT VT =
Node->getValueType(0);
3676 SDVTList VTs = DAG.getVTList(VT, VT);
3686 EVT VT =
Node->getValueType(0);
3690 if (TLI.getLibcallName(LC))
3696 Results.push_back(Expanded.getValue(1));
3705 if (TLI.getLibcallName(LC))
3710 Results.push_back(Expanded.getValue(1));
3718 if (
Node->getValueType(0) != MVT::f32) {
3730 if (
Node->getValueType(0) != MVT::f32) {
3735 {Node->getOperand(0), Node->getOperand(1)});
3737 {
Node->getValueType(0), MVT::Other},
3745 if (!TLI.useSoftFloat() &&
TM.Options.UnsafeFPMath) {
3747 MVT SVT =
Op.getSimpleValueType();
3748 if ((SVT == MVT::f64 || SVT == MVT::f80) &&
3754 DAG.getIntPtrConstant(0, dl,
true));
3765 DAG.shouldOptForSize()))
3766 Results.push_back(ExpandConstantFP(CFP,
true));
3771 Results.push_back(ExpandConstant(CP));
3775 EVT VT =
Node->getValueType(0);
3776 if (TLI.isOperationLegalOrCustom(
ISD::FADD, VT) &&
3777 TLI.isOperationLegalOrCustom(
ISD::FNEG, VT)) {
3786 EVT VT =
Node->getValueType(0);
3788 TLI.isOperationLegalOrCustom(
ISD::XOR, VT) &&
3789 "Don't know how to expand this subtraction!");
3790 Tmp1 = DAG.getNOT(dl,
Node->getOperand(1), VT);
3791 Tmp1 = DAG.
getNode(
ISD::ADD, dl, VT, Tmp1, DAG.getConstant(1, dl, VT));
3797 if (TLI.expandREM(
Node, Tmp1, DAG))
3804 EVT VT =
Node->getValueType(0);
3805 if (TLI.isOperationLegalOrCustom(DivRemOpc, VT)) {
3806 SDVTList VTs = DAG.getVTList(VT, VT);
3807 Tmp1 = DAG.
getNode(DivRemOpc, dl, VTs,
Node->getOperand(0),
3808 Node->getOperand(1));
3815 unsigned ExpandOpcode =
3817 EVT VT =
Node->getValueType(0);
3818 SDVTList VTs = DAG.getVTList(VT, VT);
3820 Tmp1 = DAG.
getNode(ExpandOpcode, dl, VTs,
Node->getOperand(0),
3821 Node->getOperand(1));
3829 MVT VT =
LHS.getSimpleValueType();
3830 unsigned MULHOpcode =
3833 if (TLI.isOperationLegalOrCustom(MULHOpcode, VT)) {
3835 Results.push_back(DAG.getNode(MULHOpcode, dl, VT, LHS, RHS));
3841 assert(TLI.isTypeLegal(HalfType));
3842 if (TLI.expandMUL_LOHI(
Node->getOpcode(), VT, dl, LHS, RHS, Halves,
3844 TargetLowering::MulExpansionKind::Always)) {
3845 for (
unsigned i = 0; i < 2; ++i) {
3848 SDValue Shift = DAG.getConstant(
3850 TLI.getShiftAmountTy(HalfType, DAG.getDataLayout()));
3859 EVT VT =
Node->getValueType(0);
3860 SDVTList VTs = DAG.getVTList(VT, VT);
3866 bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(
ISD::SMUL_LOHI, VT);
3867 bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(
ISD::UMUL_LOHI, VT);
3868 bool HasMULHS = TLI.isOperationLegalOrCustom(
ISD::MULHS, VT);
3869 bool HasMULHU = TLI.isOperationLegalOrCustom(
ISD::MULHU, VT);
3870 unsigned OpToUse = 0;
3871 if (HasSMUL_LOHI && !HasMULHS) {
3873 }
else if (HasUMUL_LOHI && !HasMULHU) {
3875 }
else if (HasSMUL_LOHI) {
3877 }
else if (HasUMUL_LOHI) {
3881 Results.push_back(DAG.getNode(OpToUse, dl, VTs,
Node->getOperand(0),
3882 Node->getOperand(1)));
3890 TLI.isOperationLegalOrCustom(
ISD::SHL, VT) &&
3891 TLI.isOperationLegalOrCustom(
ISD::OR, VT) &&
3892 TLI.expandMUL(
Node,
Lo,
Hi, HalfType, DAG,
3893 TargetLowering::MulExpansionKind::OnlyLegalOrCustom)) {
3898 TLI.getShiftAmountTy(HalfType, DAG.getDataLayout()));
3906 if (
SDValue Expanded = TLI.expandFunnelShift(
Node, DAG))
3911 if (
SDValue Expanded = TLI.expandROT(
Node,
true , DAG))
3918 Results.push_back(TLI.expandAddSubSat(
Node, DAG));
3932 Results.push_back(TLI.expandFixedPointMul(
Node, DAG));
3939 Node->getOperand(0),
3940 Node->getOperand(1),
3941 Node->getConstantOperandVal(2),
3964 EVT VT =
LHS.getValueType();
3968 EVT CarryType =
Node->getValueType(1);
3969 EVT SetCCType = getSetCCResultType(
Node->getValueType(0));
3971 SDValue Overflow = DAG.getSetCC(dl, SetCCType, Sum, LHS,
CC);
3974 SDValue One = DAG.getConstant(1, dl, VT);
3976 DAG.
getNode(
ISD::AND, dl, VT, DAG.getZExtOrTrunc(Carry, dl, VT), One);
3985 IsAdd ? DAG.getSetCC(dl, SetCCType, Sum2, Zero,
ISD::SETEQ)
3986 : DAG.getSetCC(dl, SetCCType, Sum, Zero,
ISD::SETEQ);
3988 DAG.getZExtOrTrunc(Carry, dl, SetCCType));
3994 Results.push_back(DAG.getBoolExtOrTrunc(ResultCarry, dl, CarryType, VT));
4000 TLI.expandSADDSUBO(
Node, Result, Overflow, DAG);
4008 TLI.expandUADDSUBO(
Node, Result, Overflow, DAG);
4016 if (TLI.expandMULO(
Node, Result, Overflow, DAG)) {
4028 DAG.getConstant(
PairTy.getSizeInBits() / 2, dl,
4029 TLI.getShiftAmountTy(
PairTy, DAG.getDataLayout())));
4034 Tmp1 =
Node->getOperand(0);
4035 Tmp2 =
Node->getOperand(1);
4036 Tmp3 =
Node->getOperand(2);
4040 cast<CondCodeSDNode>(Tmp1.
getOperand(2))->get());
4042 Tmp1 = DAG.getSelectCC(dl, Tmp1,
4053 int JTI = cast<JumpTableSDNode>(Table.
getNode())->getIndex();
4056 EVT PTy = TLI.getPointerTy(TD);
4058 unsigned EntrySize =
4059 DAG.getMachineFunction().getJumpTableInfo()->getEntrySize(TD);
4066 Index = DAG.getNode(
4071 DAG.getConstant(EntrySize, dl,
Index.getValueType()));
4080 if (TLI.isJumpTableRelative()) {
4085 TLI.getPICJumpTableRelocBase(Table, DAG));
4088 Tmp1 = TLI.expandIndirectJTBranch(dl,
LD.getValue(1),
Addr, JTI, DAG);
4095 Tmp1 =
Node->getOperand(0);
4096 Tmp2 =
Node->getOperand(1);
4102 Node->getOperand(2));
4114 Node->getOperand(2));
4122 bool IsVP =
Node->getOpcode() == ISD::VP_SETCC;
4127 unsigned Offset = IsStrict ? 1 : 0;
4136 bool Legalized = TLI.LegalizeSetCCCondCode(
4137 DAG,
Node->getValueType(0), Tmp1, Tmp2, Tmp3, Mask, EVL, NeedInvert, dl,
4138 Chain, IsSignaling);
4146 {Chain, Tmp1, Tmp2, Tmp3},
Node->getFlags());
4150 {Tmp1, Tmp2, Tmp3, Mask, EVL},
Node->getFlags());
4152 Tmp1 = DAG.
getNode(
Node->getOpcode(), dl,
Node->getValueType(0), Tmp1,
4153 Tmp2, Tmp3,
Node->getFlags());
4161 Tmp1 = DAG.getLogicalNOT(dl, Tmp1, Tmp1->
getValueType(0));
4164 DAG.getVPLogicalNOT(dl, Tmp1, Mask, EVL, Tmp1->
getValueType(0));
4176 assert(!IsStrict &&
"Don't know how to expand for strict nodes.");
4181 EVT VT =
Node->getValueType(0);
4184 DAG.getBoolConstant(
true, dl, VT, Tmp1VT),
4185 DAG.getBoolConstant(
false, dl, VT, Tmp1VT), Tmp3);
4192 Tmp1 =
Node->getOperand(0);
4193 Tmp2 =
Node->getOperand(1);
4194 Tmp3 =
Node->getOperand(2);
4195 Tmp4 =
Node->getOperand(3);
4196 EVT VT =
Node->getValueType(0);
4206 "Cannot expand ISD::SELECT_CC when ISD::SELECT also needs to be "
4208 EVT CCVT = getSetCCResultType(CmpVT);
4211 DAG.getSelect(dl, VT,
Cond, Tmp3, Tmp4,
Node->getFlags()));
4216 bool Legalized =
false;
4224 Tmp1 = DAG.getSelectCC(dl, Tmp1, Tmp2, Tmp4, Tmp3, InvCC);
4234 Tmp1 = DAG.getSelectCC(dl, Tmp2, Tmp1, Tmp4, Tmp3, SwapInvCC);
4240 Legalized = TLI.LegalizeSetCCCondCode(
4244 assert(Legalized &&
"Can't legalize SELECT_CC with legal condition!");
4255 Tmp1, Tmp2, Tmp3, Tmp4,
CC);
4260 Tmp2, Tmp3, Tmp4,
CC);
4270 Tmp1 =
Node->getOperand(0);
4271 Tmp2 =
Node->getOperand(2);
4272 Tmp3 =
Node->getOperand(3);
4273 Tmp4 =
Node->getOperand(1);
4275 bool Legalized = TLI.LegalizeSetCCCondCode(
4276 DAG, getSetCCResultType(Tmp2.
getValueType()), Tmp2, Tmp3, Tmp4,
4279 assert(Legalized &&
"Can't legalize BR_CC with legal condition!");
4284 assert(!NeedInvert &&
"Don't know how to invert BR_CC!");
4287 Tmp4, Tmp2, Tmp3,
Node->getOperand(4));
4292 Tmp2, Tmp3,
Node->getOperand(4));
4307 EVT VT =
Node->getValueType(0);
4313 for (
unsigned Idx = 0;
Idx < NumElem;
Idx++) {
4316 Node->getOperand(0), DAG.getVectorIdxConstant(
Idx, dl));
4319 Node->getOperand(1), DAG.getVectorIdxConstant(
Idx, dl));
4343 Results.push_back(TLI.expandVecReduce(
Node, DAG));
4345 case ISD::VP_CTTZ_ELTS:
4346 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
4347 Results.push_back(TLI.expandVPCTTZElements(
Node, DAG));
4358 EVT ResVT =
Node->getValueType(0);
4379 if (!TLI.isStrictFPEnabled() &&
Results.
empty() &&
Node->isStrictFPOpcode()) {
4385 switch (
Node->getOpcode()) {
4387 if (TLI.getStrictFPOperationAction(
Node->getOpcode(),
4388 Node->getValueType(0))
4389 == TargetLowering::Legal)
4393 if (TLI.getStrictFPOperationAction(
4396 if (TLI.getStrictFPOperationAction(
4400 EVT VT =
Node->getValueType(0);
4404 {Node->getOperand(0), Node->getOperand(1), Neg},
4419 if (TLI.getStrictFPOperationAction(
Node->getOpcode(),
4420 Node->getOperand(1).getValueType())
4421 == TargetLowering::Legal)
4438void SelectionDAGLegalize::ConvertNodeToLibcall(
SDNode *
Node) {
4443 unsigned Opc =
Node->getOpcode();
4452 .setChain(
Node->getOperand(0))
4455 DAG.getExternalSymbol(
"__sync_synchronize",
4456 TLI.getPointerTy(DAG.getDataLayout())),
4459 std::pair<SDValue, SDValue> CallResult = TLI.LowerCallTo(CLI);
4461 Results.push_back(CallResult.second);
4483 EVT RetVT =
Node->getValueType(0);
4486 if (TLI.getLibcallName(LC)) {
4493 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
4494 "Unexpected atomic op or value type!");
4498 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, RetVT,
4501 Node->getOperand(0));
4503 Results.push_back(Tmp.second);
4511 .setChain(
Node->getOperand(0))
4513 DAG.getExternalSymbol(
4514 "abort", TLI.getPointerTy(DAG.getDataLayout())),
4516 std::pair<SDValue, SDValue> CallResult = TLI.LowerCallTo(CLI);
4518 Results.push_back(CallResult.second);
4526 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(
4527 DAG, RTLIB::CLEAR_CACHE, MVT::isVoid, {StartVal, EndVal}, CallOptions,
4529 Results.push_back(Tmp.second);
4534 ExpandFPLibCall(
Node, RTLIB::FMIN_F32, RTLIB::FMIN_F64,
4535 RTLIB::FMIN_F80, RTLIB::FMIN_F128,
4536 RTLIB::FMIN_PPCF128,
Results);
4543 ExpandFPLibCall(
Node, RTLIB::FMAX_F32, RTLIB::FMAX_F64,
4544 RTLIB::FMAX_F80, RTLIB::FMAX_F128,
4545 RTLIB::FMAX_PPCF128,
Results);
4548 ExpandFPLibCall(
Node, RTLIB::FMINIMUMNUM_F32, RTLIB::FMINIMUMNUM_F64,
4549 RTLIB::FMINIMUMNUM_F80, RTLIB::FMINIMUMNUM_F128,
4550 RTLIB::FMINIMUMNUM_PPCF128,
Results);
4553 ExpandFPLibCall(
Node, RTLIB::FMAXIMUMNUM_F32, RTLIB::FMAXIMUMNUM_F64,
4554 RTLIB::FMAXIMUMNUM_F80, RTLIB::FMAXIMUMNUM_F128,
4555 RTLIB::FMAXIMUMNUM_PPCF128,
Results);
4559 ExpandFPLibCall(
Node, RTLIB::SQRT_F32, RTLIB::SQRT_F64,
4560 RTLIB::SQRT_F80, RTLIB::SQRT_F128,
4561 RTLIB::SQRT_PPCF128,
Results);
4564 ExpandFPLibCall(
Node, RTLIB::CBRT_F32, RTLIB::CBRT_F64,
4565 RTLIB::CBRT_F80, RTLIB::CBRT_F128,
4566 RTLIB::CBRT_PPCF128,
Results);
4570 ExpandFPLibCall(
Node, RTLIB::SIN_F32, RTLIB::SIN_F64,
4571 RTLIB::SIN_F80, RTLIB::SIN_F128,
4576 ExpandFPLibCall(
Node, RTLIB::COS_F32, RTLIB::COS_F64,
4577 RTLIB::COS_F80, RTLIB::COS_F128,
4582 ExpandFPLibCall(
Node, RTLIB::TAN_F32, RTLIB::TAN_F64, RTLIB::TAN_F80,
4583 RTLIB::TAN_F128, RTLIB::TAN_PPCF128,
Results);
4587 ExpandFPLibCall(
Node, RTLIB::ASIN_F32, RTLIB::ASIN_F64, RTLIB::ASIN_F80,
4588 RTLIB::ASIN_F128, RTLIB::ASIN_PPCF128,
Results);
4592 ExpandFPLibCall(
Node, RTLIB::ACOS_F32, RTLIB::ACOS_F64, RTLIB::ACOS_F80,
4593 RTLIB::ACOS_F128, RTLIB::ACOS_PPCF128,
Results);
4597 ExpandFPLibCall(
Node, RTLIB::ATAN_F32, RTLIB::ATAN_F64, RTLIB::ATAN_F80,
4598 RTLIB::ATAN_F128, RTLIB::ATAN_PPCF128,
Results);
4602 ExpandFPLibCall(
Node, RTLIB::SINH_F32, RTLIB::SINH_F64, RTLIB::SINH_F80,
4603 RTLIB::SINH_F128, RTLIB::SINH_PPCF128,
Results);
4607 ExpandFPLibCall(
Node, RTLIB::COSH_F32, RTLIB::COSH_F64, RTLIB::COSH_F80,
4608 RTLIB::COSH_F128, RTLIB::COSH_PPCF128,
Results);
4612 ExpandFPLibCall(
Node, RTLIB::TANH_F32, RTLIB::TANH_F64, RTLIB::TANH_F80,
4613 RTLIB::TANH_F128, RTLIB::TANH_PPCF128,
Results);
4621 ExpandFPLibCall(
Node, RTLIB::LOG_F32, RTLIB::LOG_F64, RTLIB::LOG_F80,
4622 RTLIB::LOG_F128, RTLIB::LOG_PPCF128,
Results);
4626 ExpandFPLibCall(
Node, RTLIB::LOG2_F32, RTLIB::LOG2_F64, RTLIB::LOG2_F80,
4627 RTLIB::LOG2_F128, RTLIB::LOG2_PPCF128,
Results);
4631 ExpandFPLibCall(
Node, RTLIB::LOG10_F32, RTLIB::LOG10_F64, RTLIB::LOG10_F80,
4632 RTLIB::LOG10_F128, RTLIB::LOG10_PPCF128,
Results);
4636 ExpandFPLibCall(
Node, RTLIB::EXP_F32, RTLIB::EXP_F64, RTLIB::EXP_F80,
4637 RTLIB::EXP_F128, RTLIB::EXP_PPCF128,
Results);
4641 ExpandFPLibCall(
Node, RTLIB::EXP2_F32, RTLIB::EXP2_F64, RTLIB::EXP2_F80,
4642 RTLIB::EXP2_F128, RTLIB::EXP2_PPCF128,
Results);
4645 ExpandFPLibCall(
Node, RTLIB::EXP10_F32, RTLIB::EXP10_F64, RTLIB::EXP10_F80,
4646 RTLIB::EXP10_F128, RTLIB::EXP10_PPCF128,
Results);
4650 ExpandFPLibCall(
Node, RTLIB::TRUNC_F32, RTLIB::TRUNC_F64,
4651 RTLIB::TRUNC_F80, RTLIB::TRUNC_F128,
4652 RTLIB::TRUNC_PPCF128,
Results);
4656 ExpandFPLibCall(
Node, RTLIB::FLOOR_F32, RTLIB::FLOOR_F64,
4657 RTLIB::FLOOR_F80, RTLIB::FLOOR_F128,
4658 RTLIB::FLOOR_PPCF128,
Results);
4662 ExpandFPLibCall(
Node, RTLIB::CEIL_F32, RTLIB::CEIL_F64,
4663 RTLIB::CEIL_F80, RTLIB::CEIL_F128,
4664 RTLIB::CEIL_PPCF128,
Results);
4668 ExpandFPLibCall(
Node, RTLIB::RINT_F32, RTLIB::RINT_F64,
4669 RTLIB::RINT_F80, RTLIB::RINT_F128,
4670 RTLIB::RINT_PPCF128,
Results);
4674 ExpandFPLibCall(
Node, RTLIB::NEARBYINT_F32,
4675 RTLIB::NEARBYINT_F64,
4676 RTLIB::NEARBYINT_F80,
4677 RTLIB::NEARBYINT_F128,
4678 RTLIB::NEARBYINT_PPCF128,
Results);
4682 ExpandFPLibCall(
Node, RTLIB::ROUND_F32,
4686 RTLIB::ROUND_PPCF128,
Results);
4690 ExpandFPLibCall(
Node, RTLIB::ROUNDEVEN_F32,
4691 RTLIB::ROUNDEVEN_F64,
4692 RTLIB::ROUNDEVEN_F80,
4693 RTLIB::ROUNDEVEN_F128,
4694 RTLIB::ROUNDEVEN_PPCF128,
Results);
4698 ExpandFPLibCall(
Node, RTLIB::LDEXP_F32, RTLIB::LDEXP_F64, RTLIB::LDEXP_F80,
4699 RTLIB::LDEXP_F128, RTLIB::LDEXP_PPCF128,
Results);
4708 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected fpowi.");
4709 if (!TLI.getLibcallName(LC)) {
4711 if (
Node->isStrictFPOpcode()) {
4714 {
Node->getValueType(0),
Node->getValueType(1)},
4715 {
Node->getOperand(0),
Node->getOperand(2)});
4718 {
Node->getValueType(0),
Node->getValueType(1)},
4725 Node->getOperand(1));
4727 Node->getValueType(0),
4732 unsigned Offset =
Node->isStrictFPOpcode() ? 1 : 0;
4733 bool ExponentHasSizeOfInt =
4734 DAG.getLibInfo().getIntSize() ==
4735 Node->getOperand(1 +
Offset).getValueType().getSizeInBits();
4736 if (!ExponentHasSizeOfInt) {
4739 DAG.getContext()->emitError(
"POWI exponent does not match sizeof(int)");
4740 Results.push_back(DAG.getUNDEF(
Node->getValueType(0)));
4748 ExpandFPLibCall(
Node, RTLIB::POW_F32, RTLIB::POW_F64, RTLIB::POW_F80,
4749 RTLIB::POW_F128, RTLIB::POW_PPCF128,
Results);
4753 ExpandArgFPLibCall(
Node, RTLIB::LROUND_F32,
4754 RTLIB::LROUND_F64, RTLIB::LROUND_F80,
4756 RTLIB::LROUND_PPCF128,
Results);
4760 ExpandArgFPLibCall(
Node, RTLIB::LLROUND_F32,
4761 RTLIB::LLROUND_F64, RTLIB::LLROUND_F80,
4762 RTLIB::LLROUND_F128,
4763 RTLIB::LLROUND_PPCF128,
Results);
4767 ExpandArgFPLibCall(
Node, RTLIB::LRINT_F32,
4768 RTLIB::LRINT_F64, RTLIB::LRINT_F80,
4770 RTLIB::LRINT_PPCF128,
Results);
4774 ExpandArgFPLibCall(
Node, RTLIB::LLRINT_F32,
4775 RTLIB::LLRINT_F64, RTLIB::LLRINT_F80,
4777 RTLIB::LLRINT_PPCF128,
Results);
4781 ExpandFPLibCall(
Node, RTLIB::DIV_F32, RTLIB::DIV_F64,
4782 RTLIB::DIV_F80, RTLIB::DIV_F128,
4787 ExpandFPLibCall(
Node, RTLIB::REM_F32, RTLIB::REM_F64,
4788 RTLIB::REM_F80, RTLIB::REM_F128,
4793 ExpandFPLibCall(
Node, RTLIB::FMA_F32, RTLIB::FMA_F64,
4794 RTLIB::FMA_F80, RTLIB::FMA_F128,
4799 ExpandFPLibCall(
Node, RTLIB::ADD_F32, RTLIB::ADD_F64,
4800 RTLIB::ADD_F80, RTLIB::ADD_F128,
4805 ExpandFPLibCall(
Node, RTLIB::MUL_F32, RTLIB::MUL_F64,
4806 RTLIB::MUL_F80, RTLIB::MUL_F128,
4810 if (
Node->getValueType(0) == MVT::f32) {
4811 Results.push_back(ExpandLibCall(RTLIB::FPEXT_F16_F32,
Node,
false).first);
4815 if (
Node->getValueType(0) == MVT::f32) {
4817 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(
4818 DAG, RTLIB::FPEXT_BF16_F32, MVT::f32,
Node->getOperand(1),
4821 Results.push_back(Tmp.second);
4825 if (
Node->getValueType(0) == MVT::f32) {
4827 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(
4828 DAG, RTLIB::FPEXT_F16_F32, MVT::f32,
Node->getOperand(1), CallOptions,
4831 Results.push_back(Tmp.second);
4838 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unable to expand fp_to_fp16");
4839 Results.push_back(ExpandLibCall(LC,
Node,
false).first);
4845 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unable to expand fp_to_bf16");
4846 Results.push_back(ExpandLibCall(LC,
Node,
false).first);
4854 bool IsStrict =
Node->isStrictFPOpcode();
4857 EVT SVT =
Node->getOperand(IsStrict ? 1 : 0).getValueType();
4858 EVT RVT =
Node->getValueType(0);
4866 for (
unsigned t = MVT::FIRST_INTEGER_VALUETYPE;
4867 t <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
4875 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unable to legalize as libcall");
4880 NVT,
Node->getOperand(IsStrict ? 1 : 0));
4883 std::pair<SDValue, SDValue> Tmp =
4884 TLI.makeLibCall(DAG, LC, RVT,
Op, CallOptions, dl, Chain);
4887 Results.push_back(Tmp.second);
4895 bool IsStrict =
Node->isStrictFPOpcode();
4900 EVT SVT =
Op.getValueType();
4901 EVT RVT =
Node->getValueType(0);
4909 for (
unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
4910 IntVT <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
4918 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unable to legalize as libcall");
4922 std::pair<SDValue, SDValue> Tmp =
4923 TLI.makeLibCall(DAG, LC, NVT,
Op, CallOptions, dl, Chain);
4928 Results.push_back(Tmp.second);
4939 bool IsStrict =
Node->isStrictFPOpcode();
4942 EVT VT =
Node->getValueType(0);
4943 assert(cast<ConstantSDNode>(
Node->getOperand(IsStrict ? 2 : 1))->isZero() &&
4944 "Unable to expand as libcall if it is not normal rounding");
4947 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unable to legalize as libcall");
4950 std::pair<SDValue, SDValue> Tmp =
4951 TLI.makeLibCall(DAG, LC, VT,
Op, CallOptions,
SDLoc(
Node), Chain);
4954 Results.push_back(Tmp.second);
4960 Node->getValueType(0)),
4961 Node,
false).first);
4974 Node->getValueType(0));
4976 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unable to legalize as libcall");
4979 std::pair<SDValue, SDValue> Tmp =
4980 TLI.makeLibCall(DAG, LC,
Node->getValueType(0),
Node->getOperand(1),
4983 Results.push_back(Tmp.second);
4988 ExpandFPLibCall(
Node, RTLIB::SUB_F32, RTLIB::SUB_F64,
4989 RTLIB::SUB_F80, RTLIB::SUB_F128,
4995 RTLIB::SREM_I16, RTLIB::SREM_I32,
4996 RTLIB::SREM_I64, RTLIB::SREM_I128));
5001 RTLIB::UREM_I16, RTLIB::UREM_I32,
5002 RTLIB::UREM_I64, RTLIB::UREM_I128));
5007 RTLIB::SDIV_I16, RTLIB::SDIV_I32,
5008 RTLIB::SDIV_I64, RTLIB::SDIV_I128));
5013 RTLIB::UDIV_I16, RTLIB::UDIV_I32,
5014 RTLIB::UDIV_I64, RTLIB::UDIV_I128));
5024 RTLIB::MUL_I16, RTLIB::MUL_I32,
5025 RTLIB::MUL_I64, RTLIB::MUL_I128));
5028 switch (
Node->getSimpleValueType(0).SimpleTy) {
5032 Results.push_back(ExpandLibCall(RTLIB::CTLZ_I32,
Node,
false).first);
5035 Results.push_back(ExpandLibCall(RTLIB::CTLZ_I64,
Node,
false).first);
5038 Results.push_back(ExpandLibCall(RTLIB::CTLZ_I128,
Node,
false).first);
5045 EVT PtrTy = TLI.getPointerTy(DAG.getDataLayout());
5046 SDValue Ptr = DAG.getAllOnesConstant(dl, PtrTy);
5049 DAG.makeStateFunctionCall(RTLIB::FESETENV,
Ptr, Chain, dl));
5056 DAG.makeStateFunctionCall(RTLIB::FEGETENV, EnvPtr, Chain, dl));
5063 DAG.makeStateFunctionCall(RTLIB::FESETENV, EnvPtr, Chain, dl));
5069 EVT ModeVT =
Node->getValueType(0);
5071 int SPFI = cast<FrameIndexSDNode>(
StackPtr.getNode())->getIndex();
5072 SDValue Chain = DAG.makeStateFunctionCall(RTLIB::FEGETMODE, StackPtr,
5073 Node->getOperand(0), dl);
5075 ModeVT, dl, Chain, StackPtr,
5085 EVT ModeVT =
Mode.getValueType();
5087 int SPFI = cast<FrameIndexSDNode>(
StackPtr.getNode())->getIndex();
5088 SDValue StInst = DAG.getStore(
5089 Node->getOperand(0), dl, Mode, StackPtr,
5092 DAG.makeStateFunctionCall(RTLIB::FESETMODE, StackPtr, StInst, dl));
5100 EVT PtrTy = TLI.getPointerTy(
DL);
5102 Results.push_back(DAG.makeStateFunctionCall(RTLIB::FESETMODE, Mode,
5103 Node->getOperand(0), dl));
5110 LLVM_DEBUG(
dbgs() <<
"Successfully converted node to libcall\n");
5119 MVT EltVT,
MVT NewEltVT) {
5121 MVT MidVT = OldEltsPerNewElt == 1
5128void SelectionDAGLegalize::PromoteNode(
SDNode *
Node) {
5131 MVT OVT =
Node->getSimpleValueType(0);
5137 OVT =
Node->getOperand(0).getSimpleValueType();
5144 Node->getOpcode() == ISD::VP_REDUCE_FADD ||
5145 Node->getOpcode() == ISD::VP_REDUCE_FMUL ||
5146 Node->getOpcode() == ISD::VP_REDUCE_FMAX ||
5147 Node->getOpcode() == ISD::VP_REDUCE_FMIN ||
5148 Node->getOpcode() == ISD::VP_REDUCE_FMAXIMUM ||
5149 Node->getOpcode() == ISD::VP_REDUCE_FMINIMUM ||
5150 Node->getOpcode() == ISD::VP_REDUCE_SEQ_FADD)
5151 OVT =
Node->getOperand(1).getSimpleValueType();
5154 OVT =
Node->getOperand(2).getSimpleValueType();
5155 MVT NVT = TLI.getTypeToPromoteTo(
Node->getOpcode(), OVT);
5157 SDValue Tmp1, Tmp2, Tmp3, Tmp4;
5158 switch (
Node->getOpcode()) {
5170 unsigned NewOpc =
Node->getOpcode();
5178 DAG.getConstant(TopBit, dl, NVT));
5183 Tmp1 = DAG.
getNode(NewOpc, dl, NVT, Tmp1);
5198 auto AnyExtendedNode =
5202 auto ShiftConstant = DAG.getShiftAmountConstant(
5204 auto LeftShiftResult =
5205 DAG.getNode(
ISD::SHL, dl, NVT, AnyExtendedNode, ShiftConstant);
5208 auto CTLZResult = DAG.getNode(
Node->getOpcode(), dl, NVT, LeftShiftResult);
5216 Tmp1 = DAG.
getNode(
Node->getOpcode(), dl, NVT, Tmp1);
5219 DAG.getConstant(DiffBits, dl,
5220 TLI.getShiftAmountTy(NVT, DAG.getDataLayout())));
5233 Results.push_back(PromoteLegalFP_TO_INT_SAT(
Node, dl));
5250 &&
"VAARG promotion is supported only for vectors or integer types");
5255 Tmp1 = DAG.getVAArg(NVT, dl, Chain,
Ptr,
Node->getOperand(2),
5256 Node->getConstantOperandVal(3));
5259 Tmp2 = DAG.
getNode(TruncOp, dl, OVT, Tmp1);
5263 DAG.ReplaceAllUsesOfValueWith(
SDValue(
Node, 0), Tmp2);
5264 DAG.ReplaceAllUsesOfValueWith(
SDValue(
Node, 1), Chain);
5266 UpdatedNodes->insert(Tmp2.
getNode());
5267 UpdatedNodes->insert(Chain.
getNode());
5284 unsigned ExtOp, TruncOp;
5291 switch (
Node->getOpcode()) {
5307 if (TLI.isSExtCheaperThanZExt(OVT, NVT))
5316 Tmp1 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(0));
5317 Tmp2 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(1));
5319 Tmp1 = DAG.
getNode(
Node->getOpcode(), dl, NVT, Tmp1, Tmp2);
5320 Results.push_back(DAG.getNode(TruncOp, dl, OVT, Tmp1));
5328 Tmp1 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(0));
5329 Tmp2 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(1));
5332 auto &
DL = DAG.getDataLayout();
5336 DAG.getConstant(OriginalSize, dl, TLI.getScalarShiftAmountTy(
DL, NVT)));
5342 unsigned ExtOp, TruncOp;
5343 if (
Node->getValueType(0).isVector() ||
5347 }
else if (
Node->getValueType(0).isInteger()) {
5354 Tmp1 =
Node->getOperand(0);
5356 Tmp2 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(1));
5357 Tmp3 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(2));
5359 Tmp1 = DAG.getSelect(dl, NVT, Tmp1, Tmp2, Tmp3);
5362 Tmp1 = DAG.
getNode(TruncOp, dl,
Node->getValueType(0), Tmp1);
5364 Tmp1 = DAG.
getNode(TruncOp, dl,
Node->getValueType(0), Tmp1,
5365 DAG.getIntPtrConstant(0, dl));
5377 Tmp1 = ShuffleWithNarrowerEltType(NVT, OVT, dl, Tmp1, Tmp2, Mask);
5386 Node->getOperand(2));
5394 MVT CVT =
Node->getSimpleValueType(0);
5395 assert(CVT == OVT &&
"not handled");
5403 if (TLI.isCondCodeLegal(CCCode, CVT)) {
5404 Tmp1 =
Node->getOperand(0);
5405 Tmp2 =
Node->getOperand(1);
5407 Tmp1 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(0));
5408 Tmp2 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(1));
5411 Tmp3 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(2));
5412 Tmp4 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(3));
5422 DAG.getIntPtrConstant(0, dl,
true));
5434 TLI.isSExtCheaperThanZExt(
Node->getOperand(0).getValueType(), NVT))
5439 if (
Node->isStrictFPOpcode()) {
5441 std::tie(Tmp1, std::ignore) =
5442 DAG.getStrictFPExtendOrRound(
Node->getOperand(1), InChain, dl, NVT);
5443 std::tie(Tmp2, std::ignore) =
5444 DAG.getStrictFPExtendOrRound(
Node->getOperand(2), InChain, dl, NVT);
5446 SDValue OutChain = DAG.getTokenFactor(dl, TmpChains);
5447 SDVTList VTs = DAG.getVTList(
Node->getValueType(0), MVT::Other);
5448 Results.push_back(DAG.getNode(
Node->getOpcode(), dl, VTs,
5449 {OutChain, Tmp1, Tmp2, Node->getOperand(3)},
5454 Tmp1 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(0));
5455 Tmp2 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(1));
5457 Tmp2,
Node->getOperand(2),
Node->getFlags()));
5464 cast<CondCodeSDNode>(
Node->getOperand(1))->get();
5467 Tmp1 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(2));
5468 Tmp2 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(3));
5470 Node->getOperand(0),
Node->getOperand(1),
5471 Tmp1, Tmp2,
Node->getOperand(4)));
5488 Tmp3 = DAG.
getNode(
Node->getOpcode(), dl, NVT, Tmp1, Tmp2,
5492 DAG.getIntPtrConstant(0, dl,
true)));
5503 {
Node->getOperand(0),
Node->getOperand(1)});
5505 {
Node->getOperand(0),
Node->getOperand(2)});
5508 Tmp1 = DAG.
getNode(
Node->getOpcode(), dl, {NVT, MVT::Other},
5509 {Tmp3, Tmp1, Tmp2});
5511 {Tmp1.
getValue(1), Tmp1, DAG.getIntPtrConstant(0, dl)});
5521 DAG.getNode(
Node->getOpcode(), dl, NVT, Tmp1, Tmp2, Tmp3),
5522 DAG.getIntPtrConstant(0, dl,
true)));
5526 {
Node->getOperand(0),
Node->getOperand(1)});
5528 {
Node->getOperand(0),
Node->getOperand(2)});
5530 {
Node->getOperand(0),
Node->getOperand(3)});
5533 Tmp4 = DAG.
getNode(
Node->getOpcode(), dl, {NVT, MVT::Other},
5534 {Tmp4, Tmp1, Tmp2, Tmp3});
5536 {Tmp4.
getValue(1), Tmp4, DAG.getIntPtrConstant(0, dl)});
5544 Tmp2 =
Node->getOperand(1);
5545 Tmp3 = DAG.
getNode(
Node->getOpcode(), dl, NVT, Tmp1, Tmp2);
5555 DAG.getIntPtrConstant(isTrunc, dl,
true)));
5560 {
Node->getOperand(0),
Node->getOperand(1)});
5561 Tmp2 = DAG.
getNode(
Node->getOpcode(), dl, {NVT, MVT::Other},
5564 {Tmp2.
getValue(1), Tmp2, DAG.getIntPtrConstant(0, dl)});
5574 DAG.getIntPtrConstant(0, dl,
true)));
5606 Tmp2 = DAG.
getNode(
Node->getOpcode(), dl, NVT, Tmp1);
5609 DAG.getIntPtrConstant(0, dl,
true)));
5634 {
Node->getOperand(0),
Node->getOperand(1)});
5635 Tmp2 = DAG.
getNode(
Node->getOpcode(), dl, {NVT, MVT::Other},
5638 {Tmp2.
getValue(1), Tmp2, DAG.getIntPtrConstant(0, dl)});
5653 "Invalid promote type for build_vector");
5686 "Invalid promote type for extract_vector_elt");
5693 EVT IdxVT =
Idx.getValueType();
5695 SDValue Factor = DAG.getConstant(NewEltsPerOldElt, SL, IdxVT);
5701 for (
unsigned I = 0;
I < NewEltsPerOldElt; ++
I) {
5702 SDValue IdxOffset = DAG.getConstant(
I, SL, IdxVT);
5710 SDValue NewVec = DAG.getBuildVector(MidVT, SL, NewOps);
5732 "Invalid promote type for insert_vector_elt");
5740 EVT IdxVT =
Idx.getValueType();
5743 SDValue Factor = DAG.getConstant(NewEltsPerOldElt,
SDLoc(), IdxVT);
5750 for (
unsigned I = 0;
I < NewEltsPerOldElt; ++
I) {
5751 SDValue IdxOffset = DAG.getConstant(
I, SL, IdxVT);
5755 CastVal, IdxOffset);
5758 NewVec, Elt, InEltIdx);
5798 "unexpected promotion type");
5800 "unexpected atomic_swap with illegal type");
5824 "unexpected promotion type");
5826 "unexpected atomic_load with illegal type");
5837 MVT ScalarType =
Scalar.getSimpleValueType();
5841 Tmp2 = DAG.
getNode(
Node->getOpcode(), dl, NVT, Tmp1);
5846 Tmp2 = DAG.
getNode(
Node->getOpcode(), dl, NVT, Tmp1);
5849 DAG.getIntPtrConstant(0, dl,
true)));
5852 case ISD::VP_REDUCE_FADD:
5853 case ISD::VP_REDUCE_FMUL:
5854 case ISD::VP_REDUCE_FMAX:
5855 case ISD::VP_REDUCE_FMIN:
5856 case ISD::VP_REDUCE_FMAXIMUM:
5857 case ISD::VP_REDUCE_FMINIMUM:
5858 case ISD::VP_REDUCE_SEQ_FADD:
5884 SelectionDAGLegalize
Legalizer(*
this, LegalizedNodes);
5891 bool AnyLegalized =
false;
5902 if (LegalizedNodes.
insert(
N).second) {
5903 AnyLegalized =
true;
5924 SelectionDAGLegalize
Legalizer(*
this, LegalizedNodes, &UpdatedNodes);
5931 return LegalizedNodes.
count(
N);
aarch64 falkor hwpf fix Falkor HW Prefetch Fix Late Phase
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
static bool isConstant(const MachineInstr &MI)
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
Function Alias Analysis Results
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static bool isSigned(unsigned int Opcode)
Utilities for dealing with flags related to floating point properties and mode controls.
static MaybeAlign getAlign(Value *Ptr)
static bool ExpandBVWithShuffles(SDNode *Node, SelectionDAG &DAG, const TargetLowering &TLI, SDValue &Res)
static bool isSinCosLibcallAvailable(SDNode *Node, const TargetLowering &TLI)
Return true if sincos libcall is available.
static bool useSinCos(SDNode *Node)
Only issue sincos libcall if both sin and cos are needed.
static MachineMemOperand * getStackAlignedMMO(SDValue StackPtr, MachineFunction &MF, bool isObjectScalable)
static MVT getPromotedVectorElementType(const TargetLowering &TLI, MVT EltVT, MVT NewEltVT)
mir Rename Register Operands
std::pair< MCSymbol *, MachineModuleInfoImpl::StubValueTy > PairTy
PowerPC Reduce CR logical Operation
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file describes how to lower LLVM code to machine code.
static constexpr int Concat[]
support::ulittle16_t & Lo
support::ulittle16_t & Hi
DEMANGLE_DUMP_METHOD void dump() const
static APFloat getSmallestNormalized(const fltSemantics &Sem, bool Negative=false)
Returns the smallest (by magnitude) normalized finite number in the given semantics.
APInt bitcastToAPInt() const
static APFloat getInf(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Infinity.
Class for arbitrary precision integers.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
This is an SDNode representing atomic operations.
const SDValue & getBasePtr() const
const SDValue & getVal() const
static bool isValueValidForType(EVT VT, const APFloat &Val)
const APFloat & getValueAPF() const
const ConstantFP * getConstantFPValue() const
ConstantFP - Floating Point Values [float, double].
const APFloat & getValueAPF() const
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
static Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
const BasicBlock & back() const
This class is used to form a handle around another node that is persistent and is updated across invo...
This class is used to represent ISD::LOAD nodes.
static LocationSize precise(uint64_t Value)
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
uint64_t getScalarSizeInBits() const
bool bitsLE(MVT VT) const
Return true if this has no more bits than VT.
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.
bool bitsLT(MVT VT) const
Return true if this has less bits than VT.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static MVT getVectorVT(MVT VT, unsigned NumElements)
MVT getVectorElementType() const
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
A description of a memory reference used in the backend.
Flags
Flags values. These may be or'd together.
@ MOStore
The memory access writes data.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
void dump() const
Dump this node, for debugging.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
iterator_range< use_iterator > uses()
static bool hasPredecessorHelper(const SDNode *N, SmallPtrSetImpl< const SDNode * > &Visited, SmallVectorImpl< const SDNode * > &Worklist, unsigned int MaxSteps=0, bool TopologicalPrune=false)
Returns true if N is a predecessor of any node in Worklist.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
void setFlags(SDNodeFlags NewFlags)
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.
const SDValue & getOperand(unsigned i) const
uint64_t getScalarValueSizeInBits() 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
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
const SDValue & getRoot() const
Return the root tag of the SelectionDAG.
const TargetLowering & getTargetLoweringInfo() const
allnodes_const_iterator allnodes_begin() const
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
allnodes_const_iterator allnodes_end() const
void DeleteNode(SDNode *N)
Remove the specified node from the system.
const DataLayout & getDataLayout() const
void Legalize()
This transforms the SelectionDAG into a SelectionDAG that is compatible with the target instruction s...
bool LegalizeOp(SDNode *N, SmallSetVector< SDNode *, 16 > &UpdatedNodes)
Transforms a SelectionDAG node and any operands to it into a node that is compatible with the target ...
void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
void RemoveDeadNodes()
This method deletes all unreachable nodes in the SelectionDAG.
const TargetMachine & getTarget() const
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
unsigned AssignTopologicalOrder()
Topological-sort the AllNodes list and a assign a unique node id for each node in the DAG based on th...
void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
LLVMContext * getContext() const
SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
bool insert(const value_type &X)
Insert a new element into the SetVector.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
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.
This class is used to represent ISD::STORE nodes.
Information about stack frame layout on the target.
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
StackDirection getStackGrowthDirection() const
getStackGrowthDirection - Return the direction the stack grows
virtual bool isShuffleMaskLegal(ArrayRef< int >, EVT) const
Targets can use this to indicate that they only support some VECTOR_SHUFFLE operations,...
LegalizeAction
This enum indicates whether operations are valid for a target, and if not, what action should be used...
virtual EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const
Return the ValueType of the result of SETCC operations.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
const char * getLibcallName(RTLIB::Libcall Call) const
Get the libcall routine name for the specified libcall.
std::vector< ArgListEntry > ArgListTy
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
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.
static Type * getVoidTy(LLVMContext &C)
static IntegerType * getInt64Ty(LLVMContext &C)
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
LLVM Value Representation.
constexpr ScalarTy getFixedValue() const
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
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.
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ 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.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ SET_FPENV
Sets the current floating-point environment.
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ 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, ptr, val) This corresponds to "store atomic" instruction.
@ FRAME_TO_ARGS_OFFSET
FRAME_TO_ARGS_OFFSET - This node represents offset from frame pointer to first (possible) on-stack ar...
@ RESET_FPENV
Set floating-point environment to default state.
@ FMAD
FMAD - Perform a * b + c, while getting the same result as the separately rounded operations.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ 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.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ 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.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ 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.
@ 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...
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
@ 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,...
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ READSTEADYCOUNTER
READSTEADYCOUNTER - This corresponds to the readfixedcounter intrinsic.
@ ADDROFRETURNADDR
ADDROFRETURNADDR - Represents the llvm.addressofreturnaddress intrinsic.
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ SETCCCARRY
Like SetCC, ops #0 and #1 are the LHS and RHS operands to compare, but op #2 is a boolean indicating ...
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ SSUBO
Same for subtraction.
@ BR_JT
BR_JT - Jumptable branch.
@ 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).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ 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,...
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ 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...
@ GET_FPMODE
Reads the current dynamic floating-point control modes.
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ 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.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two values.
@ UBSANTRAP
UBSANTRAP - Trap with an immediate describing the kind of sanitizer failure.
@ SSHLSAT
RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift.
@ SMULO
Same for multiplication.
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ 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.
@ GLOBAL_OFFSET_TABLE
The address of the GOT.
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ BF16_TO_FP
BF16_TO_FP, FP_TO_BF16 - These operators are used to perform promotions and truncation for bfloat16.
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ 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.
@ TargetConstant
TargetConstant* - Like Constant*, but the DAG does not do any folding, simplification,...
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ 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...
@ GET_FPENV_MEM
Gets the current floating-point environment.
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ 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.
@ VECTOR_SPLICE
VECTOR_SPLICE(VEC1, VEC2, IMM) - Returns a subvector of the same type as VEC1/VEC2 from CONCAT_VECTOR...
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
@ 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 ...
@ SPONENTRY
SPONENTRY - Represents the llvm.sponentry intrinsic.
@ 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.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ 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)...
@ CALLSEQ_START
CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of a call sequence,...
@ GET_DYNAMIC_AREA_OFFSET
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca.
@ SET_FPENV_MEM
Sets the current floating point environment.
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ 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...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
NodeType getExtForLoadExtType(bool IsFP, LoadExtType)
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
CondCode getSetCCInverse(CondCode Operation, EVT Type)
Return the operation corresponding to !(X op Y), where 'op' is a valid SetCC operation.
std::optional< unsigned > getVPMaskIdx(unsigned Opcode)
The operand position of the vector mask.
CondCode getSetCCSwappedOperands(CondCode Operation)
Return the operation corresponding to (Y op X) when given the operation for (X op Y).
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isVPOpcode(unsigned Opcode)
Whether this is a vector-predicated Opcode.
Libcall getPOWI(EVT RetVT)
getPOWI - Return the POWI_* value for the given types, or UNKNOWN_LIBCALL if there is none.
Libcall getSINTTOFP(EVT OpVT, EVT RetVT)
getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
Libcall getSYNC(unsigned Opc, MVT VT)
Return the SYNC_FETCH_AND_* value for the given opcode and type, or UNKNOWN_LIBCALL if there is none.
Libcall getLDEXP(EVT RetVT)
getLDEXP - Return the LDEXP_* value for the given types, or UNKNOWN_LIBCALL if there is none.
Libcall getUINTTOFP(EVT OpVT, EVT RetVT)
getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
Libcall getFREXP(EVT RetVT)
getFREXP - Return the FREXP_* value for the given types, or UNKNOWN_LIBCALL if there is none.
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit.
Libcall getFPTOUINT(EVT OpVT, EVT RetVT)
getFPTOUINT - Return the FPTOUINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
Libcall getFPTOSINT(EVT OpVT, EVT RetVT)
getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
Libcall getOUTLINE_ATOMIC(unsigned Opc, AtomicOrdering Order, MVT VT)
Return the outline atomics value for the given opcode, atomic ordering and type, or UNKNOWN_LIBCALL i...
Libcall getFPEXT(EVT OpVT, EVT RetVT)
getFPEXT - Return the FPEXT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
Libcall getFPROUND(EVT OpVT, EVT RetVT)
getFPROUND - Return the FPROUND_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
Libcall getFPLibCall(EVT VT, Libcall Call_F32, Libcall Call_F64, Libcall Call_F80, Libcall Call_F128, Libcall Call_PPCF128)
GetFPLibCall - Helper to return the right libcall for the given floating point type,...
@ Undef
Value of the register doesn't matter.
ManagedStatic< cl::opt< FnT >, OptCreatorT > Action
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
APFloat scalbn(APFloat X, int Exp, APFloat::roundingMode RM)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Or
Bitwise or logical OR of integers.
@ And
Bitwise or logical AND of integers.
DWARFExpression::Operation Op
bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...
int32_t ExponentType
A signed type to represent a floating point numbers unbiased exponent.
This struct is a compact representation of a valid (non-zero power of two) alignment.
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.
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.
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.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
bool isByteSized() const
Return true if the bit size is a multiple of 8.
uint64_t getScalarSizeInBits() const
EVT getHalfSizedIntegerVT(LLVMContext &Context) const
Finds the smallest simple value type that is greater than or equal to half the width of this EVT.
TypeSize getStoreSizeInBits() const
Return the number of bits overwritten by a store of the specified value 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 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 bitsEq(EVT VT) const
Return true if this has the same number of bits as VT.
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
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.
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
const fltSemantics & getFltSemantics() const
Returns an APFloat semantics tag appropriate for the value type.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool bitsLE(EVT VT) const
Return true if this has no more bits than VT.
bool isInteger() const
Return true if this is an integer or a vector integer type.
This class contains a discriminated union of information about pointers in memory operands,...
static MachinePointerInfo getJumpTable(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a jump table entry.
static MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
MachinePointerInfo getWithOffset(int64_t O) const
static MachinePointerInfo getUnknownStack(MachineFunction &MF)
Stack memory without other information.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
These are IR-level optimization flags that may be propagated to SDNodes.
void setNoUnsignedWrap(bool b)
void setNoSignedWrap(bool b)
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This structure contains all information that is necessary for lowering calls.
This structure is used to pass arguments to makeLibCall function.
MakeLibCallOptions & setSExt(bool Value=true)