292  case Builtin::BI__builtin_hlsl_adduint64: {
 
  298           "AddUint64 operand types must match");
 
  300           "AddUint64 operands must have an integer representation");
 
  301    assert((NumElements == 2 || NumElements == 4) &&
 
  302           "AddUint64 operands must have 2 or 4 elements");
 
  310    if (NumElements == 2) {
 
  311      LowA = 
Builder.CreateExtractElement(OpA, (uint64_t)0, 
"LowA");
 
  312      HighA = 
Builder.CreateExtractElement(OpA, (uint64_t)1, 
"HighA");
 
  313      LowB = 
Builder.CreateExtractElement(OpB, (uint64_t)0, 
"LowB");
 
  314      HighB = 
Builder.CreateExtractElement(OpB, (uint64_t)1, 
"HighB");
 
  316      LowA = 
Builder.CreateShuffleVector(OpA, {0, 2}, 
"LowA");
 
  317      HighA = 
Builder.CreateShuffleVector(OpA, {1, 3}, 
"HighA");
 
  318      LowB = 
Builder.CreateShuffleVector(OpB, {0, 2}, 
"LowB");
 
  319      HighB = 
Builder.CreateShuffleVector(OpB, {1, 3}, 
"HighB");
 
  326        *
this, Intrinsic::uadd_with_overflow, LowA, LowB, Carry);
 
  327    llvm::Value *ZExtCarry =
 
  328        Builder.CreateZExt(Carry, HighA->getType(), 
"CarryZExt");
 
  331    llvm::Value *HighSum = 
Builder.CreateAdd(HighA, HighB, 
"HighSum");
 
  332    llvm::Value *HighSumPlusCarry =
 
  333        Builder.CreateAdd(HighSum, ZExtCarry, 
"HighSumPlusCarry");
 
  335    if (NumElements == 4) {
 
  336      return Builder.CreateShuffleVector(LowSum, HighSumPlusCarry, {0, 2, 1, 3},
 
  342                                         "hlsl.AddUint64.upto0");
 
  347  case Builtin::BI__builtin_hlsl_resource_getpointer: {
 
  352    return Builder.CreateIntrinsic(
 
  353        RetTy, 
CGM.getHLSLRuntime().getCreateResourceGetPointerIntrinsic(),
 
  356  case Builtin::BI__builtin_hlsl_resource_uninitializedhandle: {
 
  357    llvm::Type *HandleTy = 
CGM.getTypes().ConvertType(E->
getType());
 
  358    return llvm::PoisonValue::get(HandleTy);
 
  360  case Builtin::BI__builtin_hlsl_resource_handlefrombinding: {
 
  361    llvm::Type *HandleTy = 
CGM.getTypes().ConvertType(E->
getType());
 
  367    llvm::Intrinsic::ID IntrinsicID =
 
  368        CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic();
 
  370    return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
 
  372  case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: {
 
  373    llvm::Type *HandleTy = 
CGM.getTypes().ConvertType(E->
getType());
 
  379    llvm::Intrinsic::ID IntrinsicID =
 
  380        CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
 
  382    return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
 
  384  case Builtin::BI__builtin_hlsl_resource_counterhandlefromimplicitbinding: {
 
  386    if (!
CGM.getTriple().isSPIRV())
 
  389    llvm::Type *HandleTy = 
CGM.getTypes().ConvertType(E->
getType());
 
  392    llvm::Intrinsic::ID IntrinsicID =
 
  393        llvm::Intrinsic::spv_resource_counterhandlefromimplicitbinding;
 
  395    return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
 
  397  case Builtin::BI__builtin_hlsl_resource_nonuniformindex: {
 
  400    return Builder.CreateIntrinsic(
 
  401        RetTy, 
CGM.getHLSLRuntime().getNonUniformResourceIndexIntrinsic(),
 
  404  case Builtin::BI__builtin_hlsl_resource_getdimensions_x: {
 
  409        RetTy, 
CGM.getHLSLRuntime().getGetDimensionsXIntrinsic(),
 
  411    return Builder.CreateStore(DimValue, 
Dim.getAddress());
 
  413  case Builtin::BI__builtin_hlsl_resource_getstride: {
 
  417  case Builtin::BI__builtin_hlsl_all: {
 
  419    return Builder.CreateIntrinsic(
 
  424  case Builtin::BI__builtin_hlsl_and: {
 
  427    return Builder.CreateAnd(Op0, Op1, 
"hlsl.and");
 
  429  case Builtin::BI__builtin_hlsl_or: {
 
  432    return Builder.CreateOr(Op0, Op1, 
"hlsl.or");
 
  434  case Builtin::BI__builtin_hlsl_any: {
 
  436    return Builder.CreateIntrinsic(
 
  441  case Builtin::BI__builtin_hlsl_asdouble:
 
  443  case Builtin::BI__builtin_hlsl_elementwise_clamp: {
 
  450      Ty = VecTy->getElementType();
 
  454      Intr = 
CGM.getHLSLRuntime().getNClampIntrinsic();
 
  456      Intr = 
CGM.getHLSLRuntime().getUClampIntrinsic();
 
  459      Intr = 
CGM.getHLSLRuntime().getSClampIntrinsic();
 
  461    return Builder.CreateIntrinsic(
 
  465  case Builtin::BI__builtin_hlsl_crossf16:
 
  466  case Builtin::BI__builtin_hlsl_crossf32: {
 
  471           "cross operands must have a float representation");
 
  476        "input vectors must have 3 elements each");
 
  477    return Builder.CreateIntrinsic(
 
  478        Op0->
getType(), 
CGM.getHLSLRuntime().getCrossIntrinsic(),
 
  481  case Builtin::BI__builtin_hlsl_dot: {
 
  484    llvm::Type *T0 = Op0->
getType();
 
  485    llvm::Type *T1 = Op1->
getType();
 
  488    if (!T0->isVectorTy() && !T1->isVectorTy()) {
 
  489      if (T0->isFloatingPointTy())
 
  490        return Builder.CreateFMul(Op0, Op1, 
"hlsl.dot");
 
  492      if (T0->isIntegerTy())
 
  493        return Builder.CreateMul(Op0, Op1, 
"hlsl.dot");
 
  496          "Scalar dot product is only supported on ints and floats.");
 
  501           "Dot product operands must have the same type.");
 
  504    assert(VecTy0 && 
"Dot product argument must be a vector.");
 
  506    return Builder.CreateIntrinsic(
 
  511  case Builtin::BI__builtin_hlsl_dot4add_i8packed: {
 
  516    Intrinsic::ID ID = 
CGM.getHLSLRuntime().getDot4AddI8PackedIntrinsic();
 
  519    return Builder.CreateIntrinsic(
 
  521        nullptr, 
"hlsl.dot4add.i8packed");
 
  523  case Builtin::BI__builtin_hlsl_dot4add_u8packed: {
 
  528    Intrinsic::ID ID = 
CGM.getHLSLRuntime().getDot4AddU8PackedIntrinsic();
 
  531    return Builder.CreateIntrinsic(
 
  533        nullptr, 
"hlsl.dot4add.u8packed");
 
  535  case Builtin::BI__builtin_hlsl_elementwise_firstbithigh: {
 
  538    return Builder.CreateIntrinsic(
 
  543  case Builtin::BI__builtin_hlsl_elementwise_firstbitlow: {
 
  546    return Builder.CreateIntrinsic(
 
  549        nullptr, 
"hlsl.firstbitlow");
 
  551  case Builtin::BI__builtin_hlsl_lerp: {
 
  556      llvm_unreachable(
"lerp operand must have a float representation");
 
  557    return Builder.CreateIntrinsic(
 
  558        X->getType(), 
CGM.getHLSLRuntime().getLerpIntrinsic(),
 
  561  case Builtin::BI__builtin_hlsl_normalize: {
 
  565           "normalize operand must have a float representation");
 
  567    return Builder.CreateIntrinsic(
 
  570        nullptr, 
"hlsl.normalize");
 
  572  case Builtin::BI__builtin_hlsl_elementwise_degrees: {
 
  576           "degree operand must have a float representation");
 
  578    return Builder.CreateIntrinsic(
 
  579        X->getType(), 
CGM.getHLSLRuntime().getDegreesIntrinsic(),
 
  582  case Builtin::BI__builtin_hlsl_elementwise_frac: {
 
  585      llvm_unreachable(
"frac operand must have a float representation");
 
  586    return Builder.CreateIntrinsic(
 
  587        Op0->
getType(), 
CGM.getHLSLRuntime().getFracIntrinsic(),
 
  590  case Builtin::BI__builtin_hlsl_elementwise_isinf: {
 
  592    llvm::Type *Xty = Op0->
getType();
 
  593    llvm::Type *retType = llvm::Type::getInt1Ty(this->
getLLVMContext());
 
  594    if (Xty->isVectorTy()) {
 
  596      retType = llvm::VectorType::get(
 
  597          retType, ElementCount::getFixed(XVecTy->getNumElements()));
 
  600      llvm_unreachable(
"isinf operand must have a float representation");
 
  601    return Builder.CreateIntrinsic(
 
  602        retType, 
CGM.getHLSLRuntime().getIsInfIntrinsic(),
 
  605  case Builtin::BI__builtin_hlsl_elementwise_isnan: {
 
  607    llvm::Type *Xty = Op0->
getType();
 
  608    llvm::Type *retType = llvm::Type::getInt1Ty(this->
getLLVMContext());
 
  609    if (Xty->isVectorTy()) {
 
  611      retType = llvm::VectorType::get(
 
  612          retType, ElementCount::getFixed(XVecTy->getNumElements()));
 
  615      llvm_unreachable(
"isnan operand must have a float representation");
 
  616    return Builder.CreateIntrinsic(
 
  617        retType, 
CGM.getHLSLRuntime().getIsNaNIntrinsic(),
 
  620  case Builtin::BI__builtin_hlsl_mad: {
 
  625      return Builder.CreateIntrinsic(
 
  626           M->
getType(), Intrinsic::fmuladd,
 
  630      if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
 
  631        return Builder.CreateIntrinsic(
 
  632             M->
getType(), Intrinsic::dx_imad,
 
  636      return Builder.CreateNSWAdd(Mul, B);
 
  639    if (
CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil)
 
  640      return Builder.CreateIntrinsic(
 
  641          M->
getType(), Intrinsic::dx_umad,
 
  645    return Builder.CreateNUWAdd(Mul, B);
 
  647  case Builtin::BI__builtin_hlsl_elementwise_rcp: {
 
  650      llvm_unreachable(
"rcp operand must have a float representation");
 
  651    llvm::Type *Ty = Op0->
getType();
 
  652    llvm::Type *EltTy = Ty->getScalarType();
 
  653    Constant *One = Ty->isVectorTy()
 
  654                        ? ConstantVector::getSplat(
 
  655                              ElementCount::getFixed(
 
  657                              ConstantFP::get(EltTy, 1.0))
 
  658                        : ConstantFP::get(EltTy, 1.0);
 
  659    return Builder.CreateFDiv(One, Op0, 
"hlsl.rcp");
 
  661  case Builtin::BI__builtin_hlsl_elementwise_rsqrt: {
 
  664      llvm_unreachable(
"rsqrt operand must have a float representation");
 
  665    return Builder.CreateIntrinsic(
 
  666        Op0->
getType(), 
CGM.getHLSLRuntime().getRsqrtIntrinsic(),
 
  669  case Builtin::BI__builtin_hlsl_elementwise_saturate: {
 
  672           "saturate operand must have a float representation");
 
  673    return Builder.CreateIntrinsic(
 
  676        nullptr, 
"hlsl.saturate");
 
  678  case Builtin::BI__builtin_hlsl_select: {
 
  691      if (!OpTrue->
getType()->isVectorTy())
 
  693            Builder.CreateVectorSplat(VTy->getNumElements(), OpTrue, 
"splat");
 
  694      if (!OpFalse->
getType()->isVectorTy())
 
  696            Builder.CreateVectorSplat(VTy->getNumElements(), OpFalse, 
"splat");
 
  700        Builder.CreateSelect(OpCond, OpTrue, OpFalse, 
"hlsl.select");
 
  707  case Builtin::BI__builtin_hlsl_step: {
 
  712           "step operands must have a float representation");
 
  713    return Builder.CreateIntrinsic(
 
  714        Op0->
getType(), 
CGM.getHLSLRuntime().getStepIntrinsic(),
 
  717  case Builtin::BI__builtin_hlsl_wave_active_all_true: {
 
  719    assert(Op->
getType()->isIntegerTy(1) &&
 
  720           "Intrinsic WaveActiveAllTrue operand must be a bool");
 
  722    Intrinsic::ID ID = 
CGM.getHLSLRuntime().getWaveActiveAllTrueIntrinsic();
 
  724        Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID), {Op});
 
  726  case Builtin::BI__builtin_hlsl_wave_active_any_true: {
 
  728    assert(Op->
getType()->isIntegerTy(1) &&
 
  729           "Intrinsic WaveActiveAnyTrue operand must be a bool");
 
  731    Intrinsic::ID ID = 
CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic();
 
  733        Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID), {Op});
 
  735  case Builtin::BI__builtin_hlsl_wave_active_count_bits: {
 
  737    Intrinsic::ID ID = 
CGM.getHLSLRuntime().getWaveActiveCountBitsIntrinsic();
 
  739        Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID),
 
  742  case Builtin::BI__builtin_hlsl_wave_active_sum: {
 
  746        getTarget().getTriple().getArch(), 
CGM.getHLSLRuntime(),
 
  750                               &
CGM.getModule(), IID, {OpExpr->getType()}),
 
  751                           ArrayRef{OpExpr}, 
"hlsl.wave.active.sum");
 
  753  case Builtin::BI__builtin_hlsl_wave_active_max: {
 
  757        getTarget().getTriple().getArch(), 
CGM.getHLSLRuntime(),
 
  761                               &
CGM.getModule(), IID, {OpExpr->getType()}),
 
  762                           ArrayRef{OpExpr}, 
"hlsl.wave.active.max");
 
  764  case Builtin::BI__builtin_hlsl_wave_active_min: {
 
  768        getTarget().getTriple().getArch(), 
CGM.getHLSLRuntime(),
 
  772                               &
CGM.getModule(), IID, {OpExpr->getType()}),
 
  773                           ArrayRef{OpExpr}, 
"hlsl.wave.active.min");
 
  775  case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
 
  779    switch (
CGM.getTarget().getTriple().getArch()) {
 
  780    case llvm::Triple::dxil:
 
  782          &
CGM.getModule(), Intrinsic::dx_wave_getlaneindex));
 
  783    case llvm::Triple::spirv:
 
  785          llvm::FunctionType::get(
IntTy, {}, 
false),
 
  786          "__hlsl_wave_get_lane_index", {}, 
false, 
true));
 
  789          "Intrinsic WaveGetLaneIndex not supported by target architecture");
 
  792  case Builtin::BI__builtin_hlsl_wave_is_first_lane: {
 
  793    Intrinsic::ID ID = 
CGM.getHLSLRuntime().getWaveIsFirstLaneIntrinsic();
 
  795        Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID));
 
  797  case Builtin::BI__builtin_hlsl_wave_get_lane_count: {
 
  798    Intrinsic::ID ID = 
CGM.getHLSLRuntime().getWaveGetLaneCountIntrinsic();
 
  800        Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID));
 
  802  case Builtin::BI__builtin_hlsl_wave_read_lane_at: {
 
  808        Intrinsic::getOrInsertDeclaration(
 
  809            &
CGM.getModule(), 
CGM.getHLSLRuntime().getWaveReadLaneAtIntrinsic(),
 
  810            {OpExpr->getType()}),
 
  811        ArrayRef{OpExpr, OpIndex}, 
"hlsl.wave.readlane");
 
  813  case Builtin::BI__builtin_hlsl_elementwise_sign: {
 
  814    auto *Arg0 = E->
getArg(0);
 
  816    llvm::Type *Xty = Op0->
getType();
 
  817    llvm::Type *retType = llvm::Type::getInt32Ty(this->
getLLVMContext());
 
  818    if (Xty->isVectorTy()) {
 
  819      auto *XVecTy = Arg0->getType()->castAs<
VectorType>();
 
  820      retType = llvm::VectorType::get(
 
  821          retType, ElementCount::getFixed(XVecTy->getNumElements()));
 
  823    assert((Arg0->getType()->hasFloatingRepresentation() ||
 
  824            Arg0->getType()->hasIntegerRepresentation()) &&
 
  825           "sign operand must have a float or int representation");
 
  827    if (Arg0->getType()->hasUnsignedIntegerRepresentation()) {
 
  828      Value *Cmp = 
Builder.CreateICmpEQ(Op0, ConstantInt::get(Xty, 0));
 
  829      return Builder.CreateSelect(Cmp, ConstantInt::get(retType, 0),
 
  830                                  ConstantInt::get(retType, 1), 
"hlsl.sign");
 
  833    return Builder.CreateIntrinsic(
 
  834        retType, 
CGM.getHLSLRuntime().getSignIntrinsic(),
 
  837  case Builtin::BI__builtin_hlsl_elementwise_radians: {
 
  840           "radians operand must have a float representation");
 
  841    return Builder.CreateIntrinsic(
 
  844        nullptr, 
"hlsl.radians");
 
  846  case Builtin::BI__builtin_hlsl_buffer_update_counter: {
 
  850    return Builder.CreateIntrinsic(
 
  852        CGM.getHLSLRuntime().getBufferUpdateCounterIntrinsic(),
 
  855  case Builtin::BI__builtin_hlsl_elementwise_splitdouble: {
 
  860           "asuint operands types mismatch");
 
  863  case Builtin::BI__builtin_hlsl_elementwise_clip:
 
  865           "clip operands types mismatch");
 
  867  case Builtin::BI__builtin_hlsl_group_memory_barrier_with_group_sync: {
 
  869        CGM.getHLSLRuntime().getGroupMemoryBarrierWithGroupSyncIntrinsic();
 
  871        Intrinsic::getOrInsertDeclaration(&
CGM.getModule(), ID));
 
  873  case Builtin::BI__builtin_get_spirv_spec_constant_bool:
 
  874  case Builtin::BI__builtin_get_spirv_spec_constant_short:
 
  875  case Builtin::BI__builtin_get_spirv_spec_constant_ushort:
 
  876  case Builtin::BI__builtin_get_spirv_spec_constant_int:
 
  877  case Builtin::BI__builtin_get_spirv_spec_constant_uint:
 
  878  case Builtin::BI__builtin_get_spirv_spec_constant_longlong:
 
  879  case Builtin::BI__builtin_get_spirv_spec_constant_ulonglong:
 
  880  case Builtin::BI__builtin_get_spirv_spec_constant_half:
 
  881  case Builtin::BI__builtin_get_spirv_spec_constant_float:
 
  882  case Builtin::BI__builtin_get_spirv_spec_constant_double: {
 
  886    llvm::Value *Args[] = {SpecId, DefaultVal};
 
  887    return Builder.CreateCall(SpecConstantFn, Args);