[clang] [HLSL] Add CustomTypeChecking and improve sema for texture builtins (PR #221060)
Deric C. via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 11 13:52:48 PDT 2026
https://github.com/Icohedron updated https://github.com/llvm/llvm-project/pull/221060
>From 7188b039a012e36faf0d32055f5dda778069beb3 Mon Sep 17 00:00:00 2001
From: Deric Cheung <cheung.deric at gmail.com>
Date: Tue, 1 Sep 2026 17:30:00 -0700
Subject: [PATCH 1/2] Use CustomTypeChecking with texture builtins
---
clang/include/clang/Basic/Builtins.td | 24 ++--
clang/lib/CodeGen/CGHLSLBuiltins.cpp | 38 +-----
clang/lib/Sema/SemaHLSL.cpp | 124 ++++++------------
.../resources/Textures-Gather.hlsl | 6 +-
.../resources/Textures-Sample.hlsl | 11 +-
.../resources/Textures-SampleBias.hlsl | 24 ++--
.../resources/Textures-SampleCmp.hlsl | 24 ++--
.../Textures-SampleCmpLevelZero.hlsl | 10 +-
.../resources/Textures-SampleGrad.hlsl | 11 +-
.../resources/Textures-SampleLevel.hlsl | 10 +-
.../BuiltIns/resource_gather-errors.hlsl | 42 ++++++
.../BuiltIns/resource_load-errors.hlsl | 52 ++++++++
.../BuiltIns/resource_sample-errors.hlsl | 117 +++++++++++++++++
13 files changed, 311 insertions(+), 182 deletions(-)
create mode 100644 clang/test/SemaHLSL/BuiltIns/resource_gather-errors.hlsl
create mode 100644 clang/test/SemaHLSL/BuiltIns/resource_load-errors.hlsl
create mode 100644 clang/test/SemaHLSL/BuiltIns/resource_sample-errors.hlsl
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index d148cb4b9101e..90340ad7f812c 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -5339,73 +5339,73 @@ def HLSLResourceLoadWithStatusTyped : LangBuiltin<"HLSL_LANG"> {
def HLSLResourceLoadLevel : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_resource_load_level"];
- let Attributes = [NoThrow];
+ let Attributes = [NoThrow, CustomTypeChecking];
let Prototype = "void(...)";
}
def HLSLResourceLoadMS : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_resource_load_ms"];
- let Attributes = [NoThrow];
+ let Attributes = [NoThrow, CustomTypeChecking];
let Prototype = "void(...)";
}
def HLSLResourceSample : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_resource_sample"];
- let Attributes = [NoThrow];
+ let Attributes = [NoThrow, CustomTypeChecking];
let Prototype = "void(...)";
}
def HLSLResourceSampleBias : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_resource_sample_bias"];
- let Attributes = [NoThrow];
+ let Attributes = [NoThrow, CustomTypeChecking];
let Prototype = "void(...)";
}
def HLSLResourceSampleGrad : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_resource_sample_grad"];
- let Attributes = [NoThrow];
+ let Attributes = [NoThrow, CustomTypeChecking];
let Prototype = "void(...)";
}
def HLSLResourceSampleLevel : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_resource_sample_level"];
- let Attributes = [NoThrow];
+ let Attributes = [NoThrow, CustomTypeChecking];
let Prototype = "void(...)";
}
def HLSLResourceSampleCmp : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_resource_sample_cmp"];
- let Attributes = [NoThrow];
+ let Attributes = [NoThrow, CustomTypeChecking];
let Prototype = "void(...)";
}
def HLSLResourceSampleCmpLevelZero : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_resource_sample_cmp_level_zero"];
- let Attributes = [NoThrow];
+ let Attributes = [NoThrow, CustomTypeChecking];
let Prototype = "void(...)";
}
def HLSLResourceCalculateLod : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_resource_calculate_lod"];
- let Attributes = [NoThrow];
+ let Attributes = [NoThrow, CustomTypeChecking];
let Prototype = "void(...)";
}
def HLSLResourceCalculateLodUnclamped : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_resource_calculate_lod_unclamped"];
- let Attributes = [NoThrow];
+ let Attributes = [NoThrow, CustomTypeChecking];
let Prototype = "void(...)";
}
def HLSLResourceGather : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_resource_gather"];
- let Attributes = [NoThrow];
+ let Attributes = [NoThrow, CustomTypeChecking];
let Prototype = "void(...)";
}
def HLSLResourceGatherCmp : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_resource_gather_cmp"];
- let Attributes = [NoThrow];
+ let Attributes = [NoThrow, CustomTypeChecking];
let Prototype = "void(...)";
}
diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
index 52aac50e6baa6..45b3d8ab27a25 100644
--- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp
+++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
@@ -540,17 +540,6 @@ static unsigned getHlslClampArgIndex(const HLSLAttributedResourceType *RT,
: OffsetArgIndex;
}
-static Value *emitHlslClamp(CodeGenFunction &CGF, const CallExpr *E,
- unsigned ClampArgIndex) {
- Value *Clamp = CGF.EmitScalarExpr(E->getArg(ClampArgIndex));
- // The builtin is defined with variadic arguments, so the clamp parameter
- // might have been promoted to double. The intrinsic requires a 32-bit
- // float.
- if (Clamp->getType() != CGF.Builder.getFloatTy())
- Clamp = CGF.Builder.CreateFPCast(Clamp, CGF.Builder.getFloatTy());
- return Clamp;
-}
-
static Value *emitGetDimensions(CodeGenFunction &CGF, const CallExpr *E,
unsigned IntrinsicID, unsigned NumRetComps,
bool HasLod) {
@@ -721,7 +710,7 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
return EmitIntrinsicCall(CGM.getHLSLRuntime().getSampleIntrinsic(), Args,
RetTy);
- Args.push_back(emitHlslClamp(*this, E, ClampIdx));
+ Args.push_back(EmitScalarExpr(E->getArg(ClampIdx)));
return EmitIntrinsicCall(CGM.getHLSLRuntime().getSampleClampIntrinsic(),
Args, RetTy);
}
@@ -730,8 +719,6 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
Value *SamplerOp = EmitScalarExpr(E->getArg(1));
Value *CoordOp = EmitScalarExpr(E->getArg(2));
Value *BiasOp = EmitScalarExpr(E->getArg(3));
- if (BiasOp->getType() != Builder.getFloatTy())
- BiasOp = Builder.CreateFPCast(BiasOp, Builder.getFloatTy());
const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
SmallVector<Value *, 6> Args; // Max 6 arguments for SampleBias
@@ -748,7 +735,7 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
return EmitIntrinsicCall(CGM.getHLSLRuntime().getSampleBiasIntrinsic(),
Args, RetTy);
- Args.push_back(emitHlslClamp(*this, E, ClampIdx));
+ Args.push_back(EmitScalarExpr(E->getArg(ClampIdx)));
return EmitIntrinsicCall(CGM.getHLSLRuntime().getSampleBiasClampIntrinsic(),
Args, RetTy);
}
@@ -776,7 +763,7 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
return Builder.CreateIntrinsic(
RetTy, CGM.getHLSLRuntime().getSampleGradIntrinsic(), Args);
- Args.push_back(emitHlslClamp(*this, E, ClampIdx));
+ Args.push_back(EmitScalarExpr(E->getArg(ClampIdx)));
return Builder.CreateIntrinsic(
RetTy, CGM.getHLSLRuntime().getSampleGradClampIntrinsic(), Args);
}
@@ -785,8 +772,6 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
Value *SamplerOp = EmitScalarExpr(E->getArg(1));
Value *CoordOp = EmitScalarExpr(E->getArg(2));
Value *LODOp = EmitScalarExpr(E->getArg(3));
- if (LODOp->getType() != Builder.getFloatTy())
- LODOp = Builder.CreateFPCast(LODOp, Builder.getFloatTy());
const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
SmallVector<Value *, 5> Args; // Max 5 arguments for SampleLevel
@@ -843,9 +828,6 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
Value *HandleOp = EmitScalarExpr(E->getArg(0));
Value *CoordOp = EmitScalarExpr(E->getArg(1));
Value *SampleOp = EmitScalarExpr(E->getArg(2));
- if (SampleOp->getType() != Builder.getInt32Ty())
- SampleOp = Builder.CreateIntCast(SampleOp, Builder.getInt32Ty(),
- /*isSigned=*/true);
const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
SmallVector<Value *, 4> Args;
@@ -863,8 +845,6 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
Value *SamplerOp = EmitScalarExpr(E->getArg(1));
Value *CoordOp = EmitScalarExpr(E->getArg(2));
Value *CmpOp = EmitScalarExpr(E->getArg(3));
- if (CmpOp->getType() != Builder.getFloatTy())
- CmpOp = Builder.CreateFPCast(CmpOp, Builder.getFloatTy());
const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
SmallVector<Value *, 6> Args; // Max 6 arguments for SampleCmp
@@ -881,7 +861,7 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
return Builder.CreateIntrinsic(
RetTy, CGM.getHLSLRuntime().getSampleCmpIntrinsic(), Args);
- Args.push_back(emitHlslClamp(*this, E, ClampIdx));
+ Args.push_back(EmitScalarExpr(E->getArg(ClampIdx)));
return Builder.CreateIntrinsic(
RetTy, CGM.getHLSLRuntime().getSampleCmpClampIntrinsic(), Args);
}
@@ -890,8 +870,6 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
Value *SamplerOp = EmitScalarExpr(E->getArg(1));
Value *CoordOp = EmitScalarExpr(E->getArg(2));
Value *CmpOp = EmitScalarExpr(E->getArg(3));
- if (CmpOp->getType() != Builder.getFloatTy())
- CmpOp = Builder.CreateFPCast(CmpOp, Builder.getFloatTy());
const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
SmallVector<Value *, 5> Args;
@@ -929,9 +907,6 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
Value *SamplerOp = EmitScalarExpr(E->getArg(1));
Value *CoordOp = EmitScalarExpr(E->getArg(2));
Value *ComponentOp = EmitScalarExpr(E->getArg(3));
- if (ComponentOp->getType() != Builder.getInt32Ty())
- ComponentOp = Builder.CreateIntCast(ComponentOp, Builder.getInt32Ty(),
- /*isSigned=*/false);
const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
SmallVector<Value *, 5> Args;
@@ -950,8 +925,6 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
Value *SamplerOp = EmitScalarExpr(E->getArg(1));
Value *CoordOp = EmitScalarExpr(E->getArg(2));
Value *CompareOp = EmitScalarExpr(E->getArg(3));
- if (CompareOp->getType() != Builder.getFloatTy())
- CompareOp = Builder.CreateFPCast(CompareOp, Builder.getFloatTy());
SmallVector<Value *, 6> Args;
Args.push_back(HandleOp);
@@ -961,9 +934,6 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
if (CGM.getTarget().getTriple().isDXIL()) {
Value *ComponentOp = EmitScalarExpr(E->getArg(4));
- if (ComponentOp->getType() != Builder.getInt32Ty())
- ComponentOp = Builder.CreateIntCast(ComponentOp, Builder.getInt32Ty(),
- /*isSigned=*/false);
Args.push_back(ComponentOp);
}
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index d9978d1d171bb..86ce02444e1d6 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -3626,6 +3626,16 @@ static bool CheckVectorSelect(Sema *S, CallExpr *TheCall) {
return false;
}
+static QualType getVectorOrScalarType(Sema &S, QualType BaseType,
+ unsigned Count) {
+ return Count > 1 ? S.Context.getExtVectorType(BaseType, Count) : BaseType;
+}
+
+static bool CheckScalarFloatOperand(Sema &S, CallExpr *TheCall,
+ unsigned ArgIndex) {
+ return CheckArgTypeMatches(&S, TheCall->getArg(ArgIndex), S.Context.FloatTy);
+}
+
static bool CheckIndexType(Sema *S, CallExpr *TheCall, unsigned IndexArgIndex) {
assert(TheCall->getNumArgs() > IndexArgIndex && "Index argument missing");
QualType ArgType = TheCall->getArg(IndexArgIndex)->getType();
@@ -3700,22 +3710,6 @@ static QualType createCounterHandleType(ASTContext &AST,
MainAttrs);
}
-static bool CheckVectorElementCount(Sema *S, QualType PassedType,
- QualType BaseType, unsigned ExpectedCount,
- SourceLocation Loc) {
- unsigned PassedCount = 1;
- if (const auto *VecTy = PassedType->getAs<VectorType>())
- PassedCount = VecTy->getNumElements();
-
- if (PassedCount != ExpectedCount) {
- QualType ExpectedType =
- S->Context.getExtVectorType(BaseType, ExpectedCount);
- S->Diag(Loc, diag::err_typecheck_convert_incompatible)
- << PassedType << ExpectedType << 1 << 0 << 0;
- return true;
- }
- return false;
-}
enum class SampleKind { Sample, Bias, Grad, Level, Cmp, CmpLevelZero };
@@ -3834,9 +3828,9 @@ static bool CheckTextureSamplerAndLocation(Sema &S, CallExpr *TheCall,
unsigned ExpectedDim =
getResourceDimensions(ResourceTy->getAttrs().ResourceDimension) +
(IncludeArraySlice && ResourceTy->getAttrs().IsArray ? 1 : 0);
- if (CheckVectorElementCount(&S, TheCall->getArg(2)->getType(),
- S.Context.FloatTy, ExpectedDim,
- TheCall->getBeginLoc()))
+ if (CheckArgTypeMatches(
+ &S, TheCall->getArg(2),
+ getVectorOrScalarType(S, S.Context.FloatTy, ExpectedDim)))
return true;
return false;
@@ -3865,25 +3859,16 @@ static bool CheckGatherBuiltin(Sema &S, CallExpr *TheCall, bool IsCmp) {
unsigned NextIdx = 3;
if (IsCmp) {
// Check the compare value.
- QualType CmpTy = TheCall->getArg(NextIdx)->getType();
- if (!CmpTy->isFloatingType() || CmpTy->isVectorType()) {
- S.Diag(TheCall->getArg(NextIdx)->getBeginLoc(),
- diag::err_typecheck_convert_incompatible)
- << CmpTy << S.Context.FloatTy << 1 << 0 << 0;
+ if (CheckScalarFloatOperand(S, TheCall, NextIdx))
return true;
- }
NextIdx++;
}
// Check the component operand.
- Expr *ComponentArg = TheCall->getArg(NextIdx);
- QualType ComponentTy = ComponentArg->getType();
- if (!ComponentTy->isIntegerType() || ComponentTy->isVectorType()) {
- S.Diag(ComponentArg->getBeginLoc(),
- diag::err_typecheck_convert_incompatible)
- << ComponentTy << S.Context.UnsignedIntTy << 1 << 0 << 0;
+ if (CheckArgTypeMatches(&S, TheCall->getArg(NextIdx),
+ S.Context.UnsignedIntTy))
return true;
- }
+ Expr *ComponentArg = TheCall->getArg(NextIdx);
// GatherCmp operations on Vulkan target must use component 0 (Red).
if (IsCmp && S.getASTContext().getTargetInfo().getTriple().isSPIRV()) {
@@ -3912,9 +3897,9 @@ static bool CheckGatherBuiltin(Sema &S, CallExpr *TheCall, bool IsCmp) {
if (TheCall->getNumArgs() > NextIdx) {
unsigned ExpectedDim =
getResourceDimensions(ResourceTy->getAttrs().ResourceDimension);
- if (CheckVectorElementCount(&S, TheCall->getArg(NextIdx)->getType(),
- S.Context.IntTy, ExpectedDim,
- TheCall->getArg(NextIdx)->getBeginLoc()))
+ if (CheckArgTypeMatches(
+ &S, TheCall->getArg(NextIdx),
+ getVectorOrScalarType(S, S.Context.IntTy, ExpectedDim)))
return true;
NextIdx++;
}
@@ -3973,25 +3958,16 @@ static bool CheckLoadLevelBuiltin(Sema &S, CallExpr *TheCall) {
unsigned LocationDim = ResourceDim + (ResourceTy->getAttrs().IsArray ? 1 : 0);
if (!IsUAV)
++LocationDim;
- QualType CoordLODTy = TheCall->getArg(1)->getType();
- if (CheckVectorElementCount(&S, CoordLODTy, S.Context.IntTy, LocationDim,
- TheCall->getArg(1)->getBeginLoc()))
- return true;
-
- QualType EltTy = CoordLODTy;
- if (const auto *VTy = EltTy->getAs<VectorType>())
- EltTy = VTy->getElementType();
- if (!EltTy->isIntegerType()) {
- S.Diag(TheCall->getArg(1)->getBeginLoc(), diag::err_typecheck_expect_int)
- << CoordLODTy;
+ if (CheckArgTypeMatches(
+ &S, TheCall->getArg(1),
+ getVectorOrScalarType(S, S.Context.IntTy, LocationDim)))
return true;
- }
// Check the offset operand (int2 for 2D textures; no array slice).
if (TheCall->getNumArgs() > 2) {
- if (CheckVectorElementCount(&S, TheCall->getArg(2)->getType(),
- S.Context.IntTy, ResourceDim,
- TheCall->getArg(2)->getBeginLoc()))
+ if (CheckArgTypeMatches(
+ &S, TheCall->getArg(2),
+ getVectorOrScalarType(S, S.Context.IntTy, ResourceDim)))
return true;
}
@@ -4018,23 +3994,20 @@ static bool CheckLoadMSBuiltin(Sema &S, CallExpr *TheCall) {
unsigned ResourceDim =
getResourceDimensions(ResourceTy->getAttrs().ResourceDimension);
unsigned LocationDim = ResourceDim + (ResourceTy->getAttrs().IsArray ? 1 : 0);
- QualType LocationTy = TheCall->getArg(1)->getType();
- if (CheckVectorElementCount(&S, LocationTy, S.Context.IntTy, LocationDim,
- TheCall->getArg(1)->getBeginLoc()))
+ if (CheckArgTypeMatches(
+ &S, TheCall->getArg(1),
+ getVectorOrScalarType(S, S.Context.IntTy, LocationDim)))
return true;
// Check the sample index operand (scalar int).
- if (!TheCall->getArg(2)->getType()->isIntegerType()) {
- S.Diag(TheCall->getArg(2)->getBeginLoc(), diag::err_typecheck_expect_int)
- << TheCall->getArg(2)->getType();
+ if (CheckArgTypeMatches(&S, TheCall->getArg(2), S.Context.IntTy))
return true;
- }
// Check the offset operand (int2 for 2D textures; no array slice).
if (TheCall->getNumArgs() > 3) {
- if (CheckVectorElementCount(&S, TheCall->getArg(3)->getType(),
- S.Context.IntTy, ResourceDim,
- TheCall->getArg(3)->getBeginLoc()))
+ if (CheckArgTypeMatches(
+ &S, TheCall->getArg(3),
+ getVectorOrScalarType(S, S.Context.IntTy, ResourceDim)))
return true;
}
@@ -4081,26 +4054,18 @@ static bool CheckSamplingBuiltin(Sema &S, CallExpr *TheCall, SampleKind Kind) {
Kind == SampleKind::Cmp || Kind == SampleKind::CmpLevelZero) {
// Check the bias, lod level, or compare value, depending on the kind.
// All of them must be a scalar float value.
- QualType BiasOrLODOrCmpTy = TheCall->getArg(NextIdx)->getType();
- if (!BiasOrLODOrCmpTy->isFloatingType() ||
- BiasOrLODOrCmpTy->isVectorType()) {
- S.Diag(TheCall->getArg(NextIdx)->getBeginLoc(),
- diag::err_typecheck_convert_incompatible)
- << BiasOrLODOrCmpTy << S.Context.FloatTy << 1 << 0 << 0;
+ if (CheckScalarFloatOperand(S, TheCall, NextIdx))
return true;
- }
NextIdx++;
} else if (Kind == SampleKind::Grad) {
+ QualType GradTy = getVectorOrScalarType(S, S.Context.FloatTy, ExpectedDim);
+
// Check the DDX operand.
- if (CheckVectorElementCount(&S, TheCall->getArg(NextIdx)->getType(),
- S.Context.FloatTy, ExpectedDim,
- TheCall->getArg(NextIdx)->getBeginLoc()))
+ if (CheckArgTypeMatches(&S, TheCall->getArg(NextIdx), GradTy))
return true;
// Check the DDY operand.
- if (CheckVectorElementCount(&S, TheCall->getArg(NextIdx + 1)->getType(),
- S.Context.FloatTy, ExpectedDim,
- TheCall->getArg(NextIdx + 1)->getBeginLoc()))
+ if (CheckArgTypeMatches(&S, TheCall->getArg(NextIdx + 1), GradTy))
return true;
NextIdx += 2;
}
@@ -4108,9 +4073,9 @@ static bool CheckSamplingBuiltin(Sema &S, CallExpr *TheCall, SampleKind Kind) {
// Check the offset operand (if applicable).
if (hasResourceOffset(ResourceTy->getAttrs().ResourceDimension) &&
TheCall->getNumArgs() > NextIdx) {
- if (CheckVectorElementCount(&S, TheCall->getArg(NextIdx)->getType(),
- S.Context.IntTy, ExpectedDim,
- TheCall->getArg(NextIdx)->getBeginLoc()))
+ if (CheckArgTypeMatches(
+ &S, TheCall->getArg(NextIdx),
+ getVectorOrScalarType(S, S.Context.IntTy, ExpectedDim)))
return true;
NextIdx++;
}
@@ -4118,13 +4083,8 @@ static bool CheckSamplingBuiltin(Sema &S, CallExpr *TheCall, SampleKind Kind) {
// Check the clamp operand.
if (Kind != SampleKind::Level && Kind != SampleKind::CmpLevelZero &&
TheCall->getNumArgs() > NextIdx) {
- QualType ClampTy = TheCall->getArg(NextIdx)->getType();
- if (!ClampTy->isFloatingType() || ClampTy->isVectorType()) {
- S.Diag(TheCall->getArg(NextIdx)->getBeginLoc(),
- diag::err_typecheck_convert_incompatible)
- << ClampTy << S.Context.FloatTy << 1 << 0 << 0;
+ if (CheckScalarFloatOperand(S, TheCall, NextIdx))
return true;
- }
}
assert(ResourceTy->hasContainedType() &&
diff --git a/clang/test/CodeGenHLSL/resources/Textures-Gather.hlsl b/clang/test/CodeGenHLSL/resources/Textures-Gather.hlsl
index afdf0b502ead9..86da05951fb6f 100644
--- a/clang/test/CodeGenHLSL/resources/Textures-Gather.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Textures-Gather.hlsl
@@ -266,8 +266,6 @@ float4 test_cmp(COORD_TYPE loc : LOC) : SV_Target {
// CHECK: %[[SAMPLER_H:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP]]
// CHECK: %[[COORD_VAL:.*]] = load <[[COORD_DIM]] x float>, ptr %[[COORD_ADDR]]
// CHECK: %[[CMP_VAL:.*]] = load float, ptr %[[CMP_ADDR]]
-// CHECK: %[[CONV:.*]] = fpext {{.*}} float %[[CMP_VAL]] to double
-// CHECK: %[[TRUNC:.*]] = fptrunc {{.*}} double %[[CONV]] to float
-// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.gather.cmp.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE]], target("dx.Sampler", 0) %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], float %[[TRUNC]], i32 0, <[[DIM]] x i32> zeroinitializer)
-// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.gather.cmp.v4f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], float %[[TRUNC]], <[[DIM]] x i32> zeroinitializer)
+// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.gather.cmp.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE]], target("dx.Sampler", 0) %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], float %[[CMP_VAL]], i32 0, <[[DIM]] x i32> zeroinitializer)
+// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.gather.cmp.v4f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], float %[[CMP_VAL]], <[[DIM]] x i32> zeroinitializer)
// CHECK: ret <4 x float> %[[RES]]
diff --git a/clang/test/CodeGenHLSL/resources/Textures-Sample.hlsl b/clang/test/CodeGenHLSL/resources/Textures-Sample.hlsl
index a6a6add106d2b..01107d08f72fb 100644
--- a/clang/test/CodeGenHLSL/resources/Textures-Sample.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Textures-Sample.hlsl
@@ -208,9 +208,8 @@ float4 test_clamp(COORD_TYPE loc : LOC) : SV_Target {
// CHECK-OFFSET: %[[COORD_VAL:.*]] = load <[[COORD_DIM]] x float>, ptr %[[COORD_ADDR]]
// CHECK-OFFSET: %[[OFFSET_VAL:.*]] = load <[[DIM]] x i32>, ptr %[[OFFSET_ADDR]]
// CHECK-OFFSET: %[[CLAMP_VAL:.*]] = load float, ptr %[[CLAMP_ADDR]]
-// CHECK-OFFSET: %[[CLAMP_CAST:.*]] = fptrunc {{.*}} double {{.*}} to float
-// DXIL-OFFSET: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.sample.clamp.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE]], target("dx.Sampler", 0) %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <[[DIM]] x i32> %[[OFFSET_VAL]], float %[[CLAMP_CAST]]) [ "convergencectrl"(token %0) ]
-// SPIRV-OFFSET: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.sample.clamp.v4f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <[[DIM]] x i32> %[[OFFSET_VAL]], float %[[CLAMP_CAST]]) [ "convergencectrl"(token %0) ]
+// DXIL-OFFSET: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.sample.clamp.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE]], target("dx.Sampler", 0) %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <[[DIM]] x i32> %[[OFFSET_VAL]], float %[[CLAMP_VAL]]) [ "convergencectrl"(token %0) ]
+// SPIRV-OFFSET: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.sample.clamp.v4f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <[[DIM]] x i32> %[[OFFSET_VAL]], float %[[CLAMP_VAL]]) [ "convergencectrl"(token %0) ]
// CHECK-OFFSET: ret <4 x float> %[[RES]]
// CHECK-NOOFFSET: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::[[TEXTURE]]<float vector[4]>::Sample(hlsl::SamplerState, float vector[[[COORD_DIM]]], float)(
@@ -219,6 +218,6 @@ float4 test_clamp(COORD_TYPE loc : LOC) : SV_Target {
// CHECK-NOOFFSET: %[[HANDLE_NC:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP_NC]]
// CHECK-NOOFFSET: %[[SAMPLER_GEP_NC:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %{{.*}}, i32 0, i32 0
// CHECK-NOOFFSET: %[[SAMPLER_H_NC:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP_NC]]
-// CHECK-NOOFFSET: %[[CLAMP_CAST_NC:.*]] = fptrunc {{.*}} double {{.*}} to float
-// DXIL-NOOFFSET: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.sample.clamp.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE_NC]], target("dx.Sampler", 0) %[[SAMPLER_H_NC]], <[[COORD_DIM]] x float> %{{.*}}, <[[DIM]] x i32> zeroinitializer, float %[[CLAMP_CAST_NC]])
-// SPIRV-NOOFFSET: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.sample.clamp.v4f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE_NC]], target("spirv.Sampler") %[[SAMPLER_H_NC]], <[[COORD_DIM]] x float> %{{.*}}, <[[DIM]] x i32> zeroinitializer, float %[[CLAMP_CAST_NC]])
+// CHECK-NOOFFSET: %[[CLAMP_VAL_NC:.*]] = load float, ptr %{{.*}}
+// DXIL-NOOFFSET: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.sample.clamp.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE_NC]], target("dx.Sampler", 0) %[[SAMPLER_H_NC]], <[[COORD_DIM]] x float> %{{.*}}, <[[DIM]] x i32> zeroinitializer, float %[[CLAMP_VAL_NC]])
+// SPIRV-NOOFFSET: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.sample.clamp.v4f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE_NC]], target("spirv.Sampler") %[[SAMPLER_H_NC]], <[[COORD_DIM]] x float> %{{.*}}, <[[DIM]] x i32> zeroinitializer, float %[[CLAMP_VAL_NC]])
diff --git a/clang/test/CodeGenHLSL/resources/Textures-SampleBias.hlsl b/clang/test/CodeGenHLSL/resources/Textures-SampleBias.hlsl
index 8760ae923544a..1de79c9db3b58 100644
--- a/clang/test/CodeGenHLSL/resources/Textures-SampleBias.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Textures-SampleBias.hlsl
@@ -133,9 +133,9 @@ float4 test_bias(COORD_TYPE loc : LOC) : SV_Target {
// CHECK: %[[HANDLE1:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP1]]
// CHECK: %[[SAMPLER_GEP1:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %{{.*}}, i32 0, i32 0
// CHECK: %[[SAMPLER_H1:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP1]]
-// CHECK: %[[BIAS_CAST1:.*]] = fptrunc {{.*}} double {{.*}} to float
-// DXIL: %{{.*}} = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.samplebias.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE1]], target("dx.Sampler", 0) %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %{{.*}}, float %[[BIAS_CAST1]], <[[DIM]] x i32> zeroinitializer) [ "convergencectrl"(token %0) ]
-// SPIRV: %{{.*}} = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplebias.v4f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %{{.*}}, float %[[BIAS_CAST1]], <[[DIM]] x i32> zeroinitializer) [ "convergencectrl"(token %0) ]
+// CHECK: %[[BIAS_VAL1:.*]] = load float, ptr %{{.*}}
+// DXIL: %{{.*}} = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.samplebias.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE1]], target("dx.Sampler", 0) %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %{{.*}}, float %[[BIAS_VAL1]], <[[DIM]] x i32> zeroinitializer) [ "convergencectrl"(token %0) ]
+// SPIRV: %{{.*}} = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplebias.v4f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %{{.*}}, float %[[BIAS_VAL1]], <[[DIM]] x i32> zeroinitializer) [ "convergencectrl"(token %0) ]
// CHECK-OFFSET: @test_offset(float vector[[[COORD_DIM]]])
// CHECK-OFFSET: %[[CALL_OFFSET:.*]] = call {{.*}} <4 x float> @hlsl::[[TEXTURE]]<float vector[4]>::SampleBias(hlsl::SamplerState, float vector[[[COORD_DIM]]], float, int vector[[[DIM]]])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <[[COORD_DIM]] x float> {{.*}} %{{.*}}, float {{.*}} 0.000000e+00, <[[DIM]] x i32> noundef [[OFFSET_CONST]])
@@ -154,7 +154,7 @@ float4 test_offset(COORD_TYPE loc : LOC) : SV_Target {
// CHECK-OFFSET: %[[HANDLE2:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP2]]
// CHECK-OFFSET: %[[SAMPLER_GEP2:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %{{.*}}, i32 0, i32 0
// CHECK-OFFSET: %[[SAMPLER_H2:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP2]]
-// CHECK-OFFSET: %[[BIAS_CAST2:.*]] = fptrunc {{.*}} double {{.*}} to float
+// CHECK-OFFSET: %[[BIAS_VAL2:.*]] = load float, ptr %{{.*}}
// DXIL-OFFSET: %{{.*}} = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.samplebias.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]])
// SPIRV-OFFSET: %{{.*}} = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplebias.v4f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]])
@@ -184,10 +184,10 @@ float4 test_clamp(COORD_TYPE loc : LOC) : SV_Target {
// CHECK-OFFSET: %[[HANDLE3:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP3]]
// CHECK-OFFSET: %[[SAMPLER_GEP3:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %{{.*}}, i32 0, i32 0
// CHECK-OFFSET: %[[SAMPLER_H3:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP3]]
-// CHECK-OFFSET: %[[BIAS_CAST3:.*]] = fptrunc {{.*}} double {{.*}} to float
-// CHECK-OFFSET: %[[CLAMP_CAST3:.*]] = fptrunc {{.*}} double {{.*}} to float
-// DXIL-OFFSET: %{{.*}} = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.samplebias.clamp.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE3]], target("dx.Sampler", 0) %[[SAMPLER_H3]], <[[COORD_DIM]] x float> %{{.*}}, float %[[BIAS_CAST3]], <[[DIM]] x i32> %{{.*}}, float %[[CLAMP_CAST3]]) [ "convergencectrl"(token %0) ]
-// SPIRV-OFFSET: %{{.*}} = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplebias.clamp.v4f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE3]], target("spirv.Sampler") %[[SAMPLER_H3]], <[[COORD_DIM]] x float> %{{.*}}, float %[[BIAS_CAST3]], <[[DIM]] x i32> %{{.*}}, float %[[CLAMP_CAST3]]) [ "convergencectrl"(token %0) ]
+// CHECK-OFFSET: %[[BIAS_VAL3:.*]] = load float, ptr %{{.*}}
+// CHECK-OFFSET: %[[CLAMP_VAL3:.*]] = load float, ptr %{{.*}}
+// DXIL-OFFSET: %{{.*}} = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.samplebias.clamp.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE3]], target("dx.Sampler", 0) %[[SAMPLER_H3]], <[[COORD_DIM]] x float> %{{.*}}, float %[[BIAS_VAL3]], <[[DIM]] x i32> %{{.*}}, float %[[CLAMP_VAL3]]) [ "convergencectrl"(token %0) ]
+// SPIRV-OFFSET: %{{.*}} = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplebias.clamp.v4f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE3]], target("spirv.Sampler") %[[SAMPLER_H3]], <[[COORD_DIM]] x float> %{{.*}}, float %[[BIAS_VAL3]], <[[DIM]] x i32> %{{.*}}, float %[[CLAMP_VAL3]]) [ "convergencectrl"(token %0) ]
// CHECK-NOOFFSET: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::[[TEXTURE]]<float vector[4]>::SampleBias(hlsl::SamplerState, float vector[[[COORD_DIM]]], float, float)(
// CHECK-NOOFFSET: %[[THIS_VAL_NC:.*]] = load ptr, ptr %{{.*}}
@@ -195,7 +195,7 @@ float4 test_clamp(COORD_TYPE loc : LOC) : SV_Target {
// CHECK-NOOFFSET: %[[HANDLE_NC:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP_NC]]
// CHECK-NOOFFSET: %[[SAMPLER_GEP_NC:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %{{.*}}, i32 0, i32 0
// CHECK-NOOFFSET: %[[SAMPLER_H_NC:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP_NC]]
-// CHECK-NOOFFSET: %[[BIAS_CAST_NC:.*]] = fptrunc {{.*}} double {{.*}} to float
-// CHECK-NOOFFSET: %[[CLAMP_CAST_NC:.*]] = fptrunc {{.*}} double {{.*}} to float
-// DXIL-NOOFFSET: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.samplebias.clamp.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE_NC]], target("dx.Sampler", 0) %[[SAMPLER_H_NC]], <[[COORD_DIM]] x float> %{{.*}}, float %[[BIAS_CAST_NC]], <[[DIM]] x i32> zeroinitializer, float %[[CLAMP_CAST_NC]])
-// SPIRV-NOOFFSET: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplebias.clamp.v4f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE_NC]], target("spirv.Sampler") %[[SAMPLER_H_NC]], <[[COORD_DIM]] x float> %{{.*}}, float %[[BIAS_CAST_NC]], <[[DIM]] x i32> zeroinitializer, float %[[CLAMP_CAST_NC]])
+// CHECK-NOOFFSET: %[[BIAS_VAL_NC:.*]] = load float, ptr %{{.*}}
+// CHECK-NOOFFSET: %[[CLAMP_VAL_NC:.*]] = load float, ptr %{{.*}}
+// DXIL-NOOFFSET: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.samplebias.clamp.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE_NC]], target("dx.Sampler", 0) %[[SAMPLER_H_NC]], <[[COORD_DIM]] x float> %{{.*}}, float %[[BIAS_VAL_NC]], <[[DIM]] x i32> zeroinitializer, float %[[CLAMP_VAL_NC]])
+// SPIRV-NOOFFSET: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplebias.clamp.v4f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE_NC]], target("spirv.Sampler") %[[SAMPLER_H_NC]], <[[COORD_DIM]] x float> %{{.*}}, float %[[BIAS_VAL_NC]], <[[DIM]] x i32> zeroinitializer, float %[[CLAMP_VAL_NC]])
diff --git a/clang/test/CodeGenHLSL/resources/Textures-SampleCmp.hlsl b/clang/test/CodeGenHLSL/resources/Textures-SampleCmp.hlsl
index 7e152475b3b98..babfb6086385a 100644
--- a/clang/test/CodeGenHLSL/resources/Textures-SampleCmp.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Textures-SampleCmp.hlsl
@@ -119,9 +119,8 @@ float test_cmp(COORD_TYPE loc : LOC, float cmp : CMP) : SV_Target {
// CHECK: %[[SAMPLER_H1:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP1]]
// CHECK: %[[COORD_VAL1:.*]] = load <[[COORD_DIM]] x float>, ptr %{{.*}}
// CHECK: %[[CMP_VAL1:.*]] = load float, ptr %{{.*}}
-// CHECK: %[[CMP_CAST1:.*]] = fptrunc {{.*}} double {{.*}} to float
-// DXIL: call reassoc nnan ninf nsz arcp afn float @llvm.dx.resource.samplecmp.f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE1]], target("dx.Sampler", 0) %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL1]], float %[[CMP_CAST1]], <[[DIM]] x i32> zeroinitializer)
-// SPIRV: call reassoc nnan ninf nsz arcp afn float @llvm.spv.resource.samplecmp.f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL1]], float %[[CMP_CAST1]], <[[DIM]] x i32> zeroinitializer)
+// DXIL: call reassoc nnan ninf nsz arcp afn float @llvm.dx.resource.samplecmp.f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE1]], target("dx.Sampler", 0) %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL1]], float %[[CMP_VAL1]], <[[DIM]] x i32> zeroinitializer)
+// SPIRV: call reassoc nnan ninf nsz arcp afn float @llvm.spv.resource.samplecmp.f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL1]], float %[[CMP_VAL1]], <[[DIM]] x i32> zeroinitializer)
// CHECK-OFFSET: @test_offset(float vector[[[COORD_DIM]]], float)
// CHECK-OFFSET: %[[CALL_OFFSET:.*]] = call {{.*}} float @hlsl::[[TEXTURE]]<float vector[4]>::SampleCmp(hlsl::SamplerComparisonState, float vector[[[COORD_DIM]]], float, int vector[[[DIM]]])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerComparisonState") {{.*}}, <[[COORD_DIM]] x float> {{.*}} %{{.*}}, float {{.*}} 0.000000e+00, <[[DIM]] x i32> noundef [[OFFSET_CONST]])
@@ -143,10 +142,9 @@ float test_offset(COORD_TYPE loc : LOC, float cmp : CMP) : SV_Target {
// CHECK-OFFSET: %[[SAMPLER_H2:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP2]]
// CHECK-OFFSET: %[[COORD_VAL2:.*]] = load <[[COORD_DIM]] x float>, ptr %{{.*}}
// CHECK-OFFSET: %[[CMP_VAL2:.*]] = load float, ptr %{{.*}}
-// CHECK-OFFSET: %[[CMP_CAST2:.*]] = fptrunc {{.*}} double {{.*}} to float
// CHECK-OFFSET: %[[OFFSET_VAL2:.*]] = load <[[DIM]] x i32>, ptr %{{.*}}
-// DXIL-OFFSET: call reassoc nnan ninf nsz arcp afn float @llvm.dx.resource.samplecmp.f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE2]], target("dx.Sampler", 0) %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL2]], float %[[CMP_CAST2]], <[[DIM]] x i32> %[[OFFSET_VAL2]])
-// SPIRV-OFFSET: call reassoc nnan ninf nsz arcp afn float @llvm.spv.resource.samplecmp.f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE2]], target("spirv.Sampler") %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL2]], float %[[CMP_CAST2]], <[[DIM]] x i32> %[[OFFSET_VAL2]])
+// DXIL-OFFSET: call reassoc nnan ninf nsz arcp afn float @llvm.dx.resource.samplecmp.f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE2]], target("dx.Sampler", 0) %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL2]], float %[[CMP_VAL2]], <[[DIM]] x i32> %[[OFFSET_VAL2]])
+// SPIRV-OFFSET: call reassoc nnan ninf nsz arcp afn float @llvm.spv.resource.samplecmp.f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE2]], target("spirv.Sampler") %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL2]], float %[[CMP_VAL2]], <[[DIM]] x i32> %[[OFFSET_VAL2]])
// CHECK-OFFSET: @test_clamp(float vector[[[COORD_DIM]]], float)
// CHECK-OFFSET: %[[CALL_CLAMP:.*]] = call {{.*}} float @hlsl::[[TEXTURE]]<float vector[4]>::SampleCmp(hlsl::SamplerComparisonState, float vector[[[COORD_DIM]]], float, int vector[[[DIM]]], float)(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerComparisonState") {{.*}}, <[[COORD_DIM]] x float> {{.*}} %{{.*}}, float {{.*}} 0.000000e+00, <[[DIM]] x i32> noundef [[OFFSET_CONST]], float {{.*}} 1.000000e+00)
@@ -177,12 +175,10 @@ float test_clamp(COORD_TYPE loc : LOC, float cmp : CMP) : SV_Target {
// CHECK-OFFSET: %[[SAMPLER_H3:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP3]]
// CHECK-OFFSET: %[[COORD_VAL3:.*]] = load <[[COORD_DIM]] x float>, ptr %{{.*}}
// CHECK-OFFSET: %[[CMP_VAL3:.*]] = load float, ptr %{{.*}}
-// CHECK-OFFSET: %[[CMP_CAST3:.*]] = fptrunc {{.*}} double {{.*}} to float
// CHECK-OFFSET: %[[OFFSET_VAL3:.*]] = load <[[DIM]] x i32>, ptr %{{.*}}
// CHECK-OFFSET: %[[CLAMP_VAL3:.*]] = load float, ptr %{{.*}}
-// CHECK-OFFSET: %[[CLAMP_CAST3:.*]] = fptrunc {{.*}} double {{.*}} to float
-// DXIL-OFFSET: call reassoc nnan ninf nsz arcp afn float @llvm.dx.resource.samplecmp.clamp.f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE3]], target("dx.Sampler", 0) %[[SAMPLER_H3]], <[[COORD_DIM]] x float> %[[COORD_VAL3]], float %[[CMP_CAST3]], <[[DIM]] x i32> %[[OFFSET_VAL3]], float %[[CLAMP_CAST3]])
-// SPIRV-OFFSET: call reassoc nnan ninf nsz arcp afn float @llvm.spv.resource.samplecmp.clamp.f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE3]], target("spirv.Sampler") %[[SAMPLER_H3]], <[[COORD_DIM]] x float> %[[COORD_VAL3]], float %[[CMP_CAST3]], <[[DIM]] x i32> %[[OFFSET_VAL3]], float %[[CLAMP_CAST3]])
+// DXIL-OFFSET: call reassoc nnan ninf nsz arcp afn float @llvm.dx.resource.samplecmp.clamp.f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE3]], target("dx.Sampler", 0) %[[SAMPLER_H3]], <[[COORD_DIM]] x float> %[[COORD_VAL3]], float %[[CMP_VAL3]], <[[DIM]] x i32> %[[OFFSET_VAL3]], float %[[CLAMP_VAL3]])
+// SPIRV-OFFSET: call reassoc nnan ninf nsz arcp afn float @llvm.spv.resource.samplecmp.clamp.f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE3]], target("spirv.Sampler") %[[SAMPLER_H3]], <[[COORD_DIM]] x float> %[[COORD_VAL3]], float %[[CMP_VAL3]], <[[DIM]] x i32> %[[OFFSET_VAL3]], float %[[CLAMP_VAL3]])
// CHECK-NOOFFSET: define linkonce_odr hidden {{.*}} float @hlsl::[[TEXTURE]]<float vector[4]>::SampleCmp(hlsl::SamplerComparisonState, float vector[[[COORD_DIM]]], float, float)(
// CHECK-NOOFFSET: %[[THIS_VAL_NC:.*]] = load ptr, ptr %{{.*}}
@@ -190,7 +186,7 @@ float test_clamp(COORD_TYPE loc : LOC, float cmp : CMP) : SV_Target {
// CHECK-NOOFFSET: %[[HANDLE_NC:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP_NC]]
// CHECK-NOOFFSET: %[[SAMPLER_GEP_NC:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerComparisonState", ptr %{{.*}}, i32 0, i32 0
// CHECK-NOOFFSET: %[[SAMPLER_H_NC:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP_NC]]
-// CHECK-NOOFFSET: %[[CMP_CAST_NC:.*]] = fptrunc {{.*}} double {{.*}} to float
-// CHECK-NOOFFSET: %[[CLAMP_CAST_NC:.*]] = fptrunc {{.*}} double {{.*}} to float
-// DXIL-NOOFFSET: call reassoc nnan ninf nsz arcp afn float @llvm.dx.resource.samplecmp.clamp.f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE_NC]], target("dx.Sampler", 0) %[[SAMPLER_H_NC]], <[[COORD_DIM]] x float> %{{.*}}, float %[[CMP_CAST_NC]], <[[DIM]] x i32> zeroinitializer, float %[[CLAMP_CAST_NC]])
-// SPIRV-NOOFFSET: call reassoc nnan ninf nsz arcp afn float @llvm.spv.resource.samplecmp.clamp.f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE_NC]], target("spirv.Sampler") %[[SAMPLER_H_NC]], <[[COORD_DIM]] x float> %{{.*}}, float %[[CMP_CAST_NC]], <[[DIM]] x i32> zeroinitializer, float %[[CLAMP_CAST_NC]])
+// CHECK-NOOFFSET: %[[CMP_VAL_NC:.*]] = load float, ptr %{{.*}}
+// CHECK-NOOFFSET: %[[CLAMP_VAL_NC:.*]] = load float, ptr %{{.*}}
+// DXIL-NOOFFSET: call reassoc nnan ninf nsz arcp afn float @llvm.dx.resource.samplecmp.clamp.f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE_NC]], target("dx.Sampler", 0) %[[SAMPLER_H_NC]], <[[COORD_DIM]] x float> %{{.*}}, float %[[CMP_VAL_NC]], <[[DIM]] x i32> zeroinitializer, float %[[CLAMP_VAL_NC]])
+// SPIRV-NOOFFSET: call reassoc nnan ninf nsz arcp afn float @llvm.spv.resource.samplecmp.clamp.f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE_NC]], target("spirv.Sampler") %[[SAMPLER_H_NC]], <[[COORD_DIM]] x float> %{{.*}}, float %[[CMP_VAL_NC]], <[[DIM]] x i32> zeroinitializer, float %[[CLAMP_VAL_NC]])
diff --git a/clang/test/CodeGenHLSL/resources/Textures-SampleCmpLevelZero.hlsl b/clang/test/CodeGenHLSL/resources/Textures-SampleCmpLevelZero.hlsl
index f7c4d7bbc5c05..c2593ac370cbc 100644
--- a/clang/test/CodeGenHLSL/resources/Textures-SampleCmpLevelZero.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Textures-SampleCmpLevelZero.hlsl
@@ -103,9 +103,8 @@ float test_cmp_level_zero(COORD_TYPE loc : LOC, float cmp : CMP) : SV_Target {
// CHECK: %[[SAMPLER_H1:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP1]]
// CHECK: %[[COORD_VAL1:.*]] = load <[[COORD_DIM]] x float>, ptr %{{.*}}
// CHECK: %[[CMP_VAL1:.*]] = load float, ptr %{{.*}}
-// CHECK: %[[CMP_CAST1:.*]] = fptrunc {{.*}} double {{.*}} to float
-// DXIL: call reassoc nnan ninf nsz arcp afn float @llvm.dx.resource.samplecmplevelzero.f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE1]], target("dx.Sampler", 0) %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL1]], float %[[CMP_CAST1]], <[[DIM]] x i32> zeroinitializer)
-// SPIRV: call reassoc nnan ninf nsz arcp afn float @llvm.spv.resource.samplecmplevelzero.f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL1]], float %[[CMP_CAST1]], <[[DIM]] x i32> zeroinitializer)
+// DXIL: call reassoc nnan ninf nsz arcp afn float @llvm.dx.resource.samplecmplevelzero.f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE1]], target("dx.Sampler", 0) %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL1]], float %[[CMP_VAL1]], <[[DIM]] x i32> zeroinitializer)
+// SPIRV: call reassoc nnan ninf nsz arcp afn float @llvm.spv.resource.samplecmplevelzero.f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL1]], float %[[CMP_VAL1]], <[[DIM]] x i32> zeroinitializer)
// CHECK-OFFSET: @test_cmp_level_zero_offset(float vector[[[COORD_DIM]]], float)
// CHECK-OFFSET: %[[CALL_OFFSET:.*]] = call {{.*}} float @hlsl::[[TEXTURE]]<float vector[4]>::SampleCmpLevelZero(hlsl::SamplerComparisonState, float vector[[[COORD_DIM]]], float, int vector[[[DIM]]])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerComparisonState") {{.*}}, <[[COORD_DIM]] x float> {{.*}} %{{.*}}, float {{.*}} 0.000000e+00, <[[DIM]] x i32> noundef [[OFFSET_CONST]])
@@ -126,7 +125,6 @@ float test_cmp_level_zero_offset(COORD_TYPE loc : LOC, float cmp : CMP) : SV_Tar
// CHECK-OFFSET: %[[SAMPLER_H2:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP2]]
// CHECK-OFFSET: %[[COORD_VAL2:.*]] = load <[[COORD_DIM]] x float>, ptr %{{.*}}
// CHECK-OFFSET: %[[CMP_VAL2:.*]] = load float, ptr %{{.*}}
-// CHECK-OFFSET: %[[CMP_CAST2:.*]] = fptrunc {{.*}} double {{.*}} to float
// CHECK-OFFSET: %[[OFFSET_VAL2:.*]] = load <[[DIM]] x i32>, ptr %{{.*}}
-// DXIL-OFFSET: call reassoc nnan ninf nsz arcp afn float @llvm.dx.resource.samplecmplevelzero.f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE2]], target("dx.Sampler", 0) %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL2]], float %[[CMP_CAST2]], <[[DIM]] x i32> %[[OFFSET_VAL2]])
-// SPIRV-OFFSET: call reassoc nnan ninf nsz arcp afn float @llvm.spv.resource.samplecmplevelzero.f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE2]], target("spirv.Sampler") %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL2]], float %[[CMP_CAST2]], <[[DIM]] x i32> %[[OFFSET_VAL2]])
+// DXIL-OFFSET: call reassoc nnan ninf nsz arcp afn float @llvm.dx.resource.samplecmplevelzero.f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE2]], target("dx.Sampler", 0) %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL2]], float %[[CMP_VAL2]], <[[DIM]] x i32> %[[OFFSET_VAL2]])
+// SPIRV-OFFSET: call reassoc nnan ninf nsz arcp afn float @llvm.spv.resource.samplecmplevelzero.f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE2]], target("spirv.Sampler") %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL2]], float %[[CMP_VAL2]], <[[DIM]] x i32> %[[OFFSET_VAL2]])
diff --git a/clang/test/CodeGenHLSL/resources/Textures-SampleGrad.hlsl b/clang/test/CodeGenHLSL/resources/Textures-SampleGrad.hlsl
index dd12d2750f8c0..5a1e8a640c321 100644
--- a/clang/test/CodeGenHLSL/resources/Textures-SampleGrad.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Textures-SampleGrad.hlsl
@@ -229,9 +229,8 @@ float4 test_clamp(COORD_TYPE loc : LOC, GRAD_TYPE ddx : DDX, GRAD_TYPE ddy : DDY
// CHECK-OFFSET: %[[DDY_VAL:.*]] = load <[[DIM]] x float>, ptr %[[DDY_ADDR]]
// CHECK-OFFSET: %[[OFFSET_VAL:.*]] = load <[[DIM]] x i32>, ptr %[[OFFSET_ADDR]]
// CHECK-OFFSET: %[[CLAMP_VAL:.*]] = load float, ptr %[[CLAMP_ADDR]]
-// CHECK-OFFSET: %[[CLAMP_CAST3:.*]] = fptrunc {{.*}} double {{.*}} to float
-// DXIL-OFFSET: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.samplegrad.clamp.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE3]], target("dx.Sampler", 0) %[[SAMPLER_H3]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <[[DIM]] x float> %[[DDX_VAL]], <[[DIM]] x float> %[[DDY_VAL]], <[[DIM]] x i32> %[[OFFSET_VAL]], float %[[CLAMP_CAST3]])
-// SPIRV-OFFSET: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplegrad.clamp.v4f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE3]], target("spirv.Sampler") %[[SAMPLER_H3]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <[[DIM]] x float> %[[DDX_VAL]], <[[DIM]] x float> %[[DDY_VAL]], <[[DIM]] x i32> %[[OFFSET_VAL]], float %[[CLAMP_CAST3]])
+// DXIL-OFFSET: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.samplegrad.clamp.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE3]], target("dx.Sampler", 0) %[[SAMPLER_H3]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <[[DIM]] x float> %[[DDX_VAL]], <[[DIM]] x float> %[[DDY_VAL]], <[[DIM]] x i32> %[[OFFSET_VAL]], float %[[CLAMP_VAL]])
+// SPIRV-OFFSET: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplegrad.clamp.v4f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE3]], target("spirv.Sampler") %[[SAMPLER_H3]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <[[DIM]] x float> %[[DDX_VAL]], <[[DIM]] x float> %[[DDY_VAL]], <[[DIM]] x i32> %[[OFFSET_VAL]], float %[[CLAMP_VAL]])
// CHECK-NOOFFSET: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::[[TEXTURE]]<float vector[4]>::SampleGrad(hlsl::SamplerState, float vector[[[COORD_DIM]]], float vector[[[DIM]]], float vector[[[DIM]]], float)(
// CHECK-NOOFFSET: %[[THIS_VAL_NC:.*]] = load ptr, ptr %{{.*}}
@@ -239,6 +238,6 @@ float4 test_clamp(COORD_TYPE loc : LOC, GRAD_TYPE ddx : DDX, GRAD_TYPE ddy : DDY
// CHECK-NOOFFSET: %[[HANDLE_NC:.*]] = load target{{.*}}, ptr %[[HANDLE_GEP_NC]]
// CHECK-NOOFFSET: %[[SAMPLER_GEP_NC:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %{{.*}}, i32 0, i32 0
// CHECK-NOOFFSET: %[[SAMPLER_H_NC:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP_NC]]
-// CHECK-NOOFFSET: %[[CLAMP_CAST_NC:.*]] = fptrunc {{.*}} double {{.*}} to float
-// DXIL-NOOFFSET: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.samplegrad.clamp.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE_NC]], target("dx.Sampler", 0) %[[SAMPLER_H_NC]], <[[COORD_DIM]] x float> %{{.*}}, <[[DIM]] x float> %{{.*}}, <[[DIM]] x float> %{{.*}}, <[[DIM]] x i32> zeroinitializer, float %[[CLAMP_CAST_NC]])
-// SPIRV-NOOFFSET: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplegrad.clamp.v4f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE_NC]], target("spirv.Sampler") %[[SAMPLER_H_NC]], <[[COORD_DIM]] x float> %{{.*}}, <[[DIM]] x float> %{{.*}}, <[[DIM]] x float> %{{.*}}, <[[DIM]] x i32> zeroinitializer, float %[[CLAMP_CAST_NC]])
+// CHECK-NOOFFSET: %[[CLAMP_VAL_NC:.*]] = load float, ptr %{{.*}}
+// DXIL-NOOFFSET: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.samplegrad.clamp.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE_NC]], target("dx.Sampler", 0) %[[SAMPLER_H_NC]], <[[COORD_DIM]] x float> %{{.*}}, <[[DIM]] x float> %{{.*}}, <[[DIM]] x float> %{{.*}}, <[[DIM]] x i32> zeroinitializer, float %[[CLAMP_VAL_NC]])
+// SPIRV-NOOFFSET: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplegrad.clamp.v4f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE_NC]], target("spirv.Sampler") %[[SAMPLER_H_NC]], <[[COORD_DIM]] x float> %{{.*}}, <[[DIM]] x float> %{{.*}}, <[[DIM]] x float> %{{.*}}, <[[DIM]] x i32> zeroinitializer, float %[[CLAMP_VAL_NC]])
diff --git a/clang/test/CodeGenHLSL/resources/Textures-SampleLevel.hlsl b/clang/test/CodeGenHLSL/resources/Textures-SampleLevel.hlsl
index ca66af9c52056..7a0dc8c723c02 100644
--- a/clang/test/CodeGenHLSL/resources/Textures-SampleLevel.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Textures-SampleLevel.hlsl
@@ -138,9 +138,8 @@ float4 test_level(COORD_TYPE loc : LOC, float lod : LOD) : SV_Target {
// CHECK: %[[SAMPLER_H1:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP1]]
// CHECK: %[[COORD_VAL1:.*]] = load <[[COORD_DIM]] x float>, ptr %[[COORD_ADDR1]]
// CHECK: %[[LOD_VAL1:.*]] = load float, ptr %[[LOD_ADDR1]]
-// CHECK: %[[LOD_CAST1:.*]] = fptrunc {{.*}} double {{.*}} to float
-// DXIL: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.samplelevel.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE1]], target("dx.Sampler", 0) %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL1]], float %[[LOD_CAST1]], <[[DIM]] x i32> zeroinitializer)
-// SPIRV: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplelevel.v4f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL1]], float %[[LOD_CAST1]], <[[DIM]] x i32> zeroinitializer)
+// DXIL: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.samplelevel.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE1]], target("dx.Sampler", 0) %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL1]], float %[[LOD_VAL1]], <[[DIM]] x i32> zeroinitializer)
+// SPIRV: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplelevel.v4f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL1]], float %[[LOD_VAL1]], <[[DIM]] x i32> zeroinitializer)
// CHECK-OFFSET: @test_offset(float vector[[[COORD_DIM]]], float)
// CHECK-OFFSET: %[[CALL_OFFSET:.*]] = call {{.*}} <4 x float> @hlsl::[[TEXTURE]]<float vector[4]>::SampleLevel(hlsl::SamplerState, float vector[[[COORD_DIM]]], float, int vector[[[DIM]]])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <[[COORD_DIM]] x float> {{.*}} %{{.*}}, float {{.*}} 0.000000e+00, <[[DIM]] x i32> noundef [[OFFSET_CONST]])
@@ -169,7 +168,6 @@ float4 test_offset(COORD_TYPE loc : LOC, float lod : LOD) : SV_Target {
// CHECK-OFFSET: %[[SAMPLER_H2:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP2]]
// CHECK-OFFSET: %[[COORD_VAL2:.*]] = load <[[COORD_DIM]] x float>, ptr %[[COORD_ADDR2]]
// CHECK-OFFSET: %[[LOD_VAL2:.*]] = load float, ptr %[[LOD_ADDR2]]
-// CHECK-OFFSET: %[[LOD_CAST2:.*]] = fptrunc {{.*}} double {{.*}} to float
// CHECK-OFFSET: %[[OFFSET_VAL2:.*]] = load <[[DIM]] x i32>, ptr %[[OFFSET_ADDR2]]
-// DXIL-OFFSET: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.samplelevel.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE2]], target("dx.Sampler", 0) %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL2]], float %[[LOD_CAST2]], <[[DIM]] x i32> %[[OFFSET_VAL2]])
-// SPIRV-OFFSET: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplelevel.v4f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE2]], target("spirv.Sampler") %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL2]], float %[[LOD_CAST2]], <[[DIM]] x i32> %[[OFFSET_VAL2]])
+// DXIL-OFFSET: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.samplelevel.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE2]], target("dx.Sampler", 0) %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL2]], float %[[LOD_VAL2]], <[[DIM]] x i32> %[[OFFSET_VAL2]])
+// SPIRV-OFFSET: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplelevel.v4f32.{{.*}}(target("spirv.Image", float, [[SPV_DIM]], 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE2]], target("spirv.Sampler") %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL2]], float %[[LOD_VAL2]], <[[DIM]] x i32> %[[OFFSET_VAL2]])
diff --git a/clang/test/SemaHLSL/BuiltIns/resource_gather-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/resource_gather-errors.hlsl
new file mode 100644
index 0000000000000..2fff9f865042e
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/resource_gather-errors.hlsl
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -x hlsl \
+// RUN: -finclude-default-header -fnative-half-type -emit-llvm-only \
+// RUN: -disable-llvm-passes -verify %s
+
+// Texture2D<float4>
+using tex_t = __hlsl_resource_t [[hlsl::resource_class("SRV")]]
+ [[hlsl::contained_type(float4)]] [[hlsl::dimension("2D")]];
+using samp_t = __hlsl_resource_t [[hlsl::resource_class("Sampler")]];
+using samp_cmp_t = __hlsl_resource_t [[hlsl::resource_class("Sampler")]];
+
+export void gather(tex_t t, samp_t s, samp_cmp_t sc, float2 uv, double2 duv,
+ uint comp, int64_t lcomp, float fcomp, int2 off, uint2 uoff,
+ float2 foff, float cmp, double d) {
+ __builtin_hlsl_resource_gather(t, s, uv, comp);
+ __builtin_hlsl_resource_gather(t, s, uv, 0u, off);
+
+ // expected-error at +1 {{passing 'double2' (aka 'vector<double, 2>') to parameter of incompatible type 'vector<float, 2>'}}
+ __builtin_hlsl_resource_gather(t, s, duv, 0u);
+
+ // expected-error at +1 {{passing 'int' to parameter of incompatible type 'unsigned int'}}
+ __builtin_hlsl_resource_gather(t, s, uv, 0);
+
+ // expected-error at +1 {{passing 'int64_t' (aka 'long') to parameter of incompatible type 'unsigned int'}}
+ __builtin_hlsl_resource_gather(t, s, uv, lcomp);
+
+ // expected-error at +1 {{passing 'float' to parameter of incompatible type 'unsigned int'}}
+ __builtin_hlsl_resource_gather(t, s, uv, fcomp);
+
+ // expected-error at +1 {{passing 'uint2' (aka 'vector<uint, 2>') to parameter of incompatible type 'vector<int, 2>'}}
+ __builtin_hlsl_resource_gather(t, s, uv, 0u, uoff);
+
+ // expected-error at +1 {{passing 'float2' (aka 'vector<float, 2>') to parameter of incompatible type 'vector<int, 2>'}}
+ __builtin_hlsl_resource_gather(t, s, uv, 0u, foff);
+
+ __builtin_hlsl_resource_gather_cmp(t, sc, uv, cmp, 0u);
+
+ // expected-error at +1 {{passing 'double' to parameter of incompatible type 'float'}}
+ __builtin_hlsl_resource_gather_cmp(t, sc, uv, d, 0u);
+
+ // expected-error at +1 {{passing 'double2' (aka 'vector<double, 2>') to parameter of incompatible type 'vector<float, 2>'}}
+ __builtin_hlsl_resource_gather_cmp(t, sc, duv, cmp, 0u);
+}
diff --git a/clang/test/SemaHLSL/BuiltIns/resource_load-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/resource_load-errors.hlsl
new file mode 100644
index 0000000000000..b22dae4d1bae9
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/resource_load-errors.hlsl
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -x hlsl \
+// RUN: -finclude-default-header -fnative-half-type -emit-llvm-only \
+// RUN: -disable-llvm-passes -verify %s
+
+// Texture2D<float4>
+using tex_t = __hlsl_resource_t [[hlsl::resource_class("SRV")]]
+ [[hlsl::contained_type(float4)]] [[hlsl::dimension("2D")]];
+// Texture2DMS<float4>
+using tex_ms_t = __hlsl_resource_t [[hlsl::resource_class("SRV")]]
+ [[hlsl::contained_type(float4)]] [[hlsl::dimension("2D")]]
+ [[hlsl::is_ms]];
+
+export void load(tex_t t, int3 loc, vector<int64_t,3> wide_loc, uint3 uloc,
+ float3 floc, int2 off, uint2 uoff, float2 foff) {
+ __builtin_hlsl_resource_load_level(t, loc);
+ __builtin_hlsl_resource_load_level(t, loc, off);
+
+ // expected-error at +1 {{passing 'vector<int64_t, 3>' (vector of 3 'int64_t' values) to parameter of incompatible type 'vector<int, 3>'}}
+ __builtin_hlsl_resource_load_level(t, wide_loc);
+
+ // expected-error at +1 {{passing 'uint3' (aka 'vector<uint, 3>') to parameter of incompatible type 'vector<int, 3>'}}
+ __builtin_hlsl_resource_load_level(t, uloc);
+
+ // expected-error at +1 {{passing 'float3' (aka 'vector<float, 3>') to parameter of incompatible type 'vector<int, 3>'}}
+ __builtin_hlsl_resource_load_level(t, floc);
+
+ // expected-error at +1 {{passing 'uint2' (aka 'vector<uint, 2>') to parameter of incompatible type 'vector<int, 2>'}}
+ __builtin_hlsl_resource_load_level(t, loc, uoff);
+
+ // expected-error at +1 {{passing 'float2' (aka 'vector<float, 2>') to parameter of incompatible type 'vector<int, 2>'}}
+ __builtin_hlsl_resource_load_level(t, loc, foff);
+}
+
+export void load_ms(tex_ms_t t, int2 loc, int sample, int64_t lsample,
+ float fsample, int2 off, uint2 uoff, float2 foff) {
+ __builtin_hlsl_resource_load_ms(t, loc, sample);
+ __builtin_hlsl_resource_load_ms(t, loc, 0, off);
+
+ // expected-error at +1 {{passing 'int64_t' (aka 'long') to parameter of incompatible type 'int'}}
+ __builtin_hlsl_resource_load_ms(t, loc, lsample);
+
+ // Names 'float', not the 'double' that default argument promotion would have
+ // widened it to without CustomTypeChecking.
+ // expected-error at +1 {{passing 'float' to parameter of incompatible type 'int'}}
+ __builtin_hlsl_resource_load_ms(t, loc, fsample);
+
+ // expected-error at +1 {{passing 'uint2' (aka 'vector<uint, 2>') to parameter of incompatible type 'vector<int, 2>'}}
+ __builtin_hlsl_resource_load_ms(t, loc, 0, uoff);
+
+ // expected-error at +1 {{passing 'float2' (aka 'vector<float, 2>') to parameter of incompatible type 'vector<int, 2>'}}
+ __builtin_hlsl_resource_load_ms(t, loc, 0, foff);
+}
diff --git a/clang/test/SemaHLSL/BuiltIns/resource_sample-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/resource_sample-errors.hlsl
new file mode 100644
index 0000000000000..4c2db670e5cb1
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/resource_sample-errors.hlsl
@@ -0,0 +1,117 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -x hlsl \
+// RUN: -finclude-default-header -fnative-half-type -emit-llvm-only \
+// RUN: -disable-llvm-passes -verify %s
+
+// Texture2D<float4>
+using tex_t = __hlsl_resource_t [[hlsl::resource_class("SRV")]]
+ [[hlsl::contained_type(float4)]] [[hlsl::dimension("2D")]];
+
+using samp_t = __hlsl_resource_t [[hlsl::resource_class("Sampler")]];
+using samp_cmp_t = __hlsl_resource_t [[hlsl::resource_class("Sampler")]];
+
+//
+// Sample location.
+//
+
+export void location(tex_t t, samp_t s, float2 uv, double2 duv, half2 huv,
+ int2 iuv, float3 uvw, float u) {
+ __builtin_hlsl_resource_sample(t, s, uv);
+
+ // expected-error at +1 {{passing 'double2' (aka 'vector<double, 2>') to parameter of incompatible type 'vector<float, 2>'}}
+ __builtin_hlsl_resource_sample(t, s, duv);
+
+ // expected-error at +1 {{passing 'half2' (aka 'vector<half, 2>') to parameter of incompatible type 'vector<float, 2>'}}
+ __builtin_hlsl_resource_sample(t, s, huv);
+
+ // expected-error at +1 {{passing 'int2' (aka 'vector<int, 2>') to parameter of incompatible type 'vector<float, 2>'}}
+ __builtin_hlsl_resource_sample(t, s, iuv);
+
+ // expected-error at +1 {{passing 'float3' (aka 'vector<float, 3>') to parameter of incompatible type 'vector<float, 2>'}}
+ __builtin_hlsl_resource_sample(t, s, uvw);
+
+ // expected-error at +1 {{passing 'float' to parameter of incompatible type 'vector<float, 2>'}}
+ __builtin_hlsl_resource_sample(t, s, u);
+}
+
+//
+// Offset.
+//
+
+export void offset(tex_t t, samp_t s, float2 uv, int2 off, uint2 uoff,
+ float2 foff, vector<int64_t,2> loff) {
+ __builtin_hlsl_resource_sample(t, s, uv, off);
+
+ // expected-error at +1 {{passing 'uint2' (aka 'vector<uint, 2>') to parameter of incompatible type 'vector<int, 2>'}}
+ __builtin_hlsl_resource_sample(t, s, uv, uoff);
+
+ // expected-error at +1 {{passing 'vector<int64_t, 2>' (vector of 2 'int64_t' values) to parameter of incompatible type 'vector<int, 2>'}}
+ __builtin_hlsl_resource_sample(t, s, uv, loff);
+
+ // expected-error at +1 {{passing 'float2' (aka 'vector<float, 2>') to parameter of incompatible type 'vector<int, 2>'}}
+ __builtin_hlsl_resource_sample(t, s, uv, foff);
+}
+
+//
+// Scalar float operands: bias, LOD, compare value and clamp.
+//
+
+export void scalar_operands(tex_t t, samp_t s, samp_cmp_t sc, float2 uv,
+ float f, double d, half h, float2 v) {
+ // Each is a single 32-bit float.
+ __builtin_hlsl_resource_sample_bias(t, s, uv, f);
+
+ // expected-error at +1 {{passing 'double' to parameter of incompatible type 'float'}}
+ __builtin_hlsl_resource_sample_bias(t, s, uv, d);
+
+ // expected-error at +1 {{passing 'half' to parameter of incompatible type 'float'}}
+ __builtin_hlsl_resource_sample_bias(t, s, uv, h);
+
+ // expected-error at +1 {{passing 'double' to parameter of incompatible type 'float'}}
+ __builtin_hlsl_resource_sample_level(t, s, uv, d);
+
+ // expected-error at +1 {{passing 'double' to parameter of incompatible type 'float'}}
+ __builtin_hlsl_resource_sample_cmp(t, sc, uv, d);
+
+ // expected-error at +1 {{passing 'double' to parameter of incompatible type 'float'}}
+ __builtin_hlsl_resource_sample_cmp_level_zero(t, sc, uv, d);
+
+ // expected-error at +1 {{passing 'double' to parameter of incompatible type 'float'}}
+ __builtin_hlsl_resource_sample(t, s, uv, int2(0, 0), d);
+
+ // expected-error at +1 {{passing 'float2' (aka 'vector<float, 2>') to parameter of incompatible type 'float'}}
+ __builtin_hlsl_resource_sample(t, s, uv, int2(0, 0), v);
+
+ // expected-error at +1 {{passing 'float2' (aka 'vector<float, 2>') to parameter of incompatible type 'float'}}
+ __builtin_hlsl_resource_sample_cmp_level_zero(t, sc, uv, v);
+}
+
+//
+// Gradients.
+//
+
+export void gradients(tex_t t, samp_t s, float2 uv, double2 d, float3 wide) {
+ __builtin_hlsl_resource_sample_grad(t, s, uv, uv, uv);
+
+ // expected-error at +1 {{passing 'double2' (aka 'vector<double, 2>') to parameter of incompatible type 'vector<float, 2>'}}
+ __builtin_hlsl_resource_sample_grad(t, s, uv, d, uv);
+
+ // expected-error at +1 {{passing 'float3' (aka 'vector<float, 3>') to parameter of incompatible type 'vector<float, 2>'}}
+ __builtin_hlsl_resource_sample_grad(t, s, uv, wide, uv);
+}
+
+//
+// CalculateLevelOfDetail.
+//
+
+export void calculate_lod(tex_t t, samp_t s, float2 uv, double2 duv) {
+ __builtin_hlsl_resource_calculate_lod(t, s, uv);
+
+ // expected-error at +1 {{passing 'double2' (aka 'vector<double, 2>') to parameter of incompatible type 'vector<float, 2>'}}
+ __builtin_hlsl_resource_calculate_lod(t, s, duv);
+
+ // expected-error at +1 {{passing 'double2' (aka 'vector<double, 2>') to parameter of incompatible type 'vector<float, 2>'}}
+ __builtin_hlsl_resource_calculate_lod_unclamped(t, s, duv);
+
+ // expected-error at +1 {{passing 'float' to parameter of incompatible type 'vector<float, 2>'}}
+ __builtin_hlsl_resource_calculate_lod(t, s, uv.x);
+}
>From 429c88317e76967f3d00055d2034c87bab858fc0 Mon Sep 17 00:00:00 2001
From: Deric Cheung <cheung.deric at gmail.com>
Date: Thu, 3 Sep 2026 14:47:20 -0700
Subject: [PATCH 2/2] Apply clang-format
---
clang/lib/Sema/SemaHLSL.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 86ce02444e1d6..461bb8fb96678 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -3710,7 +3710,6 @@ static QualType createCounterHandleType(ASTContext &AST,
MainAttrs);
}
-
enum class SampleKind { Sample, Bias, Grad, Level, Cmp, CmpLevelZero };
static StringRef getSampleMethodName(SampleKind Kind) {
More information about the cfe-commits
mailing list