https://github.com/bob80905 created 
https://github.com/llvm/llvm-project/pull/190037

draft

>From ea9445b3fa97f5fa0132985f39a41609ed51e6f5 Mon Sep 17 00:00:00 2001
From: Joshua Batista <[email protected]>
Date: Wed, 25 Mar 2026 16:40:16 -0700
Subject: [PATCH 1/4] 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@-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@-1 {{scalar, vector, or matrix expected}}
+    return tex;
+    // expected-error@-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@-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@-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@-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@-1 {{scalar, vector, or matrix expected}}
+}
+
+
+//--------------------------------------------------------------
+// FAIL 7: default parameter on resource
+//--------------------------------------------------------------
+
+float4 Fail_DefaultParam(Texture2D<float4> tex = gTex0, float2 uv)
+    // expected-error@-1 {{missing default argument on parameter 'uv'}}
+    // expected-note@-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@-1 {{cannot convert from 'SamplerState' to 
'Texture2D<float4>'}}
+}
+
+//--------------------------------------------------------------
+// FAIL 9: RWStructuredBuffer with resource type
+//--------------------------------------------------------------
+
+void Fail_LocalBuffer()
+{
+    RWStructuredBuffer<Texture2D<float4> > badBuffer;
+    // expected-error@-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@-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@+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 <[email protected]>
Date: Mon, 30 Mar 2026 14:39:07 -0700
Subject: [PATCH 2/4] 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@+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@+1{{variable 'buf' is declared here}}
+    RWByteAddressBuffer buf = gBuf0;
+    // expected-warning@+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@+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@+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@+2{{variable 'buf' is declared here}}
+    // expected-note@+1{{variable 'buf' is declared here}}
+    RWByteAddressBuffer buf = gBuf0;
 
     switch(v)
     {
-        case 1: tex = gTex1; break;
-        case 2: tex = gTex2; break;
+        // expected-warning@+1{{assignment of 'gBuf1' to local resource 'buf' 
is not to the same unique global resource}}
+        case 1: buf = gBuf1; break;
+        // expected-warning@+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@+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@+1{{variable 'buf' is declared here}}
+    RWByteAddressBuffer buf = gBuf0;
 
     for(int i=0;i<iterations;i++)
-    {
-        tex = gTexArray[i & 3];
-    }
+        // expected-warning@+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@+2{{variable 'buf' is declared here}}
+    // expected-note@+1{{variable 'buf' is declared here}}
+    RWByteAddressBuffer buf = gBuf0;
 
     switch(v)
     {
-        case 0:
-            tex = gTex1;
-        case 1:
-            tex = gTex2;
-            break;
+        // expected-warning@+1{{assignment of 'gBuf1' to local resource 'buf' 
is not to the same unique global resource}}
+        case 0: buf = gBuf1;
+        // expected-warning@+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@+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@+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@+1{{variable 'buf' is declared here}}
+    RWByteAddressBuffer buf;
 
     {
-        tex = gTex1;
-
+        buf = gBuf1;
         {
-            tex = gTex2;
+            // expected-warning@+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 <[email protected]>
Date: Mon, 30 Mar 2026 15:00:21 -0700
Subject: [PATCH 3/4] 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 <[email protected]>
Date: Tue, 31 Mar 2026 12:04:50 -0700
Subject: [PATCH 4/4] 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) }
+
+@_ZL5gBuf0 = internal global %"class.hlsl::RWByteAddressBuffer" poison, align 4
[email protected] = private unnamed_addr constant [6 x i8] c"gBuf0\00", align 1
+@_ZL5gBuf1 = internal global %"class.hlsl::RWByteAddressBuffer" poison, align 4
[email protected] = private unnamed_addr constant [6 x i8] c"gBuf1\00", align 1
+@_ZL4gOut = internal global %"class.hlsl::RWByteAddressBuffer" poison, align 4
[email protected] = 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@+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@+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@+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@+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" }
+
+@_ZL4gOut = internal global %"class.hlsl::RWByteAddressBuffer" poison, align 4
[email protected] = private unnamed_addr constant [5 x i8] c"gOut\00", align 1
+@_ZL16sharedStruct.buf = internal global %"class.hlsl::RWByteAddressBuffer" 
poison, align 4
[email protected] = private unnamed_addr constant [17 x i8] c"sharedStruct.buf\00", 
align 1
+@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@+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; };
 

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to