586 case Builtin::BI__builtin_hlsl_adduint64: {
592 "AddUint64 operand types must match");
594 "AddUint64 operands must have an integer representation");
595 assert((NumElements == 2 || NumElements == 4) &&
596 "AddUint64 operands must have 2 or 4 elements");
604 if (NumElements == 2) {
605 LowA =
Builder.CreateExtractElement(OpA, (uint64_t)0,
"LowA");
606 HighA =
Builder.CreateExtractElement(OpA, (uint64_t)1,
"HighA");
607 LowB =
Builder.CreateExtractElement(OpB, (uint64_t)0,
"LowB");
608 HighB =
Builder.CreateExtractElement(OpB, (uint64_t)1,
"HighB");
610 LowA =
Builder.CreateShuffleVector(OpA, {0, 2},
"LowA");
611 HighA =
Builder.CreateShuffleVector(OpA, {1, 3},
"HighA");
612 LowB =
Builder.CreateShuffleVector(OpB, {0, 2},
"LowB");
613 HighB =
Builder.CreateShuffleVector(OpB, {1, 3},
"HighB");
620 *
this, Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
621 llvm::Value *ZExtCarry =
622 Builder.CreateZExt(Carry, HighA->getType(),
"CarryZExt");
625 llvm::Value *HighSum =
Builder.CreateAdd(HighA, HighB,
"HighSum");
626 llvm::Value *HighSumPlusCarry =
627 Builder.CreateAdd(HighSum, ZExtCarry,
"HighSumPlusCarry");
629 if (NumElements == 4) {
630 return Builder.CreateShuffleVector(LowSum, HighSumPlusCarry, {0, 2, 1, 3},
636 "hlsl.AddUint64.upto0");
641 case Builtin::BI__builtin_hlsl_resource_getpointer:
642 case Builtin::BI__builtin_hlsl_resource_getpointer_typed: {
645 BuiltinID == Builtin::BI__builtin_hlsl_resource_getpointer_typed ||
649 llvm::Function *IntrFn =
nullptr;
650 llvm::CallInst *CI =
nullptr;
653 IntrFn = llvm::Intrinsic::getOrInsertDeclaration(
655 CGM.getHLSLRuntime().getCreateResourceGetPointerIntrinsic(),
656 {RetTy, HandleOp->getType(), IndexOp->getType()});
659 IntrFn = llvm::Intrinsic::getOrInsertDeclaration(
661 CGM.getHLSLRuntime().getCreateResourceGetBasePointerIntrinsic(),
662 {RetTy, HandleOp->getType()});
665 CI->setCallingConv(IntrFn->getCallingConv());
668 case Builtin::BI__builtin_hlsl_resource_sample: {
675 Args.push_back(HandleOp);
676 Args.push_back(SamplerOp);
677 Args.push_back(CoordOp);
682 return Builder.CreateIntrinsic(
683 RetTy,
CGM.getHLSLRuntime().getSampleIntrinsic(), Args);
687 return Builder.CreateIntrinsic(
688 RetTy,
CGM.getHLSLRuntime().getSampleClampIntrinsic(), Args);
690 case Builtin::BI__builtin_hlsl_resource_sample_bias: {
700 Args.push_back(HandleOp);
701 Args.push_back(SamplerOp);
702 Args.push_back(CoordOp);
703 Args.push_back(BiasOp);
708 return Builder.CreateIntrinsic(
709 RetTy,
CGM.getHLSLRuntime().getSampleBiasIntrinsic(), Args);
712 return Builder.CreateIntrinsic(
713 RetTy,
CGM.getHLSLRuntime().getSampleBiasClampIntrinsic(), Args);
715 case Builtin::BI__builtin_hlsl_resource_sample_grad: {
724 Args.push_back(HandleOp);
725 Args.push_back(SamplerOp);
726 Args.push_back(CoordOp);
727 Args.push_back(DDXOp);
728 Args.push_back(DDYOp);
734 return Builder.CreateIntrinsic(
735 RetTy,
CGM.getHLSLRuntime().getSampleGradIntrinsic(), Args);
739 return Builder.CreateIntrinsic(
740 RetTy,
CGM.getHLSLRuntime().getSampleGradClampIntrinsic(), Args);
742 case Builtin::BI__builtin_hlsl_resource_sample_level: {
752 Args.push_back(HandleOp);
753 Args.push_back(SamplerOp);
754 Args.push_back(CoordOp);
755 Args.push_back(LODOp);
759 return Builder.CreateIntrinsic(
760 RetTy,
CGM.getHLSLRuntime().getSampleLevelIntrinsic(), Args);
762 case Builtin::BI__builtin_hlsl_resource_load_level: {
767 unsigned NumElts = CoordLODVecTy->getNumElements();
768 assert(NumElts >= 2 &&
"CoordLOD must have at least 2 elements");
772 for (
unsigned I = 0; I < NumElts - 1; ++I)
776 Builder.CreateShuffleVector(CoordLODOp, Mask,
"hlsl.load.coord");
778 Builder.CreateExtractElement(CoordLODOp, NumElts - 1,
"hlsl.load.lod");
782 Args.push_back(HandleOp);
783 Args.push_back(CoordOp);
784 Args.push_back(LODOp);
788 return Builder.CreateIntrinsic(
789 RetTy,
CGM.getHLSLRuntime().getLoadLevelIntrinsic(), Args);
791 case Builtin::BI__builtin_hlsl_resource_sample_cmp: {
801 Args.push_back(HandleOp);
802 Args.push_back(SamplerOp);
803 Args.push_back(CoordOp);
804 Args.push_back(CmpOp);
809 return Builder.CreateIntrinsic(
810 RetTy,
CGM.getHLSLRuntime().getSampleCmpIntrinsic(), Args);
814 return Builder.CreateIntrinsic(
815 RetTy,
CGM.getHLSLRuntime().getSampleCmpClampIntrinsic(), Args);
817 case Builtin::BI__builtin_hlsl_resource_sample_cmp_level_zero: {
827 Args.push_back(HandleOp);
828 Args.push_back(SamplerOp);
829 Args.push_back(CoordOp);
830 Args.push_back(CmpOp);
834 return Builder.CreateIntrinsic(
835 RetTy,
CGM.getHLSLRuntime().getSampleCmpLevelZeroIntrinsic(), Args);
837 case Builtin::BI__builtin_hlsl_resource_calculate_lod: {
842 return Builder.CreateIntrinsic(
844 CGM.getHLSLRuntime().getCalculateLodIntrinsic(),
845 {HandleOp, SamplerOp, CoordOp});
847 case Builtin::BI__builtin_hlsl_resource_calculate_lod_unclamped: {
852 return Builder.CreateIntrinsic(
854 CGM.getHLSLRuntime().getCalculateLodUnclampedIntrinsic(),
855 {HandleOp, SamplerOp, CoordOp});
857 case Builtin::BI__builtin_hlsl_resource_gather: {
863 ComponentOp =
Builder.CreateIntCast(ComponentOp,
Builder.getInt32Ty(),
868 Args.push_back(HandleOp);
869 Args.push_back(SamplerOp);
870 Args.push_back(CoordOp);
871 Args.push_back(ComponentOp);
875 return Builder.CreateIntrinsic(
876 RetTy,
CGM.getHLSLRuntime().getGatherIntrinsic(), Args);
878 case Builtin::BI__builtin_hlsl_resource_gather_cmp: {
884 CompareOp =
Builder.CreateFPCast(CompareOp,
Builder.getFloatTy());
887 Args.push_back(HandleOp);
888 Args.push_back(SamplerOp);
889 Args.push_back(CoordOp);
890 Args.push_back(CompareOp);
892 if (
CGM.getTarget().getTriple().isDXIL()) {
895 ComponentOp =
Builder.CreateIntCast(ComponentOp,
Builder.getInt32Ty(),
897 Args.push_back(ComponentOp);
904 return Builder.CreateIntrinsic(
905 RetTy,
CGM.getHLSLRuntime().getGatherCmpIntrinsic(), Args);
907 case Builtin::BI__builtin_hlsl_resource_load_with_status:
908 case Builtin::BI__builtin_hlsl_resource_load_with_status_typed: {
917 const HLSLAttributedResourceType *RT =
918 HandleTy->
getAs<HLSLAttributedResourceType>();
919 assert(
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil &&
920 "Only DXIL currently implements load with status");
922 Intrinsic::ID IntrID = RT->getAttrs().RawBuffer
923 ? llvm::Intrinsic::dx_resource_load_rawbuffer
924 : llvm::Intrinsic::dx_resource_load_typedbuffer;
927 llvm::Type *RetTy = llvm::StructType::get(
Builder.getContext(),
928 {DataTy, Builder.getInt1Ty()});
931 Args.push_back(HandleOp);
932 Args.push_back(IndexOp);
937 if (!RT->isStructured())
938 Offset = llvm::PoisonValue::get(
Builder.getInt32Ty());
939 Args.push_back(Offset);
945 Builder.CreateIntrinsic(RetTy, IntrID, Args, {},
"ld.struct");
946 Value *LoadedValue =
Builder.CreateExtractValue(ResRet, {0},
"ld.value");
947 Value *StatusBit =
Builder.CreateExtractValue(ResRet, {1},
"ld.status");
948 Value *ExtendedStatus =
949 Builder.CreateZExt(StatusBit,
Builder.getInt32Ty(),
"ld.status.ext");
950 Builder.CreateStore(ExtendedStatus, StatusAddr);
954 case Builtin::BI__builtin_hlsl_resource_uninitializedhandle: {
955 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
956 return llvm::PoisonValue::get(HandleTy);
958 case Builtin::BI__builtin_hlsl_resource_handlefrombinding: {
959 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
965 llvm::Intrinsic::ID IntrinsicID =
966 CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic();
968 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
970 case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: {
971 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
977 llvm::Intrinsic::ID IntrinsicID =
978 CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
980 return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
982 case Builtin::BI__builtin_hlsl_resource_counterhandlefromimplicitbinding: {
984 if (!
CGM.getTriple().isSPIRV())
987 llvm::Type *HandleTy =
CGM.getTypes().ConvertType(E->
getType());
990 llvm::Intrinsic::ID IntrinsicID =
991 llvm::Intrinsic::spv_resource_counterhandlefromimplicitbinding;
996 case Builtin::BI__builtin_hlsl_resource_nonuniformindex: {
999 return Builder.CreateIntrinsic(
1000 RetTy,
CGM.getHLSLRuntime().getNonUniformResourceIndexIntrinsic(),
1003 case Builtin::BI__builtin_hlsl_resource_getdimensions_x:
1004 case Builtin::BI__builtin_hlsl_resource_getdimensions_x_float:
1006 CGM.getHLSLRuntime().getGetDimensionsXIntrinsic(),
1008 case Builtin::BI__builtin_hlsl_resource_getdimensions_xy:
1009 case Builtin::BI__builtin_hlsl_resource_getdimensions_xy_float:
1011 CGM.getHLSLRuntime().getGetDimensionsXYIntrinsic(),
1013 case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy:
1014 case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy_float:
1016 *
this, E,
CGM.getHLSLRuntime().getGetDimensionsLevelsXYIntrinsic(), 3,
1018 case Builtin::BI__builtin_hlsl_resource_getstride: {
1022 case Builtin::BI__builtin_hlsl_all: {
1024 return Builder.CreateIntrinsic(
1029 case Builtin::BI__builtin_hlsl_and: {
1032 return Builder.CreateAnd(Op0, Op1,
"hlsl.and");
1034 case Builtin::BI__builtin_hlsl_or: {
1037 return Builder.CreateOr(Op0, Op1,
"hlsl.or");
1039 case Builtin::BI__builtin_hlsl_any: {
1041 return Builder.CreateIntrinsic(
1046 case Builtin::BI__builtin_hlsl_asdouble:
1048 case Builtin::BI__builtin_hlsl_elementwise_clamp: {
1055 Ty = VecTy->getElementType();
1059 Intr =
CGM.getHLSLRuntime().getNClampIntrinsic();
1061 Intr =
CGM.getHLSLRuntime().getUClampIntrinsic();
1064 Intr =
CGM.getHLSLRuntime().getSClampIntrinsic();
1066 return Builder.CreateIntrinsic(
1070 case Builtin::BI__builtin_hlsl_dot: {
1073 llvm::Type *T0 = Op0->
getType();
1074 llvm::Type *T1 = Op1->
getType();
1077 if (!T0->isVectorTy() && !T1->isVectorTy()) {
1078 if (T0->isFloatingPointTy())
1079 return Builder.CreateFMul(Op0, Op1,
"hlsl.dot");
1081 if (T0->isIntegerTy())
1082 return Builder.CreateMul(Op0, Op1,
"hlsl.dot");
1085 "Scalar dot product is only supported on ints and floats.");
1090 "Dot product operands must have the same type.");
1093 assert(VecTy0 &&
"Dot product argument must be a vector.");
1095 return Builder.CreateIntrinsic(
1096 T0->getScalarType(),
1100 case Builtin::BI__builtin_hlsl_dot4add_i8packed: {
1105 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddI8PackedIntrinsic();
1108 return Builder.CreateIntrinsic(
1110 nullptr,
"hlsl.dot4add.i8packed");
1112 case Builtin::BI__builtin_hlsl_dot4add_u8packed: {
1117 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDot4AddU8PackedIntrinsic();
1120 return Builder.CreateIntrinsic(
1122 nullptr,
"hlsl.dot4add.u8packed");
1124 case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
1127 return Builder.CreateIntrinsic(
1132 case Builtin::BI__builtin_hlsl_elementwise_firstbitlow: {
1135 return Builder.CreateIntrinsic(
1138 nullptr,
"hlsl.firstbitlow");
1140 case Builtin::BI__builtin_hlsl_normalize: {
1144 "normalize operand must have a float representation");
1146 return Builder.CreateIntrinsic(
1149 nullptr,
"hlsl.normalize");
1151 case Builtin::BI__builtin_hlsl_elementwise_f16tof32: {
1154 case Builtin::BI__builtin_hlsl_elementwise_f32tof16: {
1157 case Builtin::BI__builtin_hlsl_elementwise_frac: {
1160 llvm_unreachable(
"frac operand must have a float representation");
1161 return Builder.CreateIntrinsic(
1162 Op0->
getType(),
CGM.getHLSLRuntime().getFracIntrinsic(),
1165 case Builtin::BI__builtin_hlsl_elementwise_isinf: {
1168 llvm_unreachable(
"isinf operand must have a float representation");
1171 return Builder.CreateIntrinsic(
1172 retType,
CGM.getHLSLRuntime().getIsInfIntrinsic(),
1175 case Builtin::BI__builtin_hlsl_elementwise_isnan: {
1178 llvm_unreachable(
"isnan operand must have a float representation");
1181 return Builder.CreateIntrinsic(
1182 retType,
CGM.getHLSLRuntime().getIsNaNIntrinsic(),
1185 case Builtin::BI__builtin_hlsl_mad: {
1190 return Builder.CreateIntrinsic(
1191 M->
getType(), Intrinsic::fmuladd,
1195 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1196 return Builder.CreateIntrinsic(
1197 M->
getType(), Intrinsic::dx_imad,
1201 return Builder.CreateNSWAdd(Mul, B);
1204 if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
1205 return Builder.CreateIntrinsic(
1206 M->
getType(), Intrinsic::dx_umad,
1210 return Builder.CreateNUWAdd(Mul, B);
1212 case Builtin::BI__builtin_hlsl_mul: {
1230 llvm::MatrixBuilder MB(
Builder);
1231 if (IsVec0 && IsMat1) {
1235 unsigned Cols = MatTy->getNumColumns();
1236 assert(N == Rows &&
"vector length must match matrix row count");
1238 Op1 = MB.CreateRowMajorToColumnMajorTransform(Op1, Rows, Cols);
1239 return MB.CreateMatrixMultiply(Op0, Op1, 1, N, Cols,
"hlsl.mul");
1241 if (IsMat0 && IsVec1) {
1244 unsigned Cols = MatTy->getNumColumns();
1246 "vector length must match matrix column count");
1248 Op0 = MB.CreateRowMajorToColumnMajorTransform(Op0, Rows, Cols);
1249 return MB.CreateMatrixMultiply(Op0, Op1, Rows, Cols, 1,
"hlsl.mul");
1251 assert(IsMat0 && IsMat1);
1256 unsigned Cols0 = MatTy0->getNumColumns();
1258 assert(Cols0 == Rows1 &&
1259 "inner matrix dimensions must match for multiplication");
1261 Op0 = MB.CreateRowMajorToColumnMajorTransform(Op0, Rows0, Cols0);
1263 Op1 = MB.CreateRowMajorToColumnMajorTransform(Op1, Rows1, Cols1);
1266 MB.CreateMatrixMultiply(Op0, Op1, Rows0, Cols0, Cols1,
"hlsl.mul");
1269 if (IsResultRowMajor)
1270 Result = MB.CreateColumnMajorToRowMajorTransform(
Result, Rows0, Cols1);
1273 case Builtin::BI__builtin_hlsl_transpose: {
1277 unsigned Cols = MatTy->getNumColumns();
1278 llvm::MatrixBuilder MB(
Builder);
1285 if (SrcRowMajor != DstRowMajor)
1290 return MB.CreateMatrixTranspose(Op0, Cols, Rows);
1291 return MB.CreateMatrixTranspose(Op0, Rows, Cols);
1293 case Builtin::BI__builtin_hlsl_elementwise_rcp: {
1296 llvm_unreachable(
"rcp operand must have a float representation");
1297 llvm::Type *Ty = Op0->
getType();
1298 llvm::Type *EltTy = Ty->getScalarType();
1300 ? ConstantVector::getSplat(
1301 ElementCount::getFixed(
1303 ConstantFP::get(EltTy, 1.0))
1304 : ConstantFP::get(EltTy, 1.0);
1305 return Builder.CreateFDiv(One, Op0,
"hlsl.rcp");
1307 case Builtin::BI__builtin_hlsl_elementwise_rsqrt: {
1310 llvm_unreachable(
"rsqrt operand must have a float representation");
1311 return Builder.CreateIntrinsic(
1312 Op0->
getType(),
CGM.getHLSLRuntime().getRsqrtIntrinsic(),
1315 case Builtin::BI__builtin_hlsl_elementwise_saturate: {
1318 "saturate operand must have a float representation");
1319 return Builder.CreateIntrinsic(
1322 nullptr,
"hlsl.saturate");
1324 case Builtin::BI__builtin_hlsl_wave_prefix_count_bits: {
1326 assert(Op->
getType()->isIntegerTy(1) &&
1327 "WavePrefixBitCount operand must be a boolean type");
1334 case Builtin::BI__builtin_hlsl_select: {
1347 if (!OpTrue->
getType()->isVectorTy())
1349 Builder.CreateVectorSplat(VTy->getNumElements(), OpTrue,
"splat");
1350 if (!OpFalse->
getType()->isVectorTy())
1352 Builder.CreateVectorSplat(VTy->getNumElements(), OpFalse,
"splat");
1356 Builder.CreateSelect(OpCond, OpTrue, OpFalse,
"hlsl.select");
1363 case Builtin::BI__builtin_hlsl_wave_active_all_equal: {
1366 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllEqualIntrinsic();
1369 case Builtin::BI__builtin_hlsl_wave_active_all_true: {
1371 assert(Op->
getType()->isIntegerTy(1) &&
1372 "Intrinsic WaveActiveAllTrue operand must be a bool");
1374 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAllTrueIntrinsic();
1377 case Builtin::BI__builtin_hlsl_wave_active_any_true: {
1379 assert(Op->
getType()->isIntegerTy(1) &&
1380 "Intrinsic WaveActiveAnyTrue operand must be a bool");
1382 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic();
1385 case Builtin::BI__builtin_hlsl_wave_active_bit_or: {
1388 "Intrinsic WaveActiveBitOr operand must have an unsigned integer "
1391 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitOrIntrinsic();
1393 "hlsl.wave.active.bit.or");
1395 case Builtin::BI__builtin_hlsl_wave_active_bit_xor: {
1398 "Intrinsic WaveActiveBitXor operand must have an unsigned integer "
1401 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitXorIntrinsic();
1403 "hlsl.wave.active.bit.xor");
1405 case Builtin::BI__builtin_hlsl_wave_active_bit_and: {
1408 "Intrinsic WaveActiveBitAnd operand must have an unsigned integer "
1411 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveBitAndIntrinsic();
1413 "hlsl.wave.active.bit.and");
1415 case Builtin::BI__builtin_hlsl_interlocked_add: {
1422 case Builtin::BI__builtin_hlsl_interlocked_or: {
1425 case Builtin::BI__builtin_hlsl_interlocked_xor: {
1428 case Builtin::BI__builtin_hlsl_wave_active_ballot: {
1430 assert(Op->
getType()->isIntegerTy(1) &&
1431 "Intrinsic WaveActiveBallot operand must be a bool");
1435 case Builtin::BI__builtin_hlsl_wave_active_count_bits: {
1437 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveActiveCountBitsIntrinsic();
1440 case Builtin::BI__builtin_hlsl_wave_active_sum: {
1447 "hlsl.wave.active.sum");
1449 case Builtin::BI__builtin_hlsl_wave_active_product: {
1456 "hlsl.wave.active.product");
1458 case Builtin::BI__builtin_hlsl_wave_active_max: {
1464 IID =
CGM.getHLSLRuntime().getWaveActiveUMaxIntrinsic();
1466 IID =
CGM.getHLSLRuntime().getWaveActiveMaxIntrinsic();
1469 "hlsl.wave.active.max");
1471 case Builtin::BI__builtin_hlsl_wave_active_min: {
1477 IID =
CGM.getHLSLRuntime().getWaveActiveUMinIntrinsic();
1479 IID =
CGM.getHLSLRuntime().getWaveActiveMinIntrinsic();
1482 "hlsl.wave.active.min");
1484 case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
1488 switch (
CGM.getTarget().getTriple().getArch()) {
1489 case llvm::Triple::dxil:
1491 case llvm::Triple::spirv:
1493 llvm::FunctionType::get(
IntTy, {},
false),
1494 "__hlsl_wave_get_lane_index", {},
false,
true));
1497 "Intrinsic WaveGetLaneIndex not supported by target architecture");
1500 case Builtin::BI__builtin_hlsl_wave_is_first_lane: {
1501 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveIsFirstLaneIntrinsic();
1504 case Builtin::BI__builtin_hlsl_wave_get_lane_count: {
1505 Intrinsic::ID ID =
CGM.getHLSLRuntime().getWaveGetLaneCountIntrinsic();
1508 case Builtin::BI__builtin_hlsl_wave_read_lane_at: {
1514 {OpExpr->getType()},
ArrayRef{OpExpr, OpIndex},
1515 "hlsl.wave.readlane");
1517 case Builtin::BI__builtin_hlsl_wave_prefix_sum: {
1522 "hlsl.wave.prefix.sum");
1524 case Builtin::BI__builtin_hlsl_wave_prefix_product: {
1529 "hlsl.wave.prefix.product");
1531 case Builtin::BI__builtin_hlsl_quad_read_across_x: {
1533 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossXIntrinsic();
1535 "hlsl.quad.read.across.x");
1537 case Builtin::BI__builtin_hlsl_quad_read_across_y: {
1539 Intrinsic::ID ID =
CGM.getHLSLRuntime().getQuadReadAcrossYIntrinsic();
1541 "hlsl.quad.read.across.y");
1543 case Builtin::BI__builtin_hlsl_quad_read_across_diagonal: {
1546 CGM.getHLSLRuntime().getQuadReadAcrossDiagonalIntrinsic();
1548 &
CGM.getModule(), ID, {OpExpr->getType()}),
1549 ArrayRef{OpExpr},
"hlsl.quad.read.across.diagonal");
1551 case Builtin::BI__builtin_hlsl_elementwise_sign: {
1552 auto *Arg0 = E->
getArg(0);
1554 llvm::Type *Xty = Op0->
getType();
1555 llvm::Type *retType = llvm::Type::getInt32Ty(this->
getLLVMContext());
1556 if (Xty->isVectorTy()) {
1557 auto *XVecTy = Arg0->getType()->castAs<
VectorType>();
1558 retType = llvm::VectorType::get(
1559 retType, ElementCount::getFixed(XVecTy->getNumElements()));
1561 assert((Arg0->getType()->hasFloatingRepresentation() ||
1562 Arg0->getType()->hasIntegerRepresentation()) &&
1563 "sign operand must have a float or int representation");
1565 if (Arg0->getType()->hasUnsignedIntegerRepresentation()) {
1567 return Builder.CreateSelect(
Cmp, ConstantInt::get(retType, 0),
1568 ConstantInt::get(retType, 1),
"hlsl.sign");
1571 return Builder.CreateIntrinsic(
1572 retType,
CGM.getHLSLRuntime().getSignIntrinsic(),
1575 case Builtin::BI__builtin_hlsl_buffer_update_counter: {
1579 return Builder.CreateIntrinsic(
1581 CGM.getHLSLRuntime().getBufferUpdateCounterIntrinsic(),
1584 case Builtin::BI__builtin_hlsl_elementwise_splitdouble: {
1589 "asuint operands types mismatch");
1592 case Builtin::BI__builtin_hlsl_elementwise_clip:
1594 "clip operands types mismatch");
1596 case Builtin::BI__builtin_hlsl_all_memory_barrier: {
1597 Intrinsic::ID ID =
CGM.getHLSLRuntime().getAllMemoryBarrierIntrinsic();
1600 case Builtin::BI__builtin_hlsl_all_memory_barrier_with_group_sync: {
1602 CGM.getHLSLRuntime().getAllMemoryBarrierWithGroupSyncIntrinsic();
1605 case Builtin::BI__builtin_hlsl_device_memory_barrier: {
1606 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDeviceMemoryBarrierIntrinsic();
1609 case Builtin::BI__builtin_hlsl_device_memory_barrier_with_group_sync: {
1611 CGM.getHLSLRuntime().getDeviceMemoryBarrierWithGroupSyncIntrinsic();
1614 case Builtin::BI__builtin_hlsl_group_memory_barrier: {
1615 Intrinsic::ID ID =
CGM.getHLSLRuntime().getGroupMemoryBarrierIntrinsic();
1618 case Builtin::BI__builtin_hlsl_group_memory_barrier_with_group_sync: {
1620 CGM.getHLSLRuntime().getGroupMemoryBarrierWithGroupSyncIntrinsic();
1623 case Builtin::BI__builtin_hlsl_elementwise_ddx_coarse: {
1626 llvm_unreachable(
"ddx_coarse operand must have a float representation");
1627 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxCoarseIntrinsic();
1632 case Builtin::BI__builtin_hlsl_elementwise_ddy_coarse: {
1635 llvm_unreachable(
"ddy_coarse operand must have a float representation");
1636 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyCoarseIntrinsic();
1641 case Builtin::BI__builtin_hlsl_elementwise_ddx_fine: {
1644 llvm_unreachable(
"ddx_fine operand must have a float representation");
1645 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdxFineIntrinsic();
1650 case Builtin::BI__builtin_hlsl_elementwise_ddy_fine: {
1653 llvm_unreachable(
"ddy_fine operand must have a float representation");
1654 Intrinsic::ID ID =
CGM.getHLSLRuntime().getDdyFineIntrinsic();
1659 case Builtin::BI__builtin_get_spirv_spec_constant_bool:
1660 case Builtin::BI__builtin_get_spirv_spec_constant_short:
1661 case Builtin::BI__builtin_get_spirv_spec_constant_ushort:
1662 case Builtin::BI__builtin_get_spirv_spec_constant_int:
1663 case Builtin::BI__builtin_get_spirv_spec_constant_uint:
1664 case Builtin::BI__builtin_get_spirv_spec_constant_longlong:
1665 case Builtin::BI__builtin_get_spirv_spec_constant_ulonglong:
1666 case Builtin::BI__builtin_get_spirv_spec_constant_half:
1667 case Builtin::BI__builtin_get_spirv_spec_constant_float:
1668 case Builtin::BI__builtin_get_spirv_spec_constant_double: {
1672 llvm::Value *Args[] = {SpecId, DefaultVal};
1673 return Builder.CreateCall(SpecConstantFn, Args);