516 case Builtin::BI__builtin_hlsl_adduint64: {
522 "AddUint64 operand types must match");
524 "AddUint64 operands must have an integer representation");
525 assert((NumElements == 2 || NumElements == 4) &&
526 "AddUint64 operands must have 2 or 4 elements");
534 if (NumElements == 2) {
535 LowA =
Builder.CreateExtractElement(OpA, (uint64_t)0,
"LowA");
536 HighA =
Builder.CreateExtractElement(OpA, (uint64_t)1,
"HighA");
537 LowB =
Builder.CreateExtractElement(OpB, (uint64_t)0,
"LowB");
538 HighB =
Builder.CreateExtractElement(OpB, (uint64_t)1,
"HighB");
540 LowA =
Builder.CreateShuffleVector(OpA, {0, 2},
"LowA");
541 HighA =
Builder.CreateShuffleVector(OpA, {1, 3},
"HighA");
542 LowB =
Builder.CreateShuffleVector(OpB, {0, 2},
"LowB");
543 HighB =
Builder.CreateShuffleVector(OpB, {1, 3},
"HighB");
550 *
this, Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
551 llvm::Value *ZExtCarry =
552 Builder.CreateZExt(Carry, HighA->getType(),
"CarryZExt");
555 llvm::Value *HighSum =
Builder.CreateAdd(HighA, HighB,
"HighSum");
556 llvm::Value *HighSumPlusCarry =
557 Builder.CreateAdd(HighSum, ZExtCarry,
"HighSumPlusCarry");
559 if (NumElements == 4) {
560 return Builder.CreateShuffleVector(LowSum, HighSumPlusCarry, {0, 2, 1, 3},
566 "hlsl.AddUint64.upto0");
571 case Builtin::BI__builtin_hlsl_resource_getpointer:
572 case Builtin::BI__builtin_hlsl_resource_getpointer_typed: {
575 BuiltinID == Builtin::BI__builtin_hlsl_resource_getpointer_typed ||
581 return Builder.CreateIntrinsic(
582 RetTy,
CGM.getHLSLRuntime().getCreateResourceGetPointerIntrinsic(),
585 return Builder.CreateIntrinsic(
586 RetTy,
CGM.getHLSLRuntime().getCreateResourceGetBasePointerIntrinsic(),
589 case Builtin::BI__builtin_hlsl_resource_sample: {
595 Args.push_back(HandleOp);
596 Args.push_back(SamplerOp);
597 Args.push_back(CoordOp);
603 return Builder.CreateIntrinsic(
604 RetTy,
CGM.getHLSLRuntime().getSampleIntrinsic(), Args);
608 return Builder.CreateIntrinsic(
609 RetTy,
CGM.getHLSLRuntime().getSampleClampIntrinsic(), Args);
611 case Builtin::BI__builtin_hlsl_resource_sample_bias: {
620 Args.push_back(HandleOp);
621 Args.push_back(SamplerOp);
622 Args.push_back(CoordOp);
623 Args.push_back(BiasOp);
629 return Builder.CreateIntrinsic(
630 RetTy,
CGM.getHLSLRuntime().getSampleBiasIntrinsic(), Args);
633 return Builder.CreateIntrinsic(
634 RetTy,
CGM.getHLSLRuntime().getSampleBiasClampIntrinsic(), Args);
636 case Builtin::BI__builtin_hlsl_resource_sample_grad: {
644 Args.push_back(HandleOp);
645 Args.push_back(SamplerOp);
646 Args.push_back(CoordOp);
647 Args.push_back(DDXOp);
648 Args.push_back(DDYOp);
655 return Builder.CreateIntrinsic(
656 RetTy,
CGM.getHLSLRuntime().getSampleGradIntrinsic(), Args);
660 return Builder.CreateIntrinsic(
661 RetTy,
CGM.getHLSLRuntime().getSampleGradClampIntrinsic(), Args);
663 case Builtin::BI__builtin_hlsl_resource_sample_level: {
672 Args.push_back(HandleOp);
673 Args.push_back(SamplerOp);
674 Args.push_back(CoordOp);
675 Args.push_back(LODOp);
680 return Builder.CreateIntrinsic(
681 RetTy,
CGM.getHLSLRuntime().getSampleLevelIntrinsic(), Args);
683 case Builtin::BI__builtin_hlsl_resource_load_level: {
688 unsigned NumElts = CoordLODVecTy->getNumElements();
689 assert(NumElts >= 2 &&
"CoordLOD must have at least 2 elements");
693 for (
unsigned I = 0; I < NumElts - 1; ++I)
697 Builder.CreateShuffleVector(CoordLODOp, Mask,
"hlsl.load.coord");
699 Builder.CreateExtractElement(CoordLODOp, NumElts - 1,
"hlsl.load.lod");
702 Args.push_back(HandleOp);
703 Args.push_back(CoordOp);
704 Args.push_back(LODOp);
709 return Builder.CreateIntrinsic(
710 RetTy,
CGM.getHLSLRuntime().getLoadLevelIntrinsic(), Args);
712 case Builtin::BI__builtin_hlsl_resource_sample_cmp: {
721 Args.push_back(HandleOp);
722 Args.push_back(SamplerOp);
723 Args.push_back(CoordOp);
724 Args.push_back(CmpOp);
730 return Builder.CreateIntrinsic(
731 RetTy,
CGM.getHLSLRuntime().getSampleCmpIntrinsic(), Args);
735 return Builder.CreateIntrinsic(
736 RetTy,
CGM.getHLSLRuntime().getSampleCmpClampIntrinsic(), Args);
738 case Builtin::BI__builtin_hlsl_resource_sample_cmp_level_zero: {
747 Args.push_back(HandleOp);
748 Args.push_back(SamplerOp);
749 Args.push_back(CoordOp);
750 Args.push_back(CmpOp);
756 return Builder.CreateIntrinsic(
757 RetTy,
CGM.getHLSLRuntime().getSampleCmpLevelZeroIntrinsic(), Args);
759 case Builtin::BI__builtin_hlsl_resource_calculate_lod: {
764 return Builder.CreateIntrinsic(
766 CGM.getHLSLRuntime().getCalculateLodIntrinsic(),
767 {HandleOp, SamplerOp, CoordOp});
769 case Builtin::BI__builtin_hlsl_resource_calculate_lod_unclamped: {
774 return Builder.CreateIntrinsic(
776 CGM.getHLSLRuntime().getCalculateLodUnclampedIntrinsic(),
777 {HandleOp, SamplerOp, CoordOp});
779 case Builtin::BI__builtin_hlsl_resource_gather: {
785 ComponentOp =
Builder.CreateIntCast(ComponentOp,
Builder.getInt32Ty(),
789 Args.push_back(HandleOp);
790 Args.push_back(SamplerOp);
791 Args.push_back(CoordOp);
792 Args.push_back(ComponentOp);
797 return Builder.CreateIntrinsic(
798 RetTy,
CGM.getHLSLRuntime().getGatherIntrinsic(), Args);
800 case Builtin::BI__builtin_hlsl_resource_gather_cmp: {
806 CompareOp =
Builder.CreateFPCast(CompareOp,
Builder.getFloatTy());
809 Args.push_back(HandleOp);
810 Args.push_back(SamplerOp);
811 Args.push_back(CoordOp);
812 Args.push_back(CompareOp);
814 if (
CGM.getTarget().getTriple().isDXIL()) {
817 ComponentOp =
Builder.CreateIntCast(ComponentOp,
Builder.getInt32Ty(),
819 Args.push_back(ComponentOp);
826 return Builder.CreateIntrinsic(
827 RetTy,
CGM.getHLSLRuntime().getGatherCmpIntrinsic(), Args);
829 case Builtin::BI__builtin_hlsl_resource_load_with_status:
830 case Builtin::BI__builtin_hlsl_resource_load_with_status_typed: {
839 const HLSLAttributedResourceType *RT =
840 HandleTy->
getAs<HLSLAttributedResourceType>();
841 assert(
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil &&
842 "Only DXIL currently implements load with status");
844 Intrinsic::ID IntrID = RT->getAttrs().RawBuffer
845 ? llvm::Intrinsic::dx_resource_load_rawbuffer
846 : llvm::Intrinsic::dx_resource_load_typedbuffer;
849 llvm::Type *RetTy = llvm::StructType::get(
Builder.getContext(),
850 {DataTy, Builder.getInt1Ty()});
853 Args.push_back(HandleOp);
854 Args.push_back(IndexOp);
859 if (!RT->isStructured())
860 Offset = llvm::PoisonValue::get(
Builder.getInt32Ty());
861 Args.push_back(Offset);
867 Builder.CreateIntrinsic(RetTy, IntrID, Args, {},
"ld.struct");
868 Value *LoadedValue =
Builder.CreateExtractValue(ResRet, {0},
"ld.value");
869 Value *StatusBit =
Builder.CreateExtractValue(ResRet, {1},
"ld.status");
870 Value *ExtendedStatus =
871 Builder.CreateZExt(StatusBit,
Builder.getInt32Ty(),
"ld.status.ext");
872 Builder.CreateStore(ExtendedStatus, StatusAddr);
876 case Builtin::BI__builtin_hlsl_resource_uninitializedhandle: {
877 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
878 return llvm::PoisonValue::get(HandleTy);
880 case Builtin::BI__builtin_hlsl_resource_handlefrombinding: {
881 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
887 llvm::Intrinsic::ID IntrinsicID =
888 CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic();
890 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
892 case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: {
893 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
899 llvm::Intrinsic::ID IntrinsicID =
900 CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
902 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
904 case Builtin::BI__builtin_hlsl_resource_counterhandlefromimplicitbinding: {
906 if (!
CGM.getTriple().isSPIRV())
909 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
912 llvm::Intrinsic::ID IntrinsicID =
913 llvm::Intrinsic::spv_resource_counterhandlefromimplicitbinding;
915 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
917 case Builtin::BI__builtin_hlsl_resource_nonuniformindex: {
920 return Builder.CreateIntrinsic(
921 RetTy,
CGM.getHLSLRuntime().getNonUniformResourceIndexIntrinsic(),
924 case Builtin::BI__builtin_hlsl_resource_getdimensions_x:
925 case Builtin::BI__builtin_hlsl_resource_getdimensions_x_float:
927 CGM.getHLSLRuntime().getGetDimensionsXIntrinsic(),
929 case Builtin::BI__builtin_hlsl_resource_getdimensions_xy:
930 case Builtin::BI__builtin_hlsl_resource_getdimensions_xy_float:
932 CGM.getHLSLRuntime().getGetDimensionsXYIntrinsic(),
934 case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy:
935 case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy_float:
937 *
this, E,
CGM.getHLSLRuntime().getGetDimensionsLevelsXYIntrinsic(), 3,
939 case Builtin::BI__builtin_hlsl_resource_getstride: {
943 case Builtin::BI__builtin_hlsl_all: {
945 return Builder.CreateIntrinsic(
950 case Builtin::BI__builtin_hlsl_and: {
953 return Builder.CreateAnd(Op0, Op1,
"hlsl.and");
955 case Builtin::BI__builtin_hlsl_or: {
958 return Builder.CreateOr(Op0, Op1,
"hlsl.or");
960 case Builtin::BI__builtin_hlsl_any: {
962 return Builder.CreateIntrinsic(
967 case Builtin::BI__builtin_hlsl_asdouble:
969 case Builtin::BI__builtin_hlsl_elementwise_clamp: {
976 Ty = VecTy->getElementType();
980 Intr =
CGM.getHLSLRuntime().getNClampIntrinsic();
982 Intr =
CGM.getHLSLRuntime().getUClampIntrinsic();
985 Intr =
CGM.getHLSLRuntime().getSClampIntrinsic();
987 return Builder.CreateIntrinsic(
991 case Builtin::BI__builtin_hlsl_crossf16:
992 case Builtin::BI__builtin_hlsl_crossf32: {
997 "cross operands must have a float representation");
1002 "input vectors must have 3 elements each");
1003 return Builder.CreateIntrinsic(
1004 Op0->
getType(),
CGM.getHLSLRuntime().getCrossIntrinsic(),
1007 case Builtin::BI__builtin_hlsl_dot: {
1010 llvm::Type *T0 = Op0->
getType();
1011 llvm::Type *T1 = Op1->
getType();
1014 if (!T0->isVectorTy() && !T1->isVectorTy()) {
1015 if (T0->isFloatingPointTy())
1016 return Builder.CreateFMul(Op0, Op1,
"hlsl.dot");
1018 if (T0->isIntegerTy())
1019 return Builder.CreateMul(Op0, Op1,
"hlsl.dot");
1022 "Scalar dot product is only supported on ints and floats.");
1027 "Dot product operands must have the same type.");
1030 assert(VecTy0 &&
"Dot product argument must be a vector.");
1032 return Builder.CreateIntrinsic(
1033 T0->getScalarType(),
1037 case Builtin::BI__builtin_hlsl_dot4add_i8packed: {
1042 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddI8PackedIntrinsic();
1045 return Builder.CreateIntrinsic(
1047 nullptr,
"hlsl.dot4add.i8packed");
1049 case Builtin::BI__builtin_hlsl_dot4add_u8packed: {
1054 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddU8PackedIntrinsic();
1057 return Builder.CreateIntrinsic(
1059 nullptr,
"hlsl.dot4add.u8packed");
1061 case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
1064 return Builder.CreateIntrinsic(
1069 case Builtin::BI__builtin_hlsl_elementwise_firstbitlow: {
1072 return Builder.CreateIntrinsic(
1075 nullptr,
"hlsl.firstbitlow");
1077 case Builtin::BI__builtin_hlsl_lerp: {
1082 llvm_unreachable(
"lerp operand must have a float representation");
1083 return Builder.CreateIntrinsic(
1084 X->getType(),
CGM.getHLSLRuntime().getLerpIntrinsic(),
1087 case Builtin::BI__builtin_hlsl_normalize: {
1091 "normalize operand must have a float representation");
1093 return Builder.CreateIntrinsic(
1096 nullptr,
"hlsl.normalize");
1098 case Builtin::BI__builtin_hlsl_elementwise_degrees: {
1102 "degree operand must have a float representation");
1104 return Builder.CreateIntrinsic(
1105 X->getType(),
CGM.getHLSLRuntime().getDegreesIntrinsic(),
1108 case Builtin::BI__builtin_hlsl_elementwise_f16tof32: {
1111 case Builtin::BI__builtin_hlsl_elementwise_f32tof16: {
1114 case Builtin::BI__builtin_hlsl_elementwise_frac: {
1117 llvm_unreachable(
"frac operand must have a float representation");
1118 return Builder.CreateIntrinsic(
1119 Op0->
getType(),
CGM.getHLSLRuntime().getFracIntrinsic(),
1122 case Builtin::BI__builtin_hlsl_elementwise_isinf: {
1124 llvm::Type *Xty = Op0->
getType();
1125 llvm::Type *retType = llvm::Type::getInt1Ty(this->
getLLVMContext());
1126 if (Xty->isVectorTy()) {
1128 retType = llvm::VectorType::get(
1129 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1132 llvm_unreachable(
"isinf operand must have a float representation");
1133 return Builder.CreateIntrinsic(
1134 retType,
CGM.getHLSLRuntime().getIsInfIntrinsic(),
1137 case Builtin::BI__builtin_hlsl_elementwise_isnan: {
1139 llvm::Type *Xty = Op0->
getType();
1140 llvm::Type *retType = llvm::Type::getInt1Ty(this->
getLLVMContext());
1141 if (Xty->isVectorTy()) {
1143 retType = llvm::VectorType::get(
1144 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1147 llvm_unreachable(
"isnan operand must have a float representation");
1148 return Builder.CreateIntrinsic(
1149 retType,
CGM.getHLSLRuntime().getIsNaNIntrinsic(),
1152 case Builtin::BI__builtin_hlsl_mad: {
1157 return Builder.CreateIntrinsic(
1158 M->
getType(), Intrinsic::fmuladd,
1162 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1163 return Builder.CreateIntrinsic(
1164 M->
getType(), Intrinsic::dx_imad,
1168 return Builder.CreateNSWAdd(Mul, B);
1171 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1172 return Builder.CreateIntrinsic(
1173 M->
getType(), Intrinsic::dx_umad,
1177 return Builder.CreateNUWAdd(Mul, B);
1179 case Builtin::BI__builtin_hlsl_mul: {
1193 bool IsRowMajor =
getLangOpts().getDefaultMatrixMemoryLayout() ==
1196 llvm::MatrixBuilder MB(
Builder);
1197 if (IsVec0 && IsMat1) {
1201 unsigned Cols = MatTy->getNumColumns();
1202 assert(N == Rows &&
"vector length must match matrix row count");
1204 Op1 = MB.CreateRowMajorToColumnMajorTransform(Op1, Rows, Cols);
1205 return MB.CreateMatrixMultiply(Op0, Op1, 1, N, Cols,
"hlsl.mul");
1207 if (IsMat0 && IsVec1) {
1210 unsigned Cols = MatTy->getNumColumns();
1212 "vector length must match matrix column count");
1214 Op0 = MB.CreateRowMajorToColumnMajorTransform(Op0, Rows, Cols);
1215 return MB.CreateMatrixMultiply(Op0, Op1, Rows, Cols, 1,
"hlsl.mul");
1217 assert(IsMat0 && IsMat1);
1222 unsigned Cols0 = MatTy0->getNumColumns();
1224 assert(Cols0 == Rows1 &&
1225 "inner matrix dimensions must match for multiplication");
1227 Op0 = MB.CreateRowMajorToColumnMajorTransform(Op0, Rows0, Cols0);
1228 Op1 = MB.CreateRowMajorToColumnMajorTransform(Op1, Rows1, Cols1);
1231 MB.CreateMatrixMultiply(Op0, Op1, Rows0, Cols0, Cols1,
"hlsl.mul");
1233 Result = MB.CreateColumnMajorToRowMajorTransform(
Result, Rows0, Cols1);
1236 case Builtin::BI__builtin_hlsl_transpose: {
1240 unsigned Cols = MatTy->getNumColumns();
1241 llvm::MatrixBuilder MB(
Builder);
1246 bool IsRowMajor =
getLangOpts().getDefaultMatrixMemoryLayout() ==
1249 return MB.CreateMatrixTranspose(Op0, Cols, Rows);
1250 return MB.CreateMatrixTranspose(Op0, Rows, Cols);
1252 case Builtin::BI__builtin_hlsl_elementwise_rcp: {
1255 llvm_unreachable(
"rcp operand must have a float representation");
1256 llvm::Type *Ty = Op0->
getType();
1257 llvm::Type *EltTy = Ty->getScalarType();
1259 ? ConstantVector::getSplat(
1260 ElementCount::getFixed(
1262 ConstantFP::get(EltTy, 1.0))
1263 : ConstantFP::get(EltTy, 1.0);
1264 return Builder.CreateFDiv(One, Op0,
"hlsl.rcp");
1266 case Builtin::BI__builtin_hlsl_elementwise_rsqrt: {
1269 llvm_unreachable(
"rsqrt operand must have a float representation");
1270 return Builder.CreateIntrinsic(
1271 Op0->
getType(),
CGM.getHLSLRuntime().getRsqrtIntrinsic(),
1274 case Builtin::BI__builtin_hlsl_elementwise_saturate: {
1277 "saturate operand must have a float representation");
1278 return Builder.CreateIntrinsic(
1281 nullptr,
"hlsl.saturate");
1283 case Builtin::BI__builtin_hlsl_wave_prefix_count_bits: {
1285 assert(Op->
getType()->isIntegerTy(1) &&
1286 "WavePrefixBitCount operand must be a boolean type");
1292 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), IID),
ArrayRef{Op},
1293 "hlsl.wave.prefix.bit.count");
1295 case Builtin::BI__builtin_hlsl_select: {
1308 if (!OpTrue->
getType()->isVectorTy())
1310 Builder.CreateVectorSplat(VTy->getNumElements(), OpTrue,
"splat");
1311 if (!OpFalse->
getType()->isVectorTy())
1313 Builder.CreateVectorSplat(VTy->getNumElements(), OpFalse,
"splat");
1317 Builder.CreateSelect(OpCond, OpTrue, OpFalse,
"hlsl.select");
1324 case Builtin::BI__builtin_hlsl_step: {
1329 "step operands must have a float representation");
1330 return Builder.CreateIntrinsic(
1331 Op0->
getType(),
CGM.getHLSLRuntime().getStepIntrinsic(),
1334 case Builtin::BI__builtin_hlsl_wave_active_all_equal: {
1337 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllEqualIntrinsic();
1339 &
CGM.getModule(), ID, {Op->getType()}),
1342 case Builtin::BI__builtin_hlsl_wave_active_all_true: {
1344 assert(Op->
getType()->isIntegerTy(1) &&
1345 "Intrinsic WaveActiveAllTrue operand must be a bool");
1347 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllTrueIntrinsic();
1349 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID), {Op});
1351 case Builtin::BI__builtin_hlsl_wave_active_any_true: {
1353 assert(Op->
getType()->isIntegerTy(1) &&
1354 "Intrinsic WaveActiveAnyTrue operand must be a bool");
1356 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic();
1358 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID), {Op});
1360 case Builtin::BI__builtin_hlsl_wave_active_bit_or: {
1363 "Intrinsic WaveActiveBitOr operand must have an unsigned integer "
1366 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitOrIntrinsic();
1368 &
CGM.getModule(), ID, {Op->getType()}),
1369 ArrayRef{Op},
"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 &
CGM.getModule(), ID, {Op->getType()}),
1380 ArrayRef{Op},
"hlsl.wave.active.bit.xor");
1382 case Builtin::BI__builtin_hlsl_wave_active_bit_and: {
1385 "Intrinsic WaveActiveBitAnd operand must have an unsigned integer "
1388 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitAndIntrinsic();
1390 &
CGM.getModule(), ID, {Op->getType()}),
1391 ArrayRef{Op},
"hlsl.wave.active.bit.and");
1393 case Builtin::BI__builtin_hlsl_wave_active_ballot: {
1395 assert(Op->
getType()->isIntegerTy(1) &&
1396 "Intrinsic WaveActiveBallot operand must be a bool");
1400 case Builtin::BI__builtin_hlsl_wave_active_count_bits: {
1402 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveCountBitsIntrinsic();
1404 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID),
1407 case Builtin::BI__builtin_hlsl_wave_active_sum: {
1414 &
CGM.getModule(), IID, {OpExpr->getType()}),
1415 ArrayRef{OpExpr},
"hlsl.wave.active.sum");
1417 case Builtin::BI__builtin_hlsl_wave_active_product: {
1424 &
CGM.getModule(), IID, {OpExpr->getType()}),
1425 ArrayRef{OpExpr},
"hlsl.wave.active.product");
1427 case Builtin::BI__builtin_hlsl_wave_active_max: {
1433 IID =
CGM.getHLSLRuntime().getWaveActiveUMaxIntrinsic();
1435 IID =
CGM.getHLSLRuntime().getWaveActiveMaxIntrinsic();
1438 &
CGM.getModule(), IID, {OpExpr->getType()}),
1439 ArrayRef{OpExpr},
"hlsl.wave.active.max");
1441 case Builtin::BI__builtin_hlsl_wave_active_min: {
1447 IID =
CGM.getHLSLRuntime().getWaveActiveUMinIntrinsic();
1449 IID =
CGM.getHLSLRuntime().getWaveActiveMinIntrinsic();
1452 &
CGM.getModule(), IID, {OpExpr->getType()}),
1453 ArrayRef{OpExpr},
"hlsl.wave.active.min");
1455 case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
1459 switch (
CGM.getTarget().getTriple().getArch()) {
1460 case llvm::Triple::dxil:
1462 &
CGM.getModule(), Intrinsic::dx_wave_getlaneindex));
1463 case llvm::Triple::spirv:
1465 llvm::FunctionType::get(
IntTy, {},
false),
1466 "__hlsl_wave_get_lane_index", {},
false,
true));
1469 "Intrinsic WaveGetLaneIndex not supported by target architecture");
1472 case Builtin::BI__builtin_hlsl_wave_is_first_lane: {
1473 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveIsFirstLaneIntrinsic();
1475 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID));
1477 case Builtin::BI__builtin_hlsl_wave_get_lane_count: {
1478 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveGetLaneCountIntrinsic();
1480 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID));
1482 case Builtin::BI__builtin_hlsl_wave_read_lane_at: {
1488 Intrinsic::getOrInsertDeclaration(
1489 &
CGM.getModule(),
CGM.getHLSLRuntime().getWaveReadLaneAtIntrinsic(),
1490 {OpExpr->getType()}),
1491 ArrayRef{OpExpr, OpIndex},
"hlsl.wave.readlane");
1493 case Builtin::BI__builtin_hlsl_wave_prefix_sum: {
1498 &
CGM.getModule(), IID, {OpExpr->getType()}),
1499 ArrayRef{OpExpr},
"hlsl.wave.prefix.sum");
1501 case Builtin::BI__builtin_hlsl_wave_prefix_product: {
1506 &
CGM.getModule(), IID, {OpExpr->getType()}),
1507 ArrayRef{OpExpr},
"hlsl.wave.prefix.product");
1509 case Builtin::BI__builtin_hlsl_quad_read_across_x: {
1511 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossXIntrinsic();
1513 &
CGM.getModule(), ID, {OpExpr->getType()}),
1514 ArrayRef{OpExpr},
"hlsl.quad.read.across.x");
1516 case Builtin::BI__builtin_hlsl_quad_read_across_y: {
1518 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossYIntrinsic();
1520 &
CGM.getModule(), ID, {OpExpr->getType()}),
1521 ArrayRef{OpExpr},
"hlsl.quad.read.across.y");
1523 case Builtin::BI__builtin_hlsl_elementwise_sign: {
1524 auto *Arg0 = E->
getArg(0);
1526 llvm::Type *Xty = Op0->
getType();
1527 llvm::Type *retType = llvm::Type::getInt32Ty(this->
getLLVMContext());
1528 if (Xty->isVectorTy()) {
1529 auto *XVecTy = Arg0->getType()->castAs<
VectorType>();
1530 retType = llvm::VectorType::get(
1531 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1533 assert((Arg0->getType()->hasFloatingRepresentation() ||
1534 Arg0->getType()->hasIntegerRepresentation()) &&
1535 "sign operand must have a float or int representation");
1537 if (Arg0->getType()->hasUnsignedIntegerRepresentation()) {
1539 return Builder.CreateSelect(
Cmp, ConstantInt::get(retType, 0),
1540 ConstantInt::get(retType, 1),
"hlsl.sign");
1543 return Builder.CreateIntrinsic(
1544 retType,
CGM.getHLSLRuntime().getSignIntrinsic(),
1547 case Builtin::BI__builtin_hlsl_elementwise_radians: {
1550 "radians operand must have a float representation");
1551 return Builder.CreateIntrinsic(
1554 nullptr,
"hlsl.radians");
1556 case Builtin::BI__builtin_hlsl_buffer_update_counter: {
1560 return Builder.CreateIntrinsic(
1562 CGM.getHLSLRuntime().getBufferUpdateCounterIntrinsic(),
1565 case Builtin::BI__builtin_hlsl_elementwise_splitdouble: {
1570 "asuint operands types mismatch");
1573 case Builtin::BI__builtin_hlsl_elementwise_clip:
1575 "clip operands types mismatch");
1577 case Builtin::BI__builtin_hlsl_all_memory_barrier: {
1578 Intrinsic::ID ID =
CGM.getHLSLRuntime().getAllMemoryBarrierIntrinsic();
1580 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID));
1582 case Builtin::BI__builtin_hlsl_all_memory_barrier_with_group_sync: {
1584 CGM.getHLSLRuntime().getAllMemoryBarrierWithGroupSyncIntrinsic();
1586 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID));
1588 case Builtin::BI__builtin_hlsl_device_memory_barrier: {
1589 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDeviceMemoryBarrierIntrinsic();
1591 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID));
1593 case Builtin::BI__builtin_hlsl_device_memory_barrier_with_group_sync: {
1595 CGM.getHLSLRuntime().getDeviceMemoryBarrierWithGroupSyncIntrinsic();
1597 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID));
1599 case Builtin::BI__builtin_hlsl_group_memory_barrier: {
1600 Intrinsic::ID ID =
CGM.getHLSLRuntime().getGroupMemoryBarrierIntrinsic();
1602 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID));
1604 case Builtin::BI__builtin_hlsl_group_memory_barrier_with_group_sync: {
1606 CGM.getHLSLRuntime().getGroupMemoryBarrierWithGroupSyncIntrinsic();
1608 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID));
1610 case Builtin::BI__builtin_hlsl_elementwise_ddx_coarse: {
1613 llvm_unreachable(
"ddx_coarse operand must have a float representation");
1614 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxCoarseIntrinsic();
1619 case Builtin::BI__builtin_hlsl_elementwise_ddy_coarse: {
1622 llvm_unreachable(
"ddy_coarse operand must have a float representation");
1623 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyCoarseIntrinsic();
1628 case Builtin::BI__builtin_hlsl_elementwise_ddx_fine: {
1631 llvm_unreachable(
"ddx_fine operand must have a float representation");
1632 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxFineIntrinsic();
1637 case Builtin::BI__builtin_hlsl_elementwise_ddy_fine: {
1640 llvm_unreachable(
"ddy_fine operand must have a float representation");
1641 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyFineIntrinsic();
1646 case Builtin::BI__builtin_get_spirv_spec_constant_bool:
1647 case Builtin::BI__builtin_get_spirv_spec_constant_short:
1648 case Builtin::BI__builtin_get_spirv_spec_constant_ushort:
1649 case Builtin::BI__builtin_get_spirv_spec_constant_int:
1650 case Builtin::BI__builtin_get_spirv_spec_constant_uint:
1651 case Builtin::BI__builtin_get_spirv_spec_constant_longlong:
1652 case Builtin::BI__builtin_get_spirv_spec_constant_ulonglong:
1653 case Builtin::BI__builtin_get_spirv_spec_constant_half:
1654 case Builtin::BI__builtin_get_spirv_spec_constant_float:
1655 case Builtin::BI__builtin_get_spirv_spec_constant_double: {
1659 llvm::Value *Args[] = {SpecId, DefaultVal};
1660 return Builder.CreateCall(SpecConstantFn, Args);