568 case Builtin::BI__builtin_hlsl_adduint64: {
574 "AddUint64 operand types must match");
576 "AddUint64 operands must have an integer representation");
577 assert((NumElements == 2 || NumElements == 4) &&
578 "AddUint64 operands must have 2 or 4 elements");
586 if (NumElements == 2) {
587 LowA =
Builder.CreateExtractElement(OpA, (uint64_t)0,
"LowA");
588 HighA =
Builder.CreateExtractElement(OpA, (uint64_t)1,
"HighA");
589 LowB =
Builder.CreateExtractElement(OpB, (uint64_t)0,
"LowB");
590 HighB =
Builder.CreateExtractElement(OpB, (uint64_t)1,
"HighB");
592 LowA =
Builder.CreateShuffleVector(OpA, {0, 2},
"LowA");
593 HighA =
Builder.CreateShuffleVector(OpA, {1, 3},
"HighA");
594 LowB =
Builder.CreateShuffleVector(OpB, {0, 2},
"LowB");
595 HighB =
Builder.CreateShuffleVector(OpB, {1, 3},
"HighB");
602 *
this, Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
603 llvm::Value *ZExtCarry =
604 Builder.CreateZExt(Carry, HighA->getType(),
"CarryZExt");
607 llvm::Value *HighSum =
Builder.CreateAdd(HighA, HighB,
"HighSum");
608 llvm::Value *HighSumPlusCarry =
609 Builder.CreateAdd(HighSum, ZExtCarry,
"HighSumPlusCarry");
611 if (NumElements == 4) {
612 return Builder.CreateShuffleVector(LowSum, HighSumPlusCarry, {0, 2, 1, 3},
618 "hlsl.AddUint64.upto0");
623 case Builtin::BI__builtin_hlsl_resource_getpointer:
624 case Builtin::BI__builtin_hlsl_resource_getpointer_typed: {
627 BuiltinID == Builtin::BI__builtin_hlsl_resource_getpointer_typed ||
631 llvm::Function *IntrFn =
nullptr;
632 llvm::CallInst *CI =
nullptr;
635 IntrFn = llvm::Intrinsic::getOrInsertDeclaration(
637 CGM.getHLSLRuntime().getCreateResourceGetPointerIntrinsic(),
638 {RetTy, HandleOp->getType(), IndexOp->getType()});
641 IntrFn = llvm::Intrinsic::getOrInsertDeclaration(
643 CGM.getHLSLRuntime().getCreateResourceGetBasePointerIntrinsic(),
644 {RetTy, HandleOp->getType()});
647 CI->setCallingConv(IntrFn->getCallingConv());
650 case Builtin::BI__builtin_hlsl_resource_sample: {
657 Args.push_back(HandleOp);
658 Args.push_back(SamplerOp);
659 Args.push_back(CoordOp);
664 return Builder.CreateIntrinsic(
665 RetTy,
CGM.getHLSLRuntime().getSampleIntrinsic(), Args);
669 return Builder.CreateIntrinsic(
670 RetTy,
CGM.getHLSLRuntime().getSampleClampIntrinsic(), Args);
672 case Builtin::BI__builtin_hlsl_resource_sample_bias: {
682 Args.push_back(HandleOp);
683 Args.push_back(SamplerOp);
684 Args.push_back(CoordOp);
685 Args.push_back(BiasOp);
690 return Builder.CreateIntrinsic(
691 RetTy,
CGM.getHLSLRuntime().getSampleBiasIntrinsic(), Args);
694 return Builder.CreateIntrinsic(
695 RetTy,
CGM.getHLSLRuntime().getSampleBiasClampIntrinsic(), Args);
697 case Builtin::BI__builtin_hlsl_resource_sample_grad: {
706 Args.push_back(HandleOp);
707 Args.push_back(SamplerOp);
708 Args.push_back(CoordOp);
709 Args.push_back(DDXOp);
710 Args.push_back(DDYOp);
716 return Builder.CreateIntrinsic(
717 RetTy,
CGM.getHLSLRuntime().getSampleGradIntrinsic(), Args);
721 return Builder.CreateIntrinsic(
722 RetTy,
CGM.getHLSLRuntime().getSampleGradClampIntrinsic(), Args);
724 case Builtin::BI__builtin_hlsl_resource_sample_level: {
734 Args.push_back(HandleOp);
735 Args.push_back(SamplerOp);
736 Args.push_back(CoordOp);
737 Args.push_back(LODOp);
741 return Builder.CreateIntrinsic(
742 RetTy,
CGM.getHLSLRuntime().getSampleLevelIntrinsic(), Args);
744 case Builtin::BI__builtin_hlsl_resource_load_level: {
749 unsigned NumElts = CoordLODVecTy->getNumElements();
750 assert(NumElts >= 2 &&
"CoordLOD must have at least 2 elements");
754 for (
unsigned I = 0; I < NumElts - 1; ++I)
758 Builder.CreateShuffleVector(CoordLODOp, Mask,
"hlsl.load.coord");
760 Builder.CreateExtractElement(CoordLODOp, NumElts - 1,
"hlsl.load.lod");
764 Args.push_back(HandleOp);
765 Args.push_back(CoordOp);
766 Args.push_back(LODOp);
770 return Builder.CreateIntrinsic(
771 RetTy,
CGM.getHLSLRuntime().getLoadLevelIntrinsic(), Args);
773 case Builtin::BI__builtin_hlsl_resource_sample_cmp: {
783 Args.push_back(HandleOp);
784 Args.push_back(SamplerOp);
785 Args.push_back(CoordOp);
786 Args.push_back(CmpOp);
791 return Builder.CreateIntrinsic(
792 RetTy,
CGM.getHLSLRuntime().getSampleCmpIntrinsic(), Args);
796 return Builder.CreateIntrinsic(
797 RetTy,
CGM.getHLSLRuntime().getSampleCmpClampIntrinsic(), Args);
799 case Builtin::BI__builtin_hlsl_resource_sample_cmp_level_zero: {
809 Args.push_back(HandleOp);
810 Args.push_back(SamplerOp);
811 Args.push_back(CoordOp);
812 Args.push_back(CmpOp);
816 return Builder.CreateIntrinsic(
817 RetTy,
CGM.getHLSLRuntime().getSampleCmpLevelZeroIntrinsic(), Args);
819 case Builtin::BI__builtin_hlsl_resource_calculate_lod: {
824 return Builder.CreateIntrinsic(
826 CGM.getHLSLRuntime().getCalculateLodIntrinsic(),
827 {HandleOp, SamplerOp, CoordOp});
829 case Builtin::BI__builtin_hlsl_resource_calculate_lod_unclamped: {
834 return Builder.CreateIntrinsic(
836 CGM.getHLSLRuntime().getCalculateLodUnclampedIntrinsic(),
837 {HandleOp, SamplerOp, CoordOp});
839 case Builtin::BI__builtin_hlsl_resource_gather: {
845 ComponentOp =
Builder.CreateIntCast(ComponentOp,
Builder.getInt32Ty(),
850 Args.push_back(HandleOp);
851 Args.push_back(SamplerOp);
852 Args.push_back(CoordOp);
853 Args.push_back(ComponentOp);
857 return Builder.CreateIntrinsic(
858 RetTy,
CGM.getHLSLRuntime().getGatherIntrinsic(), Args);
860 case Builtin::BI__builtin_hlsl_resource_gather_cmp: {
866 CompareOp =
Builder.CreateFPCast(CompareOp,
Builder.getFloatTy());
869 Args.push_back(HandleOp);
870 Args.push_back(SamplerOp);
871 Args.push_back(CoordOp);
872 Args.push_back(CompareOp);
874 if (
CGM.getTarget().getTriple().isDXIL()) {
877 ComponentOp =
Builder.CreateIntCast(ComponentOp,
Builder.getInt32Ty(),
879 Args.push_back(ComponentOp);
886 return Builder.CreateIntrinsic(
887 RetTy,
CGM.getHLSLRuntime().getGatherCmpIntrinsic(), Args);
889 case Builtin::BI__builtin_hlsl_resource_load_with_status:
890 case Builtin::BI__builtin_hlsl_resource_load_with_status_typed: {
899 const HLSLAttributedResourceType *RT =
900 HandleTy->
getAs<HLSLAttributedResourceType>();
901 assert(
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil &&
902 "Only DXIL currently implements load with status");
904 Intrinsic::ID IntrID = RT->getAttrs().RawBuffer
905 ? llvm::Intrinsic::dx_resource_load_rawbuffer
906 : llvm::Intrinsic::dx_resource_load_typedbuffer;
909 llvm::Type *RetTy = llvm::StructType::get(
Builder.getContext(),
910 {DataTy, Builder.getInt1Ty()});
913 Args.push_back(HandleOp);
914 Args.push_back(IndexOp);
919 if (!RT->isStructured())
920 Offset = llvm::PoisonValue::get(
Builder.getInt32Ty());
921 Args.push_back(Offset);
927 Builder.CreateIntrinsic(RetTy, IntrID, Args, {},
"ld.struct");
928 Value *LoadedValue =
Builder.CreateExtractValue(ResRet, {0},
"ld.value");
929 Value *StatusBit =
Builder.CreateExtractValue(ResRet, {1},
"ld.status");
930 Value *ExtendedStatus =
931 Builder.CreateZExt(StatusBit,
Builder.getInt32Ty(),
"ld.status.ext");
932 Builder.CreateStore(ExtendedStatus, StatusAddr);
936 case Builtin::BI__builtin_hlsl_resource_uninitializedhandle: {
937 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
938 return llvm::PoisonValue::get(HandleTy);
940 case Builtin::BI__builtin_hlsl_resource_handlefrombinding: {
941 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
947 llvm::Intrinsic::ID IntrinsicID =
948 CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic();
950 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
952 case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: {
953 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
959 llvm::Intrinsic::ID IntrinsicID =
960 CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
962 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
964 case Builtin::BI__builtin_hlsl_resource_counterhandlefromimplicitbinding: {
966 if (!
CGM.getTriple().isSPIRV())
969 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
972 llvm::Intrinsic::ID IntrinsicID =
973 llvm::Intrinsic::spv_resource_counterhandlefromimplicitbinding;
978 case Builtin::BI__builtin_hlsl_resource_nonuniformindex: {
981 return Builder.CreateIntrinsic(
982 RetTy,
CGM.getHLSLRuntime().getNonUniformResourceIndexIntrinsic(),
985 case Builtin::BI__builtin_hlsl_resource_getdimensions_x:
986 case Builtin::BI__builtin_hlsl_resource_getdimensions_x_float:
988 CGM.getHLSLRuntime().getGetDimensionsXIntrinsic(),
990 case Builtin::BI__builtin_hlsl_resource_getdimensions_xy:
991 case Builtin::BI__builtin_hlsl_resource_getdimensions_xy_float:
993 CGM.getHLSLRuntime().getGetDimensionsXYIntrinsic(),
995 case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy:
996 case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy_float:
998 *
this, E,
CGM.getHLSLRuntime().getGetDimensionsLevelsXYIntrinsic(), 3,
1000 case Builtin::BI__builtin_hlsl_resource_getstride: {
1004 case Builtin::BI__builtin_hlsl_all: {
1006 return Builder.CreateIntrinsic(
1011 case Builtin::BI__builtin_hlsl_and: {
1014 return Builder.CreateAnd(Op0, Op1,
"hlsl.and");
1016 case Builtin::BI__builtin_hlsl_or: {
1019 return Builder.CreateOr(Op0, Op1,
"hlsl.or");
1021 case Builtin::BI__builtin_hlsl_any: {
1023 return Builder.CreateIntrinsic(
1028 case Builtin::BI__builtin_hlsl_asdouble:
1030 case Builtin::BI__builtin_hlsl_elementwise_clamp: {
1037 Ty = VecTy->getElementType();
1041 Intr =
CGM.getHLSLRuntime().getNClampIntrinsic();
1043 Intr =
CGM.getHLSLRuntime().getUClampIntrinsic();
1046 Intr =
CGM.getHLSLRuntime().getSClampIntrinsic();
1048 return Builder.CreateIntrinsic(
1052 case Builtin::BI__builtin_hlsl_crossf16:
1053 case Builtin::BI__builtin_hlsl_crossf32: {
1058 "cross operands must have a float representation");
1063 "input vectors must have 3 elements each");
1064 return Builder.CreateIntrinsic(
1065 Op0->
getType(),
CGM.getHLSLRuntime().getCrossIntrinsic(),
1068 case Builtin::BI__builtin_hlsl_dot: {
1071 llvm::Type *T0 = Op0->
getType();
1072 llvm::Type *T1 = Op1->
getType();
1075 if (!T0->isVectorTy() && !T1->isVectorTy()) {
1076 if (T0->isFloatingPointTy())
1077 return Builder.CreateFMul(Op0, Op1,
"hlsl.dot");
1079 if (T0->isIntegerTy())
1080 return Builder.CreateMul(Op0, Op1,
"hlsl.dot");
1083 "Scalar dot product is only supported on ints and floats.");
1088 "Dot product operands must have the same type.");
1091 assert(VecTy0 &&
"Dot product argument must be a vector.");
1093 return Builder.CreateIntrinsic(
1094 T0->getScalarType(),
1098 case Builtin::BI__builtin_hlsl_dot4add_i8packed: {
1103 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddI8PackedIntrinsic();
1106 return Builder.CreateIntrinsic(
1108 nullptr,
"hlsl.dot4add.i8packed");
1110 case Builtin::BI__builtin_hlsl_dot4add_u8packed: {
1115 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddU8PackedIntrinsic();
1118 return Builder.CreateIntrinsic(
1120 nullptr,
"hlsl.dot4add.u8packed");
1122 case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
1125 return Builder.CreateIntrinsic(
1130 case Builtin::BI__builtin_hlsl_elementwise_firstbitlow: {
1133 return Builder.CreateIntrinsic(
1136 nullptr,
"hlsl.firstbitlow");
1138 case Builtin::BI__builtin_hlsl_lerp: {
1143 llvm_unreachable(
"lerp operand must have a float representation");
1144 return Builder.CreateIntrinsic(
1145 X->getType(),
CGM.getHLSLRuntime().getLerpIntrinsic(),
1148 case Builtin::BI__builtin_hlsl_normalize: {
1152 "normalize operand must have a float representation");
1154 return Builder.CreateIntrinsic(
1157 nullptr,
"hlsl.normalize");
1159 case Builtin::BI__builtin_hlsl_elementwise_degrees: {
1163 "degree operand must have a float representation");
1165 return Builder.CreateIntrinsic(
1166 X->getType(),
CGM.getHLSLRuntime().getDegreesIntrinsic(),
1169 case Builtin::BI__builtin_hlsl_elementwise_f16tof32: {
1172 case Builtin::BI__builtin_hlsl_elementwise_f32tof16: {
1175 case Builtin::BI__builtin_hlsl_elementwise_frac: {
1178 llvm_unreachable(
"frac operand must have a float representation");
1179 return Builder.CreateIntrinsic(
1180 Op0->
getType(),
CGM.getHLSLRuntime().getFracIntrinsic(),
1183 case Builtin::BI__builtin_hlsl_elementwise_isinf: {
1185 llvm::Type *Xty = Op0->
getType();
1186 llvm::Type *retType = llvm::Type::getInt1Ty(this->
getLLVMContext());
1187 if (Xty->isVectorTy()) {
1189 retType = llvm::VectorType::get(
1190 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1193 llvm_unreachable(
"isinf operand must have a float representation");
1194 return Builder.CreateIntrinsic(
1195 retType,
CGM.getHLSLRuntime().getIsInfIntrinsic(),
1198 case Builtin::BI__builtin_hlsl_elementwise_isnan: {
1200 llvm::Type *Xty = Op0->
getType();
1201 llvm::Type *retType = llvm::Type::getInt1Ty(this->
getLLVMContext());
1202 if (Xty->isVectorTy()) {
1204 retType = llvm::VectorType::get(
1205 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1208 llvm_unreachable(
"isnan operand must have a float representation");
1209 return Builder.CreateIntrinsic(
1210 retType,
CGM.getHLSLRuntime().getIsNaNIntrinsic(),
1213 case Builtin::BI__builtin_hlsl_mad: {
1218 return Builder.CreateIntrinsic(
1219 M->
getType(), Intrinsic::fmuladd,
1223 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1224 return Builder.CreateIntrinsic(
1225 M->
getType(), Intrinsic::dx_imad,
1229 return Builder.CreateNSWAdd(Mul, B);
1232 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1233 return Builder.CreateIntrinsic(
1234 M->
getType(), Intrinsic::dx_umad,
1238 return Builder.CreateNUWAdd(Mul, B);
1240 case Builtin::BI__builtin_hlsl_mul: {
1258 llvm::MatrixBuilder MB(
Builder);
1259 if (IsVec0 && IsMat1) {
1263 unsigned Cols = MatTy->getNumColumns();
1264 assert(N == Rows &&
"vector length must match matrix row count");
1266 Op1 = MB.CreateRowMajorToColumnMajorTransform(Op1, Rows, Cols);
1267 return MB.CreateMatrixMultiply(Op0, Op1, 1, N, Cols,
"hlsl.mul");
1269 if (IsMat0 && IsVec1) {
1272 unsigned Cols = MatTy->getNumColumns();
1274 "vector length must match matrix column count");
1276 Op0 = MB.CreateRowMajorToColumnMajorTransform(Op0, Rows, Cols);
1277 return MB.CreateMatrixMultiply(Op0, Op1, Rows, Cols, 1,
"hlsl.mul");
1279 assert(IsMat0 && IsMat1);
1284 unsigned Cols0 = MatTy0->getNumColumns();
1286 assert(Cols0 == Rows1 &&
1287 "inner matrix dimensions must match for multiplication");
1289 Op0 = MB.CreateRowMajorToColumnMajorTransform(Op0, Rows0, Cols0);
1291 Op1 = MB.CreateRowMajorToColumnMajorTransform(Op1, Rows1, Cols1);
1294 MB.CreateMatrixMultiply(Op0, Op1, Rows0, Cols0, Cols1,
"hlsl.mul");
1297 if (IsResultRowMajor)
1298 Result = MB.CreateColumnMajorToRowMajorTransform(
Result, Rows0, Cols1);
1301 case Builtin::BI__builtin_hlsl_transpose: {
1305 unsigned Cols = MatTy->getNumColumns();
1306 llvm::MatrixBuilder MB(
Builder);
1313 if (SrcRowMajor != DstRowMajor)
1318 return MB.CreateMatrixTranspose(Op0, Cols, Rows);
1319 return MB.CreateMatrixTranspose(Op0, Rows, Cols);
1321 case Builtin::BI__builtin_hlsl_elementwise_rcp: {
1324 llvm_unreachable(
"rcp operand must have a float representation");
1325 llvm::Type *Ty = Op0->
getType();
1326 llvm::Type *EltTy = Ty->getScalarType();
1328 ? ConstantVector::getSplat(
1329 ElementCount::getFixed(
1331 ConstantFP::get(EltTy, 1.0))
1332 : ConstantFP::get(EltTy, 1.0);
1333 return Builder.CreateFDiv(One, Op0,
"hlsl.rcp");
1335 case Builtin::BI__builtin_hlsl_elementwise_rsqrt: {
1338 llvm_unreachable(
"rsqrt operand must have a float representation");
1339 return Builder.CreateIntrinsic(
1340 Op0->
getType(),
CGM.getHLSLRuntime().getRsqrtIntrinsic(),
1343 case Builtin::BI__builtin_hlsl_elementwise_saturate: {
1346 "saturate operand must have a float representation");
1347 return Builder.CreateIntrinsic(
1350 nullptr,
"hlsl.saturate");
1352 case Builtin::BI__builtin_hlsl_wave_prefix_count_bits: {
1354 assert(Op->
getType()->isIntegerTy(1) &&
1355 "WavePrefixBitCount operand must be a boolean type");
1362 case Builtin::BI__builtin_hlsl_select: {
1375 if (!OpTrue->
getType()->isVectorTy())
1377 Builder.CreateVectorSplat(VTy->getNumElements(), OpTrue,
"splat");
1378 if (!OpFalse->
getType()->isVectorTy())
1380 Builder.CreateVectorSplat(VTy->getNumElements(), OpFalse,
"splat");
1384 Builder.CreateSelect(OpCond, OpTrue, OpFalse,
"hlsl.select");
1391 case Builtin::BI__builtin_hlsl_step: {
1396 "step operands must have a float representation");
1397 return Builder.CreateIntrinsic(
1398 Op0->
getType(),
CGM.getHLSLRuntime().getStepIntrinsic(),
1401 case Builtin::BI__builtin_hlsl_wave_active_all_equal: {
1404 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllEqualIntrinsic();
1407 case Builtin::BI__builtin_hlsl_wave_active_all_true: {
1409 assert(Op->
getType()->isIntegerTy(1) &&
1410 "Intrinsic WaveActiveAllTrue operand must be a bool");
1412 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllTrueIntrinsic();
1415 case Builtin::BI__builtin_hlsl_wave_active_any_true: {
1417 assert(Op->
getType()->isIntegerTy(1) &&
1418 "Intrinsic WaveActiveAnyTrue operand must be a bool");
1420 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic();
1423 case Builtin::BI__builtin_hlsl_wave_active_bit_or: {
1426 "Intrinsic WaveActiveBitOr operand must have an unsigned integer "
1429 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitOrIntrinsic();
1431 "hlsl.wave.active.bit.or");
1433 case Builtin::BI__builtin_hlsl_wave_active_bit_xor: {
1436 "Intrinsic WaveActiveBitXor operand must have an unsigned integer "
1439 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitXorIntrinsic();
1441 "hlsl.wave.active.bit.xor");
1443 case Builtin::BI__builtin_hlsl_wave_active_bit_and: {
1446 "Intrinsic WaveActiveBitAnd operand must have an unsigned integer "
1449 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitAndIntrinsic();
1451 "hlsl.wave.active.bit.and");
1453 case Builtin::BI__builtin_hlsl_interlocked_add: {
1460 case Builtin::BI__builtin_hlsl_interlocked_or: {
1463 case Builtin::BI__builtin_hlsl_wave_active_ballot: {
1465 assert(Op->
getType()->isIntegerTy(1) &&
1466 "Intrinsic WaveActiveBallot operand must be a bool");
1470 case Builtin::BI__builtin_hlsl_wave_active_count_bits: {
1472 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveCountBitsIntrinsic();
1475 case Builtin::BI__builtin_hlsl_wave_active_sum: {
1482 "hlsl.wave.active.sum");
1484 case Builtin::BI__builtin_hlsl_wave_active_product: {
1491 "hlsl.wave.active.product");
1493 case Builtin::BI__builtin_hlsl_wave_active_max: {
1499 IID =
CGM.getHLSLRuntime().getWaveActiveUMaxIntrinsic();
1501 IID =
CGM.getHLSLRuntime().getWaveActiveMaxIntrinsic();
1504 "hlsl.wave.active.max");
1506 case Builtin::BI__builtin_hlsl_wave_active_min: {
1512 IID =
CGM.getHLSLRuntime().getWaveActiveUMinIntrinsic();
1514 IID =
CGM.getHLSLRuntime().getWaveActiveMinIntrinsic();
1517 "hlsl.wave.active.min");
1519 case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
1523 switch (
CGM.getTarget().getTriple().getArch()) {
1524 case llvm::Triple::dxil:
1526 case llvm::Triple::spirv:
1528 llvm::FunctionType::get(
IntTy, {},
false),
1529 "__hlsl_wave_get_lane_index", {},
false,
true));
1532 "Intrinsic WaveGetLaneIndex not supported by target architecture");
1535 case Builtin::BI__builtin_hlsl_wave_is_first_lane: {
1536 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveIsFirstLaneIntrinsic();
1539 case Builtin::BI__builtin_hlsl_wave_get_lane_count: {
1540 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveGetLaneCountIntrinsic();
1543 case Builtin::BI__builtin_hlsl_wave_read_lane_at: {
1549 {OpExpr->getType()},
ArrayRef{OpExpr, OpIndex},
1550 "hlsl.wave.readlane");
1552 case Builtin::BI__builtin_hlsl_wave_prefix_sum: {
1557 "hlsl.wave.prefix.sum");
1559 case Builtin::BI__builtin_hlsl_wave_prefix_product: {
1564 "hlsl.wave.prefix.product");
1566 case Builtin::BI__builtin_hlsl_quad_read_across_x: {
1568 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossXIntrinsic();
1570 "hlsl.quad.read.across.x");
1572 case Builtin::BI__builtin_hlsl_quad_read_across_y: {
1574 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossYIntrinsic();
1576 "hlsl.quad.read.across.y");
1578 case Builtin::BI__builtin_hlsl_quad_read_across_diagonal: {
1581 CGM.getHLSLRuntime().getQuadReadAcrossDiagonalIntrinsic();
1583 &
CGM.getModule(), ID, {OpExpr->getType()}),
1584 ArrayRef{OpExpr},
"hlsl.quad.read.across.diagonal");
1586 case Builtin::BI__builtin_hlsl_elementwise_sign: {
1587 auto *Arg0 = E->
getArg(0);
1589 llvm::Type *Xty = Op0->
getType();
1590 llvm::Type *retType = llvm::Type::getInt32Ty(this->
getLLVMContext());
1591 if (Xty->isVectorTy()) {
1592 auto *XVecTy = Arg0->getType()->castAs<
VectorType>();
1593 retType = llvm::VectorType::get(
1594 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1596 assert((Arg0->getType()->hasFloatingRepresentation() ||
1597 Arg0->getType()->hasIntegerRepresentation()) &&
1598 "sign operand must have a float or int representation");
1600 if (Arg0->getType()->hasUnsignedIntegerRepresentation()) {
1602 return Builder.CreateSelect(
Cmp, ConstantInt::get(retType, 0),
1603 ConstantInt::get(retType, 1),
"hlsl.sign");
1606 return Builder.CreateIntrinsic(
1607 retType,
CGM.getHLSLRuntime().getSignIntrinsic(),
1610 case Builtin::BI__builtin_hlsl_elementwise_radians: {
1613 "radians operand must have a float representation");
1614 return Builder.CreateIntrinsic(
1617 nullptr,
"hlsl.radians");
1619 case Builtin::BI__builtin_hlsl_buffer_update_counter: {
1623 return Builder.CreateIntrinsic(
1625 CGM.getHLSLRuntime().getBufferUpdateCounterIntrinsic(),
1628 case Builtin::BI__builtin_hlsl_elementwise_splitdouble: {
1633 "asuint operands types mismatch");
1636 case Builtin::BI__builtin_hlsl_elementwise_clip:
1638 "clip operands types mismatch");
1640 case Builtin::BI__builtin_hlsl_all_memory_barrier: {
1641 Intrinsic::ID ID =
CGM.getHLSLRuntime().getAllMemoryBarrierIntrinsic();
1644 case Builtin::BI__builtin_hlsl_all_memory_barrier_with_group_sync: {
1646 CGM.getHLSLRuntime().getAllMemoryBarrierWithGroupSyncIntrinsic();
1649 case Builtin::BI__builtin_hlsl_device_memory_barrier: {
1650 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDeviceMemoryBarrierIntrinsic();
1653 case Builtin::BI__builtin_hlsl_device_memory_barrier_with_group_sync: {
1655 CGM.getHLSLRuntime().getDeviceMemoryBarrierWithGroupSyncIntrinsic();
1658 case Builtin::BI__builtin_hlsl_group_memory_barrier: {
1659 Intrinsic::ID ID =
CGM.getHLSLRuntime().getGroupMemoryBarrierIntrinsic();
1662 case Builtin::BI__builtin_hlsl_group_memory_barrier_with_group_sync: {
1664 CGM.getHLSLRuntime().getGroupMemoryBarrierWithGroupSyncIntrinsic();
1667 case Builtin::BI__builtin_hlsl_elementwise_ddx_coarse: {
1670 llvm_unreachable(
"ddx_coarse operand must have a float representation");
1671 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxCoarseIntrinsic();
1676 case Builtin::BI__builtin_hlsl_elementwise_ddy_coarse: {
1679 llvm_unreachable(
"ddy_coarse operand must have a float representation");
1680 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyCoarseIntrinsic();
1685 case Builtin::BI__builtin_hlsl_elementwise_ddx_fine: {
1688 llvm_unreachable(
"ddx_fine operand must have a float representation");
1689 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxFineIntrinsic();
1694 case Builtin::BI__builtin_hlsl_elementwise_ddy_fine: {
1697 llvm_unreachable(
"ddy_fine operand must have a float representation");
1698 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyFineIntrinsic();
1703 case Builtin::BI__builtin_get_spirv_spec_constant_bool:
1704 case Builtin::BI__builtin_get_spirv_spec_constant_short:
1705 case Builtin::BI__builtin_get_spirv_spec_constant_ushort:
1706 case Builtin::BI__builtin_get_spirv_spec_constant_int:
1707 case Builtin::BI__builtin_get_spirv_spec_constant_uint:
1708 case Builtin::BI__builtin_get_spirv_spec_constant_longlong:
1709 case Builtin::BI__builtin_get_spirv_spec_constant_ulonglong:
1710 case Builtin::BI__builtin_get_spirv_spec_constant_half:
1711 case Builtin::BI__builtin_get_spirv_spec_constant_float:
1712 case Builtin::BI__builtin_get_spirv_spec_constant_double: {
1716 llvm::Value *Args[] = {SpecId, DefaultVal};
1717 return Builder.CreateCall(SpecConstantFn, Args);