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: {
577 return Builder.CreateIntrinsic(
578 RetTy,
CGM.getHLSLRuntime().getCreateResourceGetPointerIntrinsic(),
581 case Builtin::BI__builtin_hlsl_resource_sample: {
587 Args.push_back(HandleOp);
588 Args.push_back(SamplerOp);
589 Args.push_back(CoordOp);
595 return Builder.CreateIntrinsic(
596 RetTy,
CGM.getHLSLRuntime().getSampleIntrinsic(), Args);
600 return Builder.CreateIntrinsic(
601 RetTy,
CGM.getHLSLRuntime().getSampleClampIntrinsic(), Args);
603 case Builtin::BI__builtin_hlsl_resource_sample_bias: {
612 Args.push_back(HandleOp);
613 Args.push_back(SamplerOp);
614 Args.push_back(CoordOp);
615 Args.push_back(BiasOp);
621 return Builder.CreateIntrinsic(
622 RetTy,
CGM.getHLSLRuntime().getSampleBiasIntrinsic(), Args);
625 return Builder.CreateIntrinsic(
626 RetTy,
CGM.getHLSLRuntime().getSampleBiasClampIntrinsic(), Args);
628 case Builtin::BI__builtin_hlsl_resource_sample_grad: {
636 Args.push_back(HandleOp);
637 Args.push_back(SamplerOp);
638 Args.push_back(CoordOp);
639 Args.push_back(DDXOp);
640 Args.push_back(DDYOp);
647 return Builder.CreateIntrinsic(
648 RetTy,
CGM.getHLSLRuntime().getSampleGradIntrinsic(), Args);
652 return Builder.CreateIntrinsic(
653 RetTy,
CGM.getHLSLRuntime().getSampleGradClampIntrinsic(), Args);
655 case Builtin::BI__builtin_hlsl_resource_sample_level: {
664 Args.push_back(HandleOp);
665 Args.push_back(SamplerOp);
666 Args.push_back(CoordOp);
667 Args.push_back(LODOp);
672 return Builder.CreateIntrinsic(
673 RetTy,
CGM.getHLSLRuntime().getSampleLevelIntrinsic(), Args);
675 case Builtin::BI__builtin_hlsl_resource_load_level: {
680 unsigned NumElts = CoordLODVecTy->getNumElements();
681 assert(NumElts >= 2 &&
"CoordLOD must have at least 2 elements");
685 for (
unsigned I = 0; I < NumElts - 1; ++I)
689 Builder.CreateShuffleVector(CoordLODOp, Mask,
"hlsl.load.coord");
691 Builder.CreateExtractElement(CoordLODOp, NumElts - 1,
"hlsl.load.lod");
694 Args.push_back(HandleOp);
695 Args.push_back(CoordOp);
696 Args.push_back(LODOp);
701 return Builder.CreateIntrinsic(
702 RetTy,
CGM.getHLSLRuntime().getLoadLevelIntrinsic(), Args);
704 case Builtin::BI__builtin_hlsl_resource_sample_cmp: {
713 Args.push_back(HandleOp);
714 Args.push_back(SamplerOp);
715 Args.push_back(CoordOp);
716 Args.push_back(CmpOp);
722 return Builder.CreateIntrinsic(
723 RetTy,
CGM.getHLSLRuntime().getSampleCmpIntrinsic(), Args);
727 return Builder.CreateIntrinsic(
728 RetTy,
CGM.getHLSLRuntime().getSampleCmpClampIntrinsic(), Args);
730 case Builtin::BI__builtin_hlsl_resource_sample_cmp_level_zero: {
739 Args.push_back(HandleOp);
740 Args.push_back(SamplerOp);
741 Args.push_back(CoordOp);
742 Args.push_back(CmpOp);
748 return Builder.CreateIntrinsic(
749 RetTy,
CGM.getHLSLRuntime().getSampleCmpLevelZeroIntrinsic(), Args);
751 case Builtin::BI__builtin_hlsl_resource_calculate_lod: {
756 return Builder.CreateIntrinsic(
758 CGM.getHLSLRuntime().getCalculateLodIntrinsic(),
759 {HandleOp, SamplerOp, CoordOp});
761 case Builtin::BI__builtin_hlsl_resource_calculate_lod_unclamped: {
766 return Builder.CreateIntrinsic(
768 CGM.getHLSLRuntime().getCalculateLodUnclampedIntrinsic(),
769 {HandleOp, SamplerOp, CoordOp});
771 case Builtin::BI__builtin_hlsl_resource_gather: {
777 ComponentOp =
Builder.CreateIntCast(ComponentOp,
Builder.getInt32Ty(),
781 Args.push_back(HandleOp);
782 Args.push_back(SamplerOp);
783 Args.push_back(CoordOp);
784 Args.push_back(ComponentOp);
789 return Builder.CreateIntrinsic(
790 RetTy,
CGM.getHLSLRuntime().getGatherIntrinsic(), Args);
792 case Builtin::BI__builtin_hlsl_resource_gather_cmp: {
798 CompareOp =
Builder.CreateFPCast(CompareOp,
Builder.getFloatTy());
801 Args.push_back(HandleOp);
802 Args.push_back(SamplerOp);
803 Args.push_back(CoordOp);
804 Args.push_back(CompareOp);
806 if (
CGM.getTarget().getTriple().isDXIL()) {
809 ComponentOp =
Builder.CreateIntCast(ComponentOp,
Builder.getInt32Ty(),
811 Args.push_back(ComponentOp);
818 return Builder.CreateIntrinsic(
819 RetTy,
CGM.getHLSLRuntime().getGatherCmpIntrinsic(), Args);
821 case Builtin::BI__builtin_hlsl_resource_load_with_status:
822 case Builtin::BI__builtin_hlsl_resource_load_with_status_typed: {
831 const HLSLAttributedResourceType *RT =
832 HandleTy->
getAs<HLSLAttributedResourceType>();
833 assert(
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil &&
834 "Only DXIL currently implements load with status");
836 Intrinsic::ID IntrID = RT->getAttrs().RawBuffer
837 ? llvm::Intrinsic::dx_resource_load_rawbuffer
838 : llvm::Intrinsic::dx_resource_load_typedbuffer;
841 llvm::Type *RetTy = llvm::StructType::get(
Builder.getContext(),
842 {DataTy, Builder.getInt1Ty()});
845 Args.push_back(HandleOp);
846 Args.push_back(IndexOp);
851 if (!RT->isStructured())
852 Offset = llvm::PoisonValue::get(
Builder.getInt32Ty());
853 Args.push_back(Offset);
859 Builder.CreateIntrinsic(RetTy, IntrID, Args, {},
"ld.struct");
860 Value *LoadedValue =
Builder.CreateExtractValue(ResRet, {0},
"ld.value");
861 Value *StatusBit =
Builder.CreateExtractValue(ResRet, {1},
"ld.status");
862 Value *ExtendedStatus =
863 Builder.CreateZExt(StatusBit,
Builder.getInt32Ty(),
"ld.status.ext");
864 Builder.CreateStore(ExtendedStatus, StatusAddr);
868 case Builtin::BI__builtin_hlsl_resource_uninitializedhandle: {
869 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
870 return llvm::PoisonValue::get(HandleTy);
872 case Builtin::BI__builtin_hlsl_resource_handlefrombinding: {
873 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
879 llvm::Intrinsic::ID IntrinsicID =
880 CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic();
882 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
884 case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: {
885 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
891 llvm::Intrinsic::ID IntrinsicID =
892 CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
894 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
896 case Builtin::BI__builtin_hlsl_resource_counterhandlefromimplicitbinding: {
898 if (!
CGM.getTriple().isSPIRV())
901 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
904 llvm::Intrinsic::ID IntrinsicID =
905 llvm::Intrinsic::spv_resource_counterhandlefromimplicitbinding;
907 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
909 case Builtin::BI__builtin_hlsl_resource_nonuniformindex: {
912 return Builder.CreateIntrinsic(
913 RetTy,
CGM.getHLSLRuntime().getNonUniformResourceIndexIntrinsic(),
916 case Builtin::BI__builtin_hlsl_resource_getdimensions_x:
917 case Builtin::BI__builtin_hlsl_resource_getdimensions_x_float:
919 CGM.getHLSLRuntime().getGetDimensionsXIntrinsic(),
921 case Builtin::BI__builtin_hlsl_resource_getdimensions_xy:
922 case Builtin::BI__builtin_hlsl_resource_getdimensions_xy_float:
924 CGM.getHLSLRuntime().getGetDimensionsXYIntrinsic(),
926 case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy:
927 case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy_float:
929 *
this, E,
CGM.getHLSLRuntime().getGetDimensionsLevelsXYIntrinsic(), 3,
931 case Builtin::BI__builtin_hlsl_resource_getstride: {
935 case Builtin::BI__builtin_hlsl_all: {
937 return Builder.CreateIntrinsic(
942 case Builtin::BI__builtin_hlsl_and: {
945 return Builder.CreateAnd(Op0, Op1,
"hlsl.and");
947 case Builtin::BI__builtin_hlsl_or: {
950 return Builder.CreateOr(Op0, Op1,
"hlsl.or");
952 case Builtin::BI__builtin_hlsl_any: {
954 return Builder.CreateIntrinsic(
959 case Builtin::BI__builtin_hlsl_asdouble:
961 case Builtin::BI__builtin_hlsl_elementwise_clamp: {
968 Ty = VecTy->getElementType();
972 Intr =
CGM.getHLSLRuntime().getNClampIntrinsic();
974 Intr =
CGM.getHLSLRuntime().getUClampIntrinsic();
977 Intr =
CGM.getHLSLRuntime().getSClampIntrinsic();
979 return Builder.CreateIntrinsic(
983 case Builtin::BI__builtin_hlsl_crossf16:
984 case Builtin::BI__builtin_hlsl_crossf32: {
989 "cross operands must have a float representation");
994 "input vectors must have 3 elements each");
995 return Builder.CreateIntrinsic(
996 Op0->
getType(),
CGM.getHLSLRuntime().getCrossIntrinsic(),
999 case Builtin::BI__builtin_hlsl_dot: {
1002 llvm::Type *T0 = Op0->
getType();
1003 llvm::Type *T1 = Op1->
getType();
1006 if (!T0->isVectorTy() && !T1->isVectorTy()) {
1007 if (T0->isFloatingPointTy())
1008 return Builder.CreateFMul(Op0, Op1,
"hlsl.dot");
1010 if (T0->isIntegerTy())
1011 return Builder.CreateMul(Op0, Op1,
"hlsl.dot");
1014 "Scalar dot product is only supported on ints and floats.");
1019 "Dot product operands must have the same type.");
1022 assert(VecTy0 &&
"Dot product argument must be a vector.");
1024 return Builder.CreateIntrinsic(
1025 T0->getScalarType(),
1029 case Builtin::BI__builtin_hlsl_dot4add_i8packed: {
1034 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddI8PackedIntrinsic();
1037 return Builder.CreateIntrinsic(
1039 nullptr,
"hlsl.dot4add.i8packed");
1041 case Builtin::BI__builtin_hlsl_dot4add_u8packed: {
1046 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddU8PackedIntrinsic();
1049 return Builder.CreateIntrinsic(
1051 nullptr,
"hlsl.dot4add.u8packed");
1053 case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
1056 return Builder.CreateIntrinsic(
1061 case Builtin::BI__builtin_hlsl_elementwise_firstbitlow: {
1064 return Builder.CreateIntrinsic(
1067 nullptr,
"hlsl.firstbitlow");
1069 case Builtin::BI__builtin_hlsl_lerp: {
1074 llvm_unreachable(
"lerp operand must have a float representation");
1075 return Builder.CreateIntrinsic(
1076 X->getType(),
CGM.getHLSLRuntime().getLerpIntrinsic(),
1079 case Builtin::BI__builtin_hlsl_normalize: {
1083 "normalize operand must have a float representation");
1085 return Builder.CreateIntrinsic(
1088 nullptr,
"hlsl.normalize");
1090 case Builtin::BI__builtin_hlsl_elementwise_degrees: {
1094 "degree operand must have a float representation");
1096 return Builder.CreateIntrinsic(
1097 X->getType(),
CGM.getHLSLRuntime().getDegreesIntrinsic(),
1100 case Builtin::BI__builtin_hlsl_elementwise_f16tof32: {
1103 case Builtin::BI__builtin_hlsl_elementwise_f32tof16: {
1106 case Builtin::BI__builtin_hlsl_elementwise_frac: {
1109 llvm_unreachable(
"frac operand must have a float representation");
1110 return Builder.CreateIntrinsic(
1111 Op0->
getType(),
CGM.getHLSLRuntime().getFracIntrinsic(),
1114 case Builtin::BI__builtin_hlsl_elementwise_isinf: {
1116 llvm::Type *Xty = Op0->
getType();
1117 llvm::Type *retType = llvm::Type::getInt1Ty(this->
getLLVMContext());
1118 if (Xty->isVectorTy()) {
1120 retType = llvm::VectorType::get(
1121 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1124 llvm_unreachable(
"isinf operand must have a float representation");
1125 return Builder.CreateIntrinsic(
1126 retType,
CGM.getHLSLRuntime().getIsInfIntrinsic(),
1129 case Builtin::BI__builtin_hlsl_elementwise_isnan: {
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(
"isnan operand must have a float representation");
1140 return Builder.CreateIntrinsic(
1141 retType,
CGM.getHLSLRuntime().getIsNaNIntrinsic(),
1144 case Builtin::BI__builtin_hlsl_mad: {
1149 return Builder.CreateIntrinsic(
1150 M->
getType(), Intrinsic::fmuladd,
1154 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1155 return Builder.CreateIntrinsic(
1156 M->
getType(), Intrinsic::dx_imad,
1160 return Builder.CreateNSWAdd(Mul, B);
1163 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1164 return Builder.CreateIntrinsic(
1165 M->
getType(), Intrinsic::dx_umad,
1169 return Builder.CreateNUWAdd(Mul, B);
1171 case Builtin::BI__builtin_hlsl_mul: {
1185 bool IsRowMajor =
getLangOpts().getDefaultMatrixMemoryLayout() ==
1188 llvm::MatrixBuilder MB(
Builder);
1189 if (IsVec0 && IsMat1) {
1193 unsigned Cols = MatTy->getNumColumns();
1194 assert(N == Rows &&
"vector length must match matrix row count");
1196 Op1 = MB.CreateRowMajorToColumnMajorTransform(Op1, Rows, Cols);
1197 return MB.CreateMatrixMultiply(Op0, Op1, 1, N, Cols,
"hlsl.mul");
1199 if (IsMat0 && IsVec1) {
1202 unsigned Cols = MatTy->getNumColumns();
1204 "vector length must match matrix column count");
1206 Op0 = MB.CreateRowMajorToColumnMajorTransform(Op0, Rows, Cols);
1207 return MB.CreateMatrixMultiply(Op0, Op1, Rows, Cols, 1,
"hlsl.mul");
1209 assert(IsMat0 && IsMat1);
1214 unsigned Cols0 = MatTy0->getNumColumns();
1216 assert(Cols0 == Rows1 &&
1217 "inner matrix dimensions must match for multiplication");
1219 Op0 = MB.CreateRowMajorToColumnMajorTransform(Op0, Rows0, Cols0);
1220 Op1 = MB.CreateRowMajorToColumnMajorTransform(Op1, Rows1, Cols1);
1223 MB.CreateMatrixMultiply(Op0, Op1, Rows0, Cols0, Cols1,
"hlsl.mul");
1225 Result = MB.CreateColumnMajorToRowMajorTransform(
Result, Rows0, Cols1);
1228 case Builtin::BI__builtin_hlsl_transpose: {
1232 unsigned Cols = MatTy->getNumColumns();
1233 llvm::MatrixBuilder MB(
Builder);
1238 bool IsRowMajor =
getLangOpts().getDefaultMatrixMemoryLayout() ==
1241 return MB.CreateMatrixTranspose(Op0, Cols, Rows);
1242 return MB.CreateMatrixTranspose(Op0, Rows, Cols);
1244 case Builtin::BI__builtin_hlsl_elementwise_rcp: {
1247 llvm_unreachable(
"rcp operand must have a float representation");
1248 llvm::Type *Ty = Op0->
getType();
1249 llvm::Type *EltTy = Ty->getScalarType();
1250 Constant *One = Ty->isVectorTy()
1251 ? ConstantVector::getSplat(
1252 ElementCount::getFixed(
1254 ConstantFP::get(EltTy, 1.0))
1255 : ConstantFP::get(EltTy, 1.0);
1256 return Builder.CreateFDiv(One, Op0,
"hlsl.rcp");
1258 case Builtin::BI__builtin_hlsl_elementwise_rsqrt: {
1261 llvm_unreachable(
"rsqrt operand must have a float representation");
1262 return Builder.CreateIntrinsic(
1263 Op0->
getType(),
CGM.getHLSLRuntime().getRsqrtIntrinsic(),
1266 case Builtin::BI__builtin_hlsl_elementwise_saturate: {
1269 "saturate operand must have a float representation");
1270 return Builder.CreateIntrinsic(
1273 nullptr,
"hlsl.saturate");
1275 case Builtin::BI__builtin_hlsl_wave_prefix_count_bits: {
1277 assert(Op->
getType()->isIntegerTy(1) &&
1278 "WavePrefixBitCount operand must be a boolean type");
1284 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), IID),
ArrayRef{Op},
1285 "hlsl.wave.prefix.bit.count");
1287 case Builtin::BI__builtin_hlsl_select: {
1300 if (!OpTrue->
getType()->isVectorTy())
1302 Builder.CreateVectorSplat(VTy->getNumElements(), OpTrue,
"splat");
1303 if (!OpFalse->
getType()->isVectorTy())
1305 Builder.CreateVectorSplat(VTy->getNumElements(), OpFalse,
"splat");
1309 Builder.CreateSelect(OpCond, OpTrue, OpFalse,
"hlsl.select");
1316 case Builtin::BI__builtin_hlsl_step: {
1321 "step operands must have a float representation");
1322 return Builder.CreateIntrinsic(
1323 Op0->
getType(),
CGM.getHLSLRuntime().getStepIntrinsic(),
1326 case Builtin::BI__builtin_hlsl_wave_active_all_equal: {
1329 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllEqualIntrinsic();
1331 &
CGM.getModule(), ID, {Op->getType()}),
1334 case Builtin::BI__builtin_hlsl_wave_active_all_true: {
1336 assert(Op->
getType()->isIntegerTy(1) &&
1337 "Intrinsic WaveActiveAllTrue operand must be a bool");
1339 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllTrueIntrinsic();
1341 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID), {Op});
1343 case Builtin::BI__builtin_hlsl_wave_active_any_true: {
1345 assert(Op->
getType()->isIntegerTy(1) &&
1346 "Intrinsic WaveActiveAnyTrue operand must be a bool");
1348 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic();
1350 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID), {Op});
1352 case Builtin::BI__builtin_hlsl_wave_active_bit_or: {
1355 "Intrinsic WaveActiveBitOr operand must have an unsigned integer "
1358 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitOrIntrinsic();
1360 &
CGM.getModule(), ID, {Op->getType()}),
1361 ArrayRef{Op},
"hlsl.wave.active.bit.or");
1363 case Builtin::BI__builtin_hlsl_wave_active_bit_xor: {
1366 "Intrinsic WaveActiveBitXor operand must have an unsigned integer "
1369 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitXorIntrinsic();
1371 &
CGM.getModule(), ID, {Op->getType()}),
1372 ArrayRef{Op},
"hlsl.wave.active.bit.xor");
1374 case Builtin::BI__builtin_hlsl_wave_active_bit_and: {
1377 "Intrinsic WaveActiveBitAnd operand must have an unsigned integer "
1380 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitAndIntrinsic();
1382 &
CGM.getModule(), ID, {Op->getType()}),
1383 ArrayRef{Op},
"hlsl.wave.active.bit.and");
1385 case Builtin::BI__builtin_hlsl_wave_active_ballot: {
1387 assert(Op->
getType()->isIntegerTy(1) &&
1388 "Intrinsic WaveActiveBallot operand must be a bool");
1392 case Builtin::BI__builtin_hlsl_wave_active_count_bits: {
1394 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveCountBitsIntrinsic();
1396 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID),
1399 case Builtin::BI__builtin_hlsl_wave_active_sum: {
1406 &
CGM.getModule(), IID, {OpExpr->getType()}),
1407 ArrayRef{OpExpr},
"hlsl.wave.active.sum");
1409 case Builtin::BI__builtin_hlsl_wave_active_product: {
1416 &
CGM.getModule(), IID, {OpExpr->getType()}),
1417 ArrayRef{OpExpr},
"hlsl.wave.active.product");
1419 case Builtin::BI__builtin_hlsl_wave_active_max: {
1425 IID =
CGM.getHLSLRuntime().getWaveActiveUMaxIntrinsic();
1427 IID =
CGM.getHLSLRuntime().getWaveActiveMaxIntrinsic();
1430 &
CGM.getModule(), IID, {OpExpr->getType()}),
1431 ArrayRef{OpExpr},
"hlsl.wave.active.max");
1433 case Builtin::BI__builtin_hlsl_wave_active_min: {
1439 IID =
CGM.getHLSLRuntime().getWaveActiveUMinIntrinsic();
1441 IID =
CGM.getHLSLRuntime().getWaveActiveMinIntrinsic();
1444 &
CGM.getModule(), IID, {OpExpr->getType()}),
1445 ArrayRef{OpExpr},
"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 &
CGM.getModule(), Intrinsic::dx_wave_getlaneindex));
1455 case llvm::Triple::spirv:
1457 llvm::FunctionType::get(
IntTy, {},
false),
1458 "__hlsl_wave_get_lane_index", {},
false,
true));
1461 "Intrinsic WaveGetLaneIndex not supported by target architecture");
1464 case Builtin::BI__builtin_hlsl_wave_is_first_lane: {
1465 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveIsFirstLaneIntrinsic();
1467 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID));
1469 case Builtin::BI__builtin_hlsl_wave_get_lane_count: {
1470 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveGetLaneCountIntrinsic();
1472 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID));
1474 case Builtin::BI__builtin_hlsl_wave_read_lane_at: {
1480 Intrinsic::getOrInsertDeclaration(
1481 &
CGM.getModule(),
CGM.getHLSLRuntime().getWaveReadLaneAtIntrinsic(),
1482 {OpExpr->getType()}),
1483 ArrayRef{OpExpr, OpIndex},
"hlsl.wave.readlane");
1485 case Builtin::BI__builtin_hlsl_wave_prefix_sum: {
1490 &
CGM.getModule(), IID, {OpExpr->getType()}),
1491 ArrayRef{OpExpr},
"hlsl.wave.prefix.sum");
1493 case Builtin::BI__builtin_hlsl_wave_prefix_product: {
1498 &
CGM.getModule(), IID, {OpExpr->getType()}),
1499 ArrayRef{OpExpr},
"hlsl.wave.prefix.product");
1501 case Builtin::BI__builtin_hlsl_quad_read_across_x: {
1503 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossXIntrinsic();
1505 &
CGM.getModule(), ID, {OpExpr->getType()}),
1506 ArrayRef{OpExpr},
"hlsl.quad.read.across.x");
1508 case Builtin::BI__builtin_hlsl_quad_read_across_y: {
1510 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossYIntrinsic();
1512 &
CGM.getModule(), ID, {OpExpr->getType()}),
1513 ArrayRef{OpExpr},
"hlsl.quad.read.across.y");
1515 case Builtin::BI__builtin_hlsl_elementwise_sign: {
1516 auto *Arg0 = E->
getArg(0);
1518 llvm::Type *Xty = Op0->
getType();
1519 llvm::Type *retType = llvm::Type::getInt32Ty(this->
getLLVMContext());
1520 if (Xty->isVectorTy()) {
1521 auto *XVecTy = Arg0->getType()->castAs<
VectorType>();
1522 retType = llvm::VectorType::get(
1523 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1525 assert((Arg0->getType()->hasFloatingRepresentation() ||
1526 Arg0->getType()->hasIntegerRepresentation()) &&
1527 "sign operand must have a float or int representation");
1529 if (Arg0->getType()->hasUnsignedIntegerRepresentation()) {
1531 return Builder.CreateSelect(
Cmp, ConstantInt::get(retType, 0),
1532 ConstantInt::get(retType, 1),
"hlsl.sign");
1535 return Builder.CreateIntrinsic(
1536 retType,
CGM.getHLSLRuntime().getSignIntrinsic(),
1539 case Builtin::BI__builtin_hlsl_elementwise_radians: {
1542 "radians operand must have a float representation");
1543 return Builder.CreateIntrinsic(
1546 nullptr,
"hlsl.radians");
1548 case Builtin::BI__builtin_hlsl_buffer_update_counter: {
1552 return Builder.CreateIntrinsic(
1554 CGM.getHLSLRuntime().getBufferUpdateCounterIntrinsic(),
1557 case Builtin::BI__builtin_hlsl_elementwise_splitdouble: {
1562 "asuint operands types mismatch");
1565 case Builtin::BI__builtin_hlsl_elementwise_clip:
1567 "clip operands types mismatch");
1569 case Builtin::BI__builtin_hlsl_group_memory_barrier: {
1570 Intrinsic::ID ID =
CGM.getHLSLRuntime().getGroupMemoryBarrierIntrinsic();
1572 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID));
1574 case Builtin::BI__builtin_hlsl_group_memory_barrier_with_group_sync: {
1576 CGM.getHLSLRuntime().getGroupMemoryBarrierWithGroupSyncIntrinsic();
1578 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID));
1580 case Builtin::BI__builtin_hlsl_elementwise_ddx_coarse: {
1583 llvm_unreachable(
"ddx_coarse operand must have a float representation");
1584 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxCoarseIntrinsic();
1589 case Builtin::BI__builtin_hlsl_elementwise_ddy_coarse: {
1592 llvm_unreachable(
"ddy_coarse operand must have a float representation");
1593 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyCoarseIntrinsic();
1598 case Builtin::BI__builtin_hlsl_elementwise_ddx_fine: {
1601 llvm_unreachable(
"ddx_fine operand must have a float representation");
1602 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxFineIntrinsic();
1607 case Builtin::BI__builtin_hlsl_elementwise_ddy_fine: {
1610 llvm_unreachable(
"ddy_fine operand must have a float representation");
1611 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyFineIntrinsic();
1616 case Builtin::BI__builtin_get_spirv_spec_constant_bool:
1617 case Builtin::BI__builtin_get_spirv_spec_constant_short:
1618 case Builtin::BI__builtin_get_spirv_spec_constant_ushort:
1619 case Builtin::BI__builtin_get_spirv_spec_constant_int:
1620 case Builtin::BI__builtin_get_spirv_spec_constant_uint:
1621 case Builtin::BI__builtin_get_spirv_spec_constant_longlong:
1622 case Builtin::BI__builtin_get_spirv_spec_constant_ulonglong:
1623 case Builtin::BI__builtin_get_spirv_spec_constant_half:
1624 case Builtin::BI__builtin_get_spirv_spec_constant_float:
1625 case Builtin::BI__builtin_get_spirv_spec_constant_double: {
1629 llvm::Value *Args[] = {SpecId, DefaultVal};
1630 return Builder.CreateCall(SpecConstantFn, Args);