26#include "llvm/IR/IntrinsicsAMDGPU.h"
34#define GET_CALLING_CONV_IMPL
35#include "AMDGPUGenCallingConv.inc"
38 "amdgpu-bypass-slow-div",
39 cl::desc(
"Skip 64-bit divide for dynamic 32-bit values"),
48 if (StoreSize % 32 == 0)
66 bool IsSigned,
bool SelfMultiply) {
193 {MVT::v2i8, MVT::v4i8, MVT::v2i16, MVT::v3i16, MVT::v4i16})
400 {MVT::f16, MVT::f32},
Legal);
406 {MVT::f16, MVT::f32, MVT::f64},
Expand);
433 {MVT::v2f32, MVT::v3f32, MVT::v4f32, MVT::v5f32,
434 MVT::v6f32, MVT::v7f32, MVT::v8f32, MVT::v16f32,
435 MVT::v2f64, MVT::v3f64, MVT::v4f64, MVT::v8f64,
443 {MVT::v3i32, MVT::v3f32, MVT::v4i32, MVT::v4f32,
444 MVT::v5i32, MVT::v5f32, MVT::v6i32, MVT::v6f32,
445 MVT::v7i32, MVT::v7f32, MVT::v8i32, MVT::v8f32,
446 MVT::v9i32, MVT::v9f32, MVT::v10i32, MVT::v10f32,
447 MVT::v11i32, MVT::v11f32, MVT::v12i32, MVT::v12f32},
452 {MVT::v2f32, MVT::v2i32, MVT::v3f32, MVT::v3i32, MVT::v4f32,
453 MVT::v4i32, MVT::v5f32, MVT::v5i32, MVT::v6f32, MVT::v6i32,
454 MVT::v7f32, MVT::v7i32, MVT::v8f32, MVT::v8i32, MVT::v9f32,
455 MVT::v9i32, MVT::v10i32, MVT::v10f32, MVT::v11i32, MVT::v11f32,
456 MVT::v12i32, MVT::v12f32, MVT::v16i32, MVT::v32f32, MVT::v32i32,
457 MVT::v2f64, MVT::v2i64, MVT::v3f64, MVT::v3i64, MVT::v4f64,
458 MVT::v4i64, MVT::v8f64, MVT::v8i64, MVT::v16f64, MVT::v16i64},
465 const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
466 for (
MVT VT : ScalarIntVTs) {
501 for (
auto VT : {MVT::i8, MVT::i16})
505 MVT::v2i32, MVT::v3i32, MVT::v4i32, MVT::v5i32, MVT::v6i32, MVT::v7i32,
506 MVT::v9i32, MVT::v10i32, MVT::v11i32, MVT::v12i32};
508 for (
MVT VT : VectorIntTypes) {
535 MVT::v2f32, MVT::v3f32, MVT::v4f32, MVT::v5f32, MVT::v6f32, MVT::v7f32,
536 MVT::v9f32, MVT::v10f32, MVT::v11f32, MVT::v12f32};
538 for (
MVT VT : FloatVectorTypes) {
659 case AMDGPUISD::RCP_LEGACY:
660 case AMDGPUISD::RCP_IFLAG:
661 case AMDGPUISD::SIN_HW:
662 case AMDGPUISD::FMUL_LEGACY:
663 case AMDGPUISD::FMIN_LEGACY:
664 case AMDGPUISD::FMAX_LEGACY:
665 case AMDGPUISD::FMED3:
676 unsigned Opc =
N->getOpcode();
697 return (
N->getNumOperands() > 2 &&
N->getOpcode() !=
ISD::SELECT) ||
706 return N->getValueType(0) == MVT::f32;
716 switch (
N->getOpcode()) {
722 case AMDGPUISD::DIV_SCALE:
731 switch (
N->getConstantOperandVal(0)) {
732 case Intrinsic::amdgcn_interp_p1:
733 case Intrinsic::amdgcn_interp_p2:
734 case Intrinsic::amdgcn_interp_mov:
735 case Intrinsic::amdgcn_interp_p1_f16:
736 case Intrinsic::amdgcn_interp_p2_f16:
750 unsigned CostThreshold) {
756 unsigned NumMayIncreaseSize = 0;
757 MVT VT =
N->getValueType(0).getScalarType().getSimpleVT();
762 for (
const SDNode *U :
N->users()) {
767 if (++NumMayIncreaseSize > CostThreshold)
798 bool ForCodeSize)
const {
806 return (ScalarVT != MVT::f32 && ScalarVT != MVT::f64);
811 std::optional<unsigned> ByteOffset)
const {
823 EVT OldVT =
N->getValueType(0);
838 if (OldSize >= 32 && NewSize < 32 && MN->
getAlign() >=
Align(4) &&
853 return (OldSize < 32);
868 if ((LScalarSize >= CastScalarSize) && (CastScalarSize < 32))
873 CastTy, MMO, &
Fast) &&
889 switch (
N->getOpcode()) {
894 unsigned IntrID =
N->getConstantOperandVal(0);
898 unsigned IntrID =
N->getConstantOperandVal(1);
906 case AMDGPUISD::SETCC:
916 switch (
Op.getOpcode()) {
924 case AMDGPUISD::RCP: {
926 EVT VT =
Op.getValueType();
932 return DAG.
getNode(AMDGPUISD::RCP, SL, VT, NegSrc,
Op->getFlags());
952 return VT == MVT::f32 || VT == MVT::f64 || VT == MVT::f16 || VT == MVT::bf16;
959 return VT == MVT::f32 || VT == MVT::f64 || VT == MVT::f16 || VT == MVT::bf16;
983 unsigned SrcSize = Source.getSizeInBits();
986 return DestSize < SrcSize && DestSize % 32 == 0 ;
992 unsigned SrcSize = Source->getScalarSizeInBits();
995 if (DestSize== 16 && Subtarget->has16BitInsts())
996 return SrcSize >= 32;
998 return DestSize < SrcSize && DestSize % 32 == 0;
1002 unsigned SrcSize = Src->getScalarSizeInBits();
1005 if (SrcSize == 16 && Subtarget->has16BitInsts())
1006 return DestSize >= 32;
1008 return SrcSize == 32 && DestSize == 64;
1017 if (Src == MVT::i16)
1018 return Dest == MVT::i32 ||Dest == MVT::i64 ;
1020 return Src == MVT::i32 && Dest == MVT::i64;
1025 switch (
N->getOpcode()) {
1048 if (!
N->isDivergent() && DestVT.
isInteger() &&
1076 "Expected shift op");
1078 SDValue ShiftLHS =
N->getOperand(0);
1093 if (
N->getValueType(0) == MVT::i32 &&
N->hasOneUse() &&
1094 (
N->user_begin()->getOpcode() ==
ISD::SRA ||
1095 N->user_begin()->getOpcode() ==
ISD::SRL))
1105 return LHS0 && LHS1 && RHSLd && LHS0->getExtensionType() ==
ISD::ZEXTLOAD &&
1106 LHS1->getAPIntValue() == LHS0->getMemoryVT().getScalarSizeInBits() &&
1109 SDValue LHS =
N->getOperand(0).getOperand(0);
1110 SDValue RHS =
N->getOperand(0).getOperand(1);
1111 return !(IsShiftAndLoad(LHS, RHS) || IsShiftAndLoad(RHS, LHS));
1131 return CC_AMDGPU_CS_CHAIN;
1135 return CC_AMDGPU_Func;
1161 return RetCC_SI_Shader;
1164 return RetCC_SI_Gfx;
1168 return RetCC_AMDGPU_Func;
1206 const unsigned ExplicitOffset = Subtarget->getExplicitKernelArgOffset();
1210 uint64_t ExplicitArgOffset = 0;
1213 unsigned InIndex = 0;
1216 const bool IsByRef = Arg.hasByRefAttr();
1217 Type *BaseArgTy = Arg.getType();
1218 Type *MemArgTy = IsByRef ? Arg.getParamByRefType() : BaseArgTy;
1219 Align Alignment =
DL.getValueOrABITypeAlignment(
1220 IsByRef ? Arg.getParamAlign() : std::nullopt, MemArgTy);
1221 MaxAlign = std::max(Alignment, MaxAlign);
1222 uint64_t AllocSize =
DL.getTypeAllocSize(MemArgTy);
1224 uint64_t ArgOffset =
alignTo(ExplicitArgOffset, Alignment) + ExplicitOffset;
1225 ExplicitArgOffset =
alignTo(ExplicitArgOffset, Alignment) + AllocSize;
1237 &Offsets, ArgOffset);
1239 for (
unsigned Value = 0, NumValues = ValueVTs.
size();
1241 uint64_t BasePartOffset = Offsets[
Value];
1277 }
else if (RegisterVT.
isVector()) {
1280 assert(MemoryBits % NumElements == 0);
1284 MemoryBits / NumElements);
1302 unsigned PartOffset = 0;
1303 for (
unsigned i = 0; i != NumRegs; ++i) {
1305 BasePartOffset + PartOffset,
1323 return DAG.
getNode(AMDGPUISD::ENDPGM,
DL, MVT::Other, Chain);
1344 int ClobberedFI)
const {
1347 int64_t LastByte = FirstByte + MFI.
getObjectSize(ClobberedFI) - 1;
1358 if (FI->getIndex() < 0) {
1360 int64_t InLastByte = InFirstByte;
1363 if ((InFirstByte <= FirstByte && FirstByte <= InLastByte) ||
1364 (FirstByte <= InFirstByte && InFirstByte <= LastByte))
1386 FuncName =
G->getSymbol();
1388 FuncName =
G->getGlobal()->getName();
1423 switch (
Op.getOpcode()) {
1427 "instruction is not implemented yet!");
1479 switch (
N->getOpcode()) {
1520 EVT VT =
Op.getValueType();
1539 Fn,
"unsupported use of BARRIER address space",
1549 if (std::optional<uint32_t>
Address =
1559 GV->
getName() !=
"llvm.amdgcn.module.lds") {
1563 Fn,
"local memory global used by non-kernel function",
1595 EVT VT =
Op.getValueType();
1597 unsigned OpBitSize =
Op.getOperand(0).getValueType().getSizeInBits();
1598 if (OpBitSize >= 32 && OpBitSize % 32 == 0) {
1599 unsigned NewNumElt = OpBitSize / 32;
1600 EVT NewEltVT = (NewNumElt == 1) ? MVT::i32
1602 MVT::i32, NewNumElt);
1603 for (
const SDUse &U :
Op->ops()) {
1609 Args.push_back(NewIn);
1613 NewNumElt *
Op.getNumOperands());
1619 for (
const SDUse &U :
Op->ops())
1629 unsigned Start =
Op.getConstantOperandVal(1);
1630 EVT VT =
Op.getValueType();
1631 EVT SrcVT =
Op.getOperand(0).getValueType();
1636 assert(NumElt % 2 == 0 && NumSrcElt % 2 == 0 &&
"expect legal types");
1640 EVT NewVT = NumElt == 2
1712 Opc = AMDGPUISD::FMIN_LEGACY;
1718 Opc = AMDGPUISD::FMIN_LEGACY;
1724 Opc = AMDGPUISD::FMAX_LEGACY;
1730 Opc = AMDGPUISD::FMAX_LEGACY;
1773 if (LHS == NegTrue && CFalse && CRHS) {
1787std::pair<SDValue, SDValue>
1799 return std::pair(
Lo,
Hi);
1820 HiVT = NumElts - LoNumElts == 1
1823 return std::pair(LoVT, HiVT);
1828std::pair<SDValue, SDValue>
1830 const EVT &LoVT,
const EVT &HiVT,
1832 EVT VT =
N.getValueType();
1836 "More vector elements requested than available!");
1867 EVT VT =
Op.getValueType();
1880 EVT MemVT =
Load->getMemoryVT();
1885 EVT LoMemVT, HiMemVT;
1897 Load->getExtensionType(), SL, LoVT,
Load->getChain(), BasePtr, SrcValue,
1898 LoMemVT, BaseAlign,
Load->getMemOperand()->getFlags(),
Load->getAAInfo());
1901 Load->getExtensionType(), SL, HiVT,
Load->getChain(), HiPtr,
1903 Load->getMemOperand()->getFlags(),
Load->getAAInfo());
1927 EVT VT =
Op.getValueType();
1929 EVT MemVT =
Load->getMemoryVT();
1937 if (NumElements != 3 ||
1938 (BaseAlign <
Align(8) &&
1942 assert(NumElements == 3);
1949 Load->getExtensionType(), SL, WideVT,
Load->getChain(), BasePtr, SrcValue,
1950 WideMemVT, BaseAlign,
Load->getMemOperand()->getFlags());
1975 EVT LoMemVT, HiMemVT;
1990 DAG.
getTruncStore(Chain, SL,
Lo, BasePtr, SrcValue, LoMemVT, BaseAlign,
1991 Store->getMemOperand()->getFlags(),
Store->getAAInfo());
1994 Store->getMemOperand()->getFlags(),
Store->getAAInfo());
2004 EVT VT =
Op.getValueType();
2005 assert(VT == MVT::i32 &&
"LowerDIVREMToFloat expects an i32");
2009 MVT IntVT = MVT::i32;
2010 MVT FltVT = MVT::f32;
2012 unsigned LHSSignBits;
2013 unsigned RHSSignBits;
2017 if (LHSSignBits < 9 || RHSSignBits < 9)
2028 unsigned SignBits = std::min(LHSSignBits, RHSSignBits);
2029 unsigned DivBits = BitSize - SignBits;
2038 if (DivBits > (Sign ? 23 : 22))
2071 fa, DAG.
getNode(AMDGPUISD::RCP,
DL, FltVT, fb));
2090 EVT VT =
Op.getValueType();
2092 assert(VT == MVT::i64 &&
"LowerUDIVREM64 expects an i64");
2102 std::tie(LHS_Lo, LHS_Hi) = DAG.
SplitScalar(LHS,
DL, HalfVT, HalfVT);
2106 std::tie(RHS_Lo, RHS_Hi) = DAG.
SplitScalar(RHS,
DL, HalfVT, HalfVT);
2165 std::tie(Mulhi1_Lo, Mulhi1_Hi) =
2178 std::tie(Mulhi2_Lo, Mulhi2_Hi) =
2192 std::tie(Mul3_Lo, Mul3_Hi) = DAG.
SplitScalar(Mul3,
DL, HalfVT, HalfVT);
2271 for (
unsigned i = 0; i < halfBitWidth; ++i) {
2272 const unsigned bitPos = halfBitWidth - i - 1;
2303 EVT VT =
Op.getValueType();
2305 if (VT == MVT::i64) {
2311 if (VT == MVT::i32) {
2358 EVT VT =
Op.getValueType();
2366 if (VT == MVT::i32) {
2445 const unsigned FractBits = 52;
2446 const unsigned ExpBits = 11;
2462 assert(
Op.getValueType() == MVT::f64);
2472 const unsigned FractBits = 52;
2484 = DAG.
getConstant((UINT64_C(1) << FractBits) - 1, SL, MVT::i64);
2509 assert(
Op.getValueType() == MVT::f64);
2542 auto VT =
Op.getValueType();
2543 auto Arg =
Op.getOperand(0u);
2555 EVT VT =
Op.getValueType();
2606 switch (Src.getOpcode()) {
2608 return Src.getOperand(0).getValueType() == MVT::f16;
2612 case AMDGPUISD::LOG:
2613 case AMDGPUISD::EXP:
2616 unsigned IntrinsicID = Src.getConstantOperandVal(0);
2617 switch (IntrinsicID) {
2618 case Intrinsic::amdgcn_frexp_mant:
2619 case Intrinsic::amdgcn_log:
2620 case Intrinsic::amdgcn_log_clamp:
2621 case Intrinsic::amdgcn_exp2:
2622 case Intrinsic::amdgcn_sqrt:
2637 return Flags.hasApproximateFuncs();
2652 EVT VT = Src.getValueType();
2665std::pair<SDValue, SDValue>
2686 return {ScaledInput, IsLtSmallestNormal};
2697 EVT VT =
Op.getValueType();
2701 if (VT == MVT::f16) {
2705 SDValue Log = DAG.
getNode(AMDGPUISD::LOG, SL, MVT::f32, Ext, Flags);
2710 auto [ScaledInput, IsLtSmallestNormal] =
2713 return DAG.
getNode(AMDGPUISD::LOG, SL, VT, Src, Flags);
2733 EVT VT =
Op.getValueType();
2739 if (VT == MVT::f16 || Flags.hasApproximateFuncs()) {
2743 bool PromoteToF32 = VT == MVT::f16 && (!Flags.hasApproximateFuncs() ||
2760 SDValue ScaledInput, IsScaled;
2772 if (Subtarget->hasFastFMAF32()) {
2774 const float c_log10 = 0x1.344134p-2f;
2775 const float cc_log10 = 0x1.09f79ep-26f;
2778 const float c_log = 0x1.62e42ep-1f;
2779 const float cc_log = 0x1.efa39ep-25f;
2785 Flags.setAllowContract(
false);
2793 const float ch_log10 = 0x1.344000p-2f;
2794 const float ct_log10 = 0x1.3509f6p-18f;
2797 const float ch_log = 0x1.62e000p-1f;
2798 const float ct_log = 0x1.0bfbe8p-15f;
2810 Flags.setAllowContract(
false);
2817 const bool IsFiniteOnly = Flags.hasNoNaNs() && Flags.hasNoInfs();
2820 if (!IsFiniteOnly) {
2842 EVT VT = Src.getValueType();
2846 double Log2BaseInverted =
2849 if (VT == MVT::f32) {
2852 SDValue LogSrc = DAG.
getNode(AMDGPUISD::LOG, SL, VT, ScaledInput, Flags);
2859 ScaledResultOffset, Zero, Flags);
2863 if (Subtarget->hasFastFMAF32())
2874 return DAG.
getNode(
ISD::FMUL, SL, VT, Log2Operand, Log2BaseInvertedOperand,
2971 if (!Flags.hasNoInfs()) {
2974 Z = DAG.
getSelect(
DL, MVT::f64, CondHi, Z, PInf, Flags);
2980 Z = DAG.
getSelect(
DL, MVT::f64, CondLo, Z, Zero, Flags);
2989 EVT VT =
Op.getValueType();
2997 if (VT == MVT::f16) {
3001 SDValue Log = DAG.
getNode(AMDGPUISD::EXP, SL, MVT::f32, Ext, Flags);
3009 return DAG.
getNode(AMDGPUISD::EXP, SL, MVT::f32, Src, Flags);
3029 SDValue Exp2 = DAG.
getNode(AMDGPUISD::EXP, SL, VT, AddInput, Flags);
3042 bool IsExp10)
const {
3045 EVT VT =
X.getValueType();
3050 return DAG.
getNode(VT == MVT::f32 ? (
unsigned)AMDGPUISD::EXP
3052 SL, VT,
Mul, Flags);
3058 EVT VT =
X.getValueType();
3077 SDValue Exp2 = DAG.
getNode(AMDGPUISD::EXP, SL, VT, ExpInput, Flags);
3092 const EVT VT =
X.getValueType();
3094 const unsigned Exp2Op = VT == MVT::f32 ?
static_cast<unsigned>(AMDGPUISD::EXP)
3144 EVT VT =
Op.getValueType();
3208 if (Subtarget->hasFastFMAF32()) {
3210 const float cc_exp = 0x1.4ae0bep-26f;
3211 const float c_exp10 = 0x1.a934f0p+1f;
3212 const float cc_exp10 = 0x1.2f346ep-24f;
3222 const float ch_exp = 0x1.714000p+0f;
3223 const float cl_exp = 0x1.47652ap-12f;
3225 const float ch_exp10 = 0x1.a92000p+1f;
3226 const float cl_exp10 = 0x1.4f0978p-11f;
3241 PL =
getMad(DAG, SL, VT, XH, CL, Mad0, Flags);
3256 DAG.
getConstantFP(IsExp10 ? -0x1.66d3e8p+5f : -0x1.9d1da0p+6f, SL, VT);
3265 if (!Flags.hasNoInfs()) {
3267 DAG.
getConstantFP(IsExp10 ? 0x1.344136p+5f : 0x1.62e430p+6f, SL, VT);
3282 EVT VT =
Op.getValueType();
3299 DAG.
getNode(AMDGPUISD::FMUL_LEGACY, SL, VT,
Y, Log, CoreFlags);
3300 return DAG.
getNode(AMDGPUISD::EXP, SL, VT,
Mul, CoreFlags);
3328 if (Flags.hasNoNaNs())
3343 DAG.
getNOT(SL, YIsInt, SetCCVT));
3360 auto Opc =
Op.getOpcode();
3361 auto Arg =
Op.getOperand(0u);
3362 auto ResultVT =
Op.getValueType();
3364 if (ResultVT != MVT::i8 && ResultVT != MVT::i16)
3368 assert(ResultVT == Arg.getValueType());
3370 const uint64_t NumBits = ResultVT.getFixedSizeInBits();
3377 NewOp = DAG.
getNode(
Opc, SL, MVT::i32, NewOp);
3380 NewOp = DAG.
getNode(
Opc, SL, MVT::i32, NewOp);
3393 unsigned NewOpc = Ctlz ? AMDGPUISD::FFBH_U32 : AMDGPUISD::FFBL_B32;
3397 bool Is64BitScalar = !Src->isDivergent() && Src.getValueType() == MVT::i64;
3399 if (Src.getValueType() == MVT::i32 || Is64BitScalar) {
3413 Op.getValueType().getScalarSizeInBits(), SL, MVT::i32);
3433 OprLo = DAG.
getNode(AddOpc, SL, MVT::i32, OprLo, Const32);
3435 OprHi = DAG.
getNode(AddOpc, SL, MVT::i32, OprHi, Const32);
3450 assert(Src.getValueType() == MVT::i32 &&
"LowerCTLS only supports i32");
3462 assert(FP16Ty == MVT::f16 || FP16Ty == MVT::bf16);
3505 if (
Signed && Subtarget->isGCN()) {
3620 EVT DestVT =
Op.getValueType();
3622 EVT SrcVT = Src.getValueType();
3626 if (SrcVT == MVT::i16) {
3627 if (DestVT == MVT::f16)
3632 return DAG.
getNode(CvtOpc,
DL, DestVT, Ext);
3635 if (DestVT == MVT::bf16 || DestVT == MVT::f16)
3638 if (SrcVT != MVT::i64)
3641 if (DestVT == MVT::f32)
3644 assert(DestVT == MVT::f64);
3663 EVT SrcVT = Src.getValueType();
3665 assert(SrcVT == MVT::f32 || SrcVT == MVT::f64);
3678 if (
Signed && SrcVT == MVT::f32) {
3691 if (SrcVT == MVT::f64) {
3713 SL, MVT::i32, FloorMul);
3719 if (
Signed && SrcVT == MVT::f32) {
3739 return DAG.
getNode(AMDGPUISD::FP_TO_FP16,
DL,
Op.getValueType(), N0);
3741 if (
Op->getFlags().hasApproximateFuncs()) {
3752 assert(Src.getSimpleValueType() == MVT::f64);
3756 const unsigned ExpMask = 0x7ff;
3757 const unsigned ExpBiasf64 = 1023;
3758 const unsigned ExpBiasf16 = 15;
3841 unsigned OpOpcode =
Op.getOpcode();
3842 EVT SrcVT = Src.getValueType();
3843 EVT DestVT =
Op.getValueType();
3846 if (SrcVT == MVT::f16 && DestVT == MVT::i16)
3849 if (SrcVT == MVT::bf16 || (SrcVT == MVT::f16 && DestVT == MVT::i32)) {
3852 return DAG.
getNode(
Op.getOpcode(),
DL, DestVT, PromotedSrc);
3856 if (DestVT == MVT::i16 && (SrcVT == MVT::f32 || SrcVT == MVT::f64)) {
3863 if (DestVT != MVT::i64)
3866 if (SrcVT == MVT::f16 ||
3873 return DAG.
getNode(Ext,
DL, MVT::i64, FpToInt32);
3876 if (SrcVT == MVT::f32 || SrcVT == MVT::f64)
3885 unsigned OpOpcode =
Op.getOpcode();
3886 EVT SrcVT = Src.getValueType();
3887 EVT DstVT =
Op.getValueType();
3888 SDValue SatVTOp =
Op.getNode()->getOperand(1);
3894 assert(SatWidth <= DstWidth &&
"Saturation width cannot exceed result width");
3898 if (SatWidth == DstWidth) {
3899 if ((DstVT == MVT::i32 && (SrcVT == MVT::f32 || SrcVT == MVT::f64)) ||
3900 (DstVT == MVT::i16 && (SrcVT == MVT::f16 || SrcVT == MVT::f32)) ||
3901 (DstVT == MVT::v2i16 && SrcVT == MVT::v2f32))
3910 if (SatWidth < DstWidth && SatWidth <= 32) {
3915 Subtarget->has16BitInsts() && SrcVT == MVT::f16 && SatWidth < 16
3949 if (DstVT == MVT::i64 &&
3950 (SrcVT == MVT::f16 || SrcVT == MVT::bf16 ||
3953 return DAG.
getNode(OpOpcode,
DL, DstVT, Src, Int32VTOp);
3957 if (DstVT == MVT::i32 && (SrcVT == MVT::f16 || SrcVT == MVT::bf16)) {
3959 return DAG.
getNode(
Op.getOpcode(),
DL, DstVT, PromotedSrc, SatVTOp);
3965 if (DstWidth < 32) {
3969 (DstWidth < 16 && Subtarget->has16BitInsts()) ? MVT::i16 : MVT::i32;
3982 MVT VT =
Op.getSimpleValueType();
3996 for (
unsigned I = 0;
I < NElts; ++
I)
4011 EVT VT =
Op.getValueType();
4025 unsigned NewOpcode = Node24->
getOpcode();
4029 case Intrinsic::amdgcn_mul_i24:
4030 NewOpcode = AMDGPUISD::MUL_I24;
4032 case Intrinsic::amdgcn_mul_u24:
4033 NewOpcode = AMDGPUISD::MUL_U24;
4035 case Intrinsic::amdgcn_mulhi_i24:
4036 NewOpcode = AMDGPUISD::MULHI_I24;
4038 case Intrinsic::amdgcn_mulhi_u24:
4039 NewOpcode = AMDGPUISD::MULHI_U24;
4063 if (DemandedLHS || DemandedRHS)
4065 DemandedLHS ? DemandedLHS :
LHS,
4066 DemandedRHS ? DemandedRHS :
RHS);
4071template <
typename IntTy>
4074 if (Width +
Offset < 32) {
4076 IntTy Result =
static_cast<IntTy
>(Shl) >> (32 - Width);
4077 if constexpr (std::is_signed_v<IntTy>) {
4090 if (M->isVolatile())
4242 EVT SrcVT = Src.getValueType();
4243 if (SrcVT.
bitsGE(ExtVT)) {
4254 unsigned IID =
N->getConstantOperandVal(0);
4256 case Intrinsic::amdgcn_mul_i24:
4257 case Intrinsic::amdgcn_mul_u24:
4258 case Intrinsic::amdgcn_mulhi_i24:
4259 case Intrinsic::amdgcn_mulhi_u24:
4261 case Intrinsic::amdgcn_fract:
4262 case Intrinsic::amdgcn_rsq:
4263 case Intrinsic::amdgcn_rcp_legacy:
4264 case Intrinsic::amdgcn_rsq_legacy:
4265 case Intrinsic::amdgcn_rsq_clamp:
4266 case Intrinsic::amdgcn_tanh:
4267 case Intrinsic::amdgcn_prng_b32: {
4270 return Src.isUndef() ? Src :
SDValue();
4272 case Intrinsic::amdgcn_frexp_exp: {
4278 if (PeekSign == Src)
4315 EVT VT =
N->getValueType(0);
4328 switch (LHS->getOpcode()) {
4336 if (VT == MVT::i32 && RHSVal == 16 &&
X.getValueType() == MVT::i16 &&
4350 unsigned LZ =
Known.countMinLeadingZeros();
4353 EVT XVT =
X.getValueType();
4385 ShiftAmt = DAG.
getNode(
ISD::AND, SL, TargetType, TruncShiftAmt, ShiftMask);
4396 EVT ConcatType = TargetType.getDoubleNumVectorElementsVT(*DAG.
getContext());
4397 unsigned NElts = TargetType.getVectorNumElements();
4402 for (
unsigned I = 0;
I != NElts; ++
I)
4403 HiAndLoOps[2 *
I + 1] = HiOps[
I];
4416 EVT VT =
N->getValueType(0);
4446 }
else if (
Known.getMinValue().getZExtValue() ==
4447 (ElementType.getSizeInBits() - 1)) {
4448 ShiftAmt = ShiftFullAmt;
4455 ShiftAmt = DAG.
getNode(
ISD::AND, SL, TargetType, TruncShiftAmt, ShiftMask);
4463 unsigned NElts = TargetType.getVectorNumElements();
4464 ConcatType = TargetType.getDoubleNumVectorElementsVT(*DAG.
getContext());
4470 for (
unsigned I = 0;
I != NElts; ++
I) {
4471 HiOps[
I] = HiAndLoOps[2 *
I + 1];
4488 CRHS->
getZExtValue() == (ElementType.getSizeInBits() - 1)) {
4489 NewShift = HiShift =
4500 unsigned NElts = TargetType.getVectorNumElements();
4507 for (
unsigned I = 0;
I != NElts; ++
I) {
4508 HiAndLoOps[2 *
I + 1] = HiOps[
I];
4509 HiAndLoOps[2 *
I] = LoOps[
I];
4522 EVT VT =
N->getValueType(0);
4535 unsigned MaskIdx, MaskLen;
4536 if (Mask->getAPIntValue().isShiftedMask(MaskIdx, MaskLen) &&
4537 MaskIdx == RHSVal) {
4576 ShiftAmt = DAG.
getNode(
ISD::AND, SL, TargetType, TruncShiftAmt, ShiftMask);
4585 unsigned NElts = TargetType.getVectorNumElements();
4586 ConcatType = TargetType.getDoubleNumVectorElementsVT(*DAG.
getContext());
4592 for (
unsigned I = 0;
I != NElts; ++
I)
4593 HiOps[
I] = HiAndLoOps[2 *
I + 1];
4607 unsigned NElts = TargetType.getVectorNumElements();
4612 for (
unsigned I = 0;
I != NElts; ++
I)
4613 HiAndLoOps[2 *
I] = LoOps[
I];
4625 EVT VT =
N->getValueType(0);
4654 unsigned BitIndex =
K->getZExtValue();
4655 unsigned PartIndex = BitIndex / SrcEltSize;
4657 if (PartIndex * SrcEltSize == BitIndex &&
4675 EVT SrcVT = Src.getValueType();
4687 const unsigned MaxCstSize =
4689 if (
Known.getMaxValue().ule(MaxCstSize)) {
4721 unsigned MulOpc =
Signed ? AMDGPUISD::MUL_I24 : AMDGPUISD::MUL_U24;
4722 return DAG.
getNode(MulOpc, SL, MVT::i32, N0, N1);
4725 unsigned MulLoOpc =
Signed ? AMDGPUISD::MUL_I24 : AMDGPUISD::MUL_U24;
4726 unsigned MulHiOpc =
Signed ? AMDGPUISD::MULHI_I24 : AMDGPUISD::MULHI_U24;
4746 EVT VT =
N->getValueType(0);
4752 if (!
N->isDivergent())
4774 if (V.hasOneUse() ||
all_of(V->users(), [](
const SDNode *U) ->
bool {
4775 return U->getOpcode() == ISD::MUL;
4784 if (
SDValue MulOper = IsFoldableAdd(N0)) {
4789 if (
SDValue MulOper = IsFoldableAdd(N1)) {
4810 if (Subtarget->hasMulU24() &&
isU24(N0, DAG) &&
isU24(N1, DAG)) {
4814 }
else if (Subtarget->hasMulI24() &&
isI24(N0, DAG) &&
isI24(N1, DAG)) {
4830 if (
N->getValueType(0) != MVT::i32)
4851 unsigned LoOpcode = 0;
4852 unsigned HiOpcode = 0;
4854 if (Subtarget->hasMulI24() &&
isI24(N0, DAG) &&
isI24(N1, DAG)) {
4857 LoOpcode = AMDGPUISD::MUL_I24;
4858 HiOpcode = AMDGPUISD::MULHI_I24;
4861 if (Subtarget->hasMulU24() &&
isU24(N0, DAG) &&
isU24(N1, DAG)) {
4864 LoOpcode = AMDGPUISD::MUL_U24;
4865 HiOpcode = AMDGPUISD::MULHI_U24;
4879 EVT VT =
N->getValueType(0);
4881 if (!Subtarget->hasMulI24() || VT.
isVector())
4890 if (Subtarget->hasSMulHi() && !
N->isDivergent())
4912 EVT VT =
N->getValueType(0);
4923 if (!
N->isDivergent() && Subtarget->hasSMulHi())
4946 unsigned Opc)
const {
4947 EVT VT =
Op.getValueType();
4984 isCttzOpc(RHS.getOpcode()) ? AMDGPUISD::FFBL_B32 : AMDGPUISD::FFBH_U32;
4985 return getFFBX_U32(DAG, CmpLHS, SL,
Opc);
4994 isCttzOpc(LHS.getOpcode()) ? AMDGPUISD::FFBL_B32 : AMDGPUISD::FFBH_U32;
4996 return getFFBX_U32(DAG, CmpLHS, SL,
Opc);
5014 return DAG.
getNode(
Op, SL, VT, NewSelect);
5032 EVT VT =
N.getValueType();
5059 bool ShouldFoldNeg =
true;
5064 ShouldFoldNeg =
false;
5066 ShouldFoldNeg =
false;
5069 if (ShouldFoldNeg) {
5093 Cond, NewLHS, NewRHS);
5095 return DAG.
getNode(LHS.getOpcode(), SL, VT, NewSelect);
5111 EVT VT =
N->getValueType(0);
5119 if (
Cond.hasOneUse()) {
5135 if (VT == MVT::f32 && Subtarget->hasFminFmaxLegacy()) {
5137 CC,
N->getFlags(), DCI);
5165 if (Subtarget->hasInv2PiInlineImm() &&
isInv2Pi(
C->getValueAPF()))
5195 case AMDGPUISD::FMAX_LEGACY:
5196 return AMDGPUISD::FMIN_LEGACY;
5197 case AMDGPUISD::FMIN_LEGACY:
5198 return AMDGPUISD::FMAX_LEGACY;
5229 EVT VT =
N->getValueType(0);
5236 bool MayIgnoreSignedZeroForAllUses =
5238 (N0.
hasOneUse() &&
N->getFlags().hasNoSignedZeros());
5243 if (!MayIgnoreSignedZeroForAllUses)
5268 case AMDGPUISD::FMUL_LEGACY: {
5291 if (!MayIgnoreSignedZeroForAllUses)
5326 case AMDGPUISD::FMAX_LEGACY:
5327 case AMDGPUISD::FMIN_LEGACY: {
5342 if ((
Opc == AMDGPUISD::FMIN_LEGACY ||
Opc == AMDGPUISD::FMAX_LEGACY) &&
5357 case AMDGPUISD::FMED3: {
5365 for (
unsigned I = 0;
I < 3; ++
I)
5369 if (Res.
getOpcode() != AMDGPUISD::FMED3)
5389 case AMDGPUISD::RCP:
5390 case AMDGPUISD::RCP_LEGACY:
5391 case AMDGPUISD::RCP_IFLAG:
5392 case AMDGPUISD::SIN_HW: {
5431 EVT SrcVT = Src.getValueType();
5467 Ops.back() = CastBack;
5517 EVT SrcVT = Src.getValueType();
5553 if (!Subtarget->isGCN())
5559 const auto *
TII = ST.getInstrInfo();
5561 if (!ST.hasVMovB64Inst() || (!SDConstant && !SDFPConstant))
5564 if (ST.has64BitLiterals())
5581 switch(
N->getOpcode()) {
5585 EVT DestVT =
N->getValueType(0);
5597 EVT SrcVT = Src.getValueType();
5627 uint64_t CVal =
C->getZExtValue();
5635 const APInt &Val =
C->getValueAPF().bitcastToAPInt();
5656 if (!(
N->getValueType(0).isVector() &&
5670 case AMDGPUISD::MUL_U24:
5671 case AMDGPUISD::MUL_I24: {
5676 case AMDGPUISD::MULHI_I24:
5677 case AMDGPUISD::MULHI_U24:
5692 case AMDGPUISD::BFE_I32:
5693 case AMDGPUISD::BFE_U32: {
5694 assert(
N->getValueType(0) == MVT::i32 &&
5695 "BFE_I32/BFE_U32 is a 32-bit operation");
5708 SDValue BitsFrom =
N->getOperand(0);
5711 bool Signed =
N->getOpcode() == AMDGPUISD::BFE_I32;
5713 if (OffsetVal == 0) {
5740 CVal->getSExtValue(),
5747 CVal->getZExtValue(),
5753 if ((OffsetVal + WidthVal) >= 32 &&
5754 !(OffsetVal == 16 && WidthVal == 16 && Subtarget->hasSDWA())) {
5757 BitsFrom, ShiftVal);
5763 OffsetVal + WidthVal);
5781 case AMDGPUISD::RCP:
5782 case AMDGPUISD::RCP_IFLAG:
5789 case AMDGPUISD::FMAD_FTZ: {
5793 EVT VT =
N->getValueType(0);
5800 if (N0CFP && N1CFP && N2CFP) {
5801 const auto FTZ = [](
const APFloat &V) {
5802 if (V.isDenormal()) {
5803 APFloat Zero(V.getSemantics(), 0);
5804 return V.isNegative() ? -Zero : Zero;
5826 unsigned Depth)
const {
5827 switch (
Op.getOpcode()) {
5829 switch (
Op.getConstantOperandVal(0)) {
5830 case Intrinsic::amdgcn_readfirstlane:
5831 case Intrinsic::amdgcn_readlane:
5832 case Intrinsic::amdgcn_wwm: {
5834 OriginalDemandedElts,
Known, TLO,
Depth + 1))
5838 case Intrinsic::amdgcn_set_inactive:
5839 case Intrinsic::amdgcn_set_inactive_chain_arg: {
5844 OriginalDemandedElts, KnownValue, TLO,
5848 OriginalDemandedElts, KnownInactive, TLO,
5874 bool RawReg)
const {
5879 if (!
MRI.isLiveIn(Reg)) {
5880 VReg =
MRI.createVirtualRegister(RC);
5881 MRI.addLiveIn(Reg, VReg);
5883 VReg =
MRI.getLiveInVirtReg(Reg);
5934 DAG.
getCopyFromReg(Chain, SL, Info->getStackPtrOffsetReg(), MVT::i32);
5945 assert(Arg &&
"Attempting to load missing argument");
5954 unsigned Mask = Arg.
getMask();
5964 unsigned ExplicitArgOffset = Subtarget->getExplicitKernelArgOffset();
5965 const Align Alignment = Subtarget->getAlignmentForImplicitArgPtr();
5966 uint64_t ArgOffset =
5967 alignTo(ExplicitKernArgSize, Alignment) + ExplicitArgOffset;
5990 int &RefinementSteps,
5991 bool &UseOneConstNR,
5992 bool Reciprocal)
const {
5995 if (VT == MVT::f32) {
5996 RefinementSteps = 0;
5997 return DAG.
getNode(AMDGPUISD::RSQ,
SDLoc(Operand), VT, Operand);
6008 int &RefinementSteps)
const {
6011 if (VT == MVT::f32) {
6017 RefinementSteps = 0;
6018 return DAG.
getNode(AMDGPUISD::RCP,
SDLoc(Operand), VT, Operand);
6029 case Intrinsic::amdgcn_workitem_id_x:
6031 case Intrinsic::amdgcn_workitem_id_y:
6033 case Intrinsic::amdgcn_workitem_id_z:
6046 unsigned Opc =
Op.getOpcode();
6051 case AMDGPUISD::CARRY:
6052 case AMDGPUISD::BORROW: {
6057 case AMDGPUISD::BFE_I32:
6058 case AMDGPUISD::BFE_U32: {
6065 if (
Opc == AMDGPUISD::BFE_U32)
6070 case AMDGPUISD::FP_TO_FP16: {
6077 case AMDGPUISD::MUL_U24:
6078 case AMDGPUISD::MUL_I24: {
6083 bool SelfMultiply =
Op.getOperand(0) ==
Op.getOperand(1);
6090 Op.getScalarValueSizeInBits(),
6091 Opc == AMDGPUISD::MUL_I24, SelfMultiply);
6094 case AMDGPUISD::PERM: {
6103 for (
unsigned I = 0;
I < 32;
I += 8) {
6104 unsigned SelBits = Sel & 0xff;
6109 }
else if (SelBits < 7) {
6110 SelBits = (SelBits & 3) * 8;
6113 }
else if (SelBits == 0x0c) {
6114 Known.Zero |= 0xFFull <<
I;
6115 }
else if (SelBits > 0x0c) {
6116 Known.One |= 0xFFull <<
I;
6122 case AMDGPUISD::BUFFER_LOAD_UBYTE: {
6123 Known.Zero.setHighBits(24);
6126 case AMDGPUISD::BUFFER_LOAD_USHORT: {
6127 Known.Zero.setHighBits(16);
6130 case AMDGPUISD::LDS: {
6134 Known.Zero.setHighBits(16);
6138 case AMDGPUISD::SMIN3:
6139 case AMDGPUISD::SMAX3:
6140 case AMDGPUISD::SMED3:
6141 case AMDGPUISD::UMIN3:
6142 case AMDGPUISD::UMAX3:
6143 case AMDGPUISD::UMED3: {
6162 unsigned IID =
Op.getConstantOperandVal(0);
6164 case Intrinsic::amdgcn_workitem_id_x:
6165 case Intrinsic::amdgcn_workitem_id_y:
6166 case Intrinsic::amdgcn_workitem_id_z: {
6167 unsigned MaxValue = Subtarget->getMaxWorkitemID(
6172 case Intrinsic::amdgcn_readfirstlane:
6173 case Intrinsic::amdgcn_readlane:
6186 unsigned Depth)
const {
6187 switch (
Op.getOpcode()) {
6188 case AMDGPUISD::BFE_I32: {
6193 unsigned SignBits = 32 - (Width->
getZExtValue() & 0x1f) + 1;
6199 return std::max(SignBits, Op0SignBits);
6202 case AMDGPUISD::BFE_U32: {
6204 return Width ? 32 - (Width->
getZExtValue() & 0x1f) : 1;
6207 case AMDGPUISD::CARRY:
6208 case AMDGPUISD::BORROW:
6210 case AMDGPUISD::BUFFER_LOAD_BYTE:
6212 case AMDGPUISD::BUFFER_LOAD_SHORT:
6214 case AMDGPUISD::BUFFER_LOAD_UBYTE:
6216 case AMDGPUISD::BUFFER_LOAD_USHORT:
6218 case AMDGPUISD::FP_TO_FP16:
6220 case AMDGPUISD::SMIN3:
6221 case AMDGPUISD::SMAX3:
6222 case AMDGPUISD::SMED3:
6223 case AMDGPUISD::UMIN3:
6224 case AMDGPUISD::UMAX3:
6225 case AMDGPUISD::UMED3: {
6238 return std::min({Tmp0, Tmp1, Tmp2});
6253 switch (
MI->getOpcode()) {
6254 case AMDGPU::G_AMDGPU_BUFFER_LOAD_SBYTE:
6256 case AMDGPU::G_AMDGPU_BUFFER_LOAD_SSHORT:
6258 case AMDGPU::G_AMDGPU_BUFFER_LOAD_UBYTE:
6260 case AMDGPU::G_AMDGPU_BUFFER_LOAD_USHORT:
6262 case AMDGPU::G_AMDGPU_SMED3:
6263 case AMDGPU::G_AMDGPU_UMED3: {
6264 auto [Dst, Src0, Src1, Src2] =
MI->getFirst4Regs();
6265 unsigned Tmp2 =
Analysis.computeNumSignBits(Src2, DemandedElts,
Depth + 1);
6268 unsigned Tmp1 =
Analysis.computeNumSignBits(Src1, DemandedElts,
Depth + 1);
6271 unsigned Tmp0 =
Analysis.computeNumSignBits(Src0, DemandedElts,
Depth + 1);
6274 return std::min({Tmp0, Tmp1, Tmp2});
6284 unsigned Opcode =
Op.getOpcode();
6286 case AMDGPUISD::BFE_I32:
6287 case AMDGPUISD::BFE_U32:
6291 Op, DemandedElts, DAG, Kind, ConsiderFlags,
Depth);
6296 unsigned Depth)
const {
6297 unsigned Opcode =
Op.getOpcode();
6299 case AMDGPUISD::FMIN_LEGACY:
6300 case AMDGPUISD::FMAX_LEGACY:
6303 case AMDGPUISD::FMUL_LEGACY:
6304 case AMDGPUISD::CVT_PKRTZ_F16_F32: {
6310 case AMDGPUISD::FMED3:
6311 case AMDGPUISD::FMIN3:
6312 case AMDGPUISD::FMAX3:
6313 case AMDGPUISD::FMINIMUM3:
6314 case AMDGPUISD::FMAXIMUM3:
6315 case AMDGPUISD::FMAD_FTZ: {
6322 case AMDGPUISD::CVT_F32_UBYTE0:
6323 case AMDGPUISD::CVT_F32_UBYTE1:
6324 case AMDGPUISD::CVT_F32_UBYTE2:
6325 case AMDGPUISD::CVT_F32_UBYTE3:
6328 case AMDGPUISD::RCP:
6329 case AMDGPUISD::RSQ:
6330 case AMDGPUISD::RCP_LEGACY:
6331 case AMDGPUISD::RSQ_CLAMP: {
6339 case AMDGPUISD::FRACT: {
6344 case AMDGPUISD::DIV_SCALE:
6345 case AMDGPUISD::DIV_FMAS:
6346 case AMDGPUISD::DIV_FIXUP:
6349 case AMDGPUISD::SIN_HW:
6350 case AMDGPUISD::COS_HW: {
6355 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
6357 switch (IntrinsicID) {
6358 case Intrinsic::amdgcn_cubeid:
6359 case Intrinsic::amdgcn_cvt_off_f32_i4:
6362 case Intrinsic::amdgcn_frexp_mant: {
6367 case Intrinsic::amdgcn_cvt_pkrtz: {
6373 case Intrinsic::amdgcn_rcp:
6374 case Intrinsic::amdgcn_rsq:
6375 case Intrinsic::amdgcn_rcp_legacy:
6376 case Intrinsic::amdgcn_rsq_legacy:
6377 case Intrinsic::amdgcn_rsq_clamp:
6378 case Intrinsic::amdgcn_tanh: {
6385 case Intrinsic::amdgcn_trig_preop:
6386 case Intrinsic::amdgcn_fdot2:
6389 case Intrinsic::amdgcn_fma_legacy:
6406 return MRI.hasOneNonDBGUse(N0);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU address space definition.
static LLVM_READONLY bool hasSourceMods(const MachineInstr &MI)
static bool isInv2Pi(const APFloat &APF)
static LLVM_READONLY bool opMustUseVOP3Encoding(const MachineInstr &MI, const MachineRegisterInfo &MRI)
returns true if the operation will definitely need to use a 64-bit encoding, and thus will use a VOP3...
static unsigned inverseMinMax(unsigned Opc)
static SDValue extractF64Exponent(SDValue Hi, const SDLoc &SL, SelectionDAG &DAG)
static unsigned workitemIntrinsicDim(unsigned ID)
static int getOrCreateFixedStackObject(MachineFrameInfo &MFI, unsigned Size, int64_t Offset)
static SDValue constantFoldBFE(SelectionDAG &DAG, IntTy Src0, uint32_t Offset, uint32_t Width, const SDLoc &DL)
static SDValue getMad(SelectionDAG &DAG, const SDLoc &SL, EVT VT, SDValue X, SDValue Y, SDValue C, SDNodeFlags Flags=SDNodeFlags())
static SDValue getAddOneOp(const SDNode *V)
If V is an add of a constant 1, returns the other operand.
static bool canIgnoreLegacyMinMaxTies(const SelectionDAG &DAG, SDNodeFlags Flags, SDValue LHS, SDValue RHS)
static LLVM_READONLY bool selectSupportsSourceMods(const SDNode *N)
Return true if v_cndmask_b32 will support fabs/fneg source modifiers for the type for ISD::SELECT.
static cl::opt< bool > AMDGPUBypassSlowDiv("amdgpu-bypass-slow-div", cl::desc("Skip 64-bit divide for dynamic 32-bit values"), cl::init(true))
static SDValue getMul24(SelectionDAG &DAG, const SDLoc &SL, SDValue N0, SDValue N1, unsigned Size, bool Signed)
static bool fnegFoldsIntoOp(const SDNode *N)
static bool isI24(SDValue Op, SelectionDAG &DAG)
static bool isCttzOpc(unsigned Opc)
static bool isU24(SDValue Op, SelectionDAG &DAG)
static bool valueIsKnownNeverF32Denorm(SDValue Src)
Return true if it's known that Src can never be an f32 denormal value.
static SDValue distributeOpThroughSelect(TargetLowering::DAGCombinerInfo &DCI, unsigned Op, const SDLoc &SL, SDValue Cond, SDValue N1, SDValue N2)
static SDValue peekFNeg(SDValue Val)
static SDValue simplifyMul24(SDNode *Node24, TargetLowering::DAGCombinerInfo &DCI)
static bool isCtlzOpc(unsigned Opc)
static LLVM_READNONE bool fnegFoldsIntoOpcode(unsigned Opc)
static bool hasVolatileUser(SDNode *Val)
Interface definition of the TargetLowering class that is common to all AMD GPUs.
Contains the definition of a TargetInstrInfo class that is common to all AMD GPUs.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
block Block Frequency Analysis
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Provides analysis for querying information about KnownBits during GISel passes.
const HexagonInstrInfo * TII
static MaybeAlign getAlign(Value *Ptr)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
MachineBasicBlock * Folded
SmallVector< MachineOperand, 4 > Cond
MachineRegisterInfo & MRI
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static CCAssignFn * CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg)
static CCAssignFn * CCAssignFnForReturn(CallingConv::ID CC, bool IsVarArg)
unsigned allocateBarrierGlobal(const DataLayout &DL, const GlobalVariable &GV)
uint64_t getExplicitKernArgSize() const
bool isModuleEntryFunction() const
static std::optional< uint32_t > get32BitAbsoluteAddress(const GlobalValue &GV, unsigned AS)
unsigned allocateLDSGlobal(const DataLayout &DL, const GlobalVariable &GV)
static unsigned numBitsSigned(SDValue Op, SelectionDAG &DAG)
unsigned ComputeNumSignBitsForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
This method can be implemented by targets that want to expose additional information about sign bits ...
SDValue performMulhuCombine(SDNode *N, DAGCombinerInfo &DCI) const
EVT getTypeForExtReturn(LLVMContext &Context, EVT VT, ISD::NodeType ExtendKind) const override
Return the type that should be used to zero or sign extend a zeroext/signext integer return value.
SDValue SplitVectorLoad(SDValue Op, SelectionDAG &DAG) const
Split a vector load into 2 loads of half the vector.
SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const
SDValue performLoadCombine(SDNode *N, DAGCombinerInfo &DCI) const
void analyzeFormalArgumentsCompute(CCState &State, const SmallVectorImpl< ISD::InputArg > &Ins) const
The SelectionDAGBuilder will automatically promote function arguments with illegal types.
SDValue LowerF64ToF16Safe(SDValue Src, const SDLoc &DL, SelectionDAG &DAG) const
SDValue LowerFROUND(SDValue Op, SelectionDAG &DAG) const
SDValue storeStackInputValue(SelectionDAG &DAG, const SDLoc &SL, SDValue Chain, SDValue ArgVal, int64_t Offset) const
bool storeOfVectorConstantIsCheap(bool IsZero, EVT MemVT, unsigned NumElem, unsigned AS) const override
Return true if it is expected to be cheaper to do a store of vector constant with the given size and ...
SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
bool shouldCombineMemoryType(EVT VT) const
SDValue splitBinaryBitConstantOpImpl(DAGCombinerInfo &DCI, const SDLoc &SL, unsigned Opc, SDValue LHS, uint32_t ValLo, uint32_t ValHi) const
Split the 64-bit value LHS into two 32-bit components, and perform the binary operation Opc to it wit...
SDValue lowerUnhandledCall(CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals, StringRef Reason) const
virtual SDValue LowerGlobalAddress(AMDGPUMachineFunctionInfo *MFI, SDValue Op, SelectionDAG &DAG) const
SDValue performAssertSZExtCombine(SDNode *N, DAGCombinerInfo &DCI) const
bool isTruncateFree(EVT Src, EVT Dest) const override
bool aggressivelyPreferBuildVectorSources(EVT VecVT) const override
SDValue LowerFCEIL(SDValue Op, SelectionDAG &DAG) const
TargetLowering::NegatibleCost getConstantNegateCost(const ConstantFPSDNode *C) const
SDValue LowerFLOGUnsafe(SDValue Op, const SDLoc &SL, SelectionDAG &DAG, bool IsLog10, SDNodeFlags Flags) const
SDValue combineFMinMaxLegacy(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, SDValue True, SDValue False, SDValue CC, SDNodeFlags Flags, DAGCombinerInfo &DCI) const
Flags must be the select flags, not the compare (SELECT_CC flags come from the fcmp and say nothing a...
SDValue performMulhsCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue lowerFEXPUnsafeImpl(SDValue Op, const SDLoc &SL, SelectionDAG &DAG, SDNodeFlags Flags, bool IsExp10) const
bool isSDNodeAlwaysUniform(const SDNode *N) const override
bool isDesirableToCommuteWithShift(const SDNode *N, CombineLevel Level) const override
Return true if it is profitable to move this shift by a constant amount through its operand,...
SDValue performShlCombine(SDNode *N, DAGCombinerInfo &DCI) const
bool isCheapToSpeculateCtlz(Type *Ty) const override
Return true if it is cheap to speculate a call to intrinsic ctlz.
SDValue LowerSDIVREM(SDValue Op, SelectionDAG &DAG) const
bool isFNegFree(EVT VT) const override
Return true if an fneg operation is free to the point where it is never worthwhile to replace it with...
FPImmAction getFPImmAction(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns how the legalizer should materialize the specified FP immediate.
SDValue LowerINT_TO_FP64(SDValue Op, SelectionDAG &DAG, bool Signed) const
unsigned computeNumSignBitsForTargetInstr(GISelValueTracking &Analysis, Register R, const APInt &DemandedElts, const MachineRegisterInfo &MRI, unsigned Depth=0) const override
This method can be implemented by targets that want to expose additional information about sign bits ...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
SDValue LowerFP_TO_FP16(SDValue Op, SelectionDAG &DAG) const
SDValue addTokenForArgument(SDValue Chain, SelectionDAG &DAG, MachineFrameInfo &MFI, int ClobberedFI) const
bool isReassocProfitable(MachineRegisterInfo &MRI, Register N0, Register N1) const override
bool isKnownNeverNaNForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, bool SNaN=false, unsigned Depth=0) const override
If SNaN is false,.
static bool needsDenormHandlingF32(const SelectionDAG &DAG, SDValue Src, SDNodeFlags Flags)
SDValue lowerFPOW(SDValue Op, SelectionDAG &DAG) const
uint32_t getImplicitParameterOffset(const MachineFunction &MF, const ImplicitParameter Param) const
Helper function that returns the byte offset of the given type of implicit parameter.
SDValue lowerFEXPF64(SDValue Op, SelectionDAG &DAG) const
SDValue LowerFFLOOR(SDValue Op, SelectionDAG &DAG) const
SDValue performSelectCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue performFNegCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const
bool isConstantCostlierToNegate(SDValue N) const
static KnownBits computeKnownBitsForMul24(const KnownBits &LHSKnown, const KnownBits &RHSKnown, unsigned BitWidth, bool IsSigned, bool SelfMultiply)
SDValue loadInputValue(SelectionDAG &DAG, const TargetRegisterClass *RC, EVT VT, const SDLoc &SL, const ArgDescriptor &Arg) const
SDValue lowerFEXP10Unsafe(SDValue Op, const SDLoc &SL, SelectionDAG &DAG, SDNodeFlags Flags) const
Emit approx-funcs appropriate lowering for exp10.
bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtType, EVT ExtVT, std::optional< unsigned > ByteOffset) const override
Return true if it is profitable to reduce a load to a smaller type.
SDValue LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const
bool canCreateUndefOrPoisonForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const override
Return true if Op can create undef or poison from non-undef & non-poison operands.
bool isCheapToSpeculateCttz(Type *Ty) const override
Return true if it is cheap to speculate a call to intrinsic cttz.
SDValue performCtlz_CttzCombine(const SDLoc &SL, SDValue Cond, SDValue LHS, SDValue RHS, DAGCombinerInfo &DCI) const
SDValue performSraCombine(SDNode *N, DAGCombinerInfo &DCI) const
bool isSelectSupported(SelectSupportKind) const override
bool isZExtFree(Type *Src, Type *Dest) const override
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
SDValue lowerFEXP2(SDValue Op, SelectionDAG &DAG) const
SDValue LowerCall(CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower calls into the specified DAG.
SDValue performSrlCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue lowerFEXP(SDValue Op, SelectionDAG &DAG) const
SDValue getIsFinite(SelectionDAG &DAG, SDValue Op, SDNodeFlags Flags) const
bool isLoadBitCastBeneficial(EVT, EVT, const SelectionDAG &DAG, const MachineMemOperand &MMO) const final
Return true if the following transform is beneficial: fold (conv (load x)) -> (load (conv*)x) On arch...
std::pair< SDValue, SDValue > splitVector(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HighVT, SelectionDAG &DAG) const
Split a vector value into two parts of types LoVT and HiVT.
AMDGPUTargetLowering(const TargetMachine &TM, const TargetSubtargetInfo &STI, const AMDGPUSubtarget &AMDGPUSTI)
SDValue LowerFLOGCommon(SDValue Op, SelectionDAG &DAG) const
SDValue foldFreeOpFromSelect(TargetLowering::DAGCombinerInfo &DCI, SDValue N) const
SDValue LowerINT_TO_FP32(SDValue Op, SelectionDAG &DAG, bool Signed) const
bool isFAbsFree(EVT VT) const override
Return true if an fabs operation is free to the point where it is never worthwhile to replace it with...
bool isInt64ImmLegal(SDNode *Val, SelectionDAG &DAG) const
Check whether value Val can be supported by v_mov_b64, for the current target.
SDValue loadStackInputValue(SelectionDAG &DAG, EVT VT, const SDLoc &SL, int64_t Offset) const
Similar to CreateLiveInRegister, except value maybe loaded from a stack slot rather than passed in a ...
SDValue LowerFLOG2(SDValue Op, SelectionDAG &DAG) const
static EVT getEquivalentMemType(LLVMContext &Context, EVT VT)
SDValue LowerCTLS(SDValue Op, SelectionDAG &DAG) const
Split a vector store into multiple scalar stores.
SDValue getSqrtEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled, int &RefinementSteps, bool &UseOneConstNR, bool Reciprocal) const override
Hooks for building estimates in place of slower divisions and square roots.
SDValue performTruncateCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) const
static SDValue stripBitcast(SDValue Val)
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const
SDValue CreateLiveInRegister(SelectionDAG &DAG, const TargetRegisterClass *RC, Register Reg, EVT VT, const SDLoc &SL, bool RawReg=false) const
Helper function that adds Reg to the LiveIn list of the DAG's MachineFunction.
SDValue SplitVectorStore(SDValue Op, SelectionDAG &DAG) const
Split a vector store into 2 stores of half the vector.
SDValue LowerCTLZ_CTTZ(SDValue Op, SelectionDAG &DAG) const
SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOperations, bool ForCodeSize, NegatibleCost &Cost, unsigned Depth) const override
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
std::pair< SDValue, SDValue > split64BitValue(SDValue Op, SelectionDAG &DAG) const
Return 64-bit value Op as two 32-bit integers.
SDValue performMulCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue combineFMinMaxLegacyImpl(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, SDValue True, SDValue False, SDValue CC, SDNodeFlags Flags, DAGCombinerInfo &DCI) const
SDValue getRecipEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled, int &RefinementSteps) const override
Return a reciprocal estimate value for the input operand.
SDValue LowerFNEARBYINT(SDValue Op, SelectionDAG &DAG) const
SDValue LowerSIGN_EXTEND_INREG(SDValue Op, SelectionDAG &DAG) const
static CCAssignFn * CCAssignFnForReturn(CallingConv::ID CC, bool IsVarArg)
std::pair< SDValue, SDValue > getScaledLogInput(SelectionDAG &DAG, const SDLoc SL, SDValue Op, SDNodeFlags Flags) const
If denormal handling is required return the scaled input to FLOG2, and the check for denormal range.
static CCAssignFn * CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg)
Selects the correct CCAssignFn for a given CallingConvention value.
bool SimplifyDemandedBitsForTargetNode(SDValue Op, const APInt &OriginalDemandedBits, const APInt &OriginalDemandedElts, KnownBits &Known, TargetLoweringOpt &TLO, unsigned Depth) const override
Attempt to simplify any target nodes based on the demanded bits/elts, returning true on success.
static bool allUsesHaveSourceMods(const SDNode *N, unsigned CostThreshold=4)
SDValue LowerFROUNDEVEN(SDValue Op, SelectionDAG &DAG) const
static unsigned numBitsUnsigned(SDValue Op, SelectionDAG &DAG)
SDValue lowerFEXPUnsafe(SDValue Op, const SDLoc &SL, SelectionDAG &DAG, SDNodeFlags Flags) const
SDValue LowerFTRUNC(SDValue Op, SelectionDAG &DAG) const
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const
static bool allowApproxFunc(const SelectionDAG &DAG, SDNodeFlags Flags)
bool ShouldShrinkFPConstant(EVT VT) const override
If true, then instruction selection should seek to shrink the FP constant of the specified type to a ...
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, const SmallVectorImpl< SDValue > &OutVals, const SDLoc &DL, SelectionDAG &DAG) const override
This hook must be implemented to lower outgoing return values, described by the Outs array,...
SDValue performStoreCombine(SDNode *N, DAGCombinerInfo &DCI) const
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked when a node result type is illegal for the target, and the operation was reg...
SDValue performRcpCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue lowerCTLZResults(SDValue Op, SelectionDAG &DAG) const
SDValue LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const
SDValue performFAbsCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue LowerFP_TO_INT64(SDValue Op, SelectionDAG &DAG, bool Signed) const
static bool shouldFoldFNegIntoSrc(SDNode *FNeg, SDValue FNegSrc)
bool isNarrowingProfitable(SDNode *N, EVT SrcVT, EVT DestVT) const override
Return true if it's profitable to narrow operations of type SrcVT to DestVT.
SDValue LowerFRINT(SDValue Op, SelectionDAG &DAG) const
SDValue performIntrinsicWOChainCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue LowerUDIVREM(SDValue Op, SelectionDAG &DAG) const
SDValue performMulLoHiCombine(SDNode *N, DAGCombinerInfo &DCI) const
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue lowerINT_TO_FPImpl(SDValue Op, SelectionDAG &DAG, bool Signed) const
void LowerUDIVREM64(SDValue Op, SelectionDAG &DAG, SmallVectorImpl< SDValue > &Results) const
SDValue WidenOrSplitVectorLoad(SDValue Op, SelectionDAG &DAG) const
Widen a suitably aligned v3 load.
SDValue LowerDIVREMToFloat(SDValue Op, SelectionDAG &DAG, bool sign) const
std::pair< EVT, EVT > getSplitDestVTs(const EVT &VT, SelectionDAG &DAG) const
Split a vector type into two parts.
SDValue getHiHalf64(SDValue Op, SelectionDAG &DAG) const
SDValue LowerINT_TO_FP16(SDValue Op, SelectionDAG &DAG, EVT FP16Ty) const
unsigned getVectorIdxWidth(const DataLayout &) const override
Returns the type to be used for the index operand vector operations.
static const fltSemantics & IEEEsingle()
static const fltSemantics & IEEEdouble()
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & IEEEhalf()
static APFloat getQNaN(const fltSemantics &Sem, bool Negative=false, const APInt *payload=nullptr)
Factory for QNaN values.
bool bitwiseIsEqual(const APFloat &RHS) 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.
uint64_t getZExtValue() const
Get zero extended value.
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
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 getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
This class represents an incoming formal argument to a Function.
int64_t getOffset() const
unsigned getTargetFlags() const
const BlockAddress * getBlockAddress() const
CCState - This class holds information needed while lowering arguments and return values.
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP)
const APFloat & getValueAPF() const
bool isNegative() const
Return true if the value is negative.
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
A parsed version of the target data layout string in and methods for querying it.
Diagnostic information for unsupported feature in backend.
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
iterator_range< arg_iterator > args()
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
bool signBitIsZeroOrNaN() const
Return true if the sign bit must be 0, ignoring the sign of nans.
This is an important class for using LLVM in a threaded context.
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
static auto integer_fixedlen_vector_valuetypes()
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
int getObjectIndexBegin() const
Return the minimum frame object index.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
DenormalMode getDenormalMode(const fltSemantics &FPType) const
Returns the denormal handling type for the default rounding mode of the function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Representation of each machine instruction.
A description of a memory reference used in the backend.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOInvariant
The memory access always returns the same value (or traps).
Flags getFlags() const
Return the raw flags of the source value,.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
This is an abstract virtual class for memory operations.
unsigned getAddressSpace() const
Return the address space for the associated pointer.
bool isSimple() const
Returns true if the memory operation is neither atomic or volatile.
MachineMemOperand * getMemOperand() const
Return the unique 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...
const DebugLoc & getDebugLoc() const
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
SDNodeFlags getFlags() const
SDVTList getVTList() const
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
Represents a use of a SDNode.
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
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node, in exactly one operand.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
unsigned getOpcode() const
unsigned getNumOperands() const
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
SIModeRegisterDefaults getMode() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI bool isKnownNeverLogicalZero(SDValue Op, const APInt &DemandedElts, unsigned Depth=0) const
Test whether the given floating point SDValue (or all elements of it, if it is a vector) is known to ...
SDValue getExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT, unsigned Opcode)
Convert Op, which must be of integer type, to the integer type VT, by either any/sign/zero-extending ...
LLVM_ABI unsigned ComputeMaxSignificantBits(SDValue Op, unsigned Depth=0) const
Get the upper bound on bit size for this Value Op as a signed integer.
const SDValue & getRoot() const
Return the root tag of the SelectionDAG.
const TargetSubtargetInfo & getSubtarget() const
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getShiftAmountConstant(uint64_t Val, EVT VT, const SDLoc &DL)
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI void ExtractVectorElements(SDValue Op, SmallVectorImpl< SDValue > &Args, unsigned Start=0, unsigned Count=0, EVT EltVT=EVT())
Append the extracted elements from Start to Count out of the vector Op in Args.
LLVM_ABI SDValue getFreeze(SDValue V)
Return a freeze using the SDLoc of the value operand.
LLVM_ABI SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false, SDNodeFlags Flags={})
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, SDValue Offset, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
LLVM_ABI SDValue getZeroExtendInReg(SDValue Op, const SDLoc &DL, EVT VT)
Return the expression required to zero extend the Op value assuming it was the smaller SrcTy value.
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
LLVM_ABI void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
LLVM_ABI SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
bool isConstantValueOfAnyType(SDValue N) const
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
LLVM_ABI SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI KnownFPClass computeKnownFPClass(SDValue Op, FPClassTest InterestedClasses, unsigned Depth=0) const
Determine floating-point class information about Op.
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(SDValue Op, UndefPoisonKind Kind=UndefPoisonKind::UndefOrPoison, unsigned Depth=0) const
Return true if this function can prove that Op is never poison and, Kind can be used to track poison ...
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
LLVM_ABI bool isKnownNeverNaN(SDValue Op, const APInt &DemandedElts, bool SNaN=false, unsigned Depth=0) const
Test whether the given SDValue (or all elements of it, if it is a vector) is known to never be NaN in...
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
LLVM_ABI SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getPOISON(EVT VT)
Return a POISON node. POISON does not have a useful SDLoc.
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
const SDValue & setRoot(SDValue N)
Set the current root tag of the SelectionDAG.
LLVM_ABI SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
Represent a constant reference to a string, i.e.
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
void setMaxDivRemBitWidthSupported(unsigned SizeInBits)
Set the size in bits of the maximum div/rem the backend supports.
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
virtual bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy, EVT NewVT, std::optional< unsigned > ByteOffset=std::nullopt) const
Return true if it is profitable to reduce a load to a smaller type.
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
const TargetMachine & getTargetMachine() const
virtual unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain targets require unusual breakdowns of certain types.
unsigned MaxGluedStoresPerMemcpy
Specify max number of store instructions to glue in inlined memcpy.
virtual MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
void addBypassSlowDiv(unsigned int SlowBitWidth, unsigned int FastBitWidth)
Tells the code generator which bitwidths to bypass.
void setMaxLargeFPConvertBitWidthSupported(unsigned SizeInBits)
Set the size in bits of the maximum fp to/from int conversion the backend supports.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
SelectSupportKind
Enum that describes what type of support for selects the target has.
virtual bool allowsMisalignedMemoryAccesses(EVT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *=nullptr) const
Determine if the target supports unaligned memory accesses.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const
Returns the type for the shift amount of a shift opcode.
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
virtual EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const
Return the ValueType of the result of SETCC operations.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setSupportsUnalignedAtomics(bool UnalignedSupported)
Sets whether unaligned atomic operations are supported.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
FPImmAction
How the legalizer should materialize a floating-point immediate.
@ ConstantPool
Load the immediate from the constant pool.
@ Legal
The target can instruction select the immediate natively.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
void setMinCmpXchgSizeInBits(unsigned SizeInBits)
Sets the minimum cmpxchg or ll/sc size supported by the backend.
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
unsigned GatherAllAliasesMaxDepth
Depth that GatherAllAliases should continue looking for chain dependencies when trying to find a more...
NegatibleCost
Enum that specifies when a float negation is beneficial.
bool allowsMemoryAccessForAlignment(LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const
This function returns true if the memory access is aligned or if the target allows this specific unal...
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
SDValue scalarizeVectorStore(StoreSDNode *ST, SelectionDAG &DAG) const
SDValue SimplifyMultipleUseDemandedBits(SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts, SelectionDAG &DAG, unsigned Depth=0) const
More limited version of SimplifyDemandedBits that can be used to "lookthrough" ops that don't contrib...
SDValue expandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG) const
Expands an unaligned store to 2 half-size stores for integer values, and possibly more for vectors.
bool ShrinkDemandedConstant(SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts, TargetLoweringOpt &TLO) const
Check to see if the specified operand of the specified instruction is a constant integer.
std::pair< SDValue, SDValue > expandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG) const
Expands an unaligned load to 2 half-size loads for an integer, and possibly more for vectors.
virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
std::pair< SDValue, SDValue > scalarizeVectorLoad(LoadSDNode *LD, SelectionDAG &DAG) const
Turn load of vector type into a load of the individual elements.
bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts, KnownBits &Known, TargetLoweringOpt &TLO, unsigned Depth=0, bool AssumeSingleUse=false) const
Look at Op.
TargetLowering(const TargetLowering &)=delete
virtual bool canCreateUndefOrPoisonForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const
Return true if Op can create undef or poison from non-undef & non-poison operands.
Primary interface to the complete machine description for the target machine.
TargetSubtargetInfo - Generic base class for all target subtargets.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
LLVM Value Representation.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ CONSTANT_ADDRESS_32BIT
Address space for 32-bit constant memory.
@ BARRIER
Address space for modeling barrier IDs as addresses.
@ REGION_ADDRESS
Address space for region memory. (GDS)
@ LOCAL_ADDRESS
Address space for local memory.
@ CONSTANT_ADDRESS
Address space for constant memory (VTX2).
@ GLOBAL_ADDRESS
Address space for global memory (RAT0, VTX0).
bool isIntrinsicAlwaysUniform(unsigned IntrID)
TargetExtType * isNamedBarrier(const GlobalVariable &GV)
std::optional< APFloat > evaluateRcp(const APFloat &Val)
Evaluate the constant-folded result of v_rcp for Val, accounting for the hardware's denormal flushing...
bool isUniformMMO(const MachineMemOperand *MMO)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ AMDGPU_CS
Used for Mesa/AMDPAL compute shaders.
@ AMDGPU_VS
Used for Mesa vertex shaders, or AMDPAL last shader stage before rasterization (vertex shader if tess...
@ AMDGPU_KERNEL
Used for AMDGPU code object kernels.
@ AMDGPU_Gfx
Used for AMD graphics targets.
@ AMDGPU_CS_ChainPreserve
Used on AMDGPUs to give the middle-end more control over argument placement.
@ AMDGPU_HS
Used for Mesa/AMDPAL hull shaders (= tessellation control shaders).
@ AMDGPU_GS
Used for Mesa/AMDPAL geometry shaders.
@ AMDGPU_CS_Chain
Used on AMDGPUs to give the middle-end more control over argument placement.
@ AMDGPU_PS
Used for Mesa/AMDPAL pixel shaders.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ SPIR_KERNEL
Used for SPIR kernel functions.
@ Fast
Attempts to make calls as fast as possible (e.g.
@ AMDGPU_ES
Used for AMDPAL shader stage before geometry shader if geometry is in use.
@ AMDGPU_LS
Used for AMDPAL vertex shader if tessellation is in use.
@ C
The default llvm calling convention, compatible with C.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ 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.
@ 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...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ 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 ...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ 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.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ SIGN_EXTEND
Conversion operators.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BRIND
BRIND - Indirect branch.
@ 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.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ CTLS
Count leading redundant sign bits.
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ 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.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Same as FMINNUM/FMAXNUM, except that a signaling NaN operand deterministi...
@ EntryToken
EntryToken - This is the marker used to indicate the start of a region.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ FMINNUM
FMINNUM/FMAXNUM - Same semantics as the llvm.minnum/maxnum intrinsics.
@ 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.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ INLINEASM_BR
INLINEASM_BR - Branching version of inline asm. Used by asm-goto.
@ FMINIMUM
FMINIMUM/FMAXIMUM - Same semantics as the llvm.minimum/maximum intrinsics.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ 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...
@ 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.
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ ADDRSPACECAST
ADDRSPACECAST - This operator converts between pointers of different address spaces.
@ INLINEASM
INLINEASM - Represents an inline asm block.
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ 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.
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - Same semantics as the llvm.minimumnum/maximumnum intrinsics.
@ 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,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
LLVM_ABI CondCode getSetCCInverse(CondCode Operation, EVT Type)
Return the operation corresponding to !(X op Y), where 'op' is a valid SetCC operation.
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 isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
@ Known
Known to have no common set bits.
LLVM_ABI void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, SmallVectorImpl< EVT > &ValueVTs, SmallVectorImpl< EVT > *MemVTs=nullptr, SmallVectorImpl< TypeSize > *Offsets=nullptr, TypeSize StartingOffset=TypeSize::getZero())
ComputeValueVTs - Given an LLVM IR type, compute a sequence of EVTs that represent all the individual...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
SDValue peekFPSignOps(SDValue Val)
Strip fabs/fneg/fcopysign from a value to get the underlying source.
LLVM_ABI ConstantFPSDNode * isConstOrConstSplatFP(SDValue N, bool AllowUndefs=false)
Returns the SDNode if it is a constant splat BuildVector or constant float.
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
To bit_cast(const From &from) noexcept
@ Mul
Product of integers.
@ Fast
Assign the register banks as fast as possible (default).
DWARFExpression::Operation Op
LLVM_ABI ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
UndefPoisonKind
Enumeration to track whether we are interested in Undef, Poison, or both.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
APFloat neg(APFloat X)
Returns the negated value of the argument.
unsigned Log2(Align A)
Returns the log2 of the alignment.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
MCRegisterClass TargetRegisterClass
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
MCRegister getRegister() const
unsigned getStackOffset() const
DenormalModeKind Input
Denormal treatment kind for floating point instruction inputs in the default floating-point environme...
@ PreserveSign
The sign of a flushed-to-zero number is preserved in the sign of 0.
constexpr bool inputsAreZero() const
Return true if input denormals must be implicitly treated as 0.
static constexpr DenormalMode getPreserveSign()
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
EVT getPow2VectorType(LLVMContext &Context) const
Widens the length of the given vector EVT up to the nearest power of 2 and returns that type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
EVT changeTypeToInteger() const
Return the type converted to an equivalently sized integer or vector with integer element type.
bool bitsGT(EVT VT) const
Return true if this has more 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.
bool isPow2VectorType() const
Returns true if the given vector is a power of 2.
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.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
EVT getRoundIntegerType(LLVMContext &Context) const
Rounds the bit-width of the given integer EVT up to the nearest power of two (and at least to eight),...
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.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
EVT changeElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a type whose attributes match ourselves with the exception of the element type that i...
LLVM_ABI 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.
bool isUnknown() const
Returns true if we don't know any bits.
KnownBits trunc(unsigned BitWidth) const
Return known bits for a truncation of the value we're tracking.
KnownBits zext(unsigned BitWidth) const
Return known bits for a zero extension of the value we're tracking.
unsigned countMaxActiveBits() const
Returns the maximum number of bits needed to represent all possible unsigned values with these known ...
KnownBits intersectWith(const KnownBits &RHS) const
Returns KnownBits information that is known to be true for both this and RHS.
KnownBits sext(unsigned BitWidth) const
Return known bits for a sign extension of the value we're tracking.
unsigned countMinLeadingZeros() const
Returns the minimum number of leading zero bits.
bool isNegative() const
Returns true if this value is known to be negative.
static LLVM_ABI KnownBits mul(const KnownBits &LHS, const KnownBits &RHS, bool NoUndefSelfMultiply=false)
Compute known bits resulting from multiplying LHS and RHS.
This class contains a discriminated union of information about pointers in memory operands,...
LLVM_ABI bool isDereferenceable(unsigned Size, LLVMContext &C, const DataLayout &DL) const
Return true if memory region [V, V+Offset+Size) is known to be dereferenceable.
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
These are IR-level optimization flags that may be propagated to SDNodes.
void setAllowContract(bool b)
bool hasNoSignedZeros() const
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
DenormalMode FP32Denormals
If this is set, neither input or output denormals are flushed for most f32 instructions.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
bool isBeforeLegalizeOps() const
CombineLevel getDAGCombineLevel()
LLVM_ABI void AddToWorklist(SDNode *N)
bool isCalledByLegalizer() const
bool isBeforeLegalize() const
LLVM_ABI SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)
LLVM_ABI void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO)
A convenience struct that encapsulates a DAG, and two SDValues for returning information from TargetL...