546 case Builtin::BI__builtin_hlsl_adduint64: {
552 "AddUint64 operand types must match");
554 "AddUint64 operands must have an integer representation");
555 assert((NumElements == 2 || NumElements == 4) &&
556 "AddUint64 operands must have 2 or 4 elements");
564 if (NumElements == 2) {
565 LowA =
Builder.CreateExtractElement(OpA, (uint64_t)0,
"LowA");
566 HighA =
Builder.CreateExtractElement(OpA, (uint64_t)1,
"HighA");
567 LowB =
Builder.CreateExtractElement(OpB, (uint64_t)0,
"LowB");
568 HighB =
Builder.CreateExtractElement(OpB, (uint64_t)1,
"HighB");
570 LowA =
Builder.CreateShuffleVector(OpA, {0, 2},
"LowA");
571 HighA =
Builder.CreateShuffleVector(OpA, {1, 3},
"HighA");
572 LowB =
Builder.CreateShuffleVector(OpB, {0, 2},
"LowB");
573 HighB =
Builder.CreateShuffleVector(OpB, {1, 3},
"HighB");
580 *
this, Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
581 llvm::Value *ZExtCarry =
582 Builder.CreateZExt(Carry, HighA->getType(),
"CarryZExt");
585 llvm::Value *HighSum =
Builder.CreateAdd(HighA, HighB,
"HighSum");
586 llvm::Value *HighSumPlusCarry =
587 Builder.CreateAdd(HighSum, ZExtCarry,
"HighSumPlusCarry");
589 if (NumElements == 4) {
590 return Builder.CreateShuffleVector(LowSum, HighSumPlusCarry, {0, 2, 1, 3},
596 "hlsl.AddUint64.upto0");
601 case Builtin::BI__builtin_hlsl_resource_getpointer:
602 case Builtin::BI__builtin_hlsl_resource_getpointer_typed: {
605 BuiltinID == Builtin::BI__builtin_hlsl_resource_getpointer_typed ||
609 llvm::Function *IntrFn =
nullptr;
610 llvm::CallInst *CI =
nullptr;
613 IntrFn = llvm::Intrinsic::getOrInsertDeclaration(
615 CGM.getHLSLRuntime().getCreateResourceGetPointerIntrinsic(),
616 {RetTy, HandleOp->getType(), IndexOp->getType()});
619 IntrFn = llvm::Intrinsic::getOrInsertDeclaration(
621 CGM.getHLSLRuntime().getCreateResourceGetBasePointerIntrinsic(),
622 {RetTy, HandleOp->getType()});
625 CI->setCallingConv(IntrFn->getCallingConv());
628 case Builtin::BI__builtin_hlsl_resource_sample: {
635 Args.push_back(HandleOp);
636 Args.push_back(SamplerOp);
637 Args.push_back(CoordOp);
642 return Builder.CreateIntrinsic(
643 RetTy,
CGM.getHLSLRuntime().getSampleIntrinsic(), Args);
647 return Builder.CreateIntrinsic(
648 RetTy,
CGM.getHLSLRuntime().getSampleClampIntrinsic(), Args);
650 case Builtin::BI__builtin_hlsl_resource_sample_bias: {
660 Args.push_back(HandleOp);
661 Args.push_back(SamplerOp);
662 Args.push_back(CoordOp);
663 Args.push_back(BiasOp);
668 return Builder.CreateIntrinsic(
669 RetTy,
CGM.getHLSLRuntime().getSampleBiasIntrinsic(), Args);
672 return Builder.CreateIntrinsic(
673 RetTy,
CGM.getHLSLRuntime().getSampleBiasClampIntrinsic(), Args);
675 case Builtin::BI__builtin_hlsl_resource_sample_grad: {
684 Args.push_back(HandleOp);
685 Args.push_back(SamplerOp);
686 Args.push_back(CoordOp);
687 Args.push_back(DDXOp);
688 Args.push_back(DDYOp);
694 return Builder.CreateIntrinsic(
695 RetTy,
CGM.getHLSLRuntime().getSampleGradIntrinsic(), Args);
699 return Builder.CreateIntrinsic(
700 RetTy,
CGM.getHLSLRuntime().getSampleGradClampIntrinsic(), Args);
702 case Builtin::BI__builtin_hlsl_resource_sample_level: {
712 Args.push_back(HandleOp);
713 Args.push_back(SamplerOp);
714 Args.push_back(CoordOp);
715 Args.push_back(LODOp);
719 return Builder.CreateIntrinsic(
720 RetTy,
CGM.getHLSLRuntime().getSampleLevelIntrinsic(), Args);
722 case Builtin::BI__builtin_hlsl_resource_load_level: {
727 unsigned NumElts = CoordLODVecTy->getNumElements();
728 assert(NumElts >= 2 &&
"CoordLOD must have at least 2 elements");
732 for (
unsigned I = 0; I < NumElts - 1; ++I)
736 Builder.CreateShuffleVector(CoordLODOp, Mask,
"hlsl.load.coord");
738 Builder.CreateExtractElement(CoordLODOp, NumElts - 1,
"hlsl.load.lod");
742 Args.push_back(HandleOp);
743 Args.push_back(CoordOp);
744 Args.push_back(LODOp);
748 return Builder.CreateIntrinsic(
749 RetTy,
CGM.getHLSLRuntime().getLoadLevelIntrinsic(), Args);
751 case Builtin::BI__builtin_hlsl_resource_sample_cmp: {
761 Args.push_back(HandleOp);
762 Args.push_back(SamplerOp);
763 Args.push_back(CoordOp);
764 Args.push_back(CmpOp);
769 return Builder.CreateIntrinsic(
770 RetTy,
CGM.getHLSLRuntime().getSampleCmpIntrinsic(), Args);
774 return Builder.CreateIntrinsic(
775 RetTy,
CGM.getHLSLRuntime().getSampleCmpClampIntrinsic(), Args);
777 case Builtin::BI__builtin_hlsl_resource_sample_cmp_level_zero: {
787 Args.push_back(HandleOp);
788 Args.push_back(SamplerOp);
789 Args.push_back(CoordOp);
790 Args.push_back(CmpOp);
794 return Builder.CreateIntrinsic(
795 RetTy,
CGM.getHLSLRuntime().getSampleCmpLevelZeroIntrinsic(), Args);
797 case Builtin::BI__builtin_hlsl_resource_calculate_lod: {
802 return Builder.CreateIntrinsic(
804 CGM.getHLSLRuntime().getCalculateLodIntrinsic(),
805 {HandleOp, SamplerOp, CoordOp});
807 case Builtin::BI__builtin_hlsl_resource_calculate_lod_unclamped: {
812 return Builder.CreateIntrinsic(
814 CGM.getHLSLRuntime().getCalculateLodUnclampedIntrinsic(),
815 {HandleOp, SamplerOp, CoordOp});
817 case Builtin::BI__builtin_hlsl_resource_gather: {
823 ComponentOp =
Builder.CreateIntCast(ComponentOp,
Builder.getInt32Ty(),
828 Args.push_back(HandleOp);
829 Args.push_back(SamplerOp);
830 Args.push_back(CoordOp);
831 Args.push_back(ComponentOp);
835 return Builder.CreateIntrinsic(
836 RetTy,
CGM.getHLSLRuntime().getGatherIntrinsic(), Args);
838 case Builtin::BI__builtin_hlsl_resource_gather_cmp: {
844 CompareOp =
Builder.CreateFPCast(CompareOp,
Builder.getFloatTy());
847 Args.push_back(HandleOp);
848 Args.push_back(SamplerOp);
849 Args.push_back(CoordOp);
850 Args.push_back(CompareOp);
852 if (
CGM.getTarget().getTriple().isDXIL()) {
855 ComponentOp =
Builder.CreateIntCast(ComponentOp,
Builder.getInt32Ty(),
857 Args.push_back(ComponentOp);
864 return Builder.CreateIntrinsic(
865 RetTy,
CGM.getHLSLRuntime().getGatherCmpIntrinsic(), Args);
867 case Builtin::BI__builtin_hlsl_resource_load_with_status:
868 case Builtin::BI__builtin_hlsl_resource_load_with_status_typed: {
877 const HLSLAttributedResourceType *RT =
878 HandleTy->
getAs<HLSLAttributedResourceType>();
879 assert(
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil &&
880 "Only DXIL currently implements load with status");
882 Intrinsic::ID IntrID = RT->getAttrs().RawBuffer
883 ? llvm::Intrinsic::dx_resource_load_rawbuffer
884 : llvm::Intrinsic::dx_resource_load_typedbuffer;
887 llvm::Type *RetTy = llvm::StructType::get(
Builder.getContext(),
888 {DataTy, Builder.getInt1Ty()});
891 Args.push_back(HandleOp);
892 Args.push_back(IndexOp);
897 if (!RT->isStructured())
898 Offset = llvm::PoisonValue::get(
Builder.getInt32Ty());
899 Args.push_back(Offset);
905 Builder.CreateIntrinsic(RetTy, IntrID, Args, {},
"ld.struct");
906 Value *LoadedValue =
Builder.CreateExtractValue(ResRet, {0},
"ld.value");
907 Value *StatusBit =
Builder.CreateExtractValue(ResRet, {1},
"ld.status");
908 Value *ExtendedStatus =
909 Builder.CreateZExt(StatusBit,
Builder.getInt32Ty(),
"ld.status.ext");
910 Builder.CreateStore(ExtendedStatus, StatusAddr);
914 case Builtin::BI__builtin_hlsl_resource_uninitializedhandle: {
915 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
916 return llvm::PoisonValue::get(HandleTy);
918 case Builtin::BI__builtin_hlsl_resource_handlefrombinding: {
919 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
925 llvm::Intrinsic::ID IntrinsicID =
926 CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic();
928 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
930 case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: {
931 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
937 llvm::Intrinsic::ID IntrinsicID =
938 CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
940 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
942 case Builtin::BI__builtin_hlsl_resource_counterhandlefromimplicitbinding: {
944 if (!
CGM.getTriple().isSPIRV())
947 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
950 llvm::Intrinsic::ID IntrinsicID =
951 llvm::Intrinsic::spv_resource_counterhandlefromimplicitbinding;
953 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
955 case Builtin::BI__builtin_hlsl_resource_nonuniformindex: {
958 return Builder.CreateIntrinsic(
959 RetTy,
CGM.getHLSLRuntime().getNonUniformResourceIndexIntrinsic(),
962 case Builtin::BI__builtin_hlsl_resource_getdimensions_x:
963 case Builtin::BI__builtin_hlsl_resource_getdimensions_x_float:
965 CGM.getHLSLRuntime().getGetDimensionsXIntrinsic(),
967 case Builtin::BI__builtin_hlsl_resource_getdimensions_xy:
968 case Builtin::BI__builtin_hlsl_resource_getdimensions_xy_float:
970 CGM.getHLSLRuntime().getGetDimensionsXYIntrinsic(),
972 case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy:
973 case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy_float:
975 *
this, E,
CGM.getHLSLRuntime().getGetDimensionsLevelsXYIntrinsic(), 3,
977 case Builtin::BI__builtin_hlsl_resource_getstride: {
981 case Builtin::BI__builtin_hlsl_all: {
983 return Builder.CreateIntrinsic(
988 case Builtin::BI__builtin_hlsl_and: {
991 return Builder.CreateAnd(Op0, Op1,
"hlsl.and");
993 case Builtin::BI__builtin_hlsl_or: {
996 return Builder.CreateOr(Op0, Op1,
"hlsl.or");
998 case Builtin::BI__builtin_hlsl_any: {
1000 return Builder.CreateIntrinsic(
1005 case Builtin::BI__builtin_hlsl_asdouble:
1007 case Builtin::BI__builtin_hlsl_elementwise_clamp: {
1014 Ty = VecTy->getElementType();
1018 Intr =
CGM.getHLSLRuntime().getNClampIntrinsic();
1020 Intr =
CGM.getHLSLRuntime().getUClampIntrinsic();
1023 Intr =
CGM.getHLSLRuntime().getSClampIntrinsic();
1025 return Builder.CreateIntrinsic(
1029 case Builtin::BI__builtin_hlsl_crossf16:
1030 case Builtin::BI__builtin_hlsl_crossf32: {
1035 "cross operands must have a float representation");
1040 "input vectors must have 3 elements each");
1041 return Builder.CreateIntrinsic(
1042 Op0->
getType(),
CGM.getHLSLRuntime().getCrossIntrinsic(),
1045 case Builtin::BI__builtin_hlsl_dot: {
1048 llvm::Type *T0 = Op0->
getType();
1049 llvm::Type *T1 = Op1->
getType();
1052 if (!T0->isVectorTy() && !T1->isVectorTy()) {
1053 if (T0->isFloatingPointTy())
1054 return Builder.CreateFMul(Op0, Op1,
"hlsl.dot");
1056 if (T0->isIntegerTy())
1057 return Builder.CreateMul(Op0, Op1,
"hlsl.dot");
1060 "Scalar dot product is only supported on ints and floats.");
1065 "Dot product operands must have the same type.");
1068 assert(VecTy0 &&
"Dot product argument must be a vector.");
1070 return Builder.CreateIntrinsic(
1071 T0->getScalarType(),
1075 case Builtin::BI__builtin_hlsl_dot4add_i8packed: {
1080 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddI8PackedIntrinsic();
1083 return Builder.CreateIntrinsic(
1085 nullptr,
"hlsl.dot4add.i8packed");
1087 case Builtin::BI__builtin_hlsl_dot4add_u8packed: {
1092 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddU8PackedIntrinsic();
1095 return Builder.CreateIntrinsic(
1097 nullptr,
"hlsl.dot4add.u8packed");
1099 case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
1102 return Builder.CreateIntrinsic(
1107 case Builtin::BI__builtin_hlsl_elementwise_firstbitlow: {
1110 return Builder.CreateIntrinsic(
1113 nullptr,
"hlsl.firstbitlow");
1115 case Builtin::BI__builtin_hlsl_lerp: {
1120 llvm_unreachable(
"lerp operand must have a float representation");
1121 return Builder.CreateIntrinsic(
1122 X->getType(),
CGM.getHLSLRuntime().getLerpIntrinsic(),
1125 case Builtin::BI__builtin_hlsl_normalize: {
1129 "normalize operand must have a float representation");
1131 return Builder.CreateIntrinsic(
1134 nullptr,
"hlsl.normalize");
1136 case Builtin::BI__builtin_hlsl_elementwise_degrees: {
1140 "degree operand must have a float representation");
1142 return Builder.CreateIntrinsic(
1143 X->getType(),
CGM.getHLSLRuntime().getDegreesIntrinsic(),
1146 case Builtin::BI__builtin_hlsl_elementwise_f16tof32: {
1149 case Builtin::BI__builtin_hlsl_elementwise_f32tof16: {
1152 case Builtin::BI__builtin_hlsl_elementwise_frac: {
1155 llvm_unreachable(
"frac operand must have a float representation");
1156 return Builder.CreateIntrinsic(
1157 Op0->
getType(),
CGM.getHLSLRuntime().getFracIntrinsic(),
1160 case Builtin::BI__builtin_hlsl_elementwise_isinf: {
1162 llvm::Type *Xty = Op0->
getType();
1163 llvm::Type *retType = llvm::Type::getInt1Ty(this->
getLLVMContext());
1164 if (Xty->isVectorTy()) {
1166 retType = llvm::VectorType::get(
1167 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1170 llvm_unreachable(
"isinf operand must have a float representation");
1171 return Builder.CreateIntrinsic(
1172 retType,
CGM.getHLSLRuntime().getIsInfIntrinsic(),
1175 case Builtin::BI__builtin_hlsl_elementwise_isnan: {
1177 llvm::Type *Xty = Op0->
getType();
1178 llvm::Type *retType = llvm::Type::getInt1Ty(this->
getLLVMContext());
1179 if (Xty->isVectorTy()) {
1181 retType = llvm::VectorType::get(
1182 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1185 llvm_unreachable(
"isnan operand must have a float representation");
1186 return Builder.CreateIntrinsic(
1187 retType,
CGM.getHLSLRuntime().getIsNaNIntrinsic(),
1190 case Builtin::BI__builtin_hlsl_mad: {
1195 return Builder.CreateIntrinsic(
1196 M->
getType(), Intrinsic::fmuladd,
1200 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1201 return Builder.CreateIntrinsic(
1202 M->
getType(), Intrinsic::dx_imad,
1206 return Builder.CreateNSWAdd(Mul, B);
1209 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1210 return Builder.CreateIntrinsic(
1211 M->
getType(), Intrinsic::dx_umad,
1215 return Builder.CreateNUWAdd(Mul, B);
1217 case Builtin::BI__builtin_hlsl_mul: {
1235 llvm::MatrixBuilder MB(
Builder);
1236 if (IsVec0 && IsMat1) {
1240 unsigned Cols = MatTy->getNumColumns();
1241 assert(N == Rows &&
"vector length must match matrix row count");
1243 Op1 = MB.CreateRowMajorToColumnMajorTransform(Op1, Rows, Cols);
1244 return MB.CreateMatrixMultiply(Op0, Op1, 1, N, Cols,
"hlsl.mul");
1246 if (IsMat0 && IsVec1) {
1249 unsigned Cols = MatTy->getNumColumns();
1251 "vector length must match matrix column count");
1253 Op0 = MB.CreateRowMajorToColumnMajorTransform(Op0, Rows, Cols);
1254 return MB.CreateMatrixMultiply(Op0, Op1, Rows, Cols, 1,
"hlsl.mul");
1256 assert(IsMat0 && IsMat1);
1261 unsigned Cols0 = MatTy0->getNumColumns();
1263 assert(Cols0 == Rows1 &&
1264 "inner matrix dimensions must match for multiplication");
1266 Op0 = MB.CreateRowMajorToColumnMajorTransform(Op0, Rows0, Cols0);
1268 Op1 = MB.CreateRowMajorToColumnMajorTransform(Op1, Rows1, Cols1);
1271 MB.CreateMatrixMultiply(Op0, Op1, Rows0, Cols0, Cols1,
"hlsl.mul");
1274 if (IsResultRowMajor)
1275 Result = MB.CreateColumnMajorToRowMajorTransform(
Result, Rows0, Cols1);
1278 case Builtin::BI__builtin_hlsl_transpose: {
1282 unsigned Cols = MatTy->getNumColumns();
1283 llvm::MatrixBuilder MB(
Builder);
1290 if (SrcRowMajor != DstRowMajor)
1295 return MB.CreateMatrixTranspose(Op0, Cols, Rows);
1296 return MB.CreateMatrixTranspose(Op0, Rows, Cols);
1298 case Builtin::BI__builtin_hlsl_elementwise_rcp: {
1301 llvm_unreachable(
"rcp operand must have a float representation");
1302 llvm::Type *Ty = Op0->
getType();
1303 llvm::Type *EltTy = Ty->getScalarType();
1305 ? ConstantVector::getSplat(
1306 ElementCount::getFixed(
1308 ConstantFP::get(EltTy, 1.0))
1309 : ConstantFP::get(EltTy, 1.0);
1310 return Builder.CreateFDiv(One, Op0,
"hlsl.rcp");
1312 case Builtin::BI__builtin_hlsl_elementwise_rsqrt: {
1315 llvm_unreachable(
"rsqrt operand must have a float representation");
1316 return Builder.CreateIntrinsic(
1317 Op0->
getType(),
CGM.getHLSLRuntime().getRsqrtIntrinsic(),
1320 case Builtin::BI__builtin_hlsl_elementwise_saturate: {
1323 "saturate operand must have a float representation");
1324 return Builder.CreateIntrinsic(
1327 nullptr,
"hlsl.saturate");
1329 case Builtin::BI__builtin_hlsl_wave_prefix_count_bits: {
1331 assert(Op->
getType()->isIntegerTy(1) &&
1332 "WavePrefixBitCount operand must be a boolean type");
1339 case Builtin::BI__builtin_hlsl_select: {
1352 if (!OpTrue->
getType()->isVectorTy())
1354 Builder.CreateVectorSplat(VTy->getNumElements(), OpTrue,
"splat");
1355 if (!OpFalse->
getType()->isVectorTy())
1357 Builder.CreateVectorSplat(VTy->getNumElements(), OpFalse,
"splat");
1361 Builder.CreateSelect(OpCond, OpTrue, OpFalse,
"hlsl.select");
1368 case Builtin::BI__builtin_hlsl_step: {
1373 "step operands must have a float representation");
1374 return Builder.CreateIntrinsic(
1375 Op0->
getType(),
CGM.getHLSLRuntime().getStepIntrinsic(),
1378 case Builtin::BI__builtin_hlsl_wave_active_all_equal: {
1381 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllEqualIntrinsic();
1384 case Builtin::BI__builtin_hlsl_wave_active_all_true: {
1386 assert(Op->
getType()->isIntegerTy(1) &&
1387 "Intrinsic WaveActiveAllTrue operand must be a bool");
1389 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllTrueIntrinsic();
1392 case Builtin::BI__builtin_hlsl_wave_active_any_true: {
1394 assert(Op->
getType()->isIntegerTy(1) &&
1395 "Intrinsic WaveActiveAnyTrue operand must be a bool");
1397 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic();
1400 case Builtin::BI__builtin_hlsl_wave_active_bit_or: {
1403 "Intrinsic WaveActiveBitOr operand must have an unsigned integer "
1406 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitOrIntrinsic();
1408 "hlsl.wave.active.bit.or");
1410 case Builtin::BI__builtin_hlsl_wave_active_bit_xor: {
1413 "Intrinsic WaveActiveBitXor operand must have an unsigned integer "
1416 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitXorIntrinsic();
1418 "hlsl.wave.active.bit.xor");
1420 case Builtin::BI__builtin_hlsl_wave_active_bit_and: {
1423 "Intrinsic WaveActiveBitAnd operand must have an unsigned integer "
1426 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitAndIntrinsic();
1428 "hlsl.wave.active.bit.and");
1430 case Builtin::BI__builtin_hlsl_interlocked_add: {
1441 "Intrinsic InterlockedAdd value operand must be an integer");
1443 Intrinsic::ID ID =
CGM.getHLSLRuntime().getInterlockedAddIntrinsic();
1445 Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID,
1446 {Val->getType(), Ptr->getType()}),
1457 case Builtin::BI__builtin_hlsl_wave_active_ballot: {
1459 assert(Op->
getType()->isIntegerTy(1) &&
1460 "Intrinsic WaveActiveBallot operand must be a bool");
1464 case Builtin::BI__builtin_hlsl_wave_active_count_bits: {
1466 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveCountBitsIntrinsic();
1469 case Builtin::BI__builtin_hlsl_wave_active_sum: {
1476 "hlsl.wave.active.sum");
1478 case Builtin::BI__builtin_hlsl_wave_active_product: {
1485 "hlsl.wave.active.product");
1487 case Builtin::BI__builtin_hlsl_wave_active_max: {
1493 IID =
CGM.getHLSLRuntime().getWaveActiveUMaxIntrinsic();
1495 IID =
CGM.getHLSLRuntime().getWaveActiveMaxIntrinsic();
1498 "hlsl.wave.active.max");
1500 case Builtin::BI__builtin_hlsl_wave_active_min: {
1506 IID =
CGM.getHLSLRuntime().getWaveActiveUMinIntrinsic();
1508 IID =
CGM.getHLSLRuntime().getWaveActiveMinIntrinsic();
1511 "hlsl.wave.active.min");
1513 case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
1517 switch (
CGM.getTarget().getTriple().getArch()) {
1518 case llvm::Triple::dxil:
1520 case llvm::Triple::spirv:
1522 llvm::FunctionType::get(
IntTy, {},
false),
1523 "__hlsl_wave_get_lane_index", {},
false,
true));
1526 "Intrinsic WaveGetLaneIndex not supported by target architecture");
1529 case Builtin::BI__builtin_hlsl_wave_is_first_lane: {
1530 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveIsFirstLaneIntrinsic();
1533 case Builtin::BI__builtin_hlsl_wave_get_lane_count: {
1534 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveGetLaneCountIntrinsic();
1537 case Builtin::BI__builtin_hlsl_wave_read_lane_at: {
1543 {OpExpr->getType()},
ArrayRef{OpExpr, OpIndex},
1544 "hlsl.wave.readlane");
1546 case Builtin::BI__builtin_hlsl_wave_prefix_sum: {
1551 "hlsl.wave.prefix.sum");
1553 case Builtin::BI__builtin_hlsl_wave_prefix_product: {
1558 "hlsl.wave.prefix.product");
1560 case Builtin::BI__builtin_hlsl_quad_read_across_x: {
1562 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossXIntrinsic();
1564 "hlsl.quad.read.across.x");
1566 case Builtin::BI__builtin_hlsl_quad_read_across_y: {
1568 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossYIntrinsic();
1570 "hlsl.quad.read.across.y");
1572 case Builtin::BI__builtin_hlsl_quad_read_across_diagonal: {
1575 CGM.getHLSLRuntime().getQuadReadAcrossDiagonalIntrinsic();
1577 &
CGM.getModule(), ID, {OpExpr->getType()}),
1578 ArrayRef{OpExpr},
"hlsl.quad.read.across.diagonal");
1580 case Builtin::BI__builtin_hlsl_elementwise_sign: {
1581 auto *Arg0 = E->
getArg(0);
1583 llvm::Type *Xty = Op0->
getType();
1584 llvm::Type *retType = llvm::Type::getInt32Ty(this->
getLLVMContext());
1585 if (Xty->isVectorTy()) {
1586 auto *XVecTy = Arg0->getType()->castAs<
VectorType>();
1587 retType = llvm::VectorType::get(
1588 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1590 assert((Arg0->getType()->hasFloatingRepresentation() ||
1591 Arg0->getType()->hasIntegerRepresentation()) &&
1592 "sign operand must have a float or int representation");
1594 if (Arg0->getType()->hasUnsignedIntegerRepresentation()) {
1596 return Builder.CreateSelect(
Cmp, ConstantInt::get(retType, 0),
1597 ConstantInt::get(retType, 1),
"hlsl.sign");
1600 return Builder.CreateIntrinsic(
1601 retType,
CGM.getHLSLRuntime().getSignIntrinsic(),
1604 case Builtin::BI__builtin_hlsl_elementwise_radians: {
1607 "radians operand must have a float representation");
1608 return Builder.CreateIntrinsic(
1611 nullptr,
"hlsl.radians");
1613 case Builtin::BI__builtin_hlsl_buffer_update_counter: {
1617 return Builder.CreateIntrinsic(
1619 CGM.getHLSLRuntime().getBufferUpdateCounterIntrinsic(),
1622 case Builtin::BI__builtin_hlsl_elementwise_splitdouble: {
1627 "asuint operands types mismatch");
1630 case Builtin::BI__builtin_hlsl_elementwise_clip:
1632 "clip operands types mismatch");
1634 case Builtin::BI__builtin_hlsl_all_memory_barrier: {
1635 Intrinsic::ID ID =
CGM.getHLSLRuntime().getAllMemoryBarrierIntrinsic();
1638 case Builtin::BI__builtin_hlsl_all_memory_barrier_with_group_sync: {
1640 CGM.getHLSLRuntime().getAllMemoryBarrierWithGroupSyncIntrinsic();
1643 case Builtin::BI__builtin_hlsl_device_memory_barrier: {
1644 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDeviceMemoryBarrierIntrinsic();
1647 case Builtin::BI__builtin_hlsl_device_memory_barrier_with_group_sync: {
1649 CGM.getHLSLRuntime().getDeviceMemoryBarrierWithGroupSyncIntrinsic();
1652 case Builtin::BI__builtin_hlsl_group_memory_barrier: {
1653 Intrinsic::ID ID =
CGM.getHLSLRuntime().getGroupMemoryBarrierIntrinsic();
1656 case Builtin::BI__builtin_hlsl_group_memory_barrier_with_group_sync: {
1658 CGM.getHLSLRuntime().getGroupMemoryBarrierWithGroupSyncIntrinsic();
1661 case Builtin::BI__builtin_hlsl_elementwise_ddx_coarse: {
1664 llvm_unreachable(
"ddx_coarse operand must have a float representation");
1665 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxCoarseIntrinsic();
1670 case Builtin::BI__builtin_hlsl_elementwise_ddy_coarse: {
1673 llvm_unreachable(
"ddy_coarse operand must have a float representation");
1674 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyCoarseIntrinsic();
1679 case Builtin::BI__builtin_hlsl_elementwise_ddx_fine: {
1682 llvm_unreachable(
"ddx_fine operand must have a float representation");
1683 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxFineIntrinsic();
1688 case Builtin::BI__builtin_hlsl_elementwise_ddy_fine: {
1691 llvm_unreachable(
"ddy_fine operand must have a float representation");
1692 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyFineIntrinsic();
1697 case Builtin::BI__builtin_get_spirv_spec_constant_bool:
1698 case Builtin::BI__builtin_get_spirv_spec_constant_short:
1699 case Builtin::BI__builtin_get_spirv_spec_constant_ushort:
1700 case Builtin::BI__builtin_get_spirv_spec_constant_int:
1701 case Builtin::BI__builtin_get_spirv_spec_constant_uint:
1702 case Builtin::BI__builtin_get_spirv_spec_constant_longlong:
1703 case Builtin::BI__builtin_get_spirv_spec_constant_ulonglong:
1704 case Builtin::BI__builtin_get_spirv_spec_constant_half:
1705 case Builtin::BI__builtin_get_spirv_spec_constant_float:
1706 case Builtin::BI__builtin_get_spirv_spec_constant_double: {
1710 llvm::Value *Args[] = {SpecId, DefaultVal};
1711 return Builder.CreateCall(SpecConstantFn, Args);