715 case Builtin::BI__builtin_hlsl_adduint64: {
721 "AddUint64 operand types must match");
723 "AddUint64 operands must have an integer representation");
724 assert((NumElements == 2 || NumElements == 4) &&
725 "AddUint64 operands must have 2 or 4 elements");
733 if (NumElements == 2) {
734 LowA =
Builder.CreateExtractElement(OpA, (uint64_t)0,
"LowA");
735 HighA =
Builder.CreateExtractElement(OpA, (uint64_t)1,
"HighA");
736 LowB =
Builder.CreateExtractElement(OpB, (uint64_t)0,
"LowB");
737 HighB =
Builder.CreateExtractElement(OpB, (uint64_t)1,
"HighB");
739 LowA =
Builder.CreateShuffleVector(OpA, {0, 2},
"LowA");
740 HighA =
Builder.CreateShuffleVector(OpA, {1, 3},
"HighA");
741 LowB =
Builder.CreateShuffleVector(OpB, {0, 2},
"LowB");
742 HighB =
Builder.CreateShuffleVector(OpB, {1, 3},
"HighB");
749 *
this, Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
750 llvm::Value *ZExtCarry =
751 Builder.CreateZExt(Carry, HighA->getType(),
"CarryZExt");
754 llvm::Value *HighSum =
Builder.CreateAdd(HighA, HighB,
"HighSum");
755 llvm::Value *HighSumPlusCarry =
756 Builder.CreateAdd(HighSum, ZExtCarry,
"HighSumPlusCarry");
758 if (NumElements == 4) {
759 return Builder.CreateShuffleVector(LowSum, HighSumPlusCarry, {0, 2, 1, 3},
765 "hlsl.AddUint64.upto0");
770 case Builtin::BI__builtin_hlsl_resource_getpointer:
771 case Builtin::BI__builtin_hlsl_resource_getpointer_typed: {
774 BuiltinID == Builtin::BI__builtin_hlsl_resource_getpointer_typed ||
781 CGM.getHLSLRuntime().getCreateResourceGetPointerIntrinsic(),
782 {RetTy, HandleOp->getType(), IndexOp->getType()},
783 {HandleOp, IndexOp});
787 CGM.getHLSLRuntime().getCreateResourceGetBasePointerIntrinsic(),
788 {RetTy, HandleOp->getType()}, {HandleOp});
790 case Builtin::BI__builtin_hlsl_transpose_if_memory_is_row_major: {
800 if (!MatTy || !
getLangOpts().HLSLSpvUseLegacyBufferMatrixOrder)
805 unsigned Rows = MatTy->getNumRows();
806 unsigned Columns = MatTy->getNumColumns();
807 llvm::MatrixBuilder MB(
Builder);
808 return IsLoad ? MB.CreateMatrixTranspose(ValueOp, Columns, Rows)
809 : MB.CreateMatrixTranspose(ValueOp, Rows, Columns);
811 case Builtin::BI__builtin_hlsl_resource_sample: {
818 Args.push_back(HandleOp);
819 Args.push_back(SamplerOp);
820 Args.push_back(CoordOp);
821 constexpr unsigned OffsetIdx = 3;
834 case Builtin::BI__builtin_hlsl_resource_sample_bias: {
842 Args.push_back(HandleOp);
843 Args.push_back(SamplerOp);
844 Args.push_back(CoordOp);
845 Args.push_back(BiasOp);
846 constexpr unsigned OffsetIdx = 4;
859 case Builtin::BI__builtin_hlsl_resource_sample_grad: {
868 Args.push_back(HandleOp);
869 Args.push_back(SamplerOp);
870 Args.push_back(CoordOp);
871 Args.push_back(DDXOp);
872 Args.push_back(DDYOp);
873 constexpr unsigned OffsetIdx = 5;
880 return Builder.CreateIntrinsic(
881 RetTy,
CGM.getHLSLRuntime().getSampleGradIntrinsic(), Args);
884 return Builder.CreateIntrinsic(
885 RetTy,
CGM.getHLSLRuntime().getSampleGradClampIntrinsic(), Args);
887 case Builtin::BI__builtin_hlsl_resource_sample_level: {
895 Args.push_back(HandleOp);
896 Args.push_back(SamplerOp);
897 Args.push_back(CoordOp);
898 Args.push_back(LODOp);
899 constexpr unsigned OffsetIdx = 4;
903 return Builder.CreateIntrinsic(
904 RetTy,
CGM.getHLSLRuntime().getSampleLevelIntrinsic(), Args);
906 case Builtin::BI__builtin_hlsl_resource_load_level: {
911 const auto &Attrs = RT->getAttrs();
913 Value *CoordOp =
nullptr;
914 Value *LODOp =
nullptr;
915 if (Attrs.ResourceClass == llvm::dxil::ResourceClass::UAV) {
918 CoordOp = CoordLODOp;
919 LODOp = llvm::PoisonValue::get(
Int32Ty);
925 (Attrs.IsArray ? 1 : 0);
927 ->getNumElements() == CoordSize + 1 &&
928 "CoordLOD must have one element per coordinate, plus the level");
930 if (CoordSize == 1) {
931 CoordOp =
Builder.CreateExtractElement(CoordLODOp, uint64_t(0),
935 for (
unsigned I = 0; I < CoordSize; ++I)
938 Builder.CreateShuffleVector(CoordLODOp, Mask,
"hlsl.load.coord");
941 Builder.CreateExtractElement(CoordLODOp, CoordSize,
"hlsl.load.lod");
945 Args.push_back(HandleOp);
946 Args.push_back(CoordOp);
947 Args.push_back(LODOp);
951 return Builder.CreateIntrinsic(
952 RetTy,
CGM.getHLSLRuntime().getLoadLevelIntrinsic(), Args);
954 case Builtin::BI__builtin_hlsl_resource_load_ms: {
961 Args.push_back(HandleOp);
962 Args.push_back(CoordOp);
963 Args.push_back(SampleOp);
967 return Builder.CreateIntrinsic(
968 RetTy,
CGM.getHLSLRuntime().getLoadMSIntrinsic(), Args);
970 case Builtin::BI__builtin_hlsl_resource_sample_cmp: {
978 Args.push_back(HandleOp);
979 Args.push_back(SamplerOp);
980 Args.push_back(CoordOp);
981 Args.push_back(CmpOp);
982 constexpr unsigned OffsetIdx = 4;
988 return Builder.CreateIntrinsic(
989 RetTy,
CGM.getHLSLRuntime().getSampleCmpIntrinsic(), Args);
992 return Builder.CreateIntrinsic(
993 RetTy,
CGM.getHLSLRuntime().getSampleCmpClampIntrinsic(), Args);
995 case Builtin::BI__builtin_hlsl_resource_sample_cmp_level_zero: {
1003 Args.push_back(HandleOp);
1004 Args.push_back(SamplerOp);
1005 Args.push_back(CoordOp);
1006 Args.push_back(CmpOp);
1007 constexpr unsigned OffsetIdx = 4;
1011 return Builder.CreateIntrinsic(
1012 RetTy,
CGM.getHLSLRuntime().getSampleCmpLevelZeroIntrinsic(), Args);
1014 case Builtin::BI__builtin_hlsl_resource_calculate_lod: {
1020 {HandleOp, SamplerOp, CoordOp},
1023 case Builtin::BI__builtin_hlsl_resource_calculate_lod_unclamped: {
1029 CGM.getHLSLRuntime().getCalculateLodUnclampedIntrinsic(),
1032 case Builtin::BI__builtin_hlsl_resource_gather: {
1040 Args.push_back(HandleOp);
1041 Args.push_back(SamplerOp);
1042 Args.push_back(CoordOp);
1043 Args.push_back(ComponentOp);
1047 return Builder.CreateIntrinsic(
1048 RetTy,
CGM.getHLSLRuntime().getGatherIntrinsic(), Args);
1050 case Builtin::BI__builtin_hlsl_resource_gather_cmp: {
1057 Args.push_back(HandleOp);
1058 Args.push_back(SamplerOp);
1059 Args.push_back(CoordOp);
1060 Args.push_back(CompareOp);
1062 if (
CGM.getTarget().getTriple().isDXIL()) {
1064 Args.push_back(ComponentOp);
1071 return Builder.CreateIntrinsic(
1072 RetTy,
CGM.getHLSLRuntime().getGatherCmpIntrinsic(), Args);
1074 case Builtin::BI__builtin_hlsl_resource_load_with_status:
1075 case Builtin::BI__builtin_hlsl_resource_load_with_status_typed: {
1084 const HLSLAttributedResourceType *RT =
1085 HandleTy->
getAs<HLSLAttributedResourceType>();
1086 assert(
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil &&
1087 "Only DXIL currently implements load with status");
1089 Intrinsic::ID IntrID = RT->getAttrs().RawBuffer
1090 ? llvm::Intrinsic::dx_resource_load_rawbuffer
1091 : llvm::Intrinsic::dx_resource_load_typedbuffer;
1094 llvm::Type *RetTy = llvm::StructType::get(
Builder.getContext(),
1095 {DataTy, Builder.getInt1Ty()});
1098 Args.push_back(HandleOp);
1099 Args.push_back(IndexOp);
1104 if (!RT->isStructured())
1105 Offset = llvm::PoisonValue::get(
Builder.getInt32Ty());
1106 Args.push_back(Offset);
1112 Builder.CreateIntrinsic(RetTy, IntrID, Args, {},
"ld.struct");
1113 Value *LoadedValue =
Builder.CreateExtractValue(ResRet, {0},
"ld.value");
1114 Value *StatusBit =
Builder.CreateExtractValue(ResRet, {1},
"ld.status");
1115 Value *ExtendedStatus =
1116 Builder.CreateZExt(StatusBit,
Builder.getInt32Ty(),
"ld.status.ext");
1117 Builder.CreateStore(ExtendedStatus, StatusAddr);
1121 case Builtin::BI__builtin_hlsl_resource_uninitializedhandle: {
1122 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
1123 return llvm::PoisonValue::get(HandleTy);
1125 case Builtin::BI__builtin_hlsl_resource_handlefrombinding: {
1126 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
1132 llvm::Intrinsic::ID IntrinsicID =
1133 CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic();
1135 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
1137 case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: {
1138 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
1144 llvm::Intrinsic::ID IntrinsicID =
1145 CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
1147 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
1149 case Builtin::BI__builtin_hlsl_resource_counterhandlefromimplicitbinding: {
1151 if (!
CGM.getTriple().isSPIRV())
1154 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
1157 llvm::Intrinsic::ID IntrinsicID =
1158 llvm::Intrinsic::spv_resource_counterhandlefromimplicitbinding;
1163 case Builtin::BI__builtin_hlsl_resource_handlefromheap: {
1164 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
1166 llvm::Intrinsic::ID IntrinsicID =
1167 CGM.getHLSLRuntime().getCreateHandleFromHeapIntrinsic();
1168 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, {IndexOp});
1170 case Builtin::BI__builtin_hlsl_resource_counterhandlefromheap: {
1172 if (!
CGM.getTriple().isSPIRV())
1175 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
1176 llvm::Intrinsic::ID IntrinsicID =
1177 llvm::Intrinsic::spv_resource_counterhandlefromheap;
1182 case Builtin::BI__builtin_hlsl_resource_nonuniformindex: {
1185 return Builder.CreateIntrinsic(
1186 RetTy,
CGM.getHLSLRuntime().getNonUniformResourceIndexIntrinsic(),
1189 case Builtin::BI__builtin_hlsl_resource_getdimensions_x:
1190 case Builtin::BI__builtin_hlsl_resource_getdimensions_x_float:
1192 CGM.getHLSLRuntime().getGetDimensionsXIntrinsic(),
1194 case Builtin::BI__builtin_hlsl_resource_getdimensions_xy:
1195 case Builtin::BI__builtin_hlsl_resource_getdimensions_xy_float:
1197 CGM.getHLSLRuntime().getGetDimensionsXYIntrinsic(),
1199 case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy:
1200 case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy_float:
1202 *
this, E,
CGM.getHLSLRuntime().getGetDimensionsLevelsXYIntrinsic(), 3,
1204 case Builtin::BI__builtin_hlsl_resource_getstride: {
1208 case Builtin::BI__builtin_hlsl_all: {
1210 return Builder.CreateIntrinsic(
1215 case Builtin::BI__builtin_hlsl_and: {
1218 return Builder.CreateAnd(Op0, Op1,
"hlsl.and");
1220 case Builtin::BI__builtin_hlsl_or: {
1223 return Builder.CreateOr(Op0, Op1,
"hlsl.or");
1225 case Builtin::BI__builtin_hlsl_any: {
1227 return Builder.CreateIntrinsic(
1232 case Builtin::BI__builtin_hlsl_asdouble:
1234 case Builtin::BI__builtin_hlsl_elementwise_clamp: {
1241 Ty = VecTy->getElementType();
1245 Intr =
CGM.getHLSLRuntime().getNClampIntrinsic();
1247 Intr =
CGM.getHLSLRuntime().getUClampIntrinsic();
1250 Intr =
CGM.getHLSLRuntime().getSClampIntrinsic();
1252 return Builder.CreateIntrinsic(
1256 case Builtin::BI__builtin_hlsl_dot: {
1259 llvm::Type *T0 = Op0->
getType();
1260 llvm::Type *T1 = Op1->
getType();
1263 if (!T0->isVectorTy() && !T1->isVectorTy()) {
1264 if (T0->isFloatingPointTy())
1265 return Builder.CreateFMul(Op0, Op1,
"hlsl.dot");
1267 if (T0->isIntegerTy())
1268 return Builder.CreateMul(Op0, Op1,
"hlsl.dot");
1271 "Scalar dot product is only supported on ints and floats.");
1276 "Dot product operands must have the same type.");
1279 assert(VecTy0 &&
"Dot product argument must be a vector.");
1281 return Builder.CreateIntrinsic(
1282 T0->getScalarType(),
1286 case Builtin::BI__builtin_hlsl_dot4add_i8packed: {
1291 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddI8PackedIntrinsic();
1294 return Builder.CreateIntrinsic(
1296 nullptr,
"hlsl.dot4add.i8packed");
1298 case Builtin::BI__builtin_hlsl_dot4add_u8packed: {
1303 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddU8PackedIntrinsic();
1306 return Builder.CreateIntrinsic(
1308 nullptr,
"hlsl.dot4add.u8packed");
1310 case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
1313 return Builder.CreateIntrinsic(
1318 case Builtin::BI__builtin_hlsl_elementwise_firstbitlow: {
1321 return Builder.CreateIntrinsic(
1324 nullptr,
"hlsl.firstbitlow");
1326 case Builtin::BI__builtin_hlsl_elementwise_f16tof32: {
1329 case Builtin::BI__builtin_hlsl_elementwise_f32tof16: {
1332 case Builtin::BI__builtin_hlsl_elementwise_frac: {
1335 llvm_unreachable(
"frac operand must have a float representation");
1336 return Builder.CreateIntrinsic(
1337 Op0->
getType(),
CGM.getHLSLRuntime().getFracIntrinsic(),
1340 case Builtin::BI__builtin_hlsl_elementwise_isfinite: {
1343 llvm_unreachable(
"isfinite operand must have a float representation");
1346 return Builder.CreateIntrinsic(
1347 retType,
CGM.getHLSLRuntime().getIsFiniteIntrinsic(),
1350 case Builtin::BI__builtin_hlsl_elementwise_isinf: {
1353 llvm_unreachable(
"isinf operand must have a float representation");
1356 return Builder.CreateIntrinsic(
1357 retType,
CGM.getHLSLRuntime().getIsInfIntrinsic(),
1360 case Builtin::BI__builtin_hlsl_elementwise_isnan: {
1363 llvm_unreachable(
"isnan operand must have a float representation");
1366 return Builder.CreateIntrinsic(
1367 retType,
CGM.getHLSLRuntime().getIsNaNIntrinsic(),
1370 case Builtin::BI__builtin_hlsl_mad: {
1375 return Builder.CreateIntrinsic(
1376 M->
getType(), Intrinsic::fmuladd,
1380 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1381 return Builder.CreateIntrinsic(
1382 M->
getType(), Intrinsic::dx_imad,
1386 return Builder.CreateNSWAdd(Mul, B);
1389 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1390 return Builder.CreateIntrinsic(
1391 M->
getType(), Intrinsic::dx_umad,
1395 return Builder.CreateNUWAdd(Mul, B);
1397 case Builtin::BI__builtin_hlsl_mul: {
1408 llvm::MatrixBuilder MB(
Builder);
1409 if (IsVec0 && IsMat1) {
1413 assert(N == MatTy->getNumRows() &&
1414 "vector length must match matrix row count");
1415 return MB.CreateMatrixMultiply(Op0, Op1, 1, N, Cols,
"hlsl.mul");
1417 if (IsMat0 && IsVec1) {
1420 unsigned Cols = MatTy->getNumColumns();
1422 "vector length must match matrix column count");
1423 return MB.CreateMatrixMultiply(Op0, Op1, Rows, Cols, 1,
"hlsl.mul");
1425 assert(IsMat0 && IsMat1);
1429 unsigned Cols0 = MatTy0->getNumColumns();
1432 "inner matrix dimensions must match for multiplication");
1433 return MB.CreateMatrixMultiply(Op0, Op1, Rows0, Cols0, Cols1,
"hlsl.mul");
1435 case Builtin::BI__builtin_hlsl_transpose: {
1439 unsigned Cols = MatTy->getNumColumns();
1440 if (
auto *Transpose = dyn_cast<CallInst>(Op0);
1442 Transpose->getIntrinsicID() == Intrinsic::matrix_transpose &&
1443 Transpose->use_empty() &&
1449 Transpose->eraseFromParent();
1452 llvm::MatrixBuilder MB(
Builder);
1453 return MB.CreateMatrixTranspose(Op0, Rows, Cols);
1455 case Builtin::BI__builtin_hlsl_elementwise_rcp: {
1458 llvm_unreachable(
"rcp operand must have a float representation");
1459 llvm::Type *Ty = Op0->
getType();
1460 llvm::Type *EltTy = Ty->getScalarType();
1462 ? ConstantVector::getSplat(
1463 ElementCount::getFixed(
1465 ConstantFP::get(EltTy, 1.0))
1466 : ConstantFP::get(EltTy, 1.0);
1467 return Builder.CreateFDiv(One, Op0,
"hlsl.rcp");
1469 case Builtin::BI__builtin_hlsl_elementwise_rsqrt: {
1472 llvm_unreachable(
"rsqrt operand must have a float representation");
1473 return Builder.CreateIntrinsic(
1474 Op0->
getType(),
CGM.getHLSLRuntime().getRsqrtIntrinsic(),
1477 case Builtin::BI__builtin_hlsl_elementwise_saturate: {
1480 "saturate operand must have a float representation");
1481 return Builder.CreateIntrinsic(
1484 nullptr,
"hlsl.saturate");
1486 case Builtin::BI__builtin_hlsl_wave_prefix_count_bits: {
1488 assert(Op->
getType()->isIntegerTy(1) &&
1489 "WavePrefixBitCount operand must be a boolean type");
1496 case Builtin::BI__builtin_hlsl_select: {
1509 unsigned NumElements = 0;
1511 NumElements = VTy->getNumElements();
1513 NumElements = MTy->getNumElementsFlattened();
1515 if (!OpTrue->
getType()->isVectorTy())
1516 OpTrue =
Builder.CreateVectorSplat(NumElements, OpTrue,
"splat");
1517 if (!OpFalse->
getType()->isVectorTy())
1518 OpFalse =
Builder.CreateVectorSplat(NumElements, OpFalse,
"splat");
1522 Builder.CreateSelect(OpCond, OpTrue, OpFalse,
"hlsl.select");
1529 case Builtin::BI__builtin_hlsl_wave_active_all_equal: {
1532 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllEqualIntrinsic();
1535 case Builtin::BI__builtin_hlsl_wave_active_all_true: {
1537 assert(Op->
getType()->isIntegerTy(1) &&
1538 "Intrinsic WaveActiveAllTrue operand must be a bool");
1540 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllTrueIntrinsic();
1543 case Builtin::BI__builtin_hlsl_wave_active_any_true: {
1545 assert(Op->
getType()->isIntegerTy(1) &&
1546 "Intrinsic WaveActiveAnyTrue operand must be a bool");
1548 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic();
1551 case Builtin::BI__builtin_hlsl_wave_active_bit_or: {
1554 "Intrinsic WaveActiveBitOr operand must have an unsigned integer "
1557 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitOrIntrinsic();
1559 "hlsl.wave.active.bit.or");
1561 case Builtin::BI__builtin_hlsl_wave_active_bit_xor: {
1564 "Intrinsic WaveActiveBitXor operand must have an unsigned integer "
1567 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitXorIntrinsic();
1569 "hlsl.wave.active.bit.xor");
1571 case Builtin::BI__builtin_hlsl_wave_active_bit_and: {
1574 "Intrinsic WaveActiveBitAnd operand must have an unsigned integer "
1577 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitAndIntrinsic();
1579 "hlsl.wave.active.bit.and");
1581 case Builtin::BI__builtin_hlsl_interlocked_add: {
1588 case Builtin::BI__builtin_hlsl_interlocked_and: {
1591 case Builtin::BI__builtin_hlsl_interlocked_compare_exchange:
1592 case Builtin::BI__builtin_hlsl_interlocked_compare_exchange_float_bitwise:
1593 case Builtin::BI__builtin_hlsl_interlocked_compare_store:
1594 case Builtin::BI__builtin_hlsl_interlocked_compare_store_float_bitwise: {
1597 case Builtin::BI__builtin_hlsl_interlocked_exchange: {
1600 case Builtin::BI__builtin_hlsl_interlocked_max: {
1601 llvm::AtomicRMWInst::BinOp Op =
1603 ? llvm::AtomicRMWInst::Max
1604 : llvm::AtomicRMWInst::UMax;
1607 case Builtin::BI__builtin_hlsl_interlocked_min: {
1608 llvm::AtomicRMWInst::BinOp Op =
1610 ? llvm::AtomicRMWInst::Min
1611 : llvm::AtomicRMWInst::UMin;
1614 case Builtin::BI__builtin_hlsl_interlocked_or: {
1617 case Builtin::BI__builtin_hlsl_interlocked_xor: {
1620 case Builtin::BI__builtin_hlsl_wave_active_ballot: {
1622 assert(Op->
getType()->isIntegerTy(1) &&
1623 "Intrinsic WaveActiveBallot operand must be a bool");
1627 case Builtin::BI__builtin_hlsl_wave_active_count_bits: {
1629 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveCountBitsIntrinsic();
1632 case Builtin::BI__builtin_hlsl_wave_active_sum: {
1639 "hlsl.wave.active.sum");
1641 case Builtin::BI__builtin_hlsl_wave_active_product: {
1648 "hlsl.wave.active.product");
1650 case Builtin::BI__builtin_hlsl_wave_active_max: {
1656 IID =
CGM.getHLSLRuntime().getWaveActiveUMaxIntrinsic();
1658 IID =
CGM.getHLSLRuntime().getWaveActiveMaxIntrinsic();
1661 "hlsl.wave.active.max");
1663 case Builtin::BI__builtin_hlsl_wave_active_min: {
1669 IID =
CGM.getHLSLRuntime().getWaveActiveUMinIntrinsic();
1671 IID =
CGM.getHLSLRuntime().getWaveActiveMinIntrinsic();
1674 "hlsl.wave.active.min");
1676 case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
1680 switch (
CGM.getTarget().getTriple().getArch()) {
1681 case llvm::Triple::dxil:
1683 case llvm::Triple::spirv:
1685 CGM.CreateRuntimeFunction(llvm::FunctionType::get(
IntTy, {},
false),
1686 "__hlsl_wave_get_lane_index", {},
false,
1691 "Intrinsic WaveGetLaneIndex not supported by target architecture");
1694 case Builtin::BI__builtin_hlsl_wave_is_first_lane: {
1695 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveIsFirstLaneIntrinsic();
1698 case Builtin::BI__builtin_hlsl_wave_get_lane_count: {
1699 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveGetLaneCountIntrinsic();
1702 case Builtin::BI__builtin_hlsl_wave_read_lane_at: {
1708 {OpExpr->getType()},
ArrayRef{OpExpr, OpIndex},
1709 "hlsl.wave.readlane");
1711 case Builtin::BI__builtin_hlsl_wave_read_lane_first: {
1714 CGM.getHLSLRuntime().getWaveReadLaneFirstIntrinsic(),
1715 {OpExpr->getType()},
ArrayRef{OpExpr},
"hlsl.wave.readlane.first");
1717 case Builtin::BI__builtin_hlsl_wave_prefix_sum: {
1722 "hlsl.wave.prefix.sum");
1724 case Builtin::BI__builtin_hlsl_wave_prefix_product: {
1729 "hlsl.wave.prefix.product");
1731 case Builtin::BI__builtin_hlsl_quad_read_across_x: {
1733 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossXIntrinsic();
1735 "hlsl.quad.read.across.x");
1737 case Builtin::BI__builtin_hlsl_quad_read_across_y: {
1739 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossYIntrinsic();
1741 "hlsl.quad.read.across.y");
1743 case Builtin::BI__builtin_hlsl_quad_read_across_diagonal: {
1746 CGM.getHLSLRuntime().getQuadReadAcrossDiagonalIntrinsic();
1748 "hlsl.quad.read.across.diagonal");
1750 case Builtin::BI__builtin_hlsl_elementwise_sign: {
1751 auto *Arg0 = E->
getArg(0);
1753 llvm::Type *Xty = Op0->
getType();
1754 llvm::Type *retType = llvm::Type::getInt32Ty(this->
getLLVMContext());
1755 if (Xty->isVectorTy()) {
1756 auto *XVecTy = Arg0->getType()->castAs<
VectorType>();
1757 retType = llvm::VectorType::get(
1758 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1760 assert((Arg0->getType()->hasFloatingRepresentation() ||
1761 Arg0->getType()->hasIntegerRepresentation()) &&
1762 "sign operand must have a float or int representation");
1764 if (Arg0->getType()->hasUnsignedIntegerRepresentation()) {
1766 return Builder.CreateSelect(
Cmp, ConstantInt::get(retType, 0),
1767 ConstantInt::get(retType, 1),
"hlsl.sign");
1770 return Builder.CreateIntrinsic(
1771 retType,
CGM.getHLSLRuntime().getSignIntrinsic(),
1774 case Builtin::BI__builtin_hlsl_buffer_update_counter: {
1778 return Builder.CreateIntrinsic(
1780 CGM.getHLSLRuntime().getBufferUpdateCounterIntrinsic(),
1783 case Builtin::BI__builtin_hlsl_elementwise_splitdouble: {
1788 "asuint operands types mismatch");
1791 case Builtin::BI__builtin_hlsl_elementwise_clip:
1793 "clip operands types mismatch");
1795 case Builtin::BI__builtin_hlsl_all_memory_barrier: {
1796 Intrinsic::ID ID =
CGM.getHLSLRuntime().getAllMemoryBarrierIntrinsic();
1799 case Builtin::BI__builtin_hlsl_all_memory_barrier_with_group_sync: {
1801 CGM.getHLSLRuntime().getAllMemoryBarrierWithGroupSyncIntrinsic();
1804 case Builtin::BI__builtin_hlsl_device_memory_barrier: {
1805 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDeviceMemoryBarrierIntrinsic();
1808 case Builtin::BI__builtin_hlsl_device_memory_barrier_with_group_sync: {
1810 CGM.getHLSLRuntime().getDeviceMemoryBarrierWithGroupSyncIntrinsic();
1813 case Builtin::BI__builtin_hlsl_group_memory_barrier: {
1814 Intrinsic::ID ID =
CGM.getHLSLRuntime().getGroupMemoryBarrierIntrinsic();
1817 case Builtin::BI__builtin_hlsl_group_memory_barrier_with_group_sync: {
1819 CGM.getHLSLRuntime().getGroupMemoryBarrierWithGroupSyncIntrinsic();
1822 case Builtin::BI__builtin_hlsl_barrier: {
1823 std::optional<llvm::APSInt> SemanticFlagsConstant =
1825 assert(SemanticFlagsConstant &&
"expected constant semantic flags");
1826 constexpr uint64_t GroupScope =
1827 llvm::to_underlying(llvm::dxil::BarrierSemanticFlag::GroupScope);
1829 llvm::to_underlying(llvm::dxil::BarrierSemanticFlag::DeviceScope);
1830 constexpr uint64_t ScopeMask = GroupScope |
DeviceScope;
1831 uint64_t SemanticFlagsValue = SemanticFlagsConstant->getZExtValue();
1834 if ((SemanticFlagsValue & ScopeMask) == ScopeMask)
1835 SemanticFlagsValue &= ~GroupScope;
1836 Value *SemanticFlags = llvm::ConstantInt::get(
1840 std::optional<llvm::APSInt> MemoryFlagsConstant =
1842 assert(MemoryFlagsConstant &&
"expected constant memory flags");
1843 uint64_t MemoryFlagsValue = MemoryFlagsConstant->getZExtValue();
1844 llvm::Triple::EnvironmentType Stage =
1846 if (Stage == llvm::Triple::Library)
1847 if (
const auto *FD = dyn_cast_or_null<FunctionDecl>(
CurFuncDecl))
1848 if (
const auto *ShaderAttr = FD->getAttr<HLSLShaderAttr>())
1849 Stage = ShaderAttr->getType();
1852 Value *MemoryFlags = llvm::ConstantInt::get(
1854 Intrinsic::ID ID =
CGM.getHLSLRuntime().getBarrierByMemoryTypeIntrinsic();
1863 Value *HandleValue =
1865 Intrinsic::ID ID =
CGM.getHLSLRuntime().getBarrierByMemoryHandleIntrinsic();
1869 case Builtin::BI__builtin_hlsl_elementwise_ddx_coarse: {
1872 llvm_unreachable(
"ddx_coarse operand must have a float representation");
1873 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxCoarseIntrinsic();
1878 case Builtin::BI__builtin_hlsl_elementwise_ddy_coarse: {
1881 llvm_unreachable(
"ddy_coarse operand must have a float representation");
1882 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyCoarseIntrinsic();
1887 case Builtin::BI__builtin_hlsl_elementwise_ddx_fine: {
1890 llvm_unreachable(
"ddx_fine operand must have a float representation");
1891 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxFineIntrinsic();
1896 case Builtin::BI__builtin_hlsl_elementwise_ddy_fine: {
1899 llvm_unreachable(
"ddy_fine operand must have a float representation");
1900 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyFineIntrinsic();
1905 case Builtin::BI__builtin_get_spirv_spec_constant_bool:
1906 case Builtin::BI__builtin_get_spirv_spec_constant_short:
1907 case Builtin::BI__builtin_get_spirv_spec_constant_ushort:
1908 case Builtin::BI__builtin_get_spirv_spec_constant_int:
1909 case Builtin::BI__builtin_get_spirv_spec_constant_uint:
1910 case Builtin::BI__builtin_get_spirv_spec_constant_longlong:
1911 case Builtin::BI__builtin_get_spirv_spec_constant_ulonglong:
1912 case Builtin::BI__builtin_get_spirv_spec_constant_half:
1913 case Builtin::BI__builtin_get_spirv_spec_constant_float:
1914 case Builtin::BI__builtin_get_spirv_spec_constant_double: {
1918 llvm::Value *Args[] = {SpecId, DefaultVal};
1919 return Builder.CreateCall(SpecConstantFn, Args);