[clang] Test locally scoped resources (PR #190037)
Joshua Batista via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 16 11:31:00 PDT 2026
https://github.com/bob80905 updated https://github.com/llvm/llvm-project/pull/190037
>From ea9445b3fa97f5fa0132985f39a41609ed51e6f5 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Wed, 25 Mar 2026 16:40:16 -0700
Subject: [PATCH 01/10] first attempt
---
.../Resources/local_resources_failures.hlsl | 175 +++++
.../Resources/local_resources_passes.hlsl | 643 ++++++++++++++++++
2 files changed, 818 insertions(+)
create mode 100644 clang/test/SemaHLSL/Resources/local_resources_failures.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/local_resources_passes.hlsl
diff --git a/clang/test/SemaHLSL/Resources/local_resources_failures.hlsl b/clang/test/SemaHLSL/Resources/local_resources_failures.hlsl
new file mode 100644
index 0000000000000..84637cf8ce99f
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/local_resources_failures.hlsl
@@ -0,0 +1,175 @@
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -verify
+
+Texture2D<float4> gTex0 : register(t0);
+Texture2D<float4> gTex1 : register(t1);
+SamplerState gSampler : register(s0);
+
+StructuredBuffer<float4> gSB : register(t2);
+RWStructuredBuffer<float4> gRW : register(u0);
+
+Texture2D<float4> gTexArray[4] : register(t10);
+
+//--------------------------------------------------------------
+// FAIL 1: static local resource
+//--------------------------------------------------------------
+// This causes an assert in DXC
+float4 Fail_Static(float2 uv)
+{
+ static Texture2D<float4> tex = gTex0;
+ // expected-error at -1 {{static resource}}
+ return tex.Sample(gSampler, uv);
+}
+
+//--------------------------------------------------------------
+// FAIL 2: arithmetic on resource
+//--------------------------------------------------------------
+
+float Fail_Arithmetic()
+{
+ Texture2D<float4> tex = gTex0;
+ tex = tex + 1;
+ // expected-error at -1 {{scalar, vector, or matrix expected}}
+ return tex;
+ // expected-error at -1 {{cannot initialize return object of type 'float' with an lvalue of type 'Texture2D<float4>'}}
+}
+
+//--------------------------------------------------------------
+// FAIL 3: comparison of resources
+//--------------------------------------------------------------
+
+bool Fail_Compare()
+{
+ Texture2D<float4> a = gTex0;
+ Texture2D<float4> b = gTex1;
+ return a == b;
+ // expected-error at -1 {{operator cannot be used with built-in type 'Texture2D<vector<float, 4> >'}}
+}
+
+//--------------------------------------------------------------
+// FAIL 4: conversion to bool
+//--------------------------------------------------------------
+
+bool Fail_Bool()
+{
+ Texture2D<float4> tex = gTex0;
+ return tex;
+ // expected-error at -1 {{cannot initialize return object of type 'bool' with an lvalue of type 'Texture2D<float4>'}}
+}
+
+//--------------------------------------------------------------
+// FAIL 5: cast from resource
+//--------------------------------------------------------------
+
+uint Fail_Cast()
+{
+ Texture2D<float4> tex = gTex0;
+ return (uint)tex;
+ // expected-error at -1 {{cannot convert from 'Texture2D<float4>' to 'uint'}}
+}
+
+//--------------------------------------------------------------
+// FAIL 6: addition of resources
+//--------------------------------------------------------------
+
+float Fail_Add()
+{
+ Texture2D<float4> tex = gTex0;
+ return tex + tex;
+ // expected-error at -1 {{scalar, vector, or matrix expected}}
+}
+
+
+//--------------------------------------------------------------
+// FAIL 7: default parameter on resource
+//--------------------------------------------------------------
+
+float4 Fail_DefaultParam(Texture2D<float4> tex = gTex0, float2 uv)
+ // expected-error at -1 {{missing default argument on parameter 'uv'}}
+ // expected-note at -2 {{candidate function not viable: requires 2 arguments, but 1 was provided}}
+ // note, this note above does not get emitted when -verify is passed as an option.
+{
+ return tex.Sample(gSampler, uv);
+}
+
+//--------------------------------------------------------------
+// FAIL 8: reinterpret cast
+//--------------------------------------------------------------
+
+float4 Fail_Reinterpret(float2 uv)
+{
+ Texture2D<float4> tex = gTex0;
+ return ((Texture2D<float4>)gSampler).Sample(gSampler, uv);
+ // expected-error at -1 {{cannot convert from 'SamplerState' to 'Texture2D<float4>'}}
+}
+
+//--------------------------------------------------------------
+// FAIL 9: RWStructuredBuffer with resource type
+//--------------------------------------------------------------
+
+void Fail_LocalBuffer()
+{
+ RWStructuredBuffer<Texture2D<float4> > badBuffer;
+ // expected-error at -1 {{object 'Texture2D<float4>' is not allowed in builtin template parameters}}
+}
+
+//--------------------------------------------------------------
+// FAIL 10: wave uniformity violation
+//--------------------------------------------------------------
+
+float4 Fail_WaveUniform(float2 uv)
+{
+ Texture2D<float4> tex = gTex0;
+ // I presume the reason we don't see this expected error is that
+ // DxilCondenseResources is responsible for emitting this.
+ // So, it will not run when -verify is passed to the compiler since
+ // DXIL IR is not the intended output in that situation.
+ // However, in DXC, we do expect an error here.
+ if(WaveActiveAllTrue(true))
+ // expected-error at -1 {{local resource not guaranteed to map to unique global resource}}
+ tex = gTex1;
+ return tex.Sample(gSampler, uv);
+}
+
+//--------------------------------------------------------------
+// Entry point calling all fail functions to prevent DCE
+//--------------------------------------------------------------
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ float2 uv = float2(0,0);
+ float4 r = 0;
+ gTex0 = tex;
+ // FAIL 1
+ r += Fail_Static(uv);
+
+ // FAIL 2
+ Fail_Arithmetic();
+
+ // FAIL 3
+ Fail_Compare();
+
+ // FAIL 4
+ Fail_Bool();
+
+ // FAIL 5
+ Fail_Cast();
+
+ // FAIL 6
+ Fail_Add();
+
+ // FAIL 7
+ // note, this error does not get emitted when -verify is passed as an option.
+ // expected-error at +1{{no matching function for call to 'Fail_DefaultParam'}}
+ Fail_DefaultParam(gTex0, uv);
+
+ // FAIL 8
+ Fail_Reinterpret(uv);
+
+ // FAIL 9
+ Fail_LocalBuffer();
+
+ // FAIL 10
+ r += Fail_WaveUniform(uv);
+}
diff --git a/clang/test/SemaHLSL/Resources/local_resources_passes.hlsl b/clang/test/SemaHLSL/Resources/local_resources_passes.hlsl
new file mode 100644
index 0000000000000..cc5fc2835033e
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/local_resources_passes.hlsl
@@ -0,0 +1,643 @@
+// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -verify
+
+//==============================================================
+// COMPREHENSIVE LOCAL RESOURCE VARIABLE TEST SUITE
+//
+// Structure
+// PASS TESTS
+// ENTRYPOINT
+//
+// Goal
+// Exhaustively document legal and illegal uses of HLSL
+// resource variables declared in local scope.
+//
+//==============================================================
+
+//--------------------------------------------------------------
+// Global resources
+//--------------------------------------------------------------
+
+Texture2D<float4> gTex0 : register(t0);
+Texture2D<float4> gTex1 : register(t1);
+Texture2D<float4> gTex2 : register(t2);
+
+SamplerState gSampler : register(s0);
+
+RWTexture2D<float4> gOut : register(u0);
+
+StructuredBuffer<float4> gSB : register(t3);
+RWStructuredBuffer<float4> gRW : register(u1);
+
+Texture2D<float4> gTexArray[4] : register(t10);
+
+
+//==============================================================
+// PASS TESTS
+//==============================================================
+
+
+//--------------------------------------------------------------
+// PASS 0
+//--------------------------------------------------------------
+
+groupshared Texture2D<float4> sharedTex;
+
+float4 Use_SharedTex(float2 uv)
+{
+ return gTex0.Sample(gSampler, uv);
+}
+
+//--------------------------------------------------------------
+// PASS 1
+//--------------------------------------------------------------
+
+float4 Fail_TernaryInit(bool cond, float2 uv)
+{
+ Texture2D<float4> tex = cond ? gTex0 : gTex1;
+
+ return tex.Sample(gSampler, uv);
+}
+//--------------------------------------------------------------
+// PASS 2
+//--------------------------------------------------------------
+
+void Fail_LoopVar()
+{
+ for(Texture2D<float4> tex = gTex0; false;)
+ {
+ }
+}
+
+//--------------------------------------------------------------
+// PASS 3
+//--------------------------------------------------------------
+
+float4 Fail_ExpressionInit(float2 uv)
+{
+ Texture2D<float4> tex = (true ? gTex0 : gTex1);
+ return tex.Sample(gSampler, uv);
+}
+//--------------------------------------------------------------
+// PASS 4
+//--------------------------------------------------------------
+
+struct FailSharedStruct
+{
+ Texture2D<float4> tex;
+};
+
+groupshared FailSharedStruct sharedStruct;
+
+float4 Use_FailSharedStruct(float2 uv)
+{
+ return gTex0.Sample(gSampler, uv);
+}
+
+//--------------------------------------------------------------
+// PASS 5
+//--------------------------------------------------------------
+
+struct FailStruct
+{
+ Texture2D<float4> tex;
+};
+
+float4 Fail_StructArray(float2 uv)
+{
+ FailStruct s[2];
+
+ s[0].tex = gTex0;
+ return s[0].tex.Sample(gSampler, uv);
+}
+
+//--------------------------------------------------------------
+// PASS 6
+//--------------------------------------------------------------
+groupshared Texture2D<float4> Fail_Shared;
+
+float4 Use_Fail_Shared(float2 uv)
+{
+ return gTex0.Sample(gSampler, uv);
+}
+
+//--------------------------------------------------------------
+// PASS 7
+//--------------------------------------------------------------
+Texture2D<float4> Fail_ReturnLocal_Uninitialized()
+{
+ Texture2D<float4> tex; // uninitialized local resource
+ return tex;
+}
+
+//--------------------------------------------------------------
+// PASS 8
+//--------------------------------------------------------------
+Texture2D<float4> Fail_ReturnLocal()
+{
+ Texture2D<float4> tex = gTex0;
+ return tex;
+}
+
+
+//--------------------------------------------------------------
+// PASS 9
+//--------------------------------------------------------------
+struct S { Texture2D<float4> arr[2]; };
+float4 Pass_StructArray(float2 uv)
+{
+ S s;
+ s.arr[0] = gTex0;
+ return s.arr[0].Sample(gSampler, uv);
+}
+
+//--------------------------------------------------------------
+// PASS 10
+//--------------------------------------------------------------
+
+float4 Pass_LocalArray(float2 uv)
+{
+ Texture2D<float4> arr[2];
+
+ arr[0] = gTex0;
+ return arr[0].Sample(gSampler, uv);
+}
+
+//--------------------------------------------------------------
+// PASS 11
+// Uninitialized use
+//--------------------------------------------------------------
+
+float4 Pass_Uninitialized(float2 uv)
+{
+ Texture2D<float4> tex;
+
+
+ return tex.Sample(gSampler, uv);
+}
+
+//--------------------------------------------------------------
+// PASS 12
+// Simple local alias
+//--------------------------------------------------------------
+
+float4 Pass_Alias(float2 uv)
+{
+ Texture2D<float4> tex = gTex0;
+ return tex.Sample(gSampler, uv);
+}
+
+
+//--------------------------------------------------------------
+// PASS 13
+// Reassignment
+//--------------------------------------------------------------
+
+float4 Pass_Reassign(float2 uv)
+{
+ Texture2D<float4> tex = gTex0;
+ tex = gTex1;
+ return tex.Sample(gSampler, uv);
+}
+
+
+//--------------------------------------------------------------
+// PASS 14
+// Control flow aliasing
+//--------------------------------------------------------------
+
+float4 Pass_IfAlias(bool cond, float2 uv)
+{
+ Texture2D<float4> tex;
+
+ if (cond)
+ tex = gTex0;
+ else
+ tex = gTex1;
+
+ return tex.Sample(gSampler, uv);
+}
+
+
+//--------------------------------------------------------------
+// PASS 15
+// Loop aliasing
+//--------------------------------------------------------------
+
+float4 Pass_Loop(float2 uv)
+{
+ float4 sum = 0;
+
+ for(int i=0;i<4;i++)
+ {
+ Texture2D<float4> tex = gTexArray[i];
+ sum += tex.Sample(gSampler, uv);
+ }
+
+ return sum;
+}
+
+
+
+//--------------------------------------------------------------
+// PASS 16
+// Struct containing resource
+//--------------------------------------------------------------
+
+struct PassStruct
+{
+ Texture2D<float4> tex;
+ SamplerState samp;
+};
+
+float4 Pass_Struct(float2 uv)
+{
+ PassStruct s;
+ s.tex = gTex0;
+ s.samp = gSampler;
+
+ return s.tex.Sample(s.samp, uv);
+}
+
+
+
+//--------------------------------------------------------------
+// PASS 17
+// Passing resource through multiple functions
+//--------------------------------------------------------------
+
+float4 Pass_Level2(Texture2D<float4> tex, float2 uv)
+{
+ return tex.Sample(gSampler, uv);
+}
+
+float4 Pass_Level1(Texture2D<float4> tex, float2 uv)
+{
+ return Pass_Level2(tex, uv);
+}
+
+float4 Pass_FunctionForward(float2 uv)
+{
+ Texture2D<float4> tex = gTex1;
+ return Pass_Level1(tex, uv);
+}
+
+
+
+//--------------------------------------------------------------
+// PASS 18
+// Resource merge via conditional assignments
+// (SSA-style PHI equivalent)
+//--------------------------------------------------------------
+
+float4 Pass_PhiMerge(bool cond, float2 uv)
+{
+ Texture2D<float4> tex;
+
+ if(cond)
+ tex = gTex0;
+ else
+ tex = gTex2;
+
+ return tex.Sample(gSampler, uv);
+}
+
+
+
+//--------------------------------------------------------------
+// PASS 19
+// Nested scope shadowing
+//--------------------------------------------------------------
+
+float4 Pass_Shadow(float2 uv)
+{
+ Texture2D<float4> tex = gTex0;
+
+ {
+ Texture2D<float4> tex = gTex1;
+ return tex.Sample(gSampler, uv);
+ }
+}
+
+
+
+//--------------------------------------------------------------
+// PASS 20
+// Resource in switch
+//--------------------------------------------------------------
+
+float4 Pass_Switch(int v, float2 uv)
+{
+ Texture2D<float4> tex = gTex0;
+
+ switch(v)
+ {
+ case 1: tex = gTex1; break;
+ case 2: tex = gTex2; break;
+ }
+
+ return tex.Sample(gSampler, uv);
+}
+
+
+
+//--------------------------------------------------------------
+// PASS 21
+// Bindless descriptor indexing
+//--------------------------------------------------------------
+
+float4 Pass_Bindless(uint idx, float2 uv)
+{
+ Texture2D<float4> tex = gTexArray[idx];
+ return tex.Sample(gSampler, uv);
+}
+
+
+
+//--------------------------------------------------------------
+// PASS 22
+// Resource with wave operations
+//--------------------------------------------------------------
+
+float4 Pass_WaveUse(float2 uv)
+{
+ Texture2D<float4> tex = gTex0;
+
+ float4 v = tex.Sample(gSampler, uv);
+
+ uint active = WaveActiveCountBits(true);
+
+ return v * active;
+}
+
+
+
+//--------------------------------------------------------------
+// PASS 23
+// Resource alias used inside nested loops
+//--------------------------------------------------------------
+
+float4 Pass_NestedLoops(float2 uv)
+{
+ float4 sum = 0;
+
+ for(int i=0;i<2;i++)
+ for(int j=0;j<2;j++)
+ {
+ Texture2D<float4> tex = gTexArray[i+j];
+ sum += tex.Sample(gSampler, uv);
+ }
+
+ return sum;
+}
+
+
+
+//--------------------------------------------------------------
+// PASS 24
+// Resource lifetime across blocks
+//--------------------------------------------------------------
+
+float4 Pass_BlockLifetime(float2 uv)
+{
+ Texture2D<float4> tex;
+
+ {
+ tex = gTex1;
+ }
+
+ return tex.Sample(gSampler, uv);
+}
+
+
+//--------------------------------------------------------------
+// PASS 25
+// Deep nested PHI merges
+//--------------------------------------------------------------
+
+float4 Pass_DeepPhi(bool a, bool b, float2 uv)
+{
+ Texture2D<float4> tex;
+
+ if(a)
+ {
+ if(b)
+ tex = gTex0;
+ else
+ tex = gTex1;
+ }
+ else
+ {
+ tex = gTex2;
+ }
+
+ return tex.Sample(gSampler, uv);
+}
+
+
+
+//--------------------------------------------------------------
+// PASS 26
+// Loop-carried resource value
+//--------------------------------------------------------------
+
+float4 Pass_LoopCarried(int iterations, float2 uv)
+{
+ Texture2D<float4> tex = gTex0;
+
+ for(int i=0;i<iterations;i++)
+ {
+ tex = gTexArray[i & 3];
+ }
+
+ return tex.Sample(gSampler, uv);
+}
+
+
+
+//--------------------------------------------------------------
+// PASS 27
+// Resource alias chain
+//--------------------------------------------------------------
+
+float4 Pass_AliasChain(float2 uv)
+{
+ Texture2D<float4> a = gTex0;
+ Texture2D<float4> b = a;
+ Texture2D<float4> c = b;
+
+ return c.Sample(gSampler, uv);
+}
+
+
+
+//--------------------------------------------------------------
+// PASS 28
+// Resource inside nested structs
+//--------------------------------------------------------------
+
+struct PassNestedInner
+{
+ Texture2D<float4> tex;
+};
+
+struct PassNestedOuter
+{
+ PassNestedInner inner;
+};
+
+float4 Pass_NestedStruct(float2 uv)
+{
+ PassNestedOuter s;
+
+ s.inner.tex = gTex1;
+
+ return s.inner.tex.Sample(gSampler, uv);
+}
+
+
+
+//--------------------------------------------------------------
+// PASS 29
+// Resource forwarded through multiple struct layers
+//--------------------------------------------------------------
+
+struct PassForwardA { Texture2D<float4> tex; };
+struct PassForwardB { PassForwardA a; };
+
+float4 Pass_ForwardStructLayers(float2 uv)
+{
+ PassForwardB b;
+ b.a.tex = gTex2;
+
+ return b.a.tex.Sample(gSampler, uv);
+}
+
+
+
+//--------------------------------------------------------------
+// PASS 30
+// Resource alias inside switch fallthrough
+//--------------------------------------------------------------
+
+float4 Pass_SwitchFallthrough(int v, float2 uv)
+{
+ Texture2D<float4> tex = gTex0;
+
+ switch(v)
+ {
+ case 0:
+ tex = gTex1;
+ case 1:
+ tex = gTex2;
+ break;
+ }
+
+ return tex.Sample(gSampler, uv);
+}
+
+
+
+//--------------------------------------------------------------
+// PASS 31
+// Resource used after early-return path merge
+//--------------------------------------------------------------
+
+float4 Pass_EarlyReturn(bool cond, float2 uv)
+{
+ Texture2D<float4> tex = gTex0;
+
+ if(cond)
+ return tex.Sample(gSampler, uv);
+
+ tex = gTex1;
+
+ return tex.Sample(gSampler, uv);
+}
+
+
+//--------------------------------------------------------------
+// PASS 32
+// Resource alias across nested blocks
+//--------------------------------------------------------------
+
+float4 Pass_NestedBlocks(float2 uv)
+{
+ Texture2D<float4> tex;
+
+ {
+ tex = gTex1;
+
+ {
+ tex = gTex2;
+ }
+ }
+
+ return tex.Sample(gSampler, uv);
+}
+
+
+
+//--------------------------------------------------------------
+// PASS 33
+// Resource assigned via bindless selection
+//--------------------------------------------------------------
+
+float4 Pass_BindlessSelection(uint a, uint b, float2 uv)
+{
+ Texture2D<float4> tex;
+
+ tex = gTexArray[a];
+ tex = gTexArray[b];
+
+ return tex.Sample(gSampler, uv);
+}
+
+
+//==============================================================
+// ENTRY POINT
+//==============================================================
+
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ float2 uv = float2(tid.xy)/256.0;
+
+ float4 r = 0;
+ r += Pass_TernaryInit(true, uv);
+ Pass_LoopVar();
+ r += Pass_ExpressionInit(uv);
+ r += Use_FailSharedStruct(uv);
+ r += Pass_StructArray(uv);
+ r += Use_Fail_Shared(uv);
+ Texture2D<float4> mytex = Fail_ReturnLocal_Uninitialized();
+ Texture2D<float4> mytex2 = Fail_ReturnLocal();
+ r += Pass_StructArray(uv);
+ r += Pass_LocalArray(uv);
+ r += Pass_Uninitialized(uv);
+ r += Pass_Alias(uv);
+ r += Pass_Reassign(uv);
+ r += Pass_IfAlias(true,uv);
+ r += Pass_Loop(uv);
+ r += Pass_Struct(uv);
+ r += Pass_FunctionForward(uv);
+ r += Pass_PhiMerge(true,uv);
+ r += Pass_Shadow(uv);
+ r += Pass_Switch(1,uv);
+ r += Pass_Bindless(0,uv);
+ r += Pass_WaveUse(uv);
+ r += Pass_NestedLoops(uv);
+ r += Pass_BlockLifetime(uv);
+ r += Pass_DeepPhi(true, false, uv);
+ r += Pass_LoopCarried(15, uv);
+ r += Pass_AliasChain(uv);
+ r += Pass_NestedStruct(uv);
+ r += Pass_ForwardStructLayers(uv);
+ r += Pass_SwitchFallthrough(0, uv);
+ r += Pass_EarlyReturn(true, uv);
+ r += Pass_NestedBlocks(uv);
+ r += Pass_BindlessSelection(2, 3, uv);
+
+ gOut[tid.xy] = r;
+}
\ No newline at end of file
>From bcc445e537ae44546db6ce4928d94039f5e4637e Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Mon, 30 Mar 2026 14:39:07 -0700
Subject: [PATCH 02/10] cleanup
---
.../Resources/local_resources_failures.hlsl | 2 +-
.../Resources/local_resources_passes.hlsl | 641 ++++++------------
2 files changed, 218 insertions(+), 425 deletions(-)
diff --git a/clang/test/SemaHLSL/Resources/local_resources_failures.hlsl b/clang/test/SemaHLSL/Resources/local_resources_failures.hlsl
index 84637cf8ce99f..aee4d33815e51 100644
--- a/clang/test/SemaHLSL/Resources/local_resources_failures.hlsl
+++ b/clang/test/SemaHLSL/Resources/local_resources_failures.hlsl
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -triple \
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -verify
Texture2D<float4> gTex0 : register(t0);
diff --git a/clang/test/SemaHLSL/Resources/local_resources_passes.hlsl b/clang/test/SemaHLSL/Resources/local_resources_passes.hlsl
index cc5fc2835033e..b44e9ff8896dc 100644
--- a/clang/test/SemaHLSL/Resources/local_resources_passes.hlsl
+++ b/clang/test/SemaHLSL/Resources/local_resources_passes.hlsl
@@ -1,596 +1,389 @@
-// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -verify
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -verify
//==============================================================
-// COMPREHENSIVE LOCAL RESOURCE VARIABLE TEST SUITE
-//
-// Structure
-// PASS TESTS
-// ENTRYPOINT
-//
-// Goal
-// Exhaustively document legal and illegal uses of HLSL
-// resource variables declared in local scope.
-//
+// GLOBAL RESOURCES
//==============================================================
-//--------------------------------------------------------------
-// Global resources
-//--------------------------------------------------------------
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+RWByteAddressBuffer gBuf2 : register(u2);
-Texture2D<float4> gTex0 : register(t0);
-Texture2D<float4> gTex1 : register(t1);
-Texture2D<float4> gTex2 : register(t2);
+RWByteAddressBuffer gOut : register(u3);
-SamplerState gSampler : register(s0);
+RWByteAddressBuffer gBufArray[4] : register(u10);
-RWTexture2D<float4> gOut : register(u0);
-StructuredBuffer<float4> gSB : register(t3);
-RWStructuredBuffer<float4> gRW : register(u1);
+//==============================================================
+// HELPERS
+//==============================================================
-Texture2D<float4> gTexArray[4] : register(t10);
+uint DoStore(RWByteAddressBuffer buf, uint offset, uint value)
+{
+ buf.Store(offset, value);
+ return value;
+}
//==============================================================
// PASS TESTS
//==============================================================
-
-//--------------------------------------------------------------
// PASS 0
-//--------------------------------------------------------------
-
-groupshared Texture2D<float4> sharedTex;
+groupshared RWByteAddressBuffer sharedBuf;
-float4 Use_SharedTex(float2 uv)
+uint Use_Shared(uint idx)
{
- return gTex0.Sample(gSampler, uv);
+ return DoStore(gBuf0, idx * 4, 1);
}
-//--------------------------------------------------------------
// PASS 1
-//--------------------------------------------------------------
-
-float4 Fail_TernaryInit(bool cond, float2 uv)
+uint Pass_TernaryInit(bool cond, uint idx)
{
- Texture2D<float4> tex = cond ? gTex0 : gTex1;
-
- return tex.Sample(gSampler, uv);
+ // expected-warning at +1{{assignment of 'cond ? gBuf0 : gBuf1' to local resource 'buf' is not to the same unique global resource}}
+ RWByteAddressBuffer buf = cond ? gBuf0 : gBuf1;
+ return DoStore(buf, idx * 4, 2);
}
-//--------------------------------------------------------------
-// PASS 2
-//--------------------------------------------------------------
-void Fail_LoopVar()
+// PASS 2
+void Pass_LoopVar()
{
- for(Texture2D<float4> tex = gTex0; false;)
+ for(RWByteAddressBuffer buf = gBuf0; false;)
{
}
}
-//--------------------------------------------------------------
// PASS 3
-//--------------------------------------------------------------
-
-float4 Fail_ExpressionInit(float2 uv)
+uint Pass_ExpressionInit(uint idx)
{
- Texture2D<float4> tex = (true ? gTex0 : gTex1);
- return tex.Sample(gSampler, uv);
+ RWByteAddressBuffer buf = (true ? gBuf0 : gBuf1);
+ return DoStore(buf, idx * 4, 3);
}
-//--------------------------------------------------------------
-// PASS 4
-//--------------------------------------------------------------
-struct FailSharedStruct
-{
- Texture2D<float4> tex;
-};
+// PASS 4
+struct PassBufStruct { RWByteAddressBuffer buf; };
-groupshared FailSharedStruct sharedStruct;
+groupshared PassBufStruct sharedStruct;
-float4 Use_FailSharedStruct(float2 uv)
+uint Use_PassSharedStruct(uint idx)
{
- return gTex0.Sample(gSampler, uv);
+ return DoStore(gBuf0, idx * 4, 4);
}
-//--------------------------------------------------------------
// PASS 5
-//--------------------------------------------------------------
-
-struct FailStruct
+uint Pass_StructArray(uint idx)
{
- Texture2D<float4> tex;
-};
-
-float4 Fail_StructArray(float2 uv)
-{
- FailStruct s[2];
-
- s[0].tex = gTex0;
- return s[0].tex.Sample(gSampler, uv);
+ PassBufStruct s[2];
+ s[0].buf = gBuf0;
+ return DoStore(s[0].buf, idx * 4, 5);
}
-//--------------------------------------------------------------
// PASS 6
-//--------------------------------------------------------------
-groupshared Texture2D<float4> Fail_Shared;
+groupshared RWByteAddressBuffer Pass_Shared;
-float4 Use_Fail_Shared(float2 uv)
+uint Use_Pass_Shared(uint idx)
{
- return gTex0.Sample(gSampler, uv);
+ return DoStore(gBuf0, idx * 4, 6);
}
-//--------------------------------------------------------------
// PASS 7
-//--------------------------------------------------------------
-Texture2D<float4> Fail_ReturnLocal_Uninitialized()
+RWByteAddressBuffer Pass_ReturnLocal_Uninitialized()
{
- Texture2D<float4> tex; // uninitialized local resource
- return tex;
+ RWByteAddressBuffer buf;
+ return buf;
}
-//--------------------------------------------------------------
// PASS 8
-//--------------------------------------------------------------
-Texture2D<float4> Fail_ReturnLocal()
+RWByteAddressBuffer Pass_ReturnLocal()
{
- Texture2D<float4> tex = gTex0;
- return tex;
+ RWByteAddressBuffer buf = gBuf0;
+ return buf;
}
-
-//--------------------------------------------------------------
// PASS 9
-//--------------------------------------------------------------
-struct S { Texture2D<float4> arr[2]; };
-float4 Pass_StructArray(float2 uv)
+struct S { RWByteAddressBuffer arr[2]; };
+
+uint Pass_StructArrayAssignment(uint idx)
{
S s;
- s.arr[0] = gTex0;
- return s.arr[0].Sample(gSampler, uv);
+ s.arr[0] = gBuf0;
+ return DoStore(s.arr[0], idx * 4, 9);
}
-//--------------------------------------------------------------
// PASS 10
-//--------------------------------------------------------------
-
-float4 Pass_LocalArray(float2 uv)
+uint Pass_LocalArray(uint idx)
{
- Texture2D<float4> arr[2];
-
- arr[0] = gTex0;
- return arr[0].Sample(gSampler, uv);
+ RWByteAddressBuffer arr[2];
+ arr[0] = gBuf0;
+ return DoStore(arr[0], idx * 4, 10);
}
-//--------------------------------------------------------------
// PASS 11
-// Uninitialized use
-//--------------------------------------------------------------
-
-float4 Pass_Uninitialized(float2 uv)
+uint Pass_Uninitialized(uint idx)
{
- Texture2D<float4> tex;
-
-
- return tex.Sample(gSampler, uv);
+ RWByteAddressBuffer buf;
+ return DoStore(buf, idx * 4, 11);
}
-//--------------------------------------------------------------
// PASS 12
-// Simple local alias
-//--------------------------------------------------------------
-
-float4 Pass_Alias(float2 uv)
+uint Pass_Alias(uint idx)
{
- Texture2D<float4> tex = gTex0;
- return tex.Sample(gSampler, uv);
+ RWByteAddressBuffer buf = gBuf0;
+ return DoStore(buf, idx * 4, 12);
}
-
-//--------------------------------------------------------------
// PASS 13
-// Reassignment
-//--------------------------------------------------------------
-
-float4 Pass_Reassign(float2 uv)
+uint Pass_Reassign(uint idx)
{
- Texture2D<float4> tex = gTex0;
- tex = gTex1;
- return tex.Sample(gSampler, uv);
+ // expected-note at +1{{variable 'buf' is declared here}}
+ RWByteAddressBuffer buf = gBuf0;
+ // expected-warning at +1{{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
+ buf = gBuf1;
+ return DoStore(buf, idx * 4, 13);
}
-
-//--------------------------------------------------------------
// PASS 14
-// Control flow aliasing
-//--------------------------------------------------------------
-
-float4 Pass_IfAlias(bool cond, float2 uv)
+uint Pass_IfAlias(bool cond, uint idx)
{
- Texture2D<float4> tex;
-
- if (cond)
- tex = gTex0;
- else
- tex = gTex1;
-
- return tex.Sample(gSampler, uv);
+ RWByteAddressBuffer buf;
+ // expected-warning at +1{{assignment of 'cond ? gBuf0 : gBuf1' to local resource 'buf' is not to the same unique global resource}}
+ buf = cond ? gBuf0 : gBuf1;
+ return DoStore(buf, idx * 4, 14);
}
-
-//--------------------------------------------------------------
// PASS 15
-// Loop aliasing
-//--------------------------------------------------------------
-
-float4 Pass_Loop(float2 uv)
+uint Pass_Loop(uint idx)
{
- float4 sum = 0;
-
- for(int i=0;i<4;i++)
- {
- Texture2D<float4> tex = gTexArray[i];
- sum += tex.Sample(gSampler, uv);
+ uint sum = 0;
+ for(unsigned int i=0;i<4;i++)
+ {
+ RWByteAddressBuffer buf = gBufArray[i];
+ sum += DoStore(buf, idx * 4 + i * 4, 15);
}
-
return sum;
}
-
-
-//--------------------------------------------------------------
// PASS 16
-// Struct containing resource
-//--------------------------------------------------------------
-
struct PassStruct
{
- Texture2D<float4> tex;
- SamplerState samp;
+ RWByteAddressBuffer buf;
};
-float4 Pass_Struct(float2 uv)
+uint Pass_Struct(uint idx)
{
PassStruct s;
- s.tex = gTex0;
- s.samp = gSampler;
-
- return s.tex.Sample(s.samp, uv);
+ s.buf = gBuf0;
+ return DoStore(s.buf, idx * 4, 16);
}
-
-
-//--------------------------------------------------------------
// PASS 17
-// Passing resource through multiple functions
-//--------------------------------------------------------------
-
-float4 Pass_Level2(Texture2D<float4> tex, float2 uv)
+uint Pass_Level2(RWByteAddressBuffer buf, uint idx)
{
- return tex.Sample(gSampler, uv);
+ return DoStore(buf, idx * 4, 17);
}
-float4 Pass_Level1(Texture2D<float4> tex, float2 uv)
+uint Pass_Level1(RWByteAddressBuffer buf, uint idx)
{
- return Pass_Level2(tex, uv);
+ return Pass_Level2(buf, idx);
}
-float4 Pass_FunctionForward(float2 uv)
+uint Pass_FunctionForward(uint idx)
{
- Texture2D<float4> tex = gTex1;
- return Pass_Level1(tex, uv);
+ RWByteAddressBuffer buf = gBuf1;
+ return Pass_Level1(buf, idx);
}
-
-
-//--------------------------------------------------------------
// PASS 18
-// Resource merge via conditional assignments
-// (SSA-style PHI equivalent)
-//--------------------------------------------------------------
-
-float4 Pass_PhiMerge(bool cond, float2 uv)
+uint Pass_PhiMerge(bool cond, uint idx)
{
- Texture2D<float4> tex;
-
- if(cond)
- tex = gTex0;
- else
- tex = gTex2;
-
- return tex.Sample(gSampler, uv);
+ RWByteAddressBuffer buf;
+ // expected-warning at +1{{assignment of 'cond ? gBuf0 : gBuf2' to local resource 'buf' is not to the same unique global resource}}
+ buf = cond ? gBuf0 : gBuf2;
+ return DoStore(buf, idx * 4, 18);
}
-
-
-//--------------------------------------------------------------
// PASS 19
-// Nested scope shadowing
-//--------------------------------------------------------------
-
-float4 Pass_Shadow(float2 uv)
+uint Pass_Shadow(uint idx)
{
- Texture2D<float4> tex = gTex0;
-
+ RWByteAddressBuffer buf = gBuf0;
{
- Texture2D<float4> tex = gTex1;
- return tex.Sample(gSampler, uv);
+ RWByteAddressBuffer buf = gBuf1;
+ return DoStore(buf, idx * 4, 19);
}
}
-
-
-//--------------------------------------------------------------
// PASS 20
-// Resource in switch
-//--------------------------------------------------------------
-
-float4 Pass_Switch(int v, float2 uv)
+uint Pass_Switch(int v, uint idx)
{
- Texture2D<float4> tex = gTex0;
+ // expected-note at +2{{variable 'buf' is declared here}}
+ // expected-note at +1{{variable 'buf' is declared here}}
+ RWByteAddressBuffer buf = gBuf0;
switch(v)
{
- case 1: tex = gTex1; break;
- case 2: tex = gTex2; break;
+ // expected-warning at +1{{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
+ case 1: buf = gBuf1; break;
+ // expected-warning at +1{{assignment of 'gBuf2' to local resource 'buf' is not to the same unique global resource}}
+ case 2: buf = gBuf2; break;
}
- return tex.Sample(gSampler, uv);
+ return DoStore(buf, idx * 4, 20);
}
-
-
-//--------------------------------------------------------------
// PASS 21
-// Bindless descriptor indexing
-//--------------------------------------------------------------
-
-float4 Pass_Bindless(uint idx, float2 uv)
+uint Pass_Bindless(uint idx)
{
- Texture2D<float4> tex = gTexArray[idx];
- return tex.Sample(gSampler, uv);
+ RWByteAddressBuffer buf = gBufArray[idx & 3];
+ return DoStore(buf, idx * 4, 21);
}
-
-
-//--------------------------------------------------------------
// PASS 22
-// Resource with wave operations
-//--------------------------------------------------------------
-
-float4 Pass_WaveUse(float2 uv)
+uint Pass_WaveUse(uint idx)
{
- Texture2D<float4> tex = gTex0;
-
- float4 v = tex.Sample(gSampler, uv);
-
+ RWByteAddressBuffer buf = gBuf0;
uint active = WaveActiveCountBits(true);
-
- return v * active;
+ return DoStore(buf, idx * 4, active);
}
-
-
-//--------------------------------------------------------------
// PASS 23
-// Resource alias used inside nested loops
-//--------------------------------------------------------------
-
-float4 Pass_NestedLoops(float2 uv)
-{
- float4 sum = 0;
-
- for(int i=0;i<2;i++)
- for(int j=0;j<2;j++)
- {
- Texture2D<float4> tex = gTexArray[i+j];
- sum += tex.Sample(gSampler, uv);
+uint Pass_NestedLoops(uint idx)
+{
+ uint sum = 0;
+ for(unsigned int i=0;i<2;i++)
+ for(unsigned int j=0;j<2;j++)
+ {
+ RWByteAddressBuffer buf = gBufArray[i+j];
+ sum += DoStore(buf, idx * 4 + (i+j)*4, 23);
}
-
return sum;
}
-
-
-//--------------------------------------------------------------
// PASS 24
-// Resource lifetime across blocks
-//--------------------------------------------------------------
-
-float4 Pass_BlockLifetime(float2 uv)
+uint Pass_BlockLifetime(uint idx)
{
- Texture2D<float4> tex;
-
+ RWByteAddressBuffer buf;
{
- tex = gTex1;
+ buf = gBuf1;
}
-
- return tex.Sample(gSampler, uv);
+ return DoStore(buf, idx * 4, 24);
}
-
-//--------------------------------------------------------------
// PASS 25
-// Deep nested PHI merges
-//--------------------------------------------------------------
-
-float4 Pass_DeepPhi(bool a, bool b, float2 uv)
+uint Pass_DeepPhi(bool a, bool b, uint idx)
{
- Texture2D<float4> tex;
+ RWByteAddressBuffer buf;
if(a)
- {
- if(b)
- tex = gTex0;
- else
- tex = gTex1;
- }
+ // expected-warning at +1{{assignment of 'b ? gBuf0 : gBuf1' to local resource 'buf' is not to the same unique global resource}}
+ buf = b ? gBuf0 : gBuf1;
else
- {
- tex = gTex2;
- }
+ buf = gBuf2;
- return tex.Sample(gSampler, uv);
+ return DoStore(buf, idx * 4, 25);
}
-
-
-//--------------------------------------------------------------
// PASS 26
-// Loop-carried resource value
-//--------------------------------------------------------------
-
-float4 Pass_LoopCarried(int iterations, float2 uv)
+uint Pass_LoopCarried(int iterations, uint idx)
{
- Texture2D<float4> tex = gTex0;
+ // expected-note at +1{{variable 'buf' is declared here}}
+ RWByteAddressBuffer buf = gBuf0;
for(int i=0;i<iterations;i++)
- {
- tex = gTexArray[i & 3];
- }
+ // expected-warning at +1{{assignment of 'gBufArray[i & 3]' to local resource 'buf' is not to the same unique global resource}}
+ buf = gBufArray[i & 3];
- return tex.Sample(gSampler, uv);
+ return DoStore(buf, idx * 4, 26);
}
-
-
-//--------------------------------------------------------------
// PASS 27
-// Resource alias chain
-//--------------------------------------------------------------
-
-float4 Pass_AliasChain(float2 uv)
+uint Pass_AliasChain(uint idx)
{
- Texture2D<float4> a = gTex0;
- Texture2D<float4> b = a;
- Texture2D<float4> c = b;
+ RWByteAddressBuffer a = gBuf0;
+ RWByteAddressBuffer b = a;
+ RWByteAddressBuffer c = b;
- return c.Sample(gSampler, uv);
+ return DoStore(c, idx * 4, 27);
}
-
-
-//--------------------------------------------------------------
// PASS 28
-// Resource inside nested structs
-//--------------------------------------------------------------
-
-struct PassNestedInner
-{
- Texture2D<float4> tex;
-};
-
-struct PassNestedOuter
-{
- PassNestedInner inner;
-};
+struct PassNestedInner { RWByteAddressBuffer buf; };
+struct PassNestedOuter { PassNestedInner inner; };
-float4 Pass_NestedStruct(float2 uv)
+uint Pass_NestedStruct(uint idx)
{
PassNestedOuter s;
-
- s.inner.tex = gTex1;
-
- return s.inner.tex.Sample(gSampler, uv);
+ s.inner.buf = gBuf1;
+ return DoStore(s.inner.buf, idx * 4, 28);
}
-
-
-//--------------------------------------------------------------
// PASS 29
-// Resource forwarded through multiple struct layers
-//--------------------------------------------------------------
-
-struct PassForwardA { Texture2D<float4> tex; };
+struct PassForwardA { RWByteAddressBuffer buf; };
struct PassForwardB { PassForwardA a; };
-float4 Pass_ForwardStructLayers(float2 uv)
+uint Pass_ForwardStructLayers(uint idx)
{
PassForwardB b;
- b.a.tex = gTex2;
-
- return b.a.tex.Sample(gSampler, uv);
+ b.a.buf = gBuf2;
+ return DoStore(b.a.buf, idx * 4, 29);
}
-
-
-//--------------------------------------------------------------
// PASS 30
-// Resource alias inside switch fallthrough
-//--------------------------------------------------------------
-
-float4 Pass_SwitchFallthrough(int v, float2 uv)
+uint Pass_SwitchFallthrough(int v, uint idx)
{
- Texture2D<float4> tex = gTex0;
+ // expected-note at +2{{variable 'buf' is declared here}}
+ // expected-note at +1{{variable 'buf' is declared here}}
+ RWByteAddressBuffer buf = gBuf0;
switch(v)
{
- case 0:
- tex = gTex1;
- case 1:
- tex = gTex2;
- break;
+ // expected-warning at +1{{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
+ case 0: buf = gBuf1;
+ // expected-warning at +1{{assignment of 'gBuf2' to local resource 'buf' is not to the same unique global resource}}
+ case 1: buf = gBuf2; break;
}
- return tex.Sample(gSampler, uv);
+ return DoStore(buf, idx * 4, 30);
}
-
-
-//--------------------------------------------------------------
// PASS 31
-// Resource used after early-return path merge
-//--------------------------------------------------------------
-
-float4 Pass_EarlyReturn(bool cond, float2 uv)
+uint Pass_EarlyReturn(bool cond, uint idx)
{
- Texture2D<float4> tex = gTex0;
+ // expected-note at +1{{variable 'buf' is declared here}}
+ RWByteAddressBuffer buf = gBuf0;
if(cond)
- return tex.Sample(gSampler, uv);
-
- tex = gTex1;
-
- return tex.Sample(gSampler, uv);
+ return DoStore(buf, idx * 4, 31);
+ // expected-warning at +1{{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
+ buf = gBuf1;
+ return DoStore(buf, idx * 4, 31);
}
-
-//--------------------------------------------------------------
// PASS 32
-// Resource alias across nested blocks
-//--------------------------------------------------------------
-
-float4 Pass_NestedBlocks(float2 uv)
+uint Pass_NestedBlocks(uint idx)
{
- Texture2D<float4> tex;
+ // expected-note at +1{{variable 'buf' is declared here}}
+ RWByteAddressBuffer buf;
{
- tex = gTex1;
-
+ buf = gBuf1;
{
- tex = gTex2;
+ // expected-warning at +1{{assignment of 'gBuf2' to local resource 'buf' is not to the same unique global resource}}
+ buf = gBuf2;
}
}
- return tex.Sample(gSampler, uv);
+ return DoStore(buf, idx * 4, 32);
}
-
-
-//--------------------------------------------------------------
// PASS 33
-// Resource assigned via bindless selection
-//--------------------------------------------------------------
-
-float4 Pass_BindlessSelection(uint a, uint b, float2 uv)
+uint Pass_BindlessSelection(uint a, uint b, uint idx)
{
- Texture2D<float4> tex;
+ RWByteAddressBuffer buf;
- tex = gTexArray[a];
- tex = gTexArray[b];
+ buf = gBufArray[a & 3];
+ buf = gBufArray[b & 3];
- return tex.Sample(gSampler, uv);
+ return DoStore(buf, idx * 4, 33);
}
@@ -598,46 +391,46 @@ float4 Pass_BindlessSelection(uint a, uint b, float2 uv)
// ENTRY POINT
//==============================================================
-
[numthreads(8,8,1)]
void main(uint3 tid : SV_DispatchThreadID)
{
- float2 uv = float2(tid.xy)/256.0;
+ uint idx = tid.x + tid.y * 8;
+
+ uint r = 0;
- float4 r = 0;
- r += Pass_TernaryInit(true, uv);
+ r += Pass_TernaryInit(true, idx);
Pass_LoopVar();
- r += Pass_ExpressionInit(uv);
- r += Use_FailSharedStruct(uv);
- r += Pass_StructArray(uv);
- r += Use_Fail_Shared(uv);
- Texture2D<float4> mytex = Fail_ReturnLocal_Uninitialized();
- Texture2D<float4> mytex2 = Fail_ReturnLocal();
- r += Pass_StructArray(uv);
- r += Pass_LocalArray(uv);
- r += Pass_Uninitialized(uv);
- r += Pass_Alias(uv);
- r += Pass_Reassign(uv);
- r += Pass_IfAlias(true,uv);
- r += Pass_Loop(uv);
- r += Pass_Struct(uv);
- r += Pass_FunctionForward(uv);
- r += Pass_PhiMerge(true,uv);
- r += Pass_Shadow(uv);
- r += Pass_Switch(1,uv);
- r += Pass_Bindless(0,uv);
- r += Pass_WaveUse(uv);
- r += Pass_NestedLoops(uv);
- r += Pass_BlockLifetime(uv);
- r += Pass_DeepPhi(true, false, uv);
- r += Pass_LoopCarried(15, uv);
- r += Pass_AliasChain(uv);
- r += Pass_NestedStruct(uv);
- r += Pass_ForwardStructLayers(uv);
- r += Pass_SwitchFallthrough(0, uv);
- r += Pass_EarlyReturn(true, uv);
- r += Pass_NestedBlocks(uv);
- r += Pass_BindlessSelection(2, 3, uv);
-
- gOut[tid.xy] = r;
+ r += Pass_ExpressionInit(idx);
+ r += Use_PassSharedStruct(idx);
+ r += Pass_StructArray(idx);
+ r += Use_Pass_Shared(idx);
+ RWByteAddressBuffer tmp0 = Pass_ReturnLocal_Uninitialized();
+ RWByteAddressBuffer tmp1 = Pass_ReturnLocal();
+ r += Pass_StructArray(idx);
+ r += Pass_LocalArray(idx);
+ r += Pass_Uninitialized(idx);
+ r += Pass_Alias(idx);
+ r += Pass_Reassign(idx);
+ r += Pass_IfAlias(true, idx);
+ r += Pass_Loop(idx);
+ r += Pass_Struct(idx);
+ r += Pass_FunctionForward(idx);
+ r += Pass_PhiMerge(true, idx);
+ r += Pass_Shadow(idx);
+ r += Pass_Switch(1, idx);
+ r += Pass_Bindless(idx);
+ r += Pass_WaveUse(idx);
+ r += Pass_NestedLoops(idx);
+ r += Pass_BlockLifetime(idx);
+ r += Pass_DeepPhi(true, false, idx);
+ r += Pass_LoopCarried(15, idx);
+ r += Pass_AliasChain(idx);
+ r += Pass_NestedStruct(idx);
+ r += Pass_ForwardStructLayers(idx);
+ r += Pass_SwitchFallthrough(0, idx);
+ r += Pass_EarlyReturn(true, idx);
+ r += Pass_NestedBlocks(idx);
+ r += Pass_BindlessSelection(2, 3, idx);
+
+ gOut.Store(idx * 4, r);
}
\ No newline at end of file
>From 9146bb048c6712faeb8113ab2b22051156a7f036 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Mon, 30 Mar 2026 15:00:21 -0700
Subject: [PATCH 03/10] first test, failing
---
.../Local-Resources/use_groupshared.hlsl | 23 +++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared.hlsl
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared.hlsl
new file mode 100644
index 0000000000000..16747acbc19ff
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared.hlsl
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -verify
+
+RWByteAddressBuffer gOut : register(u3);
+
+uint DoStore(RWByteAddressBuffer buf, uint offset, uint value)
+{
+ buf.Store(offset, value);
+ return value;
+}
+
+groupshared RWByteAddressBuffer sharedBuf;
+uint Use_Shared(uint idx)
+{
+ return DoStore(sharedBuf, idx * 4, 1);
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Use_Shared(idx);
+}
\ No newline at end of file
>From 20646667ced7fb1a343b793e6c3b23f4075f7e4d Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Tue, 31 Mar 2026 12:04:50 -0700
Subject: [PATCH 04/10] checkpoint
---
.../ternary_initialization.hlsl | 30 ++
.../Local-Resources/expression_init.hlsl | 28 ++
.../Local-Resources/expression_init.ll | 318 ++++++++++++++++++
.../Resources/Local-Resources/loop_var.hlsl | 23 ++
.../Local-Resources/use_groupshared.hlsl | 12 +-
.../use_struct_groupshared.hlsl | 37 ++
.../Local-Resources/use_struct_groupshared.ll | 255 ++++++++++++++
.../Resources/local_resources_passes.hlsl | 31 --
8 files changed, 701 insertions(+), 33 deletions(-)
create mode 100644 clang/test/CodeGenHLSL/resources/Local-Resources/ternary_initialization.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/expression_init.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/expression_init.ll
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/loop_var.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.ll
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/ternary_initialization.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/ternary_initialization.hlsl
new file mode 100644
index 0000000000000..71da9d8e1af5b
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/ternary_initialization.hlsl
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute -emit-llvm -disable-llvm-passes 2>&1 -o - %s | llvm-cxxfilt | FileCheck %s
+
+// This test fails after verify.
+
+RWByteAddressBuffer gOut : register(u3);
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+uint DoStore(RWByteAddressBuffer buf, uint offset, uint value)
+{
+ buf.Store(offset, value);
+ return value;
+}
+
+uint Pass_TernaryInit(bool cond, uint idx)
+{
+ // DXC emits this warning: local resource not guaranteed to map to unique global resource.
+ // Below is generated by -Whlsl-explicit-binding
+ // CHECK: warning: assignment of 'cond ? gBuf0 : gBuf1' to local resource 'buf' is not to the same unique global resource
+ RWByteAddressBuffer buf = cond ? gBuf0 : gBuf1;
+ return DoStore(buf, idx * 4, 2);
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_TernaryInit(idx < 32, idx);
+}
\ No newline at end of file
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.hlsl
new file mode 100644
index 0000000000000..3480b5f65a82e
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.hlsl
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -verify
+
+// expected-no-diagnostics
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+RWByteAddressBuffer gOut : register(u3);
+
+uint DoStore(RWByteAddressBuffer buf, uint offset, uint value)
+{
+ buf.Store(offset, value);
+ return value;
+}
+
+uint Pass_ExpressionInit(uint idx)
+{
+ RWByteAddressBuffer buf = (true ? gBuf0 : gBuf1);
+ return DoStore(buf, idx * 4, 3);
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_ExpressionInit(idx);
+}
\ No newline at end of file
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.ll b/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.ll
new file mode 100644
index 0000000000000..0ff7f24d7fefe
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.ll
@@ -0,0 +1,318 @@
+; ModuleID = 'D:\llvm-project\clang\test\SemaHLSL\Resources\Local-Resources\expression_init.hlsl'
+source_filename = "D:\\llvm-project\\clang\\test\\SemaHLSL\\Resources\\Local-Resources\\expression_init.hlsl"
+target datalayout = "e-m:e-ve-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64"
+target triple = "dxilv1.6-pc-shadermodel6.6-compute"
+
+%"class.hlsl::RWByteAddressBuffer" = type { target("dx.RawBuffer", i8, 1, 0) }
+
+ at _ZL5gBuf0 = internal global %"class.hlsl::RWByteAddressBuffer" poison, align 4
+ at .str = private unnamed_addr constant [6 x i8] c"gBuf0\00", align 1
+ at _ZL5gBuf1 = internal global %"class.hlsl::RWByteAddressBuffer" poison, align 4
+ at .str.2 = private unnamed_addr constant [6 x i8] c"gBuf1\00", align 1
+ at _ZL4gOut = internal global %"class.hlsl::RWByteAddressBuffer" poison, align 4
+ at .str.4 = private unnamed_addr constant [5 x i8] c"gOut\00", align 1
+
+; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
+define hidden noundef i32 @_Z7DoStoreN4hlsl19RWByteAddressBufferEjj(ptr noundef byval(%"class.hlsl::RWByteAddressBuffer") align 4 %buf, i32 noundef %offset, i32 noundef %value) #0 {
+entry:
+ %this.addr.i = alloca ptr, align 4
+ %Index.addr.i = alloca i32, align 4
+ %Value.addr.i = alloca i32, align 4
+ %offset.addr = alloca i32, align 4
+ %value.addr = alloca i32, align 4
+ store i32 %offset, ptr %offset.addr, align 4
+ store i32 %value, ptr %value.addr, align 4
+ %0 = load i32, ptr %offset.addr, align 4
+ %1 = load i32, ptr %value.addr, align 4
+ store ptr %buf, ptr %this.addr.i, align 4
+ store i32 %0, ptr %Index.addr.i, align 4
+ store i32 %1, ptr %Value.addr.i, align 4
+ %this1.i = load ptr, ptr %this.addr.i, align 4
+ %2 = load i32, ptr %Value.addr.i, align 4
+ %3 = load target("dx.RawBuffer", i8, 1, 0), ptr %this1.i, align 4
+ %4 = load i32, ptr %Index.addr.i, align 4
+ %5 = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i8_1_0t.i32(target("dx.RawBuffer", i8, 1, 0) %3, i32 %4)
+ store i32 %2, ptr %5, align 4
+ %6 = load i32, ptr %value.addr, align 4
+ ret i32 %6
+}
+
+; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
+define hidden noundef i32 @_Z19Pass_ExpressionInitj(i32 noundef %idx) #0 {
+entry:
+ %this.addr.i10 = alloca ptr, align 4
+ %other.addr.i11 = alloca ptr, align 4
+ %this.addr.i7 = alloca ptr, align 4
+ %other.addr.i8 = alloca ptr, align 4
+ %this.addr.i4 = alloca ptr, align 4
+ %other.addr.i5 = alloca ptr, align 4
+ %this.addr.i2 = alloca ptr, align 4
+ %other.addr.i = alloca ptr, align 4
+ %this.addr.i = alloca ptr, align 4
+ %Index.addr.i = alloca i32, align 4
+ %Value.addr.i = alloca i32, align 4
+ %offset.addr.i = alloca i32, align 4
+ %value.addr.i = alloca i32, align 4
+ %agg.tmp1 = alloca %"class.hlsl::RWByteAddressBuffer", align 8
+ %idx.addr = alloca i32, align 4
+ %buf = alloca %"class.hlsl::RWByteAddressBuffer", align 4
+ %agg.tmp = alloca %"class.hlsl::RWByteAddressBuffer", align 4
+ store i32 %idx, ptr %idx.addr, align 4
+ store ptr %buf, ptr %this.addr.i4, align 4
+ store ptr @_ZL5gBuf0, ptr %other.addr.i5, align 4
+ %this1.i6 = load ptr, ptr %this.addr.i4, align 4
+ %0 = load ptr, ptr %other.addr.i5, align 4
+ store ptr %this1.i6, ptr %this.addr.i7, align 4
+ store ptr %0, ptr %other.addr.i8, align 4
+ %this1.i9 = load ptr, ptr %this.addr.i7, align 4
+ %1 = load ptr, ptr %other.addr.i8, align 4, !nonnull !3, !align !4
+ %2 = load target("dx.RawBuffer", i8, 1, 0), ptr %1, align 4
+ store target("dx.RawBuffer", i8, 1, 0) %2, ptr %this1.i9, align 4
+ store ptr %agg.tmp, ptr %this.addr.i2, align 4
+ store ptr %buf, ptr %other.addr.i, align 4
+ %this1.i3 = load ptr, ptr %this.addr.i2, align 4
+ %3 = load ptr, ptr %other.addr.i, align 4
+ store ptr %this1.i3, ptr %this.addr.i10, align 4
+ store ptr %3, ptr %other.addr.i11, align 4
+ %this1.i12 = load ptr, ptr %this.addr.i10, align 4
+ %4 = load ptr, ptr %other.addr.i11, align 4, !nonnull !3, !align !4
+ %5 = load target("dx.RawBuffer", i8, 1, 0), ptr %4, align 4
+ store target("dx.RawBuffer", i8, 1, 0) %5, ptr %this1.i12, align 4
+ %6 = load i32, ptr %idx.addr, align 4
+ %mul = mul i32 %6, 4
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %agg.tmp1, ptr align 4 %agg.tmp, i64 4, i1 false)
+ store i32 %mul, ptr %offset.addr.i, align 4
+ store i32 3, ptr %value.addr.i, align 4
+ %7 = load i32, ptr %offset.addr.i, align 4
+ %8 = load i32, ptr %value.addr.i, align 4
+ store ptr %agg.tmp1, ptr %this.addr.i, align 4
+ store i32 %7, ptr %Index.addr.i, align 4
+ store i32 %8, ptr %Value.addr.i, align 4
+ %this1.i = load ptr, ptr %this.addr.i, align 4
+ %9 = load i32, ptr %Value.addr.i, align 4
+ %10 = load target("dx.RawBuffer", i8, 1, 0), ptr %this1.i, align 4
+ %11 = load i32, ptr %Index.addr.i, align 4
+ %12 = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i8_1_0t.i32(target("dx.RawBuffer", i8, 1, 0) %10, i32 %11)
+ store i32 %9, ptr %12, align 4
+ %13 = load i32, ptr %value.addr.i, align 4
+ ret i32 %13
+}
+
+; Function Attrs: convergent noinline norecurse
+define void @main() #1 {
+entry:
+ %this.addr.i19.i = alloca ptr, align 4
+ %other.addr.i20.i = alloca ptr, align 4
+ %this.addr.i16.i = alloca ptr, align 4
+ %other.addr.i17.i = alloca ptr, align 4
+ %this.addr.i13.i = alloca ptr, align 4
+ %other.addr.i14.i = alloca ptr, align 4
+ %this.addr.i10.i = alloca ptr, align 4
+ %other.addr.i11.i = alloca ptr, align 4
+ %this.addr.i7.i = alloca ptr, align 4
+ %other.addr.i8.i = alloca ptr, align 4
+ %this.addr.i.i4 = alloca ptr, align 4
+ %other.addr.i.i5 = alloca ptr, align 4
+ %registerNo.addr.i.i1.i = alloca i32, align 4
+ %spaceNo.addr.i.i2.i = alloca i32, align 4
+ %range.addr.i.i3.i = alloca i32, align 4
+ %index.addr.i.i4.i = alloca i32, align 4
+ %name.addr.i.i5.i = alloca ptr, align 4
+ %tmp.i.i6.i = alloca %"class.hlsl::RWByteAddressBuffer", align 4
+ %registerNo.addr.i.i.i = alloca i32, align 4
+ %spaceNo.addr.i.i.i = alloca i32, align 4
+ %range.addr.i.i.i = alloca i32, align 4
+ %index.addr.i.i.i = alloca i32, align 4
+ %name.addr.i.i.i = alloca ptr, align 4
+ %tmp.i.i.i = alloca %"class.hlsl::RWByteAddressBuffer", align 4
+ %registerNo.addr.i.i = alloca i32, align 4
+ %spaceNo.addr.i.i = alloca i32, align 4
+ %range.addr.i.i = alloca i32, align 4
+ %index.addr.i.i = alloca i32, align 4
+ %name.addr.i.i = alloca ptr, align 4
+ %tmp.i.i = alloca %"class.hlsl::RWByteAddressBuffer", align 4
+ %this.addr.i1 = alloca ptr, align 4
+ %other.addr.i2 = alloca ptr, align 4
+ %this.addr.i = alloca ptr, align 4
+ %other.addr.i = alloca ptr, align 4
+ %this.addr.i1.i = alloca ptr, align 4
+ %other.addr.i2.i = alloca ptr, align 4
+ %this.addr.i.i = alloca ptr, align 4
+ %other.addr.i.i = alloca ptr, align 4
+ %this.addr.i.i.i = alloca ptr, align 4
+ %Index.addr.i.i.i = alloca i32, align 4
+ %Value.addr.i.i.i = alloca i32, align 4
+ %offset.addr.i.i.i = alloca i32, align 4
+ %value.addr.i.i.i = alloca i32, align 4
+ %agg.tmp1.i.i = alloca %"class.hlsl::RWByteAddressBuffer", align 8
+ %idx.addr.i.i = alloca i32, align 4
+ %buf.i.i = alloca %"class.hlsl::RWByteAddressBuffer", align 4
+ %agg.tmp.i.i = alloca %"class.hlsl::RWByteAddressBuffer", align 4
+ %tid.addr.i = alloca <3 x i32>, align 4
+ %idx.i = alloca i32, align 4
+ call void @llvm.experimental.noalias.scope.decl(metadata !5)
+ store i32 0, ptr %registerNo.addr.i.i, align 4, !noalias !5
+ store i32 0, ptr %spaceNo.addr.i.i, align 4, !noalias !5
+ store i32 1, ptr %range.addr.i.i, align 4, !noalias !5
+ store i32 0, ptr %index.addr.i.i, align 4, !noalias !5
+ store ptr @.str, ptr %name.addr.i.i, align 4, !noalias !5
+ %0 = load i32, ptr %registerNo.addr.i.i, align 4, !noalias !5
+ %1 = load i32, ptr %spaceNo.addr.i.i, align 4, !noalias !5
+ %2 = load i32, ptr %range.addr.i.i, align 4, !noalias !5
+ %3 = load i32, ptr %index.addr.i.i, align 4, !noalias !5
+ %4 = load ptr, ptr %name.addr.i.i, align 4, !noalias !5
+ %5 = call target("dx.RawBuffer", i8, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_1_0t(i32 %1, i32 %0, i32 %2, i32 %3, ptr %4)
+ store target("dx.RawBuffer", i8, 1, 0) %5, ptr %tmp.i.i, align 4, !noalias !5
+ store ptr @_ZL5gBuf0, ptr %this.addr.i10.i, align 4
+ store ptr %tmp.i.i, ptr %other.addr.i11.i, align 4
+ %this1.i12.i = load ptr, ptr %this.addr.i10.i, align 4
+ %6 = load ptr, ptr %other.addr.i11.i, align 4
+ store ptr %this1.i12.i, ptr %this.addr.i13.i, align 4
+ store ptr %6, ptr %other.addr.i14.i, align 4
+ %this1.i15.i = load ptr, ptr %this.addr.i13.i, align 4
+ %7 = load ptr, ptr %other.addr.i14.i, align 4, !nonnull !3, !align !4
+ %8 = load target("dx.RawBuffer", i8, 1, 0), ptr %7, align 4
+ store target("dx.RawBuffer", i8, 1, 0) %8, ptr %this1.i15.i, align 4
+ call void @llvm.experimental.noalias.scope.decl(metadata !8)
+ store i32 1, ptr %registerNo.addr.i.i.i, align 4, !noalias !8
+ store i32 0, ptr %spaceNo.addr.i.i.i, align 4, !noalias !8
+ store i32 1, ptr %range.addr.i.i.i, align 4, !noalias !8
+ store i32 0, ptr %index.addr.i.i.i, align 4, !noalias !8
+ store ptr @.str.2, ptr %name.addr.i.i.i, align 4, !noalias !8
+ %9 = load i32, ptr %registerNo.addr.i.i.i, align 4, !noalias !8
+ %10 = load i32, ptr %spaceNo.addr.i.i.i, align 4, !noalias !8
+ %11 = load i32, ptr %range.addr.i.i.i, align 4, !noalias !8
+ %12 = load i32, ptr %index.addr.i.i.i, align 4, !noalias !8
+ %13 = load ptr, ptr %name.addr.i.i.i, align 4, !noalias !8
+ %14 = call target("dx.RawBuffer", i8, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_1_0t(i32 %10, i32 %9, i32 %11, i32 %12, ptr %13)
+ store target("dx.RawBuffer", i8, 1, 0) %14, ptr %tmp.i.i.i, align 4, !noalias !8
+ store ptr @_ZL5gBuf1, ptr %this.addr.i7.i, align 4
+ store ptr %tmp.i.i.i, ptr %other.addr.i8.i, align 4
+ %this1.i9.i = load ptr, ptr %this.addr.i7.i, align 4
+ %15 = load ptr, ptr %other.addr.i8.i, align 4
+ store ptr %this1.i9.i, ptr %this.addr.i16.i, align 4
+ store ptr %15, ptr %other.addr.i17.i, align 4
+ %this1.i18.i = load ptr, ptr %this.addr.i16.i, align 4
+ %16 = load ptr, ptr %other.addr.i17.i, align 4, !nonnull !3, !align !4
+ %17 = load target("dx.RawBuffer", i8, 1, 0), ptr %16, align 4
+ store target("dx.RawBuffer", i8, 1, 0) %17, ptr %this1.i18.i, align 4
+ call void @llvm.experimental.noalias.scope.decl(metadata !11)
+ store i32 3, ptr %registerNo.addr.i.i1.i, align 4, !noalias !11
+ store i32 0, ptr %spaceNo.addr.i.i2.i, align 4, !noalias !11
+ store i32 1, ptr %range.addr.i.i3.i, align 4, !noalias !11
+ store i32 0, ptr %index.addr.i.i4.i, align 4, !noalias !11
+ store ptr @.str.4, ptr %name.addr.i.i5.i, align 4, !noalias !11
+ %18 = load i32, ptr %registerNo.addr.i.i1.i, align 4, !noalias !11
+ %19 = load i32, ptr %spaceNo.addr.i.i2.i, align 4, !noalias !11
+ %20 = load i32, ptr %range.addr.i.i3.i, align 4, !noalias !11
+ %21 = load i32, ptr %index.addr.i.i4.i, align 4, !noalias !11
+ %22 = load ptr, ptr %name.addr.i.i5.i, align 4, !noalias !11
+ %23 = call target("dx.RawBuffer", i8, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_1_0t(i32 %19, i32 %18, i32 %20, i32 %21, ptr %22)
+ store target("dx.RawBuffer", i8, 1, 0) %23, ptr %tmp.i.i6.i, align 4, !noalias !11
+ store ptr @_ZL4gOut, ptr %this.addr.i.i4, align 4
+ store ptr %tmp.i.i6.i, ptr %other.addr.i.i5, align 4
+ %this1.i.i6 = load ptr, ptr %this.addr.i.i4, align 4
+ %24 = load ptr, ptr %other.addr.i.i5, align 4
+ store ptr %this1.i.i6, ptr %this.addr.i19.i, align 4
+ store ptr %24, ptr %other.addr.i20.i, align 4
+ %this1.i21.i = load ptr, ptr %this.addr.i19.i, align 4
+ %25 = load ptr, ptr %other.addr.i20.i, align 4, !nonnull !3, !align !4
+ %26 = load target("dx.RawBuffer", i8, 1, 0), ptr %25, align 4
+ store target("dx.RawBuffer", i8, 1, 0) %26, ptr %this1.i21.i, align 4
+ %27 = call i32 @llvm.dx.thread.id(i32 0)
+ %28 = insertelement <3 x i32> poison, i32 %27, i64 0
+ %29 = call i32 @llvm.dx.thread.id(i32 1)
+ %30 = insertelement <3 x i32> %28, i32 %29, i64 1
+ %31 = call i32 @llvm.dx.thread.id(i32 2)
+ %32 = insertelement <3 x i32> %30, i32 %31, i64 2
+ store <3 x i32> %32, ptr %tid.addr.i, align 4
+ %33 = load <3 x i32>, ptr %tid.addr.i, align 4
+ %34 = extractelement <3 x i32> %33, i32 0
+ %35 = load <3 x i32>, ptr %tid.addr.i, align 4
+ %36 = extractelement <3 x i32> %35, i32 1
+ %mul.i = mul i32 %36, 8
+ %add.i = add i32 %34, %mul.i
+ store i32 %add.i, ptr %idx.i, align 4
+ %37 = load i32, ptr %idx.i, align 4
+ store i32 %37, ptr %idx.addr.i.i, align 4
+ store ptr %buf.i.i, ptr %this.addr.i1.i, align 4
+ store ptr @_ZL5gBuf0, ptr %other.addr.i2.i, align 4
+ %this1.i3.i = load ptr, ptr %this.addr.i1.i, align 4
+ %38 = load ptr, ptr %other.addr.i2.i, align 4
+ store ptr %this1.i3.i, ptr %this.addr.i1, align 4
+ store ptr %38, ptr %other.addr.i2, align 4
+ %this1.i3 = load ptr, ptr %this.addr.i1, align 4
+ %39 = load ptr, ptr %other.addr.i2, align 4, !nonnull !3, !align !4
+ %40 = load target("dx.RawBuffer", i8, 1, 0), ptr %39, align 4
+ store target("dx.RawBuffer", i8, 1, 0) %40, ptr %this1.i3, align 4
+ store ptr %agg.tmp.i.i, ptr %this.addr.i.i, align 4
+ store ptr %buf.i.i, ptr %other.addr.i.i, align 4
+ %this1.i.i = load ptr, ptr %this.addr.i.i, align 4
+ %41 = load ptr, ptr %other.addr.i.i, align 4
+ store ptr %this1.i.i, ptr %this.addr.i, align 4
+ store ptr %41, ptr %other.addr.i, align 4
+ %this1.i = load ptr, ptr %this.addr.i, align 4
+ %42 = load ptr, ptr %other.addr.i, align 4, !nonnull !3, !align !4
+ %43 = load target("dx.RawBuffer", i8, 1, 0), ptr %42, align 4
+ store target("dx.RawBuffer", i8, 1, 0) %43, ptr %this1.i, align 4
+ %44 = load i32, ptr %idx.addr.i.i, align 4
+ %mul.i.i = mul i32 %44, 4
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %agg.tmp1.i.i, ptr align 4 %agg.tmp.i.i, i64 4, i1 false)
+ store i32 %mul.i.i, ptr %offset.addr.i.i.i, align 4
+ store i32 3, ptr %value.addr.i.i.i, align 4
+ %45 = load i32, ptr %offset.addr.i.i.i, align 4
+ %46 = load i32, ptr %value.addr.i.i.i, align 4
+ store ptr %agg.tmp1.i.i, ptr %this.addr.i.i.i, align 4
+ store i32 %45, ptr %Index.addr.i.i.i, align 4
+ store i32 %46, ptr %Value.addr.i.i.i, align 4
+ %this1.i.i.i = load ptr, ptr %this.addr.i.i.i, align 4
+ %47 = load i32, ptr %Value.addr.i.i.i, align 4
+ %48 = load target("dx.RawBuffer", i8, 1, 0), ptr %this1.i.i.i, align 4
+ %49 = load i32, ptr %Index.addr.i.i.i, align 4
+ %50 = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i8_1_0t.i32(target("dx.RawBuffer", i8, 1, 0) %48, i32 %49)
+ store i32 %47, ptr %50, align 4
+ %51 = load i32, ptr %value.addr.i.i.i, align 4
+ ret void
+}
+
+; Function Attrs: nounwind willreturn memory(none)
+declare i32 @llvm.dx.thread.id(i32) #2
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
+declare target("dx.RawBuffer", i8, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_1_0t(i32, i32, i32, i32, ptr) #3
+
+; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none)
+declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i8_1_0t.i32(target("dx.RawBuffer", i8, 1, 0), i32) #4
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
+declare void @llvm.experimental.noalias.scope.decl(metadata) #5
+
+; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
+declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #6
+
+attributes #0 = { alwaysinline convergent mustprogress norecurse nounwind "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #1 = { convergent noinline norecurse "hlsl.numthreads"="8,8,1" "hlsl.shader"="compute" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #2 = { nounwind willreturn memory(none) }
+attributes #3 = { nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #4 = { convergent nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #5 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
+attributes #6 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
+
+!dx.valver = !{!0}
+!llvm.module.flags = !{!1}
+!llvm.ident = !{!2}
+
+!0 = !{i32 1, i32 8}
+!1 = !{i32 4, !"dx.disable_optimizations", i32 1}
+!2 = !{!"clang version 23.0.0git (https://github.com/llvm/llvm-project.git b084fa7a5172e2502324f9df2723e22dad071e3a)"}
+!3 = !{}
+!4 = !{i64 4}
+!5 = !{!6}
+!6 = distinct !{!6, !7, !"_ZN4hlsl19RWByteAddressBuffer19__createFromBindingEjjijPKc: %agg.result"}
+!7 = distinct !{!7, !"_ZN4hlsl19RWByteAddressBuffer19__createFromBindingEjjijPKc"}
+!8 = !{!9}
+!9 = distinct !{!9, !10, !"_ZN4hlsl19RWByteAddressBuffer19__createFromBindingEjjijPKc: %agg.result"}
+!10 = distinct !{!10, !"_ZN4hlsl19RWByteAddressBuffer19__createFromBindingEjjijPKc"}
+!11 = !{!12}
+!12 = distinct !{!12, !13, !"_ZN4hlsl19RWByteAddressBuffer19__createFromBindingEjjijPKc: %agg.result"}
+!13 = distinct !{!13, !"_ZN4hlsl19RWByteAddressBuffer19__createFromBindingEjjijPKc"}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/loop_var.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/loop_var.hlsl
new file mode 100644
index 0000000000000..71d1a1b4302b0
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/loop_var.hlsl
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -verify
+
+// expected-no-diagnostics
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+RWByteAddressBuffer gOut : register(u3);
+
+void Pass_LoopVar()
+{
+ for(RWByteAddressBuffer buf = gBuf0; false == false; )
+ {
+ buf.Store(0, 0);
+ break;
+ }
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ Pass_LoopVar();
+}
\ No newline at end of file
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared.hlsl
index 16747acbc19ff..1c6d0f9e35f0a 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared.hlsl
@@ -1,17 +1,25 @@
// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -verify
+// This test fails validation in DXC, but DXC's sema allows it.
+// Meanwhile, groupshared is immediately detected and rejected in clang's sema.
+
RWByteAddressBuffer gOut : register(u3);
+// expected-note at +1{{passing argument to parameter 'buf' here}}
uint DoStore(RWByteAddressBuffer buf, uint offset, uint value)
{
buf.Store(offset, value);
return value;
}
+// expected-note@*:*{{candidate constructor not viable: cannot bind reference in address space 'groupshared' to object in generic address space in 1st argument}}
+// expected-note@*:*{{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
+
groupshared RWByteAddressBuffer sharedBuf;
uint Use_Shared(uint idx)
{
+ // expected-error at +1{{no matching constructor for initialization of 'RWByteAddressBuffer'}}
return DoStore(sharedBuf, idx * 4, 1);
}
@@ -19,5 +27,5 @@ uint Use_Shared(uint idx)
void main(uint3 tid : SV_DispatchThreadID)
{
uint idx = tid.x + tid.y * 8;
- Use_Shared(idx);
-}
\ No newline at end of file
+ Use_Shared(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.hlsl
new file mode 100644
index 0000000000000..3f47ae6db82c6
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.hlsl
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -verify
+
+// This test fails validation in DXC, but DXC's sema allows it.
+// Meanwhile, it is for some reason accepted by clang's sema.
+// TODO: Why does this pass clang's sema, but use_groupshared.hlsl fails clang's sema?
+// Run a git bisect on https://github.com/llvm/llvm-project/issues/158107, and figure
+// out which commit seemed to resolve this issue.
+
+RWByteAddressBuffer gOut : register(u3);
+
+// expected-note at +1{{passing argument to parameter 'buf' here}}
+uint DoStore(RWByteAddressBuffer buf, uint offset, uint value)
+{
+ buf.Store(offset, value);
+ return value;
+}
+
+// expected-note@*:*{{candidate constructor not viable: cannot bind reference in address space 'groupshared' to object in generic address space in 1st argument}}
+// expected-note@*:*{{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
+
+struct PassBufStruct { RWByteAddressBuffer buf; };
+
+groupshared PassBufStruct sharedStruct;
+
+uint Use_PassSharedStruct(uint idx)
+{
+ // expected-error at +1{{no matching constructor for initialization of 'RWByteAddressBuffer'}}
+ return DoStore(sharedStruct.buf, idx * 4, 1);
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Use_PassSharedStruct(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.ll b/clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.ll
new file mode 100644
index 0000000000000..b84ac5379905c
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.ll
@@ -0,0 +1,255 @@
+; ModuleID = 'D:\llvm-project\clang\test\SemaHLSL\Resources\Local-Resources\use_struct_groupshared.hlsl'
+source_filename = "D:\\llvm-project\\clang\\test\\SemaHLSL\\Resources\\Local-Resources\\use_struct_groupshared.hlsl"
+target datalayout = "e-m:e-ve-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64"
+target triple = "dxilv1.6-pc-shadermodel6.6-compute"
+
+%"class.hlsl::RWByteAddressBuffer" = type { target("dx.RawBuffer", i8, 1, 0) }
+%struct.PassBufStruct = type { %"class.hlsl::RWByteAddressBuffer" }
+
+ at _ZL4gOut = internal global %"class.hlsl::RWByteAddressBuffer" poison, align 4
+ at .str = private unnamed_addr constant [5 x i8] c"gOut\00", align 1
+ at _ZL16sharedStruct.buf = internal global %"class.hlsl::RWByteAddressBuffer" poison, align 4
+ at .str.2 = private unnamed_addr constant [17 x i8] c"sharedStruct.buf\00", align 1
+ at sharedStruct = external hidden addrspace(3) global %struct.PassBufStruct, align 4
+
+; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
+define hidden noundef i32 @_Z7DoStoreN4hlsl19RWByteAddressBufferEjj(ptr noundef byval(%"class.hlsl::RWByteAddressBuffer") align 4 %buf, i32 noundef %offset, i32 noundef %value) #0 {
+entry:
+ %this.addr.i = alloca ptr, align 4
+ %Index.addr.i = alloca i32, align 4
+ %Value.addr.i = alloca i32, align 4
+ %offset.addr = alloca i32, align 4
+ %value.addr = alloca i32, align 4
+ store i32 %offset, ptr %offset.addr, align 4
+ store i32 %value, ptr %value.addr, align 4
+ %0 = load i32, ptr %offset.addr, align 4
+ %1 = load i32, ptr %value.addr, align 4
+ store ptr %buf, ptr %this.addr.i, align 4
+ store i32 %0, ptr %Index.addr.i, align 4
+ store i32 %1, ptr %Value.addr.i, align 4
+ %this1.i = load ptr, ptr %this.addr.i, align 4
+ %2 = load i32, ptr %Value.addr.i, align 4
+ %3 = load target("dx.RawBuffer", i8, 1, 0), ptr %this1.i, align 4
+ %4 = load i32, ptr %Index.addr.i, align 4
+ %5 = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i8_1_0t.i32(target("dx.RawBuffer", i8, 1, 0) %3, i32 %4)
+ store i32 %2, ptr %5, align 4
+ %6 = load i32, ptr %value.addr, align 4
+ ret i32 %6
+}
+
+; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
+define hidden noundef i32 @_Z20Use_PassSharedStructj(i32 noundef %idx) #0 {
+entry:
+ %this.addr.i4 = alloca ptr, align 4
+ %other.addr.i5 = alloca ptr, align 4
+ %this.addr.i2 = alloca ptr, align 4
+ %other.addr.i = alloca ptr, align 4
+ %this.addr.i = alloca ptr, align 4
+ %Index.addr.i = alloca i32, align 4
+ %Value.addr.i = alloca i32, align 4
+ %offset.addr.i = alloca i32, align 4
+ %value.addr.i = alloca i32, align 4
+ %agg.tmp1 = alloca %"class.hlsl::RWByteAddressBuffer", align 8
+ %idx.addr = alloca i32, align 4
+ %agg.tmp = alloca %"class.hlsl::RWByteAddressBuffer", align 4
+ store i32 %idx, ptr %idx.addr, align 4
+ store ptr %agg.tmp, ptr %this.addr.i2, align 4
+ store ptr addrspacecast (ptr addrspace(3) @sharedStruct to ptr), ptr %other.addr.i, align 4
+ %this1.i3 = load ptr, ptr %this.addr.i2, align 4
+ %0 = load ptr, ptr %other.addr.i, align 4
+ store ptr %this1.i3, ptr %this.addr.i4, align 4
+ store ptr %0, ptr %other.addr.i5, align 4
+ %this1.i6 = load ptr, ptr %this.addr.i4, align 4
+ %1 = load ptr, ptr %other.addr.i5, align 4, !nonnull !3, !align !4
+ %2 = load target("dx.RawBuffer", i8, 1, 0), ptr %1, align 4
+ store target("dx.RawBuffer", i8, 1, 0) %2, ptr %this1.i6, align 4
+ %3 = load i32, ptr %idx.addr, align 4
+ %mul = mul i32 %3, 4
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %agg.tmp1, ptr align 4 %agg.tmp, i64 4, i1 false)
+ store i32 %mul, ptr %offset.addr.i, align 4
+ store i32 1, ptr %value.addr.i, align 4
+ %4 = load i32, ptr %offset.addr.i, align 4
+ %5 = load i32, ptr %value.addr.i, align 4
+ store ptr %agg.tmp1, ptr %this.addr.i, align 4
+ store i32 %4, ptr %Index.addr.i, align 4
+ store i32 %5, ptr %Value.addr.i, align 4
+ %this1.i = load ptr, ptr %this.addr.i, align 4
+ %6 = load i32, ptr %Value.addr.i, align 4
+ %7 = load target("dx.RawBuffer", i8, 1, 0), ptr %this1.i, align 4
+ %8 = load i32, ptr %Index.addr.i, align 4
+ %9 = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i8_1_0t.i32(target("dx.RawBuffer", i8, 1, 0) %7, i32 %8)
+ store i32 %6, ptr %9, align 4
+ %10 = load i32, ptr %value.addr.i, align 4
+ ret i32 %10
+}
+
+; Function Attrs: convergent noinline norecurse
+define void @main() #1 {
+entry:
+ %this.addr.i12.i = alloca ptr, align 4
+ %other.addr.i13.i = alloca ptr, align 4
+ %this.addr.i9.i = alloca ptr, align 4
+ %other.addr.i10.i = alloca ptr, align 4
+ %this.addr.i6.i = alloca ptr, align 4
+ %other.addr.i7.i = alloca ptr, align 4
+ %this.addr.i.i1 = alloca ptr, align 4
+ %other.addr.i.i2 = alloca ptr, align 4
+ %orderId.addr.i.i = alloca i32, align 4
+ %spaceNo.addr.i1.i = alloca i32, align 4
+ %range.addr.i2.i = alloca i32, align 4
+ %index.addr.i3.i = alloca i32, align 4
+ %name.addr.i4.i = alloca ptr, align 4
+ %tmp.i5.i = alloca %"class.hlsl::RWByteAddressBuffer", align 4
+ %registerNo.addr.i.i = alloca i32, align 4
+ %spaceNo.addr.i.i = alloca i32, align 4
+ %range.addr.i.i = alloca i32, align 4
+ %index.addr.i.i = alloca i32, align 4
+ %name.addr.i.i = alloca ptr, align 4
+ %tmp.i.i = alloca %"class.hlsl::RWByteAddressBuffer", align 4
+ %this.addr.i = alloca ptr, align 4
+ %other.addr.i = alloca ptr, align 4
+ %this.addr.i.i = alloca ptr, align 4
+ %other.addr.i.i = alloca ptr, align 4
+ %this.addr.i.i.i = alloca ptr, align 4
+ %Index.addr.i.i.i = alloca i32, align 4
+ %Value.addr.i.i.i = alloca i32, align 4
+ %offset.addr.i.i.i = alloca i32, align 4
+ %value.addr.i.i.i = alloca i32, align 4
+ %agg.tmp1.i.i = alloca %"class.hlsl::RWByteAddressBuffer", align 8
+ %idx.addr.i.i = alloca i32, align 4
+ %agg.tmp.i.i = alloca %"class.hlsl::RWByteAddressBuffer", align 4
+ %tid.addr.i = alloca <3 x i32>, align 4
+ %idx.i = alloca i32, align 4
+ call void @llvm.experimental.noalias.scope.decl(metadata !5)
+ store i32 3, ptr %registerNo.addr.i.i, align 4, !noalias !5
+ store i32 0, ptr %spaceNo.addr.i.i, align 4, !noalias !5
+ store i32 1, ptr %range.addr.i.i, align 4, !noalias !5
+ store i32 0, ptr %index.addr.i.i, align 4, !noalias !5
+ store ptr @.str, ptr %name.addr.i.i, align 4, !noalias !5
+ %0 = load i32, ptr %registerNo.addr.i.i, align 4, !noalias !5
+ %1 = load i32, ptr %spaceNo.addr.i.i, align 4, !noalias !5
+ %2 = load i32, ptr %range.addr.i.i, align 4, !noalias !5
+ %3 = load i32, ptr %index.addr.i.i, align 4, !noalias !5
+ %4 = load ptr, ptr %name.addr.i.i, align 4, !noalias !5
+ %5 = call target("dx.RawBuffer", i8, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_1_0t(i32 %1, i32 %0, i32 %2, i32 %3, ptr %4)
+ store target("dx.RawBuffer", i8, 1, 0) %5, ptr %tmp.i.i, align 4, !noalias !5
+ store ptr @_ZL4gOut, ptr %this.addr.i6.i, align 4
+ store ptr %tmp.i.i, ptr %other.addr.i7.i, align 4
+ %this1.i8.i = load ptr, ptr %this.addr.i6.i, align 4
+ %6 = load ptr, ptr %other.addr.i7.i, align 4
+ store ptr %this1.i8.i, ptr %this.addr.i9.i, align 4
+ store ptr %6, ptr %other.addr.i10.i, align 4
+ %this1.i11.i = load ptr, ptr %this.addr.i9.i, align 4
+ %7 = load ptr, ptr %other.addr.i10.i, align 4, !nonnull !3, !align !4
+ %8 = load target("dx.RawBuffer", i8, 1, 0), ptr %7, align 4
+ store target("dx.RawBuffer", i8, 1, 0) %8, ptr %this1.i11.i, align 4
+ call void @llvm.experimental.noalias.scope.decl(metadata !8)
+ store i32 0, ptr %orderId.addr.i.i, align 4, !noalias !8
+ store i32 0, ptr %spaceNo.addr.i1.i, align 4, !noalias !8
+ store i32 1, ptr %range.addr.i2.i, align 4, !noalias !8
+ store i32 0, ptr %index.addr.i3.i, align 4, !noalias !8
+ store ptr @.str.2, ptr %name.addr.i4.i, align 4, !noalias !8
+ %9 = load i32, ptr %orderId.addr.i.i, align 4, !noalias !8
+ %10 = load i32, ptr %spaceNo.addr.i1.i, align 4, !noalias !8
+ %11 = load i32, ptr %range.addr.i2.i, align 4, !noalias !8
+ %12 = load i32, ptr %index.addr.i3.i, align 4, !noalias !8
+ %13 = load ptr, ptr %name.addr.i4.i, align 4, !noalias !8
+ %14 = call target("dx.RawBuffer", i8, 1, 0) @llvm.dx.resource.handlefromimplicitbinding.tdx.RawBuffer_i8_1_0t(i32 %9, i32 %10, i32 %11, i32 %12, ptr %13)
+ store target("dx.RawBuffer", i8, 1, 0) %14, ptr %tmp.i5.i, align 4, !noalias !8
+ store ptr @_ZL16sharedStruct.buf, ptr %this.addr.i.i1, align 4
+ store ptr %tmp.i5.i, ptr %other.addr.i.i2, align 4
+ %this1.i.i3 = load ptr, ptr %this.addr.i.i1, align 4
+ %15 = load ptr, ptr %other.addr.i.i2, align 4
+ store ptr %this1.i.i3, ptr %this.addr.i12.i, align 4
+ store ptr %15, ptr %other.addr.i13.i, align 4
+ %this1.i14.i = load ptr, ptr %this.addr.i12.i, align 4
+ %16 = load ptr, ptr %other.addr.i13.i, align 4, !nonnull !3, !align !4
+ %17 = load target("dx.RawBuffer", i8, 1, 0), ptr %16, align 4
+ store target("dx.RawBuffer", i8, 1, 0) %17, ptr %this1.i14.i, align 4
+ %18 = call i32 @llvm.dx.thread.id(i32 0)
+ %19 = insertelement <3 x i32> poison, i32 %18, i64 0
+ %20 = call i32 @llvm.dx.thread.id(i32 1)
+ %21 = insertelement <3 x i32> %19, i32 %20, i64 1
+ %22 = call i32 @llvm.dx.thread.id(i32 2)
+ %23 = insertelement <3 x i32> %21, i32 %22, i64 2
+ store <3 x i32> %23, ptr %tid.addr.i, align 4
+ %24 = load <3 x i32>, ptr %tid.addr.i, align 4
+ %25 = extractelement <3 x i32> %24, i32 0
+ %26 = load <3 x i32>, ptr %tid.addr.i, align 4
+ %27 = extractelement <3 x i32> %26, i32 1
+ %mul.i = mul i32 %27, 8
+ %add.i = add i32 %25, %mul.i
+ store i32 %add.i, ptr %idx.i, align 4
+ %28 = load i32, ptr %idx.i, align 4
+ store i32 %28, ptr %idx.addr.i.i, align 4
+ store ptr %agg.tmp.i.i, ptr %this.addr.i.i, align 4
+ store ptr addrspacecast (ptr addrspace(3) @sharedStruct to ptr), ptr %other.addr.i.i, align 4
+ %this1.i.i = load ptr, ptr %this.addr.i.i, align 4
+ %29 = load ptr, ptr %other.addr.i.i, align 4
+ store ptr %this1.i.i, ptr %this.addr.i, align 4
+ store ptr %29, ptr %other.addr.i, align 4
+ %this1.i = load ptr, ptr %this.addr.i, align 4
+ %30 = load ptr, ptr %other.addr.i, align 4, !nonnull !3, !align !4
+ %31 = load target("dx.RawBuffer", i8, 1, 0), ptr %30, align 4
+ store target("dx.RawBuffer", i8, 1, 0) %31, ptr %this1.i, align 4
+ %32 = load i32, ptr %idx.addr.i.i, align 4
+ %mul.i.i = mul i32 %32, 4
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %agg.tmp1.i.i, ptr align 4 %agg.tmp.i.i, i64 4, i1 false)
+ store i32 %mul.i.i, ptr %offset.addr.i.i.i, align 4
+ store i32 1, ptr %value.addr.i.i.i, align 4
+ %33 = load i32, ptr %offset.addr.i.i.i, align 4
+ %34 = load i32, ptr %value.addr.i.i.i, align 4
+ store ptr %agg.tmp1.i.i, ptr %this.addr.i.i.i, align 4
+ store i32 %33, ptr %Index.addr.i.i.i, align 4
+ store i32 %34, ptr %Value.addr.i.i.i, align 4
+ %this1.i.i.i = load ptr, ptr %this.addr.i.i.i, align 4
+ %35 = load i32, ptr %Value.addr.i.i.i, align 4
+ %36 = load target("dx.RawBuffer", i8, 1, 0), ptr %this1.i.i.i, align 4
+ %37 = load i32, ptr %Index.addr.i.i.i, align 4
+ %38 = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i8_1_0t.i32(target("dx.RawBuffer", i8, 1, 0) %36, i32 %37)
+ store i32 %35, ptr %38, align 4
+ %39 = load i32, ptr %value.addr.i.i.i, align 4
+ ret void
+}
+
+; Function Attrs: nounwind willreturn memory(none)
+declare i32 @llvm.dx.thread.id(i32) #2
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
+declare target("dx.RawBuffer", i8, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_1_0t(i32, i32, i32, i32, ptr) #3
+
+; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none)
+declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i8_1_0t.i32(target("dx.RawBuffer", i8, 1, 0), i32) #4
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
+declare target("dx.RawBuffer", i8, 1, 0) @llvm.dx.resource.handlefromimplicitbinding.tdx.RawBuffer_i8_1_0t(i32, i32, i32, i32, ptr) #3
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
+declare void @llvm.experimental.noalias.scope.decl(metadata) #5
+
+; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
+declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #6
+
+attributes #0 = { alwaysinline convergent mustprogress norecurse nounwind "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #1 = { convergent noinline norecurse "hlsl.numthreads"="8,8,1" "hlsl.shader"="compute" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #2 = { nounwind willreturn memory(none) }
+attributes #3 = { nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #4 = { convergent nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #5 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
+attributes #6 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
+
+!dx.valver = !{!0}
+!llvm.module.flags = !{!1}
+!llvm.ident = !{!2}
+
+!0 = !{i32 1, i32 8}
+!1 = !{i32 4, !"dx.disable_optimizations", i32 1}
+!2 = !{!"clang version 23.0.0git (https://github.com/llvm/llvm-project.git b084fa7a5172e2502324f9df2723e22dad071e3a)"}
+!3 = !{}
+!4 = !{i64 4}
+!5 = !{!6}
+!6 = distinct !{!6, !7, !"_ZN4hlsl19RWByteAddressBuffer19__createFromBindingEjjijPKc: %agg.result"}
+!7 = distinct !{!7, !"_ZN4hlsl19RWByteAddressBuffer19__createFromBindingEjjijPKc"}
+!8 = !{!9}
+!9 = distinct !{!9, !10, !"_ZN4hlsl19RWByteAddressBuffer27__createFromImplicitBindingEjjijPKc: %agg.result"}
+!10 = distinct !{!10, !"_ZN4hlsl19RWByteAddressBuffer27__createFromImplicitBindingEjjijPKc"}
diff --git a/clang/test/SemaHLSL/Resources/local_resources_passes.hlsl b/clang/test/SemaHLSL/Resources/local_resources_passes.hlsl
index b44e9ff8896dc..d97a03580242c 100644
--- a/clang/test/SemaHLSL/Resources/local_resources_passes.hlsl
+++ b/clang/test/SemaHLSL/Resources/local_resources_passes.hlsl
@@ -29,37 +29,6 @@ uint DoStore(RWByteAddressBuffer buf, uint offset, uint value)
// PASS TESTS
//==============================================================
-// PASS 0
-groupshared RWByteAddressBuffer sharedBuf;
-
-uint Use_Shared(uint idx)
-{
- return DoStore(gBuf0, idx * 4, 1);
-}
-
-// PASS 1
-uint Pass_TernaryInit(bool cond, uint idx)
-{
- // expected-warning at +1{{assignment of 'cond ? gBuf0 : gBuf1' to local resource 'buf' is not to the same unique global resource}}
- RWByteAddressBuffer buf = cond ? gBuf0 : gBuf1;
- return DoStore(buf, idx * 4, 2);
-}
-
-// PASS 2
-void Pass_LoopVar()
-{
- for(RWByteAddressBuffer buf = gBuf0; false;)
- {
- }
-}
-
-// PASS 3
-uint Pass_ExpressionInit(uint idx)
-{
- RWByteAddressBuffer buf = (true ? gBuf0 : gBuf1);
- return DoStore(buf, idx * 4, 3);
-}
-
// PASS 4
struct PassBufStruct { RWByteAddressBuffer buf; };
>From 0c9208057d11de3cf408df6f9c88a41440076cb3 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Thu, 2 Apr 2026 17:40:50 -0700
Subject: [PATCH 05/10] quite comprehensive
---
.../local_resource_break_reassign.hlsl | 27 ++
.../local_resource_conditional_init.hlsl | 24 ++
.../local_resource_default_init_store.hlsl | 20 +
.../local_resource_nested_ternary.hlsl | 27 ++
.../local_resource_phi_merge_ternary.hlsl | 31 ++
.../local_resource_ternary_as_argument.hlsl | 27 ++
.../local_resource_ternary_assign.hlsl | 31 ++
.../local_resource_wave_uniform.hlsl | 34 ++
.../ternary_initialization.hlsl | 10 +-
.../Resources/Local-Resources/Readme.md | 187 ++++++++
.../Local-Resources/expression_init.hlsl | 12 +-
.../Local-Resources/expression_init.ll | 318 --------------
.../forward_struct_layers_resource.hlsl | 25 ++
.../local_resource_addition.hlsl | 22 +
.../local_resource_aggregate_init.hlsl | 20 +
.../local_resource_alias_chain.hlsl | 25 ++
.../local_resource_alias_global.hlsl | 21 +
.../local_resource_arithmetic.hlsl | 26 ++
.../Local-Resources/local_resource_array.hlsl | 22 +
.../local_resource_array_copy.hlsl | 20 +
.../local_resource_array_dynamic_index.hlsl | 19 +
.../local_resource_array_oob.hlsl | 20 +
.../local_resource_array_partial_init.hlsl | 20 +
...resource_as_structured_buffer_element.hlsl | 24 ++
.../local_resource_assign_wrong_type.hlsl | 20 +
.../local_resource_bindless_array.hlsl | 21 +
.../local_resource_bindless_selection.hlsl | 26 ++
.../local_resource_block_lifetime.hlsl | 24 ++
...local_resource_cast_sampler_to_buffer.hlsl | 26 ++
.../local_resource_cast_to_uint.hlsl | 22 +
.../local_resource_compare.hlsl | 24 ++
.../local_resource_const_param.hlsl | 23 +
.../local_resource_const_reassign.hlsl | 22 +
.../local_resource_copy_between_locals.hlsl | 18 +
.../local_resource_deep_phi.hlsl | 34 ++
.../local_resource_default_param.hlsl | 23 +
.../local_resource_different_types.hlsl | 21 +
.../local_resource_do_while_reassign.hlsl | 24 ++
.../local_resource_early_return_reassign.hlsl | 33 ++
...al_resource_forward_through_functions.hlsl | 30 ++
.../local_resource_from_function_return.hlsl | 23 +
.../local_resource_inout_param.hlsl | 22 +
.../local_resource_loop_array_index.hlsl | 26 ++
.../local_resource_loop_carried.hlsl | 32 ++
.../local_resource_mixed_struct.hlsl | 25 ++
.../local_resource_multiple_uses.hlsl | 29 ++
...local_resource_nested_blocks_reassign.hlsl | 36 ++
.../local_resource_nested_loops.hlsl | 27 ++
.../local_resource_out_param.hlsl | 23 +
...al_resource_reassign_different_global.hlsl | 27 ++
.../local_resource_self_assign.hlsl | 18 +
.../local_resource_shadow_inner_scope.hlsl | 25 ++
.../local_resource_static_local.hlsl | 26 ++
.../local_resource_struct_return.hlsl | 26 ++
.../local_resource_switch_fallthrough.hlsl | 39 ++
.../local_resource_switch_reassign.hlsl | 39 ++
.../local_resource_to_bool.hlsl | 23 +
.../local_resource_unreachable_reassign.hlsl | 25 ++
.../local_resource_volatile.hlsl | 19 +
.../local_resource_with_wave_intrinsic.hlsl | 22 +
.../local_struct_resource_member.hlsl | 27 ++
.../Resources/Local-Resources/loop_var.hlsl | 2 +-
.../nested_struct_resource_member.hlsl | 25 ++
.../return_local_resource_initialized.hlsl | 18 +
.../return_local_resource_uninitialized.hlsl | 16 +
.../struct_array_with_resource_member.hlsl | 24 ++
.../struct_resource_member_reassign.hlsl | 25 ++
.../struct_with_resource_array_member.hlsl | 24 ++
.../Local-Resources/use_groupshared.hlsl | 2 +-
.../use_groupshared_direct_store.hlsl | 28 ++
.../use_local_resource_uninitialized.hlsl | 19 +
.../use_struct_groupshared.hlsl | 2 +-
.../Local-Resources/use_struct_groupshared.ll | 255 -----------
.../Resources/local_resources_failures.hlsl | 175 --------
.../Resources/local_resources_passes.hlsl | 405 ------------------
75 files changed, 1811 insertions(+), 1171 deletions(-)
create mode 100644 clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_break_reassign.hlsl
create mode 100644 clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_conditional_init.hlsl
create mode 100644 clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_default_init_store.hlsl
create mode 100644 clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_nested_ternary.hlsl
create mode 100644 clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_phi_merge_ternary.hlsl
create mode 100644 clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_as_argument.hlsl
create mode 100644 clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_assign.hlsl
create mode 100644 clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_wave_uniform.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/Readme.md
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/expression_init.ll
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/forward_struct_layers_resource.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_addition.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_aggregate_init.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_chain.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_global.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_arithmetic.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_copy.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_dynamic_index.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_oob.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_partial_init.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_as_structured_buffer_element.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_assign_wrong_type.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_array.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_selection.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_block_lifetime.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_cast_sampler_to_buffer.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_cast_to_uint.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_compare.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_const_param.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_const_reassign.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_copy_between_locals.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_deep_phi.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_param.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_different_types.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_do_while_reassign.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_early_return_reassign.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_forward_through_functions.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_from_function_return.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_inout_param.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_array_index.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_carried.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_mixed_struct.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multiple_uses.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_blocks_reassign.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_loops.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_out_param.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_reassign_different_global.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_self_assign.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_shadow_inner_scope.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_local.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_return.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_fallthrough.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_reassign.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_to_bool.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_unreachable_reassign.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_volatile.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_with_wave_intrinsic.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_struct_resource_member.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/nested_struct_resource_member.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_initialized.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_uninitialized.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/struct_array_with_resource_member.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/struct_resource_member_reassign.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/struct_with_resource_array_member.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared_direct_store.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/use_local_resource_uninitialized.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.ll
delete mode 100644 clang/test/SemaHLSL/Resources/local_resources_failures.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/local_resources_passes.hlsl
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_break_reassign.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_break_reassign.hlsl
new file mode 100644
index 0000000000000..f6a49ba96e3f8
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_break_reassign.hlsl
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes \
+// RUN: -o - 2>&1 | llvm-cxxfilt | FileCheck %s
+
+// Test that resource reassignment before a break in a loop triggers a
+// warning in clang but still produces valid IR.
+//
+// DXC: passes sema but fails codegen with:
+// "local resource not guaranteed to map to unique global resource."
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer buf = gBuf0;
+ for(uint i = 0; i < 4; i++) {
+ if(i == tid.x) break;
+ buf = gBuf1;
+ }
+ buf.Store(tid.x * 4, 42);
+}
+
+// CHECK: warning: assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource
+// CHECK: define {{.*}} @main(
+// CHECK-NOT: error:
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_conditional_init.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_conditional_init.hlsl
new file mode 100644
index 0000000000000..214ce9e64ed0d
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_conditional_init.hlsl
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes \
+// RUN: -o - 2>&1 | llvm-cxxfilt | FileCheck %s
+
+// Test that a resource declared without initialization and only assigned
+// in one branch produces valid IR in clang.
+//
+// DXC: passes sema but fails codegen with:
+// "local resource not guaranteed to map to unique global resource."
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer buf;
+ if(tid.x > 0)
+ buf = gBuf0;
+ buf.Store(tid.x * 4, 42);
+}
+
+// CHECK-NOT: error:
+// CHECK-NOT: warning:
+// CHECK: define {{.*}} @main(
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_default_init_store.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_default_init_store.hlsl
new file mode 100644
index 0000000000000..f38a60615ca9d
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_default_init_store.hlsl
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes \
+// RUN: -o - 2>&1 | llvm-cxxfilt | FileCheck %s
+
+// Test that using a default-initialized (unbound) local resource produces
+// valid IR in clang. No warnings or errors from clang.
+//
+// DXC: passes sema but fails codegen with:
+// "local resource not guaranteed to map to unique global resource."
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer buf;
+ buf.Store(tid.x * 4, 42);
+}
+
+// CHECK-NOT: error:
+// CHECK-NOT: warning:
+// CHECK: define {{.*}} @main(
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_nested_ternary.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_nested_ternary.hlsl
new file mode 100644
index 0000000000000..017c5a2ef627e
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_nested_ternary.hlsl
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes \
+// RUN: -o - 2>&1 | llvm-cxxfilt | FileCheck %s
+
+// Test that a nested ternary resource selection produces a warning in
+// clang but still generates valid IR.
+//
+// DXC: passes sema but fails codegen with two errors:
+// "local resource not guaranteed to map to unique global resource."
+// (one for each ternary level)
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+RWByteAddressBuffer gBuf2 : register(u2);
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ bool c1 = tid.x > 0;
+ bool c2 = tid.y > 0;
+ RWByteAddressBuffer buf = c1 ? gBuf0 : (c2 ? gBuf1 : gBuf2);
+ buf.Store(tid.x * 4, 42);
+}
+
+// CHECK: warning: assignment of 'c1 ? gBuf0 : (c2 ? gBuf1 : gBuf2)' to local resource 'buf' is not to the same unique global resource
+// CHECK: define {{.*}} @main(
+// CHECK-NOT: error:
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_phi_merge_ternary.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_phi_merge_ternary.hlsl
new file mode 100644
index 0000000000000..08ea7f13ad234
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_phi_merge_ternary.hlsl
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute -emit-llvm -disable-llvm-passes 2>&1 -o - %s | llvm-cxxfilt | FileCheck %s
+
+// DXC passes sema but fails during codegen (DxilCondenseResources) with:
+// "local resource not guaranteed to map to unique global resource"
+// Clang passes both sema and codegen, emitting a -Whlsl-explicit-binding
+// warning instead.
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf2 : register(u2);
+
+uint Pass_PhiMerge(bool cond, uint idx)
+{
+ RWByteAddressBuffer buf;
+ // DXC: error after sema: local resource not guaranteed to map to unique global resource.
+ // CHECK: warning: assignment of 'cond ? gBuf0 : gBuf2' to local resource 'buf' is not to the same unique global resource
+ buf = cond ? gBuf0 : gBuf2;
+ buf.Store(idx * 4, 18);
+
+ return 18;
+}
+
+// CHECK: define hidden noundef i32 @Pass_PhiMerge(bool, unsigned int)(
+// CHECK: define void @main()
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_PhiMerge(idx < 32, idx);
+}
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_as_argument.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_as_argument.hlsl
new file mode 100644
index 0000000000000..db2dc5ffcbef0
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_as_argument.hlsl
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes \
+// RUN: -o - 2>&1 | llvm-cxxfilt | FileCheck %s
+
+// Test that a ternary resource expression passed directly as a function
+// argument produces valid IR in clang.
+//
+// DXC: passes sema but fails codegen with:
+// "local resource not guaranteed to map to unique global resource."
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+void Helper(RWByteAddressBuffer buf, uint offset, uint value)
+{
+ buf.Store(offset, value);
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ bool cond = tid.x > 0;
+ Helper(cond ? gBuf0 : gBuf1, tid.x * 4, 42);
+}
+
+// CHECK-NOT: error:
+// CHECK: define {{.*}} @main(
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_assign.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_assign.hlsl
new file mode 100644
index 0000000000000..faecc5ab5f773
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_assign.hlsl
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute -emit-llvm -disable-llvm-passes 2>&1 -o - %s | llvm-cxxfilt | FileCheck %s
+
+// DXC passes sema but fails during codegen (DxilCondenseResources) with:
+// "local resource not guaranteed to map to unique global resource"
+// Clang passes both sema and codegen, emitting a -Whlsl-explicit-binding
+// warning instead.
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+uint Pass_IfAlias(bool cond, uint idx)
+{
+ RWByteAddressBuffer buf;
+ // DXC: error after sema: local resource not guaranteed to map to unique global resource.
+ // CHECK: warning: assignment of 'cond ? gBuf0 : gBuf1' to local resource 'buf' is not to the same unique global resource
+ buf = cond ? gBuf0 : gBuf1;
+ buf.Store(idx * 4, 14);
+
+ return 14;
+}
+
+// CHECK: define hidden noundef i32 @Pass_IfAlias(bool, unsigned int)(
+// CHECK: define void @main()
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_IfAlias(idx < 32, idx);
+}
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_wave_uniform.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_wave_uniform.hlsl
new file mode 100644
index 0000000000000..0ef5f49f56058
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_wave_uniform.hlsl
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes \
+// RUN: -o - 2>&1 | llvm-cxxfilt | FileCheck %s
+
+// Test that a wave-conditional resource reassignment produces a warning
+// in clang but still generates valid IR.
+//
+// DXC: passes sema but fails codegen with:
+// "local resource not guaranteed to map to unique global resource."
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+uint Fail_WaveUniform(uint offset, uint value)
+{
+ RWByteAddressBuffer buf = gBuf0;
+ if(WaveActiveAllTrue(true))
+ buf = gBuf1;
+ // expected-warning: assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource
+ buf.Store(offset, value);
+
+ return value;
+}
+
+// CHECK: warning: assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource
+// CHECK: define {{.*}} @Fail_WaveUniform(
+// CHECK: define {{.*}} @main(
+// CHECK-NOT: error:
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ Fail_WaveUniform(tid.x * 4, 10);
+}
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/ternary_initialization.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/ternary_initialization.hlsl
index 71da9d8e1af5b..c9b6f47cdcd9c 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/ternary_initialization.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/ternary_initialization.hlsl
@@ -7,19 +7,15 @@ RWByteAddressBuffer gOut : register(u3);
RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
-uint DoStore(RWByteAddressBuffer buf, uint offset, uint value)
-{
- buf.Store(offset, value);
- return value;
-}
-
uint Pass_TernaryInit(bool cond, uint idx)
{
// DXC emits this warning: local resource not guaranteed to map to unique global resource.
// Below is generated by -Whlsl-explicit-binding
// CHECK: warning: assignment of 'cond ? gBuf0 : gBuf1' to local resource 'buf' is not to the same unique global resource
RWByteAddressBuffer buf = cond ? gBuf0 : gBuf1;
- return DoStore(buf, idx * 4, 2);
+ buf.Store(idx * 4, 2);
+
+ return 2;
}
[numthreads(8,8,1)]
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/Readme.md b/clang/test/SemaHLSL/Resources/Local-Resources/Readme.md
new file mode 100644
index 0000000000000..f8d007bcbee3e
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/Readme.md
@@ -0,0 +1,187 @@
+# Local Resource Tests
+
+## Purpose
+
+This test suite documents and verifies the behavior of **local resource variables** in HLSL — that is, resource handles declared within function scope rather than at global scope. Local resources are a common pattern in HLSL shaders, yet their semantics around initialization, assignment, aliasing, and control flow have historically been under-documented and inconsistently handled across compilers.
+
+## Motivation
+
+DXC has never had structured test coverage for local resource patterns. Many valid and invalid usage patterns were either untested or bundled into monolithic test files, making it difficult to understand what is intentional behavior versus incidental. This suite was created to:
+
+1. **Establish a reference** for how both Clang and DXC handle each local resource pattern.
+2. **Document behavioral differences** between the two compilers, particularly where DXC issues hard errors for patterns that Clang treats as warnings or accepts silently.
+3. **Enable regression testing** so that future compiler changes can be validated against well-defined expectations.
+4. **Provide individual, self-contained tests** — each file tests exactly one pattern with its own globals, helpers, and entry point, making failures easy to diagnose.
+
+## Organization
+
+Tests are split across two directories based on compiler behavior:
+
+### `SemaHLSL/Resources/Local-Resources/` (this directory)
+
+Tests where **sema is the interesting stage**. This includes:
+- Tests that **pass both sema and codegen** in both compilers (clean passes).
+- Tests that **fail during sema** (expected errors caught by `-verify`).
+- Tests where Clang emits **sema-level warnings** (`-Whlsl-explicit-binding`) that DXC does not — these are verified with `expected-warning` annotations and document the DXC difference in comments.
+
+### `CodeGenHLSL/resources/Local-Resources/`
+
+Tests where **codegen is the interesting stage**. This includes:
+- Tests that **pass sema but fail codegen** in either compiler. These use `FileCheck` to verify that Clang produces valid IR and emits the expected diagnostics, while documenting DXC's codegen-stage errors in comments.
+
+## Test Categories
+
+### Basic Local Resource Operations
+| File | Pattern |
+|------|---------|
+| `local_resource_alias_global.hlsl` | Local resource initialized from a global |
+| `local_resource_alias_chain.hlsl` | Chain of local-to-local aliases (`a = g; b = a; c = b`) |
+| `local_resource_copy_between_locals.hlsl` | Copy one local resource to another (`a = g; b = a`) |
+| `local_resource_self_assign.hlsl` | Self-assignment (`buf = buf`) |
+| `use_local_resource_uninitialized.hlsl` | Using an uninitialized local resource |
+| `return_local_resource_uninitialized.hlsl` | Returning an uninitialized local resource |
+| `return_local_resource_initialized.hlsl` | Returning a local resource initialized from a global |
+| `expression_init.hlsl` | Initializing with a parenthesized ternary expression |
+| `local_resource_aggregate_init.hlsl` | Aggregate initialization of a struct containing a resource |
+
+### Parameter Passing
+| File | Pattern |
+|------|---------|
+| `local_resource_out_param.hlsl` | Resource written through an `out` parameter |
+| `local_resource_inout_param.hlsl` | Resource passed as an `inout` parameter |
+| `local_resource_const_param.hlsl` | Resource passed as a `const` parameter |
+
+### Struct and Array Patterns
+| File | Pattern |
+|------|---------|
+| `local_struct_resource_member.hlsl` | Struct with a resource member |
+| `struct_array_with_resource_member.hlsl` | Array of structs, each containing a resource |
+| `struct_with_resource_array_member.hlsl` | Struct containing an array of resources |
+| `nested_struct_resource_member.hlsl` | Inner/outer nested struct with resource |
+| `forward_struct_layers_resource.hlsl` | Deeply composed struct layers with resource |
+| `local_resource_array.hlsl` | Plain local array of resources |
+| `local_resource_array_copy.hlsl` | Copy one local resource array to another |
+| `local_resource_array_dynamic_index.hlsl` | Runtime dynamic index into a local resource array |
+| `local_resource_array_partial_init.hlsl` | Partially initialized resource array (`{g0}` for a 2-element array) |
+| `struct_resource_member_reassign.hlsl` | Reassign a struct's resource member to a different global |
+| `local_resource_struct_return.hlsl` | Function returns a struct containing a resource |
+| `local_resource_mixed_struct.hlsl` | Struct with both a resource member and a scalar member |
+
+### Control Flow
+| File | Pattern |
+|------|---------|
+| `local_resource_shadow_inner_scope.hlsl` | Shadowed resource in an inner block |
+| `local_resource_block_lifetime.hlsl` | Assigned in inner block, used in outer scope |
+| `local_resource_nested_blocks_reassign.hlsl` | Reassigned across nested blocks *(clang warns, DXC silent)* |
+| `local_resource_early_return_reassign.hlsl` | Reassigned after an early return path *(clang warns, DXC silent)* |
+| `local_resource_unreachable_reassign.hlsl` | Reassigned in code after an early return *(clang warns, DXC silent)* |
+| `local_resource_switch_reassign.hlsl` | Reassigned in switch cases *(clang warns, DXC silent)* |
+| `local_resource_switch_fallthrough.hlsl` | Switch with fallthrough reassignment *(clang warns, DXC silent)* |
+
+### Loop Patterns
+| File | Pattern |
+|------|---------|
+| `loop_var.hlsl` | Resource as a for-loop variable |
+| `local_resource_loop_array_index.hlsl` | Resource from array inside a loop |
+| `local_resource_nested_loops.hlsl` | Resource from array in nested loops |
+| `local_resource_loop_carried.hlsl` | Loop-carried reassignment from array *(clang warns, DXC silent)* |
+| `local_resource_do_while_reassign.hlsl` | Reassignment inside a do-while loop *(clang warns, DXC silent)* |
+
+### Reassignment and Phi/Merge
+| File | Pattern |
+|------|---------|
+| `local_resource_reassign_different_global.hlsl` | Reassign to a different global *(clang warns, DXC silent)* |
+| `local_resource_deep_phi.hlsl` | Nested if/else with ternary *(clang warns, DXC silent)* |
+
+### Bindless
+| File | Pattern |
+|------|---------|
+| `local_resource_bindless_array.hlsl` | Dynamic index into global resource array |
+| `local_resource_bindless_selection.hlsl` | Multiple dynamic array selections |
+
+### Function Forwarding and Multiple Uses
+| File | Pattern |
+|------|---------|
+| `local_resource_forward_through_functions.hlsl` | Resource passed through a call chain |
+| `local_resource_with_wave_intrinsic.hlsl` | Resource used alongside wave intrinsics |
+| `local_resource_multiple_uses.hlsl` | Same local resource passed to multiple helper functions |
+| `local_resource_from_function_return.hlsl` | Local resource initialized from a function's return value |
+
+### Static and Storage
+| File | Pattern |
+|------|---------|
+| `local_resource_static_local.hlsl` | Static local resource initialized from a global *(passes both compilers with RWByteAddressBuffer; DXC ICEs with Texture2D)* |
+
+### Type Mixing
+| File | Pattern |
+|------|---------|
+| `local_resource_different_types.hlsl` | Two different resource types (`RWByteAddressBuffer` + `RWStructuredBuffer`) in the same function |
+
+### Invalid Type Operations (Sema Failures)
+| File | Pattern |
+|------|---------|
+| `local_resource_arithmetic.hlsl` | Arithmetic (`buf + 1`) on a resource handle |
+| `local_resource_addition.hlsl` | Addition (`buf + buf`) of two resource handles |
+| `local_resource_compare.hlsl` | Equality comparison (`a == b`) of two resources |
+| `local_resource_to_bool.hlsl` | Implicit conversion of a resource to `bool` |
+| `local_resource_cast_to_uint.hlsl` | C-style cast of a resource to `uint` |
+| `local_resource_cast_sampler_to_buffer.hlsl` | C-style cast from `SamplerState` to `RWByteAddressBuffer` |
+| `local_resource_assign_wrong_type.hlsl` | Assign `RWStructuredBuffer` to `RWByteAddressBuffer` (type mismatch) |
+| `local_resource_volatile.hlsl` | `volatile` qualifier on resource prevents method calls *(clang errors, DXC accepts)* |
+| `local_resource_const_reassign.hlsl` | `const` local resource prevents reassignment *(both compilers error)* |
+
+### Invalid Declarations (Sema Failures)
+| File | Pattern |
+|------|---------|
+| `local_resource_default_param.hlsl` | Resource parameter with default followed by parameter without default |
+| `local_resource_as_structured_buffer_element.hlsl` | Resource type as element of `RWStructuredBuffer` (intangible type) |
+| `local_resource_array_oob.hlsl` | Compile-time out-of-bounds index into resource array *(clang warns, DXC errors)* |
+
+### Groupshared Resources
+| File | Pattern |
+|------|---------|
+| `use_groupshared.hlsl` | Passing a groupshared resource as a function argument *(fails sema — constructor mismatch)* |
+| `use_groupshared_direct_store.hlsl` | Calling Store directly on a groupshared resource *(fails sema — address space mismatch)* |
+| `use_struct_groupshared.hlsl` | Using a resource from a groupshared struct *(expected to fail sema — see TODO in file)* |
+
+### CodeGen Tests (`CodeGenHLSL/resources/Local-Resources/`)
+| File | Pattern |
+|------|---------|
+| `ternary_initialization.hlsl` | Ternary init (`buf = cond ? g0 : g1`) *(DXC codegen error)* |
+| `local_resource_ternary_assign.hlsl` | Ternary assignment post-declaration *(DXC codegen error)* |
+| `local_resource_phi_merge_ternary.hlsl` | Ternary phi merge *(DXC codegen error)* |
+| `local_resource_wave_uniform.hlsl` | Wave-conditional reassignment *(DXC codegen error; clang warns)* |
+| `local_resource_default_init_store.hlsl` | Store through a default-initialized (unbound) resource *(DXC codegen error; clang silent)* |
+| `local_resource_break_reassign.hlsl` | Reassignment before a break in a loop *(DXC codegen error; clang warns)* |
+| `local_resource_conditional_init.hlsl` | Resource only initialized in one branch of an if *(DXC codegen error; clang silent)* |
+| `local_resource_ternary_as_argument.hlsl` | Ternary resource passed directly as a function argument *(DXC codegen error; clang silent)* |
+| `local_resource_nested_ternary.hlsl` | Nested ternary (`c1 ? g0 : (c2 ? g1 : g2)`) *(DXC codegen 2 errors; clang warns)* |
+
+## Key Behavioral Differences: Clang vs DXC
+
+### `-Whlsl-explicit-binding` (Clang-only)
+Clang emits warnings when a local resource is assigned from a source that does not resolve to a single unique global resource. DXC has no equivalent diagnostic — it either silently accepts the pattern or rejects it as a hard error during codegen.
+
+### Ternary Conditional Resource Assignment
+DXC's `DxilCondenseResources` pass rejects `cond ? gBuf0 : gBuf1` as a codegen error: *"local resource not guaranteed to map to unique global resource."* Clang accepts this pattern and emits a warning.
+
+### Groupshared Resources
+Both compilers reject using groupshared resources in most contexts, but the specific diagnostics differ. Clang rejects at sema with constructor-mismatch errors. DXC rejects during validation.
+
+### Sema Error Messages
+For type-error tests (arithmetic, comparison, cast, etc.), both compilers reject the invalid code at sema, but the error messages often differ. Clang uses its standard C++ diagnostics (e.g., "invalid operands to binary expression") while DXC uses HLSL-specific messages (e.g., "scalar, vector, or matrix expected"). Each test file documents both.
+
+### Texture2D vs RWByteAddressBuffer
+The failure tests use `RWByteAddressBuffer` rather than `Texture2D` because Clang does not yet support `Texture2D`. Some behaviors differ between the two resource types — notably, DXC asserts/ICEs with `static Texture2D` but accepts `static RWByteAddressBuffer`. This is documented in `local_resource_static_local.hlsl`.
+
+### Wave-Conditional Reassignment
+DXC's `DxilCondenseResources` pass rejects resource reassignment under wave-conditional control flow as a hard codegen error: *"local resource not guaranteed to map to unique global resource."* DXC's sema passes this pattern silently. Clang treats it as a sema-level warning (`-Whlsl-explicit-binding`). This pattern is in `CodeGenHLSL` because of the DXC codegen failure.
+
+### `volatile` Resources
+Clang rejects calling methods on a `volatile`-qualified resource because the methods are not marked `volatile`. DXC silently accepts `volatile` on resources and compiles successfully. This is documented in `local_resource_volatile.hlsl`.
+
+### Conditional/Partial Initialization
+DXC rejects resources that are only initialized in one branch (`if(cond) buf = g;`) or that use default-initialized (unbound) handles. These patterns fail in DXC's `DxilCondenseResources` pass with *"local resource not guaranteed to map to unique global resource."* Clang accepts them silently. See `local_resource_conditional_init.hlsl` and `local_resource_default_init_store.hlsl` in `CodeGenHLSL`.
+
+### Array Out-of-Bounds
+Both compilers catch compile-time OOB indexing into resource arrays, but at different severity levels. Clang emits a warning (`-Warray-bounds`); DXC emits a hard error. See `local_resource_array_oob.hlsl`.
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.hlsl
index 3480b5f65a82e..cc519b5f05993 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.hlsl
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -verify
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
// expected-no-diagnostics
@@ -8,16 +8,12 @@ RWByteAddressBuffer gBuf1 : register(u1);
RWByteAddressBuffer gOut : register(u3);
-uint DoStore(RWByteAddressBuffer buf, uint offset, uint value)
-{
- buf.Store(offset, value);
- return value;
-}
-
uint Pass_ExpressionInit(uint idx)
{
RWByteAddressBuffer buf = (true ? gBuf0 : gBuf1);
- return DoStore(buf, idx * 4, 3);
+ buf.Store(idx * 4, 3);
+
+ return 3;
}
[numthreads(8,8,1)]
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.ll b/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.ll
deleted file mode 100644
index 0ff7f24d7fefe..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.ll
+++ /dev/null
@@ -1,318 +0,0 @@
-; ModuleID = 'D:\llvm-project\clang\test\SemaHLSL\Resources\Local-Resources\expression_init.hlsl'
-source_filename = "D:\\llvm-project\\clang\\test\\SemaHLSL\\Resources\\Local-Resources\\expression_init.hlsl"
-target datalayout = "e-m:e-ve-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64"
-target triple = "dxilv1.6-pc-shadermodel6.6-compute"
-
-%"class.hlsl::RWByteAddressBuffer" = type { target("dx.RawBuffer", i8, 1, 0) }
-
- at _ZL5gBuf0 = internal global %"class.hlsl::RWByteAddressBuffer" poison, align 4
- at .str = private unnamed_addr constant [6 x i8] c"gBuf0\00", align 1
- at _ZL5gBuf1 = internal global %"class.hlsl::RWByteAddressBuffer" poison, align 4
- at .str.2 = private unnamed_addr constant [6 x i8] c"gBuf1\00", align 1
- at _ZL4gOut = internal global %"class.hlsl::RWByteAddressBuffer" poison, align 4
- at .str.4 = private unnamed_addr constant [5 x i8] c"gOut\00", align 1
-
-; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
-define hidden noundef i32 @_Z7DoStoreN4hlsl19RWByteAddressBufferEjj(ptr noundef byval(%"class.hlsl::RWByteAddressBuffer") align 4 %buf, i32 noundef %offset, i32 noundef %value) #0 {
-entry:
- %this.addr.i = alloca ptr, align 4
- %Index.addr.i = alloca i32, align 4
- %Value.addr.i = alloca i32, align 4
- %offset.addr = alloca i32, align 4
- %value.addr = alloca i32, align 4
- store i32 %offset, ptr %offset.addr, align 4
- store i32 %value, ptr %value.addr, align 4
- %0 = load i32, ptr %offset.addr, align 4
- %1 = load i32, ptr %value.addr, align 4
- store ptr %buf, ptr %this.addr.i, align 4
- store i32 %0, ptr %Index.addr.i, align 4
- store i32 %1, ptr %Value.addr.i, align 4
- %this1.i = load ptr, ptr %this.addr.i, align 4
- %2 = load i32, ptr %Value.addr.i, align 4
- %3 = load target("dx.RawBuffer", i8, 1, 0), ptr %this1.i, align 4
- %4 = load i32, ptr %Index.addr.i, align 4
- %5 = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i8_1_0t.i32(target("dx.RawBuffer", i8, 1, 0) %3, i32 %4)
- store i32 %2, ptr %5, align 4
- %6 = load i32, ptr %value.addr, align 4
- ret i32 %6
-}
-
-; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
-define hidden noundef i32 @_Z19Pass_ExpressionInitj(i32 noundef %idx) #0 {
-entry:
- %this.addr.i10 = alloca ptr, align 4
- %other.addr.i11 = alloca ptr, align 4
- %this.addr.i7 = alloca ptr, align 4
- %other.addr.i8 = alloca ptr, align 4
- %this.addr.i4 = alloca ptr, align 4
- %other.addr.i5 = alloca ptr, align 4
- %this.addr.i2 = alloca ptr, align 4
- %other.addr.i = alloca ptr, align 4
- %this.addr.i = alloca ptr, align 4
- %Index.addr.i = alloca i32, align 4
- %Value.addr.i = alloca i32, align 4
- %offset.addr.i = alloca i32, align 4
- %value.addr.i = alloca i32, align 4
- %agg.tmp1 = alloca %"class.hlsl::RWByteAddressBuffer", align 8
- %idx.addr = alloca i32, align 4
- %buf = alloca %"class.hlsl::RWByteAddressBuffer", align 4
- %agg.tmp = alloca %"class.hlsl::RWByteAddressBuffer", align 4
- store i32 %idx, ptr %idx.addr, align 4
- store ptr %buf, ptr %this.addr.i4, align 4
- store ptr @_ZL5gBuf0, ptr %other.addr.i5, align 4
- %this1.i6 = load ptr, ptr %this.addr.i4, align 4
- %0 = load ptr, ptr %other.addr.i5, align 4
- store ptr %this1.i6, ptr %this.addr.i7, align 4
- store ptr %0, ptr %other.addr.i8, align 4
- %this1.i9 = load ptr, ptr %this.addr.i7, align 4
- %1 = load ptr, ptr %other.addr.i8, align 4, !nonnull !3, !align !4
- %2 = load target("dx.RawBuffer", i8, 1, 0), ptr %1, align 4
- store target("dx.RawBuffer", i8, 1, 0) %2, ptr %this1.i9, align 4
- store ptr %agg.tmp, ptr %this.addr.i2, align 4
- store ptr %buf, ptr %other.addr.i, align 4
- %this1.i3 = load ptr, ptr %this.addr.i2, align 4
- %3 = load ptr, ptr %other.addr.i, align 4
- store ptr %this1.i3, ptr %this.addr.i10, align 4
- store ptr %3, ptr %other.addr.i11, align 4
- %this1.i12 = load ptr, ptr %this.addr.i10, align 4
- %4 = load ptr, ptr %other.addr.i11, align 4, !nonnull !3, !align !4
- %5 = load target("dx.RawBuffer", i8, 1, 0), ptr %4, align 4
- store target("dx.RawBuffer", i8, 1, 0) %5, ptr %this1.i12, align 4
- %6 = load i32, ptr %idx.addr, align 4
- %mul = mul i32 %6, 4
- call void @llvm.memcpy.p0.p0.i64(ptr align 8 %agg.tmp1, ptr align 4 %agg.tmp, i64 4, i1 false)
- store i32 %mul, ptr %offset.addr.i, align 4
- store i32 3, ptr %value.addr.i, align 4
- %7 = load i32, ptr %offset.addr.i, align 4
- %8 = load i32, ptr %value.addr.i, align 4
- store ptr %agg.tmp1, ptr %this.addr.i, align 4
- store i32 %7, ptr %Index.addr.i, align 4
- store i32 %8, ptr %Value.addr.i, align 4
- %this1.i = load ptr, ptr %this.addr.i, align 4
- %9 = load i32, ptr %Value.addr.i, align 4
- %10 = load target("dx.RawBuffer", i8, 1, 0), ptr %this1.i, align 4
- %11 = load i32, ptr %Index.addr.i, align 4
- %12 = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i8_1_0t.i32(target("dx.RawBuffer", i8, 1, 0) %10, i32 %11)
- store i32 %9, ptr %12, align 4
- %13 = load i32, ptr %value.addr.i, align 4
- ret i32 %13
-}
-
-; Function Attrs: convergent noinline norecurse
-define void @main() #1 {
-entry:
- %this.addr.i19.i = alloca ptr, align 4
- %other.addr.i20.i = alloca ptr, align 4
- %this.addr.i16.i = alloca ptr, align 4
- %other.addr.i17.i = alloca ptr, align 4
- %this.addr.i13.i = alloca ptr, align 4
- %other.addr.i14.i = alloca ptr, align 4
- %this.addr.i10.i = alloca ptr, align 4
- %other.addr.i11.i = alloca ptr, align 4
- %this.addr.i7.i = alloca ptr, align 4
- %other.addr.i8.i = alloca ptr, align 4
- %this.addr.i.i4 = alloca ptr, align 4
- %other.addr.i.i5 = alloca ptr, align 4
- %registerNo.addr.i.i1.i = alloca i32, align 4
- %spaceNo.addr.i.i2.i = alloca i32, align 4
- %range.addr.i.i3.i = alloca i32, align 4
- %index.addr.i.i4.i = alloca i32, align 4
- %name.addr.i.i5.i = alloca ptr, align 4
- %tmp.i.i6.i = alloca %"class.hlsl::RWByteAddressBuffer", align 4
- %registerNo.addr.i.i.i = alloca i32, align 4
- %spaceNo.addr.i.i.i = alloca i32, align 4
- %range.addr.i.i.i = alloca i32, align 4
- %index.addr.i.i.i = alloca i32, align 4
- %name.addr.i.i.i = alloca ptr, align 4
- %tmp.i.i.i = alloca %"class.hlsl::RWByteAddressBuffer", align 4
- %registerNo.addr.i.i = alloca i32, align 4
- %spaceNo.addr.i.i = alloca i32, align 4
- %range.addr.i.i = alloca i32, align 4
- %index.addr.i.i = alloca i32, align 4
- %name.addr.i.i = alloca ptr, align 4
- %tmp.i.i = alloca %"class.hlsl::RWByteAddressBuffer", align 4
- %this.addr.i1 = alloca ptr, align 4
- %other.addr.i2 = alloca ptr, align 4
- %this.addr.i = alloca ptr, align 4
- %other.addr.i = alloca ptr, align 4
- %this.addr.i1.i = alloca ptr, align 4
- %other.addr.i2.i = alloca ptr, align 4
- %this.addr.i.i = alloca ptr, align 4
- %other.addr.i.i = alloca ptr, align 4
- %this.addr.i.i.i = alloca ptr, align 4
- %Index.addr.i.i.i = alloca i32, align 4
- %Value.addr.i.i.i = alloca i32, align 4
- %offset.addr.i.i.i = alloca i32, align 4
- %value.addr.i.i.i = alloca i32, align 4
- %agg.tmp1.i.i = alloca %"class.hlsl::RWByteAddressBuffer", align 8
- %idx.addr.i.i = alloca i32, align 4
- %buf.i.i = alloca %"class.hlsl::RWByteAddressBuffer", align 4
- %agg.tmp.i.i = alloca %"class.hlsl::RWByteAddressBuffer", align 4
- %tid.addr.i = alloca <3 x i32>, align 4
- %idx.i = alloca i32, align 4
- call void @llvm.experimental.noalias.scope.decl(metadata !5)
- store i32 0, ptr %registerNo.addr.i.i, align 4, !noalias !5
- store i32 0, ptr %spaceNo.addr.i.i, align 4, !noalias !5
- store i32 1, ptr %range.addr.i.i, align 4, !noalias !5
- store i32 0, ptr %index.addr.i.i, align 4, !noalias !5
- store ptr @.str, ptr %name.addr.i.i, align 4, !noalias !5
- %0 = load i32, ptr %registerNo.addr.i.i, align 4, !noalias !5
- %1 = load i32, ptr %spaceNo.addr.i.i, align 4, !noalias !5
- %2 = load i32, ptr %range.addr.i.i, align 4, !noalias !5
- %3 = load i32, ptr %index.addr.i.i, align 4, !noalias !5
- %4 = load ptr, ptr %name.addr.i.i, align 4, !noalias !5
- %5 = call target("dx.RawBuffer", i8, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_1_0t(i32 %1, i32 %0, i32 %2, i32 %3, ptr %4)
- store target("dx.RawBuffer", i8, 1, 0) %5, ptr %tmp.i.i, align 4, !noalias !5
- store ptr @_ZL5gBuf0, ptr %this.addr.i10.i, align 4
- store ptr %tmp.i.i, ptr %other.addr.i11.i, align 4
- %this1.i12.i = load ptr, ptr %this.addr.i10.i, align 4
- %6 = load ptr, ptr %other.addr.i11.i, align 4
- store ptr %this1.i12.i, ptr %this.addr.i13.i, align 4
- store ptr %6, ptr %other.addr.i14.i, align 4
- %this1.i15.i = load ptr, ptr %this.addr.i13.i, align 4
- %7 = load ptr, ptr %other.addr.i14.i, align 4, !nonnull !3, !align !4
- %8 = load target("dx.RawBuffer", i8, 1, 0), ptr %7, align 4
- store target("dx.RawBuffer", i8, 1, 0) %8, ptr %this1.i15.i, align 4
- call void @llvm.experimental.noalias.scope.decl(metadata !8)
- store i32 1, ptr %registerNo.addr.i.i.i, align 4, !noalias !8
- store i32 0, ptr %spaceNo.addr.i.i.i, align 4, !noalias !8
- store i32 1, ptr %range.addr.i.i.i, align 4, !noalias !8
- store i32 0, ptr %index.addr.i.i.i, align 4, !noalias !8
- store ptr @.str.2, ptr %name.addr.i.i.i, align 4, !noalias !8
- %9 = load i32, ptr %registerNo.addr.i.i.i, align 4, !noalias !8
- %10 = load i32, ptr %spaceNo.addr.i.i.i, align 4, !noalias !8
- %11 = load i32, ptr %range.addr.i.i.i, align 4, !noalias !8
- %12 = load i32, ptr %index.addr.i.i.i, align 4, !noalias !8
- %13 = load ptr, ptr %name.addr.i.i.i, align 4, !noalias !8
- %14 = call target("dx.RawBuffer", i8, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_1_0t(i32 %10, i32 %9, i32 %11, i32 %12, ptr %13)
- store target("dx.RawBuffer", i8, 1, 0) %14, ptr %tmp.i.i.i, align 4, !noalias !8
- store ptr @_ZL5gBuf1, ptr %this.addr.i7.i, align 4
- store ptr %tmp.i.i.i, ptr %other.addr.i8.i, align 4
- %this1.i9.i = load ptr, ptr %this.addr.i7.i, align 4
- %15 = load ptr, ptr %other.addr.i8.i, align 4
- store ptr %this1.i9.i, ptr %this.addr.i16.i, align 4
- store ptr %15, ptr %other.addr.i17.i, align 4
- %this1.i18.i = load ptr, ptr %this.addr.i16.i, align 4
- %16 = load ptr, ptr %other.addr.i17.i, align 4, !nonnull !3, !align !4
- %17 = load target("dx.RawBuffer", i8, 1, 0), ptr %16, align 4
- store target("dx.RawBuffer", i8, 1, 0) %17, ptr %this1.i18.i, align 4
- call void @llvm.experimental.noalias.scope.decl(metadata !11)
- store i32 3, ptr %registerNo.addr.i.i1.i, align 4, !noalias !11
- store i32 0, ptr %spaceNo.addr.i.i2.i, align 4, !noalias !11
- store i32 1, ptr %range.addr.i.i3.i, align 4, !noalias !11
- store i32 0, ptr %index.addr.i.i4.i, align 4, !noalias !11
- store ptr @.str.4, ptr %name.addr.i.i5.i, align 4, !noalias !11
- %18 = load i32, ptr %registerNo.addr.i.i1.i, align 4, !noalias !11
- %19 = load i32, ptr %spaceNo.addr.i.i2.i, align 4, !noalias !11
- %20 = load i32, ptr %range.addr.i.i3.i, align 4, !noalias !11
- %21 = load i32, ptr %index.addr.i.i4.i, align 4, !noalias !11
- %22 = load ptr, ptr %name.addr.i.i5.i, align 4, !noalias !11
- %23 = call target("dx.RawBuffer", i8, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_1_0t(i32 %19, i32 %18, i32 %20, i32 %21, ptr %22)
- store target("dx.RawBuffer", i8, 1, 0) %23, ptr %tmp.i.i6.i, align 4, !noalias !11
- store ptr @_ZL4gOut, ptr %this.addr.i.i4, align 4
- store ptr %tmp.i.i6.i, ptr %other.addr.i.i5, align 4
- %this1.i.i6 = load ptr, ptr %this.addr.i.i4, align 4
- %24 = load ptr, ptr %other.addr.i.i5, align 4
- store ptr %this1.i.i6, ptr %this.addr.i19.i, align 4
- store ptr %24, ptr %other.addr.i20.i, align 4
- %this1.i21.i = load ptr, ptr %this.addr.i19.i, align 4
- %25 = load ptr, ptr %other.addr.i20.i, align 4, !nonnull !3, !align !4
- %26 = load target("dx.RawBuffer", i8, 1, 0), ptr %25, align 4
- store target("dx.RawBuffer", i8, 1, 0) %26, ptr %this1.i21.i, align 4
- %27 = call i32 @llvm.dx.thread.id(i32 0)
- %28 = insertelement <3 x i32> poison, i32 %27, i64 0
- %29 = call i32 @llvm.dx.thread.id(i32 1)
- %30 = insertelement <3 x i32> %28, i32 %29, i64 1
- %31 = call i32 @llvm.dx.thread.id(i32 2)
- %32 = insertelement <3 x i32> %30, i32 %31, i64 2
- store <3 x i32> %32, ptr %tid.addr.i, align 4
- %33 = load <3 x i32>, ptr %tid.addr.i, align 4
- %34 = extractelement <3 x i32> %33, i32 0
- %35 = load <3 x i32>, ptr %tid.addr.i, align 4
- %36 = extractelement <3 x i32> %35, i32 1
- %mul.i = mul i32 %36, 8
- %add.i = add i32 %34, %mul.i
- store i32 %add.i, ptr %idx.i, align 4
- %37 = load i32, ptr %idx.i, align 4
- store i32 %37, ptr %idx.addr.i.i, align 4
- store ptr %buf.i.i, ptr %this.addr.i1.i, align 4
- store ptr @_ZL5gBuf0, ptr %other.addr.i2.i, align 4
- %this1.i3.i = load ptr, ptr %this.addr.i1.i, align 4
- %38 = load ptr, ptr %other.addr.i2.i, align 4
- store ptr %this1.i3.i, ptr %this.addr.i1, align 4
- store ptr %38, ptr %other.addr.i2, align 4
- %this1.i3 = load ptr, ptr %this.addr.i1, align 4
- %39 = load ptr, ptr %other.addr.i2, align 4, !nonnull !3, !align !4
- %40 = load target("dx.RawBuffer", i8, 1, 0), ptr %39, align 4
- store target("dx.RawBuffer", i8, 1, 0) %40, ptr %this1.i3, align 4
- store ptr %agg.tmp.i.i, ptr %this.addr.i.i, align 4
- store ptr %buf.i.i, ptr %other.addr.i.i, align 4
- %this1.i.i = load ptr, ptr %this.addr.i.i, align 4
- %41 = load ptr, ptr %other.addr.i.i, align 4
- store ptr %this1.i.i, ptr %this.addr.i, align 4
- store ptr %41, ptr %other.addr.i, align 4
- %this1.i = load ptr, ptr %this.addr.i, align 4
- %42 = load ptr, ptr %other.addr.i, align 4, !nonnull !3, !align !4
- %43 = load target("dx.RawBuffer", i8, 1, 0), ptr %42, align 4
- store target("dx.RawBuffer", i8, 1, 0) %43, ptr %this1.i, align 4
- %44 = load i32, ptr %idx.addr.i.i, align 4
- %mul.i.i = mul i32 %44, 4
- call void @llvm.memcpy.p0.p0.i64(ptr align 8 %agg.tmp1.i.i, ptr align 4 %agg.tmp.i.i, i64 4, i1 false)
- store i32 %mul.i.i, ptr %offset.addr.i.i.i, align 4
- store i32 3, ptr %value.addr.i.i.i, align 4
- %45 = load i32, ptr %offset.addr.i.i.i, align 4
- %46 = load i32, ptr %value.addr.i.i.i, align 4
- store ptr %agg.tmp1.i.i, ptr %this.addr.i.i.i, align 4
- store i32 %45, ptr %Index.addr.i.i.i, align 4
- store i32 %46, ptr %Value.addr.i.i.i, align 4
- %this1.i.i.i = load ptr, ptr %this.addr.i.i.i, align 4
- %47 = load i32, ptr %Value.addr.i.i.i, align 4
- %48 = load target("dx.RawBuffer", i8, 1, 0), ptr %this1.i.i.i, align 4
- %49 = load i32, ptr %Index.addr.i.i.i, align 4
- %50 = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i8_1_0t.i32(target("dx.RawBuffer", i8, 1, 0) %48, i32 %49)
- store i32 %47, ptr %50, align 4
- %51 = load i32, ptr %value.addr.i.i.i, align 4
- ret void
-}
-
-; Function Attrs: nounwind willreturn memory(none)
-declare i32 @llvm.dx.thread.id(i32) #2
-
-; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
-declare target("dx.RawBuffer", i8, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_1_0t(i32, i32, i32, i32, ptr) #3
-
-; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none)
-declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i8_1_0t.i32(target("dx.RawBuffer", i8, 1, 0), i32) #4
-
-; Function Attrs: nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
-declare void @llvm.experimental.noalias.scope.decl(metadata) #5
-
-; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
-declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #6
-
-attributes #0 = { alwaysinline convergent mustprogress norecurse nounwind "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
-attributes #1 = { convergent noinline norecurse "hlsl.numthreads"="8,8,1" "hlsl.shader"="compute" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
-attributes #2 = { nounwind willreturn memory(none) }
-attributes #3 = { nocallback nofree nosync nounwind willreturn memory(none) }
-attributes #4 = { convergent nocallback nofree nosync nounwind willreturn memory(none) }
-attributes #5 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
-attributes #6 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
-
-!dx.valver = !{!0}
-!llvm.module.flags = !{!1}
-!llvm.ident = !{!2}
-
-!0 = !{i32 1, i32 8}
-!1 = !{i32 4, !"dx.disable_optimizations", i32 1}
-!2 = !{!"clang version 23.0.0git (https://github.com/llvm/llvm-project.git b084fa7a5172e2502324f9df2723e22dad071e3a)"}
-!3 = !{}
-!4 = !{i64 4}
-!5 = !{!6}
-!6 = distinct !{!6, !7, !"_ZN4hlsl19RWByteAddressBuffer19__createFromBindingEjjijPKc: %agg.result"}
-!7 = distinct !{!7, !"_ZN4hlsl19RWByteAddressBuffer19__createFromBindingEjjijPKc"}
-!8 = !{!9}
-!9 = distinct !{!9, !10, !"_ZN4hlsl19RWByteAddressBuffer19__createFromBindingEjjijPKc: %agg.result"}
-!10 = distinct !{!10, !"_ZN4hlsl19RWByteAddressBuffer19__createFromBindingEjjijPKc"}
-!11 = !{!12}
-!12 = distinct !{!12, !13, !"_ZN4hlsl19RWByteAddressBuffer19__createFromBindingEjjijPKc: %agg.result"}
-!13 = distinct !{!13, !"_ZN4hlsl19RWByteAddressBuffer19__createFromBindingEjjijPKc"}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/forward_struct_layers_resource.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/forward_struct_layers_resource.hlsl
new file mode 100644
index 0000000000000..c989414989bfe
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/forward_struct_layers_resource.hlsl
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+RWByteAddressBuffer gBuf2 : register(u2);
+
+struct ForwardA { RWByteAddressBuffer buf; };
+struct ForwardB { ForwardA a; };
+
+uint Pass_ForwardStructLayers(uint idx)
+{
+ ForwardB b;
+ b.a.buf = gBuf2;
+ b.a.buf.Store(idx * 4, 29);
+
+ return 29;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_ForwardStructLayers(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_addition.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_addition.hlsl
new file mode 100644
index 0000000000000..3af4858b85e3c
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_addition.hlsl
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// Test that adding two resource handles together is rejected.
+//
+// DXC: also fails sema with a different message:
+// "scalar, vector, or matrix expected"
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+float Fail_Add()
+{
+ RWByteAddressBuffer buf = gBuf0;
+ return buf + buf;
+ // expected-error at -1 {{invalid operands to binary expression ('RWByteAddressBuffer' and 'RWByteAddressBuffer')}}
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ Fail_Add();
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_aggregate_init.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_aggregate_init.hlsl
new file mode 100644
index 0000000000000..961cd06b2e68b
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_aggregate_init.hlsl
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that aggregate (brace) initialization of a struct with a resource
+// member works correctly.
+//
+// DXC: passes (both sema and codegen).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+struct ResHolder { RWByteAddressBuffer buf; };
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ ResHolder h = {gBuf0};
+ h.buf.Store(tid.x * 4, 42);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_chain.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_chain.hlsl
new file mode 100644
index 0000000000000..fd7ba77d057cd
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_chain.hlsl
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+uint Pass_AliasChain(uint idx)
+{
+ RWByteAddressBuffer a = gBuf0;
+ RWByteAddressBuffer b = a;
+ RWByteAddressBuffer c = b;
+
+ c.Store(idx * 4, 27);
+
+
+ return 27;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_AliasChain(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_global.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_global.hlsl
new file mode 100644
index 0000000000000..69c7fc545f4c4
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_global.hlsl
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+uint Pass_Alias(uint idx)
+{
+ RWByteAddressBuffer buf = gBuf0;
+ buf.Store(idx * 4, 12);
+
+ return 12;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_Alias(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_arithmetic.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_arithmetic.hlsl
new file mode 100644
index 0000000000000..8ad396ad5a9ae
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_arithmetic.hlsl
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// Test that arithmetic operations on resource types are rejected.
+//
+// DXC: also fails sema, but with different messages:
+// "scalar, vector, or matrix expected" (for buf + 1)
+// "cannot initialize return object of type 'float' with an lvalue
+// of type 'RWByteAddressBuffer'" (for return buf)
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+float Fail_Arithmetic()
+{
+ RWByteAddressBuffer buf = gBuf0;
+ buf = buf + 1;
+ // expected-error at -1 {{invalid operands to binary expression ('RWByteAddressBuffer' and 'int')}}
+ return buf;
+ // expected-error at -1 {{no viable conversion from returned value of type 'RWByteAddressBuffer' to function return type 'float'}}
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ Fail_Arithmetic();
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array.hlsl
new file mode 100644
index 0000000000000..acb04d5346b1b
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array.hlsl
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+uint Pass_LocalArray(uint idx)
+{
+ RWByteAddressBuffer arr[2];
+ arr[0] = gBuf0;
+ arr[0].Store(idx * 4, 10);
+
+ return 10;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_LocalArray(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_copy.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_copy.hlsl
new file mode 100644
index 0000000000000..cb6f6943acdf7
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_copy.hlsl
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that a local resource array can be copied to another local array.
+//
+// DXC: passes (both sema and codegen).
+
+RWByteAddressBuffer gBufArray[4] : register(u0);
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer src[2];
+ src[0] = gBufArray[0];
+ src[1] = gBufArray[1];
+ RWByteAddressBuffer dst[2] = src;
+ dst[0].Store(tid.x * 4, 42);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_dynamic_index.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_dynamic_index.hlsl
new file mode 100644
index 0000000000000..2fa6404421059
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_dynamic_index.hlsl
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that a local resource array can be dynamically indexed at runtime.
+//
+// DXC: passes (both sema and codegen).
+
+RWByteAddressBuffer gBufArray[4] : register(u0);
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer localArr[2];
+ localArr[0] = gBufArray[0];
+ localArr[1] = gBufArray[1];
+ localArr[tid.x & 1].Store(tid.x * 4, 42);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_oob.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_oob.hlsl
new file mode 100644
index 0000000000000..0946509e820cb
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_oob.hlsl
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// Test that a compile-time out-of-bounds index into a global resource
+// array produces a warning in clang but still compiles.
+//
+// DXC: fails sema with a hard error:
+// "array index 5 is out of bounds"
+
+// expected-note at +1{{array 'gBufArray' declared here}}
+RWByteAddressBuffer gBufArray[4] : register(u0);
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer buf = gBufArray[5];
+ // expected-warning at -1 {{array index 5 is past the end of the array (that has type 'RWByteAddressBuffer[4]')}}
+
+ buf.Store(tid.x * 4, 42);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_partial_init.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_partial_init.hlsl
new file mode 100644
index 0000000000000..67ef424c6991e
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_partial_init.hlsl
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that a local resource array with only some elements initialized
+// (others left default) compiles successfully.
+//
+// DXC: passes (both sema and codegen).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer arr[4];
+ arr[0] = gBuf0;
+ arr[1] = gBuf0;
+ arr[tid.x & 3].Store(tid.x * 4, 42);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_as_structured_buffer_element.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_as_structured_buffer_element.hlsl
new file mode 100644
index 0000000000000..c74c567381994
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_as_structured_buffer_element.hlsl
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// Test that using a resource type as an element of RWStructuredBuffer
+// is rejected because resource types are intangible.
+//
+// DXC: also fails sema with a different message:
+// "object 'RWByteAddressBuffer' is not allowed in builtin template parameters"
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+void Fail_LocalBuffer()
+{
+ RWStructuredBuffer<RWByteAddressBuffer> badBuffer;
+ // expected-error at -1 {{constraints not satisfied for class template 'RWStructuredBuffer' [with element_type = RWByteAddressBuffer]}}
+ // expected-note@*:* {{because 'RWByteAddressBuffer' does not satisfy '__is_structured_resource_element_compatible'}}
+ // expected-note@*:* {{because '!__builtin_hlsl_is_intangible(hlsl::RWByteAddressBuffer)' evaluated to false}}
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ Fail_LocalBuffer();
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_assign_wrong_type.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_assign_wrong_type.hlsl
new file mode 100644
index 0000000000000..a0b1f4ccda0d7
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_assign_wrong_type.hlsl
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// Test that assigning between incompatible resource types is rejected.
+//
+// DXC: also fails sema with a different message:
+// "cannot convert from 'RWStructuredBuffer<uint>' to 'RWByteAddressBuffer'"
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWStructuredBuffer<uint> gSB : register(u1);
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer buf = gBuf0;
+ RWStructuredBuffer<uint> sb = gSB;
+ buf = sb;
+ // expected-error at -1 {{no viable overloaded '='}}
+ // expected-note@*:* {{candidate function not viable: no known conversion from 'RWStructuredBuffer<uint>' (aka 'RWStructuredBuffer<unsigned int>') to 'const hlsl::RWByteAddressBuffer' for 1st argument}}
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_array.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_array.hlsl
new file mode 100644
index 0000000000000..eecce30234f2b
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_array.hlsl
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+RWByteAddressBuffer gBufArray[4] : register(u10);
+
+uint Pass_Bindless(uint idx)
+{
+ RWByteAddressBuffer buf = gBufArray[idx & 3];
+ buf.Store(idx * 4, 21);
+
+ return 21;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_Bindless(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_selection.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_selection.hlsl
new file mode 100644
index 0000000000000..52fea1d8c9a06
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_selection.hlsl
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+RWByteAddressBuffer gBufArray[4] : register(u10);
+
+uint Pass_BindlessSelection(uint a, uint b, uint idx)
+{
+ RWByteAddressBuffer buf;
+
+ buf = gBufArray[a & 3];
+ buf = gBufArray[b & 3];
+
+ buf.Store(idx * 4, 33);
+
+
+ return 33;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_BindlessSelection(2, 3, idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_block_lifetime.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_block_lifetime.hlsl
new file mode 100644
index 0000000000000..95525cd5757b4
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_block_lifetime.hlsl
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+RWByteAddressBuffer gBuf1 : register(u1);
+
+uint Pass_BlockLifetime(uint idx)
+{
+ RWByteAddressBuffer buf;
+ {
+ buf = gBuf1;
+ }
+ buf.Store(idx * 4, 24);
+
+ return 24;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_BlockLifetime(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_cast_sampler_to_buffer.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_cast_sampler_to_buffer.hlsl
new file mode 100644
index 0000000000000..92412e59387ac
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_cast_sampler_to_buffer.hlsl
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// Test that C-style casting a SamplerState to RWByteAddressBuffer is rejected.
+//
+// DXC: also fails sema with a different message:
+// "cannot convert from 'SamplerState' to 'RWByteAddressBuffer'"
+
+RWByteAddressBuffer gBuf0 : register(u0);
+SamplerState gSampler : register(s0);
+
+uint Fail_Reinterpret(uint offset, uint value)
+{
+ RWByteAddressBuffer buf = gBuf0;
+ ((RWByteAddressBuffer)gSampler).Store(offset, value);
+ // expected-error at -1 {{no matching conversion for C-style cast from 'SamplerState' to 'RWByteAddressBuffer'}}
+ // expected-note@*:* {{candidate constructor not viable: no known conversion from 'SamplerState' to 'const hlsl::RWByteAddressBuffer' for 1st argument}}
+ // expected-note@*:* {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
+ return value;
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ Fail_Reinterpret(tid.x * 4, 8);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_cast_to_uint.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_cast_to_uint.hlsl
new file mode 100644
index 0000000000000..f246eb1589af5
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_cast_to_uint.hlsl
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// Test that C-style cast from a resource handle to uint is rejected.
+//
+// DXC: also fails sema with a different message:
+// "cannot convert from 'RWByteAddressBuffer' to 'uint'"
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+uint Fail_Cast()
+{
+ RWByteAddressBuffer buf = gBuf0;
+ return (uint)buf;
+ // expected-error at -1 {{cannot convert 'RWByteAddressBuffer' to 'uint' (aka 'unsigned int') without a conversion operator}}
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ Fail_Cast();
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_compare.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_compare.hlsl
new file mode 100644
index 0000000000000..a711acb8d47ab
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_compare.hlsl
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// Test that comparing two resource handles with == is rejected.
+//
+// DXC: also fails sema with a different message:
+// "operator cannot be used with built-in type 'RWByteAddressBuffer'"
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+bool Fail_Compare()
+{
+ RWByteAddressBuffer a = gBuf0;
+ RWByteAddressBuffer b = gBuf1;
+ return a == b;
+ // expected-error at -1 {{invalid operands to binary expression ('RWByteAddressBuffer' and 'RWByteAddressBuffer')}}
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ Fail_Compare();
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_const_param.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_const_param.hlsl
new file mode 100644
index 0000000000000..34e9fd5611fc5
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_const_param.hlsl
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that a local resource can be passed as a const parameter.
+//
+// DXC: passes (both sema and codegen).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+void ReadOnly(const RWByteAddressBuffer buf, uint offset, out uint result)
+{
+ result = 0;
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer local = gBuf0;
+ uint r;
+ ReadOnly(local, tid.x * 4, r);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_const_reassign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_const_reassign.hlsl
new file mode 100644
index 0000000000000..75a348d39ec0a
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_const_reassign.hlsl
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// Test that a const-qualified local resource cannot be reassigned.
+//
+// DXC: also fails sema with:
+// "cannot assign to variable 'buf' with const-qualified type
+// 'const RWByteAddressBuffer'"
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ const RWByteAddressBuffer buf = gBuf0;
+ buf = gBuf1;
+ // expected-warning at -1 {{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
+ // expected-note at -3 {{variable 'buf' is declared here}}
+ // expected-error at -3 {{no viable overloaded '='}}
+ // expected-note@*:* {{candidate function not viable: 'this' argument has type 'const RWByteAddressBuffer', but method is not marked const}}
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_copy_between_locals.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_copy_between_locals.hlsl
new file mode 100644
index 0000000000000..11531d1a85d46
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_copy_between_locals.hlsl
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that copying a local resource to another local works.
+//
+// DXC: passes (both sema and codegen).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer a = gBuf0;
+ RWByteAddressBuffer b = a;
+ b.Store(tid.x * 4, 42);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_deep_phi.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_deep_phi.hlsl
new file mode 100644
index 0000000000000..919c1ba6f18be
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_deep_phi.hlsl
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// DXC compiles this without any diagnostics (even with -Wall).
+// Clang emits a -Whlsl-explicit-binding warning for the ternary
+// resource assignment inside the if-branch; DXC does not.
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+RWByteAddressBuffer gBuf2 : register(u2);
+
+uint Pass_DeepPhi(bool a, bool b, uint idx)
+{
+ RWByteAddressBuffer buf;
+
+ if(a)
+ // DXC: no diagnostic. Clang: warning.
+ // expected-warning at +1{{assignment of 'b ? gBuf0 : gBuf1' to local resource 'buf' is not to the same unique global resource}}
+ buf = b ? gBuf0 : gBuf1;
+ else
+ buf = gBuf2;
+
+ buf.Store(idx * 4, 25);
+
+
+ return 25;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_DeepPhi(true, false, idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_param.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_param.hlsl
new file mode 100644
index 0000000000000..5e0df96430ee0
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_param.hlsl
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// Test that a resource parameter with a default value followed by a
+// parameter without a default is rejected (standard C++ rule).
+//
+// DXC: also fails sema with the same message:
+// "missing default argument on parameter 'offset'"
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+uint Fail_DefaultParam(RWByteAddressBuffer buf = gBuf0, uint offset)
+ // expected-error at -1 {{missing default argument on parameter 'offset'}}
+{
+ buf.Store(offset, 42);
+ return 42;
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ Fail_DefaultParam(gBuf0, tid.x * 4);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_different_types.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_different_types.hlsl
new file mode 100644
index 0000000000000..27783c3f12ad3
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_different_types.hlsl
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that two different resource types can coexist as local variables
+// in the same function.
+//
+// DXC: passes (both sema and codegen).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWStructuredBuffer<uint> gSB : register(u1);
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer localBuf = gBuf0;
+ RWStructuredBuffer<uint> localSB = gSB;
+ localBuf.Store(tid.x * 4, 42);
+ localSB[tid.x] = 99;
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_do_while_reassign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_do_while_reassign.hlsl
new file mode 100644
index 0000000000000..610aa540f6784
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_do_while_reassign.hlsl
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// Test that resource reassignment inside a do-while loop triggers
+// the -Whlsl-explicit-binding warning.
+//
+// DXC: passes silently (no diagnostics even with -Wall).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer buf = gBuf0;
+ // expected-note at -1 {{variable 'buf' is declared here}}
+ uint i = 0;
+ do {
+ buf = gBuf1;
+ // expected-warning at -1 {{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
+ i++;
+ } while(i < tid.x);
+ buf.Store(tid.x * 4, 42);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_early_return_reassign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_early_return_reassign.hlsl
new file mode 100644
index 0000000000000..776682131f9f3
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_early_return_reassign.hlsl
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// DXC compiles this without any diagnostics (even with -Wall).
+// Clang emits a -Whlsl-explicit-binding warning for the reassignment
+// to a different global after the early return; DXC does not.
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+uint Pass_EarlyReturn(bool cond, uint idx)
+{
+ // expected-note at +1{{variable 'buf' is declared here}}
+ RWByteAddressBuffer buf = gBuf0;
+
+ if(cond)
+ buf.Store(idx * 4, 31);
+
+ return 31;
+ // DXC: no diagnostic. Clang: warning.
+ // expected-warning at +1{{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
+ buf = gBuf1;
+ buf.Store(idx * 4, 31);
+
+ return 31;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_EarlyReturn(true, idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_forward_through_functions.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_forward_through_functions.hlsl
new file mode 100644
index 0000000000000..49290123c46b4
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_forward_through_functions.hlsl
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+RWByteAddressBuffer gBuf1 : register(u1);
+
+uint Pass_Level2(RWByteAddressBuffer buf, uint idx)
+{
+ buf.Store(idx*4, 17);
+ return 17;
+}
+
+uint Pass_Level1(RWByteAddressBuffer buf, uint idx)
+{
+ return Pass_Level2(buf, idx);
+}
+
+uint Pass_FunctionForward(uint idx)
+{
+ RWByteAddressBuffer buf = gBuf1;
+ return Pass_Level1(buf, idx);
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_FunctionForward(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_from_function_return.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_from_function_return.hlsl
new file mode 100644
index 0000000000000..3b9ee3ec6ec3b
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_from_function_return.hlsl
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that a local resource initialized from a function return value
+// works correctly.
+//
+// DXC: passes (both sema and codegen).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+RWByteAddressBuffer GetBuffer()
+{
+ return gBuf0;
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer buf = GetBuffer();
+ buf.Store(tid.x * 4, 42);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_inout_param.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_inout_param.hlsl
new file mode 100644
index 0000000000000..72c4d4019d9db
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_inout_param.hlsl
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that a local resource can be passed as an inout parameter.
+//
+// DXC: passes (both sema and codegen).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+void ReadAndWrite(inout RWByteAddressBuffer buf, uint offset, uint value)
+{
+ buf.Store(offset, value);
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer local = gBuf0;
+ ReadAndWrite(local, tid.x * 4, 42);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_array_index.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_array_index.hlsl
new file mode 100644
index 0000000000000..8daae29a695f9
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_array_index.hlsl
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+RWByteAddressBuffer gBufArray[4] : register(u10);
+
+uint Pass_Loop(uint idx)
+{
+ uint sum = 0;
+ for(unsigned int i=0;i<4;i++)
+ {
+ RWByteAddressBuffer buf = gBufArray[i];
+ buf.Store(idx * 4 + i * 4, 15);
+
+ sum += 15;
+ }
+ return sum;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_Loop(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_carried.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_carried.hlsl
new file mode 100644
index 0000000000000..3837bf38d6387
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_carried.hlsl
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// DXC compiles this without any diagnostics (even with -Wall).
+// Clang emits a -Whlsl-explicit-binding warning for the loop-carried
+// reassignment from a different array element; DXC does not.
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBufArray[4] : register(u10);
+
+uint Pass_LoopCarried(int iterations, uint idx)
+{
+ // expected-note at +1{{variable 'buf' is declared here}}
+ RWByteAddressBuffer buf = gBuf0;
+
+ for(int i=0;i<iterations;i++)
+ // DXC: no diagnostic. Clang: warning.
+ // expected-warning at +1{{assignment of 'gBufArray[i & 3]' to local resource 'buf' is not to the same unique global resource}}
+ buf = gBufArray[i & 3];
+
+ buf.Store(idx * 4, 26);
+
+
+ return 26;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_LoopCarried(15, idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_mixed_struct.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_mixed_struct.hlsl
new file mode 100644
index 0000000000000..8650bac84891a
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_mixed_struct.hlsl
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that a struct with both a resource member and a scalar member
+// can be used as a local variable.
+//
+// DXC: passes (both sema and codegen).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+struct Node {
+ RWByteAddressBuffer buf;
+ uint next;
+};
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ Node n;
+ n.buf = gBuf0;
+ n.next = 0;
+ n.buf.Store(tid.x * 4, n.next);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multiple_uses.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multiple_uses.hlsl
new file mode 100644
index 0000000000000..1fea3ccd6f18b
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multiple_uses.hlsl
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that the same local resource can be passed to multiple helper
+// functions within a single shader.
+//
+// DXC: passes (both sema and codegen).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+void HelperA(RWByteAddressBuffer buf, uint offset)
+{
+ buf.Store(offset, 1);
+}
+
+void HelperB(RWByteAddressBuffer buf, uint offset)
+{
+ buf.Store(offset, 2);
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer local = gBuf0;
+ HelperA(local, tid.x * 4);
+ HelperB(local, tid.x * 4 + 4);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_blocks_reassign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_blocks_reassign.hlsl
new file mode 100644
index 0000000000000..8fecb384cb2ff
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_blocks_reassign.hlsl
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// DXC compiles this without any diagnostics (even with -Wall).
+// Clang emits a -Whlsl-explicit-binding warning for the nested block
+// reassignment to a different global; DXC does not.
+
+RWByteAddressBuffer gBuf1 : register(u1);
+RWByteAddressBuffer gBuf2 : register(u2);
+
+uint Pass_NestedBlocks(uint idx)
+{
+ // expected-note at +1{{variable 'buf' is declared here}}
+ RWByteAddressBuffer buf;
+
+ {
+ buf = gBuf1;
+ {
+ // DXC: no diagnostic. Clang: warning.
+ // expected-warning at +1{{assignment of 'gBuf2' to local resource 'buf' is not to the same unique global resource}}
+ buf = gBuf2;
+ }
+ }
+
+ buf.Store(idx * 4, 32);
+
+
+ return 32;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_NestedBlocks(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_loops.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_loops.hlsl
new file mode 100644
index 0000000000000..93999d264565d
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_loops.hlsl
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+RWByteAddressBuffer gBufArray[4] : register(u10);
+
+uint Pass_NestedLoops(uint idx)
+{
+ uint sum = 0;
+ for(unsigned int i=0;i<2;i++)
+ for(unsigned int j=0;j<2;j++)
+ {
+ RWByteAddressBuffer buf = gBufArray[i+j];
+ buf.Store(idx * 4 + (i+j)*4, 23);
+
+ sum += 23;
+ }
+ return sum;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_NestedLoops(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_out_param.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_out_param.hlsl
new file mode 100644
index 0000000000000..4effb3f6bfdb8
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_out_param.hlsl
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that a local resource can be written through an out parameter.
+//
+// DXC: passes (both sema and codegen).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+void WriteThrough(out RWByteAddressBuffer buf)
+{
+ buf = gBuf0;
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer local;
+ WriteThrough(local);
+ local.Store(tid.x * 4, 42);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_reassign_different_global.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_reassign_different_global.hlsl
new file mode 100644
index 0000000000000..334623be44d45
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_reassign_different_global.hlsl
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// DXC compiles this without any diagnostics (even with -Wall).
+// Clang emits -Whlsl-explicit-binding warnings for reassignment
+// to a different global; DXC does not.
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+uint Pass_Reassign(uint idx)
+{
+ // expected-note at +1{{variable 'buf' is declared here}}
+ RWByteAddressBuffer buf = gBuf0;
+ // expected-warning at +1{{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
+ buf = gBuf1;
+ buf.Store(idx * 4, 13);
+
+ return 13;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_Reassign(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_self_assign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_self_assign.hlsl
new file mode 100644
index 0000000000000..eb071bcdea58a
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_self_assign.hlsl
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that self-assignment of a local resource compiles cleanly.
+//
+// DXC: passes (both sema and codegen).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer buf = gBuf0;
+ buf = buf;
+ buf.Store(tid.x * 4, 42);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_shadow_inner_scope.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_shadow_inner_scope.hlsl
new file mode 100644
index 0000000000000..efa45af3b0086
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_shadow_inner_scope.hlsl
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+uint Pass_Shadow(uint idx)
+{
+ RWByteAddressBuffer buf = gBuf0;
+ {
+ RWByteAddressBuffer buf = gBuf1;
+ buf.Store(idx * 4, 19);
+
+ return 19;
+ }
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_Shadow(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_local.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_local.hlsl
new file mode 100644
index 0000000000000..778da88a5ee05
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_local.hlsl
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that a static local resource variable initialized from a global
+// is accepted by both compilers.
+//
+// DXC: passes (both sema and codegen) with RWByteAddressBuffer.
+// Note: DXC asserts/ICEs when Texture2D is used instead.
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+uint Pass_StaticLocal(uint idx)
+{
+ static RWByteAddressBuffer buf = gBuf0;
+ buf.Store(idx * 4, 1);
+
+ return 1;
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ Pass_StaticLocal(tid.x);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_return.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_return.hlsl
new file mode 100644
index 0000000000000..0563300c30ebd
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_return.hlsl
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that a function can return a struct containing a resource member.
+//
+// DXC: passes (both sema and codegen).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+struct ResHolder { RWByteAddressBuffer buf; };
+
+ResHolder MakeHolder()
+{
+ ResHolder h;
+ h.buf = gBuf0;
+ return h;
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ ResHolder h = MakeHolder();
+ h.buf.Store(tid.x * 4, 42);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_fallthrough.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_fallthrough.hlsl
new file mode 100644
index 0000000000000..4c7e8dd89a992
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_fallthrough.hlsl
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// DXC compiles this without any diagnostics (even with -Wall).
+// Clang emits -Whlsl-explicit-binding warnings for switch-case
+// fallthrough reassignments to different globals; DXC does not.
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+RWByteAddressBuffer gBuf2 : register(u2);
+
+uint Pass_SwitchFallthrough(int v, uint idx)
+{
+ // expected-note at +2{{variable 'buf' is declared here}}
+ // expected-note at +1{{variable 'buf' is declared here}}
+ RWByteAddressBuffer buf = gBuf0;
+
+ switch(v)
+ {
+ // DXC: no diagnostic. Clang: warning.
+ // expected-warning at +1{{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
+ case 0: buf = gBuf1;
+ // DXC: no diagnostic. Clang: warning.
+ // expected-warning at +1{{assignment of 'gBuf2' to local resource 'buf' is not to the same unique global resource}}
+ case 1: buf = gBuf2; break;
+ }
+
+ buf.Store(idx * 4, 30);
+
+
+ return 30;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_SwitchFallthrough(0, idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_reassign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_reassign.hlsl
new file mode 100644
index 0000000000000..2b561f240fdbc
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_reassign.hlsl
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// DXC compiles this without any diagnostics (even with -Wall).
+// Clang emits -Whlsl-explicit-binding warnings for switch-case
+// reassignments to different globals; DXC does not.
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+RWByteAddressBuffer gBuf2 : register(u2);
+
+uint Pass_Switch(int v, uint idx)
+{
+ // expected-note at +2{{variable 'buf' is declared here}}
+ // expected-note at +1{{variable 'buf' is declared here}}
+ RWByteAddressBuffer buf = gBuf0;
+
+ switch(v)
+ {
+ // DXC: no diagnostic. Clang: warning.
+ // expected-warning at +1{{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
+ case 1: buf = gBuf1; break;
+ // DXC: no diagnostic. Clang: warning.
+ // expected-warning at +1{{assignment of 'gBuf2' to local resource 'buf' is not to the same unique global resource}}
+ case 2: buf = gBuf2; break;
+ }
+
+ buf.Store(idx * 4, 20);
+
+
+ return 20;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_Switch(1, idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_to_bool.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_to_bool.hlsl
new file mode 100644
index 0000000000000..93f0fc076c099
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_to_bool.hlsl
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// Test that implicit conversion of a resource handle to bool is rejected.
+//
+// DXC: also fails sema with a different message:
+// "cannot initialize return object of type 'bool' with an lvalue
+// of type 'RWByteAddressBuffer'"
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+bool Fail_Bool()
+{
+ RWByteAddressBuffer buf = gBuf0;
+ return buf;
+ // expected-error at -1 {{no viable conversion from returned value of type 'RWByteAddressBuffer' to function return type 'bool'}}
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ Fail_Bool();
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_unreachable_reassign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_unreachable_reassign.hlsl
new file mode 100644
index 0000000000000..089f3760f6abd
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_unreachable_reassign.hlsl
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// Test that resource reassignment after an early return (in dead code
+// from the perspective of the early-return path) still triggers the
+// -Whlsl-explicit-binding warning.
+//
+// DXC: passes silently (no diagnostics even with -Wall).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer buf = gBuf0;
+ // expected-note at -1 {{variable 'buf' is declared here}}
+ if(tid.x > 0) {
+ buf.Store(0, 1);
+ return;
+ }
+ buf = gBuf1;
+ // expected-warning at -1 {{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
+ buf.Store(tid.x * 4, 42);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_volatile.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_volatile.hlsl
new file mode 100644
index 0000000000000..9b9e8dd9bea5e
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_volatile.hlsl
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// Test that the volatile qualifier on a local resource prevents calling
+// methods on it, because the methods are not marked volatile.
+//
+// DXC: accepts volatile on resources and compiles successfully.
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ volatile RWByteAddressBuffer buf = gBuf0;
+ // expected-note@*:* {{candidate function template not viable: 'this' argument has type 'volatile RWByteAddressBuffer', but method is not marked volatile}}
+ // expected-note@*:* {{candidate function not viable: 'this' argument has type 'volatile RWByteAddressBuffer', but method is not marked volatile}}
+ // expected-error at +1 {{no matching member function for call to 'Store'}}
+ buf.Store(tid.x * 4, 42);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_with_wave_intrinsic.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_with_wave_intrinsic.hlsl
new file mode 100644
index 0000000000000..a6a3be39d45bd
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_with_wave_intrinsic.hlsl
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+uint Pass_WaveUse(uint idx)
+{
+ RWByteAddressBuffer buf = gBuf0;
+ uint active = WaveActiveCountBits(true);
+ buf.Store(idx * 4, active);
+
+ return active;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_WaveUse(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_struct_resource_member.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_struct_resource_member.hlsl
new file mode 100644
index 0000000000000..2046b176fab26
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_struct_resource_member.hlsl
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+struct PassStruct
+{
+ RWByteAddressBuffer buf;
+};
+
+uint Pass_Struct(uint idx)
+{
+ PassStruct s;
+ s.buf = gBuf0;
+ s.buf.Store(idx * 4, 16);
+
+ return 16;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_Struct(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/loop_var.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/loop_var.hlsl
index 71d1a1b4302b0..5da4339b559c1 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/loop_var.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/loop_var.hlsl
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -verify
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
// expected-no-diagnostics
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/nested_struct_resource_member.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/nested_struct_resource_member.hlsl
new file mode 100644
index 0000000000000..f2607c3092c12
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/nested_struct_resource_member.hlsl
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+RWByteAddressBuffer gBuf1 : register(u1);
+
+struct NestedInner { RWByteAddressBuffer buf; };
+struct NestedOuter { NestedInner inner; };
+
+uint Pass_NestedStruct(uint idx)
+{
+ NestedOuter s;
+ s.inner.buf = gBuf1;
+ s.inner.buf.Store(idx * 4, 28);
+
+ return 28;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_NestedStruct(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_initialized.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_initialized.hlsl
new file mode 100644
index 0000000000000..0be18c8c18450
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_initialized.hlsl
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+RWByteAddressBuffer Pass_ReturnLocal()
+{
+ RWByteAddressBuffer buf = gBuf0;
+ return buf;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer tmp = Pass_ReturnLocal();
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_uninitialized.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_uninitialized.hlsl
new file mode 100644
index 0000000000000..a0409412696c7
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_uninitialized.hlsl
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+RWByteAddressBuffer Pass_ReturnLocal_Uninitialized()
+{
+ RWByteAddressBuffer buf;
+ return buf;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer tmp = Pass_ReturnLocal_Uninitialized();
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/struct_array_with_resource_member.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/struct_array_with_resource_member.hlsl
new file mode 100644
index 0000000000000..057f4bae8e32e
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/struct_array_with_resource_member.hlsl
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+struct BufStruct { RWByteAddressBuffer buf; };
+
+uint Pass_StructArray(uint idx)
+{
+ BufStruct s[2];
+ s[0].buf = gBuf0;
+ s[0].buf.Store(idx * 4, 5);
+
+ return 5;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_StructArray(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/struct_resource_member_reassign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/struct_resource_member_reassign.hlsl
new file mode 100644
index 0000000000000..ba2e64fbca32f
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/struct_resource_member_reassign.hlsl
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that reassigning the resource member of a local struct to a
+// different global compiles without error.
+//
+// DXC: passes (both sema and codegen).
+// Note: clang does not warn here because -Whlsl-explicit-binding
+// tracks local resource variables, not struct member assignments.
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+struct ResHolder { RWByteAddressBuffer buf; };
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ ResHolder h;
+ h.buf = gBuf0;
+ h.buf = gBuf1;
+ h.buf.Store(tid.x * 4, 42);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/struct_with_resource_array_member.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/struct_with_resource_array_member.hlsl
new file mode 100644
index 0000000000000..bad04c673bb84
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/struct_with_resource_array_member.hlsl
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+struct S { RWByteAddressBuffer arr[2]; };
+
+uint Pass_StructArrayAssignment(uint idx)
+{
+ S s;
+ s.arr[0] = gBuf0;
+ s.arr[0].Store(idx * 4, 9);
+
+ return 9;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_StructArrayAssignment(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared.hlsl
index 1c6d0f9e35f0a..30bae24d853ac 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared.hlsl
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -verify
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
// This test fails validation in DXC, but DXC's sema allows it.
// Meanwhile, groupshared is immediately detected and rejected in clang's sema.
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared_direct_store.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared_direct_store.hlsl
new file mode 100644
index 0000000000000..b09e459f7d60c
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared_direct_store.hlsl
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// Test that calling Store directly on a groupshared resource is rejected
+// because the method expects a generic address space object.
+//
+// This is distinct from use_groupshared.hlsl, which tests passing a
+// groupshared resource as a function argument (constructor mismatch).
+//
+// DXC: allows this at sema but rejects during validation.
+
+groupshared RWByteAddressBuffer sharedBuf;
+
+uint Use_SharedDirect(uint idx)
+{
+ // expected-note@*:*{{candidate function template not viable: 'this' object is in address space 'groupshared', but method expects object in generic address space}}
+ // expected-note@*:*{{candidate function not viable: 'this' object is in address space 'groupshared', but method expects object in generic address space}}
+ // expected-error at +1{{no matching member function for call to 'Store'}}
+ sharedBuf.Store(idx * 4, 1);
+ return 1;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Use_SharedDirect(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/use_local_resource_uninitialized.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/use_local_resource_uninitialized.hlsl
new file mode 100644
index 0000000000000..fc6612e62c46d
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/use_local_resource_uninitialized.hlsl
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+uint Pass_Uninitialized(uint idx)
+{
+ RWByteAddressBuffer buf;
+ buf.Store(idx * 4, 11);
+
+ return 11;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_Uninitialized(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.hlsl
index 3f47ae6db82c6..9e1579336fb1e 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.hlsl
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -verify
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
// This test fails validation in DXC, but DXC's sema allows it.
// Meanwhile, it is for some reason accepted by clang's sema.
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.ll b/clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.ll
deleted file mode 100644
index b84ac5379905c..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.ll
+++ /dev/null
@@ -1,255 +0,0 @@
-; ModuleID = 'D:\llvm-project\clang\test\SemaHLSL\Resources\Local-Resources\use_struct_groupshared.hlsl'
-source_filename = "D:\\llvm-project\\clang\\test\\SemaHLSL\\Resources\\Local-Resources\\use_struct_groupshared.hlsl"
-target datalayout = "e-m:e-ve-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64"
-target triple = "dxilv1.6-pc-shadermodel6.6-compute"
-
-%"class.hlsl::RWByteAddressBuffer" = type { target("dx.RawBuffer", i8, 1, 0) }
-%struct.PassBufStruct = type { %"class.hlsl::RWByteAddressBuffer" }
-
- at _ZL4gOut = internal global %"class.hlsl::RWByteAddressBuffer" poison, align 4
- at .str = private unnamed_addr constant [5 x i8] c"gOut\00", align 1
- at _ZL16sharedStruct.buf = internal global %"class.hlsl::RWByteAddressBuffer" poison, align 4
- at .str.2 = private unnamed_addr constant [17 x i8] c"sharedStruct.buf\00", align 1
- at sharedStruct = external hidden addrspace(3) global %struct.PassBufStruct, align 4
-
-; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
-define hidden noundef i32 @_Z7DoStoreN4hlsl19RWByteAddressBufferEjj(ptr noundef byval(%"class.hlsl::RWByteAddressBuffer") align 4 %buf, i32 noundef %offset, i32 noundef %value) #0 {
-entry:
- %this.addr.i = alloca ptr, align 4
- %Index.addr.i = alloca i32, align 4
- %Value.addr.i = alloca i32, align 4
- %offset.addr = alloca i32, align 4
- %value.addr = alloca i32, align 4
- store i32 %offset, ptr %offset.addr, align 4
- store i32 %value, ptr %value.addr, align 4
- %0 = load i32, ptr %offset.addr, align 4
- %1 = load i32, ptr %value.addr, align 4
- store ptr %buf, ptr %this.addr.i, align 4
- store i32 %0, ptr %Index.addr.i, align 4
- store i32 %1, ptr %Value.addr.i, align 4
- %this1.i = load ptr, ptr %this.addr.i, align 4
- %2 = load i32, ptr %Value.addr.i, align 4
- %3 = load target("dx.RawBuffer", i8, 1, 0), ptr %this1.i, align 4
- %4 = load i32, ptr %Index.addr.i, align 4
- %5 = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i8_1_0t.i32(target("dx.RawBuffer", i8, 1, 0) %3, i32 %4)
- store i32 %2, ptr %5, align 4
- %6 = load i32, ptr %value.addr, align 4
- ret i32 %6
-}
-
-; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
-define hidden noundef i32 @_Z20Use_PassSharedStructj(i32 noundef %idx) #0 {
-entry:
- %this.addr.i4 = alloca ptr, align 4
- %other.addr.i5 = alloca ptr, align 4
- %this.addr.i2 = alloca ptr, align 4
- %other.addr.i = alloca ptr, align 4
- %this.addr.i = alloca ptr, align 4
- %Index.addr.i = alloca i32, align 4
- %Value.addr.i = alloca i32, align 4
- %offset.addr.i = alloca i32, align 4
- %value.addr.i = alloca i32, align 4
- %agg.tmp1 = alloca %"class.hlsl::RWByteAddressBuffer", align 8
- %idx.addr = alloca i32, align 4
- %agg.tmp = alloca %"class.hlsl::RWByteAddressBuffer", align 4
- store i32 %idx, ptr %idx.addr, align 4
- store ptr %agg.tmp, ptr %this.addr.i2, align 4
- store ptr addrspacecast (ptr addrspace(3) @sharedStruct to ptr), ptr %other.addr.i, align 4
- %this1.i3 = load ptr, ptr %this.addr.i2, align 4
- %0 = load ptr, ptr %other.addr.i, align 4
- store ptr %this1.i3, ptr %this.addr.i4, align 4
- store ptr %0, ptr %other.addr.i5, align 4
- %this1.i6 = load ptr, ptr %this.addr.i4, align 4
- %1 = load ptr, ptr %other.addr.i5, align 4, !nonnull !3, !align !4
- %2 = load target("dx.RawBuffer", i8, 1, 0), ptr %1, align 4
- store target("dx.RawBuffer", i8, 1, 0) %2, ptr %this1.i6, align 4
- %3 = load i32, ptr %idx.addr, align 4
- %mul = mul i32 %3, 4
- call void @llvm.memcpy.p0.p0.i64(ptr align 8 %agg.tmp1, ptr align 4 %agg.tmp, i64 4, i1 false)
- store i32 %mul, ptr %offset.addr.i, align 4
- store i32 1, ptr %value.addr.i, align 4
- %4 = load i32, ptr %offset.addr.i, align 4
- %5 = load i32, ptr %value.addr.i, align 4
- store ptr %agg.tmp1, ptr %this.addr.i, align 4
- store i32 %4, ptr %Index.addr.i, align 4
- store i32 %5, ptr %Value.addr.i, align 4
- %this1.i = load ptr, ptr %this.addr.i, align 4
- %6 = load i32, ptr %Value.addr.i, align 4
- %7 = load target("dx.RawBuffer", i8, 1, 0), ptr %this1.i, align 4
- %8 = load i32, ptr %Index.addr.i, align 4
- %9 = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i8_1_0t.i32(target("dx.RawBuffer", i8, 1, 0) %7, i32 %8)
- store i32 %6, ptr %9, align 4
- %10 = load i32, ptr %value.addr.i, align 4
- ret i32 %10
-}
-
-; Function Attrs: convergent noinline norecurse
-define void @main() #1 {
-entry:
- %this.addr.i12.i = alloca ptr, align 4
- %other.addr.i13.i = alloca ptr, align 4
- %this.addr.i9.i = alloca ptr, align 4
- %other.addr.i10.i = alloca ptr, align 4
- %this.addr.i6.i = alloca ptr, align 4
- %other.addr.i7.i = alloca ptr, align 4
- %this.addr.i.i1 = alloca ptr, align 4
- %other.addr.i.i2 = alloca ptr, align 4
- %orderId.addr.i.i = alloca i32, align 4
- %spaceNo.addr.i1.i = alloca i32, align 4
- %range.addr.i2.i = alloca i32, align 4
- %index.addr.i3.i = alloca i32, align 4
- %name.addr.i4.i = alloca ptr, align 4
- %tmp.i5.i = alloca %"class.hlsl::RWByteAddressBuffer", align 4
- %registerNo.addr.i.i = alloca i32, align 4
- %spaceNo.addr.i.i = alloca i32, align 4
- %range.addr.i.i = alloca i32, align 4
- %index.addr.i.i = alloca i32, align 4
- %name.addr.i.i = alloca ptr, align 4
- %tmp.i.i = alloca %"class.hlsl::RWByteAddressBuffer", align 4
- %this.addr.i = alloca ptr, align 4
- %other.addr.i = alloca ptr, align 4
- %this.addr.i.i = alloca ptr, align 4
- %other.addr.i.i = alloca ptr, align 4
- %this.addr.i.i.i = alloca ptr, align 4
- %Index.addr.i.i.i = alloca i32, align 4
- %Value.addr.i.i.i = alloca i32, align 4
- %offset.addr.i.i.i = alloca i32, align 4
- %value.addr.i.i.i = alloca i32, align 4
- %agg.tmp1.i.i = alloca %"class.hlsl::RWByteAddressBuffer", align 8
- %idx.addr.i.i = alloca i32, align 4
- %agg.tmp.i.i = alloca %"class.hlsl::RWByteAddressBuffer", align 4
- %tid.addr.i = alloca <3 x i32>, align 4
- %idx.i = alloca i32, align 4
- call void @llvm.experimental.noalias.scope.decl(metadata !5)
- store i32 3, ptr %registerNo.addr.i.i, align 4, !noalias !5
- store i32 0, ptr %spaceNo.addr.i.i, align 4, !noalias !5
- store i32 1, ptr %range.addr.i.i, align 4, !noalias !5
- store i32 0, ptr %index.addr.i.i, align 4, !noalias !5
- store ptr @.str, ptr %name.addr.i.i, align 4, !noalias !5
- %0 = load i32, ptr %registerNo.addr.i.i, align 4, !noalias !5
- %1 = load i32, ptr %spaceNo.addr.i.i, align 4, !noalias !5
- %2 = load i32, ptr %range.addr.i.i, align 4, !noalias !5
- %3 = load i32, ptr %index.addr.i.i, align 4, !noalias !5
- %4 = load ptr, ptr %name.addr.i.i, align 4, !noalias !5
- %5 = call target("dx.RawBuffer", i8, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_1_0t(i32 %1, i32 %0, i32 %2, i32 %3, ptr %4)
- store target("dx.RawBuffer", i8, 1, 0) %5, ptr %tmp.i.i, align 4, !noalias !5
- store ptr @_ZL4gOut, ptr %this.addr.i6.i, align 4
- store ptr %tmp.i.i, ptr %other.addr.i7.i, align 4
- %this1.i8.i = load ptr, ptr %this.addr.i6.i, align 4
- %6 = load ptr, ptr %other.addr.i7.i, align 4
- store ptr %this1.i8.i, ptr %this.addr.i9.i, align 4
- store ptr %6, ptr %other.addr.i10.i, align 4
- %this1.i11.i = load ptr, ptr %this.addr.i9.i, align 4
- %7 = load ptr, ptr %other.addr.i10.i, align 4, !nonnull !3, !align !4
- %8 = load target("dx.RawBuffer", i8, 1, 0), ptr %7, align 4
- store target("dx.RawBuffer", i8, 1, 0) %8, ptr %this1.i11.i, align 4
- call void @llvm.experimental.noalias.scope.decl(metadata !8)
- store i32 0, ptr %orderId.addr.i.i, align 4, !noalias !8
- store i32 0, ptr %spaceNo.addr.i1.i, align 4, !noalias !8
- store i32 1, ptr %range.addr.i2.i, align 4, !noalias !8
- store i32 0, ptr %index.addr.i3.i, align 4, !noalias !8
- store ptr @.str.2, ptr %name.addr.i4.i, align 4, !noalias !8
- %9 = load i32, ptr %orderId.addr.i.i, align 4, !noalias !8
- %10 = load i32, ptr %spaceNo.addr.i1.i, align 4, !noalias !8
- %11 = load i32, ptr %range.addr.i2.i, align 4, !noalias !8
- %12 = load i32, ptr %index.addr.i3.i, align 4, !noalias !8
- %13 = load ptr, ptr %name.addr.i4.i, align 4, !noalias !8
- %14 = call target("dx.RawBuffer", i8, 1, 0) @llvm.dx.resource.handlefromimplicitbinding.tdx.RawBuffer_i8_1_0t(i32 %9, i32 %10, i32 %11, i32 %12, ptr %13)
- store target("dx.RawBuffer", i8, 1, 0) %14, ptr %tmp.i5.i, align 4, !noalias !8
- store ptr @_ZL16sharedStruct.buf, ptr %this.addr.i.i1, align 4
- store ptr %tmp.i5.i, ptr %other.addr.i.i2, align 4
- %this1.i.i3 = load ptr, ptr %this.addr.i.i1, align 4
- %15 = load ptr, ptr %other.addr.i.i2, align 4
- store ptr %this1.i.i3, ptr %this.addr.i12.i, align 4
- store ptr %15, ptr %other.addr.i13.i, align 4
- %this1.i14.i = load ptr, ptr %this.addr.i12.i, align 4
- %16 = load ptr, ptr %other.addr.i13.i, align 4, !nonnull !3, !align !4
- %17 = load target("dx.RawBuffer", i8, 1, 0), ptr %16, align 4
- store target("dx.RawBuffer", i8, 1, 0) %17, ptr %this1.i14.i, align 4
- %18 = call i32 @llvm.dx.thread.id(i32 0)
- %19 = insertelement <3 x i32> poison, i32 %18, i64 0
- %20 = call i32 @llvm.dx.thread.id(i32 1)
- %21 = insertelement <3 x i32> %19, i32 %20, i64 1
- %22 = call i32 @llvm.dx.thread.id(i32 2)
- %23 = insertelement <3 x i32> %21, i32 %22, i64 2
- store <3 x i32> %23, ptr %tid.addr.i, align 4
- %24 = load <3 x i32>, ptr %tid.addr.i, align 4
- %25 = extractelement <3 x i32> %24, i32 0
- %26 = load <3 x i32>, ptr %tid.addr.i, align 4
- %27 = extractelement <3 x i32> %26, i32 1
- %mul.i = mul i32 %27, 8
- %add.i = add i32 %25, %mul.i
- store i32 %add.i, ptr %idx.i, align 4
- %28 = load i32, ptr %idx.i, align 4
- store i32 %28, ptr %idx.addr.i.i, align 4
- store ptr %agg.tmp.i.i, ptr %this.addr.i.i, align 4
- store ptr addrspacecast (ptr addrspace(3) @sharedStruct to ptr), ptr %other.addr.i.i, align 4
- %this1.i.i = load ptr, ptr %this.addr.i.i, align 4
- %29 = load ptr, ptr %other.addr.i.i, align 4
- store ptr %this1.i.i, ptr %this.addr.i, align 4
- store ptr %29, ptr %other.addr.i, align 4
- %this1.i = load ptr, ptr %this.addr.i, align 4
- %30 = load ptr, ptr %other.addr.i, align 4, !nonnull !3, !align !4
- %31 = load target("dx.RawBuffer", i8, 1, 0), ptr %30, align 4
- store target("dx.RawBuffer", i8, 1, 0) %31, ptr %this1.i, align 4
- %32 = load i32, ptr %idx.addr.i.i, align 4
- %mul.i.i = mul i32 %32, 4
- call void @llvm.memcpy.p0.p0.i64(ptr align 8 %agg.tmp1.i.i, ptr align 4 %agg.tmp.i.i, i64 4, i1 false)
- store i32 %mul.i.i, ptr %offset.addr.i.i.i, align 4
- store i32 1, ptr %value.addr.i.i.i, align 4
- %33 = load i32, ptr %offset.addr.i.i.i, align 4
- %34 = load i32, ptr %value.addr.i.i.i, align 4
- store ptr %agg.tmp1.i.i, ptr %this.addr.i.i.i, align 4
- store i32 %33, ptr %Index.addr.i.i.i, align 4
- store i32 %34, ptr %Value.addr.i.i.i, align 4
- %this1.i.i.i = load ptr, ptr %this.addr.i.i.i, align 4
- %35 = load i32, ptr %Value.addr.i.i.i, align 4
- %36 = load target("dx.RawBuffer", i8, 1, 0), ptr %this1.i.i.i, align 4
- %37 = load i32, ptr %Index.addr.i.i.i, align 4
- %38 = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i8_1_0t.i32(target("dx.RawBuffer", i8, 1, 0) %36, i32 %37)
- store i32 %35, ptr %38, align 4
- %39 = load i32, ptr %value.addr.i.i.i, align 4
- ret void
-}
-
-; Function Attrs: nounwind willreturn memory(none)
-declare i32 @llvm.dx.thread.id(i32) #2
-
-; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
-declare target("dx.RawBuffer", i8, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_1_0t(i32, i32, i32, i32, ptr) #3
-
-; Function Attrs: convergent nocallback nofree nosync nounwind willreturn memory(none)
-declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i8_1_0t.i32(target("dx.RawBuffer", i8, 1, 0), i32) #4
-
-; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
-declare target("dx.RawBuffer", i8, 1, 0) @llvm.dx.resource.handlefromimplicitbinding.tdx.RawBuffer_i8_1_0t(i32, i32, i32, i32, ptr) #3
-
-; Function Attrs: nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
-declare void @llvm.experimental.noalias.scope.decl(metadata) #5
-
-; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
-declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #6
-
-attributes #0 = { alwaysinline convergent mustprogress norecurse nounwind "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
-attributes #1 = { convergent noinline norecurse "hlsl.numthreads"="8,8,1" "hlsl.shader"="compute" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
-attributes #2 = { nounwind willreturn memory(none) }
-attributes #3 = { nocallback nofree nosync nounwind willreturn memory(none) }
-attributes #4 = { convergent nocallback nofree nosync nounwind willreturn memory(none) }
-attributes #5 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
-attributes #6 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
-
-!dx.valver = !{!0}
-!llvm.module.flags = !{!1}
-!llvm.ident = !{!2}
-
-!0 = !{i32 1, i32 8}
-!1 = !{i32 4, !"dx.disable_optimizations", i32 1}
-!2 = !{!"clang version 23.0.0git (https://github.com/llvm/llvm-project.git b084fa7a5172e2502324f9df2723e22dad071e3a)"}
-!3 = !{}
-!4 = !{i64 4}
-!5 = !{!6}
-!6 = distinct !{!6, !7, !"_ZN4hlsl19RWByteAddressBuffer19__createFromBindingEjjijPKc: %agg.result"}
-!7 = distinct !{!7, !"_ZN4hlsl19RWByteAddressBuffer19__createFromBindingEjjijPKc"}
-!8 = !{!9}
-!9 = distinct !{!9, !10, !"_ZN4hlsl19RWByteAddressBuffer27__createFromImplicitBindingEjjijPKc: %agg.result"}
-!10 = distinct !{!10, !"_ZN4hlsl19RWByteAddressBuffer27__createFromImplicitBindingEjjijPKc"}
diff --git a/clang/test/SemaHLSL/Resources/local_resources_failures.hlsl b/clang/test/SemaHLSL/Resources/local_resources_failures.hlsl
deleted file mode 100644
index aee4d33815e51..0000000000000
--- a/clang/test/SemaHLSL/Resources/local_resources_failures.hlsl
+++ /dev/null
@@ -1,175 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -verify
-
-Texture2D<float4> gTex0 : register(t0);
-Texture2D<float4> gTex1 : register(t1);
-SamplerState gSampler : register(s0);
-
-StructuredBuffer<float4> gSB : register(t2);
-RWStructuredBuffer<float4> gRW : register(u0);
-
-Texture2D<float4> gTexArray[4] : register(t10);
-
-//--------------------------------------------------------------
-// FAIL 1: static local resource
-//--------------------------------------------------------------
-// This causes an assert in DXC
-float4 Fail_Static(float2 uv)
-{
- static Texture2D<float4> tex = gTex0;
- // expected-error at -1 {{static resource}}
- return tex.Sample(gSampler, uv);
-}
-
-//--------------------------------------------------------------
-// FAIL 2: arithmetic on resource
-//--------------------------------------------------------------
-
-float Fail_Arithmetic()
-{
- Texture2D<float4> tex = gTex0;
- tex = tex + 1;
- // expected-error at -1 {{scalar, vector, or matrix expected}}
- return tex;
- // expected-error at -1 {{cannot initialize return object of type 'float' with an lvalue of type 'Texture2D<float4>'}}
-}
-
-//--------------------------------------------------------------
-// FAIL 3: comparison of resources
-//--------------------------------------------------------------
-
-bool Fail_Compare()
-{
- Texture2D<float4> a = gTex0;
- Texture2D<float4> b = gTex1;
- return a == b;
- // expected-error at -1 {{operator cannot be used with built-in type 'Texture2D<vector<float, 4> >'}}
-}
-
-//--------------------------------------------------------------
-// FAIL 4: conversion to bool
-//--------------------------------------------------------------
-
-bool Fail_Bool()
-{
- Texture2D<float4> tex = gTex0;
- return tex;
- // expected-error at -1 {{cannot initialize return object of type 'bool' with an lvalue of type 'Texture2D<float4>'}}
-}
-
-//--------------------------------------------------------------
-// FAIL 5: cast from resource
-//--------------------------------------------------------------
-
-uint Fail_Cast()
-{
- Texture2D<float4> tex = gTex0;
- return (uint)tex;
- // expected-error at -1 {{cannot convert from 'Texture2D<float4>' to 'uint'}}
-}
-
-//--------------------------------------------------------------
-// FAIL 6: addition of resources
-//--------------------------------------------------------------
-
-float Fail_Add()
-{
- Texture2D<float4> tex = gTex0;
- return tex + tex;
- // expected-error at -1 {{scalar, vector, or matrix expected}}
-}
-
-
-//--------------------------------------------------------------
-// FAIL 7: default parameter on resource
-//--------------------------------------------------------------
-
-float4 Fail_DefaultParam(Texture2D<float4> tex = gTex0, float2 uv)
- // expected-error at -1 {{missing default argument on parameter 'uv'}}
- // expected-note at -2 {{candidate function not viable: requires 2 arguments, but 1 was provided}}
- // note, this note above does not get emitted when -verify is passed as an option.
-{
- return tex.Sample(gSampler, uv);
-}
-
-//--------------------------------------------------------------
-// FAIL 8: reinterpret cast
-//--------------------------------------------------------------
-
-float4 Fail_Reinterpret(float2 uv)
-{
- Texture2D<float4> tex = gTex0;
- return ((Texture2D<float4>)gSampler).Sample(gSampler, uv);
- // expected-error at -1 {{cannot convert from 'SamplerState' to 'Texture2D<float4>'}}
-}
-
-//--------------------------------------------------------------
-// FAIL 9: RWStructuredBuffer with resource type
-//--------------------------------------------------------------
-
-void Fail_LocalBuffer()
-{
- RWStructuredBuffer<Texture2D<float4> > badBuffer;
- // expected-error at -1 {{object 'Texture2D<float4>' is not allowed in builtin template parameters}}
-}
-
-//--------------------------------------------------------------
-// FAIL 10: wave uniformity violation
-//--------------------------------------------------------------
-
-float4 Fail_WaveUniform(float2 uv)
-{
- Texture2D<float4> tex = gTex0;
- // I presume the reason we don't see this expected error is that
- // DxilCondenseResources is responsible for emitting this.
- // So, it will not run when -verify is passed to the compiler since
- // DXIL IR is not the intended output in that situation.
- // However, in DXC, we do expect an error here.
- if(WaveActiveAllTrue(true))
- // expected-error at -1 {{local resource not guaranteed to map to unique global resource}}
- tex = gTex1;
- return tex.Sample(gSampler, uv);
-}
-
-//--------------------------------------------------------------
-// Entry point calling all fail functions to prevent DCE
-//--------------------------------------------------------------
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
- float2 uv = float2(0,0);
- float4 r = 0;
- gTex0 = tex;
- // FAIL 1
- r += Fail_Static(uv);
-
- // FAIL 2
- Fail_Arithmetic();
-
- // FAIL 3
- Fail_Compare();
-
- // FAIL 4
- Fail_Bool();
-
- // FAIL 5
- Fail_Cast();
-
- // FAIL 6
- Fail_Add();
-
- // FAIL 7
- // note, this error does not get emitted when -verify is passed as an option.
- // expected-error at +1{{no matching function for call to 'Fail_DefaultParam'}}
- Fail_DefaultParam(gTex0, uv);
-
- // FAIL 8
- Fail_Reinterpret(uv);
-
- // FAIL 9
- Fail_LocalBuffer();
-
- // FAIL 10
- r += Fail_WaveUniform(uv);
-}
diff --git a/clang/test/SemaHLSL/Resources/local_resources_passes.hlsl b/clang/test/SemaHLSL/Resources/local_resources_passes.hlsl
deleted file mode 100644
index d97a03580242c..0000000000000
--- a/clang/test/SemaHLSL/Resources/local_resources_passes.hlsl
+++ /dev/null
@@ -1,405 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -verify
-
-//==============================================================
-// GLOBAL RESOURCES
-//==============================================================
-
-RWByteAddressBuffer gBuf0 : register(u0);
-RWByteAddressBuffer gBuf1 : register(u1);
-RWByteAddressBuffer gBuf2 : register(u2);
-
-RWByteAddressBuffer gOut : register(u3);
-
-RWByteAddressBuffer gBufArray[4] : register(u10);
-
-
-//==============================================================
-// HELPERS
-//==============================================================
-
-uint DoStore(RWByteAddressBuffer buf, uint offset, uint value)
-{
- buf.Store(offset, value);
- return value;
-}
-
-
-//==============================================================
-// PASS TESTS
-//==============================================================
-
-// PASS 4
-struct PassBufStruct { RWByteAddressBuffer buf; };
-
-groupshared PassBufStruct sharedStruct;
-
-uint Use_PassSharedStruct(uint idx)
-{
- return DoStore(gBuf0, idx * 4, 4);
-}
-
-// PASS 5
-uint Pass_StructArray(uint idx)
-{
- PassBufStruct s[2];
- s[0].buf = gBuf0;
- return DoStore(s[0].buf, idx * 4, 5);
-}
-
-// PASS 6
-groupshared RWByteAddressBuffer Pass_Shared;
-
-uint Use_Pass_Shared(uint idx)
-{
- return DoStore(gBuf0, idx * 4, 6);
-}
-
-// PASS 7
-RWByteAddressBuffer Pass_ReturnLocal_Uninitialized()
-{
- RWByteAddressBuffer buf;
- return buf;
-}
-
-// PASS 8
-RWByteAddressBuffer Pass_ReturnLocal()
-{
- RWByteAddressBuffer buf = gBuf0;
- return buf;
-}
-
-// PASS 9
-struct S { RWByteAddressBuffer arr[2]; };
-
-uint Pass_StructArrayAssignment(uint idx)
-{
- S s;
- s.arr[0] = gBuf0;
- return DoStore(s.arr[0], idx * 4, 9);
-}
-
-// PASS 10
-uint Pass_LocalArray(uint idx)
-{
- RWByteAddressBuffer arr[2];
- arr[0] = gBuf0;
- return DoStore(arr[0], idx * 4, 10);
-}
-
-// PASS 11
-uint Pass_Uninitialized(uint idx)
-{
- RWByteAddressBuffer buf;
- return DoStore(buf, idx * 4, 11);
-}
-
-// PASS 12
-uint Pass_Alias(uint idx)
-{
- RWByteAddressBuffer buf = gBuf0;
- return DoStore(buf, idx * 4, 12);
-}
-
-// PASS 13
-uint Pass_Reassign(uint idx)
-{
- // expected-note at +1{{variable 'buf' is declared here}}
- RWByteAddressBuffer buf = gBuf0;
- // expected-warning at +1{{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
- buf = gBuf1;
- return DoStore(buf, idx * 4, 13);
-}
-
-// PASS 14
-uint Pass_IfAlias(bool cond, uint idx)
-{
- RWByteAddressBuffer buf;
- // expected-warning at +1{{assignment of 'cond ? gBuf0 : gBuf1' to local resource 'buf' is not to the same unique global resource}}
- buf = cond ? gBuf0 : gBuf1;
- return DoStore(buf, idx * 4, 14);
-}
-
-// PASS 15
-uint Pass_Loop(uint idx)
-{
- uint sum = 0;
- for(unsigned int i=0;i<4;i++)
- {
- RWByteAddressBuffer buf = gBufArray[i];
- sum += DoStore(buf, idx * 4 + i * 4, 15);
- }
- return sum;
-}
-
-// PASS 16
-struct PassStruct
-{
- RWByteAddressBuffer buf;
-};
-
-uint Pass_Struct(uint idx)
-{
- PassStruct s;
- s.buf = gBuf0;
- return DoStore(s.buf, idx * 4, 16);
-}
-
-// PASS 17
-uint Pass_Level2(RWByteAddressBuffer buf, uint idx)
-{
- return DoStore(buf, idx * 4, 17);
-}
-
-uint Pass_Level1(RWByteAddressBuffer buf, uint idx)
-{
- return Pass_Level2(buf, idx);
-}
-
-uint Pass_FunctionForward(uint idx)
-{
- RWByteAddressBuffer buf = gBuf1;
- return Pass_Level1(buf, idx);
-}
-
-// PASS 18
-uint Pass_PhiMerge(bool cond, uint idx)
-{
- RWByteAddressBuffer buf;
- // expected-warning at +1{{assignment of 'cond ? gBuf0 : gBuf2' to local resource 'buf' is not to the same unique global resource}}
- buf = cond ? gBuf0 : gBuf2;
- return DoStore(buf, idx * 4, 18);
-}
-
-// PASS 19
-uint Pass_Shadow(uint idx)
-{
- RWByteAddressBuffer buf = gBuf0;
- {
- RWByteAddressBuffer buf = gBuf1;
- return DoStore(buf, idx * 4, 19);
- }
-}
-
-// PASS 20
-uint Pass_Switch(int v, uint idx)
-{
- // expected-note at +2{{variable 'buf' is declared here}}
- // expected-note at +1{{variable 'buf' is declared here}}
- RWByteAddressBuffer buf = gBuf0;
-
- switch(v)
- {
- // expected-warning at +1{{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
- case 1: buf = gBuf1; break;
- // expected-warning at +1{{assignment of 'gBuf2' to local resource 'buf' is not to the same unique global resource}}
- case 2: buf = gBuf2; break;
- }
-
- return DoStore(buf, idx * 4, 20);
-}
-
-// PASS 21
-uint Pass_Bindless(uint idx)
-{
- RWByteAddressBuffer buf = gBufArray[idx & 3];
- return DoStore(buf, idx * 4, 21);
-}
-
-// PASS 22
-uint Pass_WaveUse(uint idx)
-{
- RWByteAddressBuffer buf = gBuf0;
- uint active = WaveActiveCountBits(true);
- return DoStore(buf, idx * 4, active);
-}
-
-// PASS 23
-uint Pass_NestedLoops(uint idx)
-{
- uint sum = 0;
- for(unsigned int i=0;i<2;i++)
- for(unsigned int j=0;j<2;j++)
- {
- RWByteAddressBuffer buf = gBufArray[i+j];
- sum += DoStore(buf, idx * 4 + (i+j)*4, 23);
- }
- return sum;
-}
-
-// PASS 24
-uint Pass_BlockLifetime(uint idx)
-{
- RWByteAddressBuffer buf;
- {
- buf = gBuf1;
- }
- return DoStore(buf, idx * 4, 24);
-}
-
-// PASS 25
-uint Pass_DeepPhi(bool a, bool b, uint idx)
-{
- RWByteAddressBuffer buf;
-
- if(a)
- // expected-warning at +1{{assignment of 'b ? gBuf0 : gBuf1' to local resource 'buf' is not to the same unique global resource}}
- buf = b ? gBuf0 : gBuf1;
- else
- buf = gBuf2;
-
- return DoStore(buf, idx * 4, 25);
-}
-
-// PASS 26
-uint Pass_LoopCarried(int iterations, uint idx)
-{
- // expected-note at +1{{variable 'buf' is declared here}}
- RWByteAddressBuffer buf = gBuf0;
-
- for(int i=0;i<iterations;i++)
- // expected-warning at +1{{assignment of 'gBufArray[i & 3]' to local resource 'buf' is not to the same unique global resource}}
- buf = gBufArray[i & 3];
-
- return DoStore(buf, idx * 4, 26);
-}
-
-// PASS 27
-uint Pass_AliasChain(uint idx)
-{
- RWByteAddressBuffer a = gBuf0;
- RWByteAddressBuffer b = a;
- RWByteAddressBuffer c = b;
-
- return DoStore(c, idx * 4, 27);
-}
-
-// PASS 28
-struct PassNestedInner { RWByteAddressBuffer buf; };
-struct PassNestedOuter { PassNestedInner inner; };
-
-uint Pass_NestedStruct(uint idx)
-{
- PassNestedOuter s;
- s.inner.buf = gBuf1;
- return DoStore(s.inner.buf, idx * 4, 28);
-}
-
-// PASS 29
-struct PassForwardA { RWByteAddressBuffer buf; };
-struct PassForwardB { PassForwardA a; };
-
-uint Pass_ForwardStructLayers(uint idx)
-{
- PassForwardB b;
- b.a.buf = gBuf2;
- return DoStore(b.a.buf, idx * 4, 29);
-}
-
-// PASS 30
-uint Pass_SwitchFallthrough(int v, uint idx)
-{
- // expected-note at +2{{variable 'buf' is declared here}}
- // expected-note at +1{{variable 'buf' is declared here}}
- RWByteAddressBuffer buf = gBuf0;
-
- switch(v)
- {
- // expected-warning at +1{{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
- case 0: buf = gBuf1;
- // expected-warning at +1{{assignment of 'gBuf2' to local resource 'buf' is not to the same unique global resource}}
- case 1: buf = gBuf2; break;
- }
-
- return DoStore(buf, idx * 4, 30);
-}
-
-// PASS 31
-uint Pass_EarlyReturn(bool cond, uint idx)
-{
- // expected-note at +1{{variable 'buf' is declared here}}
- RWByteAddressBuffer buf = gBuf0;
-
- if(cond)
- return DoStore(buf, idx * 4, 31);
- // expected-warning at +1{{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
- buf = gBuf1;
- return DoStore(buf, idx * 4, 31);
-}
-
-// PASS 32
-uint Pass_NestedBlocks(uint idx)
-{
- // expected-note at +1{{variable 'buf' is declared here}}
- RWByteAddressBuffer buf;
-
- {
- buf = gBuf1;
- {
- // expected-warning at +1{{assignment of 'gBuf2' to local resource 'buf' is not to the same unique global resource}}
- buf = gBuf2;
- }
- }
-
- return DoStore(buf, idx * 4, 32);
-}
-
-// PASS 33
-uint Pass_BindlessSelection(uint a, uint b, uint idx)
-{
- RWByteAddressBuffer buf;
-
- buf = gBufArray[a & 3];
- buf = gBufArray[b & 3];
-
- return DoStore(buf, idx * 4, 33);
-}
-
-
-//==============================================================
-// ENTRY POINT
-//==============================================================
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
- uint idx = tid.x + tid.y * 8;
-
- uint r = 0;
-
- r += Pass_TernaryInit(true, idx);
- Pass_LoopVar();
- r += Pass_ExpressionInit(idx);
- r += Use_PassSharedStruct(idx);
- r += Pass_StructArray(idx);
- r += Use_Pass_Shared(idx);
- RWByteAddressBuffer tmp0 = Pass_ReturnLocal_Uninitialized();
- RWByteAddressBuffer tmp1 = Pass_ReturnLocal();
- r += Pass_StructArray(idx);
- r += Pass_LocalArray(idx);
- r += Pass_Uninitialized(idx);
- r += Pass_Alias(idx);
- r += Pass_Reassign(idx);
- r += Pass_IfAlias(true, idx);
- r += Pass_Loop(idx);
- r += Pass_Struct(idx);
- r += Pass_FunctionForward(idx);
- r += Pass_PhiMerge(true, idx);
- r += Pass_Shadow(idx);
- r += Pass_Switch(1, idx);
- r += Pass_Bindless(idx);
- r += Pass_WaveUse(idx);
- r += Pass_NestedLoops(idx);
- r += Pass_BlockLifetime(idx);
- r += Pass_DeepPhi(true, false, idx);
- r += Pass_LoopCarried(15, idx);
- r += Pass_AliasChain(idx);
- r += Pass_NestedStruct(idx);
- r += Pass_ForwardStructLayers(idx);
- r += Pass_SwitchFallthrough(0, idx);
- r += Pass_EarlyReturn(true, idx);
- r += Pass_NestedBlocks(idx);
- r += Pass_BindlessSelection(2, 3, idx);
-
- gOut.Store(idx * 4, r);
-}
\ No newline at end of file
>From 8f10be1fb8d8b82c08bf646087b4911e72e64714 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Fri, 3 Apr 2026 13:36:51 -0700
Subject: [PATCH 06/10] add even more tests
---
.../local_resource_continue_reassign.hlsl | 33 ++++++++++++++++
.../local_resource_multiple_returns.hlsl | 36 ++++++++++++++++++
.../ternary_initialization.hlsl | 3 ++
.../Local-Resources/use_groupshared.hlsl | 34 +++++++++++++++++
.../use_struct_groupshared.hlsl | 13 ++++---
.../Resources/Local-Resources/Readme.md | 30 ++++++++++++---
.../Local-Resources/expression_init.hlsl | 2 +
.../forward_struct_layers_resource.hlsl | 2 +
.../local_resource_alias_chain.hlsl | 2 +
.../local_resource_alias_global.hlsl | 2 +
.../Local-Resources/local_resource_array.hlsl | 2 +
.../local_resource_array_size_one.hlsl | 26 +++++++++++++
.../local_resource_bindless_array.hlsl | 2 +
.../local_resource_bindless_selection.hlsl | 2 +
.../local_resource_block_lifetime.hlsl | 2 +
.../local_resource_chained_call.hlsl | 20 ++++++++++
.../local_resource_comma_init.hlsl | 19 ++++++++++
.../local_resource_conditional_init.hlsl | 12 ++----
.../local_resource_default_init_store.hlsl | 12 ++----
...al_resource_forward_through_functions.hlsl | 2 +
.../local_resource_loop_array_index.hlsl | 2 +
.../local_resource_multi_decl.hlsl | 21 ++++++++++
.../local_resource_nested_loops.hlsl | 2 +
.../local_resource_overload.hlsl | 32 ++++++++++++++++
.../local_resource_read_only.hlsl | 25 ++++++++++++
...al_resource_reassign_different_global.hlsl | 2 +
.../local_resource_shadow_inner_scope.hlsl | 2 +
.../local_resource_static_const.hlsl | 28 ++++++++++++++
.../local_resource_struct_method.hlsl | 25 ++++++++++++
.../local_resource_structured_buffer.hlsl | 25 ++++++++++++
.../Local-Resources/local_resource_swap.hlsl | 25 ++++++++++++
.../local_resource_switch_default.hlsl | 38 +++++++++++++++++++
.../local_resource_template_function.hlsl | 30 +++++++++++++++
.../local_resource_ternary_lvalue.hlsl | 24 ++++++++++++
.../local_resource_with_wave_intrinsic.hlsl | 2 +
.../local_resource_zero_init.hlsl | 18 +++++++++
.../local_struct_resource_member.hlsl | 2 +
.../Resources/Local-Resources/loop_var.hlsl | 2 +
.../nested_struct_resource_member.hlsl | 2 +
.../return_local_resource_initialized.hlsl | 2 +
.../return_local_resource_uninitialized.hlsl | 2 +
.../struct_array_with_resource_member.hlsl | 2 +
.../struct_with_resource_array_member.hlsl | 2 +
.../Local-Resources/use_groupshared.hlsl | 31 ---------------
.../use_local_resource_uninitialized.hlsl | 2 +
45 files changed, 546 insertions(+), 58 deletions(-)
create mode 100644 clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_continue_reassign.hlsl
create mode 100644 clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_multiple_returns.hlsl
create mode 100644 clang/test/CodeGenHLSL/resources/Local-Resources/use_groupshared.hlsl
rename clang/test/{SemaHLSL/Resources => CodeGenHLSL/resources}/Local-Resources/use_struct_groupshared.hlsl (58%)
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_size_one.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_chained_call.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_comma_init.hlsl
rename clang/test/{CodeGenHLSL/resources => SemaHLSL/Resources}/Local-Resources/local_resource_conditional_init.hlsl (55%)
rename clang/test/{CodeGenHLSL/resources => SemaHLSL/Resources}/Local-Resources/local_resource_default_init_store.hlsl (51%)
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multi_decl.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_overload.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_read_only.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_const.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_method.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_structured_buffer.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_swap.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_default.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_template_function.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_lvalue.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_zero_init.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared.hlsl
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_continue_reassign.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_continue_reassign.hlsl
new file mode 100644
index 0000000000000..58db0fe0ed364
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_continue_reassign.hlsl
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute -emit-llvm -disable-llvm-passes 2>&1 -o - %s | llvm-cxxfilt | FileCheck %s
+
+// DXC passes sema but fails during codegen (DxilCondenseResources) with:
+// "local resource not guaranteed to map to unique global resource"
+// Clang passes both sema and codegen, emitting a -Whlsl-explicit-binding
+// warning instead.
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+// CHECK: warning: assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer buf = gBuf0;
+
+ for(uint i = 0; i < 4; i++)
+ {
+ if(i == 2)
+ {
+ // DXC: error after sema: local resource not guaranteed to map to unique global resource.
+ buf = gBuf1;
+ continue;
+ }
+ buf.Store(i * 4, i);
+ }
+
+ buf.Store(tid.x * 4, 99);
+}
+
+// CHECK: define void @main()
+// CHECK-NOT: error:
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_multiple_returns.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_multiple_returns.hlsl
new file mode 100644
index 0000000000000..c6e848df4f956
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_multiple_returns.hlsl
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute -emit-llvm -disable-llvm-passes 2>&1 -o - %s | llvm-cxxfilt | FileCheck %s
+
+// DXC passes sema but fails during codegen (DxilCondenseResources) with:
+// "local resource not guaranteed to map to unique global resource"
+// Clang passes both sema and codegen, emitting a -Whlsl-explicit-binding
+// warning instead.
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+// CHECK: warning: assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource
+RWByteAddressBuffer Pass_MultipleReturns(bool cond, uint idx)
+{
+ RWByteAddressBuffer buf = gBuf0;
+ if(cond)
+ {
+ buf.Store(idx * 4, 1);
+ return buf;
+ }
+ // DXC: error after sema: local resource not guaranteed to map to unique global resource.
+ buf = gBuf1;
+ buf.Store(idx * 4, 2);
+ return buf;
+}
+
+// CHECK: define hidden void @Pass_MultipleReturns(bool, unsigned int)(
+// CHECK: define void @main()
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ RWByteAddressBuffer result = Pass_MultipleReturns(idx < 32, idx);
+ result.Store(0, idx);
+}
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/ternary_initialization.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/ternary_initialization.hlsl
index c9b6f47cdcd9c..947199d3c051d 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/ternary_initialization.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/ternary_initialization.hlsl
@@ -2,6 +2,9 @@
// RUN: dxil-pc-shadermodel6.6-compute -emit-llvm -disable-llvm-passes 2>&1 -o - %s | llvm-cxxfilt | FileCheck %s
// This test fails after verify.
+//
+// DXC: passes sema but fails codegen (DxilCondenseResources) with:
+// "local resource not guaranteed to map to unique global resource."
RWByteAddressBuffer gOut : register(u3);
RWByteAddressBuffer gBuf0 : register(u0);
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/use_groupshared.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/use_groupshared.hlsl
new file mode 100644
index 0000000000000..dc56ec1ddd6fb
--- /dev/null
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/use_groupshared.hlsl
@@ -0,0 +1,34 @@
+// RUN: not %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute -emit-llvm -disable-llvm-passes 2>&1 -o - %s | llvm-cxxfilt | FileCheck %s
+
+// This test fails validation in DXC, but DXC's sema allows it.
+// Meanwhile, groupshared is immediately detected and rejected in clang's sema.
+//
+// DXC: passes sema but fails validation with:
+// "Explicit load/store type does not match pointee type of pointer operand"
+
+RWByteAddressBuffer gOut : register(u3);
+
+uint DoStore(RWByteAddressBuffer buf, uint offset, uint value)
+{
+ buf.Store(offset, value);
+ return value;
+}
+
+groupshared RWByteAddressBuffer sharedBuf;
+uint Use_Shared(uint idx)
+{
+ return DoStore(sharedBuf, idx * 4, 1);
+}
+
+// CHECK: error: no matching constructor for initialization of 'RWByteAddressBuffer'
+// CHECK: note: candidate constructor not viable: cannot bind reference in address space 'groupshared' to object in generic address space in 1st argument
+// CHECK: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
+// CHECK: note: passing argument to parameter 'buf' here
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Use_Shared(idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/use_struct_groupshared.hlsl
similarity index 58%
rename from clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.hlsl
rename to clang/test/CodeGenHLSL/resources/Local-Resources/use_struct_groupshared.hlsl
index 9e1579336fb1e..07429cf2b85c3 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/use_struct_groupshared.hlsl
@@ -1,23 +1,26 @@
// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+// RUN: dxil-pc-shadermodel6.6-compute -emit-llvm -disable-llvm-passes 2>&1 -o - %s | llvm-cxxfilt | FileCheck %s
// This test fails validation in DXC, but DXC's sema allows it.
// Meanwhile, it is for some reason accepted by clang's sema.
// TODO: Why does this pass clang's sema, but use_groupshared.hlsl fails clang's sema?
// Run a git bisect on https://github.com/llvm/llvm-project/issues/158107, and figure
// out which commit seemed to resolve this issue.
+//
+// DXC: passes sema but fails validation with:
+// "Explicit load/store type does not match pointee type of pointer operand"
RWByteAddressBuffer gOut : register(u3);
-// expected-note at +1{{passing argument to parameter 'buf' here}}
+// CHECK: note: passing argument to parameter 'buf' here
uint DoStore(RWByteAddressBuffer buf, uint offset, uint value)
{
buf.Store(offset, value);
return value;
}
-// expected-note@*:*{{candidate constructor not viable: cannot bind reference in address space 'groupshared' to object in generic address space in 1st argument}}
-// expected-note@*:*{{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
+// CHECK: note: candidate constructor not viable: cannot bind reference in address space 'groupshared' to object in generic address space in 1st argument
+// CHECK: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
struct PassBufStruct { RWByteAddressBuffer buf; };
@@ -25,7 +28,7 @@ groupshared PassBufStruct sharedStruct;
uint Use_PassSharedStruct(uint idx)
{
- // expected-error at +1{{no matching constructor for initialization of 'RWByteAddressBuffer'}}
+ // CHECK: error: no matching constructor for initialization of 'RWByteAddressBuffer'
return DoStore(sharedStruct.buf, idx * 4, 1);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/Readme.md b/clang/test/SemaHLSL/Resources/Local-Resources/Readme.md
index f8d007bcbee3e..3917189f96d31 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/Readme.md
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/Readme.md
@@ -39,10 +39,13 @@ Tests where **codegen is the interesting stage**. This includes:
| `local_resource_copy_between_locals.hlsl` | Copy one local resource to another (`a = g; b = a`) |
| `local_resource_self_assign.hlsl` | Self-assignment (`buf = buf`) |
| `use_local_resource_uninitialized.hlsl` | Using an uninitialized local resource |
+| `local_resource_default_init_store.hlsl` | Store through a default-initialized (unbound) resource *(both compilers pass)* |
| `return_local_resource_uninitialized.hlsl` | Returning an uninitialized local resource |
| `return_local_resource_initialized.hlsl` | Returning a local resource initialized from a global |
| `expression_init.hlsl` | Initializing with a parenthesized ternary expression |
| `local_resource_aggregate_init.hlsl` | Aggregate initialization of a struct containing a resource |
+| `local_resource_multi_decl.hlsl` | Two resource variables declared in a single statement |
+| `local_resource_comma_init.hlsl` | Comma expression in initializer — left operand discarded with warning *(clang warns, DXC silent)* |
### Parameter Passing
| File | Pattern |
@@ -63,20 +66,24 @@ Tests where **codegen is the interesting stage**. This includes:
| `local_resource_array_copy.hlsl` | Copy one local resource array to another |
| `local_resource_array_dynamic_index.hlsl` | Runtime dynamic index into a local resource array |
| `local_resource_array_partial_init.hlsl` | Partially initialized resource array (`{g0}` for a 2-element array) |
+| `local_resource_array_size_one.hlsl` | Local resource array of size 1 (edge case) |
| `struct_resource_member_reassign.hlsl` | Reassign a struct's resource member to a different global |
| `local_resource_struct_return.hlsl` | Function returns a struct containing a resource |
| `local_resource_mixed_struct.hlsl` | Struct with both a resource member and a scalar member |
+| `local_resource_struct_method.hlsl` | User-defined struct with a member function that uses a resource |
### Control Flow
| File | Pattern |
|------|---------|
| `local_resource_shadow_inner_scope.hlsl` | Shadowed resource in an inner block |
| `local_resource_block_lifetime.hlsl` | Assigned in inner block, used in outer scope |
+| `local_resource_conditional_init.hlsl` | Resource only initialized in one branch of an if *(both compilers pass)* |
| `local_resource_nested_blocks_reassign.hlsl` | Reassigned across nested blocks *(clang warns, DXC silent)* |
| `local_resource_early_return_reassign.hlsl` | Reassigned after an early return path *(clang warns, DXC silent)* |
| `local_resource_unreachable_reassign.hlsl` | Reassigned in code after an early return *(clang warns, DXC silent)* |
| `local_resource_switch_reassign.hlsl` | Reassigned in switch cases *(clang warns, DXC silent)* |
| `local_resource_switch_fallthrough.hlsl` | Switch with fallthrough reassignment *(clang warns, DXC silent)* |
+| `local_resource_switch_default.hlsl` | Switch with explicit default case reassignment *(clang warns, DXC silent)* |
### Loop Patterns
| File | Pattern |
@@ -92,6 +99,8 @@ Tests where **codegen is the interesting stage**. This includes:
|------|---------|
| `local_resource_reassign_different_global.hlsl` | Reassign to a different global *(clang warns, DXC silent)* |
| `local_resource_deep_phi.hlsl` | Nested if/else with ternary *(clang warns, DXC silent)* |
+| `local_resource_ternary_lvalue.hlsl` | Ternary expression as lvalue for resource assignment *(clang silent, DXC ICEs)* |
+| `local_resource_swap.hlsl` | Swap two local resources through a temporary *(both compilers pass, no warnings)* |
### Bindless
| File | Pattern |
@@ -106,16 +115,21 @@ Tests where **codegen is the interesting stage**. This includes:
| `local_resource_with_wave_intrinsic.hlsl` | Resource used alongside wave intrinsics |
| `local_resource_multiple_uses.hlsl` | Same local resource passed to multiple helper functions |
| `local_resource_from_function_return.hlsl` | Local resource initialized from a function's return value |
+| `local_resource_template_function.hlsl` | Template function taking a resource parameter |
+| `local_resource_chained_call.hlsl` | Method called directly on a function return value (`GetBuf().Store(...)`) |
+| `local_resource_overload.hlsl` | Function overloading where overloads differ by resource type |
### Static and Storage
| File | Pattern |
|------|---------|
| `local_resource_static_local.hlsl` | Static local resource initialized from a global *(passes both compilers with RWByteAddressBuffer; DXC ICEs with Texture2D)* |
-### Type Mixing
+### Type Mixing and Alternative Resource Types
| File | Pattern |
|------|---------|
| `local_resource_different_types.hlsl` | Two different resource types (`RWByteAddressBuffer` + `RWStructuredBuffer`) in the same function |
+| `local_resource_read_only.hlsl` | Read-only `ByteAddressBuffer` as local — only `Load` available (no `Store`) |
+| `local_resource_structured_buffer.hlsl` | `RWStructuredBuffer<uint>` as local with subscript operator access |
### Invalid Type Operations (Sema Failures)
| File | Pattern |
@@ -129,6 +143,7 @@ Tests where **codegen is the interesting stage**. This includes:
| `local_resource_assign_wrong_type.hlsl` | Assign `RWStructuredBuffer` to `RWByteAddressBuffer` (type mismatch) |
| `local_resource_volatile.hlsl` | `volatile` qualifier on resource prevents method calls *(clang errors, DXC accepts)* |
| `local_resource_const_reassign.hlsl` | `const` local resource prevents reassignment *(both compilers error)* |
+| `local_resource_static_const.hlsl` | `static const` prevents calling any methods — `Load` and `Store` are not `const`-qualified *(clang errors, DXC ICEs)* |
### Invalid Declarations (Sema Failures)
| File | Pattern |
@@ -136,13 +151,14 @@ Tests where **codegen is the interesting stage**. This includes:
| `local_resource_default_param.hlsl` | Resource parameter with default followed by parameter without default |
| `local_resource_as_structured_buffer_element.hlsl` | Resource type as element of `RWStructuredBuffer` (intangible type) |
| `local_resource_array_oob.hlsl` | Compile-time out-of-bounds index into resource array *(clang warns, DXC errors)* |
+| `local_resource_zero_init.hlsl` | Brace (zero) initialization `= {}` rejected — empty initializer list *(both compilers error)* |
-### Groupshared Resources
+### Groupshared Resources (now in `CodeGenHLSL/resources/Local-Resources/`)
| File | Pattern |
|------|---------|
-| `use_groupshared.hlsl` | Passing a groupshared resource as a function argument *(fails sema — constructor mismatch)* |
+| `use_groupshared.hlsl` | Passing a groupshared resource as a function argument *(clang sema error; DXC validation error)* |
| `use_groupshared_direct_store.hlsl` | Calling Store directly on a groupshared resource *(fails sema — address space mismatch)* |
-| `use_struct_groupshared.hlsl` | Using a resource from a groupshared struct *(expected to fail sema — see TODO in file)* |
+| `use_struct_groupshared.hlsl` | Using a resource from a groupshared struct *(expected to fail — see TODO in file; DXC validation error)* |
### CodeGen Tests (`CodeGenHLSL/resources/Local-Resources/`)
| File | Pattern |
@@ -151,11 +167,13 @@ Tests where **codegen is the interesting stage**. This includes:
| `local_resource_ternary_assign.hlsl` | Ternary assignment post-declaration *(DXC codegen error)* |
| `local_resource_phi_merge_ternary.hlsl` | Ternary phi merge *(DXC codegen error)* |
| `local_resource_wave_uniform.hlsl` | Wave-conditional reassignment *(DXC codegen error; clang warns)* |
-| `local_resource_default_init_store.hlsl` | Store through a default-initialized (unbound) resource *(DXC codegen error; clang silent)* |
| `local_resource_break_reassign.hlsl` | Reassignment before a break in a loop *(DXC codegen error; clang warns)* |
-| `local_resource_conditional_init.hlsl` | Resource only initialized in one branch of an if *(DXC codegen error; clang silent)* |
| `local_resource_ternary_as_argument.hlsl` | Ternary resource passed directly as a function argument *(DXC codegen error; clang silent)* |
| `local_resource_nested_ternary.hlsl` | Nested ternary (`c1 ? g0 : (c2 ? g1 : g2)`) *(DXC codegen 2 errors; clang warns)* |
+| `local_resource_continue_reassign.hlsl` | Reassignment before `continue` in a loop *(DXC codegen error; clang warns)* |
+| `local_resource_multiple_returns.hlsl` | Multiple return paths returning different resources *(DXC codegen error; clang warns)* |
+| `use_groupshared.hlsl` | Passing a groupshared resource as a function argument *(clang sema error; DXC validation error)* |
+| `use_struct_groupshared.hlsl` | Using a resource from a groupshared struct *(expected failure — clang currently silent; DXC validation error)* |
## Key Behavioral Differences: Clang vs DXC
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.hlsl
index cc519b5f05993..08c383053537d 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.hlsl
@@ -3,6 +3,8 @@
// expected-no-diagnostics
+// DXC: passes (both sema and codegen).
+
RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/forward_struct_layers_resource.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/forward_struct_layers_resource.hlsl
index c989414989bfe..65356d59c07dc 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/forward_struct_layers_resource.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/forward_struct_layers_resource.hlsl
@@ -3,6 +3,8 @@
// expected-no-diagnostics
+// DXC: passes (both sema and codegen).
+
RWByteAddressBuffer gBuf2 : register(u2);
struct ForwardA { RWByteAddressBuffer buf; };
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_chain.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_chain.hlsl
index fd7ba77d057cd..40d1f079200d9 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_chain.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_chain.hlsl
@@ -3,6 +3,8 @@
// expected-no-diagnostics
+// DXC: passes (both sema and codegen).
+
RWByteAddressBuffer gBuf0 : register(u0);
uint Pass_AliasChain(uint idx)
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_global.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_global.hlsl
index 69c7fc545f4c4..cd41a7e77f414 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_global.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_global.hlsl
@@ -3,6 +3,8 @@
// expected-no-diagnostics
+// DXC: passes (both sema and codegen).
+
RWByteAddressBuffer gBuf0 : register(u0);
uint Pass_Alias(uint idx)
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array.hlsl
index acb04d5346b1b..77d43f963cc51 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array.hlsl
@@ -3,6 +3,8 @@
// expected-no-diagnostics
+// DXC: passes (both sema and codegen).
+
RWByteAddressBuffer gBuf0 : register(u0);
uint Pass_LocalArray(uint idx)
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_size_one.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_size_one.hlsl
new file mode 100644
index 0000000000000..36100f67f983a
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_size_one.hlsl
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that a local resource array of size 1 works correctly. This is
+// an edge case where the compiler might apply different optimizations
+// compared to larger arrays.
+//
+// DXC: passes (both sema and codegen).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+uint Pass_ArraySizeOne(uint idx)
+{
+ RWByteAddressBuffer arr[1];
+ arr[0] = gBuf0;
+ arr[0].Store(idx * 4, 42);
+ return 42;
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ Pass_ArraySizeOne(tid.x);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_array.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_array.hlsl
index eecce30234f2b..5c1bfd8a7cced 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_array.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_array.hlsl
@@ -3,6 +3,8 @@
// expected-no-diagnostics
+// DXC: passes (both sema and codegen).
+
RWByteAddressBuffer gBufArray[4] : register(u10);
uint Pass_Bindless(uint idx)
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_selection.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_selection.hlsl
index 52fea1d8c9a06..7ffb9fa23dc58 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_selection.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_selection.hlsl
@@ -3,6 +3,8 @@
// expected-no-diagnostics
+// DXC: passes (both sema and codegen).
+
RWByteAddressBuffer gBufArray[4] : register(u10);
uint Pass_BindlessSelection(uint a, uint b, uint idx)
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_block_lifetime.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_block_lifetime.hlsl
index 95525cd5757b4..22dc1f5ac83ac 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_block_lifetime.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_block_lifetime.hlsl
@@ -3,6 +3,8 @@
// expected-no-diagnostics
+// DXC: passes (both sema and codegen).
+
RWByteAddressBuffer gBuf1 : register(u1);
uint Pass_BlockLifetime(uint idx)
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_chained_call.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_chained_call.hlsl
new file mode 100644
index 0000000000000..d6763d5a28960
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_chained_call.hlsl
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that a method can be called directly on the return value of a
+// function that returns a resource. This exercises temporary resource
+// lifetime — the method is invoked on an rvalue.
+//
+// DXC: passes (both sema and codegen).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+RWByteAddressBuffer GetBuf() { return gBuf0; }
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ GetBuf().Store(tid.x * 4, 42);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_comma_init.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_comma_init.hlsl
new file mode 100644
index 0000000000000..d85d3477e3bff
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_comma_init.hlsl
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// Test that using a comma expression to initialize a local resource
+// produces a warning about the unused left operand. The comma operator
+// evaluates gBuf0, discards it, then uses gBuf1 as the initializer.
+//
+// DXC: passes (both sema and codegen), no diagnostic.
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ // expected-warning at +1 {{left operand of comma operator has no effect}}
+ RWByteAddressBuffer buf = (gBuf0, gBuf1);
+ buf.Store(tid.x * 4, 42);
+}
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_conditional_init.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_conditional_init.hlsl
similarity index 55%
rename from clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_conditional_init.hlsl
rename to clang/test/SemaHLSL/Resources/Local-Resources/local_resource_conditional_init.hlsl
index 214ce9e64ed0d..1de6dd450c2a6 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_conditional_init.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_conditional_init.hlsl
@@ -1,12 +1,12 @@
// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes \
-// RUN: -o - 2>&1 | llvm-cxxfilt | FileCheck %s
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
// Test that a resource declared without initialization and only assigned
// in one branch produces valid IR in clang.
//
-// DXC: passes sema but fails codegen with:
-// "local resource not guaranteed to map to unique global resource."
+// DXC: passes (both sema and codegen).
RWByteAddressBuffer gBuf0 : register(u0);
@@ -18,7 +18,3 @@ void main(uint3 tid : SV_DispatchThreadID)
buf = gBuf0;
buf.Store(tid.x * 4, 42);
}
-
-// CHECK-NOT: error:
-// CHECK-NOT: warning:
-// CHECK: define {{.*}} @main(
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_default_init_store.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_init_store.hlsl
similarity index 51%
rename from clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_default_init_store.hlsl
rename to clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_init_store.hlsl
index f38a60615ca9d..130140e53b56f 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_default_init_store.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_init_store.hlsl
@@ -1,12 +1,12 @@
// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes \
-// RUN: -o - 2>&1 | llvm-cxxfilt | FileCheck %s
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
// Test that using a default-initialized (unbound) local resource produces
// valid IR in clang. No warnings or errors from clang.
//
-// DXC: passes sema but fails codegen with:
-// "local resource not guaranteed to map to unique global resource."
+// DXC: passes (both sema and codegen).
[numthreads(1,1,1)]
void main(uint3 tid : SV_DispatchThreadID)
@@ -14,7 +14,3 @@ void main(uint3 tid : SV_DispatchThreadID)
RWByteAddressBuffer buf;
buf.Store(tid.x * 4, 42);
}
-
-// CHECK-NOT: error:
-// CHECK-NOT: warning:
-// CHECK: define {{.*}} @main(
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_forward_through_functions.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_forward_through_functions.hlsl
index 49290123c46b4..eab7dafc61a66 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_forward_through_functions.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_forward_through_functions.hlsl
@@ -3,6 +3,8 @@
// expected-no-diagnostics
+// DXC: passes (both sema and codegen).
+
RWByteAddressBuffer gBuf1 : register(u1);
uint Pass_Level2(RWByteAddressBuffer buf, uint idx)
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_array_index.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_array_index.hlsl
index 8daae29a695f9..804a656351250 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_array_index.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_array_index.hlsl
@@ -3,6 +3,8 @@
// expected-no-diagnostics
+// DXC: passes (both sema and codegen).
+
RWByteAddressBuffer gBufArray[4] : register(u10);
uint Pass_Loop(uint idx)
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multi_decl.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multi_decl.hlsl
new file mode 100644
index 0000000000000..0d07a827e818c
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multi_decl.hlsl
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that two resource variables can be declared in a single
+// declaration statement. This exercises the C++ multi-declarator
+// path with resource types.
+//
+// DXC: passes (both sema and codegen).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer a = gBuf0, b = gBuf1;
+ a.Store(tid.x * 4, 1);
+ b.Store(tid.x * 4, 2);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_loops.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_loops.hlsl
index 93999d264565d..6e01f72cb3d89 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_loops.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_loops.hlsl
@@ -3,6 +3,8 @@
// expected-no-diagnostics
+// DXC: passes (both sema and codegen).
+
RWByteAddressBuffer gBufArray[4] : register(u10);
uint Pass_NestedLoops(uint idx)
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_overload.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_overload.hlsl
new file mode 100644
index 0000000000000..70d17dfb2d3e1
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_overload.hlsl
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that function overloading works when overloads differ by
+// resource type parameter. This exercises overload resolution
+// with resource types.
+//
+// DXC: passes (both sema and codegen).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWStructuredBuffer<uint> gSB : register(u1);
+
+void DoStore(RWByteAddressBuffer buf, uint idx, uint val)
+{
+ buf.Store(idx * 4, val);
+}
+
+void DoStore(RWStructuredBuffer<uint> buf, uint idx, uint val)
+{
+ buf[idx] = val;
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer localBuf = gBuf0;
+ RWStructuredBuffer<uint> localSB = gSB;
+ DoStore(localBuf, tid.x, 1);
+ DoStore(localSB, tid.x, 2);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_read_only.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_read_only.hlsl
new file mode 100644
index 0000000000000..d4302ff781ad1
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_read_only.hlsl
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that a read-only ByteAddressBuffer can be used as a local variable.
+// This is distinct from RWByteAddressBuffer because it only supports Load
+// (no Store), exercising different method resolution. Load is required here
+// because ByteAddressBuffer is a read-only resource type.
+//
+// DXC: passes (both sema and codegen).
+
+ByteAddressBuffer gBuf0 : register(t0);
+
+uint Pass_ReadOnlyLocal(uint idx)
+{
+ ByteAddressBuffer buf = gBuf0;
+ return buf.Load(idx * 4);
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ Pass_ReadOnlyLocal(tid.x);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_reassign_different_global.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_reassign_different_global.hlsl
index 334623be44d45..d79d462e0d1f9 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_reassign_different_global.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_reassign_different_global.hlsl
@@ -4,6 +4,8 @@
// DXC compiles this without any diagnostics (even with -Wall).
// Clang emits -Whlsl-explicit-binding warnings for reassignment
// to a different global; DXC does not.
+//
+// DXC: passes (both sema and codegen).
RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_shadow_inner_scope.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_shadow_inner_scope.hlsl
index efa45af3b0086..52f3d83f26442 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_shadow_inner_scope.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_shadow_inner_scope.hlsl
@@ -3,6 +3,8 @@
// expected-no-diagnostics
+// DXC: passes (both sema and codegen).
+
RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_const.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_const.hlsl
new file mode 100644
index 0000000000000..71b4c85a72eed
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_const.hlsl
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// Test that a static const local resource cannot call any methods,
+// because neither Load nor Store is marked const. This combines the
+// static and const qualifiers, which are tested separately in
+// local_resource_static_local.hlsl and local_resource_const_param.hlsl.
+//
+// DXC: ICEs with "llvm::cast<X>() argument of incompatible type!"
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+uint Fail_StaticConst(uint idx)
+{
+ static const RWByteAddressBuffer buf = gBuf0;
+ // expected-note@*:* {{candidate function not viable: 'this' argument has type 'const RWByteAddressBuffer', but method is not marked const}}
+ // expected-note@*:* {{candidate template ignored: couldn't infer template argument 'element_type'}}
+ // expected-note@*:* {{candidate function not viable: requires 2 arguments, but 1 was provided}}
+ // expected-note@*:* {{candidate function template not viable: requires 2 arguments, but 1 was provided}}
+ // expected-error at +1 {{no matching member function for call to 'Load'}}
+ return buf.Load(idx * 4);
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ Fail_StaticConst(tid.x);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_method.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_method.hlsl
new file mode 100644
index 0000000000000..b3af9893a4b9b
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_method.hlsl
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that a user-defined struct with a member function can use a
+// resource member. This exercises method dispatch through user-defined
+// struct methods operating on resource handles.
+//
+// DXC: passes (both sema and codegen).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+struct Wrapper {
+ RWByteAddressBuffer buf;
+ void DoStore(uint idx, uint val) { buf.Store(idx * 4, val); }
+};
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ Wrapper w;
+ w.buf = gBuf0;
+ w.DoStore(tid.x, 42);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_structured_buffer.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_structured_buffer.hlsl
new file mode 100644
index 0000000000000..3bd8f011bf506
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_structured_buffer.hlsl
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that RWStructuredBuffer<uint> works as a local variable with
+// subscript operator access. This is distinct from RWByteAddressBuffer
+// because it uses typed element access via operator[].
+//
+// DXC: passes (both sema and codegen).
+
+RWStructuredBuffer<uint> gSB : register(u0);
+
+uint Pass_StructuredBufferLocal(uint idx)
+{
+ RWStructuredBuffer<uint> sb = gSB;
+ sb[idx] = 42;
+ return 42;
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ Pass_StructuredBufferLocal(tid.x);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_swap.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_swap.hlsl
new file mode 100644
index 0000000000000..0d8ab32f11e3d
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_swap.hlsl
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that swapping two local resource variables through a temporary
+// is accepted without warnings. This exercises multi-variable
+// reassignment that does not change which global each variable maps to.
+//
+// DXC: passes (both sema and codegen).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer a = gBuf0;
+ RWByteAddressBuffer b = gBuf1;
+ RWByteAddressBuffer temp = a;
+ a = b;
+ b = temp;
+ a.Store(tid.x * 4, 1);
+ b.Store(tid.x * 4, 2);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_default.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_default.hlsl
new file mode 100644
index 0000000000000..4efadd1934c63
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_default.hlsl
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// DXC compiles this without any diagnostics (even with -Wall).
+// Clang emits -Whlsl-explicit-binding warnings for reassignments
+// in the switch cases and default case; DXC does not.
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+RWByteAddressBuffer gBuf2 : register(u2);
+
+uint Pass_SwitchDefault(int v, uint idx)
+{
+ // expected-note at +2{{variable 'buf' is declared here}}
+ // expected-note at +1{{variable 'buf' is declared here}}
+ RWByteAddressBuffer buf = gBuf0;
+
+ switch(v)
+ {
+ // DXC: no diagnostic. Clang: warning.
+ // expected-warning at +1{{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
+ case 0: buf = gBuf1; break;
+ // DXC: no diagnostic. Clang: warning.
+ // expected-warning at +1{{assignment of 'gBuf2' to local resource 'buf' is not to the same unique global resource}}
+ default: buf = gBuf2; break;
+ }
+
+ buf.Store(idx * 4, 30);
+
+ return 30;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ uint idx = tid.x + tid.y * 8;
+ Pass_SwitchDefault(0, idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_template_function.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_template_function.hlsl
new file mode 100644
index 0000000000000..210bb79272be9
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_template_function.hlsl
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that a template function can accept and use a resource parameter.
+// This exercises template instantiation with resource types.
+//
+// DXC: passes (both sema and codegen).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+template<typename T>
+void UseResource(T buf, uint idx, uint val)
+{
+ buf.Store(idx * 4, val);
+}
+
+uint Pass_TemplateFunction(uint idx)
+{
+ RWByteAddressBuffer buf = gBuf0;
+ UseResource(buf, idx, 42);
+ return 42;
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ Pass_TemplateFunction(tid.x);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_lvalue.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_lvalue.hlsl
new file mode 100644
index 0000000000000..1f117a6f031a8
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_lvalue.hlsl
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that a ternary expression can be used as an lvalue for resource
+// assignment. This exercises lvalue analysis of the ternary operator
+// with resource types.
+//
+// DXC: ICEs with "Internal compiler error: LLVM Assert" (even at sema).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer a = gBuf0;
+ RWByteAddressBuffer b = gBuf1;
+ bool cond = tid.x > 0;
+ (cond ? a : b) = gBuf0;
+ a.Store(tid.x * 4, 1);
+ b.Store(tid.x * 4, 2);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_with_wave_intrinsic.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_with_wave_intrinsic.hlsl
index a6a3be39d45bd..58f4c5c1177fd 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_with_wave_intrinsic.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_with_wave_intrinsic.hlsl
@@ -3,6 +3,8 @@
// expected-no-diagnostics
+// DXC: passes (both sema and codegen).
+
RWByteAddressBuffer gBuf0 : register(u0);
uint Pass_WaveUse(uint idx)
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_zero_init.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_zero_init.hlsl
new file mode 100644
index 0000000000000..d8122a7ef87a7
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_zero_init.hlsl
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// Test that brace (zero) initialization of a local resource is rejected
+// because the empty initializer list has zero elements but the resource
+// type expects one. This is distinct from default initialization (no
+// initializer) which is accepted.
+//
+// DXC: also fails sema with:
+// "too few elements in vector initialization (expected 1 element, have 0)"
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID)
+{
+ RWByteAddressBuffer buf = {};
+ // expected-error at -1 {{too few initializers in list for type 'RWByteAddressBuffer' (expected 1 but found 0)}}
+ buf.Store(tid.x * 4, 42);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_struct_resource_member.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_struct_resource_member.hlsl
index 2046b176fab26..aa7af2b034e3e 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_struct_resource_member.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_struct_resource_member.hlsl
@@ -3,6 +3,8 @@
// expected-no-diagnostics
+// DXC: passes (both sema and codegen).
+
RWByteAddressBuffer gBuf0 : register(u0);
struct PassStruct
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/loop_var.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/loop_var.hlsl
index 5da4339b559c1..801ac358cc5e4 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/loop_var.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/loop_var.hlsl
@@ -3,6 +3,8 @@
// expected-no-diagnostics
+// DXC: passes (both sema and codegen).
+
RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gOut : register(u3);
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/nested_struct_resource_member.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/nested_struct_resource_member.hlsl
index f2607c3092c12..f2b88c7ccbb2a 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/nested_struct_resource_member.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/nested_struct_resource_member.hlsl
@@ -3,6 +3,8 @@
// expected-no-diagnostics
+// DXC: passes (both sema and codegen).
+
RWByteAddressBuffer gBuf1 : register(u1);
struct NestedInner { RWByteAddressBuffer buf; };
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_initialized.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_initialized.hlsl
index 0be18c8c18450..6e584396e6363 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_initialized.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_initialized.hlsl
@@ -3,6 +3,8 @@
// expected-no-diagnostics
+// DXC: passes (both sema and codegen).
+
RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer Pass_ReturnLocal()
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_uninitialized.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_uninitialized.hlsl
index a0409412696c7..1a4b5ae80167a 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_uninitialized.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_uninitialized.hlsl
@@ -3,6 +3,8 @@
// expected-no-diagnostics
+// DXC: passes (both sema and codegen).
+
RWByteAddressBuffer Pass_ReturnLocal_Uninitialized()
{
RWByteAddressBuffer buf;
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/struct_array_with_resource_member.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/struct_array_with_resource_member.hlsl
index 057f4bae8e32e..27dc5f067f75b 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/struct_array_with_resource_member.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/struct_array_with_resource_member.hlsl
@@ -3,6 +3,8 @@
// expected-no-diagnostics
+// DXC: passes (both sema and codegen).
+
RWByteAddressBuffer gBuf0 : register(u0);
struct BufStruct { RWByteAddressBuffer buf; };
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/struct_with_resource_array_member.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/struct_with_resource_array_member.hlsl
index bad04c673bb84..47971ebd630bc 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/struct_with_resource_array_member.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/struct_with_resource_array_member.hlsl
@@ -3,6 +3,8 @@
// expected-no-diagnostics
+// DXC: passes (both sema and codegen).
+
RWByteAddressBuffer gBuf0 : register(u0);
struct S { RWByteAddressBuffer arr[2]; };
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared.hlsl
deleted file mode 100644
index 30bae24d853ac..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared.hlsl
+++ /dev/null
@@ -1,31 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// This test fails validation in DXC, but DXC's sema allows it.
-// Meanwhile, groupshared is immediately detected and rejected in clang's sema.
-
-RWByteAddressBuffer gOut : register(u3);
-
-// expected-note at +1{{passing argument to parameter 'buf' here}}
-uint DoStore(RWByteAddressBuffer buf, uint offset, uint value)
-{
- buf.Store(offset, value);
- return value;
-}
-
-// expected-note@*:*{{candidate constructor not viable: cannot bind reference in address space 'groupshared' to object in generic address space in 1st argument}}
-// expected-note@*:*{{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
-
-groupshared RWByteAddressBuffer sharedBuf;
-uint Use_Shared(uint idx)
-{
- // expected-error at +1{{no matching constructor for initialization of 'RWByteAddressBuffer'}}
- return DoStore(sharedBuf, idx * 4, 1);
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
- uint idx = tid.x + tid.y * 8;
- Use_Shared(idx);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/use_local_resource_uninitialized.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/use_local_resource_uninitialized.hlsl
index fc6612e62c46d..4f8e2512c74ea 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/use_local_resource_uninitialized.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/use_local_resource_uninitialized.hlsl
@@ -3,6 +3,8 @@
// expected-no-diagnostics
+// DXC: passes (both sema and codegen).
+
uint Pass_Uninitialized(uint idx)
{
RWByteAddressBuffer buf;
>From 117ea64bc7a6e721974a2f82fd0064ddf24d6a5f Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Fri, 3 Apr 2026 13:52:02 -0700
Subject: [PATCH 07/10] add xfail
---
.../resources/Local-Resources/use_struct_groupshared.hlsl | 3 +++
1 file changed, 3 insertions(+)
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/use_struct_groupshared.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/use_struct_groupshared.hlsl
index 07429cf2b85c3..fcdf8e63f1285 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/use_struct_groupshared.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/use_struct_groupshared.hlsl
@@ -1,5 +1,8 @@
// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
// RUN: dxil-pc-shadermodel6.6-compute -emit-llvm -disable-llvm-passes 2>&1 -o - %s | llvm-cxxfilt | FileCheck %s
+//
+// XFAIL: *
+// https://github.com/llvm/llvm-project/issues/158107
// This test fails validation in DXC, but DXC's sema allows it.
// Meanwhile, it is for some reason accepted by clang's sema.
>From 0e8943a49ce8cdb3e59a3f1ead75164de2fd39b9 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Fri, 3 Apr 2026 16:23:23 -0700
Subject: [PATCH 08/10] formatting
---
.../local_resource_break_reassign.hlsl | 7 +++----
.../local_resource_continue_reassign.hlsl | 9 +++------
.../local_resource_multiple_returns.hlsl | 9 +++------
.../local_resource_nested_ternary.hlsl | 3 +--
.../local_resource_phi_merge_ternary.hlsl | 6 ++----
.../local_resource_ternary_as_argument.hlsl | 6 ++----
.../local_resource_ternary_assign.hlsl | 6 ++----
.../Local-Resources/local_resource_wave_uniform.hlsl | 8 +++-----
.../Local-Resources/ternary_initialization.hlsl | 8 +++-----
.../resources/Local-Resources/use_groupshared.hlsl | 9 +++------
.../Local-Resources/use_struct_groupshared.hlsl | 9 +++------
.../Resources/Local-Resources/expression_init.hlsl | 8 +++-----
.../forward_struct_layers_resource.hlsl | 6 ++----
.../Local-Resources/local_resource_addition.hlsl | 6 ++----
.../local_resource_aggregate_init.hlsl | 3 +--
.../Local-Resources/local_resource_alias_chain.hlsl | 6 ++----
.../Local-Resources/local_resource_alias_global.hlsl | 6 ++----
.../Local-Resources/local_resource_arithmetic.hlsl | 6 ++----
.../Local-Resources/local_resource_array.hlsl | 6 ++----
.../Local-Resources/local_resource_array_copy.hlsl | 3 +--
.../local_resource_array_dynamic_index.hlsl | 3 +--
.../Local-Resources/local_resource_array_oob.hlsl | 3 +--
.../local_resource_array_partial_init.hlsl | 3 +--
.../local_resource_array_size_one.hlsl | 6 ++----
.../local_resource_as_structured_buffer_element.hlsl | 6 ++----
.../local_resource_assign_wrong_type.hlsl | 3 +--
.../local_resource_bindless_array.hlsl | 6 ++----
.../local_resource_bindless_selection.hlsl | 6 ++----
.../local_resource_block_lifetime.hlsl | 6 ++----
.../local_resource_cast_sampler_to_buffer.hlsl | 6 ++----
.../Local-Resources/local_resource_cast_to_uint.hlsl | 6 ++----
.../Local-Resources/local_resource_chained_call.hlsl | 3 +--
.../Local-Resources/local_resource_comma_init.hlsl | 3 +--
.../Local-Resources/local_resource_compare.hlsl | 6 ++----
.../local_resource_conditional_init.hlsl | 5 ++---
.../Local-Resources/local_resource_const_param.hlsl | 6 ++----
.../local_resource_const_reassign.hlsl | 3 +--
.../local_resource_copy_between_locals.hlsl | 3 +--
.../Local-Resources/local_resource_deep_phi.hlsl | 8 +++-----
.../local_resource_default_init_store.hlsl | 3 +--
.../local_resource_default_param.hlsl | 3 +--
.../local_resource_different_types.hlsl | 3 +--
.../local_resource_do_while_reassign.hlsl | 5 ++---
.../local_resource_early_return_reassign.hlsl | 8 +++-----
.../local_resource_forward_through_functions.hlsl | 12 ++++--------
.../local_resource_from_function_return.hlsl | 6 ++----
.../Local-Resources/local_resource_inout_param.hlsl | 6 ++----
.../local_resource_loop_array_index.hlsl | 9 +++------
.../Local-Resources/local_resource_loop_carried.hlsl | 8 +++-----
.../Local-Resources/local_resource_mixed_struct.hlsl | 3 +--
.../Local-Resources/local_resource_multi_decl.hlsl | 3 +--
.../local_resource_multiple_uses.hlsl | 9 +++------
.../local_resource_nested_blocks_reassign.hlsl | 6 ++----
.../Local-Resources/local_resource_nested_loops.hlsl | 11 ++++-------
.../Local-Resources/local_resource_out_param.hlsl | 6 ++----
.../Local-Resources/local_resource_overload.hlsl | 9 +++------
.../Local-Resources/local_resource_read_only.hlsl | 6 ++----
.../local_resource_reassign_different_global.hlsl | 6 ++----
.../Local-Resources/local_resource_self_assign.hlsl | 3 +--
.../local_resource_shadow_inner_scope.hlsl | 6 ++----
.../Local-Resources/local_resource_static_const.hlsl | 6 ++----
.../Local-Resources/local_resource_static_local.hlsl | 6 ++----
.../local_resource_struct_method.hlsl | 3 +--
.../local_resource_struct_return.hlsl | 6 ++----
.../local_resource_structured_buffer.hlsl | 6 ++----
.../Local-Resources/local_resource_swap.hlsl | 3 +--
.../local_resource_switch_default.hlsl | 9 +++------
.../local_resource_switch_fallthrough.hlsl | 9 +++------
.../local_resource_switch_reassign.hlsl | 9 +++------
.../local_resource_template_function.hlsl | 9 +++------
.../local_resource_ternary_lvalue.hlsl | 3 +--
.../Local-Resources/local_resource_to_bool.hlsl | 6 ++----
.../local_resource_unreachable_reassign.hlsl | 5 ++---
.../Local-Resources/local_resource_volatile.hlsl | 3 +--
.../local_resource_with_wave_intrinsic.hlsl | 6 ++----
.../Local-Resources/local_resource_zero_init.hlsl | 3 +--
.../local_struct_resource_member.hlsl | 9 +++------
.../SemaHLSL/Resources/Local-Resources/loop_var.hlsl | 11 ++++-------
.../nested_struct_resource_member.hlsl | 6 ++----
.../return_local_resource_initialized.hlsl | 6 ++----
.../return_local_resource_uninitialized.hlsl | 6 ++----
.../struct_array_with_resource_member.hlsl | 6 ++----
.../struct_resource_member_reassign.hlsl | 3 +--
.../struct_with_resource_array_member.hlsl | 6 ++----
.../use_groupshared_direct_store.hlsl | 6 ++----
.../use_local_resource_uninitialized.hlsl | 6 ++----
86 files changed, 174 insertions(+), 335 deletions(-)
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_break_reassign.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_break_reassign.hlsl
index f6a49ba96e3f8..9b1e9f26c0ba4 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_break_reassign.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_break_reassign.hlsl
@@ -12,11 +12,10 @@ RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer buf = gBuf0;
- for(uint i = 0; i < 4; i++) {
- if(i == tid.x) break;
+ for (uint i = 0; i < 4; i++) {
+ if (i == tid.x) break;
buf = gBuf1;
}
buf.Store(tid.x * 4, 42);
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_continue_reassign.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_continue_reassign.hlsl
index 58db0fe0ed364..283da82831092 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_continue_reassign.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_continue_reassign.hlsl
@@ -11,14 +11,11 @@ RWByteAddressBuffer gBuf1 : register(u1);
// CHECK: warning: assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer buf = gBuf0;
- for(uint i = 0; i < 4; i++)
- {
- if(i == 2)
- {
+ for (uint i = 0; i < 4; i++) {
+ if (i == 2) {
// DXC: error after sema: local resource not guaranteed to map to unique global resource.
buf = gBuf1;
continue;
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_multiple_returns.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_multiple_returns.hlsl
index c6e848df4f956..38482fe16faa9 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_multiple_returns.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_multiple_returns.hlsl
@@ -10,11 +10,9 @@ RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
// CHECK: warning: assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource
-RWByteAddressBuffer Pass_MultipleReturns(bool cond, uint idx)
-{
+RWByteAddressBuffer Pass_MultipleReturns(bool cond, uint idx) {
RWByteAddressBuffer buf = gBuf0;
- if(cond)
- {
+ if (cond) {
buf.Store(idx * 4, 1);
return buf;
}
@@ -28,8 +26,7 @@ RWByteAddressBuffer Pass_MultipleReturns(bool cond, uint idx)
// CHECK: define void @main()
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
RWByteAddressBuffer result = Pass_MultipleReturns(idx < 32, idx);
result.Store(0, idx);
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_nested_ternary.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_nested_ternary.hlsl
index 017c5a2ef627e..fcb14ae55263b 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_nested_ternary.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_nested_ternary.hlsl
@@ -14,8 +14,7 @@ RWByteAddressBuffer gBuf1 : register(u1);
RWByteAddressBuffer gBuf2 : register(u2);
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
bool c1 = tid.x > 0;
bool c2 = tid.y > 0;
RWByteAddressBuffer buf = c1 ? gBuf0 : (c2 ? gBuf1 : gBuf2);
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_phi_merge_ternary.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_phi_merge_ternary.hlsl
index 08ea7f13ad234..68aeeea87a178 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_phi_merge_ternary.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_phi_merge_ternary.hlsl
@@ -9,8 +9,7 @@
RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf2 : register(u2);
-uint Pass_PhiMerge(bool cond, uint idx)
-{
+uint Pass_PhiMerge(bool cond, uint idx) {
RWByteAddressBuffer buf;
// DXC: error after sema: local resource not guaranteed to map to unique global resource.
// CHECK: warning: assignment of 'cond ? gBuf0 : gBuf2' to local resource 'buf' is not to the same unique global resource
@@ -24,8 +23,7 @@ uint Pass_PhiMerge(bool cond, uint idx)
// CHECK: define void @main()
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_PhiMerge(idx < 32, idx);
}
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_as_argument.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_as_argument.hlsl
index db2dc5ffcbef0..d01c9f39d6e45 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_as_argument.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_as_argument.hlsl
@@ -11,14 +11,12 @@
RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
-void Helper(RWByteAddressBuffer buf, uint offset, uint value)
-{
+void Helper(RWByteAddressBuffer buf, uint offset, uint value) {
buf.Store(offset, value);
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
bool cond = tid.x > 0;
Helper(cond ? gBuf0 : gBuf1, tid.x * 4, 42);
}
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_assign.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_assign.hlsl
index faecc5ab5f773..e1e42f9aa835f 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_assign.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_assign.hlsl
@@ -9,8 +9,7 @@
RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
-uint Pass_IfAlias(bool cond, uint idx)
-{
+uint Pass_IfAlias(bool cond, uint idx) {
RWByteAddressBuffer buf;
// DXC: error after sema: local resource not guaranteed to map to unique global resource.
// CHECK: warning: assignment of 'cond ? gBuf0 : gBuf1' to local resource 'buf' is not to the same unique global resource
@@ -24,8 +23,7 @@ uint Pass_IfAlias(bool cond, uint idx)
// CHECK: define void @main()
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_IfAlias(idx < 32, idx);
}
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_wave_uniform.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_wave_uniform.hlsl
index 0ef5f49f56058..91aa53be6a508 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_wave_uniform.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_wave_uniform.hlsl
@@ -11,10 +11,9 @@
RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
-uint Fail_WaveUniform(uint offset, uint value)
-{
+uint Fail_WaveUniform(uint offset, uint value) {
RWByteAddressBuffer buf = gBuf0;
- if(WaveActiveAllTrue(true))
+ if (WaveActiveAllTrue(true))
buf = gBuf1;
// expected-warning: assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource
buf.Store(offset, value);
@@ -28,7 +27,6 @@ uint Fail_WaveUniform(uint offset, uint value)
// CHECK-NOT: error:
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
Fail_WaveUniform(tid.x * 4, 10);
}
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/ternary_initialization.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/ternary_initialization.hlsl
index 947199d3c051d..90e5e67681903 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/ternary_initialization.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/ternary_initialization.hlsl
@@ -10,8 +10,7 @@ RWByteAddressBuffer gOut : register(u3);
RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
-uint Pass_TernaryInit(bool cond, uint idx)
-{
+uint Pass_TernaryInit(bool cond, uint idx) {
// DXC emits this warning: local resource not guaranteed to map to unique global resource.
// Below is generated by -Whlsl-explicit-binding
// CHECK: warning: assignment of 'cond ? gBuf0 : gBuf1' to local resource 'buf' is not to the same unique global resource
@@ -22,8 +21,7 @@ uint Pass_TernaryInit(bool cond, uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_TernaryInit(idx < 32, idx);
-}
\ No newline at end of file
+}
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/use_groupshared.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/use_groupshared.hlsl
index dc56ec1ddd6fb..7b054914c6d14 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/use_groupshared.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/use_groupshared.hlsl
@@ -9,15 +9,13 @@
RWByteAddressBuffer gOut : register(u3);
-uint DoStore(RWByteAddressBuffer buf, uint offset, uint value)
-{
+uint DoStore(RWByteAddressBuffer buf, uint offset, uint value) {
buf.Store(offset, value);
return value;
}
groupshared RWByteAddressBuffer sharedBuf;
-uint Use_Shared(uint idx)
-{
+uint Use_Shared(uint idx) {
return DoStore(sharedBuf, idx * 4, 1);
}
@@ -27,8 +25,7 @@ uint Use_Shared(uint idx)
// CHECK: note: passing argument to parameter 'buf' here
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Use_Shared(idx);
}
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/use_struct_groupshared.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/use_struct_groupshared.hlsl
index fcdf8e63f1285..d78e2bfea4422 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/use_struct_groupshared.hlsl
+++ b/clang/test/CodeGenHLSL/resources/Local-Resources/use_struct_groupshared.hlsl
@@ -16,8 +16,7 @@
RWByteAddressBuffer gOut : register(u3);
// CHECK: note: passing argument to parameter 'buf' here
-uint DoStore(RWByteAddressBuffer buf, uint offset, uint value)
-{
+uint DoStore(RWByteAddressBuffer buf, uint offset, uint value) {
buf.Store(offset, value);
return value;
}
@@ -29,15 +28,13 @@ struct PassBufStruct { RWByteAddressBuffer buf; };
groupshared PassBufStruct sharedStruct;
-uint Use_PassSharedStruct(uint idx)
-{
+uint Use_PassSharedStruct(uint idx) {
// CHECK: error: no matching constructor for initialization of 'RWByteAddressBuffer'
return DoStore(sharedStruct.buf, idx * 4, 1);
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Use_PassSharedStruct(idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.hlsl
index 08c383053537d..128bcf44056ed 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.hlsl
@@ -10,8 +10,7 @@ RWByteAddressBuffer gBuf1 : register(u1);
RWByteAddressBuffer gOut : register(u3);
-uint Pass_ExpressionInit(uint idx)
-{
+uint Pass_ExpressionInit(uint idx) {
RWByteAddressBuffer buf = (true ? gBuf0 : gBuf1);
buf.Store(idx * 4, 3);
@@ -19,8 +18,7 @@ uint Pass_ExpressionInit(uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_ExpressionInit(idx);
-}
\ No newline at end of file
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/forward_struct_layers_resource.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/forward_struct_layers_resource.hlsl
index 65356d59c07dc..156f15e3d3fe5 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/forward_struct_layers_resource.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/forward_struct_layers_resource.hlsl
@@ -10,8 +10,7 @@ RWByteAddressBuffer gBuf2 : register(u2);
struct ForwardA { RWByteAddressBuffer buf; };
struct ForwardB { ForwardA a; };
-uint Pass_ForwardStructLayers(uint idx)
-{
+uint Pass_ForwardStructLayers(uint idx) {
ForwardB b;
b.a.buf = gBuf2;
b.a.buf.Store(idx * 4, 29);
@@ -20,8 +19,7 @@ uint Pass_ForwardStructLayers(uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_ForwardStructLayers(idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_addition.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_addition.hlsl
index 3af4858b85e3c..9f55cf1b9fef5 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_addition.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_addition.hlsl
@@ -8,15 +8,13 @@
RWByteAddressBuffer gBuf0 : register(u0);
-float Fail_Add()
-{
+float Fail_Add() {
RWByteAddressBuffer buf = gBuf0;
return buf + buf;
// expected-error at -1 {{invalid operands to binary expression ('RWByteAddressBuffer' and 'RWByteAddressBuffer')}}
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
Fail_Add();
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_aggregate_init.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_aggregate_init.hlsl
index 961cd06b2e68b..6f346b9959b17 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_aggregate_init.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_aggregate_init.hlsl
@@ -13,8 +13,7 @@ RWByteAddressBuffer gBuf0 : register(u0);
struct ResHolder { RWByteAddressBuffer buf; };
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
ResHolder h = {gBuf0};
h.buf.Store(tid.x * 4, 42);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_chain.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_chain.hlsl
index 40d1f079200d9..2d4b8d050848c 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_chain.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_chain.hlsl
@@ -7,8 +7,7 @@
RWByteAddressBuffer gBuf0 : register(u0);
-uint Pass_AliasChain(uint idx)
-{
+uint Pass_AliasChain(uint idx) {
RWByteAddressBuffer a = gBuf0;
RWByteAddressBuffer b = a;
RWByteAddressBuffer c = b;
@@ -20,8 +19,7 @@ uint Pass_AliasChain(uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_AliasChain(idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_global.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_global.hlsl
index cd41a7e77f414..21ad35ed26088 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_global.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_global.hlsl
@@ -7,8 +7,7 @@
RWByteAddressBuffer gBuf0 : register(u0);
-uint Pass_Alias(uint idx)
-{
+uint Pass_Alias(uint idx) {
RWByteAddressBuffer buf = gBuf0;
buf.Store(idx * 4, 12);
@@ -16,8 +15,7 @@ uint Pass_Alias(uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_Alias(idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_arithmetic.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_arithmetic.hlsl
index 8ad396ad5a9ae..64c879c516bd0 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_arithmetic.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_arithmetic.hlsl
@@ -10,8 +10,7 @@
RWByteAddressBuffer gBuf0 : register(u0);
-float Fail_Arithmetic()
-{
+float Fail_Arithmetic() {
RWByteAddressBuffer buf = gBuf0;
buf = buf + 1;
// expected-error at -1 {{invalid operands to binary expression ('RWByteAddressBuffer' and 'int')}}
@@ -20,7 +19,6 @@ float Fail_Arithmetic()
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
Fail_Arithmetic();
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array.hlsl
index 77d43f963cc51..f75ca155a448b 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array.hlsl
@@ -7,8 +7,7 @@
RWByteAddressBuffer gBuf0 : register(u0);
-uint Pass_LocalArray(uint idx)
-{
+uint Pass_LocalArray(uint idx) {
RWByteAddressBuffer arr[2];
arr[0] = gBuf0;
arr[0].Store(idx * 4, 10);
@@ -17,8 +16,7 @@ uint Pass_LocalArray(uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_LocalArray(idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_copy.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_copy.hlsl
index cb6f6943acdf7..95279e1a5536a 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_copy.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_copy.hlsl
@@ -10,8 +10,7 @@
RWByteAddressBuffer gBufArray[4] : register(u0);
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer src[2];
src[0] = gBufArray[0];
src[1] = gBufArray[1];
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_dynamic_index.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_dynamic_index.hlsl
index 2fa6404421059..bdc81a428f8ba 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_dynamic_index.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_dynamic_index.hlsl
@@ -10,8 +10,7 @@
RWByteAddressBuffer gBufArray[4] : register(u0);
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer localArr[2];
localArr[0] = gBufArray[0];
localArr[1] = gBufArray[1];
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_oob.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_oob.hlsl
index 0946509e820cb..0aa8df4d412ad 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_oob.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_oob.hlsl
@@ -11,8 +11,7 @@
RWByteAddressBuffer gBufArray[4] : register(u0);
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer buf = gBufArray[5];
// expected-warning at -1 {{array index 5 is past the end of the array (that has type 'RWByteAddressBuffer[4]')}}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_partial_init.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_partial_init.hlsl
index 67ef424c6991e..e8a8b0d93cd56 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_partial_init.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_partial_init.hlsl
@@ -11,8 +11,7 @@
RWByteAddressBuffer gBuf0 : register(u0);
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer arr[4];
arr[0] = gBuf0;
arr[1] = gBuf0;
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_size_one.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_size_one.hlsl
index 36100f67f983a..94bc2d3e7d634 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_size_one.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_size_one.hlsl
@@ -11,8 +11,7 @@
RWByteAddressBuffer gBuf0 : register(u0);
-uint Pass_ArraySizeOne(uint idx)
-{
+uint Pass_ArraySizeOne(uint idx) {
RWByteAddressBuffer arr[1];
arr[0] = gBuf0;
arr[0].Store(idx * 4, 42);
@@ -20,7 +19,6 @@ uint Pass_ArraySizeOne(uint idx)
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
Pass_ArraySizeOne(tid.x);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_as_structured_buffer_element.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_as_structured_buffer_element.hlsl
index c74c567381994..0ff70d103e0d0 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_as_structured_buffer_element.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_as_structured_buffer_element.hlsl
@@ -9,8 +9,7 @@
RWByteAddressBuffer gBuf0 : register(u0);
-void Fail_LocalBuffer()
-{
+void Fail_LocalBuffer() {
RWStructuredBuffer<RWByteAddressBuffer> badBuffer;
// expected-error at -1 {{constraints not satisfied for class template 'RWStructuredBuffer' [with element_type = RWByteAddressBuffer]}}
// expected-note@*:* {{because 'RWByteAddressBuffer' does not satisfy '__is_structured_resource_element_compatible'}}
@@ -18,7 +17,6 @@ void Fail_LocalBuffer()
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
Fail_LocalBuffer();
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_assign_wrong_type.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_assign_wrong_type.hlsl
index a0b1f4ccda0d7..957195bca8500 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_assign_wrong_type.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_assign_wrong_type.hlsl
@@ -10,8 +10,7 @@ RWByteAddressBuffer gBuf0 : register(u0);
RWStructuredBuffer<uint> gSB : register(u1);
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer buf = gBuf0;
RWStructuredBuffer<uint> sb = gSB;
buf = sb;
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_array.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_array.hlsl
index 5c1bfd8a7cced..857dfafe3b56f 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_array.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_array.hlsl
@@ -7,8 +7,7 @@
RWByteAddressBuffer gBufArray[4] : register(u10);
-uint Pass_Bindless(uint idx)
-{
+uint Pass_Bindless(uint idx) {
RWByteAddressBuffer buf = gBufArray[idx & 3];
buf.Store(idx * 4, 21);
@@ -16,8 +15,7 @@ uint Pass_Bindless(uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_Bindless(idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_selection.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_selection.hlsl
index 7ffb9fa23dc58..694d72cda9fff 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_selection.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_selection.hlsl
@@ -7,8 +7,7 @@
RWByteAddressBuffer gBufArray[4] : register(u10);
-uint Pass_BindlessSelection(uint a, uint b, uint idx)
-{
+uint Pass_BindlessSelection(uint a, uint b, uint idx) {
RWByteAddressBuffer buf;
buf = gBufArray[a & 3];
@@ -21,8 +20,7 @@ uint Pass_BindlessSelection(uint a, uint b, uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_BindlessSelection(2, 3, idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_block_lifetime.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_block_lifetime.hlsl
index 22dc1f5ac83ac..f677def01bca3 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_block_lifetime.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_block_lifetime.hlsl
@@ -7,8 +7,7 @@
RWByteAddressBuffer gBuf1 : register(u1);
-uint Pass_BlockLifetime(uint idx)
-{
+uint Pass_BlockLifetime(uint idx) {
RWByteAddressBuffer buf;
{
buf = gBuf1;
@@ -19,8 +18,7 @@ uint Pass_BlockLifetime(uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_BlockLifetime(idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_cast_sampler_to_buffer.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_cast_sampler_to_buffer.hlsl
index 92412e59387ac..d722125807ca6 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_cast_sampler_to_buffer.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_cast_sampler_to_buffer.hlsl
@@ -9,8 +9,7 @@
RWByteAddressBuffer gBuf0 : register(u0);
SamplerState gSampler : register(s0);
-uint Fail_Reinterpret(uint offset, uint value)
-{
+uint Fail_Reinterpret(uint offset, uint value) {
RWByteAddressBuffer buf = gBuf0;
((RWByteAddressBuffer)gSampler).Store(offset, value);
// expected-error at -1 {{no matching conversion for C-style cast from 'SamplerState' to 'RWByteAddressBuffer'}}
@@ -20,7 +19,6 @@ uint Fail_Reinterpret(uint offset, uint value)
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
Fail_Reinterpret(tid.x * 4, 8);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_cast_to_uint.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_cast_to_uint.hlsl
index f246eb1589af5..7ebd8b89d9a91 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_cast_to_uint.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_cast_to_uint.hlsl
@@ -8,15 +8,13 @@
RWByteAddressBuffer gBuf0 : register(u0);
-uint Fail_Cast()
-{
+uint Fail_Cast() {
RWByteAddressBuffer buf = gBuf0;
return (uint)buf;
// expected-error at -1 {{cannot convert 'RWByteAddressBuffer' to 'uint' (aka 'unsigned int') without a conversion operator}}
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
Fail_Cast();
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_chained_call.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_chained_call.hlsl
index d6763d5a28960..0cb9baa8de191 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_chained_call.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_chained_call.hlsl
@@ -14,7 +14,6 @@ RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer GetBuf() { return gBuf0; }
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
GetBuf().Store(tid.x * 4, 42);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_comma_init.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_comma_init.hlsl
index d85d3477e3bff..39fbb4dc00a2a 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_comma_init.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_comma_init.hlsl
@@ -11,8 +11,7 @@ RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
// expected-warning at +1 {{left operand of comma operator has no effect}}
RWByteAddressBuffer buf = (gBuf0, gBuf1);
buf.Store(tid.x * 4, 42);
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_compare.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_compare.hlsl
index a711acb8d47ab..9d173e630ea47 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_compare.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_compare.hlsl
@@ -9,8 +9,7 @@
RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
-bool Fail_Compare()
-{
+bool Fail_Compare() {
RWByteAddressBuffer a = gBuf0;
RWByteAddressBuffer b = gBuf1;
return a == b;
@@ -18,7 +17,6 @@ bool Fail_Compare()
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
Fail_Compare();
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_conditional_init.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_conditional_init.hlsl
index 1de6dd450c2a6..c796ec06d3a84 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_conditional_init.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_conditional_init.hlsl
@@ -11,10 +11,9 @@
RWByteAddressBuffer gBuf0 : register(u0);
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer buf;
- if(tid.x > 0)
+ if (tid.x > 0)
buf = gBuf0;
buf.Store(tid.x * 4, 42);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_const_param.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_const_param.hlsl
index 34e9fd5611fc5..431f7ac55d900 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_const_param.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_const_param.hlsl
@@ -9,14 +9,12 @@
RWByteAddressBuffer gBuf0 : register(u0);
-void ReadOnly(const RWByteAddressBuffer buf, uint offset, out uint result)
-{
+void ReadOnly(const RWByteAddressBuffer buf, uint offset, out uint result) {
result = 0;
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer local = gBuf0;
uint r;
ReadOnly(local, tid.x * 4, r);
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_const_reassign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_const_reassign.hlsl
index 75a348d39ec0a..5081cdbe51f2b 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_const_reassign.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_const_reassign.hlsl
@@ -11,8 +11,7 @@ RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
const RWByteAddressBuffer buf = gBuf0;
buf = gBuf1;
// expected-warning at -1 {{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_copy_between_locals.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_copy_between_locals.hlsl
index 11531d1a85d46..e2358df7d2241 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_copy_between_locals.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_copy_between_locals.hlsl
@@ -10,8 +10,7 @@
RWByteAddressBuffer gBuf0 : register(u0);
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer a = gBuf0;
RWByteAddressBuffer b = a;
b.Store(tid.x * 4, 42);
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_deep_phi.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_deep_phi.hlsl
index 919c1ba6f18be..604e97341e920 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_deep_phi.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_deep_phi.hlsl
@@ -9,11 +9,10 @@ RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
RWByteAddressBuffer gBuf2 : register(u2);
-uint Pass_DeepPhi(bool a, bool b, uint idx)
-{
+uint Pass_DeepPhi(bool a, bool b, uint idx) {
RWByteAddressBuffer buf;
- if(a)
+ if (a)
// DXC: no diagnostic. Clang: warning.
// expected-warning at +1{{assignment of 'b ? gBuf0 : gBuf1' to local resource 'buf' is not to the same unique global resource}}
buf = b ? gBuf0 : gBuf1;
@@ -27,8 +26,7 @@ uint Pass_DeepPhi(bool a, bool b, uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_DeepPhi(true, false, idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_init_store.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_init_store.hlsl
index 130140e53b56f..00ba8436305dc 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_init_store.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_init_store.hlsl
@@ -9,8 +9,7 @@
// DXC: passes (both sema and codegen).
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer buf;
buf.Store(tid.x * 4, 42);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_param.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_param.hlsl
index 5e0df96430ee0..23ae0c3c3f605 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_param.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_param.hlsl
@@ -17,7 +17,6 @@ uint Fail_DefaultParam(RWByteAddressBuffer buf = gBuf0, uint offset)
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
Fail_DefaultParam(gBuf0, tid.x * 4);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_different_types.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_different_types.hlsl
index 27783c3f12ad3..d6e0b04d64c8d 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_different_types.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_different_types.hlsl
@@ -12,8 +12,7 @@ RWByteAddressBuffer gBuf0 : register(u0);
RWStructuredBuffer<uint> gSB : register(u1);
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer localBuf = gBuf0;
RWStructuredBuffer<uint> localSB = gSB;
localBuf.Store(tid.x * 4, 42);
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_do_while_reassign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_do_while_reassign.hlsl
index 610aa540f6784..41fe34f922144 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_do_while_reassign.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_do_while_reassign.hlsl
@@ -10,8 +10,7 @@ RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer buf = gBuf0;
// expected-note at -1 {{variable 'buf' is declared here}}
uint i = 0;
@@ -19,6 +18,6 @@ void main(uint3 tid : SV_DispatchThreadID)
buf = gBuf1;
// expected-warning at -1 {{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
i++;
- } while(i < tid.x);
+ } while (i < tid.x);
buf.Store(tid.x * 4, 42);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_early_return_reassign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_early_return_reassign.hlsl
index 776682131f9f3..2c1ecad9c2c0a 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_early_return_reassign.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_early_return_reassign.hlsl
@@ -8,12 +8,11 @@
RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
-uint Pass_EarlyReturn(bool cond, uint idx)
-{
+uint Pass_EarlyReturn(bool cond, uint idx) {
// expected-note at +1{{variable 'buf' is declared here}}
RWByteAddressBuffer buf = gBuf0;
- if(cond)
+ if (cond)
buf.Store(idx * 4, 31);
return 31;
@@ -26,8 +25,7 @@ uint Pass_EarlyReturn(bool cond, uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_EarlyReturn(true, idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_forward_through_functions.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_forward_through_functions.hlsl
index eab7dafc61a66..61480bb526818 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_forward_through_functions.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_forward_through_functions.hlsl
@@ -7,26 +7,22 @@
RWByteAddressBuffer gBuf1 : register(u1);
-uint Pass_Level2(RWByteAddressBuffer buf, uint idx)
-{
+uint Pass_Level2(RWByteAddressBuffer buf, uint idx) {
buf.Store(idx*4, 17);
return 17;
}
-uint Pass_Level1(RWByteAddressBuffer buf, uint idx)
-{
+uint Pass_Level1(RWByteAddressBuffer buf, uint idx) {
return Pass_Level2(buf, idx);
}
-uint Pass_FunctionForward(uint idx)
-{
+uint Pass_FunctionForward(uint idx) {
RWByteAddressBuffer buf = gBuf1;
return Pass_Level1(buf, idx);
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_FunctionForward(idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_from_function_return.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_from_function_return.hlsl
index 3b9ee3ec6ec3b..ceeb5e97cbe72 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_from_function_return.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_from_function_return.hlsl
@@ -10,14 +10,12 @@
RWByteAddressBuffer gBuf0 : register(u0);
-RWByteAddressBuffer GetBuffer()
-{
+RWByteAddressBuffer GetBuffer() {
return gBuf0;
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer buf = GetBuffer();
buf.Store(tid.x * 4, 42);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_inout_param.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_inout_param.hlsl
index 72c4d4019d9db..aa4b114be04e3 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_inout_param.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_inout_param.hlsl
@@ -9,14 +9,12 @@
RWByteAddressBuffer gBuf0 : register(u0);
-void ReadAndWrite(inout RWByteAddressBuffer buf, uint offset, uint value)
-{
+void ReadAndWrite(inout RWByteAddressBuffer buf, uint offset, uint value) {
buf.Store(offset, value);
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer local = gBuf0;
ReadAndWrite(local, tid.x * 4, 42);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_array_index.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_array_index.hlsl
index 804a656351250..e6bed0b7a8b45 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_array_index.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_array_index.hlsl
@@ -7,11 +7,9 @@
RWByteAddressBuffer gBufArray[4] : register(u10);
-uint Pass_Loop(uint idx)
-{
+uint Pass_Loop(uint idx) {
uint sum = 0;
- for(unsigned int i=0;i<4;i++)
- {
+ for (unsigned int i=0;i<4;i++) {
RWByteAddressBuffer buf = gBufArray[i];
buf.Store(idx * 4 + i * 4, 15);
@@ -21,8 +19,7 @@ uint Pass_Loop(uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_Loop(idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_carried.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_carried.hlsl
index 3837bf38d6387..69575be39766b 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_carried.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_carried.hlsl
@@ -8,12 +8,11 @@
RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBufArray[4] : register(u10);
-uint Pass_LoopCarried(int iterations, uint idx)
-{
+uint Pass_LoopCarried(int iterations, uint idx) {
// expected-note at +1{{variable 'buf' is declared here}}
RWByteAddressBuffer buf = gBuf0;
- for(int i=0;i<iterations;i++)
+ for (int i=0;i<iterations;i++)
// DXC: no diagnostic. Clang: warning.
// expected-warning at +1{{assignment of 'gBufArray[i & 3]' to local resource 'buf' is not to the same unique global resource}}
buf = gBufArray[i & 3];
@@ -25,8 +24,7 @@ uint Pass_LoopCarried(int iterations, uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_LoopCarried(15, idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_mixed_struct.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_mixed_struct.hlsl
index 8650bac84891a..e4396817ccf8d 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_mixed_struct.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_mixed_struct.hlsl
@@ -16,8 +16,7 @@ struct Node {
};
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
Node n;
n.buf = gBuf0;
n.next = 0;
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multi_decl.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multi_decl.hlsl
index 0d07a827e818c..9b8bb58671b0e 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multi_decl.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multi_decl.hlsl
@@ -13,8 +13,7 @@ RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer a = gBuf0, b = gBuf1;
a.Store(tid.x * 4, 1);
b.Store(tid.x * 4, 2);
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multiple_uses.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multiple_uses.hlsl
index 1fea3ccd6f18b..d03755c8f96a9 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multiple_uses.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multiple_uses.hlsl
@@ -10,19 +10,16 @@
RWByteAddressBuffer gBuf0 : register(u0);
-void HelperA(RWByteAddressBuffer buf, uint offset)
-{
+void HelperA(RWByteAddressBuffer buf, uint offset) {
buf.Store(offset, 1);
}
-void HelperB(RWByteAddressBuffer buf, uint offset)
-{
+void HelperB(RWByteAddressBuffer buf, uint offset) {
buf.Store(offset, 2);
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer local = gBuf0;
HelperA(local, tid.x * 4);
HelperB(local, tid.x * 4 + 4);
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_blocks_reassign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_blocks_reassign.hlsl
index 8fecb384cb2ff..a0d4ee2b30b89 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_blocks_reassign.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_blocks_reassign.hlsl
@@ -8,8 +8,7 @@
RWByteAddressBuffer gBuf1 : register(u1);
RWByteAddressBuffer gBuf2 : register(u2);
-uint Pass_NestedBlocks(uint idx)
-{
+uint Pass_NestedBlocks(uint idx) {
// expected-note at +1{{variable 'buf' is declared here}}
RWByteAddressBuffer buf;
@@ -29,8 +28,7 @@ uint Pass_NestedBlocks(uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_NestedBlocks(idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_loops.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_loops.hlsl
index 6e01f72cb3d89..108341625888e 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_loops.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_loops.hlsl
@@ -7,12 +7,10 @@
RWByteAddressBuffer gBufArray[4] : register(u10);
-uint Pass_NestedLoops(uint idx)
-{
+uint Pass_NestedLoops(uint idx) {
uint sum = 0;
- for(unsigned int i=0;i<2;i++)
- for(unsigned int j=0;j<2;j++)
- {
+ for (unsigned int i=0;i<2;i++)
+ for (unsigned int j=0;j<2;j++) {
RWByteAddressBuffer buf = gBufArray[i+j];
buf.Store(idx * 4 + (i+j)*4, 23);
@@ -22,8 +20,7 @@ uint Pass_NestedLoops(uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_NestedLoops(idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_out_param.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_out_param.hlsl
index 4effb3f6bfdb8..7ef85f36a16b3 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_out_param.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_out_param.hlsl
@@ -9,14 +9,12 @@
RWByteAddressBuffer gBuf0 : register(u0);
-void WriteThrough(out RWByteAddressBuffer buf)
-{
+void WriteThrough(out RWByteAddressBuffer buf) {
buf = gBuf0;
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer local;
WriteThrough(local);
local.Store(tid.x * 4, 42);
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_overload.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_overload.hlsl
index 70d17dfb2d3e1..63e7d0ab28b12 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_overload.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_overload.hlsl
@@ -12,19 +12,16 @@
RWByteAddressBuffer gBuf0 : register(u0);
RWStructuredBuffer<uint> gSB : register(u1);
-void DoStore(RWByteAddressBuffer buf, uint idx, uint val)
-{
+void DoStore(RWByteAddressBuffer buf, uint idx, uint val) {
buf.Store(idx * 4, val);
}
-void DoStore(RWStructuredBuffer<uint> buf, uint idx, uint val)
-{
+void DoStore(RWStructuredBuffer<uint> buf, uint idx, uint val) {
buf[idx] = val;
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer localBuf = gBuf0;
RWStructuredBuffer<uint> localSB = gSB;
DoStore(localBuf, tid.x, 1);
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_read_only.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_read_only.hlsl
index d4302ff781ad1..95ee12313c27c 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_read_only.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_read_only.hlsl
@@ -12,14 +12,12 @@
ByteAddressBuffer gBuf0 : register(t0);
-uint Pass_ReadOnlyLocal(uint idx)
-{
+uint Pass_ReadOnlyLocal(uint idx) {
ByteAddressBuffer buf = gBuf0;
return buf.Load(idx * 4);
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
Pass_ReadOnlyLocal(tid.x);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_reassign_different_global.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_reassign_different_global.hlsl
index d79d462e0d1f9..b9ef1c9bc9c15 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_reassign_different_global.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_reassign_different_global.hlsl
@@ -10,8 +10,7 @@
RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
-uint Pass_Reassign(uint idx)
-{
+uint Pass_Reassign(uint idx) {
// expected-note at +1{{variable 'buf' is declared here}}
RWByteAddressBuffer buf = gBuf0;
// expected-warning at +1{{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
@@ -22,8 +21,7 @@ uint Pass_Reassign(uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_Reassign(idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_self_assign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_self_assign.hlsl
index eb071bcdea58a..ea68e34f33c15 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_self_assign.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_self_assign.hlsl
@@ -10,8 +10,7 @@
RWByteAddressBuffer gBuf0 : register(u0);
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer buf = gBuf0;
buf = buf;
buf.Store(tid.x * 4, 42);
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_shadow_inner_scope.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_shadow_inner_scope.hlsl
index 52f3d83f26442..02c9fdb98d224 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_shadow_inner_scope.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_shadow_inner_scope.hlsl
@@ -8,8 +8,7 @@
RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
-uint Pass_Shadow(uint idx)
-{
+uint Pass_Shadow(uint idx) {
RWByteAddressBuffer buf = gBuf0;
{
RWByteAddressBuffer buf = gBuf1;
@@ -20,8 +19,7 @@ uint Pass_Shadow(uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_Shadow(idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_const.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_const.hlsl
index 71b4c85a72eed..daacea3b83989 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_const.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_const.hlsl
@@ -10,8 +10,7 @@
RWByteAddressBuffer gBuf0 : register(u0);
-uint Fail_StaticConst(uint idx)
-{
+uint Fail_StaticConst(uint idx) {
static const RWByteAddressBuffer buf = gBuf0;
// expected-note@*:* {{candidate function not viable: 'this' argument has type 'const RWByteAddressBuffer', but method is not marked const}}
// expected-note@*:* {{candidate template ignored: couldn't infer template argument 'element_type'}}
@@ -22,7 +21,6 @@ uint Fail_StaticConst(uint idx)
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
Fail_StaticConst(tid.x);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_local.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_local.hlsl
index 778da88a5ee05..24561cd5cd3d3 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_local.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_local.hlsl
@@ -11,8 +11,7 @@
RWByteAddressBuffer gBuf0 : register(u0);
-uint Pass_StaticLocal(uint idx)
-{
+uint Pass_StaticLocal(uint idx) {
static RWByteAddressBuffer buf = gBuf0;
buf.Store(idx * 4, 1);
@@ -20,7 +19,6 @@ uint Pass_StaticLocal(uint idx)
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
Pass_StaticLocal(tid.x);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_method.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_method.hlsl
index b3af9893a4b9b..26382965ed6e0 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_method.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_method.hlsl
@@ -17,8 +17,7 @@ struct Wrapper {
};
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
Wrapper w;
w.buf = gBuf0;
w.DoStore(tid.x, 42);
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_return.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_return.hlsl
index 0563300c30ebd..0683b6227416b 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_return.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_return.hlsl
@@ -11,16 +11,14 @@ RWByteAddressBuffer gBuf0 : register(u0);
struct ResHolder { RWByteAddressBuffer buf; };
-ResHolder MakeHolder()
-{
+ResHolder MakeHolder() {
ResHolder h;
h.buf = gBuf0;
return h;
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
ResHolder h = MakeHolder();
h.buf.Store(tid.x * 4, 42);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_structured_buffer.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_structured_buffer.hlsl
index 3bd8f011bf506..e3c79cabf1103 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_structured_buffer.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_structured_buffer.hlsl
@@ -11,15 +11,13 @@
RWStructuredBuffer<uint> gSB : register(u0);
-uint Pass_StructuredBufferLocal(uint idx)
-{
+uint Pass_StructuredBufferLocal(uint idx) {
RWStructuredBuffer<uint> sb = gSB;
sb[idx] = 42;
return 42;
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
Pass_StructuredBufferLocal(tid.x);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_swap.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_swap.hlsl
index 0d8ab32f11e3d..a030b7dd4ee96 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_swap.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_swap.hlsl
@@ -13,8 +13,7 @@ RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer a = gBuf0;
RWByteAddressBuffer b = gBuf1;
RWByteAddressBuffer temp = a;
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_default.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_default.hlsl
index 4efadd1934c63..2fce72904728a 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_default.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_default.hlsl
@@ -9,14 +9,12 @@ RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
RWByteAddressBuffer gBuf2 : register(u2);
-uint Pass_SwitchDefault(int v, uint idx)
-{
+uint Pass_SwitchDefault(int v, uint idx) {
// expected-note at +2{{variable 'buf' is declared here}}
// expected-note at +1{{variable 'buf' is declared here}}
RWByteAddressBuffer buf = gBuf0;
- switch(v)
- {
+ switch (v) {
// DXC: no diagnostic. Clang: warning.
// expected-warning at +1{{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
case 0: buf = gBuf1; break;
@@ -31,8 +29,7 @@ uint Pass_SwitchDefault(int v, uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_SwitchDefault(0, idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_fallthrough.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_fallthrough.hlsl
index 4c7e8dd89a992..07c2c094a35a9 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_fallthrough.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_fallthrough.hlsl
@@ -9,14 +9,12 @@ RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
RWByteAddressBuffer gBuf2 : register(u2);
-uint Pass_SwitchFallthrough(int v, uint idx)
-{
+uint Pass_SwitchFallthrough(int v, uint idx) {
// expected-note at +2{{variable 'buf' is declared here}}
// expected-note at +1{{variable 'buf' is declared here}}
RWByteAddressBuffer buf = gBuf0;
- switch(v)
- {
+ switch (v) {
// DXC: no diagnostic. Clang: warning.
// expected-warning at +1{{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
case 0: buf = gBuf1;
@@ -32,8 +30,7 @@ uint Pass_SwitchFallthrough(int v, uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_SwitchFallthrough(0, idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_reassign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_reassign.hlsl
index 2b561f240fdbc..4aaa91387f669 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_reassign.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_switch_reassign.hlsl
@@ -9,14 +9,12 @@ RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
RWByteAddressBuffer gBuf2 : register(u2);
-uint Pass_Switch(int v, uint idx)
-{
+uint Pass_Switch(int v, uint idx) {
// expected-note at +2{{variable 'buf' is declared here}}
// expected-note at +1{{variable 'buf' is declared here}}
RWByteAddressBuffer buf = gBuf0;
- switch(v)
- {
+ switch (v) {
// DXC: no diagnostic. Clang: warning.
// expected-warning at +1{{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
case 1: buf = gBuf1; break;
@@ -32,8 +30,7 @@ uint Pass_Switch(int v, uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_Switch(1, idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_template_function.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_template_function.hlsl
index 210bb79272be9..a10b894b6873f 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_template_function.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_template_function.hlsl
@@ -11,20 +11,17 @@
RWByteAddressBuffer gBuf0 : register(u0);
template<typename T>
-void UseResource(T buf, uint idx, uint val)
-{
+void UseResource(T buf, uint idx, uint val) {
buf.Store(idx * 4, val);
}
-uint Pass_TemplateFunction(uint idx)
-{
+uint Pass_TemplateFunction(uint idx) {
RWByteAddressBuffer buf = gBuf0;
UseResource(buf, idx, 42);
return 42;
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
Pass_TemplateFunction(tid.x);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_lvalue.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_lvalue.hlsl
index 1f117a6f031a8..f8654215403db 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_lvalue.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_lvalue.hlsl
@@ -13,8 +13,7 @@ RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer a = gBuf0;
RWByteAddressBuffer b = gBuf1;
bool cond = tid.x > 0;
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_to_bool.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_to_bool.hlsl
index 93f0fc076c099..827262a43a9aa 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_to_bool.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_to_bool.hlsl
@@ -9,15 +9,13 @@
RWByteAddressBuffer gBuf0 : register(u0);
-bool Fail_Bool()
-{
+bool Fail_Bool() {
RWByteAddressBuffer buf = gBuf0;
return buf;
// expected-error at -1 {{no viable conversion from returned value of type 'RWByteAddressBuffer' to function return type 'bool'}}
}
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
Fail_Bool();
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_unreachable_reassign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_unreachable_reassign.hlsl
index 089f3760f6abd..0f29c377f0958 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_unreachable_reassign.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_unreachable_reassign.hlsl
@@ -11,11 +11,10 @@ RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer buf = gBuf0;
// expected-note at -1 {{variable 'buf' is declared here}}
- if(tid.x > 0) {
+ if (tid.x > 0) {
buf.Store(0, 1);
return;
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_volatile.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_volatile.hlsl
index 9b9e8dd9bea5e..451bea2e04e59 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_volatile.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_volatile.hlsl
@@ -9,8 +9,7 @@
RWByteAddressBuffer gBuf0 : register(u0);
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
volatile RWByteAddressBuffer buf = gBuf0;
// expected-note@*:* {{candidate function template not viable: 'this' argument has type 'volatile RWByteAddressBuffer', but method is not marked volatile}}
// expected-note@*:* {{candidate function not viable: 'this' argument has type 'volatile RWByteAddressBuffer', but method is not marked volatile}}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_with_wave_intrinsic.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_with_wave_intrinsic.hlsl
index 58f4c5c1177fd..f1cc040637d61 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_with_wave_intrinsic.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_with_wave_intrinsic.hlsl
@@ -7,8 +7,7 @@
RWByteAddressBuffer gBuf0 : register(u0);
-uint Pass_WaveUse(uint idx)
-{
+uint Pass_WaveUse(uint idx) {
RWByteAddressBuffer buf = gBuf0;
uint active = WaveActiveCountBits(true);
buf.Store(idx * 4, active);
@@ -17,8 +16,7 @@ uint Pass_WaveUse(uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_WaveUse(idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_zero_init.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_zero_init.hlsl
index d8122a7ef87a7..1dcd9139e0ff7 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_zero_init.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_zero_init.hlsl
@@ -10,8 +10,7 @@
// "too few elements in vector initialization (expected 1 element, have 0)"
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer buf = {};
// expected-error at -1 {{too few initializers in list for type 'RWByteAddressBuffer' (expected 1 but found 0)}}
buf.Store(tid.x * 4, 42);
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_struct_resource_member.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_struct_resource_member.hlsl
index aa7af2b034e3e..77e15ef911fdd 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_struct_resource_member.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_struct_resource_member.hlsl
@@ -7,13 +7,11 @@
RWByteAddressBuffer gBuf0 : register(u0);
-struct PassStruct
-{
+struct PassStruct {
RWByteAddressBuffer buf;
};
-uint Pass_Struct(uint idx)
-{
+uint Pass_Struct(uint idx) {
PassStruct s;
s.buf = gBuf0;
s.buf.Store(idx * 4, 16);
@@ -22,8 +20,7 @@ uint Pass_Struct(uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_Struct(idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/loop_var.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/loop_var.hlsl
index 801ac358cc5e4..2b5ca8aceeabc 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/loop_var.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/loop_var.hlsl
@@ -9,17 +9,14 @@ RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gOut : register(u3);
-void Pass_LoopVar()
-{
- for(RWByteAddressBuffer buf = gBuf0; false == false; )
- {
+void Pass_LoopVar() {
+ for (RWByteAddressBuffer buf = gBuf0; false == false; ) {
buf.Store(0, 0);
break;
}
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
Pass_LoopVar();
-}
\ No newline at end of file
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/nested_struct_resource_member.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/nested_struct_resource_member.hlsl
index f2b88c7ccbb2a..e0408620da1d0 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/nested_struct_resource_member.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/nested_struct_resource_member.hlsl
@@ -10,8 +10,7 @@ RWByteAddressBuffer gBuf1 : register(u1);
struct NestedInner { RWByteAddressBuffer buf; };
struct NestedOuter { NestedInner inner; };
-uint Pass_NestedStruct(uint idx)
-{
+uint Pass_NestedStruct(uint idx) {
NestedOuter s;
s.inner.buf = gBuf1;
s.inner.buf.Store(idx * 4, 28);
@@ -20,8 +19,7 @@ uint Pass_NestedStruct(uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_NestedStruct(idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_initialized.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_initialized.hlsl
index 6e584396e6363..5900284d6aa98 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_initialized.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_initialized.hlsl
@@ -7,14 +7,12 @@
RWByteAddressBuffer gBuf0 : register(u0);
-RWByteAddressBuffer Pass_ReturnLocal()
-{
+RWByteAddressBuffer Pass_ReturnLocal() {
RWByteAddressBuffer buf = gBuf0;
return buf;
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer tmp = Pass_ReturnLocal();
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_uninitialized.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_uninitialized.hlsl
index 1a4b5ae80167a..b92a8e88dbc66 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_uninitialized.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_uninitialized.hlsl
@@ -5,14 +5,12 @@
// DXC: passes (both sema and codegen).
-RWByteAddressBuffer Pass_ReturnLocal_Uninitialized()
-{
+RWByteAddressBuffer Pass_ReturnLocal_Uninitialized() {
RWByteAddressBuffer buf;
return buf;
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
RWByteAddressBuffer tmp = Pass_ReturnLocal_Uninitialized();
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/struct_array_with_resource_member.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/struct_array_with_resource_member.hlsl
index 27dc5f067f75b..95f5353f6dc39 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/struct_array_with_resource_member.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/struct_array_with_resource_member.hlsl
@@ -9,8 +9,7 @@ RWByteAddressBuffer gBuf0 : register(u0);
struct BufStruct { RWByteAddressBuffer buf; };
-uint Pass_StructArray(uint idx)
-{
+uint Pass_StructArray(uint idx) {
BufStruct s[2];
s[0].buf = gBuf0;
s[0].buf.Store(idx * 4, 5);
@@ -19,8 +18,7 @@ uint Pass_StructArray(uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_StructArray(idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/struct_resource_member_reassign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/struct_resource_member_reassign.hlsl
index ba2e64fbca32f..0b1a339247b67 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/struct_resource_member_reassign.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/struct_resource_member_reassign.hlsl
@@ -16,8 +16,7 @@ RWByteAddressBuffer gBuf1 : register(u1);
struct ResHolder { RWByteAddressBuffer buf; };
[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
ResHolder h;
h.buf = gBuf0;
h.buf = gBuf1;
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/struct_with_resource_array_member.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/struct_with_resource_array_member.hlsl
index 47971ebd630bc..a2ba45b7bc9e3 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/struct_with_resource_array_member.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/struct_with_resource_array_member.hlsl
@@ -9,8 +9,7 @@ RWByteAddressBuffer gBuf0 : register(u0);
struct S { RWByteAddressBuffer arr[2]; };
-uint Pass_StructArrayAssignment(uint idx)
-{
+uint Pass_StructArrayAssignment(uint idx) {
S s;
s.arr[0] = gBuf0;
s.arr[0].Store(idx * 4, 9);
@@ -19,8 +18,7 @@ uint Pass_StructArrayAssignment(uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_StructArrayAssignment(idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared_direct_store.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared_direct_store.hlsl
index b09e459f7d60c..1f492099a0414 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared_direct_store.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared_direct_store.hlsl
@@ -11,8 +11,7 @@
groupshared RWByteAddressBuffer sharedBuf;
-uint Use_SharedDirect(uint idx)
-{
+uint Use_SharedDirect(uint idx) {
// expected-note@*:*{{candidate function template not viable: 'this' object is in address space 'groupshared', but method expects object in generic address space}}
// expected-note@*:*{{candidate function not viable: 'this' object is in address space 'groupshared', but method expects object in generic address space}}
// expected-error at +1{{no matching member function for call to 'Store'}}
@@ -21,8 +20,7 @@ uint Use_SharedDirect(uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Use_SharedDirect(idx);
}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/use_local_resource_uninitialized.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/use_local_resource_uninitialized.hlsl
index 4f8e2512c74ea..3dfc8c15a1574 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/use_local_resource_uninitialized.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/use_local_resource_uninitialized.hlsl
@@ -5,8 +5,7 @@
// DXC: passes (both sema and codegen).
-uint Pass_Uninitialized(uint idx)
-{
+uint Pass_Uninitialized(uint idx) {
RWByteAddressBuffer buf;
buf.Store(idx * 4, 11);
@@ -14,8 +13,7 @@ uint Pass_Uninitialized(uint idx)
}
[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID)
-{
+void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
Pass_Uninitialized(idx);
}
>From 2a2ba9987159720186f4ca4c819159c89e2e3a86 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Tue, 14 Apr 2026 17:14:17 -0700
Subject: [PATCH 09/10] move tests that belong in the offload test suite (e.g.,
tests that compile cleanly on both compilers
---
.../local_resource_nested_ternary.hlsl | 26 ------------
.../local_resource_ternary_as_argument.hlsl | 25 ------------
.../use_struct_groupshared.hlsl | 40 -------------------
.../Resources/Local-Resources/Readme.md | 20 +++++++---
.../Local-Resources/expression_init.hlsl | 24 -----------
.../forward_struct_layers_resource.hlsl | 25 ------------
.../local_resource_aggregate_init.hlsl | 19 ---------
.../local_resource_alias_chain.hlsl | 25 ------------
.../local_resource_alias_global.hlsl | 21 ----------
.../Local-Resources/local_resource_array.hlsl | 22 ----------
.../local_resource_array_copy.hlsl | 19 ---------
.../local_resource_array_dynamic_index.hlsl | 18 ---------
.../local_resource_array_partial_init.hlsl | 19 ---------
.../local_resource_array_size_one.hlsl | 24 -----------
.../local_resource_bindless_array.hlsl | 21 ----------
.../local_resource_bindless_selection.hlsl | 26 ------------
.../local_resource_block_lifetime.hlsl | 24 -----------
.../local_resource_break_reassign.hlsl | 9 ++---
.../local_resource_chained_call.hlsl | 19 ---------
.../local_resource_conditional_init.hlsl | 19 ---------
.../local_resource_const_param.hlsl | 21 ----------
.../local_resource_continue_reassign.hlsl | 8 ++--
.../local_resource_copy_between_locals.hlsl | 17 --------
.../local_resource_default_init_store.hlsl | 15 -------
.../local_resource_different_types.hlsl | 20 ----------
...al_resource_forward_through_functions.hlsl | 28 -------------
.../local_resource_from_function_return.hlsl | 21 ----------
.../local_resource_inout_param.hlsl | 20 ----------
.../local_resource_loop_array_index.hlsl | 25 ------------
.../local_resource_mixed_struct.hlsl | 24 -----------
.../local_resource_multi_decl.hlsl | 20 ----------
.../local_resource_multiple_returns.hlsl | 8 ++--
.../local_resource_multiple_uses.hlsl | 26 ------------
.../local_resource_nested_loops.hlsl | 26 ------------
.../local_resource_nested_ternary.hlsl} | 7 +---
.../local_resource_out_param.hlsl | 21 ----------
.../local_resource_overload.hlsl | 29 --------------
.../local_resource_phi_merge_ternary.hlsl | 7 +---
.../local_resource_read_only.hlsl | 23 -----------
.../local_resource_self_assign.hlsl | 17 --------
.../local_resource_shadow_inner_scope.hlsl | 25 ------------
.../local_resource_static_local.hlsl | 24 -----------
.../local_resource_struct_method.hlsl | 24 -----------
.../local_resource_struct_return.hlsl | 24 -----------
.../local_resource_structured_buffer.hlsl | 23 -----------
.../Local-Resources/local_resource_swap.hlsl | 24 -----------
.../local_resource_template_function.hlsl | 27 -------------
.../local_resource_ternary_assign.hlsl | 26 ++++++++++++
.../local_resource_ternary_lvalue.hlsl | 23 -----------
.../local_resource_wave_uniform.hlsl | 11 ++---
.../local_resource_with_wave_intrinsic.hlsl | 22 ----------
.../local_struct_resource_member.hlsl | 26 ------------
.../Resources/Local-Resources/loop_var.hlsl | 22 ----------
.../nested_struct_resource_member.hlsl | 25 ------------
.../return_local_resource_initialized.hlsl | 18 ---------
.../return_local_resource_uninitialized.hlsl | 16 --------
.../struct_array_with_resource_member.hlsl | 24 -----------
.../struct_resource_member_reassign.hlsl | 24 -----------
.../struct_with_resource_array_member.hlsl | 24 -----------
.../ternary_initialization.hlsl | 7 +---
.../Local-Resources/use_groupshared.hlsl | 13 +++---
.../use_local_resource_uninitialized.hlsl | 19 ---------
62 files changed, 65 insertions(+), 1234 deletions(-)
delete mode 100644 clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_nested_ternary.hlsl
delete mode 100644 clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_as_argument.hlsl
delete mode 100644 clang/test/CodeGenHLSL/resources/Local-Resources/use_struct_groupshared.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/expression_init.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/forward_struct_layers_resource.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_aggregate_init.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_chain.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_global.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_copy.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_dynamic_index.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_partial_init.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_size_one.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_array.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_selection.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_block_lifetime.hlsl
rename clang/test/{CodeGenHLSL/resources => SemaHLSL/Resources}/Local-Resources/local_resource_break_reassign.hlsl (68%)
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_chained_call.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_conditional_init.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_const_param.hlsl
rename clang/test/{CodeGenHLSL/resources => SemaHLSL/Resources}/Local-Resources/local_resource_continue_reassign.hlsl (73%)
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_copy_between_locals.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_init_store.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_different_types.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_forward_through_functions.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_from_function_return.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_inout_param.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_array_index.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_mixed_struct.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multi_decl.hlsl
rename clang/test/{CodeGenHLSL/resources => SemaHLSL/Resources}/Local-Resources/local_resource_multiple_returns.hlsl (73%)
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multiple_uses.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_loops.hlsl
rename clang/test/{CodeGenHLSL/resources/Local-Resources/local_resource_ternary_assign.hlsl => SemaHLSL/Resources/Local-Resources/local_resource_nested_ternary.hlsl} (69%)
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_out_param.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_overload.hlsl
rename clang/test/{CodeGenHLSL/resources => SemaHLSL/Resources}/Local-Resources/local_resource_phi_merge_ternary.hlsl (69%)
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_read_only.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_self_assign.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_shadow_inner_scope.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_local.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_method.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_return.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_structured_buffer.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_swap.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_template_function.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_assign.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_lvalue.hlsl
rename clang/test/{CodeGenHLSL/resources => SemaHLSL/Resources}/Local-Resources/local_resource_wave_uniform.hlsl (60%)
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_with_wave_intrinsic.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_struct_resource_member.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/loop_var.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/nested_struct_resource_member.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_initialized.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_uninitialized.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/struct_array_with_resource_member.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/struct_resource_member_reassign.hlsl
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/struct_with_resource_array_member.hlsl
rename clang/test/{CodeGenHLSL/resources => SemaHLSL/Resources}/Local-Resources/ternary_initialization.hlsl (68%)
rename clang/test/{CodeGenHLSL/resources => SemaHLSL/Resources}/Local-Resources/use_groupshared.hlsl (53%)
delete mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/use_local_resource_uninitialized.hlsl
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_nested_ternary.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_nested_ternary.hlsl
deleted file mode 100644
index fcb14ae55263b..0000000000000
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_nested_ternary.hlsl
+++ /dev/null
@@ -1,26 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes \
-// RUN: -o - 2>&1 | llvm-cxxfilt | FileCheck %s
-
-// Test that a nested ternary resource selection produces a warning in
-// clang but still generates valid IR.
-//
-// DXC: passes sema but fails codegen with two errors:
-// "local resource not guaranteed to map to unique global resource."
-// (one for each ternary level)
-
-RWByteAddressBuffer gBuf0 : register(u0);
-RWByteAddressBuffer gBuf1 : register(u1);
-RWByteAddressBuffer gBuf2 : register(u2);
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- bool c1 = tid.x > 0;
- bool c2 = tid.y > 0;
- RWByteAddressBuffer buf = c1 ? gBuf0 : (c2 ? gBuf1 : gBuf2);
- buf.Store(tid.x * 4, 42);
-}
-
-// CHECK: warning: assignment of 'c1 ? gBuf0 : (c2 ? gBuf1 : gBuf2)' to local resource 'buf' is not to the same unique global resource
-// CHECK: define {{.*}} @main(
-// CHECK-NOT: error:
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_as_argument.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_as_argument.hlsl
deleted file mode 100644
index d01c9f39d6e45..0000000000000
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_as_argument.hlsl
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes \
-// RUN: -o - 2>&1 | llvm-cxxfilt | FileCheck %s
-
-// Test that a ternary resource expression passed directly as a function
-// argument produces valid IR in clang.
-//
-// DXC: passes sema but fails codegen with:
-// "local resource not guaranteed to map to unique global resource."
-
-RWByteAddressBuffer gBuf0 : register(u0);
-RWByteAddressBuffer gBuf1 : register(u1);
-
-void Helper(RWByteAddressBuffer buf, uint offset, uint value) {
- buf.Store(offset, value);
-}
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- bool cond = tid.x > 0;
- Helper(cond ? gBuf0 : gBuf1, tid.x * 4, 42);
-}
-
-// CHECK-NOT: error:
-// CHECK: define {{.*}} @main(
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/use_struct_groupshared.hlsl b/clang/test/CodeGenHLSL/resources/Local-Resources/use_struct_groupshared.hlsl
deleted file mode 100644
index d78e2bfea4422..0000000000000
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/use_struct_groupshared.hlsl
+++ /dev/null
@@ -1,40 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute -emit-llvm -disable-llvm-passes 2>&1 -o - %s | llvm-cxxfilt | FileCheck %s
-//
-// XFAIL: *
-// https://github.com/llvm/llvm-project/issues/158107
-
-// This test fails validation in DXC, but DXC's sema allows it.
-// Meanwhile, it is for some reason accepted by clang's sema.
-// TODO: Why does this pass clang's sema, but use_groupshared.hlsl fails clang's sema?
-// Run a git bisect on https://github.com/llvm/llvm-project/issues/158107, and figure
-// out which commit seemed to resolve this issue.
-//
-// DXC: passes sema but fails validation with:
-// "Explicit load/store type does not match pointee type of pointer operand"
-
-RWByteAddressBuffer gOut : register(u3);
-
-// CHECK: note: passing argument to parameter 'buf' here
-uint DoStore(RWByteAddressBuffer buf, uint offset, uint value) {
- buf.Store(offset, value);
- return value;
-}
-
-// CHECK: note: candidate constructor not viable: cannot bind reference in address space 'groupshared' to object in generic address space in 1st argument
-// CHECK: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
-
-struct PassBufStruct { RWByteAddressBuffer buf; };
-
-groupshared PassBufStruct sharedStruct;
-
-uint Use_PassSharedStruct(uint idx) {
- // CHECK: error: no matching constructor for initialization of 'RWByteAddressBuffer'
- return DoStore(sharedStruct.buf, idx * 4, 1);
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- uint idx = tid.x + tid.y * 8;
- Use_PassSharedStruct(idx);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/Readme.md b/clang/test/SemaHLSL/Resources/Local-Resources/Readme.md
index 3917189f96d31..fa4c7c972ffe4 100644
--- a/clang/test/SemaHLSL/Resources/Local-Resources/Readme.md
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/Readme.md
@@ -15,20 +15,30 @@ DXC has never had structured test coverage for local resource patterns. Many val
## Organization
-Tests are split across two directories based on compiler behavior:
+Tests are split across multiple directories based on compiler behavior:
+
+| Location | Count | Contents |
+|----------|-------|----------|
+| `SemaHLSL/Resources/Local-Resources/` (this directory) | 15 | Fail to compile on **both** compilers (invalid type ops, bad declarations) |
+| `CodeGenHLSL/resources/Local-Resources/` | 11 | Codegen-stage tests (DXC codegen failures, groupshared) |
+| `offload-test-suite/test/Feature/LocalResources/` | 55 | Produce compiled output on **both** compilers (clean, or Clang warns) |
+| `offload-test-suite/test/Feature/LocalResources/ClangPass/` | 4 | Clang compiles, DXC fails (ICE or codegen error) |
+| `offload-test-suite/test/Feature/LocalResources/DXCPass/` | 1 | DXC compiles, Clang fails to compile |
+| **Total** | **86** | |
### `SemaHLSL/Resources/Local-Resources/` (this directory)
-Tests where **sema is the interesting stage**. This includes:
-- Tests that **pass both sema and codegen** in both compilers (clean passes).
-- Tests that **fail during sema** (expected errors caught by `-verify`).
-- Tests where Clang emits **sema-level warnings** (`-Whlsl-explicit-binding`) that DXC does not — these are verified with `expected-warning` annotations and document the DXC difference in comments.
+Tests where **sema is the interesting stage** and **both compilers reject the code**. These are expected errors caught by `-verify`.
### `CodeGenHLSL/resources/Local-Resources/`
Tests where **codegen is the interesting stage**. This includes:
- Tests that **pass sema but fail codegen** in either compiler. These use `FileCheck` to verify that Clang produces valid IR and emits the expected diagnostics, while documenting DXC's codegen-stage errors in comments.
+### `offload-test-suite/test/Feature/LocalResources/`
+
+Tests where **both compilers produce a compiled output**. This includes tests that are fully clean on both compilers, as well as tests where Clang emits `-Whlsl-explicit-binding` warnings but still compiles successfully. The `ClangPass/` and `DXCPass/` subdirectories contain tests that compile on only one compiler.
+
## Test Categories
### Basic Local Resource Operations
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.hlsl
deleted file mode 100644
index 128bcf44056ed..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/expression_init.hlsl
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-RWByteAddressBuffer gBuf1 : register(u1);
-
-RWByteAddressBuffer gOut : register(u3);
-
-uint Pass_ExpressionInit(uint idx) {
- RWByteAddressBuffer buf = (true ? gBuf0 : gBuf1);
- buf.Store(idx * 4, 3);
-
- return 3;
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- uint idx = tid.x + tid.y * 8;
- Pass_ExpressionInit(idx);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/forward_struct_layers_resource.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/forward_struct_layers_resource.hlsl
deleted file mode 100644
index 156f15e3d3fe5..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/forward_struct_layers_resource.hlsl
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf2 : register(u2);
-
-struct ForwardA { RWByteAddressBuffer buf; };
-struct ForwardB { ForwardA a; };
-
-uint Pass_ForwardStructLayers(uint idx) {
- ForwardB b;
- b.a.buf = gBuf2;
- b.a.buf.Store(idx * 4, 29);
-
- return 29;
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- uint idx = tid.x + tid.y * 8;
- Pass_ForwardStructLayers(idx);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_aggregate_init.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_aggregate_init.hlsl
deleted file mode 100644
index 6f346b9959b17..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_aggregate_init.hlsl
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that aggregate (brace) initialization of a struct with a resource
-// member works correctly.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-struct ResHolder { RWByteAddressBuffer buf; };
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- ResHolder h = {gBuf0};
- h.buf.Store(tid.x * 4, 42);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_chain.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_chain.hlsl
deleted file mode 100644
index 2d4b8d050848c..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_chain.hlsl
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-uint Pass_AliasChain(uint idx) {
- RWByteAddressBuffer a = gBuf0;
- RWByteAddressBuffer b = a;
- RWByteAddressBuffer c = b;
-
- c.Store(idx * 4, 27);
-
-
- return 27;
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- uint idx = tid.x + tid.y * 8;
- Pass_AliasChain(idx);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_global.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_global.hlsl
deleted file mode 100644
index 21ad35ed26088..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_alias_global.hlsl
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-uint Pass_Alias(uint idx) {
- RWByteAddressBuffer buf = gBuf0;
- buf.Store(idx * 4, 12);
-
- return 12;
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- uint idx = tid.x + tid.y * 8;
- Pass_Alias(idx);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array.hlsl
deleted file mode 100644
index f75ca155a448b..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array.hlsl
+++ /dev/null
@@ -1,22 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-uint Pass_LocalArray(uint idx) {
- RWByteAddressBuffer arr[2];
- arr[0] = gBuf0;
- arr[0].Store(idx * 4, 10);
-
- return 10;
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- uint idx = tid.x + tid.y * 8;
- Pass_LocalArray(idx);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_copy.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_copy.hlsl
deleted file mode 100644
index 95279e1a5536a..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_copy.hlsl
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that a local resource array can be copied to another local array.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBufArray[4] : register(u0);
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- RWByteAddressBuffer src[2];
- src[0] = gBufArray[0];
- src[1] = gBufArray[1];
- RWByteAddressBuffer dst[2] = src;
- dst[0].Store(tid.x * 4, 42);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_dynamic_index.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_dynamic_index.hlsl
deleted file mode 100644
index bdc81a428f8ba..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_dynamic_index.hlsl
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that a local resource array can be dynamically indexed at runtime.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBufArray[4] : register(u0);
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- RWByteAddressBuffer localArr[2];
- localArr[0] = gBufArray[0];
- localArr[1] = gBufArray[1];
- localArr[tid.x & 1].Store(tid.x * 4, 42);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_partial_init.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_partial_init.hlsl
deleted file mode 100644
index e8a8b0d93cd56..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_partial_init.hlsl
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that a local resource array with only some elements initialized
-// (others left default) compiles successfully.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- RWByteAddressBuffer arr[4];
- arr[0] = gBuf0;
- arr[1] = gBuf0;
- arr[tid.x & 3].Store(tid.x * 4, 42);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_size_one.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_size_one.hlsl
deleted file mode 100644
index 94bc2d3e7d634..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_array_size_one.hlsl
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that a local resource array of size 1 works correctly. This is
-// an edge case where the compiler might apply different optimizations
-// compared to larger arrays.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-uint Pass_ArraySizeOne(uint idx) {
- RWByteAddressBuffer arr[1];
- arr[0] = gBuf0;
- arr[0].Store(idx * 4, 42);
- return 42;
-}
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- Pass_ArraySizeOne(tid.x);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_array.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_array.hlsl
deleted file mode 100644
index 857dfafe3b56f..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_array.hlsl
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBufArray[4] : register(u10);
-
-uint Pass_Bindless(uint idx) {
- RWByteAddressBuffer buf = gBufArray[idx & 3];
- buf.Store(idx * 4, 21);
-
- return 21;
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- uint idx = tid.x + tid.y * 8;
- Pass_Bindless(idx);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_selection.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_selection.hlsl
deleted file mode 100644
index 694d72cda9fff..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_bindless_selection.hlsl
+++ /dev/null
@@ -1,26 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBufArray[4] : register(u10);
-
-uint Pass_BindlessSelection(uint a, uint b, uint idx) {
- RWByteAddressBuffer buf;
-
- buf = gBufArray[a & 3];
- buf = gBufArray[b & 3];
-
- buf.Store(idx * 4, 33);
-
-
- return 33;
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- uint idx = tid.x + tid.y * 8;
- Pass_BindlessSelection(2, 3, idx);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_block_lifetime.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_block_lifetime.hlsl
deleted file mode 100644
index f677def01bca3..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_block_lifetime.hlsl
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf1 : register(u1);
-
-uint Pass_BlockLifetime(uint idx) {
- RWByteAddressBuffer buf;
- {
- buf = gBuf1;
- }
- buf.Store(idx * 4, 24);
-
- return 24;
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- uint idx = tid.x + tid.y * 8;
- Pass_BlockLifetime(idx);
-}
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_break_reassign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_break_reassign.hlsl
similarity index 68%
rename from clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_break_reassign.hlsl
rename to clang/test/SemaHLSL/Resources/Local-Resources/local_resource_break_reassign.hlsl
index 9b1e9f26c0ba4..acd76c701870e 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_break_reassign.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_break_reassign.hlsl
@@ -1,6 +1,5 @@
// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes \
-// RUN: -o - 2>&1 | llvm-cxxfilt | FileCheck %s
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
// Test that resource reassignment before a break in a loop triggers a
// warning in clang but still produces valid IR.
@@ -13,14 +12,12 @@ RWByteAddressBuffer gBuf1 : register(u1);
[numthreads(1,1,1)]
void main(uint3 tid : SV_DispatchThreadID) {
+ // expected-note at +1{{variable 'buf' is declared here}}
RWByteAddressBuffer buf = gBuf0;
for (uint i = 0; i < 4; i++) {
if (i == tid.x) break;
+ // expected-warning at +1{{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
buf = gBuf1;
}
buf.Store(tid.x * 4, 42);
}
-
-// CHECK: warning: assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource
-// CHECK: define {{.*}} @main(
-// CHECK-NOT: error:
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_chained_call.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_chained_call.hlsl
deleted file mode 100644
index 0cb9baa8de191..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_chained_call.hlsl
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that a method can be called directly on the return value of a
-// function that returns a resource. This exercises temporary resource
-// lifetime — the method is invoked on an rvalue.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-RWByteAddressBuffer GetBuf() { return gBuf0; }
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- GetBuf().Store(tid.x * 4, 42);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_conditional_init.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_conditional_init.hlsl
deleted file mode 100644
index c796ec06d3a84..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_conditional_init.hlsl
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that a resource declared without initialization and only assigned
-// in one branch produces valid IR in clang.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- RWByteAddressBuffer buf;
- if (tid.x > 0)
- buf = gBuf0;
- buf.Store(tid.x * 4, 42);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_const_param.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_const_param.hlsl
deleted file mode 100644
index 431f7ac55d900..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_const_param.hlsl
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that a local resource can be passed as a const parameter.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-void ReadOnly(const RWByteAddressBuffer buf, uint offset, out uint result) {
- result = 0;
-}
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- RWByteAddressBuffer local = gBuf0;
- uint r;
- ReadOnly(local, tid.x * 4, r);
-}
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_continue_reassign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_continue_reassign.hlsl
similarity index 73%
rename from clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_continue_reassign.hlsl
rename to clang/test/SemaHLSL/Resources/Local-Resources/local_resource_continue_reassign.hlsl
index 283da82831092..ffab4be5ff7f2 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_continue_reassign.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_continue_reassign.hlsl
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute -emit-llvm -disable-llvm-passes 2>&1 -o - %s | llvm-cxxfilt | FileCheck %s
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
// DXC passes sema but fails during codegen (DxilCondenseResources) with:
// "local resource not guaranteed to map to unique global resource"
@@ -9,14 +9,15 @@
RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
-// CHECK: warning: assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource
[numthreads(1,1,1)]
void main(uint3 tid : SV_DispatchThreadID) {
+ // expected-note at +1{{variable 'buf' is declared here}}
RWByteAddressBuffer buf = gBuf0;
for (uint i = 0; i < 4; i++) {
if (i == 2) {
// DXC: error after sema: local resource not guaranteed to map to unique global resource.
+ // expected-warning at +1{{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
buf = gBuf1;
continue;
}
@@ -25,6 +26,3 @@ void main(uint3 tid : SV_DispatchThreadID) {
buf.Store(tid.x * 4, 99);
}
-
-// CHECK: define void @main()
-// CHECK-NOT: error:
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_copy_between_locals.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_copy_between_locals.hlsl
deleted file mode 100644
index e2358df7d2241..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_copy_between_locals.hlsl
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that copying a local resource to another local works.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- RWByteAddressBuffer a = gBuf0;
- RWByteAddressBuffer b = a;
- b.Store(tid.x * 4, 42);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_init_store.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_init_store.hlsl
deleted file mode 100644
index 00ba8436305dc..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_init_store.hlsl
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that using a default-initialized (unbound) local resource produces
-// valid IR in clang. No warnings or errors from clang.
-//
-// DXC: passes (both sema and codegen).
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- RWByteAddressBuffer buf;
- buf.Store(tid.x * 4, 42);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_different_types.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_different_types.hlsl
deleted file mode 100644
index d6e0b04d64c8d..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_different_types.hlsl
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that two different resource types can coexist as local variables
-// in the same function.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-RWStructuredBuffer<uint> gSB : register(u1);
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- RWByteAddressBuffer localBuf = gBuf0;
- RWStructuredBuffer<uint> localSB = gSB;
- localBuf.Store(tid.x * 4, 42);
- localSB[tid.x] = 99;
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_forward_through_functions.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_forward_through_functions.hlsl
deleted file mode 100644
index 61480bb526818..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_forward_through_functions.hlsl
+++ /dev/null
@@ -1,28 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf1 : register(u1);
-
-uint Pass_Level2(RWByteAddressBuffer buf, uint idx) {
- buf.Store(idx*4, 17);
- return 17;
-}
-
-uint Pass_Level1(RWByteAddressBuffer buf, uint idx) {
- return Pass_Level2(buf, idx);
-}
-
-uint Pass_FunctionForward(uint idx) {
- RWByteAddressBuffer buf = gBuf1;
- return Pass_Level1(buf, idx);
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- uint idx = tid.x + tid.y * 8;
- Pass_FunctionForward(idx);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_from_function_return.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_from_function_return.hlsl
deleted file mode 100644
index ceeb5e97cbe72..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_from_function_return.hlsl
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that a local resource initialized from a function return value
-// works correctly.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-RWByteAddressBuffer GetBuffer() {
- return gBuf0;
-}
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- RWByteAddressBuffer buf = GetBuffer();
- buf.Store(tid.x * 4, 42);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_inout_param.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_inout_param.hlsl
deleted file mode 100644
index aa4b114be04e3..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_inout_param.hlsl
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that a local resource can be passed as an inout parameter.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-void ReadAndWrite(inout RWByteAddressBuffer buf, uint offset, uint value) {
- buf.Store(offset, value);
-}
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- RWByteAddressBuffer local = gBuf0;
- ReadAndWrite(local, tid.x * 4, 42);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_array_index.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_array_index.hlsl
deleted file mode 100644
index e6bed0b7a8b45..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_loop_array_index.hlsl
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBufArray[4] : register(u10);
-
-uint Pass_Loop(uint idx) {
- uint sum = 0;
- for (unsigned int i=0;i<4;i++) {
- RWByteAddressBuffer buf = gBufArray[i];
- buf.Store(idx * 4 + i * 4, 15);
-
- sum += 15;
- }
- return sum;
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- uint idx = tid.x + tid.y * 8;
- Pass_Loop(idx);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_mixed_struct.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_mixed_struct.hlsl
deleted file mode 100644
index e4396817ccf8d..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_mixed_struct.hlsl
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that a struct with both a resource member and a scalar member
-// can be used as a local variable.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-struct Node {
- RWByteAddressBuffer buf;
- uint next;
-};
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- Node n;
- n.buf = gBuf0;
- n.next = 0;
- n.buf.Store(tid.x * 4, n.next);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multi_decl.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multi_decl.hlsl
deleted file mode 100644
index 9b8bb58671b0e..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multi_decl.hlsl
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that two resource variables can be declared in a single
-// declaration statement. This exercises the C++ multi-declarator
-// path with resource types.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-RWByteAddressBuffer gBuf1 : register(u1);
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- RWByteAddressBuffer a = gBuf0, b = gBuf1;
- a.Store(tid.x * 4, 1);
- b.Store(tid.x * 4, 2);
-}
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_multiple_returns.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multiple_returns.hlsl
similarity index 73%
rename from clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_multiple_returns.hlsl
rename to clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multiple_returns.hlsl
index 38482fe16faa9..24b4c7a9e531d 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_multiple_returns.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multiple_returns.hlsl
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute -emit-llvm -disable-llvm-passes 2>&1 -o - %s | llvm-cxxfilt | FileCheck %s
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
// DXC passes sema but fails during codegen (DxilCondenseResources) with:
// "local resource not guaranteed to map to unique global resource"
@@ -9,22 +9,20 @@
RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
-// CHECK: warning: assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource
RWByteAddressBuffer Pass_MultipleReturns(bool cond, uint idx) {
+ // expected-note at +1{{variable 'buf' is declared here}}
RWByteAddressBuffer buf = gBuf0;
if (cond) {
buf.Store(idx * 4, 1);
return buf;
}
// DXC: error after sema: local resource not guaranteed to map to unique global resource.
+ // expected-warning at +1{{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
buf = gBuf1;
buf.Store(idx * 4, 2);
return buf;
}
-// CHECK: define hidden void @Pass_MultipleReturns(bool, unsigned int)(
-// CHECK: define void @main()
-
[numthreads(8,8,1)]
void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multiple_uses.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multiple_uses.hlsl
deleted file mode 100644
index d03755c8f96a9..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_multiple_uses.hlsl
+++ /dev/null
@@ -1,26 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that the same local resource can be passed to multiple helper
-// functions within a single shader.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-void HelperA(RWByteAddressBuffer buf, uint offset) {
- buf.Store(offset, 1);
-}
-
-void HelperB(RWByteAddressBuffer buf, uint offset) {
- buf.Store(offset, 2);
-}
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- RWByteAddressBuffer local = gBuf0;
- HelperA(local, tid.x * 4);
- HelperB(local, tid.x * 4 + 4);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_loops.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_loops.hlsl
deleted file mode 100644
index 108341625888e..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_loops.hlsl
+++ /dev/null
@@ -1,26 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBufArray[4] : register(u10);
-
-uint Pass_NestedLoops(uint idx) {
- uint sum = 0;
- for (unsigned int i=0;i<2;i++)
- for (unsigned int j=0;j<2;j++) {
- RWByteAddressBuffer buf = gBufArray[i+j];
- buf.Store(idx * 4 + (i+j)*4, 23);
-
- sum += 23;
- }
- return sum;
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- uint idx = tid.x + tid.y * 8;
- Pass_NestedLoops(idx);
-}
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_assign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_ternary.hlsl
similarity index 69%
rename from clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_assign.hlsl
rename to clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_ternary.hlsl
index e1e42f9aa835f..bbeddd0a6b51d 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_ternary_assign.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_nested_ternary.hlsl
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute -emit-llvm -disable-llvm-passes 2>&1 -o - %s | llvm-cxxfilt | FileCheck %s
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
// DXC passes sema but fails during codegen (DxilCondenseResources) with:
// "local resource not guaranteed to map to unique global resource"
@@ -12,16 +12,13 @@ RWByteAddressBuffer gBuf1 : register(u1);
uint Pass_IfAlias(bool cond, uint idx) {
RWByteAddressBuffer buf;
// DXC: error after sema: local resource not guaranteed to map to unique global resource.
- // CHECK: warning: assignment of 'cond ? gBuf0 : gBuf1' to local resource 'buf' is not to the same unique global resource
+ // expected-warning at +1{{assignment of 'cond ? gBuf0 : gBuf1' to local resource 'buf' is not to the same unique global resource}}
buf = cond ? gBuf0 : gBuf1;
buf.Store(idx * 4, 14);
return 14;
}
-// CHECK: define hidden noundef i32 @Pass_IfAlias(bool, unsigned int)(
-// CHECK: define void @main()
-
[numthreads(8,8,1)]
void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_out_param.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_out_param.hlsl
deleted file mode 100644
index 7ef85f36a16b3..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_out_param.hlsl
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that a local resource can be written through an out parameter.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-void WriteThrough(out RWByteAddressBuffer buf) {
- buf = gBuf0;
-}
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- RWByteAddressBuffer local;
- WriteThrough(local);
- local.Store(tid.x * 4, 42);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_overload.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_overload.hlsl
deleted file mode 100644
index 63e7d0ab28b12..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_overload.hlsl
+++ /dev/null
@@ -1,29 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that function overloading works when overloads differ by
-// resource type parameter. This exercises overload resolution
-// with resource types.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-RWStructuredBuffer<uint> gSB : register(u1);
-
-void DoStore(RWByteAddressBuffer buf, uint idx, uint val) {
- buf.Store(idx * 4, val);
-}
-
-void DoStore(RWStructuredBuffer<uint> buf, uint idx, uint val) {
- buf[idx] = val;
-}
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- RWByteAddressBuffer localBuf = gBuf0;
- RWStructuredBuffer<uint> localSB = gSB;
- DoStore(localBuf, tid.x, 1);
- DoStore(localSB, tid.x, 2);
-}
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_phi_merge_ternary.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_phi_merge_ternary.hlsl
similarity index 69%
rename from clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_phi_merge_ternary.hlsl
rename to clang/test/SemaHLSL/Resources/Local-Resources/local_resource_phi_merge_ternary.hlsl
index 68aeeea87a178..1a0d2a4268e0b 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_phi_merge_ternary.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_phi_merge_ternary.hlsl
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute -emit-llvm -disable-llvm-passes 2>&1 -o - %s | llvm-cxxfilt | FileCheck %s
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
// DXC passes sema but fails during codegen (DxilCondenseResources) with:
// "local resource not guaranteed to map to unique global resource"
@@ -12,16 +12,13 @@ RWByteAddressBuffer gBuf2 : register(u2);
uint Pass_PhiMerge(bool cond, uint idx) {
RWByteAddressBuffer buf;
// DXC: error after sema: local resource not guaranteed to map to unique global resource.
- // CHECK: warning: assignment of 'cond ? gBuf0 : gBuf2' to local resource 'buf' is not to the same unique global resource
+ // expected-warning at +1{{assignment of 'cond ? gBuf0 : gBuf2' to local resource 'buf' is not to the same unique global resource}}
buf = cond ? gBuf0 : gBuf2;
buf.Store(idx * 4, 18);
return 18;
}
-// CHECK: define hidden noundef i32 @Pass_PhiMerge(bool, unsigned int)(
-// CHECK: define void @main()
-
[numthreads(8,8,1)]
void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_read_only.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_read_only.hlsl
deleted file mode 100644
index 95ee12313c27c..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_read_only.hlsl
+++ /dev/null
@@ -1,23 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that a read-only ByteAddressBuffer can be used as a local variable.
-// This is distinct from RWByteAddressBuffer because it only supports Load
-// (no Store), exercising different method resolution. Load is required here
-// because ByteAddressBuffer is a read-only resource type.
-//
-// DXC: passes (both sema and codegen).
-
-ByteAddressBuffer gBuf0 : register(t0);
-
-uint Pass_ReadOnlyLocal(uint idx) {
- ByteAddressBuffer buf = gBuf0;
- return buf.Load(idx * 4);
-}
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- Pass_ReadOnlyLocal(tid.x);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_self_assign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_self_assign.hlsl
deleted file mode 100644
index ea68e34f33c15..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_self_assign.hlsl
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that self-assignment of a local resource compiles cleanly.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- RWByteAddressBuffer buf = gBuf0;
- buf = buf;
- buf.Store(tid.x * 4, 42);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_shadow_inner_scope.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_shadow_inner_scope.hlsl
deleted file mode 100644
index 02c9fdb98d224..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_shadow_inner_scope.hlsl
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-RWByteAddressBuffer gBuf1 : register(u1);
-
-uint Pass_Shadow(uint idx) {
- RWByteAddressBuffer buf = gBuf0;
- {
- RWByteAddressBuffer buf = gBuf1;
- buf.Store(idx * 4, 19);
-
- return 19;
- }
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- uint idx = tid.x + tid.y * 8;
- Pass_Shadow(idx);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_local.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_local.hlsl
deleted file mode 100644
index 24561cd5cd3d3..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_local.hlsl
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that a static local resource variable initialized from a global
-// is accepted by both compilers.
-//
-// DXC: passes (both sema and codegen) with RWByteAddressBuffer.
-// Note: DXC asserts/ICEs when Texture2D is used instead.
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-uint Pass_StaticLocal(uint idx) {
- static RWByteAddressBuffer buf = gBuf0;
- buf.Store(idx * 4, 1);
-
- return 1;
-}
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- Pass_StaticLocal(tid.x);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_method.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_method.hlsl
deleted file mode 100644
index 26382965ed6e0..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_method.hlsl
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that a user-defined struct with a member function can use a
-// resource member. This exercises method dispatch through user-defined
-// struct methods operating on resource handles.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-struct Wrapper {
- RWByteAddressBuffer buf;
- void DoStore(uint idx, uint val) { buf.Store(idx * 4, val); }
-};
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- Wrapper w;
- w.buf = gBuf0;
- w.DoStore(tid.x, 42);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_return.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_return.hlsl
deleted file mode 100644
index 0683b6227416b..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_struct_return.hlsl
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that a function can return a struct containing a resource member.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-struct ResHolder { RWByteAddressBuffer buf; };
-
-ResHolder MakeHolder() {
- ResHolder h;
- h.buf = gBuf0;
- return h;
-}
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- ResHolder h = MakeHolder();
- h.buf.Store(tid.x * 4, 42);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_structured_buffer.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_structured_buffer.hlsl
deleted file mode 100644
index e3c79cabf1103..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_structured_buffer.hlsl
+++ /dev/null
@@ -1,23 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that RWStructuredBuffer<uint> works as a local variable with
-// subscript operator access. This is distinct from RWByteAddressBuffer
-// because it uses typed element access via operator[].
-//
-// DXC: passes (both sema and codegen).
-
-RWStructuredBuffer<uint> gSB : register(u0);
-
-uint Pass_StructuredBufferLocal(uint idx) {
- RWStructuredBuffer<uint> sb = gSB;
- sb[idx] = 42;
- return 42;
-}
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- Pass_StructuredBufferLocal(tid.x);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_swap.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_swap.hlsl
deleted file mode 100644
index a030b7dd4ee96..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_swap.hlsl
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that swapping two local resource variables through a temporary
-// is accepted without warnings. This exercises multi-variable
-// reassignment that does not change which global each variable maps to.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-RWByteAddressBuffer gBuf1 : register(u1);
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- RWByteAddressBuffer a = gBuf0;
- RWByteAddressBuffer b = gBuf1;
- RWByteAddressBuffer temp = a;
- a = b;
- b = temp;
- a.Store(tid.x * 4, 1);
- b.Store(tid.x * 4, 2);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_template_function.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_template_function.hlsl
deleted file mode 100644
index a10b894b6873f..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_template_function.hlsl
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that a template function can accept and use a resource parameter.
-// This exercises template instantiation with resource types.
-//
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-template<typename T>
-void UseResource(T buf, uint idx, uint val) {
- buf.Store(idx * 4, val);
-}
-
-uint Pass_TemplateFunction(uint idx) {
- RWByteAddressBuffer buf = gBuf0;
- UseResource(buf, idx, 42);
- return 42;
-}
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- Pass_TemplateFunction(tid.x);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_assign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_assign.hlsl
new file mode 100644
index 0000000000000..d8705501d26ba
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_assign.hlsl
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// Test that ternary resource assignment post-declaration triggers a
+// warning in clang but still produces valid IR.
+//
+// DXC: passes sema but fails codegen with:
+// "local resource not guaranteed to map to unique global resource."
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+uint Pass_TernaryInit(bool cond, uint idx) {
+ // DXC emits this warning: local resource not guaranteed to map to unique global resource.
+ // expected-warning at +1{{assignment of 'cond ? gBuf0 : gBuf1' to local resource 'buf' is not to the same unique global resource}}
+ RWByteAddressBuffer buf = cond ? gBuf0 : gBuf1;
+ buf.Store(idx * 4, 2);
+
+ return 2;
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID) {
+ uint idx = tid.x + tid.y * 8;
+ Pass_TernaryInit(idx < 32, idx);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_lvalue.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_lvalue.hlsl
deleted file mode 100644
index f8654215403db..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_lvalue.hlsl
+++ /dev/null
@@ -1,23 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that a ternary expression can be used as an lvalue for resource
-// assignment. This exercises lvalue analysis of the ternary operator
-// with resource types.
-//
-// DXC: ICEs with "Internal compiler error: LLVM Assert" (even at sema).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-RWByteAddressBuffer gBuf1 : register(u1);
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- RWByteAddressBuffer a = gBuf0;
- RWByteAddressBuffer b = gBuf1;
- bool cond = tid.x > 0;
- (cond ? a : b) = gBuf0;
- a.Store(tid.x * 4, 1);
- b.Store(tid.x * 4, 2);
-}
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_wave_uniform.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_wave_uniform.hlsl
similarity index 60%
rename from clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_wave_uniform.hlsl
rename to clang/test/SemaHLSL/Resources/Local-Resources/local_resource_wave_uniform.hlsl
index 91aa53be6a508..ca0fa1765184f 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/local_resource_wave_uniform.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_wave_uniform.hlsl
@@ -1,6 +1,5 @@
// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes \
-// RUN: -o - 2>&1 | llvm-cxxfilt | FileCheck %s
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
// Test that a wave-conditional resource reassignment produces a warning
// in clang but still generates valid IR.
@@ -12,20 +11,16 @@ RWByteAddressBuffer gBuf0 : register(u0);
RWByteAddressBuffer gBuf1 : register(u1);
uint Fail_WaveUniform(uint offset, uint value) {
+ // expected-note at +1{{variable 'buf' is declared here}}
RWByteAddressBuffer buf = gBuf0;
if (WaveActiveAllTrue(true))
+ // expected-warning at +1{{assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource}}
buf = gBuf1;
- // expected-warning: assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource
buf.Store(offset, value);
return value;
}
-// CHECK: warning: assignment of 'gBuf1' to local resource 'buf' is not to the same unique global resource
-// CHECK: define {{.*}} @Fail_WaveUniform(
-// CHECK: define {{.*}} @main(
-// CHECK-NOT: error:
-
[numthreads(1,1,1)]
void main(uint3 tid : SV_DispatchThreadID) {
Fail_WaveUniform(tid.x * 4, 10);
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_with_wave_intrinsic.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_with_wave_intrinsic.hlsl
deleted file mode 100644
index f1cc040637d61..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_with_wave_intrinsic.hlsl
+++ /dev/null
@@ -1,22 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-uint Pass_WaveUse(uint idx) {
- RWByteAddressBuffer buf = gBuf0;
- uint active = WaveActiveCountBits(true);
- buf.Store(idx * 4, active);
-
- return active;
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- uint idx = tid.x + tid.y * 8;
- Pass_WaveUse(idx);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_struct_resource_member.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_struct_resource_member.hlsl
deleted file mode 100644
index 77e15ef911fdd..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/local_struct_resource_member.hlsl
+++ /dev/null
@@ -1,26 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-struct PassStruct {
- RWByteAddressBuffer buf;
-};
-
-uint Pass_Struct(uint idx) {
- PassStruct s;
- s.buf = gBuf0;
- s.buf.Store(idx * 4, 16);
-
- return 16;
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- uint idx = tid.x + tid.y * 8;
- Pass_Struct(idx);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/loop_var.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/loop_var.hlsl
deleted file mode 100644
index 2b5ca8aceeabc..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/loop_var.hlsl
+++ /dev/null
@@ -1,22 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-RWByteAddressBuffer gOut : register(u3);
-
-void Pass_LoopVar() {
- for (RWByteAddressBuffer buf = gBuf0; false == false; ) {
- buf.Store(0, 0);
- break;
- }
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- Pass_LoopVar();
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/nested_struct_resource_member.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/nested_struct_resource_member.hlsl
deleted file mode 100644
index e0408620da1d0..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/nested_struct_resource_member.hlsl
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf1 : register(u1);
-
-struct NestedInner { RWByteAddressBuffer buf; };
-struct NestedOuter { NestedInner inner; };
-
-uint Pass_NestedStruct(uint idx) {
- NestedOuter s;
- s.inner.buf = gBuf1;
- s.inner.buf.Store(idx * 4, 28);
-
- return 28;
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- uint idx = tid.x + tid.y * 8;
- Pass_NestedStruct(idx);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_initialized.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_initialized.hlsl
deleted file mode 100644
index 5900284d6aa98..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_initialized.hlsl
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-RWByteAddressBuffer Pass_ReturnLocal() {
- RWByteAddressBuffer buf = gBuf0;
- return buf;
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- RWByteAddressBuffer tmp = Pass_ReturnLocal();
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_uninitialized.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_uninitialized.hlsl
deleted file mode 100644
index b92a8e88dbc66..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/return_local_resource_uninitialized.hlsl
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer Pass_ReturnLocal_Uninitialized() {
- RWByteAddressBuffer buf;
- return buf;
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- RWByteAddressBuffer tmp = Pass_ReturnLocal_Uninitialized();
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/struct_array_with_resource_member.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/struct_array_with_resource_member.hlsl
deleted file mode 100644
index 95f5353f6dc39..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/struct_array_with_resource_member.hlsl
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-struct BufStruct { RWByteAddressBuffer buf; };
-
-uint Pass_StructArray(uint idx) {
- BufStruct s[2];
- s[0].buf = gBuf0;
- s[0].buf.Store(idx * 4, 5);
-
- return 5;
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- uint idx = tid.x + tid.y * 8;
- Pass_StructArray(idx);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/struct_resource_member_reassign.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/struct_resource_member_reassign.hlsl
deleted file mode 100644
index 0b1a339247b67..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/struct_resource_member_reassign.hlsl
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// Test that reassigning the resource member of a local struct to a
-// different global compiles without error.
-//
-// DXC: passes (both sema and codegen).
-// Note: clang does not warn here because -Whlsl-explicit-binding
-// tracks local resource variables, not struct member assignments.
-
-RWByteAddressBuffer gBuf0 : register(u0);
-RWByteAddressBuffer gBuf1 : register(u1);
-
-struct ResHolder { RWByteAddressBuffer buf; };
-
-[numthreads(1,1,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- ResHolder h;
- h.buf = gBuf0;
- h.buf = gBuf1;
- h.buf.Store(tid.x * 4, 42);
-}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/struct_with_resource_array_member.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/struct_with_resource_array_member.hlsl
deleted file mode 100644
index a2ba45b7bc9e3..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/struct_with_resource_array_member.hlsl
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// DXC: passes (both sema and codegen).
-
-RWByteAddressBuffer gBuf0 : register(u0);
-
-struct S { RWByteAddressBuffer arr[2]; };
-
-uint Pass_StructArrayAssignment(uint idx) {
- S s;
- s.arr[0] = gBuf0;
- s.arr[0].Store(idx * 4, 9);
-
- return 9;
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- uint idx = tid.x + tid.y * 8;
- Pass_StructArrayAssignment(idx);
-}
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/ternary_initialization.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/ternary_initialization.hlsl
similarity index 68%
rename from clang/test/CodeGenHLSL/resources/Local-Resources/ternary_initialization.hlsl
rename to clang/test/SemaHLSL/Resources/Local-Resources/ternary_initialization.hlsl
index 90e5e67681903..d354c349e6f14 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/ternary_initialization.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/ternary_initialization.hlsl
@@ -1,8 +1,6 @@
// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute -emit-llvm -disable-llvm-passes 2>&1 -o - %s | llvm-cxxfilt | FileCheck %s
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-// This test fails after verify.
-//
// DXC: passes sema but fails codegen (DxilCondenseResources) with:
// "local resource not guaranteed to map to unique global resource."
@@ -12,8 +10,7 @@ RWByteAddressBuffer gBuf1 : register(u1);
uint Pass_TernaryInit(bool cond, uint idx) {
// DXC emits this warning: local resource not guaranteed to map to unique global resource.
- // Below is generated by -Whlsl-explicit-binding
- // CHECK: warning: assignment of 'cond ? gBuf0 : gBuf1' to local resource 'buf' is not to the same unique global resource
+ // expected-warning at +1{{assignment of 'cond ? gBuf0 : gBuf1' to local resource 'buf' is not to the same unique global resource}}
RWByteAddressBuffer buf = cond ? gBuf0 : gBuf1;
buf.Store(idx * 4, 2);
diff --git a/clang/test/CodeGenHLSL/resources/Local-Resources/use_groupshared.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared.hlsl
similarity index 53%
rename from clang/test/CodeGenHLSL/resources/Local-Resources/use_groupshared.hlsl
rename to clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared.hlsl
index 7b054914c6d14..ea98056bf8582 100644
--- a/clang/test/CodeGenHLSL/resources/Local-Resources/use_groupshared.hlsl
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/use_groupshared.hlsl
@@ -1,5 +1,5 @@
-// RUN: not %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute -emit-llvm -disable-llvm-passes 2>&1 -o - %s | llvm-cxxfilt | FileCheck %s
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
// This test fails validation in DXC, but DXC's sema allows it.
// Meanwhile, groupshared is immediately detected and rejected in clang's sema.
@@ -9,6 +9,7 @@
RWByteAddressBuffer gOut : register(u3);
+// expected-note at +1{{passing argument to parameter 'buf' here}}
uint DoStore(RWByteAddressBuffer buf, uint offset, uint value) {
buf.Store(offset, value);
return value;
@@ -16,14 +17,12 @@ uint DoStore(RWByteAddressBuffer buf, uint offset, uint value) {
groupshared RWByteAddressBuffer sharedBuf;
uint Use_Shared(uint idx) {
+ // expected-note@*:*{{candidate constructor not viable: cannot bind reference in address space 'groupshared'}}
+ // expected-note@*:*{{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
+ // expected-error at +1{{no matching constructor for initialization of 'RWByteAddressBuffer'}}
return DoStore(sharedBuf, idx * 4, 1);
}
-// CHECK: error: no matching constructor for initialization of 'RWByteAddressBuffer'
-// CHECK: note: candidate constructor not viable: cannot bind reference in address space 'groupshared' to object in generic address space in 1st argument
-// CHECK: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
-// CHECK: note: passing argument to parameter 'buf' here
-
[numthreads(8,8,1)]
void main(uint3 tid : SV_DispatchThreadID) {
uint idx = tid.x + tid.y * 8;
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/use_local_resource_uninitialized.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/use_local_resource_uninitialized.hlsl
deleted file mode 100644
index 3dfc8c15a1574..0000000000000
--- a/clang/test/SemaHLSL/Resources/Local-Resources/use_local_resource_uninitialized.hlsl
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
-
-// expected-no-diagnostics
-
-// DXC: passes (both sema and codegen).
-
-uint Pass_Uninitialized(uint idx) {
- RWByteAddressBuffer buf;
- buf.Store(idx * 4, 11);
-
- return 11;
-}
-
-[numthreads(8,8,1)]
-void main(uint3 tid : SV_DispatchThreadID) {
- uint idx = tid.x + tid.y * 8;
- Pass_Uninitialized(idx);
-}
>From a6451547ad334b6b3c23ccde15af7471f3acfdaf Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Thu, 16 Apr 2026 11:30:32 -0700
Subject: [PATCH 10/10] add tests
---
.../local_resource_default_init_store.hlsl | 15 +++++++
.../local_resource_static_local.hlsl | 24 +++++++++++
.../local_resource_ternary_as_argument.hlsl | 25 ++++++++++++
.../local_resource_ternary_lvalue.hlsl | 23 +++++++++++
.../use_struct_groupshared.hlsl | 40 +++++++++++++++++++
5 files changed, 127 insertions(+)
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_init_store.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_local.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_as_argument.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_lvalue.hlsl
create mode 100644 clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.hlsl
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_init_store.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_init_store.hlsl
new file mode 100644
index 0000000000000..00ba8436305dc
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_default_init_store.hlsl
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that using a default-initialized (unbound) local resource produces
+// valid IR in clang. No warnings or errors from clang.
+//
+// DXC: passes (both sema and codegen).
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID) {
+ RWByteAddressBuffer buf;
+ buf.Store(tid.x * 4, 42);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_local.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_local.hlsl
new file mode 100644
index 0000000000000..24561cd5cd3d3
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_static_local.hlsl
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that a static local resource variable initialized from a global
+// is accepted by both compilers.
+//
+// DXC: passes (both sema and codegen) with RWByteAddressBuffer.
+// Note: DXC asserts/ICEs when Texture2D is used instead.
+
+RWByteAddressBuffer gBuf0 : register(u0);
+
+uint Pass_StaticLocal(uint idx) {
+ static RWByteAddressBuffer buf = gBuf0;
+ buf.Store(idx * 4, 1);
+
+ return 1;
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID) {
+ Pass_StaticLocal(tid.x);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_as_argument.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_as_argument.hlsl
new file mode 100644
index 0000000000000..d01c9f39d6e45
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_as_argument.hlsl
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes \
+// RUN: -o - 2>&1 | llvm-cxxfilt | FileCheck %s
+
+// Test that a ternary resource expression passed directly as a function
+// argument produces valid IR in clang.
+//
+// DXC: passes sema but fails codegen with:
+// "local resource not guaranteed to map to unique global resource."
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+void Helper(RWByteAddressBuffer buf, uint offset, uint value) {
+ buf.Store(offset, value);
+}
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID) {
+ bool cond = tid.x > 0;
+ Helper(cond ? gBuf0 : gBuf1, tid.x * 4, 42);
+}
+
+// CHECK-NOT: error:
+// CHECK: define {{.*}} @main(
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_lvalue.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_lvalue.hlsl
new file mode 100644
index 0000000000000..f8654215403db
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/local_resource_ternary_lvalue.hlsl
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute %s -emit-llvm -o - -verify
+
+// expected-no-diagnostics
+
+// Test that a ternary expression can be used as an lvalue for resource
+// assignment. This exercises lvalue analysis of the ternary operator
+// with resource types.
+//
+// DXC: ICEs with "Internal compiler error: LLVM Assert" (even at sema).
+
+RWByteAddressBuffer gBuf0 : register(u0);
+RWByteAddressBuffer gBuf1 : register(u1);
+
+[numthreads(1,1,1)]
+void main(uint3 tid : SV_DispatchThreadID) {
+ RWByteAddressBuffer a = gBuf0;
+ RWByteAddressBuffer b = gBuf1;
+ bool cond = tid.x > 0;
+ (cond ? a : b) = gBuf0;
+ a.Store(tid.x * 4, 1);
+ b.Store(tid.x * 4, 2);
+}
diff --git a/clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.hlsl b/clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.hlsl
new file mode 100644
index 0000000000000..d78e2bfea4422
--- /dev/null
+++ b/clang/test/SemaHLSL/Resources/Local-Resources/use_struct_groupshared.hlsl
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.6-compute -emit-llvm -disable-llvm-passes 2>&1 -o - %s | llvm-cxxfilt | FileCheck %s
+//
+// XFAIL: *
+// https://github.com/llvm/llvm-project/issues/158107
+
+// This test fails validation in DXC, but DXC's sema allows it.
+// Meanwhile, it is for some reason accepted by clang's sema.
+// TODO: Why does this pass clang's sema, but use_groupshared.hlsl fails clang's sema?
+// Run a git bisect on https://github.com/llvm/llvm-project/issues/158107, and figure
+// out which commit seemed to resolve this issue.
+//
+// DXC: passes sema but fails validation with:
+// "Explicit load/store type does not match pointee type of pointer operand"
+
+RWByteAddressBuffer gOut : register(u3);
+
+// CHECK: note: passing argument to parameter 'buf' here
+uint DoStore(RWByteAddressBuffer buf, uint offset, uint value) {
+ buf.Store(offset, value);
+ return value;
+}
+
+// CHECK: note: candidate constructor not viable: cannot bind reference in address space 'groupshared' to object in generic address space in 1st argument
+// CHECK: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
+
+struct PassBufStruct { RWByteAddressBuffer buf; };
+
+groupshared PassBufStruct sharedStruct;
+
+uint Use_PassSharedStruct(uint idx) {
+ // CHECK: error: no matching constructor for initialization of 'RWByteAddressBuffer'
+ return DoStore(sharedStruct.buf, idx * 4, 1);
+}
+
+[numthreads(8,8,1)]
+void main(uint3 tid : SV_DispatchThreadID) {
+ uint idx = tid.x + tid.y * 8;
+ Use_PassSharedStruct(idx);
+}
More information about the cfe-commits
mailing list