https://github.com/tcorringham updated https://github.com/llvm/llvm-project/pull/211256
>From 9df964e1090328a8585ca87a24c41bf90f640ee5 Mon Sep 17 00:00:00 2001 From: Tim Corringham <[email protected]> Date: Wed, 22 Jul 2026 11:08:50 +0100 Subject: [PATCH 1/8] [HLSL][SPIRV] Add IntrConvergent to convergent intrinsics A number of spirv intrinsics need to run in convergent code flow but LLVM -O3 could sometimes lower these into divergent control flow as they were missing the IntrConvergent attribute. This change adds the IntrConvergent attribute to these intrinsics, and switches the builtin emission from `Builder.CreateIntrinsic` to `EmitRuntimeCall` (via a helper function) so that the attribute is preserved through codegen. Tests check that the Convergent attribute is added where expected, and that it survives a llvm-as/llvm-dis round-trip. Assisted by Cursor Fixes #211253 --- clang/lib/CodeGen/CGHLSLBuiltins.cpp | 40 +++++++++++++------ llvm/include/llvm/IR/IntrinsicsSPIRV.td | 12 +++--- .../spirv-resource-intrinsic-attributes.ll | 29 ++++++++++++++ llvm/unittests/IR/IntrinsicsTest.cpp | 26 +++++++++++- 4 files changed, 87 insertions(+), 20 deletions(-) create mode 100644 llvm/test/Assembler/spirv-resource-intrinsic-attributes.ll diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp index 1bda113143e07..9cdf650f1d560 100644 --- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp +++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp @@ -533,6 +533,19 @@ static Value *emitHlslClamp(CodeGenFunction &CGF, const CallExpr *E, return Clamp; } +static CallInst *emitConvergentResourceIntrinsicCall(CodeGenFunction &CGF, + llvm::Type *RetTy, + Intrinsic::ID ID, + ArrayRef<Value *> Args) { + SmallVector<llvm::Type *> ArgTys; + ArgTys.reserve(Args.size()); + for (Value *Arg : Args) + ArgTys.push_back(Arg->getType()); + Function *IntrFn = Intrinsic::getOrInsertDeclaration( + &CGF.CGM.getModule(), ID, RetTy, ArgTys); + return CGF.EmitRuntimeCall(IntrFn, Args); +} + static Value *emitGetDimensions(CodeGenFunction &CGF, const CallExpr *E, unsigned IntrinsicID, unsigned NumRetComps, bool HasLod) { @@ -667,13 +680,13 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, llvm::Type *RetTy = ConvertType(E->getType()); if (E->getNumArgs() <= 4) { - return Builder.CreateIntrinsic( - RetTy, CGM.getHLSLRuntime().getSampleIntrinsic(), Args); + return emitConvergentResourceIntrinsicCall( + *this, RetTy, CGM.getHLSLRuntime().getSampleIntrinsic(), Args); } Args.push_back(emitHlslClamp(*this, E, 4)); - return Builder.CreateIntrinsic( - RetTy, CGM.getHLSLRuntime().getSampleClampIntrinsic(), Args); + return emitConvergentResourceIntrinsicCall( + *this, RetTy, CGM.getHLSLRuntime().getSampleClampIntrinsic(), Args); } case Builtin::BI__builtin_hlsl_resource_sample_bias: { Value *HandleOp = EmitScalarExpr(E->getArg(0)); @@ -692,13 +705,14 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Args.push_back(emitHlslOffset(*this, E, 4, getOffsetType(CGM, RT))); llvm::Type *RetTy = ConvertType(E->getType()); - if (E->getNumArgs() <= 5) - return Builder.CreateIntrinsic( - RetTy, CGM.getHLSLRuntime().getSampleBiasIntrinsic(), Args); + if (E->getNumArgs() <= 5) { + return emitConvergentResourceIntrinsicCall( + *this, RetTy, CGM.getHLSLRuntime().getSampleBiasIntrinsic(), Args); + } Args.push_back(emitHlslClamp(*this, E, 5)); - return Builder.CreateIntrinsic( - RetTy, CGM.getHLSLRuntime().getSampleBiasClampIntrinsic(), Args); + return emitConvergentResourceIntrinsicCall( + *this, RetTy, CGM.getHLSLRuntime().getSampleBiasClampIntrinsic(), Args); } case Builtin::BI__builtin_hlsl_resource_sample_grad: { Value *HandleOp = EmitScalarExpr(E->getArg(0)); @@ -827,8 +841,8 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *SamplerOp = EmitScalarExpr(E->getArg(1)); Value *CoordOp = EmitScalarExpr(E->getArg(2)); - return Builder.CreateIntrinsic( - ConvertType(E->getType()), + return emitConvergentResourceIntrinsicCall( + *this, ConvertType(E->getType()), CGM.getHLSLRuntime().getCalculateLodIntrinsic(), {HandleOp, SamplerOp, CoordOp}); } @@ -837,8 +851,8 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *SamplerOp = EmitScalarExpr(E->getArg(1)); Value *CoordOp = EmitScalarExpr(E->getArg(2)); - return Builder.CreateIntrinsic( - ConvertType(E->getType()), + return emitConvergentResourceIntrinsicCall( + *this, ConvertType(E->getType()), CGM.getHLSLRuntime().getCalculateLodUnclampedIntrinsic(), {HandleOp, SamplerOp, CoordOp}); } diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td index d948ef78b9584..b6debb2a0b74a 100644 --- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td +++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td @@ -245,25 +245,25 @@ def int_spv_rsqrt : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty] def int_spv_resource_sample : DefaultAttrsIntrinsic< [llvm_any_ty], [llvm_any_ty, llvm_any_ty, llvm_any_ty, llvm_any_ty], - [IntrReadMem]>; + [IntrReadMem, IntrConvergent]>; def int_spv_resource_sample_clamp : DefaultAttrsIntrinsic<[llvm_any_ty], [llvm_any_ty, llvm_any_ty, llvm_any_ty, llvm_any_ty, llvm_float_ty], - [IntrReadMem]>; + [IntrReadMem, IntrConvergent]>; def int_spv_resource_samplebias : DefaultAttrsIntrinsic<[llvm_any_ty], [llvm_any_ty, llvm_any_ty, llvm_any_ty, llvm_float_ty, llvm_any_ty], - [IntrReadMem]>; + [IntrReadMem, IntrConvergent]>; def int_spv_resource_samplebias_clamp : DefaultAttrsIntrinsic<[llvm_any_ty], [llvm_any_ty, llvm_any_ty, llvm_any_ty, llvm_float_ty, llvm_any_ty, llvm_float_ty], - [IntrReadMem]>; + [IntrReadMem, IntrConvergent]>; def int_spv_resource_samplegrad : DefaultAttrsIntrinsic<[llvm_any_ty], @@ -311,12 +311,12 @@ def int_spv_rsqrt : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty] def int_spv_resource_calculate_lod : DefaultAttrsIntrinsic<[llvm_any_ty], [llvm_any_ty, llvm_any_ty, llvm_any_ty], - [IntrReadMem]>; + [IntrReadMem, IntrConvergent]>; def int_spv_resource_calculate_lod_unclamped : DefaultAttrsIntrinsic<[llvm_any_ty], [llvm_any_ty, llvm_any_ty, llvm_any_ty], - [IntrReadMem]>; + [IntrReadMem, IntrConvergent]>; def int_spv_resource_gather : DefaultAttrsIntrinsic<[llvm_any_ty], diff --git a/llvm/test/Assembler/spirv-resource-intrinsic-attributes.ll b/llvm/test/Assembler/spirv-resource-intrinsic-attributes.ll new file mode 100644 index 0000000000000..6cb690411d8b0 --- /dev/null +++ b/llvm/test/Assembler/spirv-resource-intrinsic-attributes.ll @@ -0,0 +1,29 @@ +; RUN: llvm-as < %s | llvm-dis | FileCheck %s + +; Verify SPIR-V resource intrinsics that use implicit derivatives are marked +; convergent so LLVM does not sink them into divergent control flow. + +; CHECK: declare float @llvm.spv.resource.calculate.lod.f32.{{.*}} [[CONVERGENT:#[0-9]+]] +declare float @llvm.spv.resource.calculate.lod.f32.tspirv.Image_f32_1_2_0_0_1_0t.tspirv.Samplert.v2f32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0), target("spirv.Sampler"), <2 x float>) + +; CHECK: declare float @llvm.spv.resource.calculate.lod.unclamped.f32.{{.*}} [[CONVERGENT]] +declare float @llvm.spv.resource.calculate.lod.unclamped.f32.tspirv.Image_f32_1_2_0_0_1_0t.tspirv.Samplert.v2f32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0), target("spirv.Sampler"), <2 x float>) + +; CHECK: declare <4 x float> @llvm.spv.resource.sample.v4f32.{{.*}} [[CONVERGENT]] +declare <4 x float> @llvm.spv.resource.sample.v4f32.tspirv.Image_f32_1_2_0_0_1_0t.tspirv.Samplert.v2f32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0), target("spirv.Sampler"), <2 x float>, <2 x i32>) + +; CHECK: declare <4 x float> @llvm.spv.resource.sample.clamp.v4f32.{{.*}} [[CONVERGENT]] +declare <4 x float> @llvm.spv.resource.sample.clamp.v4f32.tspirv.Image_f32_1_2_0_0_1_0t.tspirv.Samplert.v2f32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0), target("spirv.Sampler"), <2 x float>, <2 x i32>, float) + +; CHECK: declare <4 x float> @llvm.spv.resource.samplebias.v4f32.{{.*}} [[CONVERGENT]] +declare <4 x float> @llvm.spv.resource.samplebias.v4f32.tspirv.Image_f32_1_2_0_0_1_0t.tspirv.Samplert.v2f32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0), target("spirv.Sampler"), <2 x float>, float, <2 x i32>) + +; CHECK: declare <4 x float> @llvm.spv.resource.samplebias.clamp.v4f32.{{.*}} [[CONVERGENT]] +declare <4 x float> @llvm.spv.resource.samplebias.clamp.v4f32.tspirv.Image_f32_1_2_0_0_1_0t.tspirv.Samplert.v2f32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0), target("spirv.Sampler"), <2 x float>, float, <2 x i32>, float) + +; Explicit-derivative sampling should remain non-convergent. +; CHECK: declare <4 x float> @llvm.spv.resource.samplegrad.v4f32.{{.*}} [[NON_CONVERGENT:#[0-9]+]] +declare <4 x float> @llvm.spv.resource.samplegrad.v4f32.tspirv.Image_f32_1_2_0_0_1_0t.tspirv.Samplert.v3f32.v2f32.v2f32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0), target("spirv.Sampler"), <3 x float>, <2 x float>, <2 x float>, <2 x i32>) + +; CHECK: attributes [[CONVERGENT]] = { convergent nocallback nofree nosync nounwind willreturn memory(read) } +; CHECK: attributes [[NON_CONVERGENT]] = { nocallback nofree nosync nounwind willreturn memory(read) } diff --git a/llvm/unittests/IR/IntrinsicsTest.cpp b/llvm/unittests/IR/IntrinsicsTest.cpp index d502bf591b7fa..c2a9fc5316fff 100644 --- a/llvm/unittests/IR/IntrinsicsTest.cpp +++ b/llvm/unittests/IR/IntrinsicsTest.cpp @@ -23,6 +23,7 @@ #include "llvm/IR/IntrinsicsPowerPC.h" #include "llvm/IR/IntrinsicsRISCV.h" #include "llvm/IR/IntrinsicsS390.h" +#include "llvm/IR/IntrinsicsSPIRV.h" #include "llvm/IR/IntrinsicsX86.h" #include "llvm/IR/Module.h" #include "gtest/gtest.h" @@ -189,8 +190,31 @@ TEST_F(IntrinsicsTest, InstrProfInheritance) { } } +TEST(IntrinsicAttributes, SPIRVResourceImplicitDerivativeIntrinsicsAreConvergent) { + using namespace Intrinsic; + LLVMContext Context; + static constexpr ID ConvergentResourceIntrinsics[] = { + spv_resource_sample, + spv_resource_sample_clamp, + spv_resource_samplebias, + spv_resource_samplebias_clamp, + spv_resource_calculate_lod, + spv_resource_calculate_lod_unclamped, + }; + for (ID IntrID : ConvergentResourceIntrinsics) { + AttributeSet AS = getFnAttributes(Context, IntrID); + EXPECT_TRUE(AS.hasAttribute(Attribute::Convergent)) + << "Intrinsic " << getName(IntrID) << " should be convergent"; + } + + AttributeSet SampleGradAttrs = getFnAttributes(Context, spv_resource_samplegrad); + EXPECT_FALSE(SampleGradAttrs.hasAttribute(Attribute::Convergent)) + << "Intrinsic " << getName(spv_resource_samplegrad) + << " should not be convergent"; +} + // Check that getFnAttributes for intrinsics that do not have any function -// attributes correcty returns an empty set. +// attributes correctly returns an empty set. TEST(IntrinsicAttributes, TestGetFnAttributesBug) { using namespace Intrinsic; LLVMContext Context; >From 19e3b539dde0ff0c49b1bf5a3c0a51de1f35d464 Mon Sep 17 00:00:00 2001 From: Tim Corringham <[email protected]> Date: Wed, 22 Jul 2026 14:54:59 +0100 Subject: [PATCH 2/8] Fix clang-format errors Tidy up formatting errors - no functional change. --- clang/lib/CodeGen/CGHLSLBuiltins.cpp | 4 ++-- llvm/unittests/IR/IntrinsicsTest.cpp | 15 +++++++-------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp index 9cdf650f1d560..2187f9de315f2 100644 --- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp +++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp @@ -541,8 +541,8 @@ static CallInst *emitConvergentResourceIntrinsicCall(CodeGenFunction &CGF, ArgTys.reserve(Args.size()); for (Value *Arg : Args) ArgTys.push_back(Arg->getType()); - Function *IntrFn = Intrinsic::getOrInsertDeclaration( - &CGF.CGM.getModule(), ID, RetTy, ArgTys); + Function *IntrFn = Intrinsic::getOrInsertDeclaration(&CGF.CGM.getModule(), ID, + RetTy, ArgTys); return CGF.EmitRuntimeCall(IntrFn, Args); } diff --git a/llvm/unittests/IR/IntrinsicsTest.cpp b/llvm/unittests/IR/IntrinsicsTest.cpp index c2a9fc5316fff..003b9fd61ceaf 100644 --- a/llvm/unittests/IR/IntrinsicsTest.cpp +++ b/llvm/unittests/IR/IntrinsicsTest.cpp @@ -190,16 +190,14 @@ TEST_F(IntrinsicsTest, InstrProfInheritance) { } } -TEST(IntrinsicAttributes, SPIRVResourceImplicitDerivativeIntrinsicsAreConvergent) { +TEST(IntrinsicAttributes, + SPIRVResourceImplicitDerivativeIntrinsicsAreConvergent) { using namespace Intrinsic; LLVMContext Context; static constexpr ID ConvergentResourceIntrinsics[] = { - spv_resource_sample, - spv_resource_sample_clamp, - spv_resource_samplebias, - spv_resource_samplebias_clamp, - spv_resource_calculate_lod, - spv_resource_calculate_lod_unclamped, + spv_resource_sample, spv_resource_sample_clamp, + spv_resource_samplebias, spv_resource_samplebias_clamp, + spv_resource_calculate_lod, spv_resource_calculate_lod_unclamped, }; for (ID IntrID : ConvergentResourceIntrinsics) { AttributeSet AS = getFnAttributes(Context, IntrID); @@ -207,7 +205,8 @@ TEST(IntrinsicAttributes, SPIRVResourceImplicitDerivativeIntrinsicsAreConvergent << "Intrinsic " << getName(IntrID) << " should be convergent"; } - AttributeSet SampleGradAttrs = getFnAttributes(Context, spv_resource_samplegrad); + AttributeSet SampleGradAttrs = + getFnAttributes(Context, spv_resource_samplegrad); EXPECT_FALSE(SampleGradAttrs.hasAttribute(Attribute::Convergent)) << "Intrinsic " << getName(spv_resource_samplegrad) << " should not be convergent"; >From c092b71b89a30c4c4fb847ed3b60cbbea072edf6 Mon Sep 17 00:00:00 2001 From: Tim Corringham <[email protected]> Date: Mon, 27 Jul 2026 19:10:07 +0100 Subject: [PATCH 3/8] Add IntrConvergent to DirectX resource intrinsics Added IntrConvergent property to the DirextX intrinsics, and adjusted the test case accordingly. Renamed the helper function - a wider cleanup is debatable, and is left as a separate exercise. --- clang/lib/CodeGen/CGHLSLBuiltins.cpp | 19 +++--- llvm/include/llvm/IR/IntrinsicsDirectX.td | 12 ++-- .../resource-intrinsic-attributes.ll | 59 +++++++++++++++++++ .../spirv-resource-intrinsic-attributes.ll | 29 --------- 4 files changed, 74 insertions(+), 45 deletions(-) create mode 100644 llvm/test/Assembler/resource-intrinsic-attributes.ll delete mode 100644 llvm/test/Assembler/spirv-resource-intrinsic-attributes.ll diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp index 2187f9de315f2..d6df16d65e550 100644 --- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp +++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp @@ -533,10 +533,9 @@ static Value *emitHlslClamp(CodeGenFunction &CGF, const CallExpr *E, return Clamp; } -static CallInst *emitConvergentResourceIntrinsicCall(CodeGenFunction &CGF, - llvm::Type *RetTy, - Intrinsic::ID ID, - ArrayRef<Value *> Args) { +static CallInst *emitResourceIntrinsic(CodeGenFunction &CGF, llvm::Type *RetTy, + Intrinsic::ID ID, + ArrayRef<Value *> Args) { SmallVector<llvm::Type *> ArgTys; ArgTys.reserve(Args.size()); for (Value *Arg : Args) @@ -680,12 +679,12 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, llvm::Type *RetTy = ConvertType(E->getType()); if (E->getNumArgs() <= 4) { - return emitConvergentResourceIntrinsicCall( + return emitResourceIntrinsic( *this, RetTy, CGM.getHLSLRuntime().getSampleIntrinsic(), Args); } Args.push_back(emitHlslClamp(*this, E, 4)); - return emitConvergentResourceIntrinsicCall( + return emitResourceIntrinsic( *this, RetTy, CGM.getHLSLRuntime().getSampleClampIntrinsic(), Args); } case Builtin::BI__builtin_hlsl_resource_sample_bias: { @@ -706,12 +705,12 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, llvm::Type *RetTy = ConvertType(E->getType()); if (E->getNumArgs() <= 5) { - return emitConvergentResourceIntrinsicCall( + return emitResourceIntrinsic( *this, RetTy, CGM.getHLSLRuntime().getSampleBiasIntrinsic(), Args); } Args.push_back(emitHlslClamp(*this, E, 5)); - return emitConvergentResourceIntrinsicCall( + return emitResourceIntrinsic( *this, RetTy, CGM.getHLSLRuntime().getSampleBiasClampIntrinsic(), Args); } case Builtin::BI__builtin_hlsl_resource_sample_grad: { @@ -841,7 +840,7 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *SamplerOp = EmitScalarExpr(E->getArg(1)); Value *CoordOp = EmitScalarExpr(E->getArg(2)); - return emitConvergentResourceIntrinsicCall( + return emitResourceIntrinsic( *this, ConvertType(E->getType()), CGM.getHLSLRuntime().getCalculateLodIntrinsic(), {HandleOp, SamplerOp, CoordOp}); @@ -851,7 +850,7 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *SamplerOp = EmitScalarExpr(E->getArg(1)); Value *CoordOp = EmitScalarExpr(E->getArg(2)); - return emitConvergentResourceIntrinsicCall( + return emitResourceIntrinsic( *this, ConvertType(E->getType()), CGM.getHLSLRuntime().getCalculateLodUnclampedIntrinsic(), {HandleOp, SamplerOp, CoordOp}); diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td index 4dd86270f0d01..2b155701564f7 100644 --- a/llvm/include/llvm/IR/IntrinsicsDirectX.td +++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td @@ -91,24 +91,24 @@ def int_dx_resource_getdimensions_levels_xy def int_dx_resource_sample : DefaultAttrsIntrinsic< [llvm_any_ty], [llvm_any_ty, llvm_any_ty, llvm_any_ty, llvm_any_ty], - [IntrReadMem]>; + [IntrReadMem, IntrConvergent]>; def int_dx_resource_sample_clamp : DefaultAttrsIntrinsic<[llvm_any_ty], [llvm_any_ty, llvm_any_ty, llvm_any_ty, llvm_any_ty, llvm_float_ty], - [IntrReadMem]>; + [IntrReadMem, IntrConvergent]>; def int_dx_resource_samplebias : DefaultAttrsIntrinsic<[llvm_any_ty], [llvm_any_ty, llvm_any_ty, llvm_any_ty, llvm_float_ty, llvm_any_ty], - [IntrReadMem]>; + [IntrReadMem, IntrConvergent]>; def int_dx_resource_samplebias_clamp : DefaultAttrsIntrinsic<[llvm_any_ty], [llvm_any_ty, llvm_any_ty, llvm_any_ty, llvm_float_ty, llvm_any_ty, llvm_float_ty], - [IntrReadMem]>; + [IntrReadMem, IntrConvergent]>; def int_dx_resource_samplegrad : DefaultAttrsIntrinsic<[llvm_any_ty], @@ -137,12 +137,12 @@ def int_dx_resource_load_level def int_dx_resource_calculate_lod : DefaultAttrsIntrinsic<[llvm_float_ty], [llvm_any_ty, llvm_any_ty, llvm_any_ty], - [IntrReadMem]>; + [IntrReadMem, IntrConvergent]>; def int_dx_resource_calculate_lod_unclamped : DefaultAttrsIntrinsic<[llvm_float_ty], [llvm_any_ty, llvm_any_ty, llvm_any_ty], - [IntrReadMem]>; + [IntrReadMem, IntrConvergent]>; def int_dx_resource_samplecmp : DefaultAttrsIntrinsic<[llvm_any_ty], diff --git a/llvm/test/Assembler/resource-intrinsic-attributes.ll b/llvm/test/Assembler/resource-intrinsic-attributes.ll new file mode 100644 index 0000000000000..6bb1fac70e4c5 --- /dev/null +++ b/llvm/test/Assembler/resource-intrinsic-attributes.ll @@ -0,0 +1,59 @@ +; RUN: llvm-as < %s | llvm-dis | FileCheck %s + +; Verify both DirectX and SPIR-V resource intrinsics that use implicit +; derivatives are marked convergent so LLVM does not sink them into +; divergent control flow. + +; CHECK: declare float @llvm.dx.resource.calculate.lod.{{.*}} [[CONVERGENT:#[0-9]+]] +declare float @llvm.dx.resource.calculate.lod.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32(target("dx.Texture", <4 x float>, 0, 0, 0, 2), target("dx.Sampler", 0), <2 x float>) + +; CHECK: declare float @llvm.dx.resource.calculate.lod.unclamped.{{.*}} [[CONVERGENT]] +declare float @llvm.dx.resource.calculate.lod.unclamped.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32(target("dx.Texture", <4 x float>, 0, 0, 0, 2), target("dx.Sampler", 0), <2 x float>) + +; CHECK: declare ptr @llvm.dx.resource.getpointer.p0.{{.*}} [[CONVERGENT_NO_MEM:#[0-9]+]] +declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_1_0t.i32(target("dx.RawBuffer", i32, 1, 0), i32) + +; CHECK: declare ptr @llvm.dx.resource.getbasepointer.p0.{{.*}} [[CONVERGENT_NO_MEM]] +declare ptr @llvm.dx.resource.getbasepointer.p0.tdx.RawBuffer_i32_1_0t(target("dx.RawBuffer", i32, 1, 0)) + +; CHECK: declare <4 x float> @llvm.dx.resource.sample.v4f32.{{.*}} [[CONVERGENT]] +declare <4 x float> @llvm.dx.resource.sample.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 2), target("dx.Sampler", 0), <2 x float>, <2 x i32>) + +; CHECK: declare <4 x float> @llvm.dx.resource.sample.clamp.v4f32.{{.*}} [[CONVERGENT]] +declare <4 x float> @llvm.dx.resource.sample.clamp.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 2), target("dx.Sampler", 0), <2 x float>, <2 x i32>, float) + +; CHECK: declare <4 x float> @llvm.dx.resource.samplebias.v4f32.{{.*}} [[CONVERGENT]] +declare <4 x float> @llvm.dx.resource.samplebias.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 2), target("dx.Sampler", 0), <2 x float>, float, <2 x i32>) + +; CHECK: declare <4 x float> @llvm.dx.resource.samplebias.clamp.v4f32.{{.*}} [[CONVERGENT]] +declare <4 x float> @llvm.dx.resource.samplebias.clamp.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 2), target("dx.Sampler", 0), <2 x float>, float, <2 x i32>, float) + +; Explicit-derivative sampling should remain non-convergent. +; CHECK: declare <4 x float> @llvm.dx.resource.samplegrad.v4f32.{{.*}} [[NON_CONVERGENT:#[0-9]+]] +declare <4 x float> @llvm.dx.resource.samplegrad.v4f32.tdx.Texture_v4f32_0_0_0_2t.tdx.Sampler_0t.v2f32.v2f32.v2f32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 2), target("dx.Sampler", 0), <2 x float>, <2 x float>, <2 x float>, <2 x i32>) + +; CHECK: declare float @llvm.spv.resource.calculate.lod.f32.{{.*}} [[CONVERGENT]] +declare float @llvm.spv.resource.calculate.lod.f32.tspirv.Image_f32_1_2_0_0_1_0t.tspirv.Samplert.v2f32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0), target("spirv.Sampler"), <2 x float>) + +; CHECK: declare float @llvm.spv.resource.calculate.lod.unclamped.f32.{{.*}} [[CONVERGENT]] +declare float @llvm.spv.resource.calculate.lod.unclamped.f32.tspirv.Image_f32_1_2_0_0_1_0t.tspirv.Samplert.v2f32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0), target("spirv.Sampler"), <2 x float>) + +; CHECK: declare <4 x float> @llvm.spv.resource.sample.v4f32.{{.*}} [[CONVERGENT]] +declare <4 x float> @llvm.spv.resource.sample.v4f32.tspirv.Image_f32_1_2_0_0_1_0t.tspirv.Samplert.v2f32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0), target("spirv.Sampler"), <2 x float>, <2 x i32>) + +; CHECK: declare <4 x float> @llvm.spv.resource.sample.clamp.v4f32.{{.*}} [[CONVERGENT]] +declare <4 x float> @llvm.spv.resource.sample.clamp.v4f32.tspirv.Image_f32_1_2_0_0_1_0t.tspirv.Samplert.v2f32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0), target("spirv.Sampler"), <2 x float>, <2 x i32>, float) + +; CHECK: declare <4 x float> @llvm.spv.resource.samplebias.v4f32.{{.*}} [[CONVERGENT]] +declare <4 x float> @llvm.spv.resource.samplebias.v4f32.tspirv.Image_f32_1_2_0_0_1_0t.tspirv.Samplert.v2f32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0), target("spirv.Sampler"), <2 x float>, float, <2 x i32>) + +; CHECK: declare <4 x float> @llvm.spv.resource.samplebias.clamp.v4f32.{{.*}} [[CONVERGENT]] +declare <4 x float> @llvm.spv.resource.samplebias.clamp.v4f32.tspirv.Image_f32_1_2_0_0_1_0t.tspirv.Samplert.v2f32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0), target("spirv.Sampler"), <2 x float>, float, <2 x i32>, float) + +; Explicit-derivative sampling should remain non-convergent. +; CHECK: declare <4 x float> @llvm.spv.resource.samplegrad.v4f32.{{.*}} [[NON_CONVERGENT]] +declare <4 x float> @llvm.spv.resource.samplegrad.v4f32.tspirv.Image_f32_1_2_0_0_1_0t.tspirv.Samplert.v3f32.v2f32.v2f32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0), target("spirv.Sampler"), <3 x float>, <2 x float>, <2 x float>, <2 x i32>) + +; CHECK: attributes [[CONVERGENT]] = { convergent nocallback nofree nosync nounwind willreturn memory(read) } +; CHECK: attributes [[CONVERGENT_NO_MEM]] = { convergent nocallback nofree nosync nounwind willreturn memory(none) } +; CHECK: attributes [[NON_CONVERGENT]] = { nocallback nofree nosync nounwind willreturn memory(read) } diff --git a/llvm/test/Assembler/spirv-resource-intrinsic-attributes.ll b/llvm/test/Assembler/spirv-resource-intrinsic-attributes.ll deleted file mode 100644 index 6cb690411d8b0..0000000000000 --- a/llvm/test/Assembler/spirv-resource-intrinsic-attributes.ll +++ /dev/null @@ -1,29 +0,0 @@ -; RUN: llvm-as < %s | llvm-dis | FileCheck %s - -; Verify SPIR-V resource intrinsics that use implicit derivatives are marked -; convergent so LLVM does not sink them into divergent control flow. - -; CHECK: declare float @llvm.spv.resource.calculate.lod.f32.{{.*}} [[CONVERGENT:#[0-9]+]] -declare float @llvm.spv.resource.calculate.lod.f32.tspirv.Image_f32_1_2_0_0_1_0t.tspirv.Samplert.v2f32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0), target("spirv.Sampler"), <2 x float>) - -; CHECK: declare float @llvm.spv.resource.calculate.lod.unclamped.f32.{{.*}} [[CONVERGENT]] -declare float @llvm.spv.resource.calculate.lod.unclamped.f32.tspirv.Image_f32_1_2_0_0_1_0t.tspirv.Samplert.v2f32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0), target("spirv.Sampler"), <2 x float>) - -; CHECK: declare <4 x float> @llvm.spv.resource.sample.v4f32.{{.*}} [[CONVERGENT]] -declare <4 x float> @llvm.spv.resource.sample.v4f32.tspirv.Image_f32_1_2_0_0_1_0t.tspirv.Samplert.v2f32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0), target("spirv.Sampler"), <2 x float>, <2 x i32>) - -; CHECK: declare <4 x float> @llvm.spv.resource.sample.clamp.v4f32.{{.*}} [[CONVERGENT]] -declare <4 x float> @llvm.spv.resource.sample.clamp.v4f32.tspirv.Image_f32_1_2_0_0_1_0t.tspirv.Samplert.v2f32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0), target("spirv.Sampler"), <2 x float>, <2 x i32>, float) - -; CHECK: declare <4 x float> @llvm.spv.resource.samplebias.v4f32.{{.*}} [[CONVERGENT]] -declare <4 x float> @llvm.spv.resource.samplebias.v4f32.tspirv.Image_f32_1_2_0_0_1_0t.tspirv.Samplert.v2f32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0), target("spirv.Sampler"), <2 x float>, float, <2 x i32>) - -; CHECK: declare <4 x float> @llvm.spv.resource.samplebias.clamp.v4f32.{{.*}} [[CONVERGENT]] -declare <4 x float> @llvm.spv.resource.samplebias.clamp.v4f32.tspirv.Image_f32_1_2_0_0_1_0t.tspirv.Samplert.v2f32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0), target("spirv.Sampler"), <2 x float>, float, <2 x i32>, float) - -; Explicit-derivative sampling should remain non-convergent. -; CHECK: declare <4 x float> @llvm.spv.resource.samplegrad.v4f32.{{.*}} [[NON_CONVERGENT:#[0-9]+]] -declare <4 x float> @llvm.spv.resource.samplegrad.v4f32.tspirv.Image_f32_1_2_0_0_1_0t.tspirv.Samplert.v3f32.v2f32.v2f32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0), target("spirv.Sampler"), <3 x float>, <2 x float>, <2 x float>, <2 x i32>) - -; CHECK: attributes [[CONVERGENT]] = { convergent nocallback nofree nosync nounwind willreturn memory(read) } -; CHECK: attributes [[NON_CONVERGENT]] = { nocallback nofree nosync nounwind willreturn memory(read) } >From d876f1dabdea163f371fae87220bb90d409763d5 Mon Sep 17 00:00:00 2001 From: Tim Corringham <[email protected]> Date: Thu, 13 Aug 2026 18:48:12 +0100 Subject: [PATCH 4/8] Address review comment Added a comment describing emitResourceIntrinsic(). --- clang/lib/CodeGen/CGHLSLBuiltins.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp index d6df16d65e550..48766375fe596 100644 --- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp +++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp @@ -533,6 +533,11 @@ static Value *emitHlslClamp(CodeGenFunction &CGF, const CallExpr *E, return Clamp; } +// Emit a convergent, overloaded HLSL resource intrinsic (e.g. Sample, +// CalculateLod). Looks up the declaration from RetTy and argument value types, +// then emits the call via EmitRuntimeCall so convergence control tokens are +// attached on DXIL/SPIR-V logical targets. Use for IntrConvergent resource +// ops; non-convergent resource builtins may use Builder.CreateIntrinsic. static CallInst *emitResourceIntrinsic(CodeGenFunction &CGF, llvm::Type *RetTy, Intrinsic::ID ID, ArrayRef<Value *> Args) { >From 972d98d5571fa4af02798ca1290ae6a6972989fe Mon Sep 17 00:00:00 2001 From: Tim Corringham <[email protected]> Date: Mon, 17 Aug 2026 11:29:45 +0100 Subject: [PATCH 5/8] [HLSL] Add EmitIntrinsicCall overload for resource intrinsics Replace the local emitResourceIntrinsic helper with a CodeGenFunction overload that looks up overloaded intrinsics from RetTy and argument types. Co-authored-by: Cursor --- clang/lib/CodeGen/CGCall.cpp | 17 +++++++++++ clang/lib/CodeGen/CGHLSLBuiltins.cpp | 45 ++++++++-------------------- clang/lib/CodeGen/CodeGenFunction.h | 3 ++ 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index a29f7aab0e58b..3b1e074f41ec7 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -5437,6 +5437,23 @@ llvm::CallInst *CodeGenFunction::EmitIntrinsicCall(llvm::Intrinsic::ID ID, return Call; } +llvm::CallInst *CodeGenFunction::EmitIntrinsicCall(llvm::Intrinsic::ID ID, + llvm::Type *RetTy, + ArrayRef<llvm::Value *> Args, + const llvm::Twine &Name) { + SmallVector<llvm::Type *> ArgTys; + ArgTys.reserve(Args.size()); + for (llvm::Value *Arg : Args) + ArgTys.push_back(Arg->getType()); + llvm::Function *F = llvm::Intrinsic::getOrInsertDeclaration( + &CGM.getModule(), ID, RetTy, ArgTys); + llvm::CallInst *Call = + Builder.CreateCall(F, Args, getBundlesForFunclet(F), Name); + if (CGM.shouldEmitConvergenceTokens() && Call->isConvergent()) + return cast<llvm::CallInst>(addConvergenceControlToken(Call)); + return Call; +} + /// Emits a call or invoke to the given noreturn runtime function. void CodeGenFunction::EmitNoreturnRuntimeCallOrInvoke( llvm::FunctionCallee callee, ArrayRef<llvm::Value *> args) { diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp index 48766375fe596..5c33470a4b2ff 100644 --- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp +++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp @@ -533,23 +533,6 @@ static Value *emitHlslClamp(CodeGenFunction &CGF, const CallExpr *E, return Clamp; } -// Emit a convergent, overloaded HLSL resource intrinsic (e.g. Sample, -// CalculateLod). Looks up the declaration from RetTy and argument value types, -// then emits the call via EmitRuntimeCall so convergence control tokens are -// attached on DXIL/SPIR-V logical targets. Use for IntrConvergent resource -// ops; non-convergent resource builtins may use Builder.CreateIntrinsic. -static CallInst *emitResourceIntrinsic(CodeGenFunction &CGF, llvm::Type *RetTy, - Intrinsic::ID ID, - ArrayRef<Value *> Args) { - SmallVector<llvm::Type *> ArgTys; - ArgTys.reserve(Args.size()); - for (Value *Arg : Args) - ArgTys.push_back(Arg->getType()); - Function *IntrFn = Intrinsic::getOrInsertDeclaration(&CGF.CGM.getModule(), ID, - RetTy, ArgTys); - return CGF.EmitRuntimeCall(IntrFn, Args); -} - static Value *emitGetDimensions(CodeGenFunction &CGF, const CallExpr *E, unsigned IntrinsicID, unsigned NumRetComps, bool HasLod) { @@ -684,13 +667,13 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, llvm::Type *RetTy = ConvertType(E->getType()); if (E->getNumArgs() <= 4) { - return emitResourceIntrinsic( - *this, RetTy, CGM.getHLSLRuntime().getSampleIntrinsic(), Args); + return EmitIntrinsicCall(CGM.getHLSLRuntime().getSampleIntrinsic(), RetTy, + Args); } Args.push_back(emitHlslClamp(*this, E, 4)); - return emitResourceIntrinsic( - *this, RetTy, CGM.getHLSLRuntime().getSampleClampIntrinsic(), Args); + return EmitIntrinsicCall(CGM.getHLSLRuntime().getSampleClampIntrinsic(), + RetTy, Args); } case Builtin::BI__builtin_hlsl_resource_sample_bias: { Value *HandleOp = EmitScalarExpr(E->getArg(0)); @@ -710,13 +693,13 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, llvm::Type *RetTy = ConvertType(E->getType()); if (E->getNumArgs() <= 5) { - return emitResourceIntrinsic( - *this, RetTy, CGM.getHLSLRuntime().getSampleBiasIntrinsic(), Args); + return EmitIntrinsicCall(CGM.getHLSLRuntime().getSampleBiasIntrinsic(), + RetTy, Args); } Args.push_back(emitHlslClamp(*this, E, 5)); - return emitResourceIntrinsic( - *this, RetTy, CGM.getHLSLRuntime().getSampleBiasClampIntrinsic(), Args); + return EmitIntrinsicCall( + CGM.getHLSLRuntime().getSampleBiasClampIntrinsic(), RetTy, Args); } case Builtin::BI__builtin_hlsl_resource_sample_grad: { Value *HandleOp = EmitScalarExpr(E->getArg(0)); @@ -845,20 +828,18 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *SamplerOp = EmitScalarExpr(E->getArg(1)); Value *CoordOp = EmitScalarExpr(E->getArg(2)); - return emitResourceIntrinsic( - *this, ConvertType(E->getType()), - CGM.getHLSLRuntime().getCalculateLodIntrinsic(), - {HandleOp, SamplerOp, CoordOp}); + return EmitIntrinsicCall(CGM.getHLSLRuntime().getCalculateLodIntrinsic(), + ConvertType(E->getType()), + {HandleOp, SamplerOp, CoordOp}); } case Builtin::BI__builtin_hlsl_resource_calculate_lod_unclamped: { Value *HandleOp = EmitScalarExpr(E->getArg(0)); Value *SamplerOp = EmitScalarExpr(E->getArg(1)); Value *CoordOp = EmitScalarExpr(E->getArg(2)); - return emitResourceIntrinsic( - *this, ConvertType(E->getType()), + return EmitIntrinsicCall( CGM.getHLSLRuntime().getCalculateLodUnclampedIntrinsic(), - {HandleOp, SamplerOp, CoordOp}); + ConvertType(E->getType()), {HandleOp, SamplerOp, CoordOp}); } case Builtin::BI__builtin_hlsl_resource_gather: { Value *HandleOp = EmitScalarExpr(E->getArg(0)); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 3fc9052adb87b..7f2f600d95fc9 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -4632,6 +4632,9 @@ class CodeGenFunction : public CodeGenTypeCache { ArrayRef<llvm::Type *> Types, ArrayRef<llvm::Value *> Args, const Twine &Name = ""); + llvm::CallInst *EmitIntrinsicCall(llvm::Intrinsic::ID ID, llvm::Type *RetTy, + ArrayRef<llvm::Value *> Args, + const Twine &Name = ""); llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name = ""); llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee, >From de1254da15265f60f429e640814b6f242783cedf Mon Sep 17 00:00:00 2001 From: Tim Corringham <[email protected]> Date: Mon, 17 Aug 2026 11:46:29 +0100 Subject: [PATCH 6/8] [HLSL] Check calling convention on resource intrinsic codegen tests Replace wildcarded call prefixes with explicit fast-math attributes so resource intrinsic calls are verified to use the default calling convention. Co-authored-by: Cursor --- .../Textures-CalculateLevelOfDetail.hlsl | 8 ++--- .../resources/Textures-Gather.hlsl | 28 ++++++++-------- .../CodeGenHLSL/resources/Textures-Load.hlsl | 32 +++++++++---------- .../resources/Textures-Sample.hlsl | 12 +++---- .../resources/Textures-SampleBias.hlsl | 12 +++---- .../resources/Textures-SampleCmp.hlsl | 12 +++---- .../Textures-SampleCmpLevelZero.hlsl | 8 ++--- .../resources/Textures-SampleGrad.hlsl | 12 +++---- .../resources/Textures-SampleLevel.hlsl | 8 ++--- 9 files changed, 66 insertions(+), 66 deletions(-) diff --git a/clang/test/CodeGenHLSL/resources/Textures-CalculateLevelOfDetail.hlsl b/clang/test/CodeGenHLSL/resources/Textures-CalculateLevelOfDetail.hlsl index d2ceb0a06727a..ee1a9d8d00873 100644 --- a/clang/test/CodeGenHLSL/resources/Textures-CalculateLevelOfDetail.hlsl +++ b/clang/test/CodeGenHLSL/resources/Textures-CalculateLevelOfDetail.hlsl @@ -21,8 +21,8 @@ float test_lod(float2 loc : LOC) : SV_Target { // CHECK: %[[SAMPLER_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0 // CHECK: %[[SAMPLER_H:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP]] // CHECK: %[[COORD_VAL:.*]] = load <2 x float>, ptr %[[COORD]] -// DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.resource.calculate.lod.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE]], target("dx.Sampler", 0) %[[SAMPLER_H]], <2 x float> %[[COORD_VAL]]) -// SPIRV: %[[RES:.*]] = call {{.*}} float @llvm.spv.resource.calculate.lod.f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <2 x float> %[[COORD_VAL]]) +// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.dx.resource.calculate.lod.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE]], target("dx.Sampler", 0) %[[SAMPLER_H]], <2 x float> %[[COORD_VAL]]) +// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.spv.resource.calculate.lod.f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <2 x float> %[[COORD_VAL]]) // CHECK: ret float %[[RES]] // CHECK: define hidden {{.*}} float @test_lod_unclamped(float vector[2])(<2 x float> noundef nofpclass(nan inf) %[[LOC:.*]]) @@ -41,6 +41,6 @@ float test_lod_unclamped(float2 loc : LOC) : SV_Target { // CHECK: %[[SAMPLER_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0 // CHECK: %[[SAMPLER_H:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP]] // CHECK: %[[COORD_VAL:.*]] = load <2 x float>, ptr %[[COORD]] -// DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.resource.calculate.lod.unclamped.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE]], target("dx.Sampler", 0) %[[SAMPLER_H]], <2 x float> %[[COORD_VAL]]) -// SPIRV: %[[RES:.*]] = call {{.*}} float @llvm.spv.resource.calculate.lod.unclamped.f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <2 x float> %[[COORD_VAL]]) +// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.dx.resource.calculate.lod.unclamped.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE]], target("dx.Sampler", 0) %[[SAMPLER_H]], <2 x float> %[[COORD_VAL]]) +// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.spv.resource.calculate.lod.unclamped.f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <2 x float> %[[COORD_VAL]]) // CHECK: ret float %[[RES]] diff --git a/clang/test/CodeGenHLSL/resources/Textures-Gather.hlsl b/clang/test/CodeGenHLSL/resources/Textures-Gather.hlsl index b57d8642f860b..8859a59bd20d6 100644 --- a/clang/test/CodeGenHLSL/resources/Textures-Gather.hlsl +++ b/clang/test/CodeGenHLSL/resources/Textures-Gather.hlsl @@ -34,8 +34,8 @@ float4 main(COORD_TYPE loc : LOC) : SV_Target { // CHECK: %[[SAMPLER_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0 // CHECK: %[[SAMPLER_H:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP]] // CHECK: %[[COORD_VAL:.*]] = load <[[COORD_DIM]] x float>, ptr %[[COORD_ADDR]] -// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.gather.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]], i32 0, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.gather.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], i32 0, <2 x i32> zeroinitializer) +// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.gather.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]], i32 0, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.gather.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], i32 0, <2 x i32> zeroinitializer) // CHECK: ret <4 x float> %[[RES]] // CHECK: define hidden {{.*}} <4 x float> @test_offset(float vector[[[COORD_DIM]]])(<[[COORD_DIM]] x float> noundef nofpclass(nan inf) %[[LOC:.*]]) @@ -60,8 +60,8 @@ float4 test_offset(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: %[[OFFSET_VAL:.*]] = load <2 x i32>, ptr %[[OFFSET_ADDR]] -// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.gather.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]], i32 0, <2 x i32> %[[OFFSET_VAL]]) -// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.gather.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], i32 0, <2 x i32> %[[OFFSET_VAL]]) +// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.gather.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]], i32 0, <2 x i32> %[[OFFSET_VAL]]) +// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.gather.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], i32 0, <2 x i32> %[[OFFSET_VAL]]) // CHECK: ret <4 x float> %[[RES]] // CHECK: define hidden {{.*}} <4 x float> @test_green(float vector[[[COORD_DIM]]])(<[[COORD_DIM]] x float> noundef nofpclass(nan inf) %[[LOC:.*]]) @@ -83,8 +83,8 @@ float4 test_green(COORD_TYPE loc : LOC) : SV_Target { // CHECK: %[[SAMPLER_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0 // CHECK: %[[SAMPLER_H:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP]] // CHECK: %[[COORD_VAL:.*]] = load <[[COORD_DIM]] x float>, ptr %[[COORD_ADDR]] -// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.gather.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]], i32 1, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.gather.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], i32 1, <2 x i32> zeroinitializer) +// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.gather.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]], i32 1, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.gather.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], i32 1, <2 x i32> zeroinitializer) // CHECK: ret <4 x float> %[[RES]] // CHECK: define hidden {{.*}} <4 x float> @test_red(float vector[[[COORD_DIM]]])(<[[COORD_DIM]] x float> noundef nofpclass(nan inf) %[[LOC:.*]]) @@ -106,8 +106,8 @@ float4 test_red(COORD_TYPE loc : LOC) : SV_Target { // CHECK: %[[SAMPLER_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0 // CHECK: %[[SAMPLER_H:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP]] // CHECK: %[[COORD_VAL:.*]] = load <[[COORD_DIM]] x float>, ptr %[[COORD_ADDR]] -// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.gather.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]], i32 0, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.gather.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], i32 0, <2 x i32> zeroinitializer) +// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.gather.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]], i32 0, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.gather.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], i32 0, <2 x i32> zeroinitializer) // CHECK: ret <4 x float> %[[RES]] // CHECK: define hidden {{.*}} <4 x float> @test_blue(float vector[[[COORD_DIM]]])(<[[COORD_DIM]] x float> noundef nofpclass(nan inf) %[[LOC:.*]]) @@ -129,8 +129,8 @@ float4 test_blue(COORD_TYPE loc : LOC) : SV_Target { // CHECK: %[[SAMPLER_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0 // CHECK: %[[SAMPLER_H:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP]] // CHECK: %[[COORD_VAL:.*]] = load <[[COORD_DIM]] x float>, ptr %[[COORD_ADDR]] -// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.gather.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]], i32 2, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.gather.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], i32 2, <2 x i32> zeroinitializer) +// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.gather.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]], i32 2, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.gather.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], i32 2, <2 x i32> zeroinitializer) // CHECK: ret <4 x float> %[[RES]] // CHECK: define hidden {{.*}} <4 x float> @test_alpha(float vector[[[COORD_DIM]]])(<[[COORD_DIM]] x float> noundef nofpclass(nan inf) %[[LOC:.*]]) @@ -152,8 +152,8 @@ float4 test_alpha(COORD_TYPE loc : LOC) : SV_Target { // CHECK: %[[SAMPLER_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0 // CHECK: %[[SAMPLER_H:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP]] // CHECK: %[[COORD_VAL:.*]] = load <[[COORD_DIM]] x float>, ptr %[[COORD_ADDR]] -// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.gather.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]], i32 3, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.gather.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], i32 3, <2 x i32> zeroinitializer) +// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.gather.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]], i32 3, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.gather.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], i32 3, <2 x i32> zeroinitializer) // CHECK: ret <4 x float> %[[RES]] // CHECK: define hidden {{.*}} <4 x float> @test_cmp(float vector[[[COORD_DIM]]])(<[[COORD_DIM]] x float> noundef nofpclass(nan inf) %[[LOC:.*]]) @@ -180,6 +180,6 @@ float4 test_cmp(COORD_TYPE loc : LOC) : SV_Target { // 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 {{.*}} <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, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.gather.cmp.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], float %[[TRUNC]], <2 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 %[[TRUNC]], i32 0, <2 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, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], float %[[TRUNC]], <2 x i32> zeroinitializer) // CHECK: ret <4 x float> %[[RES]] diff --git a/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl b/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl index a9b28f80eeead..96e0757950c43 100644 --- a/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl +++ b/clang/test/CodeGenHLSL/resources/Textures-Load.hlsl @@ -36,8 +36,8 @@ float4 test_load(int2 loc : LOC) : SV_Target { // CHECK: %[[LOCATION_VAL:.*]] = load <[[LOCATION_DIM]] x i32>, ptr %[[LOCATION_ADDR]] // CHECK: %[[COORD:.*]] = shufflevector <[[LOCATION_DIM]] x i32> %[[LOCATION_VAL]], <[[LOCATION_DIM]] x i32> poison, <[[COORD_DIM]] x i32> [[COORD_MASK]] // CHECK: %[[LOD:.*]] = extractelement <[[LOCATION_DIM]] x i32> %[[LOCATION_VAL]], i64 [[COORD_DIM]] -// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE]], <[[COORD_DIM]] x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT1]]) %[[HANDLE]], <[[COORD_DIM]] x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> zeroinitializer) +// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE]], <[[COORD_DIM]] x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT1]]) %[[HANDLE]], <[[COORD_DIM]] x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> zeroinitializer) // CHECK: ret <4 x float> %[[RES]] // CHECK: define hidden {{.*}} <4 x float> @test_load_offset(int vector[2]) @@ -63,8 +63,8 @@ float4 test_load_offset(int2 loc : LOC) : SV_Target { // CHECK: %[[COORD:.*]] = shufflevector <[[LOCATION_DIM]] x i32> %[[LOCATION_VAL]], <[[LOCATION_DIM]] x i32> poison, <[[COORD_DIM]] x i32> [[COORD_MASK]] // CHECK: %[[LOD:.*]] = extractelement <[[LOCATION_DIM]] x i32> %[[LOCATION_VAL]], i64 [[COORD_DIM]] // CHECK: %[[OFFSET_VAL:.*]] = load <2 x i32>, ptr %[[OFFSET_ADDR]] -// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_{{.*}}("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE]], <[[COORD_DIM]] x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> %[[OFFSET_VAL]]) -// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT1]]) %[[HANDLE]], <[[COORD_DIM]] x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> %[[OFFSET_VAL]]) +// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_{{.*}}("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE]], <[[COORD_DIM]] x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> %[[OFFSET_VAL]]) +// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT1]]) %[[HANDLE]], <[[COORD_DIM]] x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> %[[OFFSET_VAL]]) // CHECK: ret <4 x float> %[[RES]] @@ -75,8 +75,8 @@ TEXTURE<float> t_float; // CHECK: define hidden {{.*}} float @test_load_float(int vector[2]) // CHECK: define linkonce_odr hidden {{.*}} float @hlsl::[[TEXTURE]]<float>::Load(int vector[[[LOCATION_DIM]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCATION_DIM]] x i32> {{.*}} %[[LOCATION:.*]]) -// DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.resource.load.level.f32.tdx.Texture_f32_{{.*}}("dx.Texture", float, [[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call {{.*}} float @llvm.spv.resource.load.level.f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT3]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.dx.resource.load.level.f32.tdx.Texture_f32_{{.*}}("dx.Texture", float, [[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.spv.resource.load.level.f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT3]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) // CHECK: ret float %[[RES]] float test_load_float(int2 loc : LOC) { return t_float.Load(LOCATION_TYPE(loc, ZEROS)); @@ -90,8 +90,8 @@ float test_load_offset_float(int2 loc : LOC) { } // CHECK: define linkonce_odr hidden {{.*}} float @hlsl::[[TEXTURE]]<float>::Load(int vector[[[LOCATION_DIM]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCATION_DIM]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) -// DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.resource.load.level.f32.tdx.Texture_f32_{{.*}}("dx.Texture", float, [[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) -// SPIRV: %[[RES:.*]] = call {{.*}} float @llvm.spv.resource.load.level.f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT3]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.dx.resource.load.level.f32.tdx.Texture_f32_{{.*}}("dx.Texture", float, [[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.spv.resource.load.level.f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT3]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) // CHECK: ret float %[[RES]] TEXTURE<float2> t_float2; @@ -104,8 +104,8 @@ float2 test_load_float2(int2 loc : LOC) { } // CHECK: define linkonce_odr hidden {{.*}} <2 x float> @hlsl::[[TEXTURE]]<float vector[2]>::Load(int vector[[[LOCATION_DIM]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCATION_DIM]] x i32> {{.*}} %[[LOCATION:.*]]) -// DXIL: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.dx.resource.load.level.v2f32.tdx.Texture_v2f32_{{.*}}("dx.Texture", <2 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT6]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.dx.resource.load.level.v2f32.tdx.Texture_v2f32_{{.*}}("dx.Texture", <2 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT6]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) // CHECK: ret <2 x float> %[[RES]] // CHECK: define hidden {{.*}} <2 x float> @test_load_offset_float2(int vector[2]) @@ -116,8 +116,8 @@ float2 test_load_offset_float2(int2 loc : LOC) { } // CHECK: define linkonce_odr hidden {{.*}} <2 x float> @hlsl::[[TEXTURE]]<float vector[2]>::Load(int vector[[[LOCATION_DIM]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCATION_DIM]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) -// DXIL: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.dx.resource.load.level.v2f32.tdx.Texture_v2f32_{{.*}}("dx.Texture", <2 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) -// SPIRV: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT6]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.dx.resource.load.level.v2f32.tdx.Texture_v2f32_{{.*}}("dx.Texture", <2 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT6]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) // CHECK: ret <2 x float> %[[RES]] TEXTURE<float3> t_float3; @@ -130,8 +130,8 @@ float3 test_load_float3(int2 loc : LOC) { } // CHECK: define linkonce_odr hidden {{.*}} <3 x float> @hlsl::[[TEXTURE]]<float vector[3]>::Load(int vector[[[LOCATION_DIM]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCATION_DIM]] x i32> {{.*}} %[[LOCATION:.*]]) -// DXIL: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.dx.resource.load.level.v3f32.tdx.Texture_v3f32_{{.*}}("dx.Texture", <3 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], 0) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.dx.resource.load.level.v3f32.tdx.Texture_v3f32_{{.*}}("dx.Texture", <3 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], 0) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) // CHECK: ret <3 x float> %[[RES]] // CHECK: define hidden {{.*}} <3 x float> @test_load_offset_float3(int vector[2]) @@ -142,8 +142,8 @@ float3 test_load_offset_float3(int2 loc : LOC) { } // CHECK: define linkonce_odr hidden {{.*}} <3 x float> @hlsl::[[TEXTURE]]<float vector[3]>::Load(int vector[[[LOCATION_DIM]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCATION_DIM]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) -// DXIL: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.dx.resource.load.level.v3f32.tdx.Texture_v3f32_{{.*}}("dx.Texture", <3 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) -// SPIRV: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], 0) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.dx.resource.load.level.v3f32.tdx.Texture_v3f32_{{.*}}("dx.Texture", <3 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], 0) %{{.*}}, <[[COORD_DIM]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) // CHECK: ret <3 x float> %[[RES]] TEXTURE<int> t_int; diff --git a/clang/test/CodeGenHLSL/resources/Textures-Sample.hlsl b/clang/test/CodeGenHLSL/resources/Textures-Sample.hlsl index 7c76091ea254c..82dd463d85f15 100644 --- a/clang/test/CodeGenHLSL/resources/Textures-Sample.hlsl +++ b/clang/test/CodeGenHLSL/resources/Textures-Sample.hlsl @@ -31,8 +31,8 @@ float4 main(COORD_TYPE loc : LOC) : SV_Target { // CHECK: %[[SAMPLER_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %[[SAMPLER]], i32 0, i32 0 // CHECK: %[[SAMPLER_H:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP]] // CHECK: %[[COORD_VAL:.*]] = load <[[COORD_DIM]] x float>, ptr %[[COORD_ADDR]] -// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.sample.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]], <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.sample.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <2 x i32> zeroinitializer) +// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.sample.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]], <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.sample.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <2 x i32> zeroinitializer) // CHECK: ret <4 x float> %[[RES]] // CHECK: define hidden {{.*}} <4 x float> @test_offset(float vector[[[COORD_DIM]]])(<[[COORD_DIM]] x float> noundef nofpclass(nan inf) %[[LOC:.*]]) @@ -57,8 +57,8 @@ float4 test_offset(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: %[[OFFSET_VAL:.*]] = load <2 x i32>, ptr %[[OFFSET_ADDR]] -// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.sample.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]], <2 x i32> %[[OFFSET_VAL]]) -// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.sample.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <2 x i32> %[[OFFSET_VAL]]) +// DXIL: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.sample.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]], <2 x i32> %[[OFFSET_VAL]]) +// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.sample.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <2 x i32> %[[OFFSET_VAL]]) // CHECK: ret <4 x float> %[[RES]] // CHECK: define hidden {{.*}} <4 x float> @test_clamp(float vector[[[COORD_DIM]]])(<[[COORD_DIM]] x float> noundef nofpclass(nan inf) %[[LOC:.*]]) @@ -87,6 +87,6 @@ float4 test_clamp(COORD_TYPE loc : LOC) : SV_Target { // CHECK: %[[OFFSET_VAL:.*]] = load <2 x i32>, ptr %[[OFFSET_ADDR]] // CHECK: %[[CLAMP_VAL:.*]] = load float, ptr %[[CLAMP_ADDR]] // CHECK: %[[CLAMP_CAST:.*]] = fptrunc {{.*}} double {{.*}} to float -// DXIL: %[[RES:.*]] = call {{.*}} <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]], <2 x i32> %[[OFFSET_VAL]], float %[[CLAMP_CAST]]) -// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.sample.clamp.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <2 x i32> %[[OFFSET_VAL]], float %[[CLAMP_CAST]]) +// DXIL: %[[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]], <2 x i32> %[[OFFSET_VAL]], float %[[CLAMP_CAST]]) +// SPIRV: %[[RES:.*]] = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.sample.clamp.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE]], target("spirv.Sampler") %[[SAMPLER_H]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <2 x i32> %[[OFFSET_VAL]], float %[[CLAMP_CAST]]) // CHECK: ret <4 x float> %[[RES]] diff --git a/clang/test/CodeGenHLSL/resources/Textures-SampleBias.hlsl b/clang/test/CodeGenHLSL/resources/Textures-SampleBias.hlsl index c92bb7ee74c8c..264f58ab53646 100644 --- a/clang/test/CodeGenHLSL/resources/Textures-SampleBias.hlsl +++ b/clang/test/CodeGenHLSL/resources/Textures-SampleBias.hlsl @@ -27,8 +27,8 @@ float4 test_bias(COORD_TYPE loc : LOC) : SV_Target { // 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 {{.*}} <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]], <2 x i32> zeroinitializer) -// SPIRV: %{{.*}} = call {{.*}} <4 x float> @llvm.spv.resource.samplebias.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %{{.*}}, float %[[BIAS_CAST1]], <2 x i32> zeroinitializer) +// 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]], <2 x i32> zeroinitializer) +// SPIRV: %{{.*}} = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplebias.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %{{.*}}, float %[[BIAS_CAST1]], <2 x i32> zeroinitializer) // CHECK: @test_offset(float vector[[[COORD_DIM]]]) // CHECK: %[[CALL_OFFSET:.*]] = call {{.*}} <4 x float> @hlsl::[[TEXTURE]]<float vector[4]>::SampleBias(hlsl::SamplerState, float vector[[[COORD_DIM]]], float, int vector[2])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <[[COORD_DIM]] x float> {{.*}} %{{.*}}, float {{.*}} 0.000000e+00, <2 x i32> noundef <i32 1, i32 2>) @@ -45,8 +45,8 @@ float4 test_offset(COORD_TYPE loc : LOC) : SV_Target { // CHECK: %[[SAMPLER_GEP2:.*]] = getelementptr inbounds nuw %"class.hlsl::SamplerState", ptr %{{.*}}, i32 0, i32 0 // CHECK: %[[SAMPLER_H2:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP2]] // CHECK: %[[BIAS_CAST2:.*]] = fptrunc {{.*}} double {{.*}} to float -// DXIL: %{{.*}} = call {{.*}} <4 x float> @llvm.dx.resource.samplebias.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) -// SPIRV: %{{.*}} = call {{.*}} <4 x float> @llvm.spv.resource.samplebias.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) +// 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]]) +// SPIRV: %{{.*}} = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplebias.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) // CHECK: @test_clamp(float vector[[[COORD_DIM]]]) // CHECK: %[[CALL_CLAMP:.*]] = call {{.*}} <4 x float> @hlsl::[[TEXTURE]]<float vector[4]>::SampleBias(hlsl::SamplerState, float vector[[[COORD_DIM]]], float, int vector[2], float)(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <[[COORD_DIM]] x float> {{.*}} %{{.*}}, float {{.*}} 0.000000e+00, <2 x i32> noundef <i32 1, i32 2>, float {{.*}} 1.000000e+00) @@ -64,5 +64,5 @@ float4 test_clamp(COORD_TYPE loc : LOC) : SV_Target { // CHECK: %[[SAMPLER_H3:.*]] = load target{{.*}}, ptr %[[SAMPLER_GEP3]] // CHECK: %[[BIAS_CAST3:.*]] = fptrunc {{.*}} double {{.*}} to float // CHECK: %[[CLAMP_CAST3:.*]] = fptrunc {{.*}} double {{.*}} to float -// DXIL: %{{.*}} = call {{.*}} <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]], <2 x i32> %{{.*}}, float %[[CLAMP_CAST3]]) -// SPIRV: %{{.*}} = call {{.*}} <4 x float> @llvm.spv.resource.samplebias.clamp.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE3]], target("spirv.Sampler") %[[SAMPLER_H3]], <[[COORD_DIM]] x float> %{{.*}}, float %[[BIAS_CAST3]], <2 x i32> %{{.*}}, float %[[CLAMP_CAST3]]) +// DXIL: %{{.*}} = 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]], <2 x i32> %{{.*}}, float %[[CLAMP_CAST3]]) +// SPIRV: %{{.*}} = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplebias.clamp.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE3]], target("spirv.Sampler") %[[SAMPLER_H3]], <[[COORD_DIM]] x float> %{{.*}}, float %[[BIAS_CAST3]], <2 x i32> %{{.*}}, float %[[CLAMP_CAST3]]) diff --git a/clang/test/CodeGenHLSL/resources/Textures-SampleCmp.hlsl b/clang/test/CodeGenHLSL/resources/Textures-SampleCmp.hlsl index b2b4f2ff69d47..f7003a22c4ec0 100644 --- a/clang/test/CodeGenHLSL/resources/Textures-SampleCmp.hlsl +++ b/clang/test/CodeGenHLSL/resources/Textures-SampleCmp.hlsl @@ -30,8 +30,8 @@ float test_cmp(COORD_TYPE loc : LOC, float cmp : CMP) : SV_Target { // CHECK: %[[COORD_VAL1:.*]] = load <[[COORD_DIM]] x float>, ptr %{{.*}} // CHECK: %[[CMP_VAL1:.*]] = load float, ptr %{{.*}} // CHECK: %[[CMP_CAST1:.*]] = fptrunc {{.*}} double {{.*}} to float -// DXIL: call {{.*}} 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]], <2 x i32> zeroinitializer) -// SPIRV: call {{.*}} float @llvm.spv.resource.samplecmp.f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL1]], float %[[CMP_CAST1]], <2 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_CAST1]], <2 x i32> zeroinitializer) +// SPIRV: call reassoc nnan ninf nsz arcp afn float @llvm.spv.resource.samplecmp.f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL1]], float %[[CMP_CAST1]], <2 x i32> zeroinitializer) // CHECK: @test_offset(float vector[[[COORD_DIM]]], float) // CHECK: %[[CALL_OFFSET:.*]] = call {{.*}} float @hlsl::[[TEXTURE]]<float vector[4]>::SampleCmp(hlsl::SamplerComparisonState, float vector[[[COORD_DIM]]], float, int vector[2])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerComparisonState") {{.*}}, <[[COORD_DIM]] x float> {{.*}} %{{.*}}, float {{.*}} 0.000000e+00, <2 x i32> noundef <i32 1, i32 2>) @@ -52,8 +52,8 @@ float test_offset(COORD_TYPE loc : LOC, float cmp : CMP) : SV_Target { // CHECK: %[[CMP_VAL2:.*]] = load float, ptr %{{.*}} // CHECK: %[[CMP_CAST2:.*]] = fptrunc {{.*}} double {{.*}} to float // CHECK: %[[OFFSET_VAL2:.*]] = load <2 x i32>, ptr %{{.*}} -// DXIL: call {{.*}} 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]], <2 x i32> %[[OFFSET_VAL2]]) -// SPIRV: call {{.*}} float @llvm.spv.resource.samplecmp.f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE2]], target("spirv.Sampler") %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL2]], float %[[CMP_CAST2]], <2 x i32> %[[OFFSET_VAL2]]) +// 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]]) %[[HANDLE2]], target("dx.Sampler", 0) %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL2]], float %[[CMP_CAST2]], <2 x i32> %[[OFFSET_VAL2]]) +// SPIRV: call reassoc nnan ninf nsz arcp afn float @llvm.spv.resource.samplecmp.f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE2]], target("spirv.Sampler") %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL2]], float %[[CMP_CAST2]], <2 x i32> %[[OFFSET_VAL2]]) // CHECK: @test_clamp(float vector[[[COORD_DIM]]], float) // CHECK: %[[CALL_CLAMP:.*]] = call {{.*}} float @hlsl::[[TEXTURE]]<float vector[4]>::SampleCmp(hlsl::SamplerComparisonState, float vector[[[COORD_DIM]]], float, int vector[2], float)(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerComparisonState") {{.*}}, <[[COORD_DIM]] x float> {{.*}} %{{.*}}, float {{.*}} 0.000000e+00, <2 x i32> noundef <i32 1, i32 2>, float {{.*}} 1.000000e+00) @@ -76,5 +76,5 @@ float test_clamp(COORD_TYPE loc : LOC, float cmp : CMP) : SV_Target { // CHECK: %[[OFFSET_VAL3:.*]] = load <2 x i32>, ptr %{{.*}} // CHECK: %[[CLAMP_VAL3:.*]] = load float, ptr %{{.*}} // CHECK: %[[CLAMP_CAST3:.*]] = fptrunc {{.*}} double {{.*}} to float -// DXIL: call {{.*}} 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]], <2 x i32> %[[OFFSET_VAL3]], float %[[CLAMP_CAST3]]) -// SPIRV: call {{.*}} float @llvm.spv.resource.samplecmp.clamp.f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE3]], target("spirv.Sampler") %[[SAMPLER_H3]], <[[COORD_DIM]] x float> %[[COORD_VAL3]], float %[[CMP_CAST3]], <2 x i32> %[[OFFSET_VAL3]], float %[[CLAMP_CAST3]]) +// DXIL: 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]], <2 x i32> %[[OFFSET_VAL3]], float %[[CLAMP_CAST3]]) +// SPIRV: call reassoc nnan ninf nsz arcp afn float @llvm.spv.resource.samplecmp.clamp.f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE3]], target("spirv.Sampler") %[[SAMPLER_H3]], <[[COORD_DIM]] x float> %[[COORD_VAL3]], float %[[CMP_CAST3]], <2 x i32> %[[OFFSET_VAL3]], float %[[CLAMP_CAST3]]) diff --git a/clang/test/CodeGenHLSL/resources/Textures-SampleCmpLevelZero.hlsl b/clang/test/CodeGenHLSL/resources/Textures-SampleCmpLevelZero.hlsl index b80e850ab4843..0bb34720a82e9 100644 --- a/clang/test/CodeGenHLSL/resources/Textures-SampleCmpLevelZero.hlsl +++ b/clang/test/CodeGenHLSL/resources/Textures-SampleCmpLevelZero.hlsl @@ -24,8 +24,8 @@ float test_cmp_level_zero(COORD_TYPE loc : LOC, float cmp : CMP) : SV_Target { // CHECK: %[[COORD_VAL1:.*]] = load <[[COORD_DIM]] x float>, ptr %{{.*}} // CHECK: %[[CMP_VAL1:.*]] = load float, ptr %{{.*}} // CHECK: %[[CMP_CAST1:.*]] = fptrunc {{.*}} double {{.*}} to float -// DXIL: call {{.*}} 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]], <2 x i32> zeroinitializer) -// SPIRV: call {{.*}} float @llvm.spv.resource.samplecmplevelzero.f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL1]], float %[[CMP_CAST1]], <2 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_CAST1]], <2 x i32> zeroinitializer) +// SPIRV: call reassoc nnan ninf nsz arcp afn float @llvm.spv.resource.samplecmplevelzero.f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL1]], float %[[CMP_CAST1]], <2 x i32> zeroinitializer) // CHECK: @test_cmp_level_zero_offset(float vector[[[COORD_DIM]]], float) // CHECK: %[[CALL_OFFSET:.*]] = call {{.*}} float @hlsl::[[TEXTURE]]<float vector[4]>::SampleCmpLevelZero(hlsl::SamplerComparisonState, float vector[[[COORD_DIM]]], float, int vector[2])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerComparisonState") {{.*}}, <[[COORD_DIM]] x float> {{.*}} %{{.*}}, float {{.*}} 0.000000e+00, <2 x i32> noundef <i32 1, i32 2>) @@ -46,5 +46,5 @@ float test_cmp_level_zero_offset(COORD_TYPE loc : LOC, float cmp : CMP) : SV_Tar // CHECK: %[[CMP_VAL2:.*]] = load float, ptr %{{.*}} // CHECK: %[[CMP_CAST2:.*]] = fptrunc {{.*}} double {{.*}} to float // CHECK: %[[OFFSET_VAL2:.*]] = load <2 x i32>, ptr %{{.*}} -// DXIL: call {{.*}} 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]], <2 x i32> %[[OFFSET_VAL2]]) -// SPIRV: call {{.*}} float @llvm.spv.resource.samplecmplevelzero.f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE2]], target("spirv.Sampler") %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL2]], float %[[CMP_CAST2]], <2 x i32> %[[OFFSET_VAL2]]) +// 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]]) %[[HANDLE2]], target("dx.Sampler", 0) %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL2]], float %[[CMP_CAST2]], <2 x i32> %[[OFFSET_VAL2]]) +// SPIRV: call reassoc nnan ninf nsz arcp afn float @llvm.spv.resource.samplecmplevelzero.f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE2]], target("spirv.Sampler") %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL2]], float %[[CMP_CAST2]], <2 x i32> %[[OFFSET_VAL2]]) diff --git a/clang/test/CodeGenHLSL/resources/Textures-SampleGrad.hlsl b/clang/test/CodeGenHLSL/resources/Textures-SampleGrad.hlsl index 77c19acf8cd8d..616009c99a7d0 100644 --- a/clang/test/CodeGenHLSL/resources/Textures-SampleGrad.hlsl +++ b/clang/test/CodeGenHLSL/resources/Textures-SampleGrad.hlsl @@ -38,8 +38,8 @@ float4 test_grad(COORD_TYPE loc : LOC, float2 ddx : DDX, float2 ddy : DDY) : SV_ // CHECK: %[[COORD_VAL:.*]] = load <[[COORD_DIM]] x float>, ptr %[[COORD_ADDR]] // CHECK: %[[DDX_VAL:.*]] = load <2 x float>, ptr %[[DDX_ADDR]] // CHECK: %[[DDY_VAL:.*]] = load <2 x float>, ptr %[[DDY_ADDR]] -// DXIL: call {{.*}} <4 x float> @llvm.dx.resource.samplegrad.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE1]], target("dx.Sampler", 0) %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <2 x float> %[[DDX_VAL]], <2 x float> %[[DDY_VAL]], <2 x i32> zeroinitializer) -// SPIRV: call {{.*}} <4 x float> @llvm.spv.resource.samplegrad.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <2 x float> %[[DDX_VAL]], <2 x float> %[[DDY_VAL]], <2 x i32> zeroinitializer) +// DXIL: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.samplegrad.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE1]], target("dx.Sampler", 0) %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <2 x float> %[[DDX_VAL]], <2 x float> %[[DDY_VAL]], <2 x i32> zeroinitializer) +// SPIRV: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplegrad.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <2 x float> %[[DDX_VAL]], <2 x float> %[[DDY_VAL]], <2 x i32> zeroinitializer) // CHECK: @test_offset(float vector[[[COORD_DIM]]], float vector[2], float vector[2]) // CHECK: %[[CALL_OFFSET:.*]] = call {{.*}} <4 x float> @hlsl::[[TEXTURE]]<float vector[4]>::SampleGrad(hlsl::SamplerState, float vector[[[COORD_DIM]]], float vector[2], float vector[2], int vector[2])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <[[COORD_DIM]] x float> {{.*}} %{{.*}}, <2 x float> {{.*}} %{{.*}}, <2 x float> {{.*}} %{{.*}}, <2 x i32> noundef <i32 1, i32 2>) @@ -70,8 +70,8 @@ float4 test_offset(COORD_TYPE loc : LOC, float2 ddx : DDX, float2 ddy : DDY) : S // CHECK: %[[DDX_VAL:.*]] = load <2 x float>, ptr %[[DDX_ADDR]] // CHECK: %[[DDY_VAL:.*]] = load <2 x float>, ptr %[[DDY_ADDR]] // CHECK: %[[OFFSET_VAL:.*]] = load <2 x i32>, ptr %[[OFFSET_ADDR]] -// DXIL: call {{.*}} <4 x float> @llvm.dx.resource.samplegrad.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE2]], target("dx.Sampler", 0) %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <2 x float> %[[DDX_VAL]], <2 x float> %[[DDY_VAL]], <2 x i32> %[[OFFSET_VAL]]) -// SPIRV: call {{.*}} <4 x float> @llvm.spv.resource.samplegrad.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE2]], target("spirv.Sampler") %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <2 x float> %[[DDX_VAL]], <2 x float> %[[DDY_VAL]], <2 x i32> %[[OFFSET_VAL]]) +// DXIL: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.dx.resource.samplegrad.v4f32.{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXIL_TY]]) %[[HANDLE2]], target("dx.Sampler", 0) %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <2 x float> %[[DDX_VAL]], <2 x float> %[[DDY_VAL]], <2 x i32> %[[OFFSET_VAL]]) +// SPIRV: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplegrad.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE2]], target("spirv.Sampler") %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <2 x float> %[[DDX_VAL]], <2 x float> %[[DDY_VAL]], <2 x i32> %[[OFFSET_VAL]]) // CHECK: @test_clamp(float vector[[[COORD_DIM]]], float vector[2], float vector[2]) // CHECK: %[[CALL_CLAMP:.*]] = call {{.*}} <4 x float> @hlsl::[[TEXTURE]]<float vector[4]>::SampleGrad(hlsl::SamplerState, float vector[[[COORD_DIM]]], float vector[2], float vector[2], int vector[2], float)(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <[[COORD_DIM]] x float> {{.*}} %{{.*}}, <2 x float> {{.*}} %{{.*}}, <2 x float> {{.*}} %{{.*}}, <2 x i32> noundef <i32 1, i32 2>, float {{.*}} 1.000000e+00) @@ -106,5 +106,5 @@ float4 test_clamp(COORD_TYPE loc : LOC, float2 ddx : DDX, float2 ddy : DDY) : SV // CHECK: %[[OFFSET_VAL:.*]] = load <2 x i32>, ptr %[[OFFSET_ADDR]] // CHECK: %[[CLAMP_VAL:.*]] = load float, ptr %[[CLAMP_ADDR]] // CHECK: %[[CLAMP_CAST3:.*]] = fptrunc {{.*}} double {{.*}} to float -// DXIL: call {{.*}} <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]], <2 x float> %[[DDX_VAL]], <2 x float> %[[DDY_VAL]], <2 x i32> %[[OFFSET_VAL]], float %[[CLAMP_CAST3]]) -// SPIRV: call {{.*}} <4 x float> @llvm.spv.resource.samplegrad.clamp.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE3]], target("spirv.Sampler") %[[SAMPLER_H3]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <2 x float> %[[DDX_VAL]], <2 x float> %[[DDY_VAL]], <2 x i32> %[[OFFSET_VAL]], float %[[CLAMP_CAST3]]) +// DXIL: 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]], <2 x float> %[[DDX_VAL]], <2 x float> %[[DDY_VAL]], <2 x i32> %[[OFFSET_VAL]], float %[[CLAMP_CAST3]]) +// SPIRV: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplegrad.clamp.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE3]], target("spirv.Sampler") %[[SAMPLER_H3]], <[[COORD_DIM]] x float> %[[COORD_VAL]], <2 x float> %[[DDX_VAL]], <2 x float> %[[DDY_VAL]], <2 x i32> %[[OFFSET_VAL]], float %[[CLAMP_CAST3]]) diff --git a/clang/test/CodeGenHLSL/resources/Textures-SampleLevel.hlsl b/clang/test/CodeGenHLSL/resources/Textures-SampleLevel.hlsl index efff407a538a7..2e369a86c488f 100644 --- a/clang/test/CodeGenHLSL/resources/Textures-SampleLevel.hlsl +++ b/clang/test/CodeGenHLSL/resources/Textures-SampleLevel.hlsl @@ -36,8 +36,8 @@ float4 test_level(COORD_TYPE loc : LOC, float lod : LOD) : SV_Target { // 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 {{.*}} <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]], <2 x i32> zeroinitializer) -// SPIRV: call {{.*}} <4 x float> @llvm.spv.resource.samplelevel.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL1]], float %[[LOD_CAST1]], <2 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_CAST1]], <2 x i32> zeroinitializer) +// SPIRV: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplelevel.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE1]], target("spirv.Sampler") %[[SAMPLER_H1]], <[[COORD_DIM]] x float> %[[COORD_VAL1]], float %[[LOD_CAST1]], <2 x i32> zeroinitializer) // CHECK: @test_offset(float vector[[[COORD_DIM]]], float) // CHECK: %[[CALL_OFFSET:.*]] = call {{.*}} <4 x float> @hlsl::[[TEXTURE]]<float vector[4]>::SampleLevel(hlsl::SamplerState, float vector[[[COORD_DIM]]], float, int vector[2])(ptr {{.*}} @t, ptr {{.*}} byval(%"class.hlsl::SamplerState") {{.*}}, <[[COORD_DIM]] x float> {{.*}} %{{.*}}, float {{.*}} 0.000000e+00, <2 x i32> noundef <i32 1, i32 2>) @@ -66,5 +66,5 @@ float4 test_offset(COORD_TYPE loc : LOC, float lod : LOD) : SV_Target { // CHECK: %[[LOD_VAL2:.*]] = load float, ptr %[[LOD_ADDR2]] // CHECK: %[[LOD_CAST2:.*]] = fptrunc {{.*}} double {{.*}} to float // CHECK: %[[OFFSET_VAL2:.*]] = load <2 x i32>, ptr %[[OFFSET_ADDR2]] -// DXIL: call {{.*}} <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]], <2 x i32> %[[OFFSET_VAL2]]) -// SPIRV: call {{.*}} <4 x float> @llvm.spv.resource.samplelevel.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE2]], target("spirv.Sampler") %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL2]], float %[[LOD_CAST2]], <2 x i32> %[[OFFSET_VAL2]]) +// 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]]) %[[HANDLE2]], target("dx.Sampler", 0) %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL2]], float %[[LOD_CAST2]], <2 x i32> %[[OFFSET_VAL2]]) +// SPIRV: call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.resource.samplelevel.v4f32.{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[IMG_FMT]]) %[[HANDLE2]], target("spirv.Sampler") %[[SAMPLER_H2]], <[[COORD_DIM]] x float> %[[COORD_VAL2]], float %[[LOD_CAST2]], <2 x i32> %[[OFFSET_VAL2]]) >From 18a663dbc2458d30d058cdb602a5acea2e2dbbb1 Mon Sep 17 00:00:00 2001 From: Tim Corringham <[email protected]> Date: Mon, 17 Aug 2026 13:04:50 +0100 Subject: [PATCH 7/8] [HLSL] Put RetTy last in EmitIntrinsicCall resource overload Move the explicit return-type parameter after Args so it no longer conflicts with the existing Types overload for braced type lists. Co-authored-by: Cursor --- clang/lib/CodeGen/CGCall.cpp | 2 +- clang/lib/CodeGen/CGHLSLBuiltins.cpp | 27 ++++++++++++++------------- clang/lib/CodeGen/CodeGenFunction.h | 3 ++- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 3b1e074f41ec7..99d71618454cf 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -5438,8 +5438,8 @@ llvm::CallInst *CodeGenFunction::EmitIntrinsicCall(llvm::Intrinsic::ID ID, } llvm::CallInst *CodeGenFunction::EmitIntrinsicCall(llvm::Intrinsic::ID ID, - llvm::Type *RetTy, ArrayRef<llvm::Value *> Args, + llvm::Type *RetTy, const llvm::Twine &Name) { SmallVector<llvm::Type *> ArgTys; ArgTys.reserve(Args.size()); diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp index 5c33470a4b2ff..8685c5de7d607 100644 --- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp +++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp @@ -667,13 +667,13 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, llvm::Type *RetTy = ConvertType(E->getType()); if (E->getNumArgs() <= 4) { - return EmitIntrinsicCall(CGM.getHLSLRuntime().getSampleIntrinsic(), RetTy, - Args); + return EmitIntrinsicCall(CGM.getHLSLRuntime().getSampleIntrinsic(), Args, + RetTy); } Args.push_back(emitHlslClamp(*this, E, 4)); return EmitIntrinsicCall(CGM.getHLSLRuntime().getSampleClampIntrinsic(), - RetTy, Args); + Args, RetTy); } case Builtin::BI__builtin_hlsl_resource_sample_bias: { Value *HandleOp = EmitScalarExpr(E->getArg(0)); @@ -694,12 +694,12 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, llvm::Type *RetTy = ConvertType(E->getType()); if (E->getNumArgs() <= 5) { return EmitIntrinsicCall(CGM.getHLSLRuntime().getSampleBiasIntrinsic(), - RetTy, Args); + Args, RetTy); } Args.push_back(emitHlslClamp(*this, E, 5)); return EmitIntrinsicCall( - CGM.getHLSLRuntime().getSampleBiasClampIntrinsic(), RetTy, Args); + CGM.getHLSLRuntime().getSampleBiasClampIntrinsic(), Args, RetTy); } case Builtin::BI__builtin_hlsl_resource_sample_grad: { Value *HandleOp = EmitScalarExpr(E->getArg(0)); @@ -829,8 +829,8 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *CoordOp = EmitScalarExpr(E->getArg(2)); return EmitIntrinsicCall(CGM.getHLSLRuntime().getCalculateLodIntrinsic(), - ConvertType(E->getType()), - {HandleOp, SamplerOp, CoordOp}); + {HandleOp, SamplerOp, CoordOp}, + ConvertType(E->getType())); } case Builtin::BI__builtin_hlsl_resource_calculate_lod_unclamped: { Value *HandleOp = EmitScalarExpr(E->getArg(0)); @@ -839,7 +839,7 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, return EmitIntrinsicCall( CGM.getHLSLRuntime().getCalculateLodUnclampedIntrinsic(), - ConvertType(E->getType()), {HandleOp, SamplerOp, CoordOp}); + {HandleOp, SamplerOp, CoordOp}, ConvertType(E->getType())); } case Builtin::BI__builtin_hlsl_resource_gather: { Value *HandleOp = EmitScalarExpr(E->getArg(0)); @@ -977,8 +977,8 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, llvm::Intrinsic::ID IntrinsicID = llvm::Intrinsic::spv_resource_counterhandlefromimplicitbinding; SmallVector<Value *> Args{MainHandle, OrderID, SpaceOp}; - return EmitIntrinsicCall(IntrinsicID, {HandleTy, MainHandle->getType()}, - Args); + return EmitIntrinsicCall( + IntrinsicID, {HandleTy, MainHandle->getType()}, Args); } case Builtin::BI__builtin_hlsl_resource_nonuniformindex: { Value *IndexOp = EmitScalarExpr(E->getArg(0)); @@ -1550,9 +1550,10 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, // create our function type. Value *OpExpr = EmitScalarExpr(E->getArg(0)); Value *OpIndex = EmitScalarExpr(E->getArg(1)); - return EmitIntrinsicCall(CGM.getHLSLRuntime().getWaveReadLaneAtIntrinsic(), - {OpExpr->getType()}, ArrayRef{OpExpr, OpIndex}, - "hlsl.wave.readlane"); + return EmitIntrinsicCall( + CGM.getHLSLRuntime().getWaveReadLaneAtIntrinsic(), + {OpExpr->getType()}, ArrayRef{OpExpr, OpIndex}, + "hlsl.wave.readlane"); } case Builtin::BI__builtin_hlsl_wave_prefix_sum: { Value *OpExpr = EmitScalarExpr(E->getArg(0)); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 7f2f600d95fc9..67d5c0b83d997 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -4632,8 +4632,9 @@ class CodeGenFunction : public CodeGenTypeCache { ArrayRef<llvm::Type *> Types, ArrayRef<llvm::Value *> Args, const Twine &Name = ""); - llvm::CallInst *EmitIntrinsicCall(llvm::Intrinsic::ID ID, llvm::Type *RetTy, + llvm::CallInst *EmitIntrinsicCall(llvm::Intrinsic::ID ID, ArrayRef<llvm::Value *> Args, + llvm::Type *RetTy, const Twine &Name = ""); llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name = ""); >From 2adf9f2c1e6654514f5bb06e00c2a1c14b41d1b4 Mon Sep 17 00:00:00 2001 From: Tim Corringham <[email protected]> Date: Mon, 17 Aug 2026 17:28:51 +0100 Subject: [PATCH 8/8] Fix code formatting Fix clang-format errors --- clang/lib/CodeGen/CGHLSLBuiltins.cpp | 15 +++++++-------- clang/lib/CodeGen/CodeGenFunction.h | 3 +-- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp index 56598d4ff8d17..7b5fc07c1cfca 100644 --- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp +++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp @@ -710,8 +710,8 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, } Args.push_back(emitHlslClamp(*this, E, 5)); - return EmitIntrinsicCall( - CGM.getHLSLRuntime().getSampleBiasClampIntrinsic(), Args, RetTy); + return EmitIntrinsicCall(CGM.getHLSLRuntime().getSampleBiasClampIntrinsic(), + Args, RetTy); } case Builtin::BI__builtin_hlsl_resource_sample_grad: { Value *HandleOp = EmitScalarExpr(E->getArg(0)); @@ -989,8 +989,8 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, llvm::Intrinsic::ID IntrinsicID = llvm::Intrinsic::spv_resource_counterhandlefromimplicitbinding; SmallVector<Value *> Args{MainHandle, OrderID, SpaceOp}; - return EmitIntrinsicCall( - IntrinsicID, {HandleTy, MainHandle->getType()}, Args); + return EmitIntrinsicCall(IntrinsicID, {HandleTy, MainHandle->getType()}, + Args); } case Builtin::BI__builtin_hlsl_resource_nonuniformindex: { Value *IndexOp = EmitScalarExpr(E->getArg(0)); @@ -1509,10 +1509,9 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, // create our function type. Value *OpExpr = EmitScalarExpr(E->getArg(0)); Value *OpIndex = EmitScalarExpr(E->getArg(1)); - return EmitIntrinsicCall( - CGM.getHLSLRuntime().getWaveReadLaneAtIntrinsic(), - {OpExpr->getType()}, ArrayRef{OpExpr, OpIndex}, - "hlsl.wave.readlane"); + return EmitIntrinsicCall(CGM.getHLSLRuntime().getWaveReadLaneAtIntrinsic(), + {OpExpr->getType()}, ArrayRef{OpExpr, OpIndex}, + "hlsl.wave.readlane"); } case Builtin::BI__builtin_hlsl_wave_prefix_sum: { Value *OpExpr = EmitScalarExpr(E->getArg(0)); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 46f1bcf8a1968..25606a51b6d71 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -4653,8 +4653,7 @@ class CodeGenFunction : public CodeGenTypeCache { const Twine &Name = ""); llvm::CallInst *EmitIntrinsicCall(llvm::Intrinsic::ID ID, ArrayRef<llvm::Value *> Args, - llvm::Type *RetTy, - const Twine &Name = ""); + llvm::Type *RetTy, const Twine &Name = ""); llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name = ""); llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee, _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
