485 case Builtin::BI__builtin_hlsl_adduint64: {
491 "AddUint64 operand types must match");
493 "AddUint64 operands must have an integer representation");
494 assert((NumElements == 2 || NumElements == 4) &&
495 "AddUint64 operands must have 2 or 4 elements");
503 if (NumElements == 2) {
504 LowA =
Builder.CreateExtractElement(OpA, (uint64_t)0,
"LowA");
505 HighA =
Builder.CreateExtractElement(OpA, (uint64_t)1,
"HighA");
506 LowB =
Builder.CreateExtractElement(OpB, (uint64_t)0,
"LowB");
507 HighB =
Builder.CreateExtractElement(OpB, (uint64_t)1,
"HighB");
509 LowA =
Builder.CreateShuffleVector(OpA, {0, 2},
"LowA");
510 HighA =
Builder.CreateShuffleVector(OpA, {1, 3},
"HighA");
511 LowB =
Builder.CreateShuffleVector(OpB, {0, 2},
"LowB");
512 HighB =
Builder.CreateShuffleVector(OpB, {1, 3},
"HighB");
519 *
this, Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
520 llvm::Value *ZExtCarry =
521 Builder.CreateZExt(Carry, HighA->getType(),
"CarryZExt");
524 llvm::Value *HighSum =
Builder.CreateAdd(HighA, HighB,
"HighSum");
525 llvm::Value *HighSumPlusCarry =
526 Builder.CreateAdd(HighSum, ZExtCarry,
"HighSumPlusCarry");
528 if (NumElements == 4) {
529 return Builder.CreateShuffleVector(LowSum, HighSumPlusCarry, {0, 2, 1, 3},
535 "hlsl.AddUint64.upto0");
540 case Builtin::BI__builtin_hlsl_resource_getpointer:
541 case Builtin::BI__builtin_hlsl_resource_getpointer_typed: {
546 return Builder.CreateIntrinsic(
547 RetTy,
CGM.getHLSLRuntime().getCreateResourceGetPointerIntrinsic(),
550 case Builtin::BI__builtin_hlsl_resource_sample: {
556 Args.push_back(HandleOp);
557 Args.push_back(SamplerOp);
558 Args.push_back(CoordOp);
564 return Builder.CreateIntrinsic(
565 RetTy,
CGM.getHLSLRuntime().getSampleIntrinsic(), Args);
569 return Builder.CreateIntrinsic(
570 RetTy,
CGM.getHLSLRuntime().getSampleClampIntrinsic(), Args);
572 case Builtin::BI__builtin_hlsl_resource_sample_bias: {
581 Args.push_back(HandleOp);
582 Args.push_back(SamplerOp);
583 Args.push_back(CoordOp);
584 Args.push_back(BiasOp);
590 return Builder.CreateIntrinsic(
591 RetTy,
CGM.getHLSLRuntime().getSampleBiasIntrinsic(), Args);
594 return Builder.CreateIntrinsic(
595 RetTy,
CGM.getHLSLRuntime().getSampleBiasClampIntrinsic(), Args);
597 case Builtin::BI__builtin_hlsl_resource_sample_grad: {
605 Args.push_back(HandleOp);
606 Args.push_back(SamplerOp);
607 Args.push_back(CoordOp);
608 Args.push_back(DDXOp);
609 Args.push_back(DDYOp);
616 return Builder.CreateIntrinsic(
617 RetTy,
CGM.getHLSLRuntime().getSampleGradIntrinsic(), Args);
621 return Builder.CreateIntrinsic(
622 RetTy,
CGM.getHLSLRuntime().getSampleGradClampIntrinsic(), Args);
624 case Builtin::BI__builtin_hlsl_resource_sample_level: {
633 Args.push_back(HandleOp);
634 Args.push_back(SamplerOp);
635 Args.push_back(CoordOp);
636 Args.push_back(LODOp);
641 return Builder.CreateIntrinsic(
642 RetTy,
CGM.getHLSLRuntime().getSampleLevelIntrinsic(), Args);
644 case Builtin::BI__builtin_hlsl_resource_load_level: {
649 unsigned NumElts = CoordLODVecTy->getNumElements();
650 assert(NumElts >= 2 &&
"CoordLOD must have at least 2 elements");
654 for (
unsigned I = 0; I < NumElts - 1; ++I)
658 Builder.CreateShuffleVector(CoordLODOp, Mask,
"hlsl.load.coord");
660 Builder.CreateExtractElement(CoordLODOp, NumElts - 1,
"hlsl.load.lod");
663 Args.push_back(HandleOp);
664 Args.push_back(CoordOp);
665 Args.push_back(LODOp);
670 return Builder.CreateIntrinsic(
671 RetTy,
CGM.getHLSLRuntime().getLoadLevelIntrinsic(), Args);
673 case Builtin::BI__builtin_hlsl_resource_sample_cmp: {
682 Args.push_back(HandleOp);
683 Args.push_back(SamplerOp);
684 Args.push_back(CoordOp);
685 Args.push_back(CmpOp);
691 return Builder.CreateIntrinsic(
692 RetTy,
CGM.getHLSLRuntime().getSampleCmpIntrinsic(), Args);
696 return Builder.CreateIntrinsic(
697 RetTy,
CGM.getHLSLRuntime().getSampleCmpClampIntrinsic(), Args);
699 case Builtin::BI__builtin_hlsl_resource_sample_cmp_level_zero: {
708 Args.push_back(HandleOp);
709 Args.push_back(SamplerOp);
710 Args.push_back(CoordOp);
711 Args.push_back(CmpOp);
717 return Builder.CreateIntrinsic(
718 RetTy,
CGM.getHLSLRuntime().getSampleCmpLevelZeroIntrinsic(), Args);
720 case Builtin::BI__builtin_hlsl_resource_gather: {
726 ComponentOp =
Builder.CreateIntCast(ComponentOp,
Builder.getInt32Ty(),
730 Args.push_back(HandleOp);
731 Args.push_back(SamplerOp);
732 Args.push_back(CoordOp);
733 Args.push_back(ComponentOp);
738 return Builder.CreateIntrinsic(
739 RetTy,
CGM.getHLSLRuntime().getGatherIntrinsic(), Args);
741 case Builtin::BI__builtin_hlsl_resource_gather_cmp: {
747 CompareOp =
Builder.CreateFPCast(CompareOp,
Builder.getFloatTy());
750 Args.push_back(HandleOp);
751 Args.push_back(SamplerOp);
752 Args.push_back(CoordOp);
753 Args.push_back(CompareOp);
755 if (
CGM.getTarget().getTriple().isDXIL()) {
758 ComponentOp =
Builder.CreateIntCast(ComponentOp,
Builder.getInt32Ty(),
760 Args.push_back(ComponentOp);
767 return Builder.CreateIntrinsic(
768 RetTy,
CGM.getHLSLRuntime().getGatherCmpIntrinsic(), Args);
770 case Builtin::BI__builtin_hlsl_resource_load_with_status:
771 case Builtin::BI__builtin_hlsl_resource_load_with_status_typed: {
780 const HLSLAttributedResourceType *RT =
781 HandleTy->
getAs<HLSLAttributedResourceType>();
782 assert(
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil &&
783 "Only DXIL currently implements load with status");
785 Intrinsic::ID IntrID = RT->getAttrs().RawBuffer
786 ? llvm::Intrinsic::dx_resource_load_rawbuffer
787 : llvm::Intrinsic::dx_resource_load_typedbuffer;
790 llvm::Type *RetTy = llvm::StructType::get(
Builder.getContext(),
791 {DataTy, Builder.getInt1Ty()});
794 Args.push_back(HandleOp);
795 Args.push_back(IndexOp);
800 if (!RT->isStructured())
801 Offset = llvm::PoisonValue::get(
Builder.getInt32Ty());
802 Args.push_back(Offset);
808 Builder.CreateIntrinsic(RetTy, IntrID, Args, {},
"ld.struct");
809 Value *LoadedValue =
Builder.CreateExtractValue(ResRet, {0},
"ld.value");
810 Value *StatusBit =
Builder.CreateExtractValue(ResRet, {1},
"ld.status");
811 Value *ExtendedStatus =
812 Builder.CreateZExt(StatusBit,
Builder.getInt32Ty(),
"ld.status.ext");
813 Builder.CreateStore(ExtendedStatus, StatusAddr);
817 case Builtin::BI__builtin_hlsl_resource_uninitializedhandle: {
818 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
819 return llvm::PoisonValue::get(HandleTy);
821 case Builtin::BI__builtin_hlsl_resource_handlefrombinding: {
822 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
828 llvm::Intrinsic::ID IntrinsicID =
829 CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic();
831 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
833 case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: {
834 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
840 llvm::Intrinsic::ID IntrinsicID =
841 CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
843 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
845 case Builtin::BI__builtin_hlsl_resource_counterhandlefromimplicitbinding: {
847 if (!
CGM.getTriple().isSPIRV())
850 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
853 llvm::Intrinsic::ID IntrinsicID =
854 llvm::Intrinsic::spv_resource_counterhandlefromimplicitbinding;
856 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
858 case Builtin::BI__builtin_hlsl_resource_nonuniformindex: {
861 return Builder.CreateIntrinsic(
862 RetTy,
CGM.getHLSLRuntime().getNonUniformResourceIndexIntrinsic(),
865 case Builtin::BI__builtin_hlsl_resource_getdimensions_x: {
870 RetTy,
CGM.getHLSLRuntime().getGetDimensionsXIntrinsic(),
872 return Builder.CreateStore(DimValue,
Dim.getAddress());
874 case Builtin::BI__builtin_hlsl_resource_getstride: {
878 case Builtin::BI__builtin_hlsl_all: {
880 return Builder.CreateIntrinsic(
885 case Builtin::BI__builtin_hlsl_and: {
888 return Builder.CreateAnd(Op0, Op1,
"hlsl.and");
890 case Builtin::BI__builtin_hlsl_or: {
893 return Builder.CreateOr(Op0, Op1,
"hlsl.or");
895 case Builtin::BI__builtin_hlsl_any: {
897 return Builder.CreateIntrinsic(
902 case Builtin::BI__builtin_hlsl_asdouble:
904 case Builtin::BI__builtin_hlsl_elementwise_clamp: {
911 Ty = VecTy->getElementType();
915 Intr =
CGM.getHLSLRuntime().getNClampIntrinsic();
917 Intr =
CGM.getHLSLRuntime().getUClampIntrinsic();
920 Intr =
CGM.getHLSLRuntime().getSClampIntrinsic();
922 return Builder.CreateIntrinsic(
926 case Builtin::BI__builtin_hlsl_crossf16:
927 case Builtin::BI__builtin_hlsl_crossf32: {
932 "cross operands must have a float representation");
937 "input vectors must have 3 elements each");
938 return Builder.CreateIntrinsic(
939 Op0->
getType(),
CGM.getHLSLRuntime().getCrossIntrinsic(),
942 case Builtin::BI__builtin_hlsl_dot: {
945 llvm::Type *T0 = Op0->
getType();
946 llvm::Type *T1 = Op1->
getType();
949 if (!T0->isVectorTy() && !T1->isVectorTy()) {
950 if (T0->isFloatingPointTy())
951 return Builder.CreateFMul(Op0, Op1,
"hlsl.dot");
953 if (T0->isIntegerTy())
954 return Builder.CreateMul(Op0, Op1,
"hlsl.dot");
957 "Scalar dot product is only supported on ints and floats.");
962 "Dot product operands must have the same type.");
965 assert(VecTy0 &&
"Dot product argument must be a vector.");
967 return Builder.CreateIntrinsic(
972 case Builtin::BI__builtin_hlsl_dot4add_i8packed: {
977 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddI8PackedIntrinsic();
980 return Builder.CreateIntrinsic(
982 nullptr,
"hlsl.dot4add.i8packed");
984 case Builtin::BI__builtin_hlsl_dot4add_u8packed: {
989 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddU8PackedIntrinsic();
992 return Builder.CreateIntrinsic(
994 nullptr,
"hlsl.dot4add.u8packed");
996 case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
999 return Builder.CreateIntrinsic(
1004 case Builtin::BI__builtin_hlsl_elementwise_firstbitlow: {
1007 return Builder.CreateIntrinsic(
1010 nullptr,
"hlsl.firstbitlow");
1012 case Builtin::BI__builtin_hlsl_lerp: {
1017 llvm_unreachable(
"lerp operand must have a float representation");
1018 return Builder.CreateIntrinsic(
1019 X->getType(),
CGM.getHLSLRuntime().getLerpIntrinsic(),
1022 case Builtin::BI__builtin_hlsl_normalize: {
1026 "normalize operand must have a float representation");
1028 return Builder.CreateIntrinsic(
1031 nullptr,
"hlsl.normalize");
1033 case Builtin::BI__builtin_hlsl_elementwise_degrees: {
1037 "degree operand must have a float representation");
1039 return Builder.CreateIntrinsic(
1040 X->getType(),
CGM.getHLSLRuntime().getDegreesIntrinsic(),
1043 case Builtin::BI__builtin_hlsl_elementwise_f16tof32: {
1046 case Builtin::BI__builtin_hlsl_elementwise_f32tof16: {
1049 case Builtin::BI__builtin_hlsl_elementwise_frac: {
1052 llvm_unreachable(
"frac operand must have a float representation");
1053 return Builder.CreateIntrinsic(
1054 Op0->
getType(),
CGM.getHLSLRuntime().getFracIntrinsic(),
1057 case Builtin::BI__builtin_hlsl_elementwise_isinf: {
1059 llvm::Type *Xty = Op0->
getType();
1060 llvm::Type *retType = llvm::Type::getInt1Ty(this->
getLLVMContext());
1061 if (Xty->isVectorTy()) {
1063 retType = llvm::VectorType::get(
1064 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1067 llvm_unreachable(
"isinf operand must have a float representation");
1068 return Builder.CreateIntrinsic(
1069 retType,
CGM.getHLSLRuntime().getIsInfIntrinsic(),
1072 case Builtin::BI__builtin_hlsl_elementwise_isnan: {
1074 llvm::Type *Xty = Op0->
getType();
1075 llvm::Type *retType = llvm::Type::getInt1Ty(this->
getLLVMContext());
1076 if (Xty->isVectorTy()) {
1078 retType = llvm::VectorType::get(
1079 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1082 llvm_unreachable(
"isnan operand must have a float representation");
1083 return Builder.CreateIntrinsic(
1084 retType,
CGM.getHLSLRuntime().getIsNaNIntrinsic(),
1087 case Builtin::BI__builtin_hlsl_mad: {
1092 return Builder.CreateIntrinsic(
1093 M->
getType(), Intrinsic::fmuladd,
1097 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1098 return Builder.CreateIntrinsic(
1099 M->
getType(), Intrinsic::dx_imad,
1103 return Builder.CreateNSWAdd(Mul, B);
1106 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1107 return Builder.CreateIntrinsic(
1108 M->
getType(), Intrinsic::dx_umad,
1112 return Builder.CreateNUWAdd(Mul, B);
1114 case Builtin::BI__builtin_hlsl_mul: {
1128 bool IsRowMajor =
getLangOpts().getDefaultMatrixMemoryLayout() ==
1131 llvm::MatrixBuilder MB(
Builder);
1132 if (IsVec0 && IsMat1) {
1136 unsigned Cols = MatTy->getNumColumns();
1137 assert(N == Rows &&
"vector length must match matrix row count");
1139 Op1 = MB.CreateRowMajorToColumnMajorTransform(Op1, Rows, Cols);
1140 return MB.CreateMatrixMultiply(Op0, Op1, 1, N, Cols,
"hlsl.mul");
1142 if (IsMat0 && IsVec1) {
1145 unsigned Cols = MatTy->getNumColumns();
1147 "vector length must match matrix column count");
1149 Op0 = MB.CreateRowMajorToColumnMajorTransform(Op0, Rows, Cols);
1150 return MB.CreateMatrixMultiply(Op0, Op1, Rows, Cols, 1,
"hlsl.mul");
1152 assert(IsMat0 && IsMat1);
1157 unsigned Cols0 = MatTy0->getNumColumns();
1159 assert(Cols0 == Rows1 &&
1160 "inner matrix dimensions must match for multiplication");
1162 Op0 = MB.CreateRowMajorToColumnMajorTransform(Op0, Rows0, Cols0);
1163 Op1 = MB.CreateRowMajorToColumnMajorTransform(Op1, Rows1, Cols1);
1166 MB.CreateMatrixMultiply(Op0, Op1, Rows0, Cols0, Cols1,
"hlsl.mul");
1168 Result = MB.CreateColumnMajorToRowMajorTransform(
Result, Rows0, Cols1);
1171 case Builtin::BI__builtin_hlsl_transpose: {
1175 unsigned Cols = MatTy->getNumColumns();
1176 llvm::MatrixBuilder MB(
Builder);
1181 bool IsRowMajor =
getLangOpts().getDefaultMatrixMemoryLayout() ==
1184 return MB.CreateMatrixTranspose(Op0, Cols, Rows);
1185 return MB.CreateMatrixTranspose(Op0, Rows, Cols);
1187 case Builtin::BI__builtin_hlsl_elementwise_rcp: {
1190 llvm_unreachable(
"rcp operand must have a float representation");
1191 llvm::Type *Ty = Op0->
getType();
1192 llvm::Type *EltTy = Ty->getScalarType();
1193 Constant *One = Ty->isVectorTy()
1194 ? ConstantVector::getSplat(
1195 ElementCount::getFixed(
1197 ConstantFP::get(EltTy, 1.0))
1198 : ConstantFP::get(EltTy, 1.0);
1199 return Builder.CreateFDiv(One, Op0,
"hlsl.rcp");
1201 case Builtin::BI__builtin_hlsl_elementwise_rsqrt: {
1204 llvm_unreachable(
"rsqrt operand must have a float representation");
1205 return Builder.CreateIntrinsic(
1206 Op0->
getType(),
CGM.getHLSLRuntime().getRsqrtIntrinsic(),
1209 case Builtin::BI__builtin_hlsl_elementwise_saturate: {
1212 "saturate operand must have a float representation");
1213 return Builder.CreateIntrinsic(
1216 nullptr,
"hlsl.saturate");
1218 case Builtin::BI__builtin_hlsl_wave_prefix_count_bits: {
1220 assert(Op->
getType()->isIntegerTy(1) &&
1221 "WavePrefixBitCount operand must be a boolean type");
1227 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), IID),
ArrayRef{Op},
1228 "hlsl.wave.prefix.bit.count");
1230 case Builtin::BI__builtin_hlsl_select: {
1243 if (!OpTrue->
getType()->isVectorTy())
1245 Builder.CreateVectorSplat(VTy->getNumElements(), OpTrue,
"splat");
1246 if (!OpFalse->
getType()->isVectorTy())
1248 Builder.CreateVectorSplat(VTy->getNumElements(), OpFalse,
"splat");
1252 Builder.CreateSelect(OpCond, OpTrue, OpFalse,
"hlsl.select");
1259 case Builtin::BI__builtin_hlsl_step: {
1264 "step operands must have a float representation");
1265 return Builder.CreateIntrinsic(
1266 Op0->
getType(),
CGM.getHLSLRuntime().getStepIntrinsic(),
1269 case Builtin::BI__builtin_hlsl_wave_active_all_equal: {
1272 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllEqualIntrinsic();
1274 &
CGM.getModule(), ID, {Op->getType()}),
1277 case Builtin::BI__builtin_hlsl_wave_active_all_true: {
1279 assert(Op->
getType()->isIntegerTy(1) &&
1280 "Intrinsic WaveActiveAllTrue operand must be a bool");
1282 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllTrueIntrinsic();
1284 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID), {Op});
1286 case Builtin::BI__builtin_hlsl_wave_active_any_true: {
1288 assert(Op->
getType()->isIntegerTy(1) &&
1289 "Intrinsic WaveActiveAnyTrue operand must be a bool");
1291 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic();
1293 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID), {Op});
1295 case Builtin::BI__builtin_hlsl_wave_active_bit_or: {
1298 "Intrinsic WaveActiveBitOr operand must have an unsigned integer "
1301 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitOrIntrinsic();
1303 &
CGM.getModule(), ID, {Op->getType()}),
1304 ArrayRef{Op},
"hlsl.wave.active.bit.or");
1306 case Builtin::BI__builtin_hlsl_wave_active_bit_xor: {
1309 "Intrinsic WaveActiveBitXor operand must have an unsigned integer "
1312 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitXorIntrinsic();
1314 &
CGM.getModule(), ID, {Op->getType()}),
1315 ArrayRef{Op},
"hlsl.wave.active.bit.xor");
1317 case Builtin::BI__builtin_hlsl_wave_active_bit_and: {
1320 "Intrinsic WaveActiveBitAnd operand must have an unsigned integer "
1323 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitAndIntrinsic();
1325 &
CGM.getModule(), ID, {Op->getType()}),
1326 ArrayRef{Op},
"hlsl.wave.active.bit.and");
1328 case Builtin::BI__builtin_hlsl_wave_active_ballot: {
1330 assert(Op->
getType()->isIntegerTy(1) &&
1331 "Intrinsic WaveActiveBallot operand must be a bool");
1335 case Builtin::BI__builtin_hlsl_wave_active_count_bits: {
1337 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveCountBitsIntrinsic();
1339 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID),
1342 case Builtin::BI__builtin_hlsl_wave_active_sum: {
1349 &
CGM.getModule(), IID, {OpExpr->getType()}),
1350 ArrayRef{OpExpr},
"hlsl.wave.active.sum");
1352 case Builtin::BI__builtin_hlsl_wave_active_product: {
1359 &
CGM.getModule(), IID, {OpExpr->getType()}),
1360 ArrayRef{OpExpr},
"hlsl.wave.active.product");
1362 case Builtin::BI__builtin_hlsl_wave_active_max: {
1368 IID =
CGM.getHLSLRuntime().getWaveActiveUMaxIntrinsic();
1370 IID =
CGM.getHLSLRuntime().getWaveActiveMaxIntrinsic();
1373 &
CGM.getModule(), IID, {OpExpr->getType()}),
1374 ArrayRef{OpExpr},
"hlsl.wave.active.max");
1376 case Builtin::BI__builtin_hlsl_wave_active_min: {
1382 IID =
CGM.getHLSLRuntime().getWaveActiveUMinIntrinsic();
1384 IID =
CGM.getHLSLRuntime().getWaveActiveMinIntrinsic();
1387 &
CGM.getModule(), IID, {OpExpr->getType()}),
1388 ArrayRef{OpExpr},
"hlsl.wave.active.min");
1390 case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
1394 switch (
CGM.getTarget().getTriple().getArch()) {
1395 case llvm::Triple::dxil:
1397 &
CGM.getModule(), Intrinsic::dx_wave_getlaneindex));
1398 case llvm::Triple::spirv:
1400 llvm::FunctionType::get(
IntTy, {},
false),
1401 "__hlsl_wave_get_lane_index", {},
false,
true));
1404 "Intrinsic WaveGetLaneIndex not supported by target architecture");
1407 case Builtin::BI__builtin_hlsl_wave_is_first_lane: {
1408 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveIsFirstLaneIntrinsic();
1410 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID));
1412 case Builtin::BI__builtin_hlsl_wave_get_lane_count: {
1413 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveGetLaneCountIntrinsic();
1415 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID));
1417 case Builtin::BI__builtin_hlsl_wave_read_lane_at: {
1423 Intrinsic::getOrInsertDeclaration(
1424 &
CGM.getModule(),
CGM.getHLSLRuntime().getWaveReadLaneAtIntrinsic(),
1425 {OpExpr->getType()}),
1426 ArrayRef{OpExpr, OpIndex},
"hlsl.wave.readlane");
1428 case Builtin::BI__builtin_hlsl_wave_prefix_sum: {
1433 &
CGM.getModule(), IID, {OpExpr->getType()}),
1434 ArrayRef{OpExpr},
"hlsl.wave.prefix.sum");
1436 case Builtin::BI__builtin_hlsl_wave_prefix_product: {
1441 &
CGM.getModule(), IID, {OpExpr->getType()}),
1442 ArrayRef{OpExpr},
"hlsl.wave.prefix.product");
1444 case Builtin::BI__builtin_hlsl_quad_read_across_x: {
1446 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossXIntrinsic();
1448 &
CGM.getModule(), ID, {OpExpr->getType()}),
1449 ArrayRef{OpExpr},
"hlsl.quad.read.across.x");
1451 case Builtin::BI__builtin_hlsl_quad_read_across_y: {
1453 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossYIntrinsic();
1455 &
CGM.getModule(), ID, {OpExpr->getType()}),
1456 ArrayRef{OpExpr},
"hlsl.quad.read.across.y");
1458 case Builtin::BI__builtin_hlsl_elementwise_sign: {
1459 auto *Arg0 = E->
getArg(0);
1461 llvm::Type *Xty = Op0->
getType();
1462 llvm::Type *retType = llvm::Type::getInt32Ty(this->
getLLVMContext());
1463 if (Xty->isVectorTy()) {
1464 auto *XVecTy = Arg0->getType()->castAs<
VectorType>();
1465 retType = llvm::VectorType::get(
1466 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1468 assert((Arg0->getType()->hasFloatingRepresentation() ||
1469 Arg0->getType()->hasIntegerRepresentation()) &&
1470 "sign operand must have a float or int representation");
1472 if (Arg0->getType()->hasUnsignedIntegerRepresentation()) {
1474 return Builder.CreateSelect(
Cmp, ConstantInt::get(retType, 0),
1475 ConstantInt::get(retType, 1),
"hlsl.sign");
1478 return Builder.CreateIntrinsic(
1479 retType,
CGM.getHLSLRuntime().getSignIntrinsic(),
1482 case Builtin::BI__builtin_hlsl_elementwise_radians: {
1485 "radians operand must have a float representation");
1486 return Builder.CreateIntrinsic(
1489 nullptr,
"hlsl.radians");
1491 case Builtin::BI__builtin_hlsl_buffer_update_counter: {
1495 return Builder.CreateIntrinsic(
1497 CGM.getHLSLRuntime().getBufferUpdateCounterIntrinsic(),
1500 case Builtin::BI__builtin_hlsl_elementwise_splitdouble: {
1505 "asuint operands types mismatch");
1508 case Builtin::BI__builtin_hlsl_elementwise_clip:
1510 "clip operands types mismatch");
1512 case Builtin::BI__builtin_hlsl_group_memory_barrier: {
1513 Intrinsic::ID ID =
CGM.getHLSLRuntime().getGroupMemoryBarrierIntrinsic();
1515 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID));
1517 case Builtin::BI__builtin_hlsl_group_memory_barrier_with_group_sync: {
1519 CGM.getHLSLRuntime().getGroupMemoryBarrierWithGroupSyncIntrinsic();
1521 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID));
1523 case Builtin::BI__builtin_hlsl_elementwise_ddx_coarse: {
1526 llvm_unreachable(
"ddx_coarse operand must have a float representation");
1527 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxCoarseIntrinsic();
1532 case Builtin::BI__builtin_hlsl_elementwise_ddy_coarse: {
1535 llvm_unreachable(
"ddy_coarse operand must have a float representation");
1536 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyCoarseIntrinsic();
1541 case Builtin::BI__builtin_hlsl_elementwise_ddx_fine: {
1544 llvm_unreachable(
"ddx_fine operand must have a float representation");
1545 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxFineIntrinsic();
1550 case Builtin::BI__builtin_hlsl_elementwise_ddy_fine: {
1553 llvm_unreachable(
"ddy_fine operand must have a float representation");
1554 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyFineIntrinsic();
1559 case Builtin::BI__builtin_get_spirv_spec_constant_bool:
1560 case Builtin::BI__builtin_get_spirv_spec_constant_short:
1561 case Builtin::BI__builtin_get_spirv_spec_constant_ushort:
1562 case Builtin::BI__builtin_get_spirv_spec_constant_int:
1563 case Builtin::BI__builtin_get_spirv_spec_constant_uint:
1564 case Builtin::BI__builtin_get_spirv_spec_constant_longlong:
1565 case Builtin::BI__builtin_get_spirv_spec_constant_ulonglong:
1566 case Builtin::BI__builtin_get_spirv_spec_constant_half:
1567 case Builtin::BI__builtin_get_spirv_spec_constant_float:
1568 case Builtin::BI__builtin_get_spirv_spec_constant_double: {
1572 llvm::Value *Args[] = {SpecId, DefaultVal};
1573 return Builder.CreateCall(SpecConstantFn, Args);