574 case Builtin::BI__builtin_hlsl_adduint64: {
580 "AddUint64 operand types must match");
582 "AddUint64 operands must have an integer representation");
583 assert((NumElements == 2 || NumElements == 4) &&
584 "AddUint64 operands must have 2 or 4 elements");
592 if (NumElements == 2) {
593 LowA =
Builder.CreateExtractElement(OpA, (uint64_t)0,
"LowA");
594 HighA =
Builder.CreateExtractElement(OpA, (uint64_t)1,
"HighA");
595 LowB =
Builder.CreateExtractElement(OpB, (uint64_t)0,
"LowB");
596 HighB =
Builder.CreateExtractElement(OpB, (uint64_t)1,
"HighB");
598 LowA =
Builder.CreateShuffleVector(OpA, {0, 2},
"LowA");
599 HighA =
Builder.CreateShuffleVector(OpA, {1, 3},
"HighA");
600 LowB =
Builder.CreateShuffleVector(OpB, {0, 2},
"LowB");
601 HighB =
Builder.CreateShuffleVector(OpB, {1, 3},
"HighB");
608 *
this, Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
609 llvm::Value *ZExtCarry =
610 Builder.CreateZExt(Carry, HighA->getType(),
"CarryZExt");
613 llvm::Value *HighSum =
Builder.CreateAdd(HighA, HighB,
"HighSum");
614 llvm::Value *HighSumPlusCarry =
615 Builder.CreateAdd(HighSum, ZExtCarry,
"HighSumPlusCarry");
617 if (NumElements == 4) {
618 return Builder.CreateShuffleVector(LowSum, HighSumPlusCarry, {0, 2, 1, 3},
624 "hlsl.AddUint64.upto0");
629 case Builtin::BI__builtin_hlsl_resource_getpointer:
630 case Builtin::BI__builtin_hlsl_resource_getpointer_typed: {
633 BuiltinID == Builtin::BI__builtin_hlsl_resource_getpointer_typed ||
637 llvm::Function *IntrFn =
nullptr;
638 llvm::CallInst *CI =
nullptr;
641 IntrFn = llvm::Intrinsic::getOrInsertDeclaration(
643 CGM.getHLSLRuntime().getCreateResourceGetPointerIntrinsic(),
644 {RetTy, HandleOp->getType(), IndexOp->getType()});
647 IntrFn = llvm::Intrinsic::getOrInsertDeclaration(
649 CGM.getHLSLRuntime().getCreateResourceGetBasePointerIntrinsic(),
650 {RetTy, HandleOp->getType()});
653 CI->setCallingConv(IntrFn->getCallingConv());
656 case Builtin::BI__builtin_hlsl_resource_sample: {
663 Args.push_back(HandleOp);
664 Args.push_back(SamplerOp);
665 Args.push_back(CoordOp);
670 return Builder.CreateIntrinsic(
671 RetTy,
CGM.getHLSLRuntime().getSampleIntrinsic(), Args);
675 return Builder.CreateIntrinsic(
676 RetTy,
CGM.getHLSLRuntime().getSampleClampIntrinsic(), Args);
678 case Builtin::BI__builtin_hlsl_resource_sample_bias: {
688 Args.push_back(HandleOp);
689 Args.push_back(SamplerOp);
690 Args.push_back(CoordOp);
691 Args.push_back(BiasOp);
696 return Builder.CreateIntrinsic(
697 RetTy,
CGM.getHLSLRuntime().getSampleBiasIntrinsic(), Args);
700 return Builder.CreateIntrinsic(
701 RetTy,
CGM.getHLSLRuntime().getSampleBiasClampIntrinsic(), Args);
703 case Builtin::BI__builtin_hlsl_resource_sample_grad: {
712 Args.push_back(HandleOp);
713 Args.push_back(SamplerOp);
714 Args.push_back(CoordOp);
715 Args.push_back(DDXOp);
716 Args.push_back(DDYOp);
722 return Builder.CreateIntrinsic(
723 RetTy,
CGM.getHLSLRuntime().getSampleGradIntrinsic(), Args);
727 return Builder.CreateIntrinsic(
728 RetTy,
CGM.getHLSLRuntime().getSampleGradClampIntrinsic(), Args);
730 case Builtin::BI__builtin_hlsl_resource_sample_level: {
740 Args.push_back(HandleOp);
741 Args.push_back(SamplerOp);
742 Args.push_back(CoordOp);
743 Args.push_back(LODOp);
747 return Builder.CreateIntrinsic(
748 RetTy,
CGM.getHLSLRuntime().getSampleLevelIntrinsic(), Args);
750 case Builtin::BI__builtin_hlsl_resource_load_level: {
755 unsigned NumElts = CoordLODVecTy->getNumElements();
756 assert(NumElts >= 2 &&
"CoordLOD must have at least 2 elements");
760 for (
unsigned I = 0; I < NumElts - 1; ++I)
764 Builder.CreateShuffleVector(CoordLODOp, Mask,
"hlsl.load.coord");
766 Builder.CreateExtractElement(CoordLODOp, NumElts - 1,
"hlsl.load.lod");
770 Args.push_back(HandleOp);
771 Args.push_back(CoordOp);
772 Args.push_back(LODOp);
776 return Builder.CreateIntrinsic(
777 RetTy,
CGM.getHLSLRuntime().getLoadLevelIntrinsic(), Args);
779 case Builtin::BI__builtin_hlsl_resource_sample_cmp: {
789 Args.push_back(HandleOp);
790 Args.push_back(SamplerOp);
791 Args.push_back(CoordOp);
792 Args.push_back(CmpOp);
797 return Builder.CreateIntrinsic(
798 RetTy,
CGM.getHLSLRuntime().getSampleCmpIntrinsic(), Args);
802 return Builder.CreateIntrinsic(
803 RetTy,
CGM.getHLSLRuntime().getSampleCmpClampIntrinsic(), Args);
805 case Builtin::BI__builtin_hlsl_resource_sample_cmp_level_zero: {
815 Args.push_back(HandleOp);
816 Args.push_back(SamplerOp);
817 Args.push_back(CoordOp);
818 Args.push_back(CmpOp);
822 return Builder.CreateIntrinsic(
823 RetTy,
CGM.getHLSLRuntime().getSampleCmpLevelZeroIntrinsic(), Args);
825 case Builtin::BI__builtin_hlsl_resource_calculate_lod: {
830 return Builder.CreateIntrinsic(
832 CGM.getHLSLRuntime().getCalculateLodIntrinsic(),
833 {HandleOp, SamplerOp, CoordOp});
835 case Builtin::BI__builtin_hlsl_resource_calculate_lod_unclamped: {
840 return Builder.CreateIntrinsic(
842 CGM.getHLSLRuntime().getCalculateLodUnclampedIntrinsic(),
843 {HandleOp, SamplerOp, CoordOp});
845 case Builtin::BI__builtin_hlsl_resource_gather: {
851 ComponentOp =
Builder.CreateIntCast(ComponentOp,
Builder.getInt32Ty(),
856 Args.push_back(HandleOp);
857 Args.push_back(SamplerOp);
858 Args.push_back(CoordOp);
859 Args.push_back(ComponentOp);
863 return Builder.CreateIntrinsic(
864 RetTy,
CGM.getHLSLRuntime().getGatherIntrinsic(), Args);
866 case Builtin::BI__builtin_hlsl_resource_gather_cmp: {
872 CompareOp =
Builder.CreateFPCast(CompareOp,
Builder.getFloatTy());
875 Args.push_back(HandleOp);
876 Args.push_back(SamplerOp);
877 Args.push_back(CoordOp);
878 Args.push_back(CompareOp);
880 if (
CGM.getTarget().getTriple().isDXIL()) {
883 ComponentOp =
Builder.CreateIntCast(ComponentOp,
Builder.getInt32Ty(),
885 Args.push_back(ComponentOp);
892 return Builder.CreateIntrinsic(
893 RetTy,
CGM.getHLSLRuntime().getGatherCmpIntrinsic(), Args);
895 case Builtin::BI__builtin_hlsl_resource_load_with_status:
896 case Builtin::BI__builtin_hlsl_resource_load_with_status_typed: {
905 const HLSLAttributedResourceType *RT =
906 HandleTy->
getAs<HLSLAttributedResourceType>();
907 assert(
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil &&
908 "Only DXIL currently implements load with status");
910 Intrinsic::ID IntrID = RT->getAttrs().RawBuffer
911 ? llvm::Intrinsic::dx_resource_load_rawbuffer
912 : llvm::Intrinsic::dx_resource_load_typedbuffer;
915 llvm::Type *RetTy = llvm::StructType::get(
Builder.getContext(),
916 {DataTy, Builder.getInt1Ty()});
919 Args.push_back(HandleOp);
920 Args.push_back(IndexOp);
925 if (!RT->isStructured())
926 Offset = llvm::PoisonValue::get(
Builder.getInt32Ty());
927 Args.push_back(Offset);
933 Builder.CreateIntrinsic(RetTy, IntrID, Args, {},
"ld.struct");
934 Value *LoadedValue =
Builder.CreateExtractValue(ResRet, {0},
"ld.value");
935 Value *StatusBit =
Builder.CreateExtractValue(ResRet, {1},
"ld.status");
936 Value *ExtendedStatus =
937 Builder.CreateZExt(StatusBit,
Builder.getInt32Ty(),
"ld.status.ext");
938 Builder.CreateStore(ExtendedStatus, StatusAddr);
942 case Builtin::BI__builtin_hlsl_resource_uninitializedhandle: {
943 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
944 return llvm::PoisonValue::get(HandleTy);
946 case Builtin::BI__builtin_hlsl_resource_handlefrombinding: {
947 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
953 llvm::Intrinsic::ID IntrinsicID =
954 CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic();
956 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
958 case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: {
959 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
965 llvm::Intrinsic::ID IntrinsicID =
966 CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
968 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
970 case Builtin::BI__builtin_hlsl_resource_counterhandlefromimplicitbinding: {
972 if (!
CGM.getTriple().isSPIRV())
975 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
978 llvm::Intrinsic::ID IntrinsicID =
979 llvm::Intrinsic::spv_resource_counterhandlefromimplicitbinding;
984 case Builtin::BI__builtin_hlsl_resource_nonuniformindex: {
987 return Builder.CreateIntrinsic(
988 RetTy,
CGM.getHLSLRuntime().getNonUniformResourceIndexIntrinsic(),
991 case Builtin::BI__builtin_hlsl_resource_getdimensions_x:
992 case Builtin::BI__builtin_hlsl_resource_getdimensions_x_float:
994 CGM.getHLSLRuntime().getGetDimensionsXIntrinsic(),
996 case Builtin::BI__builtin_hlsl_resource_getdimensions_xy:
997 case Builtin::BI__builtin_hlsl_resource_getdimensions_xy_float:
999 CGM.getHLSLRuntime().getGetDimensionsXYIntrinsic(),
1001 case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy:
1002 case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy_float:
1004 *
this, E,
CGM.getHLSLRuntime().getGetDimensionsLevelsXYIntrinsic(), 3,
1006 case Builtin::BI__builtin_hlsl_resource_getstride: {
1010 case Builtin::BI__builtin_hlsl_all: {
1012 return Builder.CreateIntrinsic(
1017 case Builtin::BI__builtin_hlsl_and: {
1020 return Builder.CreateAnd(Op0, Op1,
"hlsl.and");
1022 case Builtin::BI__builtin_hlsl_or: {
1025 return Builder.CreateOr(Op0, Op1,
"hlsl.or");
1027 case Builtin::BI__builtin_hlsl_any: {
1029 return Builder.CreateIntrinsic(
1034 case Builtin::BI__builtin_hlsl_asdouble:
1036 case Builtin::BI__builtin_hlsl_elementwise_clamp: {
1043 Ty = VecTy->getElementType();
1047 Intr =
CGM.getHLSLRuntime().getNClampIntrinsic();
1049 Intr =
CGM.getHLSLRuntime().getUClampIntrinsic();
1052 Intr =
CGM.getHLSLRuntime().getSClampIntrinsic();
1054 return Builder.CreateIntrinsic(
1058 case Builtin::BI__builtin_hlsl_crossf16:
1059 case Builtin::BI__builtin_hlsl_crossf32: {
1064 "cross operands must have a float representation");
1069 "input vectors must have 3 elements each");
1070 return Builder.CreateIntrinsic(
1071 Op0->
getType(),
CGM.getHLSLRuntime().getCrossIntrinsic(),
1074 case Builtin::BI__builtin_hlsl_dot: {
1077 llvm::Type *T0 = Op0->
getType();
1078 llvm::Type *T1 = Op1->
getType();
1081 if (!T0->isVectorTy() && !T1->isVectorTy()) {
1082 if (T0->isFloatingPointTy())
1083 return Builder.CreateFMul(Op0, Op1,
"hlsl.dot");
1085 if (T0->isIntegerTy())
1086 return Builder.CreateMul(Op0, Op1,
"hlsl.dot");
1089 "Scalar dot product is only supported on ints and floats.");
1094 "Dot product operands must have the same type.");
1097 assert(VecTy0 &&
"Dot product argument must be a vector.");
1099 return Builder.CreateIntrinsic(
1100 T0->getScalarType(),
1104 case Builtin::BI__builtin_hlsl_dot4add_i8packed: {
1109 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddI8PackedIntrinsic();
1112 return Builder.CreateIntrinsic(
1114 nullptr,
"hlsl.dot4add.i8packed");
1116 case Builtin::BI__builtin_hlsl_dot4add_u8packed: {
1121 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddU8PackedIntrinsic();
1124 return Builder.CreateIntrinsic(
1126 nullptr,
"hlsl.dot4add.u8packed");
1128 case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
1131 return Builder.CreateIntrinsic(
1136 case Builtin::BI__builtin_hlsl_elementwise_firstbitlow: {
1139 return Builder.CreateIntrinsic(
1142 nullptr,
"hlsl.firstbitlow");
1144 case Builtin::BI__builtin_hlsl_lerp: {
1149 llvm_unreachable(
"lerp operand must have a float representation");
1150 return Builder.CreateIntrinsic(
1151 X->getType(),
CGM.getHLSLRuntime().getLerpIntrinsic(),
1154 case Builtin::BI__builtin_hlsl_normalize: {
1158 "normalize operand must have a float representation");
1160 return Builder.CreateIntrinsic(
1163 nullptr,
"hlsl.normalize");
1165 case Builtin::BI__builtin_hlsl_elementwise_degrees: {
1169 "degree operand must have a float representation");
1171 return Builder.CreateIntrinsic(
1172 X->getType(),
CGM.getHLSLRuntime().getDegreesIntrinsic(),
1175 case Builtin::BI__builtin_hlsl_elementwise_f16tof32: {
1178 case Builtin::BI__builtin_hlsl_elementwise_f32tof16: {
1181 case Builtin::BI__builtin_hlsl_elementwise_frac: {
1184 llvm_unreachable(
"frac operand must have a float representation");
1185 return Builder.CreateIntrinsic(
1186 Op0->
getType(),
CGM.getHLSLRuntime().getFracIntrinsic(),
1189 case Builtin::BI__builtin_hlsl_elementwise_isinf: {
1191 llvm::Type *Xty = Op0->
getType();
1192 llvm::Type *retType = llvm::Type::getInt1Ty(this->
getLLVMContext());
1193 if (Xty->isVectorTy()) {
1195 retType = llvm::VectorType::get(
1196 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1199 llvm_unreachable(
"isinf operand must have a float representation");
1200 return Builder.CreateIntrinsic(
1201 retType,
CGM.getHLSLRuntime().getIsInfIntrinsic(),
1204 case Builtin::BI__builtin_hlsl_elementwise_isnan: {
1206 llvm::Type *Xty = Op0->
getType();
1207 llvm::Type *retType = llvm::Type::getInt1Ty(this->
getLLVMContext());
1208 if (Xty->isVectorTy()) {
1210 retType = llvm::VectorType::get(
1211 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1214 llvm_unreachable(
"isnan operand must have a float representation");
1215 return Builder.CreateIntrinsic(
1216 retType,
CGM.getHLSLRuntime().getIsNaNIntrinsic(),
1219 case Builtin::BI__builtin_hlsl_mad: {
1224 return Builder.CreateIntrinsic(
1225 M->
getType(), Intrinsic::fmuladd,
1229 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1230 return Builder.CreateIntrinsic(
1231 M->
getType(), Intrinsic::dx_imad,
1235 return Builder.CreateNSWAdd(Mul, B);
1238 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1239 return Builder.CreateIntrinsic(
1240 M->
getType(), Intrinsic::dx_umad,
1244 return Builder.CreateNUWAdd(Mul, B);
1246 case Builtin::BI__builtin_hlsl_mul: {
1264 llvm::MatrixBuilder MB(
Builder);
1265 if (IsVec0 && IsMat1) {
1269 unsigned Cols = MatTy->getNumColumns();
1270 assert(N == Rows &&
"vector length must match matrix row count");
1272 Op1 = MB.CreateRowMajorToColumnMajorTransform(Op1, Rows, Cols);
1273 return MB.CreateMatrixMultiply(Op0, Op1, 1, N, Cols,
"hlsl.mul");
1275 if (IsMat0 && IsVec1) {
1278 unsigned Cols = MatTy->getNumColumns();
1280 "vector length must match matrix column count");
1282 Op0 = MB.CreateRowMajorToColumnMajorTransform(Op0, Rows, Cols);
1283 return MB.CreateMatrixMultiply(Op0, Op1, Rows, Cols, 1,
"hlsl.mul");
1285 assert(IsMat0 && IsMat1);
1290 unsigned Cols0 = MatTy0->getNumColumns();
1292 assert(Cols0 == Rows1 &&
1293 "inner matrix dimensions must match for multiplication");
1295 Op0 = MB.CreateRowMajorToColumnMajorTransform(Op0, Rows0, Cols0);
1297 Op1 = MB.CreateRowMajorToColumnMajorTransform(Op1, Rows1, Cols1);
1300 MB.CreateMatrixMultiply(Op0, Op1, Rows0, Cols0, Cols1,
"hlsl.mul");
1303 if (IsResultRowMajor)
1304 Result = MB.CreateColumnMajorToRowMajorTransform(
Result, Rows0, Cols1);
1307 case Builtin::BI__builtin_hlsl_transpose: {
1311 unsigned Cols = MatTy->getNumColumns();
1312 llvm::MatrixBuilder MB(
Builder);
1319 if (SrcRowMajor != DstRowMajor)
1324 return MB.CreateMatrixTranspose(Op0, Cols, Rows);
1325 return MB.CreateMatrixTranspose(Op0, Rows, Cols);
1327 case Builtin::BI__builtin_hlsl_elementwise_rcp: {
1330 llvm_unreachable(
"rcp operand must have a float representation");
1331 llvm::Type *Ty = Op0->
getType();
1332 llvm::Type *EltTy = Ty->getScalarType();
1334 ? ConstantVector::getSplat(
1335 ElementCount::getFixed(
1337 ConstantFP::get(EltTy, 1.0))
1338 : ConstantFP::get(EltTy, 1.0);
1339 return Builder.CreateFDiv(One, Op0,
"hlsl.rcp");
1341 case Builtin::BI__builtin_hlsl_elementwise_rsqrt: {
1344 llvm_unreachable(
"rsqrt operand must have a float representation");
1345 return Builder.CreateIntrinsic(
1346 Op0->
getType(),
CGM.getHLSLRuntime().getRsqrtIntrinsic(),
1349 case Builtin::BI__builtin_hlsl_elementwise_saturate: {
1352 "saturate operand must have a float representation");
1353 return Builder.CreateIntrinsic(
1356 nullptr,
"hlsl.saturate");
1358 case Builtin::BI__builtin_hlsl_wave_prefix_count_bits: {
1360 assert(Op->
getType()->isIntegerTy(1) &&
1361 "WavePrefixBitCount operand must be a boolean type");
1368 case Builtin::BI__builtin_hlsl_select: {
1381 if (!OpTrue->
getType()->isVectorTy())
1383 Builder.CreateVectorSplat(VTy->getNumElements(), OpTrue,
"splat");
1384 if (!OpFalse->
getType()->isVectorTy())
1386 Builder.CreateVectorSplat(VTy->getNumElements(), OpFalse,
"splat");
1390 Builder.CreateSelect(OpCond, OpTrue, OpFalse,
"hlsl.select");
1397 case Builtin::BI__builtin_hlsl_step: {
1402 "step operands must have a float representation");
1403 return Builder.CreateIntrinsic(
1404 Op0->
getType(),
CGM.getHLSLRuntime().getStepIntrinsic(),
1407 case Builtin::BI__builtin_hlsl_wave_active_all_equal: {
1410 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllEqualIntrinsic();
1413 case Builtin::BI__builtin_hlsl_wave_active_all_true: {
1415 assert(Op->
getType()->isIntegerTy(1) &&
1416 "Intrinsic WaveActiveAllTrue operand must be a bool");
1418 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllTrueIntrinsic();
1421 case Builtin::BI__builtin_hlsl_wave_active_any_true: {
1423 assert(Op->
getType()->isIntegerTy(1) &&
1424 "Intrinsic WaveActiveAnyTrue operand must be a bool");
1426 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic();
1429 case Builtin::BI__builtin_hlsl_wave_active_bit_or: {
1432 "Intrinsic WaveActiveBitOr operand must have an unsigned integer "
1435 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitOrIntrinsic();
1437 "hlsl.wave.active.bit.or");
1439 case Builtin::BI__builtin_hlsl_wave_active_bit_xor: {
1442 "Intrinsic WaveActiveBitXor operand must have an unsigned integer "
1445 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitXorIntrinsic();
1447 "hlsl.wave.active.bit.xor");
1449 case Builtin::BI__builtin_hlsl_wave_active_bit_and: {
1452 "Intrinsic WaveActiveBitAnd operand must have an unsigned integer "
1455 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitAndIntrinsic();
1457 "hlsl.wave.active.bit.and");
1459 case Builtin::BI__builtin_hlsl_interlocked_add: {
1461 *
this, E,
CGM.getHLSLRuntime().getInterlockedAddIntrinsic(),
1462 "hlsl.interlocked.add");
1464 case Builtin::BI__builtin_hlsl_interlocked_or: {
1466 CGM.getHLSLRuntime().getInterlockedOrIntrinsic(),
1467 "hlsl.interlocked.or");
1469 case Builtin::BI__builtin_hlsl_wave_active_ballot: {
1471 assert(Op->
getType()->isIntegerTy(1) &&
1472 "Intrinsic WaveActiveBallot operand must be a bool");
1476 case Builtin::BI__builtin_hlsl_wave_active_count_bits: {
1478 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveCountBitsIntrinsic();
1481 case Builtin::BI__builtin_hlsl_wave_active_sum: {
1488 "hlsl.wave.active.sum");
1490 case Builtin::BI__builtin_hlsl_wave_active_product: {
1497 "hlsl.wave.active.product");
1499 case Builtin::BI__builtin_hlsl_wave_active_max: {
1505 IID =
CGM.getHLSLRuntime().getWaveActiveUMaxIntrinsic();
1507 IID =
CGM.getHLSLRuntime().getWaveActiveMaxIntrinsic();
1510 "hlsl.wave.active.max");
1512 case Builtin::BI__builtin_hlsl_wave_active_min: {
1518 IID =
CGM.getHLSLRuntime().getWaveActiveUMinIntrinsic();
1520 IID =
CGM.getHLSLRuntime().getWaveActiveMinIntrinsic();
1523 "hlsl.wave.active.min");
1525 case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
1529 switch (
CGM.getTarget().getTriple().getArch()) {
1530 case llvm::Triple::dxil:
1532 case llvm::Triple::spirv:
1534 llvm::FunctionType::get(
IntTy, {},
false),
1535 "__hlsl_wave_get_lane_index", {},
false,
true));
1538 "Intrinsic WaveGetLaneIndex not supported by target architecture");
1541 case Builtin::BI__builtin_hlsl_wave_is_first_lane: {
1542 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveIsFirstLaneIntrinsic();
1545 case Builtin::BI__builtin_hlsl_wave_get_lane_count: {
1546 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveGetLaneCountIntrinsic();
1549 case Builtin::BI__builtin_hlsl_wave_read_lane_at: {
1555 {OpExpr->getType()},
ArrayRef{OpExpr, OpIndex},
1556 "hlsl.wave.readlane");
1558 case Builtin::BI__builtin_hlsl_wave_prefix_sum: {
1563 "hlsl.wave.prefix.sum");
1565 case Builtin::BI__builtin_hlsl_wave_prefix_product: {
1570 "hlsl.wave.prefix.product");
1572 case Builtin::BI__builtin_hlsl_quad_read_across_x: {
1574 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossXIntrinsic();
1576 "hlsl.quad.read.across.x");
1578 case Builtin::BI__builtin_hlsl_quad_read_across_y: {
1580 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossYIntrinsic();
1582 "hlsl.quad.read.across.y");
1584 case Builtin::BI__builtin_hlsl_quad_read_across_diagonal: {
1587 CGM.getHLSLRuntime().getQuadReadAcrossDiagonalIntrinsic();
1589 &
CGM.getModule(), ID, {OpExpr->getType()}),
1590 ArrayRef{OpExpr},
"hlsl.quad.read.across.diagonal");
1592 case Builtin::BI__builtin_hlsl_elementwise_sign: {
1593 auto *Arg0 = E->
getArg(0);
1595 llvm::Type *Xty = Op0->
getType();
1596 llvm::Type *retType = llvm::Type::getInt32Ty(this->
getLLVMContext());
1597 if (Xty->isVectorTy()) {
1598 auto *XVecTy = Arg0->getType()->castAs<
VectorType>();
1599 retType = llvm::VectorType::get(
1600 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1602 assert((Arg0->getType()->hasFloatingRepresentation() ||
1603 Arg0->getType()->hasIntegerRepresentation()) &&
1604 "sign operand must have a float or int representation");
1606 if (Arg0->getType()->hasUnsignedIntegerRepresentation()) {
1608 return Builder.CreateSelect(
Cmp, ConstantInt::get(retType, 0),
1609 ConstantInt::get(retType, 1),
"hlsl.sign");
1612 return Builder.CreateIntrinsic(
1613 retType,
CGM.getHLSLRuntime().getSignIntrinsic(),
1616 case Builtin::BI__builtin_hlsl_elementwise_radians: {
1619 "radians operand must have a float representation");
1620 return Builder.CreateIntrinsic(
1623 nullptr,
"hlsl.radians");
1625 case Builtin::BI__builtin_hlsl_buffer_update_counter: {
1629 return Builder.CreateIntrinsic(
1631 CGM.getHLSLRuntime().getBufferUpdateCounterIntrinsic(),
1634 case Builtin::BI__builtin_hlsl_elementwise_splitdouble: {
1639 "asuint operands types mismatch");
1642 case Builtin::BI__builtin_hlsl_elementwise_clip:
1644 "clip operands types mismatch");
1646 case Builtin::BI__builtin_hlsl_all_memory_barrier: {
1647 Intrinsic::ID ID =
CGM.getHLSLRuntime().getAllMemoryBarrierIntrinsic();
1650 case Builtin::BI__builtin_hlsl_all_memory_barrier_with_group_sync: {
1652 CGM.getHLSLRuntime().getAllMemoryBarrierWithGroupSyncIntrinsic();
1655 case Builtin::BI__builtin_hlsl_device_memory_barrier: {
1656 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDeviceMemoryBarrierIntrinsic();
1659 case Builtin::BI__builtin_hlsl_device_memory_barrier_with_group_sync: {
1661 CGM.getHLSLRuntime().getDeviceMemoryBarrierWithGroupSyncIntrinsic();
1664 case Builtin::BI__builtin_hlsl_group_memory_barrier: {
1665 Intrinsic::ID ID =
CGM.getHLSLRuntime().getGroupMemoryBarrierIntrinsic();
1668 case Builtin::BI__builtin_hlsl_group_memory_barrier_with_group_sync: {
1670 CGM.getHLSLRuntime().getGroupMemoryBarrierWithGroupSyncIntrinsic();
1673 case Builtin::BI__builtin_hlsl_elementwise_ddx_coarse: {
1676 llvm_unreachable(
"ddx_coarse operand must have a float representation");
1677 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxCoarseIntrinsic();
1682 case Builtin::BI__builtin_hlsl_elementwise_ddy_coarse: {
1685 llvm_unreachable(
"ddy_coarse operand must have a float representation");
1686 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyCoarseIntrinsic();
1691 case Builtin::BI__builtin_hlsl_elementwise_ddx_fine: {
1694 llvm_unreachable(
"ddx_fine operand must have a float representation");
1695 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxFineIntrinsic();
1700 case Builtin::BI__builtin_hlsl_elementwise_ddy_fine: {
1703 llvm_unreachable(
"ddy_fine operand must have a float representation");
1704 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyFineIntrinsic();
1709 case Builtin::BI__builtin_get_spirv_spec_constant_bool:
1710 case Builtin::BI__builtin_get_spirv_spec_constant_short:
1711 case Builtin::BI__builtin_get_spirv_spec_constant_ushort:
1712 case Builtin::BI__builtin_get_spirv_spec_constant_int:
1713 case Builtin::BI__builtin_get_spirv_spec_constant_uint:
1714 case Builtin::BI__builtin_get_spirv_spec_constant_longlong:
1715 case Builtin::BI__builtin_get_spirv_spec_constant_ulonglong:
1716 case Builtin::BI__builtin_get_spirv_spec_constant_half:
1717 case Builtin::BI__builtin_get_spirv_spec_constant_float:
1718 case Builtin::BI__builtin_get_spirv_spec_constant_double: {
1722 llvm::Value *Args[] = {SpecId, DefaultVal};
1723 return Builder.CreateCall(SpecConstantFn, Args);