596 case Builtin::BI__builtin_hlsl_adduint64: {
602 "AddUint64 operand types must match");
604 "AddUint64 operands must have an integer representation");
605 assert((NumElements == 2 || NumElements == 4) &&
606 "AddUint64 operands must have 2 or 4 elements");
614 if (NumElements == 2) {
615 LowA =
Builder.CreateExtractElement(OpA, (uint64_t)0,
"LowA");
616 HighA =
Builder.CreateExtractElement(OpA, (uint64_t)1,
"HighA");
617 LowB =
Builder.CreateExtractElement(OpB, (uint64_t)0,
"LowB");
618 HighB =
Builder.CreateExtractElement(OpB, (uint64_t)1,
"HighB");
620 LowA =
Builder.CreateShuffleVector(OpA, {0, 2},
"LowA");
621 HighA =
Builder.CreateShuffleVector(OpA, {1, 3},
"HighA");
622 LowB =
Builder.CreateShuffleVector(OpB, {0, 2},
"LowB");
623 HighB =
Builder.CreateShuffleVector(OpB, {1, 3},
"HighB");
630 *
this, Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
631 llvm::Value *ZExtCarry =
632 Builder.CreateZExt(Carry, HighA->getType(),
"CarryZExt");
635 llvm::Value *HighSum =
Builder.CreateAdd(HighA, HighB,
"HighSum");
636 llvm::Value *HighSumPlusCarry =
637 Builder.CreateAdd(HighSum, ZExtCarry,
"HighSumPlusCarry");
639 if (NumElements == 4) {
640 return Builder.CreateShuffleVector(LowSum, HighSumPlusCarry, {0, 2, 1, 3},
646 "hlsl.AddUint64.upto0");
651 case Builtin::BI__builtin_hlsl_resource_getpointer:
652 case Builtin::BI__builtin_hlsl_resource_getpointer_typed: {
655 BuiltinID == Builtin::BI__builtin_hlsl_resource_getpointer_typed ||
659 llvm::Function *IntrFn =
nullptr;
660 llvm::CallInst *CI =
nullptr;
663 IntrFn = llvm::Intrinsic::getOrInsertDeclaration(
665 CGM.getHLSLRuntime().getCreateResourceGetPointerIntrinsic(),
666 {RetTy, HandleOp->getType(), IndexOp->getType()});
669 IntrFn = llvm::Intrinsic::getOrInsertDeclaration(
671 CGM.getHLSLRuntime().getCreateResourceGetBasePointerIntrinsic(),
672 {RetTy, HandleOp->getType()});
675 CI->setCallingConv(IntrFn->getCallingConv());
678 case Builtin::BI__builtin_hlsl_transpose_if_memory_is_row_major: {
688 if (!MatTy || !
getLangOpts().HLSLSpvUseLegacyBufferMatrixOrder)
693 unsigned Rows = MatTy->getNumRows();
694 unsigned Columns = MatTy->getNumColumns();
695 llvm::MatrixBuilder MB(
Builder);
696 return IsLoad ? MB.CreateMatrixTranspose(ValueOp, Columns, Rows)
697 : MB.CreateMatrixTranspose(ValueOp, Rows, Columns);
699 case Builtin::BI__builtin_hlsl_resource_sample: {
706 Args.push_back(HandleOp);
707 Args.push_back(SamplerOp);
708 Args.push_back(CoordOp);
709 constexpr unsigned OffsetIdx = 3;
722 case Builtin::BI__builtin_hlsl_resource_sample_bias: {
730 Args.push_back(HandleOp);
731 Args.push_back(SamplerOp);
732 Args.push_back(CoordOp);
733 Args.push_back(BiasOp);
734 constexpr unsigned OffsetIdx = 4;
747 case Builtin::BI__builtin_hlsl_resource_sample_grad: {
756 Args.push_back(HandleOp);
757 Args.push_back(SamplerOp);
758 Args.push_back(CoordOp);
759 Args.push_back(DDXOp);
760 Args.push_back(DDYOp);
761 constexpr unsigned OffsetIdx = 5;
768 return Builder.CreateIntrinsic(
769 RetTy,
CGM.getHLSLRuntime().getSampleGradIntrinsic(), Args);
772 return Builder.CreateIntrinsic(
773 RetTy,
CGM.getHLSLRuntime().getSampleGradClampIntrinsic(), Args);
775 case Builtin::BI__builtin_hlsl_resource_sample_level: {
783 Args.push_back(HandleOp);
784 Args.push_back(SamplerOp);
785 Args.push_back(CoordOp);
786 Args.push_back(LODOp);
787 constexpr unsigned OffsetIdx = 4;
791 return Builder.CreateIntrinsic(
792 RetTy,
CGM.getHLSLRuntime().getSampleLevelIntrinsic(), Args);
794 case Builtin::BI__builtin_hlsl_resource_load_level: {
799 const auto &Attrs = RT->getAttrs();
801 Value *CoordOp =
nullptr;
802 Value *LODOp =
nullptr;
803 if (Attrs.ResourceClass == llvm::dxil::ResourceClass::UAV) {
806 CoordOp = CoordLODOp;
807 LODOp = llvm::PoisonValue::get(
Int32Ty);
813 (Attrs.IsArray ? 1 : 0);
815 ->getNumElements() == CoordSize + 1 &&
816 "CoordLOD must have one element per coordinate, plus the level");
818 if (CoordSize == 1) {
819 CoordOp =
Builder.CreateExtractElement(CoordLODOp, uint64_t(0),
823 for (
unsigned I = 0; I < CoordSize; ++I)
826 Builder.CreateShuffleVector(CoordLODOp, Mask,
"hlsl.load.coord");
829 Builder.CreateExtractElement(CoordLODOp, CoordSize,
"hlsl.load.lod");
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: {
849 Args.push_back(HandleOp);
850 Args.push_back(CoordOp);
851 Args.push_back(SampleOp);
855 return Builder.CreateIntrinsic(
856 RetTy,
CGM.getHLSLRuntime().getLoadMSIntrinsic(), Args);
858 case Builtin::BI__builtin_hlsl_resource_sample_cmp: {
866 Args.push_back(HandleOp);
867 Args.push_back(SamplerOp);
868 Args.push_back(CoordOp);
869 Args.push_back(CmpOp);
870 constexpr unsigned OffsetIdx = 4;
876 return Builder.CreateIntrinsic(
877 RetTy,
CGM.getHLSLRuntime().getSampleCmpIntrinsic(), Args);
880 return Builder.CreateIntrinsic(
881 RetTy,
CGM.getHLSLRuntime().getSampleCmpClampIntrinsic(), Args);
883 case Builtin::BI__builtin_hlsl_resource_sample_cmp_level_zero: {
891 Args.push_back(HandleOp);
892 Args.push_back(SamplerOp);
893 Args.push_back(CoordOp);
894 Args.push_back(CmpOp);
895 constexpr unsigned OffsetIdx = 4;
899 return Builder.CreateIntrinsic(
900 RetTy,
CGM.getHLSLRuntime().getSampleCmpLevelZeroIntrinsic(), Args);
902 case Builtin::BI__builtin_hlsl_resource_calculate_lod: {
908 {HandleOp, SamplerOp, CoordOp},
911 case Builtin::BI__builtin_hlsl_resource_calculate_lod_unclamped: {
917 CGM.getHLSLRuntime().getCalculateLodUnclampedIntrinsic(),
920 case Builtin::BI__builtin_hlsl_resource_gather: {
928 Args.push_back(HandleOp);
929 Args.push_back(SamplerOp);
930 Args.push_back(CoordOp);
931 Args.push_back(ComponentOp);
935 return Builder.CreateIntrinsic(
936 RetTy,
CGM.getHLSLRuntime().getGatherIntrinsic(), Args);
938 case Builtin::BI__builtin_hlsl_resource_gather_cmp: {
945 Args.push_back(HandleOp);
946 Args.push_back(SamplerOp);
947 Args.push_back(CoordOp);
948 Args.push_back(CompareOp);
950 if (
CGM.getTarget().getTriple().isDXIL()) {
952 Args.push_back(ComponentOp);
959 return Builder.CreateIntrinsic(
960 RetTy,
CGM.getHLSLRuntime().getGatherCmpIntrinsic(), Args);
962 case Builtin::BI__builtin_hlsl_resource_load_with_status:
963 case Builtin::BI__builtin_hlsl_resource_load_with_status_typed: {
972 const HLSLAttributedResourceType *RT =
973 HandleTy->
getAs<HLSLAttributedResourceType>();
974 assert(
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil &&
975 "Only DXIL currently implements load with status");
977 Intrinsic::ID IntrID = RT->getAttrs().RawBuffer
978 ? llvm::Intrinsic::dx_resource_load_rawbuffer
979 : llvm::Intrinsic::dx_resource_load_typedbuffer;
982 llvm::Type *RetTy = llvm::StructType::get(
Builder.getContext(),
983 {DataTy, Builder.getInt1Ty()});
986 Args.push_back(HandleOp);
987 Args.push_back(IndexOp);
992 if (!RT->isStructured())
993 Offset = llvm::PoisonValue::get(
Builder.getInt32Ty());
994 Args.push_back(Offset);
1000 Builder.CreateIntrinsic(RetTy, IntrID, Args, {},
"ld.struct");
1001 Value *LoadedValue =
Builder.CreateExtractValue(ResRet, {0},
"ld.value");
1002 Value *StatusBit =
Builder.CreateExtractValue(ResRet, {1},
"ld.status");
1003 Value *ExtendedStatus =
1004 Builder.CreateZExt(StatusBit,
Builder.getInt32Ty(),
"ld.status.ext");
1005 Builder.CreateStore(ExtendedStatus, StatusAddr);
1009 case Builtin::BI__builtin_hlsl_resource_uninitializedhandle: {
1010 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
1011 return llvm::PoisonValue::get(HandleTy);
1013 case Builtin::BI__builtin_hlsl_resource_handlefrombinding: {
1014 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
1020 llvm::Intrinsic::ID IntrinsicID =
1021 CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic();
1023 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
1025 case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: {
1026 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
1032 llvm::Intrinsic::ID IntrinsicID =
1033 CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
1035 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
1037 case Builtin::BI__builtin_hlsl_resource_counterhandlefromimplicitbinding: {
1039 if (!
CGM.getTriple().isSPIRV())
1042 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
1045 llvm::Intrinsic::ID IntrinsicID =
1046 llvm::Intrinsic::spv_resource_counterhandlefromimplicitbinding;
1051 case Builtin::BI__builtin_hlsl_resource_handlefromheap: {
1052 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
1054 llvm::Intrinsic::ID IntrinsicID =
1055 CGM.getHLSLRuntime().getCreateHandleFromHeapIntrinsic();
1056 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, {IndexOp});
1058 case Builtin::BI__builtin_hlsl_resource_counterhandlefromheap: {
1060 if (!
CGM.getTriple().isSPIRV())
1063 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
1064 llvm::Intrinsic::ID IntrinsicID =
1065 llvm::Intrinsic::spv_resource_counterhandlefromheap;
1070 case Builtin::BI__builtin_hlsl_resource_nonuniformindex: {
1073 return Builder.CreateIntrinsic(
1074 RetTy,
CGM.getHLSLRuntime().getNonUniformResourceIndexIntrinsic(),
1077 case Builtin::BI__builtin_hlsl_resource_getdimensions_x:
1078 case Builtin::BI__builtin_hlsl_resource_getdimensions_x_float:
1080 CGM.getHLSLRuntime().getGetDimensionsXIntrinsic(),
1082 case Builtin::BI__builtin_hlsl_resource_getdimensions_xy:
1083 case Builtin::BI__builtin_hlsl_resource_getdimensions_xy_float:
1085 CGM.getHLSLRuntime().getGetDimensionsXYIntrinsic(),
1087 case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy:
1088 case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy_float:
1090 *
this, E,
CGM.getHLSLRuntime().getGetDimensionsLevelsXYIntrinsic(), 3,
1092 case Builtin::BI__builtin_hlsl_resource_getstride: {
1096 case Builtin::BI__builtin_hlsl_all: {
1098 return Builder.CreateIntrinsic(
1103 case Builtin::BI__builtin_hlsl_and: {
1106 return Builder.CreateAnd(Op0, Op1,
"hlsl.and");
1108 case Builtin::BI__builtin_hlsl_or: {
1111 return Builder.CreateOr(Op0, Op1,
"hlsl.or");
1113 case Builtin::BI__builtin_hlsl_any: {
1115 return Builder.CreateIntrinsic(
1120 case Builtin::BI__builtin_hlsl_asdouble:
1122 case Builtin::BI__builtin_hlsl_elementwise_clamp: {
1129 Ty = VecTy->getElementType();
1133 Intr =
CGM.getHLSLRuntime().getNClampIntrinsic();
1135 Intr =
CGM.getHLSLRuntime().getUClampIntrinsic();
1138 Intr =
CGM.getHLSLRuntime().getSClampIntrinsic();
1140 return Builder.CreateIntrinsic(
1144 case Builtin::BI__builtin_hlsl_dot: {
1147 llvm::Type *T0 = Op0->
getType();
1148 llvm::Type *T1 = Op1->
getType();
1151 if (!T0->isVectorTy() && !T1->isVectorTy()) {
1152 if (T0->isFloatingPointTy())
1153 return Builder.CreateFMul(Op0, Op1,
"hlsl.dot");
1155 if (T0->isIntegerTy())
1156 return Builder.CreateMul(Op0, Op1,
"hlsl.dot");
1159 "Scalar dot product is only supported on ints and floats.");
1164 "Dot product operands must have the same type.");
1167 assert(VecTy0 &&
"Dot product argument must be a vector.");
1169 return Builder.CreateIntrinsic(
1170 T0->getScalarType(),
1174 case Builtin::BI__builtin_hlsl_dot4add_i8packed: {
1179 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddI8PackedIntrinsic();
1182 return Builder.CreateIntrinsic(
1184 nullptr,
"hlsl.dot4add.i8packed");
1186 case Builtin::BI__builtin_hlsl_dot4add_u8packed: {
1191 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddU8PackedIntrinsic();
1194 return Builder.CreateIntrinsic(
1196 nullptr,
"hlsl.dot4add.u8packed");
1198 case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
1201 return Builder.CreateIntrinsic(
1206 case Builtin::BI__builtin_hlsl_elementwise_firstbitlow: {
1209 return Builder.CreateIntrinsic(
1212 nullptr,
"hlsl.firstbitlow");
1214 case Builtin::BI__builtin_hlsl_elementwise_f16tof32: {
1217 case Builtin::BI__builtin_hlsl_elementwise_f32tof16: {
1220 case Builtin::BI__builtin_hlsl_elementwise_frac: {
1223 llvm_unreachable(
"frac operand must have a float representation");
1224 return Builder.CreateIntrinsic(
1225 Op0->
getType(),
CGM.getHLSLRuntime().getFracIntrinsic(),
1228 case Builtin::BI__builtin_hlsl_elementwise_isinf: {
1231 llvm_unreachable(
"isinf operand must have a float representation");
1234 return Builder.CreateIntrinsic(
1235 retType,
CGM.getHLSLRuntime().getIsInfIntrinsic(),
1238 case Builtin::BI__builtin_hlsl_elementwise_isnan: {
1241 llvm_unreachable(
"isnan operand must have a float representation");
1244 return Builder.CreateIntrinsic(
1245 retType,
CGM.getHLSLRuntime().getIsNaNIntrinsic(),
1248 case Builtin::BI__builtin_hlsl_mad: {
1253 return Builder.CreateIntrinsic(
1254 M->
getType(), Intrinsic::fmuladd,
1258 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1259 return Builder.CreateIntrinsic(
1260 M->
getType(), Intrinsic::dx_imad,
1264 return Builder.CreateNSWAdd(Mul, B);
1267 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1268 return Builder.CreateIntrinsic(
1269 M->
getType(), Intrinsic::dx_umad,
1273 return Builder.CreateNUWAdd(Mul, B);
1275 case Builtin::BI__builtin_hlsl_mul: {
1293 llvm::MatrixBuilder MB(
Builder);
1294 if (IsVec0 && IsMat1) {
1298 unsigned Cols = MatTy->getNumColumns();
1299 assert(N == Rows &&
"vector length must match matrix row count");
1301 Op1 = MB.CreateRowMajorToColumnMajorTransform(Op1, Rows, Cols);
1302 return MB.CreateMatrixMultiply(Op0, Op1, 1, N, Cols,
"hlsl.mul");
1304 if (IsMat0 && IsVec1) {
1307 unsigned Cols = MatTy->getNumColumns();
1309 "vector length must match matrix column count");
1311 Op0 = MB.CreateRowMajorToColumnMajorTransform(Op0, Rows, Cols);
1312 return MB.CreateMatrixMultiply(Op0, Op1, Rows, Cols, 1,
"hlsl.mul");
1314 assert(IsMat0 && IsMat1);
1319 unsigned Cols0 = MatTy0->getNumColumns();
1321 assert(Cols0 == Rows1 &&
1322 "inner matrix dimensions must match for multiplication");
1324 Op0 = MB.CreateRowMajorToColumnMajorTransform(Op0, Rows0, Cols0);
1326 Op1 = MB.CreateRowMajorToColumnMajorTransform(Op1, Rows1, Cols1);
1329 MB.CreateMatrixMultiply(Op0, Op1, Rows0, Cols0, Cols1,
"hlsl.mul");
1332 if (IsResultRowMajor)
1333 Result = MB.CreateColumnMajorToRowMajorTransform(
Result, Rows0, Cols1);
1336 case Builtin::BI__builtin_hlsl_transpose: {
1340 unsigned Cols = MatTy->getNumColumns();
1341 llvm::MatrixBuilder MB(
Builder);
1348 if (SrcRowMajor != DstRowMajor)
1353 return MB.CreateMatrixTranspose(Op0, Cols, Rows);
1354 return MB.CreateMatrixTranspose(Op0, Rows, Cols);
1356 case Builtin::BI__builtin_hlsl_elementwise_rcp: {
1359 llvm_unreachable(
"rcp operand must have a float representation");
1360 llvm::Type *Ty = Op0->
getType();
1361 llvm::Type *EltTy = Ty->getScalarType();
1363 ? ConstantVector::getSplat(
1364 ElementCount::getFixed(
1366 ConstantFP::get(EltTy, 1.0))
1367 : ConstantFP::get(EltTy, 1.0);
1368 return Builder.CreateFDiv(One, Op0,
"hlsl.rcp");
1370 case Builtin::BI__builtin_hlsl_elementwise_rsqrt: {
1373 llvm_unreachable(
"rsqrt operand must have a float representation");
1374 return Builder.CreateIntrinsic(
1375 Op0->
getType(),
CGM.getHLSLRuntime().getRsqrtIntrinsic(),
1378 case Builtin::BI__builtin_hlsl_elementwise_saturate: {
1381 "saturate operand must have a float representation");
1382 return Builder.CreateIntrinsic(
1385 nullptr,
"hlsl.saturate");
1387 case Builtin::BI__builtin_hlsl_wave_prefix_count_bits: {
1389 assert(Op->
getType()->isIntegerTy(1) &&
1390 "WavePrefixBitCount operand must be a boolean type");
1397 case Builtin::BI__builtin_hlsl_select: {
1410 if (!OpTrue->
getType()->isVectorTy())
1412 Builder.CreateVectorSplat(VTy->getNumElements(), OpTrue,
"splat");
1413 if (!OpFalse->
getType()->isVectorTy())
1415 Builder.CreateVectorSplat(VTy->getNumElements(), OpFalse,
"splat");
1419 Builder.CreateSelect(OpCond, OpTrue, OpFalse,
"hlsl.select");
1426 case Builtin::BI__builtin_hlsl_wave_active_all_equal: {
1429 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllEqualIntrinsic();
1432 case Builtin::BI__builtin_hlsl_wave_active_all_true: {
1434 assert(Op->
getType()->isIntegerTy(1) &&
1435 "Intrinsic WaveActiveAllTrue operand must be a bool");
1437 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllTrueIntrinsic();
1440 case Builtin::BI__builtin_hlsl_wave_active_any_true: {
1442 assert(Op->
getType()->isIntegerTy(1) &&
1443 "Intrinsic WaveActiveAnyTrue operand must be a bool");
1445 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic();
1448 case Builtin::BI__builtin_hlsl_wave_active_bit_or: {
1451 "Intrinsic WaveActiveBitOr operand must have an unsigned integer "
1454 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitOrIntrinsic();
1456 "hlsl.wave.active.bit.or");
1458 case Builtin::BI__builtin_hlsl_wave_active_bit_xor: {
1461 "Intrinsic WaveActiveBitXor operand must have an unsigned integer "
1464 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitXorIntrinsic();
1466 "hlsl.wave.active.bit.xor");
1468 case Builtin::BI__builtin_hlsl_wave_active_bit_and: {
1471 "Intrinsic WaveActiveBitAnd operand must have an unsigned integer "
1474 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitAndIntrinsic();
1476 "hlsl.wave.active.bit.and");
1478 case Builtin::BI__builtin_hlsl_interlocked_add: {
1485 case Builtin::BI__builtin_hlsl_interlocked_and: {
1488 case Builtin::BI__builtin_hlsl_interlocked_exchange: {
1491 case Builtin::BI__builtin_hlsl_interlocked_max: {
1492 llvm::AtomicRMWInst::BinOp Op =
1494 ? llvm::AtomicRMWInst::Max
1495 : llvm::AtomicRMWInst::UMax;
1498 case Builtin::BI__builtin_hlsl_interlocked_min: {
1499 llvm::AtomicRMWInst::BinOp Op =
1501 ? llvm::AtomicRMWInst::Min
1502 : llvm::AtomicRMWInst::UMin;
1505 case Builtin::BI__builtin_hlsl_interlocked_or: {
1508 case Builtin::BI__builtin_hlsl_interlocked_xor: {
1511 case Builtin::BI__builtin_hlsl_wave_active_ballot: {
1513 assert(Op->
getType()->isIntegerTy(1) &&
1514 "Intrinsic WaveActiveBallot operand must be a bool");
1518 case Builtin::BI__builtin_hlsl_wave_active_count_bits: {
1520 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveCountBitsIntrinsic();
1523 case Builtin::BI__builtin_hlsl_wave_active_sum: {
1530 "hlsl.wave.active.sum");
1532 case Builtin::BI__builtin_hlsl_wave_active_product: {
1539 "hlsl.wave.active.product");
1541 case Builtin::BI__builtin_hlsl_wave_active_max: {
1547 IID =
CGM.getHLSLRuntime().getWaveActiveUMaxIntrinsic();
1549 IID =
CGM.getHLSLRuntime().getWaveActiveMaxIntrinsic();
1552 "hlsl.wave.active.max");
1554 case Builtin::BI__builtin_hlsl_wave_active_min: {
1560 IID =
CGM.getHLSLRuntime().getWaveActiveUMinIntrinsic();
1562 IID =
CGM.getHLSLRuntime().getWaveActiveMinIntrinsic();
1565 "hlsl.wave.active.min");
1567 case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
1571 switch (
CGM.getTarget().getTriple().getArch()) {
1572 case llvm::Triple::dxil:
1574 case llvm::Triple::spirv:
1576 llvm::FunctionType::get(
IntTy, {},
false),
1577 "__hlsl_wave_get_lane_index", {},
false,
true));
1580 "Intrinsic WaveGetLaneIndex not supported by target architecture");
1583 case Builtin::BI__builtin_hlsl_wave_is_first_lane: {
1584 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveIsFirstLaneIntrinsic();
1587 case Builtin::BI__builtin_hlsl_wave_get_lane_count: {
1588 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveGetLaneCountIntrinsic();
1591 case Builtin::BI__builtin_hlsl_wave_read_lane_at: {
1597 {OpExpr->getType()},
ArrayRef{OpExpr, OpIndex},
1598 "hlsl.wave.readlane");
1600 case Builtin::BI__builtin_hlsl_wave_read_lane_first: {
1603 CGM.getHLSLRuntime().getWaveReadLaneFirstIntrinsic(),
1604 {OpExpr->getType()},
ArrayRef{OpExpr},
"hlsl.wave.readlane.first");
1606 case Builtin::BI__builtin_hlsl_wave_prefix_sum: {
1611 "hlsl.wave.prefix.sum");
1613 case Builtin::BI__builtin_hlsl_wave_prefix_product: {
1618 "hlsl.wave.prefix.product");
1620 case Builtin::BI__builtin_hlsl_quad_read_across_x: {
1622 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossXIntrinsic();
1624 "hlsl.quad.read.across.x");
1626 case Builtin::BI__builtin_hlsl_quad_read_across_y: {
1628 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossYIntrinsic();
1630 "hlsl.quad.read.across.y");
1632 case Builtin::BI__builtin_hlsl_quad_read_across_diagonal: {
1635 CGM.getHLSLRuntime().getQuadReadAcrossDiagonalIntrinsic();
1637 &
CGM.getModule(), ID, {OpExpr->getType()}),
1638 ArrayRef{OpExpr},
"hlsl.quad.read.across.diagonal");
1640 case Builtin::BI__builtin_hlsl_elementwise_sign: {
1641 auto *Arg0 = E->
getArg(0);
1643 llvm::Type *Xty = Op0->
getType();
1644 llvm::Type *retType = llvm::Type::getInt32Ty(this->
getLLVMContext());
1645 if (Xty->isVectorTy()) {
1646 auto *XVecTy = Arg0->getType()->castAs<
VectorType>();
1647 retType = llvm::VectorType::get(
1648 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1650 assert((Arg0->getType()->hasFloatingRepresentation() ||
1651 Arg0->getType()->hasIntegerRepresentation()) &&
1652 "sign operand must have a float or int representation");
1654 if (Arg0->getType()->hasUnsignedIntegerRepresentation()) {
1656 return Builder.CreateSelect(
Cmp, ConstantInt::get(retType, 0),
1657 ConstantInt::get(retType, 1),
"hlsl.sign");
1660 return Builder.CreateIntrinsic(
1661 retType,
CGM.getHLSLRuntime().getSignIntrinsic(),
1664 case Builtin::BI__builtin_hlsl_buffer_update_counter: {
1668 return Builder.CreateIntrinsic(
1670 CGM.getHLSLRuntime().getBufferUpdateCounterIntrinsic(),
1673 case Builtin::BI__builtin_hlsl_elementwise_splitdouble: {
1678 "asuint operands types mismatch");
1681 case Builtin::BI__builtin_hlsl_elementwise_clip:
1683 "clip operands types mismatch");
1685 case Builtin::BI__builtin_hlsl_all_memory_barrier: {
1686 Intrinsic::ID ID =
CGM.getHLSLRuntime().getAllMemoryBarrierIntrinsic();
1689 case Builtin::BI__builtin_hlsl_all_memory_barrier_with_group_sync: {
1691 CGM.getHLSLRuntime().getAllMemoryBarrierWithGroupSyncIntrinsic();
1694 case Builtin::BI__builtin_hlsl_device_memory_barrier: {
1695 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDeviceMemoryBarrierIntrinsic();
1698 case Builtin::BI__builtin_hlsl_device_memory_barrier_with_group_sync: {
1700 CGM.getHLSLRuntime().getDeviceMemoryBarrierWithGroupSyncIntrinsic();
1703 case Builtin::BI__builtin_hlsl_group_memory_barrier: {
1704 Intrinsic::ID ID =
CGM.getHLSLRuntime().getGroupMemoryBarrierIntrinsic();
1707 case Builtin::BI__builtin_hlsl_group_memory_barrier_with_group_sync: {
1709 CGM.getHLSLRuntime().getGroupMemoryBarrierWithGroupSyncIntrinsic();
1712 case Builtin::BI__builtin_hlsl_elementwise_ddx_coarse: {
1715 llvm_unreachable(
"ddx_coarse operand must have a float representation");
1716 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxCoarseIntrinsic();
1721 case Builtin::BI__builtin_hlsl_elementwise_ddy_coarse: {
1724 llvm_unreachable(
"ddy_coarse operand must have a float representation");
1725 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyCoarseIntrinsic();
1730 case Builtin::BI__builtin_hlsl_elementwise_ddx_fine: {
1733 llvm_unreachable(
"ddx_fine operand must have a float representation");
1734 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxFineIntrinsic();
1739 case Builtin::BI__builtin_hlsl_elementwise_ddy_fine: {
1742 llvm_unreachable(
"ddy_fine operand must have a float representation");
1743 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyFineIntrinsic();
1748 case Builtin::BI__builtin_get_spirv_spec_constant_bool:
1749 case Builtin::BI__builtin_get_spirv_spec_constant_short:
1750 case Builtin::BI__builtin_get_spirv_spec_constant_ushort:
1751 case Builtin::BI__builtin_get_spirv_spec_constant_int:
1752 case Builtin::BI__builtin_get_spirv_spec_constant_uint:
1753 case Builtin::BI__builtin_get_spirv_spec_constant_longlong:
1754 case Builtin::BI__builtin_get_spirv_spec_constant_ulonglong:
1755 case Builtin::BI__builtin_get_spirv_spec_constant_half:
1756 case Builtin::BI__builtin_get_spirv_spec_constant_float:
1757 case Builtin::BI__builtin_get_spirv_spec_constant_double: {
1761 llvm::Value *Args[] = {SpecId, DefaultVal};
1762 return Builder.CreateCall(SpecConstantFn, Args);