602 case Builtin::BI__builtin_hlsl_adduint64: {
608 "AddUint64 operand types must match");
610 "AddUint64 operands must have an integer representation");
611 assert((NumElements == 2 || NumElements == 4) &&
612 "AddUint64 operands must have 2 or 4 elements");
620 if (NumElements == 2) {
621 LowA =
Builder.CreateExtractElement(OpA, (uint64_t)0,
"LowA");
622 HighA =
Builder.CreateExtractElement(OpA, (uint64_t)1,
"HighA");
623 LowB =
Builder.CreateExtractElement(OpB, (uint64_t)0,
"LowB");
624 HighB =
Builder.CreateExtractElement(OpB, (uint64_t)1,
"HighB");
626 LowA =
Builder.CreateShuffleVector(OpA, {0, 2},
"LowA");
627 HighA =
Builder.CreateShuffleVector(OpA, {1, 3},
"HighA");
628 LowB =
Builder.CreateShuffleVector(OpB, {0, 2},
"LowB");
629 HighB =
Builder.CreateShuffleVector(OpB, {1, 3},
"HighB");
636 *
this, Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
637 llvm::Value *ZExtCarry =
638 Builder.CreateZExt(Carry, HighA->getType(),
"CarryZExt");
641 llvm::Value *HighSum =
Builder.CreateAdd(HighA, HighB,
"HighSum");
642 llvm::Value *HighSumPlusCarry =
643 Builder.CreateAdd(HighSum, ZExtCarry,
"HighSumPlusCarry");
645 if (NumElements == 4) {
646 return Builder.CreateShuffleVector(LowSum, HighSumPlusCarry, {0, 2, 1, 3},
652 "hlsl.AddUint64.upto0");
657 case Builtin::BI__builtin_hlsl_resource_getpointer:
658 case Builtin::BI__builtin_hlsl_resource_getpointer_typed: {
661 BuiltinID == Builtin::BI__builtin_hlsl_resource_getpointer_typed ||
665 llvm::Function *IntrFn =
nullptr;
666 llvm::CallInst *CI =
nullptr;
669 IntrFn = llvm::Intrinsic::getOrInsertDeclaration(
671 CGM.getHLSLRuntime().getCreateResourceGetPointerIntrinsic(),
672 {RetTy, HandleOp->getType(), IndexOp->getType()});
675 IntrFn = llvm::Intrinsic::getOrInsertDeclaration(
677 CGM.getHLSLRuntime().getCreateResourceGetBasePointerIntrinsic(),
678 {RetTy, HandleOp->getType()});
681 CI->setCallingConv(IntrFn->getCallingConv());
684 case Builtin::BI__builtin_hlsl_transpose_if_memory_is_row_major: {
694 if (!MatTy || !
getLangOpts().HLSLSpvUseLegacyBufferMatrixOrder)
699 unsigned Rows = MatTy->getNumRows();
700 unsigned Columns = MatTy->getNumColumns();
701 llvm::MatrixBuilder MB(
Builder);
702 return IsLoad ? MB.CreateMatrixTranspose(ValueOp, Columns, Rows)
703 : MB.CreateMatrixTranspose(ValueOp, Rows, Columns);
705 case Builtin::BI__builtin_hlsl_resource_sample: {
712 Args.push_back(HandleOp);
713 Args.push_back(SamplerOp);
714 Args.push_back(CoordOp);
715 constexpr unsigned OffsetIdx = 3;
728 case Builtin::BI__builtin_hlsl_resource_sample_bias: {
738 Args.push_back(HandleOp);
739 Args.push_back(SamplerOp);
740 Args.push_back(CoordOp);
741 Args.push_back(BiasOp);
742 constexpr unsigned OffsetIdx = 4;
755 case Builtin::BI__builtin_hlsl_resource_sample_grad: {
764 Args.push_back(HandleOp);
765 Args.push_back(SamplerOp);
766 Args.push_back(CoordOp);
767 Args.push_back(DDXOp);
768 Args.push_back(DDYOp);
769 constexpr unsigned OffsetIdx = 5;
776 return Builder.CreateIntrinsic(
777 RetTy,
CGM.getHLSLRuntime().getSampleGradIntrinsic(), Args);
780 return Builder.CreateIntrinsic(
781 RetTy,
CGM.getHLSLRuntime().getSampleGradClampIntrinsic(), Args);
783 case Builtin::BI__builtin_hlsl_resource_sample_level: {
793 Args.push_back(HandleOp);
794 Args.push_back(SamplerOp);
795 Args.push_back(CoordOp);
796 Args.push_back(LODOp);
797 constexpr unsigned OffsetIdx = 4;
801 return Builder.CreateIntrinsic(
802 RetTy,
CGM.getHLSLRuntime().getSampleLevelIntrinsic(), Args);
804 case Builtin::BI__builtin_hlsl_resource_load_level: {
809 Value *CoordOp =
nullptr;
810 Value *LODOp =
nullptr;
811 if (RT->getAttrs().ResourceClass == llvm::dxil::ResourceClass::UAV) {
814 CoordOp = CoordLODOp;
815 LODOp = llvm::PoisonValue::get(
Int32Ty);
818 unsigned NumElts = CoordLODVecTy->getNumElements();
819 assert(NumElts >= 2 &&
"CoordLOD must have at least 2 elements");
823 for (
unsigned I = 0; I < NumElts - 1; ++I)
827 Builder.CreateShuffleVector(CoordLODOp, Mask,
"hlsl.load.coord");
828 LODOp =
Builder.CreateExtractElement(CoordLODOp, NumElts - 1,
833 Args.push_back(HandleOp);
834 Args.push_back(CoordOp);
835 Args.push_back(LODOp);
839 return Builder.CreateIntrinsic(
840 RetTy,
CGM.getHLSLRuntime().getLoadLevelIntrinsic(), Args);
842 case Builtin::BI__builtin_hlsl_resource_load_ms: {
852 Args.push_back(HandleOp);
853 Args.push_back(CoordOp);
854 Args.push_back(SampleOp);
858 return Builder.CreateIntrinsic(
859 RetTy,
CGM.getHLSLRuntime().getLoadMSIntrinsic(), Args);
861 case Builtin::BI__builtin_hlsl_resource_sample_cmp: {
871 Args.push_back(HandleOp);
872 Args.push_back(SamplerOp);
873 Args.push_back(CoordOp);
874 Args.push_back(CmpOp);
875 constexpr unsigned OffsetIdx = 4;
881 return Builder.CreateIntrinsic(
882 RetTy,
CGM.getHLSLRuntime().getSampleCmpIntrinsic(), Args);
885 return Builder.CreateIntrinsic(
886 RetTy,
CGM.getHLSLRuntime().getSampleCmpClampIntrinsic(), Args);
888 case Builtin::BI__builtin_hlsl_resource_sample_cmp_level_zero: {
898 Args.push_back(HandleOp);
899 Args.push_back(SamplerOp);
900 Args.push_back(CoordOp);
901 Args.push_back(CmpOp);
902 constexpr unsigned OffsetIdx = 4;
906 return Builder.CreateIntrinsic(
907 RetTy,
CGM.getHLSLRuntime().getSampleCmpLevelZeroIntrinsic(), Args);
909 case Builtin::BI__builtin_hlsl_resource_calculate_lod: {
915 {HandleOp, SamplerOp, CoordOp},
918 case Builtin::BI__builtin_hlsl_resource_calculate_lod_unclamped: {
924 CGM.getHLSLRuntime().getCalculateLodUnclampedIntrinsic(),
927 case Builtin::BI__builtin_hlsl_resource_gather: {
933 ComponentOp =
Builder.CreateIntCast(ComponentOp,
Builder.getInt32Ty(),
938 Args.push_back(HandleOp);
939 Args.push_back(SamplerOp);
940 Args.push_back(CoordOp);
941 Args.push_back(ComponentOp);
945 return Builder.CreateIntrinsic(
946 RetTy,
CGM.getHLSLRuntime().getGatherIntrinsic(), Args);
948 case Builtin::BI__builtin_hlsl_resource_gather_cmp: {
954 CompareOp =
Builder.CreateFPCast(CompareOp,
Builder.getFloatTy());
957 Args.push_back(HandleOp);
958 Args.push_back(SamplerOp);
959 Args.push_back(CoordOp);
960 Args.push_back(CompareOp);
962 if (
CGM.getTarget().getTriple().isDXIL()) {
965 ComponentOp =
Builder.CreateIntCast(ComponentOp,
Builder.getInt32Ty(),
967 Args.push_back(ComponentOp);
974 return Builder.CreateIntrinsic(
975 RetTy,
CGM.getHLSLRuntime().getGatherCmpIntrinsic(), Args);
977 case Builtin::BI__builtin_hlsl_resource_load_with_status:
978 case Builtin::BI__builtin_hlsl_resource_load_with_status_typed: {
987 const HLSLAttributedResourceType *RT =
988 HandleTy->
getAs<HLSLAttributedResourceType>();
989 assert(
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil &&
990 "Only DXIL currently implements load with status");
992 Intrinsic::ID IntrID = RT->getAttrs().RawBuffer
993 ? llvm::Intrinsic::dx_resource_load_rawbuffer
994 : llvm::Intrinsic::dx_resource_load_typedbuffer;
997 llvm::Type *RetTy = llvm::StructType::get(
Builder.getContext(),
998 {DataTy, Builder.getInt1Ty()});
1001 Args.push_back(HandleOp);
1002 Args.push_back(IndexOp);
1007 if (!RT->isStructured())
1008 Offset = llvm::PoisonValue::get(
Builder.getInt32Ty());
1009 Args.push_back(Offset);
1015 Builder.CreateIntrinsic(RetTy, IntrID, Args, {},
"ld.struct");
1016 Value *LoadedValue =
Builder.CreateExtractValue(ResRet, {0},
"ld.value");
1017 Value *StatusBit =
Builder.CreateExtractValue(ResRet, {1},
"ld.status");
1018 Value *ExtendedStatus =
1019 Builder.CreateZExt(StatusBit,
Builder.getInt32Ty(),
"ld.status.ext");
1020 Builder.CreateStore(ExtendedStatus, StatusAddr);
1024 case Builtin::BI__builtin_hlsl_resource_uninitializedhandle: {
1025 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
1026 return llvm::PoisonValue::get(HandleTy);
1028 case Builtin::BI__builtin_hlsl_resource_handlefrombinding: {
1029 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
1035 llvm::Intrinsic::ID IntrinsicID =
1036 CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic();
1038 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
1040 case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: {
1041 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
1047 llvm::Intrinsic::ID IntrinsicID =
1048 CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
1050 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
1052 case Builtin::BI__builtin_hlsl_resource_counterhandlefromimplicitbinding: {
1054 if (!
CGM.getTriple().isSPIRV())
1057 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
1060 llvm::Intrinsic::ID IntrinsicID =
1061 llvm::Intrinsic::spv_resource_counterhandlefromimplicitbinding;
1066 case Builtin::BI__builtin_hlsl_resource_nonuniformindex: {
1069 return Builder.CreateIntrinsic(
1070 RetTy,
CGM.getHLSLRuntime().getNonUniformResourceIndexIntrinsic(),
1073 case Builtin::BI__builtin_hlsl_resource_getdimensions_x:
1074 case Builtin::BI__builtin_hlsl_resource_getdimensions_x_float:
1076 CGM.getHLSLRuntime().getGetDimensionsXIntrinsic(),
1078 case Builtin::BI__builtin_hlsl_resource_getdimensions_xy:
1079 case Builtin::BI__builtin_hlsl_resource_getdimensions_xy_float:
1081 CGM.getHLSLRuntime().getGetDimensionsXYIntrinsic(),
1083 case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy:
1084 case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy_float:
1086 *
this, E,
CGM.getHLSLRuntime().getGetDimensionsLevelsXYIntrinsic(), 3,
1088 case Builtin::BI__builtin_hlsl_resource_getstride: {
1092 case Builtin::BI__builtin_hlsl_all: {
1094 return Builder.CreateIntrinsic(
1099 case Builtin::BI__builtin_hlsl_and: {
1102 return Builder.CreateAnd(Op0, Op1,
"hlsl.and");
1104 case Builtin::BI__builtin_hlsl_or: {
1107 return Builder.CreateOr(Op0, Op1,
"hlsl.or");
1109 case Builtin::BI__builtin_hlsl_any: {
1111 return Builder.CreateIntrinsic(
1116 case Builtin::BI__builtin_hlsl_asdouble:
1118 case Builtin::BI__builtin_hlsl_elementwise_clamp: {
1125 Ty = VecTy->getElementType();
1129 Intr =
CGM.getHLSLRuntime().getNClampIntrinsic();
1131 Intr =
CGM.getHLSLRuntime().getUClampIntrinsic();
1134 Intr =
CGM.getHLSLRuntime().getSClampIntrinsic();
1136 return Builder.CreateIntrinsic(
1140 case Builtin::BI__builtin_hlsl_dot: {
1143 llvm::Type *T0 = Op0->
getType();
1144 llvm::Type *T1 = Op1->
getType();
1147 if (!T0->isVectorTy() && !T1->isVectorTy()) {
1148 if (T0->isFloatingPointTy())
1149 return Builder.CreateFMul(Op0, Op1,
"hlsl.dot");
1151 if (T0->isIntegerTy())
1152 return Builder.CreateMul(Op0, Op1,
"hlsl.dot");
1155 "Scalar dot product is only supported on ints and floats.");
1160 "Dot product operands must have the same type.");
1163 assert(VecTy0 &&
"Dot product argument must be a vector.");
1165 return Builder.CreateIntrinsic(
1166 T0->getScalarType(),
1170 case Builtin::BI__builtin_hlsl_dot4add_i8packed: {
1175 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddI8PackedIntrinsic();
1178 return Builder.CreateIntrinsic(
1180 nullptr,
"hlsl.dot4add.i8packed");
1182 case Builtin::BI__builtin_hlsl_dot4add_u8packed: {
1187 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddU8PackedIntrinsic();
1190 return Builder.CreateIntrinsic(
1192 nullptr,
"hlsl.dot4add.u8packed");
1194 case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
1197 return Builder.CreateIntrinsic(
1202 case Builtin::BI__builtin_hlsl_elementwise_firstbitlow: {
1205 return Builder.CreateIntrinsic(
1208 nullptr,
"hlsl.firstbitlow");
1210 case Builtin::BI__builtin_hlsl_elementwise_f16tof32: {
1213 case Builtin::BI__builtin_hlsl_elementwise_f32tof16: {
1216 case Builtin::BI__builtin_hlsl_elementwise_frac: {
1219 llvm_unreachable(
"frac operand must have a float representation");
1220 return Builder.CreateIntrinsic(
1221 Op0->
getType(),
CGM.getHLSLRuntime().getFracIntrinsic(),
1224 case Builtin::BI__builtin_hlsl_elementwise_isinf: {
1227 llvm_unreachable(
"isinf operand must have a float representation");
1230 return Builder.CreateIntrinsic(
1231 retType,
CGM.getHLSLRuntime().getIsInfIntrinsic(),
1234 case Builtin::BI__builtin_hlsl_elementwise_isnan: {
1237 llvm_unreachable(
"isnan operand must have a float representation");
1240 return Builder.CreateIntrinsic(
1241 retType,
CGM.getHLSLRuntime().getIsNaNIntrinsic(),
1244 case Builtin::BI__builtin_hlsl_mad: {
1249 return Builder.CreateIntrinsic(
1250 M->
getType(), Intrinsic::fmuladd,
1254 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1255 return Builder.CreateIntrinsic(
1256 M->
getType(), Intrinsic::dx_imad,
1260 return Builder.CreateNSWAdd(Mul, B);
1263 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1264 return Builder.CreateIntrinsic(
1265 M->
getType(), Intrinsic::dx_umad,
1269 return Builder.CreateNUWAdd(Mul, B);
1271 case Builtin::BI__builtin_hlsl_mul: {
1289 llvm::MatrixBuilder MB(
Builder);
1290 if (IsVec0 && IsMat1) {
1294 unsigned Cols = MatTy->getNumColumns();
1295 assert(N == Rows &&
"vector length must match matrix row count");
1297 Op1 = MB.CreateRowMajorToColumnMajorTransform(Op1, Rows, Cols);
1298 return MB.CreateMatrixMultiply(Op0, Op1, 1, N, Cols,
"hlsl.mul");
1300 if (IsMat0 && IsVec1) {
1303 unsigned Cols = MatTy->getNumColumns();
1305 "vector length must match matrix column count");
1307 Op0 = MB.CreateRowMajorToColumnMajorTransform(Op0, Rows, Cols);
1308 return MB.CreateMatrixMultiply(Op0, Op1, Rows, Cols, 1,
"hlsl.mul");
1310 assert(IsMat0 && IsMat1);
1315 unsigned Cols0 = MatTy0->getNumColumns();
1317 assert(Cols0 == Rows1 &&
1318 "inner matrix dimensions must match for multiplication");
1320 Op0 = MB.CreateRowMajorToColumnMajorTransform(Op0, Rows0, Cols0);
1322 Op1 = MB.CreateRowMajorToColumnMajorTransform(Op1, Rows1, Cols1);
1325 MB.CreateMatrixMultiply(Op0, Op1, Rows0, Cols0, Cols1,
"hlsl.mul");
1328 if (IsResultRowMajor)
1329 Result = MB.CreateColumnMajorToRowMajorTransform(
Result, Rows0, Cols1);
1332 case Builtin::BI__builtin_hlsl_transpose: {
1336 unsigned Cols = MatTy->getNumColumns();
1337 llvm::MatrixBuilder MB(
Builder);
1344 if (SrcRowMajor != DstRowMajor)
1349 return MB.CreateMatrixTranspose(Op0, Cols, Rows);
1350 return MB.CreateMatrixTranspose(Op0, Rows, Cols);
1352 case Builtin::BI__builtin_hlsl_elementwise_rcp: {
1355 llvm_unreachable(
"rcp operand must have a float representation");
1356 llvm::Type *Ty = Op0->
getType();
1357 llvm::Type *EltTy = Ty->getScalarType();
1359 ? ConstantVector::getSplat(
1360 ElementCount::getFixed(
1362 ConstantFP::get(EltTy, 1.0))
1363 : ConstantFP::get(EltTy, 1.0);
1364 return Builder.CreateFDiv(One, Op0,
"hlsl.rcp");
1366 case Builtin::BI__builtin_hlsl_elementwise_rsqrt: {
1369 llvm_unreachable(
"rsqrt operand must have a float representation");
1370 return Builder.CreateIntrinsic(
1371 Op0->
getType(),
CGM.getHLSLRuntime().getRsqrtIntrinsic(),
1374 case Builtin::BI__builtin_hlsl_elementwise_saturate: {
1377 "saturate operand must have a float representation");
1378 return Builder.CreateIntrinsic(
1381 nullptr,
"hlsl.saturate");
1383 case Builtin::BI__builtin_hlsl_wave_prefix_count_bits: {
1385 assert(Op->
getType()->isIntegerTy(1) &&
1386 "WavePrefixBitCount operand must be a boolean type");
1393 case Builtin::BI__builtin_hlsl_select: {
1406 if (!OpTrue->
getType()->isVectorTy())
1408 Builder.CreateVectorSplat(VTy->getNumElements(), OpTrue,
"splat");
1409 if (!OpFalse->
getType()->isVectorTy())
1411 Builder.CreateVectorSplat(VTy->getNumElements(), OpFalse,
"splat");
1415 Builder.CreateSelect(OpCond, OpTrue, OpFalse,
"hlsl.select");
1422 case Builtin::BI__builtin_hlsl_wave_active_all_equal: {
1425 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllEqualIntrinsic();
1428 case Builtin::BI__builtin_hlsl_wave_active_all_true: {
1430 assert(Op->
getType()->isIntegerTy(1) &&
1431 "Intrinsic WaveActiveAllTrue operand must be a bool");
1433 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllTrueIntrinsic();
1436 case Builtin::BI__builtin_hlsl_wave_active_any_true: {
1438 assert(Op->
getType()->isIntegerTy(1) &&
1439 "Intrinsic WaveActiveAnyTrue operand must be a bool");
1441 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic();
1444 case Builtin::BI__builtin_hlsl_wave_active_bit_or: {
1447 "Intrinsic WaveActiveBitOr operand must have an unsigned integer "
1450 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitOrIntrinsic();
1452 "hlsl.wave.active.bit.or");
1454 case Builtin::BI__builtin_hlsl_wave_active_bit_xor: {
1457 "Intrinsic WaveActiveBitXor operand must have an unsigned integer "
1460 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitXorIntrinsic();
1462 "hlsl.wave.active.bit.xor");
1464 case Builtin::BI__builtin_hlsl_wave_active_bit_and: {
1467 "Intrinsic WaveActiveBitAnd operand must have an unsigned integer "
1470 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitAndIntrinsic();
1472 "hlsl.wave.active.bit.and");
1474 case Builtin::BI__builtin_hlsl_interlocked_add: {
1481 case Builtin::BI__builtin_hlsl_interlocked_and: {
1484 case Builtin::BI__builtin_hlsl_interlocked_min: {
1485 llvm::AtomicRMWInst::BinOp Op =
1487 ? llvm::AtomicRMWInst::Min
1488 : llvm::AtomicRMWInst::UMin;
1491 case Builtin::BI__builtin_hlsl_interlocked_or: {
1494 case Builtin::BI__builtin_hlsl_interlocked_xor: {
1497 case Builtin::BI__builtin_hlsl_wave_active_ballot: {
1499 assert(Op->
getType()->isIntegerTy(1) &&
1500 "Intrinsic WaveActiveBallot operand must be a bool");
1504 case Builtin::BI__builtin_hlsl_wave_active_count_bits: {
1506 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveCountBitsIntrinsic();
1509 case Builtin::BI__builtin_hlsl_wave_active_sum: {
1516 "hlsl.wave.active.sum");
1518 case Builtin::BI__builtin_hlsl_wave_active_product: {
1525 "hlsl.wave.active.product");
1527 case Builtin::BI__builtin_hlsl_wave_active_max: {
1533 IID =
CGM.getHLSLRuntime().getWaveActiveUMaxIntrinsic();
1535 IID =
CGM.getHLSLRuntime().getWaveActiveMaxIntrinsic();
1538 "hlsl.wave.active.max");
1540 case Builtin::BI__builtin_hlsl_wave_active_min: {
1546 IID =
CGM.getHLSLRuntime().getWaveActiveUMinIntrinsic();
1548 IID =
CGM.getHLSLRuntime().getWaveActiveMinIntrinsic();
1551 "hlsl.wave.active.min");
1553 case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
1557 switch (
CGM.getTarget().getTriple().getArch()) {
1558 case llvm::Triple::dxil:
1560 case llvm::Triple::spirv:
1562 llvm::FunctionType::get(
IntTy, {},
false),
1563 "__hlsl_wave_get_lane_index", {},
false,
true));
1566 "Intrinsic WaveGetLaneIndex not supported by target architecture");
1569 case Builtin::BI__builtin_hlsl_wave_is_first_lane: {
1570 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveIsFirstLaneIntrinsic();
1573 case Builtin::BI__builtin_hlsl_wave_get_lane_count: {
1574 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveGetLaneCountIntrinsic();
1577 case Builtin::BI__builtin_hlsl_wave_read_lane_at: {
1583 {OpExpr->getType()},
ArrayRef{OpExpr, OpIndex},
1584 "hlsl.wave.readlane");
1586 case Builtin::BI__builtin_hlsl_wave_prefix_sum: {
1591 "hlsl.wave.prefix.sum");
1593 case Builtin::BI__builtin_hlsl_wave_prefix_product: {
1598 "hlsl.wave.prefix.product");
1600 case Builtin::BI__builtin_hlsl_quad_read_across_x: {
1602 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossXIntrinsic();
1604 "hlsl.quad.read.across.x");
1606 case Builtin::BI__builtin_hlsl_quad_read_across_y: {
1608 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossYIntrinsic();
1610 "hlsl.quad.read.across.y");
1612 case Builtin::BI__builtin_hlsl_quad_read_across_diagonal: {
1615 CGM.getHLSLRuntime().getQuadReadAcrossDiagonalIntrinsic();
1617 &
CGM.getModule(), ID, {OpExpr->getType()}),
1618 ArrayRef{OpExpr},
"hlsl.quad.read.across.diagonal");
1620 case Builtin::BI__builtin_hlsl_elementwise_sign: {
1621 auto *Arg0 = E->
getArg(0);
1623 llvm::Type *Xty = Op0->
getType();
1624 llvm::Type *retType = llvm::Type::getInt32Ty(this->
getLLVMContext());
1625 if (Xty->isVectorTy()) {
1626 auto *XVecTy = Arg0->getType()->castAs<
VectorType>();
1627 retType = llvm::VectorType::get(
1628 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1630 assert((Arg0->getType()->hasFloatingRepresentation() ||
1631 Arg0->getType()->hasIntegerRepresentation()) &&
1632 "sign operand must have a float or int representation");
1634 if (Arg0->getType()->hasUnsignedIntegerRepresentation()) {
1636 return Builder.CreateSelect(
Cmp, ConstantInt::get(retType, 0),
1637 ConstantInt::get(retType, 1),
"hlsl.sign");
1640 return Builder.CreateIntrinsic(
1641 retType,
CGM.getHLSLRuntime().getSignIntrinsic(),
1644 case Builtin::BI__builtin_hlsl_buffer_update_counter: {
1648 return Builder.CreateIntrinsic(
1650 CGM.getHLSLRuntime().getBufferUpdateCounterIntrinsic(),
1653 case Builtin::BI__builtin_hlsl_elementwise_splitdouble: {
1658 "asuint operands types mismatch");
1661 case Builtin::BI__builtin_hlsl_elementwise_clip:
1663 "clip operands types mismatch");
1665 case Builtin::BI__builtin_hlsl_all_memory_barrier: {
1666 Intrinsic::ID ID =
CGM.getHLSLRuntime().getAllMemoryBarrierIntrinsic();
1669 case Builtin::BI__builtin_hlsl_all_memory_barrier_with_group_sync: {
1671 CGM.getHLSLRuntime().getAllMemoryBarrierWithGroupSyncIntrinsic();
1674 case Builtin::BI__builtin_hlsl_device_memory_barrier: {
1675 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDeviceMemoryBarrierIntrinsic();
1678 case Builtin::BI__builtin_hlsl_device_memory_barrier_with_group_sync: {
1680 CGM.getHLSLRuntime().getDeviceMemoryBarrierWithGroupSyncIntrinsic();
1683 case Builtin::BI__builtin_hlsl_group_memory_barrier: {
1684 Intrinsic::ID ID =
CGM.getHLSLRuntime().getGroupMemoryBarrierIntrinsic();
1687 case Builtin::BI__builtin_hlsl_group_memory_barrier_with_group_sync: {
1689 CGM.getHLSLRuntime().getGroupMemoryBarrierWithGroupSyncIntrinsic();
1692 case Builtin::BI__builtin_hlsl_elementwise_ddx_coarse: {
1695 llvm_unreachable(
"ddx_coarse operand must have a float representation");
1696 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxCoarseIntrinsic();
1701 case Builtin::BI__builtin_hlsl_elementwise_ddy_coarse: {
1704 llvm_unreachable(
"ddy_coarse operand must have a float representation");
1705 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyCoarseIntrinsic();
1710 case Builtin::BI__builtin_hlsl_elementwise_ddx_fine: {
1713 llvm_unreachable(
"ddx_fine operand must have a float representation");
1714 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxFineIntrinsic();
1719 case Builtin::BI__builtin_hlsl_elementwise_ddy_fine: {
1722 llvm_unreachable(
"ddy_fine operand must have a float representation");
1723 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyFineIntrinsic();
1728 case Builtin::BI__builtin_get_spirv_spec_constant_bool:
1729 case Builtin::BI__builtin_get_spirv_spec_constant_short:
1730 case Builtin::BI__builtin_get_spirv_spec_constant_ushort:
1731 case Builtin::BI__builtin_get_spirv_spec_constant_int:
1732 case Builtin::BI__builtin_get_spirv_spec_constant_uint:
1733 case Builtin::BI__builtin_get_spirv_spec_constant_longlong:
1734 case Builtin::BI__builtin_get_spirv_spec_constant_ulonglong:
1735 case Builtin::BI__builtin_get_spirv_spec_constant_half:
1736 case Builtin::BI__builtin_get_spirv_spec_constant_float:
1737 case Builtin::BI__builtin_get_spirv_spec_constant_double: {
1741 llvm::Value *Args[] = {SpecId, DefaultVal};
1742 return Builder.CreateCall(SpecConstantFn, Args);