514 case Builtin::BI__builtin_hlsl_adduint64: {
520 "AddUint64 operand types must match");
522 "AddUint64 operands must have an integer representation");
523 assert((NumElements == 2 || NumElements == 4) &&
524 "AddUint64 operands must have 2 or 4 elements");
532 if (NumElements == 2) {
533 LowA =
Builder.CreateExtractElement(OpA, (uint64_t)0,
"LowA");
534 HighA =
Builder.CreateExtractElement(OpA, (uint64_t)1,
"HighA");
535 LowB =
Builder.CreateExtractElement(OpB, (uint64_t)0,
"LowB");
536 HighB =
Builder.CreateExtractElement(OpB, (uint64_t)1,
"HighB");
538 LowA =
Builder.CreateShuffleVector(OpA, {0, 2},
"LowA");
539 HighA =
Builder.CreateShuffleVector(OpA, {1, 3},
"HighA");
540 LowB =
Builder.CreateShuffleVector(OpB, {0, 2},
"LowB");
541 HighB =
Builder.CreateShuffleVector(OpB, {1, 3},
"HighB");
548 *
this, Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
549 llvm::Value *ZExtCarry =
550 Builder.CreateZExt(Carry, HighA->getType(),
"CarryZExt");
553 llvm::Value *HighSum =
Builder.CreateAdd(HighA, HighB,
"HighSum");
554 llvm::Value *HighSumPlusCarry =
555 Builder.CreateAdd(HighSum, ZExtCarry,
"HighSumPlusCarry");
557 if (NumElements == 4) {
558 return Builder.CreateShuffleVector(LowSum, HighSumPlusCarry, {0, 2, 1, 3},
564 "hlsl.AddUint64.upto0");
569 case Builtin::BI__builtin_hlsl_resource_getpointer:
570 case Builtin::BI__builtin_hlsl_resource_getpointer_typed: {
573 BuiltinID == Builtin::BI__builtin_hlsl_resource_getpointer_typed ||
577 llvm::Function *IntrFn =
nullptr;
578 llvm::CallInst *CI =
nullptr;
581 IntrFn = llvm::Intrinsic::getOrInsertDeclaration(
583 CGM.getHLSLRuntime().getCreateResourceGetPointerIntrinsic(),
584 {RetTy, HandleOp->getType(), IndexOp->getType()});
587 IntrFn = llvm::Intrinsic::getOrInsertDeclaration(
589 CGM.getHLSLRuntime().getCreateResourceGetBasePointerIntrinsic(),
590 {RetTy, HandleOp->getType()});
593 CI->setCallingConv(IntrFn->getCallingConv());
596 case Builtin::BI__builtin_hlsl_resource_sample: {
602 Args.push_back(HandleOp);
603 Args.push_back(SamplerOp);
604 Args.push_back(CoordOp);
610 return Builder.CreateIntrinsic(
611 RetTy,
CGM.getHLSLRuntime().getSampleIntrinsic(), Args);
615 return Builder.CreateIntrinsic(
616 RetTy,
CGM.getHLSLRuntime().getSampleClampIntrinsic(), Args);
618 case Builtin::BI__builtin_hlsl_resource_sample_bias: {
627 Args.push_back(HandleOp);
628 Args.push_back(SamplerOp);
629 Args.push_back(CoordOp);
630 Args.push_back(BiasOp);
636 return Builder.CreateIntrinsic(
637 RetTy,
CGM.getHLSLRuntime().getSampleBiasIntrinsic(), Args);
640 return Builder.CreateIntrinsic(
641 RetTy,
CGM.getHLSLRuntime().getSampleBiasClampIntrinsic(), Args);
643 case Builtin::BI__builtin_hlsl_resource_sample_grad: {
651 Args.push_back(HandleOp);
652 Args.push_back(SamplerOp);
653 Args.push_back(CoordOp);
654 Args.push_back(DDXOp);
655 Args.push_back(DDYOp);
662 return Builder.CreateIntrinsic(
663 RetTy,
CGM.getHLSLRuntime().getSampleGradIntrinsic(), Args);
667 return Builder.CreateIntrinsic(
668 RetTy,
CGM.getHLSLRuntime().getSampleGradClampIntrinsic(), Args);
670 case Builtin::BI__builtin_hlsl_resource_sample_level: {
679 Args.push_back(HandleOp);
680 Args.push_back(SamplerOp);
681 Args.push_back(CoordOp);
682 Args.push_back(LODOp);
687 return Builder.CreateIntrinsic(
688 RetTy,
CGM.getHLSLRuntime().getSampleLevelIntrinsic(), Args);
690 case Builtin::BI__builtin_hlsl_resource_load_level: {
695 unsigned NumElts = CoordLODVecTy->getNumElements();
696 assert(NumElts >= 2 &&
"CoordLOD must have at least 2 elements");
700 for (
unsigned I = 0; I < NumElts - 1; ++I)
704 Builder.CreateShuffleVector(CoordLODOp, Mask,
"hlsl.load.coord");
706 Builder.CreateExtractElement(CoordLODOp, NumElts - 1,
"hlsl.load.lod");
709 Args.push_back(HandleOp);
710 Args.push_back(CoordOp);
711 Args.push_back(LODOp);
716 return Builder.CreateIntrinsic(
717 RetTy,
CGM.getHLSLRuntime().getLoadLevelIntrinsic(), Args);
719 case Builtin::BI__builtin_hlsl_resource_sample_cmp: {
728 Args.push_back(HandleOp);
729 Args.push_back(SamplerOp);
730 Args.push_back(CoordOp);
731 Args.push_back(CmpOp);
737 return Builder.CreateIntrinsic(
738 RetTy,
CGM.getHLSLRuntime().getSampleCmpIntrinsic(), Args);
742 return Builder.CreateIntrinsic(
743 RetTy,
CGM.getHLSLRuntime().getSampleCmpClampIntrinsic(), Args);
745 case Builtin::BI__builtin_hlsl_resource_sample_cmp_level_zero: {
754 Args.push_back(HandleOp);
755 Args.push_back(SamplerOp);
756 Args.push_back(CoordOp);
757 Args.push_back(CmpOp);
763 return Builder.CreateIntrinsic(
764 RetTy,
CGM.getHLSLRuntime().getSampleCmpLevelZeroIntrinsic(), Args);
766 case Builtin::BI__builtin_hlsl_resource_calculate_lod: {
771 return Builder.CreateIntrinsic(
773 CGM.getHLSLRuntime().getCalculateLodIntrinsic(),
774 {HandleOp, SamplerOp, CoordOp});
776 case Builtin::BI__builtin_hlsl_resource_calculate_lod_unclamped: {
781 return Builder.CreateIntrinsic(
783 CGM.getHLSLRuntime().getCalculateLodUnclampedIntrinsic(),
784 {HandleOp, SamplerOp, CoordOp});
786 case Builtin::BI__builtin_hlsl_resource_gather: {
792 ComponentOp =
Builder.CreateIntCast(ComponentOp,
Builder.getInt32Ty(),
796 Args.push_back(HandleOp);
797 Args.push_back(SamplerOp);
798 Args.push_back(CoordOp);
799 Args.push_back(ComponentOp);
804 return Builder.CreateIntrinsic(
805 RetTy,
CGM.getHLSLRuntime().getGatherIntrinsic(), Args);
807 case Builtin::BI__builtin_hlsl_resource_gather_cmp: {
813 CompareOp =
Builder.CreateFPCast(CompareOp,
Builder.getFloatTy());
816 Args.push_back(HandleOp);
817 Args.push_back(SamplerOp);
818 Args.push_back(CoordOp);
819 Args.push_back(CompareOp);
821 if (
CGM.getTarget().getTriple().isDXIL()) {
824 ComponentOp =
Builder.CreateIntCast(ComponentOp,
Builder.getInt32Ty(),
826 Args.push_back(ComponentOp);
833 return Builder.CreateIntrinsic(
834 RetTy,
CGM.getHLSLRuntime().getGatherCmpIntrinsic(), Args);
836 case Builtin::BI__builtin_hlsl_resource_load_with_status:
837 case Builtin::BI__builtin_hlsl_resource_load_with_status_typed: {
846 const HLSLAttributedResourceType *RT =
847 HandleTy->
getAs<HLSLAttributedResourceType>();
848 assert(
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil &&
849 "Only DXIL currently implements load with status");
851 Intrinsic::ID IntrID = RT->getAttrs().RawBuffer
852 ? llvm::Intrinsic::dx_resource_load_rawbuffer
853 : llvm::Intrinsic::dx_resource_load_typedbuffer;
856 llvm::Type *RetTy = llvm::StructType::get(
Builder.getContext(),
857 {DataTy, Builder.getInt1Ty()});
860 Args.push_back(HandleOp);
861 Args.push_back(IndexOp);
866 if (!RT->isStructured())
867 Offset = llvm::PoisonValue::get(
Builder.getInt32Ty());
868 Args.push_back(Offset);
874 Builder.CreateIntrinsic(RetTy, IntrID, Args, {},
"ld.struct");
875 Value *LoadedValue =
Builder.CreateExtractValue(ResRet, {0},
"ld.value");
876 Value *StatusBit =
Builder.CreateExtractValue(ResRet, {1},
"ld.status");
877 Value *ExtendedStatus =
878 Builder.CreateZExt(StatusBit,
Builder.getInt32Ty(),
"ld.status.ext");
879 Builder.CreateStore(ExtendedStatus, StatusAddr);
883 case Builtin::BI__builtin_hlsl_resource_uninitializedhandle: {
884 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
885 return llvm::PoisonValue::get(HandleTy);
887 case Builtin::BI__builtin_hlsl_resource_handlefrombinding: {
888 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
894 llvm::Intrinsic::ID IntrinsicID =
895 CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic();
897 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
899 case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: {
900 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
906 llvm::Intrinsic::ID IntrinsicID =
907 CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
909 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
911 case Builtin::BI__builtin_hlsl_resource_counterhandlefromimplicitbinding: {
913 if (!
CGM.getTriple().isSPIRV())
916 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
919 llvm::Intrinsic::ID IntrinsicID =
920 llvm::Intrinsic::spv_resource_counterhandlefromimplicitbinding;
922 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
924 case Builtin::BI__builtin_hlsl_resource_nonuniformindex: {
927 return Builder.CreateIntrinsic(
928 RetTy,
CGM.getHLSLRuntime().getNonUniformResourceIndexIntrinsic(),
931 case Builtin::BI__builtin_hlsl_resource_getdimensions_x:
932 case Builtin::BI__builtin_hlsl_resource_getdimensions_x_float:
934 CGM.getHLSLRuntime().getGetDimensionsXIntrinsic(),
936 case Builtin::BI__builtin_hlsl_resource_getdimensions_xy:
937 case Builtin::BI__builtin_hlsl_resource_getdimensions_xy_float:
939 CGM.getHLSLRuntime().getGetDimensionsXYIntrinsic(),
941 case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy:
942 case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy_float:
944 *
this, E,
CGM.getHLSLRuntime().getGetDimensionsLevelsXYIntrinsic(), 3,
946 case Builtin::BI__builtin_hlsl_resource_getstride: {
950 case Builtin::BI__builtin_hlsl_all: {
952 return Builder.CreateIntrinsic(
957 case Builtin::BI__builtin_hlsl_and: {
960 return Builder.CreateAnd(Op0, Op1,
"hlsl.and");
962 case Builtin::BI__builtin_hlsl_or: {
965 return Builder.CreateOr(Op0, Op1,
"hlsl.or");
967 case Builtin::BI__builtin_hlsl_any: {
969 return Builder.CreateIntrinsic(
974 case Builtin::BI__builtin_hlsl_asdouble:
976 case Builtin::BI__builtin_hlsl_elementwise_clamp: {
983 Ty = VecTy->getElementType();
987 Intr =
CGM.getHLSLRuntime().getNClampIntrinsic();
989 Intr =
CGM.getHLSLRuntime().getUClampIntrinsic();
992 Intr =
CGM.getHLSLRuntime().getSClampIntrinsic();
994 return Builder.CreateIntrinsic(
998 case Builtin::BI__builtin_hlsl_crossf16:
999 case Builtin::BI__builtin_hlsl_crossf32: {
1004 "cross operands must have a float representation");
1009 "input vectors must have 3 elements each");
1010 return Builder.CreateIntrinsic(
1011 Op0->
getType(),
CGM.getHLSLRuntime().getCrossIntrinsic(),
1014 case Builtin::BI__builtin_hlsl_dot: {
1017 llvm::Type *T0 = Op0->
getType();
1018 llvm::Type *T1 = Op1->
getType();
1021 if (!T0->isVectorTy() && !T1->isVectorTy()) {
1022 if (T0->isFloatingPointTy())
1023 return Builder.CreateFMul(Op0, Op1,
"hlsl.dot");
1025 if (T0->isIntegerTy())
1026 return Builder.CreateMul(Op0, Op1,
"hlsl.dot");
1029 "Scalar dot product is only supported on ints and floats.");
1034 "Dot product operands must have the same type.");
1037 assert(VecTy0 &&
"Dot product argument must be a vector.");
1039 return Builder.CreateIntrinsic(
1040 T0->getScalarType(),
1044 case Builtin::BI__builtin_hlsl_dot4add_i8packed: {
1049 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddI8PackedIntrinsic();
1052 return Builder.CreateIntrinsic(
1054 nullptr,
"hlsl.dot4add.i8packed");
1056 case Builtin::BI__builtin_hlsl_dot4add_u8packed: {
1061 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddU8PackedIntrinsic();
1064 return Builder.CreateIntrinsic(
1066 nullptr,
"hlsl.dot4add.u8packed");
1068 case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
1071 return Builder.CreateIntrinsic(
1076 case Builtin::BI__builtin_hlsl_elementwise_firstbitlow: {
1079 return Builder.CreateIntrinsic(
1082 nullptr,
"hlsl.firstbitlow");
1084 case Builtin::BI__builtin_hlsl_lerp: {
1089 llvm_unreachable(
"lerp operand must have a float representation");
1090 return Builder.CreateIntrinsic(
1091 X->getType(),
CGM.getHLSLRuntime().getLerpIntrinsic(),
1094 case Builtin::BI__builtin_hlsl_normalize: {
1098 "normalize operand must have a float representation");
1100 return Builder.CreateIntrinsic(
1103 nullptr,
"hlsl.normalize");
1105 case Builtin::BI__builtin_hlsl_elementwise_degrees: {
1109 "degree operand must have a float representation");
1111 return Builder.CreateIntrinsic(
1112 X->getType(),
CGM.getHLSLRuntime().getDegreesIntrinsic(),
1115 case Builtin::BI__builtin_hlsl_elementwise_f16tof32: {
1118 case Builtin::BI__builtin_hlsl_elementwise_f32tof16: {
1121 case Builtin::BI__builtin_hlsl_elementwise_frac: {
1124 llvm_unreachable(
"frac operand must have a float representation");
1125 return Builder.CreateIntrinsic(
1126 Op0->
getType(),
CGM.getHLSLRuntime().getFracIntrinsic(),
1129 case Builtin::BI__builtin_hlsl_elementwise_isinf: {
1131 llvm::Type *Xty = Op0->
getType();
1132 llvm::Type *retType = llvm::Type::getInt1Ty(this->
getLLVMContext());
1133 if (Xty->isVectorTy()) {
1135 retType = llvm::VectorType::get(
1136 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1139 llvm_unreachable(
"isinf operand must have a float representation");
1140 return Builder.CreateIntrinsic(
1141 retType,
CGM.getHLSLRuntime().getIsInfIntrinsic(),
1144 case Builtin::BI__builtin_hlsl_elementwise_isnan: {
1146 llvm::Type *Xty = Op0->
getType();
1147 llvm::Type *retType = llvm::Type::getInt1Ty(this->
getLLVMContext());
1148 if (Xty->isVectorTy()) {
1150 retType = llvm::VectorType::get(
1151 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1154 llvm_unreachable(
"isnan operand must have a float representation");
1155 return Builder.CreateIntrinsic(
1156 retType,
CGM.getHLSLRuntime().getIsNaNIntrinsic(),
1159 case Builtin::BI__builtin_hlsl_mad: {
1164 return Builder.CreateIntrinsic(
1165 M->
getType(), Intrinsic::fmuladd,
1169 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1170 return Builder.CreateIntrinsic(
1171 M->
getType(), Intrinsic::dx_imad,
1175 return Builder.CreateNSWAdd(Mul, B);
1178 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1179 return Builder.CreateIntrinsic(
1180 M->
getType(), Intrinsic::dx_umad,
1184 return Builder.CreateNUWAdd(Mul, B);
1186 case Builtin::BI__builtin_hlsl_mul: {
1200 bool IsRowMajor =
getLangOpts().getDefaultMatrixMemoryLayout() ==
1203 llvm::MatrixBuilder MB(
Builder);
1204 if (IsVec0 && IsMat1) {
1208 unsigned Cols = MatTy->getNumColumns();
1209 assert(N == Rows &&
"vector length must match matrix row count");
1211 Op1 = MB.CreateRowMajorToColumnMajorTransform(Op1, Rows, Cols);
1212 return MB.CreateMatrixMultiply(Op0, Op1, 1, N, Cols,
"hlsl.mul");
1214 if (IsMat0 && IsVec1) {
1217 unsigned Cols = MatTy->getNumColumns();
1219 "vector length must match matrix column count");
1221 Op0 = MB.CreateRowMajorToColumnMajorTransform(Op0, Rows, Cols);
1222 return MB.CreateMatrixMultiply(Op0, Op1, Rows, Cols, 1,
"hlsl.mul");
1224 assert(IsMat0 && IsMat1);
1229 unsigned Cols0 = MatTy0->getNumColumns();
1231 assert(Cols0 == Rows1 &&
1232 "inner matrix dimensions must match for multiplication");
1234 Op0 = MB.CreateRowMajorToColumnMajorTransform(Op0, Rows0, Cols0);
1235 Op1 = MB.CreateRowMajorToColumnMajorTransform(Op1, Rows1, Cols1);
1238 MB.CreateMatrixMultiply(Op0, Op1, Rows0, Cols0, Cols1,
"hlsl.mul");
1240 Result = MB.CreateColumnMajorToRowMajorTransform(
Result, Rows0, Cols1);
1243 case Builtin::BI__builtin_hlsl_transpose: {
1247 unsigned Cols = MatTy->getNumColumns();
1248 llvm::MatrixBuilder MB(
Builder);
1253 bool IsRowMajor =
getLangOpts().getDefaultMatrixMemoryLayout() ==
1256 return MB.CreateMatrixTranspose(Op0, Cols, Rows);
1257 return MB.CreateMatrixTranspose(Op0, Rows, Cols);
1259 case Builtin::BI__builtin_hlsl_elementwise_rcp: {
1262 llvm_unreachable(
"rcp operand must have a float representation");
1263 llvm::Type *Ty = Op0->
getType();
1264 llvm::Type *EltTy = Ty->getScalarType();
1266 ? ConstantVector::getSplat(
1267 ElementCount::getFixed(
1269 ConstantFP::get(EltTy, 1.0))
1270 : ConstantFP::get(EltTy, 1.0);
1271 return Builder.CreateFDiv(One, Op0,
"hlsl.rcp");
1273 case Builtin::BI__builtin_hlsl_elementwise_rsqrt: {
1276 llvm_unreachable(
"rsqrt operand must have a float representation");
1277 return Builder.CreateIntrinsic(
1278 Op0->
getType(),
CGM.getHLSLRuntime().getRsqrtIntrinsic(),
1281 case Builtin::BI__builtin_hlsl_elementwise_saturate: {
1284 "saturate operand must have a float representation");
1285 return Builder.CreateIntrinsic(
1288 nullptr,
"hlsl.saturate");
1290 case Builtin::BI__builtin_hlsl_wave_prefix_count_bits: {
1292 assert(Op->
getType()->isIntegerTy(1) &&
1293 "WavePrefixBitCount operand must be a boolean type");
1300 case Builtin::BI__builtin_hlsl_select: {
1313 if (!OpTrue->
getType()->isVectorTy())
1315 Builder.CreateVectorSplat(VTy->getNumElements(), OpTrue,
"splat");
1316 if (!OpFalse->
getType()->isVectorTy())
1318 Builder.CreateVectorSplat(VTy->getNumElements(), OpFalse,
"splat");
1322 Builder.CreateSelect(OpCond, OpTrue, OpFalse,
"hlsl.select");
1329 case Builtin::BI__builtin_hlsl_step: {
1334 "step operands must have a float representation");
1335 return Builder.CreateIntrinsic(
1336 Op0->
getType(),
CGM.getHLSLRuntime().getStepIntrinsic(),
1339 case Builtin::BI__builtin_hlsl_wave_active_all_equal: {
1342 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllEqualIntrinsic();
1345 case Builtin::BI__builtin_hlsl_wave_active_all_true: {
1347 assert(Op->
getType()->isIntegerTy(1) &&
1348 "Intrinsic WaveActiveAllTrue operand must be a bool");
1350 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllTrueIntrinsic();
1353 case Builtin::BI__builtin_hlsl_wave_active_any_true: {
1355 assert(Op->
getType()->isIntegerTy(1) &&
1356 "Intrinsic WaveActiveAnyTrue operand must be a bool");
1358 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic();
1361 case Builtin::BI__builtin_hlsl_wave_active_bit_or: {
1364 "Intrinsic WaveActiveBitOr operand must have an unsigned integer "
1367 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitOrIntrinsic();
1369 "hlsl.wave.active.bit.or");
1371 case Builtin::BI__builtin_hlsl_wave_active_bit_xor: {
1374 "Intrinsic WaveActiveBitXor operand must have an unsigned integer "
1377 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitXorIntrinsic();
1379 "hlsl.wave.active.bit.xor");
1381 case Builtin::BI__builtin_hlsl_wave_active_bit_and: {
1384 "Intrinsic WaveActiveBitAnd operand must have an unsigned integer "
1387 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitAndIntrinsic();
1389 "hlsl.wave.active.bit.and");
1391 case Builtin::BI__builtin_hlsl_wave_active_ballot: {
1393 assert(Op->
getType()->isIntegerTy(1) &&
1394 "Intrinsic WaveActiveBallot operand must be a bool");
1398 case Builtin::BI__builtin_hlsl_wave_active_count_bits: {
1400 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveCountBitsIntrinsic();
1403 case Builtin::BI__builtin_hlsl_wave_active_sum: {
1410 "hlsl.wave.active.sum");
1412 case Builtin::BI__builtin_hlsl_wave_active_product: {
1419 "hlsl.wave.active.product");
1421 case Builtin::BI__builtin_hlsl_wave_active_max: {
1427 IID =
CGM.getHLSLRuntime().getWaveActiveUMaxIntrinsic();
1429 IID =
CGM.getHLSLRuntime().getWaveActiveMaxIntrinsic();
1432 "hlsl.wave.active.max");
1434 case Builtin::BI__builtin_hlsl_wave_active_min: {
1440 IID =
CGM.getHLSLRuntime().getWaveActiveUMinIntrinsic();
1442 IID =
CGM.getHLSLRuntime().getWaveActiveMinIntrinsic();
1445 "hlsl.wave.active.min");
1447 case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
1451 switch (
CGM.getTarget().getTriple().getArch()) {
1452 case llvm::Triple::dxil:
1454 case llvm::Triple::spirv:
1456 llvm::FunctionType::get(
IntTy, {},
false),
1457 "__hlsl_wave_get_lane_index", {},
false,
true));
1460 "Intrinsic WaveGetLaneIndex not supported by target architecture");
1463 case Builtin::BI__builtin_hlsl_wave_is_first_lane: {
1464 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveIsFirstLaneIntrinsic();
1467 case Builtin::BI__builtin_hlsl_wave_get_lane_count: {
1468 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveGetLaneCountIntrinsic();
1471 case Builtin::BI__builtin_hlsl_wave_read_lane_at: {
1477 {OpExpr->getType()},
ArrayRef{OpExpr, OpIndex},
1478 "hlsl.wave.readlane");
1480 case Builtin::BI__builtin_hlsl_wave_prefix_sum: {
1485 "hlsl.wave.prefix.sum");
1487 case Builtin::BI__builtin_hlsl_wave_prefix_product: {
1492 "hlsl.wave.prefix.product");
1494 case Builtin::BI__builtin_hlsl_quad_read_across_x: {
1496 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossXIntrinsic();
1498 "hlsl.quad.read.across.x");
1500 case Builtin::BI__builtin_hlsl_quad_read_across_y: {
1502 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossYIntrinsic();
1504 "hlsl.quad.read.across.y");
1506 case Builtin::BI__builtin_hlsl_elementwise_sign: {
1507 auto *Arg0 = E->
getArg(0);
1509 llvm::Type *Xty = Op0->
getType();
1510 llvm::Type *retType = llvm::Type::getInt32Ty(this->
getLLVMContext());
1511 if (Xty->isVectorTy()) {
1512 auto *XVecTy = Arg0->getType()->castAs<
VectorType>();
1513 retType = llvm::VectorType::get(
1514 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1516 assert((Arg0->getType()->hasFloatingRepresentation() ||
1517 Arg0->getType()->hasIntegerRepresentation()) &&
1518 "sign operand must have a float or int representation");
1520 if (Arg0->getType()->hasUnsignedIntegerRepresentation()) {
1522 return Builder.CreateSelect(
Cmp, ConstantInt::get(retType, 0),
1523 ConstantInt::get(retType, 1),
"hlsl.sign");
1526 return Builder.CreateIntrinsic(
1527 retType,
CGM.getHLSLRuntime().getSignIntrinsic(),
1530 case Builtin::BI__builtin_hlsl_elementwise_radians: {
1533 "radians operand must have a float representation");
1534 return Builder.CreateIntrinsic(
1537 nullptr,
"hlsl.radians");
1539 case Builtin::BI__builtin_hlsl_buffer_update_counter: {
1543 return Builder.CreateIntrinsic(
1545 CGM.getHLSLRuntime().getBufferUpdateCounterIntrinsic(),
1548 case Builtin::BI__builtin_hlsl_elementwise_splitdouble: {
1553 "asuint operands types mismatch");
1556 case Builtin::BI__builtin_hlsl_elementwise_clip:
1558 "clip operands types mismatch");
1560 case Builtin::BI__builtin_hlsl_all_memory_barrier: {
1561 Intrinsic::ID ID =
CGM.getHLSLRuntime().getAllMemoryBarrierIntrinsic();
1564 case Builtin::BI__builtin_hlsl_all_memory_barrier_with_group_sync: {
1566 CGM.getHLSLRuntime().getAllMemoryBarrierWithGroupSyncIntrinsic();
1569 case Builtin::BI__builtin_hlsl_device_memory_barrier: {
1570 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDeviceMemoryBarrierIntrinsic();
1573 case Builtin::BI__builtin_hlsl_device_memory_barrier_with_group_sync: {
1575 CGM.getHLSLRuntime().getDeviceMemoryBarrierWithGroupSyncIntrinsic();
1578 case Builtin::BI__builtin_hlsl_group_memory_barrier: {
1579 Intrinsic::ID ID =
CGM.getHLSLRuntime().getGroupMemoryBarrierIntrinsic();
1582 case Builtin::BI__builtin_hlsl_group_memory_barrier_with_group_sync: {
1584 CGM.getHLSLRuntime().getGroupMemoryBarrierWithGroupSyncIntrinsic();
1587 case Builtin::BI__builtin_hlsl_elementwise_ddx_coarse: {
1590 llvm_unreachable(
"ddx_coarse operand must have a float representation");
1591 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxCoarseIntrinsic();
1596 case Builtin::BI__builtin_hlsl_elementwise_ddy_coarse: {
1599 llvm_unreachable(
"ddy_coarse operand must have a float representation");
1600 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyCoarseIntrinsic();
1605 case Builtin::BI__builtin_hlsl_elementwise_ddx_fine: {
1608 llvm_unreachable(
"ddx_fine operand must have a float representation");
1609 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxFineIntrinsic();
1614 case Builtin::BI__builtin_hlsl_elementwise_ddy_fine: {
1617 llvm_unreachable(
"ddy_fine operand must have a float representation");
1618 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyFineIntrinsic();
1623 case Builtin::BI__builtin_get_spirv_spec_constant_bool:
1624 case Builtin::BI__builtin_get_spirv_spec_constant_short:
1625 case Builtin::BI__builtin_get_spirv_spec_constant_ushort:
1626 case Builtin::BI__builtin_get_spirv_spec_constant_int:
1627 case Builtin::BI__builtin_get_spirv_spec_constant_uint:
1628 case Builtin::BI__builtin_get_spirv_spec_constant_longlong:
1629 case Builtin::BI__builtin_get_spirv_spec_constant_ulonglong:
1630 case Builtin::BI__builtin_get_spirv_spec_constant_half:
1631 case Builtin::BI__builtin_get_spirv_spec_constant_float:
1632 case Builtin::BI__builtin_get_spirv_spec_constant_double: {
1636 llvm::Value *Args[] = {SpecId, DefaultVal};
1637 return Builder.CreateCall(SpecConstantFn, Args);