[clang] [HLSL] Make load methods take const attribute (PR #193858)
Joshua Batista via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 27 16:58:25 PDT 2026
https://github.com/bob80905 updated https://github.com/llvm/llvm-project/pull/193858
>From 9878e10c24e1e83edb27346a8b9ddab3cab27c57 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Thu, 23 Apr 2026 16:17:40 -0700
Subject: [PATCH 1/6] first attempt
---
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 8 ++---
.../SemaHLSL/BuiltIns/Buffers-Load-const.hlsl | 35 +++++++++++++++++++
2 files changed, 39 insertions(+), 4 deletions(-)
create mode 100644 clang/test/SemaHLSL/BuiltIns/Buffers-Load-const.hlsl
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index 4c8b0283b0f1e..0cdc2538a1bc1 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -1408,9 +1408,9 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addLoadMethods() {
IdentifierInfo &II = AST.Idents.get("Load", tok::TokenKind::identifier);
DeclarationName Load(&II);
// TODO: We also need versions with status for CheckAccessFullyMapped.
- addHandleAccessFunction(Load, /*IsConst=*/false, /*IsRef=*/false,
+ addHandleAccessFunction(Load, /*IsConst=*/true, /*IsRef=*/false,
AST.UnsignedIntTy);
- addLoadWithStatusFunction(Load, /*IsConst=*/false);
+ addLoadWithStatusFunction(Load, /*IsConst=*/true);
return *this;
}
@@ -1562,9 +1562,9 @@ BuiltinTypeDeclBuilder::addByteAddressBufferLoadMethods() {
IdentifierInfo &II = AST.Idents.get(MethodName, tok::TokenKind::identifier);
DeclarationName Load(&II);
- addHandleAccessFunction(Load, /*IsConst=*/false, /*IsRef=*/false,
+ addHandleAccessFunction(Load, /*IsConst=*/true, /*IsRef=*/false,
AST.UnsignedIntTy, ReturnType);
- addLoadWithStatusFunction(Load, /*IsConst=*/false, ReturnType);
+ addLoadWithStatusFunction(Load, /*IsConst=*/true, ReturnType);
};
AddLoads("Load", AST.UnsignedIntTy);
diff --git a/clang/test/SemaHLSL/BuiltIns/Buffers-Load-const.hlsl b/clang/test/SemaHLSL/BuiltIns/Buffers-Load-const.hlsl
new file mode 100644
index 0000000000000..3f408f7d8c2dd
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/Buffers-Load-const.hlsl
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.0-compute -x hlsl -fsyntax-only -verify \
+// RUN: -DRESOURCE="RWByteAddressBuffer" -DREGISTER=u1 %s
+// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.0-compute -x hlsl -fsyntax-only -verify \
+// RUN: -DRESOURCE="ByteAddressBuffer" -DREGISTER=t0 %s
+// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.0-compute -x hlsl -fsyntax-only -verify \
+// RUN: "-DRESOURCE=StructuredBuffer<uint>" -DREGISTER=t0 %s
+// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.0-compute -x hlsl -fsyntax-only -verify \
+// RUN: "-DRESOURCE=RWStructuredBuffer<uint>" -DREGISTER=u1 %s
+// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.0-compute -x hlsl -fsyntax-only -verify \
+// RUN: "-DRESOURCE=Buffer<uint>" -DREGISTER=t0 %s
+// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.0-compute -x hlsl -fsyntax-only -verify \
+// RUN: "-DRESOURCE=RWBuffer<uint>" -DREGISTER=u1 %s
+
+// expected-no-diagnostics
+
+// Regression test for https://github.com/llvm/llvm-project/issues/192557
+// Load on a const resource (e.g. const RWByteAddressBuffer) should be callable
+// because Load does not modify the buffer. DXC accepts this pattern.
+
+RESOURCE gBuf : register(REGISTER);
+RWByteAddressBuffer gOut : register(u0);
+
+void UseConst(const RESOURCE buf, out uint val) {
+ val = buf.Load(0);
+}
+
+[numthreads(1,1,1)]
+void main() {
+ const RESOURCE local = gBuf;
+ uint val;
+ UseConst(local, val);
+ // Write the loaded value to a separate buffer so it isn't dead-code
+ // eliminated.
+ gOut.Store(0, val);
+}
>From 6e5351017728a1dd4ea103a162396d000632c9b4 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Thu, 23 Apr 2026 17:05:00 -0700
Subject: [PATCH 2/6] add test updates
---
.../test/AST/HLSL/ByteAddressBuffers-AST.hlsl | 36 +++++++++----------
.../test/AST/HLSL/StructuredBuffers-AST.hlsl | 8 ++---
clang/test/AST/HLSL/TypedBuffers-AST.hlsl | 8 ++---
.../resources/ByteAddressBuffers-methods.hlsl | 32 ++++++++---------
.../StructuredBuffers-methods-lib.hlsl | 16 ++++-----
.../StructuredBuffers-methods-ps.hlsl | 16 ++++-----
.../resources/TypedBuffers-methods.hlsl | 16 ++++-----
.../SemaHLSL/BuiltIns/Buffers-Load-const.hlsl | 11 +++++-
8 files changed, 76 insertions(+), 67 deletions(-)
diff --git a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
index 16ce8ab0e7400..21c81dd895502 100644
--- a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
@@ -154,7 +154,7 @@ RESOURCE Buffer;
// Load methods
-// CHECK-LOAD: CXXMethodDecl {{.*}} Load 'unsigned int (unsigned int)'
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load 'const unsigned int (unsigned int) const'
// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
// CHECK-LOAD-NEXT: CompoundStmt
// CHECK-LOAD-NEXT: ReturnStmt
@@ -164,7 +164,7 @@ RESOURCE Buffer;
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer_typed' 'void (...) noexcept'
// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t {{.*}}' <LValueToRValue>
// CHECK-LOAD-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
-// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
+// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[RESOURCE]]' lvalue implicit this
// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <LValueToRValue>
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-LOAD-NEXT: CXXScalarValueInitExpr {{.*}} 'unsigned int *'
@@ -181,7 +181,7 @@ RESOURCE Buffer;
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_load_with_status_typed' 'void (...) noexcept'
// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t {{.*}}' <LValueToRValue>
// CHECK-LOAD-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
-// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
+// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[RESOURCE]]' lvalue implicit this
// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <LValueToRValue>
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <LValueToRValue>
@@ -189,7 +189,7 @@ RESOURCE Buffer;
// CHECK-LOAD-NEXT: CXXScalarValueInitExpr {{.*}} 'unsigned int *'
// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
-// CHECK-LOAD: CXXMethodDecl {{.*}} Load2 'vector<unsigned int, 2> (unsigned int)'
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load2 'vector<unsigned int, 2> const (unsigned int) const'
// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
// CHECK-LOAD-NEXT: CompoundStmt
// CHECK-LOAD-NEXT: ReturnStmt
@@ -199,13 +199,13 @@ RESOURCE Buffer;
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer_typed' 'void (...) noexcept'
// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t {{.*}}' <LValueToRValue>
// CHECK-LOAD-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
-// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
+// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[RESOURCE]]' lvalue implicit this
// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <LValueToRValue>
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-LOAD-NEXT: CXXScalarValueInitExpr {{.*}} 'vector<unsigned int, 2> *'
// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
-// CHECK-LOAD: CXXMethodDecl {{.*}} Load2 'vector<unsigned int, 2> (unsigned int, out unsigned int)'
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load2 'vector<unsigned int, 2> (unsigned int, out unsigned int) const'
// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Status 'unsigned int &__restrict'
// CHECK-LOAD-NEXT: HLSLParamModifierAttr {{.*}} out
@@ -216,7 +216,7 @@ RESOURCE Buffer;
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_load_with_status_typed' 'void (...) noexcept'
// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t {{.*}}' <LValueToRValue>
// CHECK-LOAD-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
-// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
+// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[RESOURCE]]' lvalue implicit this
// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <LValueToRValue>
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <LValueToRValue>
@@ -224,7 +224,7 @@ RESOURCE Buffer;
// CHECK-LOAD-NEXT: CXXScalarValueInitExpr {{.*}} 'vector<unsigned int, 2> *'
// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
-// CHECK-LOAD: CXXMethodDecl {{.*}} Load3 'vector<unsigned int, 3> (unsigned int)'
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load3 'vector<unsigned int, 3> const (unsigned int) const'
// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
// CHECK-LOAD-NEXT: CompoundStmt
// CHECK-LOAD-NEXT: ReturnStmt
@@ -234,13 +234,13 @@ RESOURCE Buffer;
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer_typed' 'void (...) noexcept'
// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t {{.*}}' <LValueToRValue>
// CHECK-LOAD-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
-// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
+// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[RESOURCE]]' lvalue implicit this
// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <LValueToRValue>
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-LOAD-NEXT: CXXScalarValueInitExpr {{.*}} 'vector<unsigned int, 3> *'
// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
-// CHECK-LOAD: CXXMethodDecl {{.*}} Load3 'vector<unsigned int, 3> (unsigned int, out unsigned int)'
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load3 'vector<unsigned int, 3> (unsigned int, out unsigned int) const'
// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Status 'unsigned int &__restrict'
// CHECK-LOAD-NEXT: HLSLParamModifierAttr {{.*}} out
@@ -251,7 +251,7 @@ RESOURCE Buffer;
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_load_with_status_typed' 'void (...) noexcept'
// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t {{.*}}' <LValueToRValue>
// CHECK-LOAD-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
-// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
+// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[RESOURCE]]' lvalue implicit this
// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <LValueToRValue>
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <LValueToRValue>
@@ -259,7 +259,7 @@ RESOURCE Buffer;
// CHECK-LOAD-NEXT: CXXScalarValueInitExpr {{.*}} 'vector<unsigned int, 3> *'
// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
-// CHECK-LOAD: CXXMethodDecl {{.*}} Load4 'vector<unsigned int, 4> (unsigned int)'
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load4 'vector<unsigned int, 4> const (unsigned int) const'
// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
// CHECK-LOAD-NEXT: CompoundStmt
// CHECK-LOAD-NEXT: ReturnStmt
@@ -269,13 +269,13 @@ RESOURCE Buffer;
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer_typed' 'void (...) noexcept'
// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t {{.*}}' <LValueToRValue>
// CHECK-LOAD-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
-// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
+// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[RESOURCE]]' lvalue implicit this
// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <LValueToRValue>
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-LOAD-NEXT: CXXScalarValueInitExpr {{.*}} 'vector<unsigned int, 4> *'
// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
-// CHECK-LOAD: CXXMethodDecl {{.*}} Load4 'vector<unsigned int, 4> (unsigned int, out unsigned int)'
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load4 'vector<unsigned int, 4> (unsigned int, out unsigned int) const'
// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Status 'unsigned int &__restrict'
// CHECK-LOAD-NEXT: HLSLParamModifierAttr {{.*}} out
@@ -286,7 +286,7 @@ RESOURCE Buffer;
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_load_with_status_typed' 'void (...) noexcept'
// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t {{.*}}' <LValueToRValue>
// CHECK-LOAD-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
-// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
+// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[RESOURCE]]' lvalue implicit this
// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <LValueToRValue>
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <LValueToRValue>
@@ -294,7 +294,7 @@ RESOURCE Buffer;
// CHECK-LOAD-NEXT: CXXScalarValueInitExpr {{.*}} 'vector<unsigned int, 4> *'
// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
-// CHECK-LOAD: CXXMethodDecl {{.*}} Load 'element_type (unsigned int)'
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load 'const element_type (unsigned int) const'
// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
// CHECK-LOAD-NEXT: CompoundStmt
// CHECK-LOAD-NEXT: ReturnStmt
@@ -303,7 +303,7 @@ RESOURCE Buffer;
// CHECK-LOAD-NEXT: CallExpr {{.*}} '<dependent type>'
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer_typed' 'void (...) noexcept'
// CHECK-LOAD-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
-// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
+// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[RESOURCE]]' lvalue implicit this
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-LOAD-NEXT: CXXScalarValueInitExpr {{.*}} 'element_type *'
// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
@@ -318,7 +318,7 @@ RESOURCE Buffer;
// CHECK-LOAD-NEXT: CallExpr {{.*}} '<dependent type>'
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_load_with_status_typed' 'void (...) noexcept'
// CHECK-LOAD-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
-// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
+// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[RESOURCE]]' lvalue implicit this
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Status' 'unsigned int &__restrict'
// CHECK-LOAD-NEXT: CXXScalarValueInitExpr {{.*}} 'element_type *'
diff --git a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
index 3cc33dbdb32af..bfd99814aa22a 100644
--- a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
@@ -310,7 +310,7 @@ RESOURCE<float> Buffer;
// Load method
-// CHECK-LOAD: CXXMethodDecl {{.*}} Load 'element_type (unsigned int)'
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load 'const element_type (unsigned int) const'
// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
// CHECK-LOAD-NEXT: CompoundStmt
// CHECK-LOAD-NEXT: ReturnStmt
@@ -322,13 +322,13 @@ RESOURCE<float> Buffer;
// CHECK-LOAD-SAME{LITERAL}: [[hlsl::resource_class(
// CHECK-LOAD-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
// CHECK-LOAD-SAME: ' lvalue .__handle {{.*}}
-// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
// Load with status method
-// CHECK-LOAD: CXXMethodDecl {{.*}} Load 'element_type (unsigned int, out unsigned int)'
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load 'element_type (unsigned int, out unsigned int) const'
// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Status 'unsigned int &__restrict'
// CHECK-LOAD-NEXT: HLSLParamModifierAttr {{.*}} out
@@ -341,7 +341,7 @@ RESOURCE<float> Buffer;
// CHECK-LOAD-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
// CHECK-LOAD-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
// CHECK-LOAD-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
-// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Status' 'unsigned int &__restrict'
// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
diff --git a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
index b6f9f79e0722e..ac564f61c11f7 100644
--- a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
@@ -197,7 +197,7 @@ RESOURCE<float> Buffer;
// Load method
-// CHECK: CXXMethodDecl {{.*}} Load 'element_type (unsigned int)'
+// CHECK: CXXMethodDecl {{.*}} Load 'const element_type (unsigned int) const'
// CHECK-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: ReturnStmt
@@ -210,12 +210,12 @@ RESOURCE<float> Buffer;
// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
// CHECK-SAME: ' lvalue .__handle {{.*}}
-// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
// Load with status method
-// CHECK: CXXMethodDecl {{.*}} Load 'element_type (unsigned int, out unsigned int)'
+// CHECK: CXXMethodDecl {{.*}} Load 'element_type (unsigned int, out unsigned int) const'
// CHECK-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
// CHECK-NEXT: ParmVarDecl {{.*}} Status 'unsigned int &__restrict'
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
@@ -228,7 +228,7 @@ RESOURCE<float> Buffer;
// CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
-// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Status' 'unsigned int &__restrict'
// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
diff --git a/clang/test/CodeGenHLSL/resources/ByteAddressBuffers-methods.hlsl b/clang/test/CodeGenHLSL/resources/ByteAddressBuffers-methods.hlsl
index fa04d82d54fb0..b91052bd4fa62 100644
--- a/clang/test/CodeGenHLSL/resources/ByteAddressBuffers-methods.hlsl
+++ b/clang/test/CodeGenHLSL/resources/ByteAddressBuffers-methods.hlsl
@@ -17,14 +17,14 @@ export float TestLoad() {
}
// CHECK: define {{.*}} float @TestLoad()()
-// CHECK: call {{.*}} i32 @hlsl::ByteAddressBuffer::Load(unsigned int)(ptr {{.*}} @Buf, i32 noundef 0)
-// CHECK: call {{.*}} <4 x i32> @hlsl::RWByteAddressBuffer::Load4(unsigned int)(ptr {{.*}} @RWBuf, i32 noundef 4)
-// CHECK: call {{.*}} float @float hlsl::ByteAddressBuffer::Load<float>(unsigned int)(ptr {{.*}} @Buf, i32 noundef 20)
-// CHECK: call {{.*}} <4 x float> @float vector[4] hlsl::RWByteAddressBuffer::Load<float vector[4]>(unsigned int)(ptr {{.*}} @RWBuf, i32 noundef 24)
+// CHECK: call {{.*}} i32 @hlsl::ByteAddressBuffer::Load(unsigned int) const(ptr {{.*}} @Buf, i32 noundef 0)
+// CHECK: call {{.*}} <4 x i32> @hlsl::RWByteAddressBuffer::Load4(unsigned int) const(ptr {{.*}} @RWBuf, i32 noundef 4)
+// CHECK: call {{.*}} float @float const hlsl::ByteAddressBuffer::Load<float>(unsigned int) const(ptr {{.*}} @Buf, i32 noundef 20)
+// CHECK: call {{.*}} <4 x float> @float vector[4] const hlsl::RWByteAddressBuffer::Load<float vector[4]>(unsigned int) const(ptr {{.*}} @RWBuf, i32 noundef 24)
// CHECK: add
// CHECK: ret float
-// CHECK: define {{.*}} i32 @hlsl::ByteAddressBuffer::Load(unsigned int)(ptr {{.*}} %this, i32 noundef %Index)
+// CHECK: define {{.*}} i32 @hlsl::ByteAddressBuffer::Load(unsigned int) const(ptr {{.*}} %this, i32 noundef %Index)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::ByteAddressBuffer", ptr %{{.*}}, i32 0, i32 0
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", i8, 0, 0), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
@@ -32,7 +32,7 @@ export float TestLoad() {
// CHECK-NEXT: %[[VAL:.*]] = load i32, ptr %[[PTR]]
// CHECK-NEXT: ret i32 %[[VAL]]
-// CHECK: define {{.*}} <4 x i32> @hlsl::RWByteAddressBuffer::Load4(unsigned int)(ptr {{.*}} %this, i32 noundef %Index)
+// CHECK: define {{.*}} <4 x i32> @hlsl::RWByteAddressBuffer::Load4(unsigned int) const(ptr {{.*}} %this, i32 noundef %Index)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWByteAddressBuffer", ptr %{{.*}}, i32 0, i32 0
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", i8, 1, 0), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
@@ -40,7 +40,7 @@ export float TestLoad() {
// CHECK-NEXT: %[[VEC:.*]] = load <4 x i32>, ptr %[[PTR]]
// CHECK-NEXT: ret <4 x i32> %[[VEC]]
-// CHECK: define {{.*}} float @float hlsl::ByteAddressBuffer::Load<float>(unsigned int)(ptr {{.*}} %this, i32 noundef %Index)
+// CHECK: define {{.*}} float @float const hlsl::ByteAddressBuffer::Load<float>(unsigned int) const(ptr {{.*}} %this, i32 noundef %Index)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::ByteAddressBuffer", ptr %{{.*}}, i32 0, i32 0
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", i8, 0, 0), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
@@ -48,7 +48,7 @@ export float TestLoad() {
// CHECK-NEXT: %[[VAL:.*]] = load float, ptr %[[PTR]]
// CHECK-NEXT: ret float %[[VAL]]
-// CHECK: define {{.*}} <4 x float> @float vector[4] hlsl::RWByteAddressBuffer::Load<float vector[4]>(unsigned int)(ptr {{.*}} %this, i32 noundef %Index)
+// CHECK: define {{.*}} <4 x float> @float vector[4] const hlsl::RWByteAddressBuffer::Load<float vector[4]>(unsigned int) const(ptr {{.*}} %this, i32 noundef %Index)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWByteAddressBuffer", ptr %{{.*}}, i32 0, i32 0
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", i8, 1, 0), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
@@ -64,14 +64,14 @@ export float TestLoadWithStatus() {
}
// CHECK: define {{.*}} float @TestLoadWithStatus()()
-// CHECK: call {{.*}} i32 @hlsl::ByteAddressBuffer::Load(unsigned int, unsigned int&)(ptr {{.*}} @Buf, i32 noundef 0, ptr {{.*}} %tmp)
-// CHECK: call {{.*}} <4 x i32> @hlsl::RWByteAddressBuffer::Load4(unsigned int, unsigned int&)(ptr {{.*}} @RWBuf, i32 noundef 4, ptr {{.*}} %tmp1)
-// CHECK: call {{.*}} float @float hlsl::ByteAddressBuffer::Load<float>(unsigned int, unsigned int&)(ptr {{.*}} @Buf, i32 noundef 20, ptr {{.*}} %tmp4)
-// CHECK: call {{.*}} <4 x float> @float vector[4] hlsl::RWByteAddressBuffer::Load<float vector[4]>(unsigned int, unsigned int&)(ptr {{.*}} @RWBuf, i32 noundef 24, ptr {{.*}} %tmp7)
+// CHECK: call {{.*}} i32 @hlsl::ByteAddressBuffer::Load(unsigned int, unsigned int&) const(ptr {{.*}} @Buf, i32 noundef 0, ptr {{.*}} %tmp)
+// CHECK: call {{.*}} <4 x i32> @hlsl::RWByteAddressBuffer::Load4(unsigned int, unsigned int&) const(ptr {{.*}} @RWBuf, i32 noundef 4, ptr {{.*}} %tmp1)
+// CHECK: call {{.*}} float @float hlsl::ByteAddressBuffer::Load<float>(unsigned int, unsigned int&) const(ptr {{.*}} @Buf, i32 noundef 20, ptr {{.*}} %tmp4)
+// CHECK: call {{.*}} <4 x float> @float vector[4] hlsl::RWByteAddressBuffer::Load<float vector[4]>(unsigned int, unsigned int&) const(ptr {{.*}} @RWBuf, i32 noundef 24, ptr {{.*}} %tmp7)
// CHECK: add
// CHECK: ret float
-// CHECK: define {{.*}} i32 @hlsl::ByteAddressBuffer::Load(unsigned int, unsigned int&)(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status)
+// CHECK: define {{.*}} i32 @hlsl::ByteAddressBuffer::Load(unsigned int, unsigned int&) const(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::ByteAddressBuffer", ptr %{{.*}}, i32 0, i32 0
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", i8, 0, 0), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
@@ -83,7 +83,7 @@ export float TestLoadWithStatus() {
// CHECK-NEXT: store i32 %[[STATUS_EXT]], ptr %[[LOADED_STATUS_ADDR]], align 4
// CHECK-NEXT: ret i32 %[[VALUE]]
-// CHECK: define {{.*}} <4 x i32> @hlsl::RWByteAddressBuffer::Load4(unsigned int, unsigned int&)(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status)
+// CHECK: define {{.*}} <4 x i32> @hlsl::RWByteAddressBuffer::Load4(unsigned int, unsigned int&) const(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWByteAddressBuffer", ptr %{{.*}}, i32 0, i32 0
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", i8, 1, 0), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
@@ -95,7 +95,7 @@ export float TestLoadWithStatus() {
// CHECK-NEXT: store i32 %[[STATUS_EXT]], ptr %[[LOADED_STATUS_ADDR]], align 4
// CHECK-NEXT: ret <4 x i32> %[[VALUE]]
-// CHECK: define {{.*}} float @float hlsl::ByteAddressBuffer::Load<float>(unsigned int, unsigned int&)(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status)
+// CHECK: define {{.*}} float @float hlsl::ByteAddressBuffer::Load<float>(unsigned int, unsigned int&) const(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::ByteAddressBuffer", ptr %{{.*}}, i32 0, i32 0
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", i8, 0, 0), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
@@ -107,7 +107,7 @@ export float TestLoadWithStatus() {
// CHECK-NEXT: store i32 %[[STATUS_EXT]], ptr %[[LOADED_STATUS_ADDR]], align 4
// CHECK-NEXT: ret float %[[VALUE]]
-// CHECK: define {{.*}} <4 x float> @float vector[4] hlsl::RWByteAddressBuffer::Load<float vector[4]>(unsigned int, unsigned int&)(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status)
+// CHECK: define {{.*}} <4 x float> @float vector[4] hlsl::RWByteAddressBuffer::Load<float vector[4]>(unsigned int, unsigned int&) const(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWByteAddressBuffer", ptr %{{.*}}, i32 0, i32 0
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", i8, 1, 0), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
diff --git a/clang/test/CodeGenHLSL/resources/StructuredBuffers-methods-lib.hlsl b/clang/test/CodeGenHLSL/resources/StructuredBuffers-methods-lib.hlsl
index 12a644b4d4355..35f838a48c422 100644
--- a/clang/test/CodeGenHLSL/resources/StructuredBuffers-methods-lib.hlsl
+++ b/clang/test/CodeGenHLSL/resources/StructuredBuffers-methods-lib.hlsl
@@ -83,12 +83,12 @@ export float TestLoad() {
}
// CHECK: define noundef nofpclass(nan inf) float @TestLoad()()
-// CHECK: call {{.*}} float @hlsl::RWStructuredBuffer<float>::Load(unsigned int)(ptr {{.*}} @RWSB1, i32 noundef 1)
-// CHECK: call {{.*}} float @hlsl::StructuredBuffer<float>::Load(unsigned int)(ptr {{.*}} @SB1, i32 noundef 2)
+// CHECK: call {{.*}} float @hlsl::RWStructuredBuffer<float>::Load(unsigned int) const(ptr {{.*}} @RWSB1, i32 noundef 1)
+// CHECK: call {{.*}} float @hlsl::StructuredBuffer<float>::Load(unsigned int) const(ptr {{.*}} @SB1, i32 noundef 2)
// CHECK: add
// CHECK: ret float
-// CHECK: define {{.*}} float @hlsl::RWStructuredBuffer<float>::Load(unsigned int)(ptr {{.*}} %this, i32 noundef %Index)
+// CHECK: define {{.*}} float @hlsl::RWStructuredBuffer<float>::Load(unsigned int) const(ptr {{.*}} %this, i32 noundef %Index)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWStructuredBuffer", ptr %{{.*}}, i32 0, i32 0
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", float, 1, 0), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
@@ -96,7 +96,7 @@ export float TestLoad() {
// CHECK-NEXT: %[[VAL:.*]] = load float, ptr %[[PTR]]
// CHECK-NEXT: ret float %[[VAL]]
-// CHECK: define {{.*}} float @hlsl::StructuredBuffer<float>::Load(unsigned int)(ptr {{.*}} %this, i32 noundef %Index)
+// CHECK: define {{.*}} float @hlsl::StructuredBuffer<float>::Load(unsigned int) const(ptr {{.*}} %this, i32 noundef %Index)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::StructuredBuffer", ptr %{{.*}}, i32 0, i32 0
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", float, 0, 0), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
@@ -113,12 +113,12 @@ export float TestLoadWithStatus() {
}
// CHECK: define noundef nofpclass(nan inf) float @TestLoadWithStatus()()
-// CHECK: call {{.*}} float @hlsl::RWStructuredBuffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} @RWSB1, i32 noundef 1, ptr {{.*}} %tmp)
-// CHECK: call {{.*}} float @hlsl::StructuredBuffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} @SB1, i32 noundef 2, ptr {{.*}} %tmp1)
+// CHECK: call {{.*}} float @hlsl::RWStructuredBuffer<float>::Load(unsigned int, unsigned int&) const(ptr {{.*}} @RWSB1, i32 noundef 1, ptr {{.*}} %tmp)
+// CHECK: call {{.*}} float @hlsl::StructuredBuffer<float>::Load(unsigned int, unsigned int&) const(ptr {{.*}} @SB1, i32 noundef 2, ptr {{.*}} %tmp1)
// CHECK: add
// CHECK: ret float
-// CHECK: define {{.*}} float @hlsl::RWStructuredBuffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status)
+// CHECK: define {{.*}} float @hlsl::RWStructuredBuffer<float>::Load(unsigned int, unsigned int&) const(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWStructuredBuffer", ptr %{{.*}}, i32 0, i32 0
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", float, 1, 0), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
@@ -130,7 +130,7 @@ export float TestLoadWithStatus() {
// CHECK-NEXT: store i32 %[[STATUS_EXT]], ptr %[[LOADED_STATUS_ADDR]], align 4
// CHECK-NEXT: ret float %[[VALUE]]
-// CHECK: define {{.*}} float @hlsl::StructuredBuffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status)
+// CHECK: define {{.*}} float @hlsl::StructuredBuffer<float>::Load(unsigned int, unsigned int&) const(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::StructuredBuffer", ptr %{{.*}}, i32 0, i32 0
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", float, 0, 0), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
diff --git a/clang/test/CodeGenHLSL/resources/StructuredBuffers-methods-ps.hlsl b/clang/test/CodeGenHLSL/resources/StructuredBuffers-methods-ps.hlsl
index 85ca449bc6ea3..a38b627f997b6 100644
--- a/clang/test/CodeGenHLSL/resources/StructuredBuffers-methods-ps.hlsl
+++ b/clang/test/CodeGenHLSL/resources/StructuredBuffers-methods-ps.hlsl
@@ -45,11 +45,11 @@ export float TestLoad() {
}
// CHECK: define {{.*}} float @TestLoad()()
-// CHECK: call {{.*}} float @hlsl::RasterizerOrderedStructuredBuffer<float>::Load(unsigned int)(ptr {{.*}} @ROSB1, i32 noundef 10)
-// CHECK: call {{.*}} <2 x i32> @hlsl::RasterizerOrderedStructuredBuffer<int vector[2]>::Load(unsigned int)(ptr {{.*}} @ROSB2, i32 noundef 20)
+// CHECK: call {{.*}} float @hlsl::RasterizerOrderedStructuredBuffer<float>::Load(unsigned int) const(ptr {{.*}} @ROSB1, i32 noundef 10)
+// CHECK: call {{.*}} <2 x i32> @hlsl::RasterizerOrderedStructuredBuffer<int vector[2]>::Load(unsigned int) const(ptr {{.*}} @ROSB2, i32 noundef 20)
// CHECK: ret
-// CHECK: define {{.*}} float @hlsl::RasterizerOrderedStructuredBuffer<float>::Load(unsigned int)(ptr {{.*}} %Index)
+// CHECK: define {{.*}} float @hlsl::RasterizerOrderedStructuredBuffer<float>::Load(unsigned int) const(ptr {{.*}} %Index)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RasterizerOrderedStructuredBuffer", ptr {{.*}}, i32 0, i32 0
// CHECK-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", float, 1, 1), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
@@ -57,7 +57,7 @@ export float TestLoad() {
// CHECK-NEXT: %[[VAL:.*]] = load float, ptr %[[BUFPTR]]
// CHECK-NEXT: ret float %[[VAL]]
-// CHECK: define {{.*}} <2 x i32> @hlsl::RasterizerOrderedStructuredBuffer<int vector[2]>::Load(unsigned int)(ptr {{.*}} %Index)
+// CHECK: define {{.*}} <2 x i32> @hlsl::RasterizerOrderedStructuredBuffer<int vector[2]>::Load(unsigned int) const(ptr {{.*}} %Index)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RasterizerOrderedStructuredBuffer.0", ptr {{.*}}, i32 0, i32 0
// CHECK-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", <2 x i32>, 1, 1), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
@@ -73,11 +73,11 @@ export float TestLoadWithStatus() {
}
// CHECK: define {{.*}} float @TestLoadWithStatus()()
-// CHECK: call {{.*}} float @hlsl::RasterizerOrderedStructuredBuffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} @ROSB1, i32 noundef 10, ptr {{.*}} %tmp)
-// CHECK: call {{.*}} <2 x i32> @hlsl::RasterizerOrderedStructuredBuffer<int vector[2]>::Load(unsigned int, unsigned int&)(ptr {{.*}} @ROSB2, i32 noundef 20, ptr {{.*}} %tmp2)
+// CHECK: call {{.*}} float @hlsl::RasterizerOrderedStructuredBuffer<float>::Load(unsigned int, unsigned int&) const(ptr {{.*}} @ROSB1, i32 noundef 10, ptr {{.*}} %tmp)
+// CHECK: call {{.*}} <2 x i32> @hlsl::RasterizerOrderedStructuredBuffer<int vector[2]>::Load(unsigned int, unsigned int&) const(ptr {{.*}} @ROSB2, i32 noundef 20, ptr {{.*}} %tmp2)
// CHECK: ret
-// CHECK: define {{.*}} float @hlsl::RasterizerOrderedStructuredBuffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status)
+// CHECK: define {{.*}} float @hlsl::RasterizerOrderedStructuredBuffer<float>::Load(unsigned int, unsigned int&) const(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RasterizerOrderedStructuredBuffer", ptr {{.*}}, i32 0, i32 0
// CHECK-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", float, 1, 1), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
@@ -89,7 +89,7 @@ export float TestLoadWithStatus() {
// CHECK-NEXT: store i32 %[[STATUS_EXT]], ptr %[[LOADED_STATUS_ADDR]], align 4
// CHECK-NEXT: ret float %[[VALUE]]
-// CHECK: define {{.*}} <2 x i32> @hlsl::RasterizerOrderedStructuredBuffer<int vector[2]>::Load(unsigned int, unsigned int&)(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status)
+// CHECK: define {{.*}} <2 x i32> @hlsl::RasterizerOrderedStructuredBuffer<int vector[2]>::Load(unsigned int, unsigned int&) const(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RasterizerOrderedStructuredBuffer.0", ptr {{.*}}, i32 0, i32 0
// CHECK-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", <2 x i32>, 1, 1), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
diff --git a/clang/test/CodeGenHLSL/resources/TypedBuffers-methods.hlsl b/clang/test/CodeGenHLSL/resources/TypedBuffers-methods.hlsl
index bdf7f4d7fd388..dc74b966dfe13 100644
--- a/clang/test/CodeGenHLSL/resources/TypedBuffers-methods.hlsl
+++ b/clang/test/CodeGenHLSL/resources/TypedBuffers-methods.hlsl
@@ -17,12 +17,12 @@ export float TestLoad() {
}
// CHECK: define noundef nofpclass(nan inf) float @TestLoad()()
-// CHECK: call {{.*}} float @hlsl::Buffer<float>::Load(unsigned int)(ptr {{.*}} @Buf, i32 noundef 1)
-// CHECK: call {{.*}} <4 x i32> @hlsl::RWBuffer<unsigned int vector[4]>::Load(unsigned int)(ptr {{.*}} @RWBuf, i32 noundef 2)
+// CHECK: call {{.*}} float @hlsl::Buffer<float>::Load(unsigned int) const(ptr {{.*}} @Buf, i32 noundef 1)
+// CHECK: call {{.*}} <4 x i32> @hlsl::RWBuffer<unsigned int vector[4]>::Load(unsigned int) const(ptr {{.*}} @RWBuf, i32 noundef 2)
// CHECK: add
// CHECK: ret float
-// CHECK: define {{.*}} float @hlsl::Buffer<float>::Load(unsigned int)(ptr {{.*}} %this, i32 noundef %Index)
+// CHECK: define {{.*}} float @hlsl::Buffer<float>::Load(unsigned int) const(ptr {{.*}} %this, i32 noundef %Index)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::Buffer", ptr %{{.*}}, i32 0, i32 0
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.TypedBuffer", float, 0, 0, 0), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
@@ -30,7 +30,7 @@ export float TestLoad() {
// CHECK-NEXT: %[[VAL:.*]] = load float, ptr %[[PTR]]
// CHECK-NEXT: ret float %[[VAL]]
-// CHECK: define {{.*}} <4 x i32> @hlsl::RWBuffer<unsigned int vector[4]>::Load(unsigned int)(ptr {{.*}} %this, i32 noundef %Index)
+// CHECK: define {{.*}} <4 x i32> @hlsl::RWBuffer<unsigned int vector[4]>::Load(unsigned int) const(ptr {{.*}} %this, i32 noundef %Index)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWBuffer", ptr %{{.*}}, i32 0, i32 0
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.TypedBuffer", <4 x i32>, 1, 0, 0), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
@@ -47,12 +47,12 @@ export float TestLoadWithStatus() {
}
// CHECK: define noundef nofpclass(nan inf) float @TestLoadWithStatus()()
-// CHECK: call {{.*}} float @hlsl::Buffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} @Buf, i32 noundef 1, ptr {{.*}} %tmp)
-// CHECK: call {{.*}} <4 x i32> @hlsl::RWBuffer<unsigned int vector[4]>::Load(unsigned int, unsigned int&)(ptr {{.*}} @RWBuf, i32 noundef 2, ptr {{.*}} %tmp1)
+// CHECK: call {{.*}} float @hlsl::Buffer<float>::Load(unsigned int, unsigned int&) const(ptr {{.*}} @Buf, i32 noundef 1, ptr {{.*}} %tmp)
+// CHECK: call {{.*}} <4 x i32> @hlsl::RWBuffer<unsigned int vector[4]>::Load(unsigned int, unsigned int&) const(ptr {{.*}} @RWBuf, i32 noundef 2, ptr {{.*}} %tmp1)
// CHECK: add
// CHECK: ret float
-// CHECK: define {{.*}} float @hlsl::Buffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status)
+// CHECK: define {{.*}} float @hlsl::Buffer<float>::Load(unsigned int, unsigned int&) const(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::Buffer", ptr %{{.*}}, i32 0, i32 0
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.TypedBuffer", float, 0, 0, 0), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
@@ -64,7 +64,7 @@ export float TestLoadWithStatus() {
// CHECK-NEXT: store i32 %[[STATUS_EXT]], ptr %[[LOADED_STATUS_ADDR]], align 4
// CHECK-NEXT: ret float %[[VALUE]]
-// CHECK: define {{.*}} <4 x i32> @hlsl::RWBuffer<unsigned int vector[4]>::Load(unsigned int, unsigned int&)(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status)
+// CHECK: define {{.*}} <4 x i32> @hlsl::RWBuffer<unsigned int vector[4]>::Load(unsigned int, unsigned int&) const(ptr {{.*}} %this, i32 noundef %Index, ptr {{.*}} %Status)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWBuffer", ptr %{{.*}}, i32 0, i32 0
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.TypedBuffer", <4 x i32>, 1, 0, 0), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
diff --git a/clang/test/SemaHLSL/BuiltIns/Buffers-Load-const.hlsl b/clang/test/SemaHLSL/BuiltIns/Buffers-Load-const.hlsl
index 3f408f7d8c2dd..3b2fa7c05440e 100644
--- a/clang/test/SemaHLSL/BuiltIns/Buffers-Load-const.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/Buffers-Load-const.hlsl
@@ -24,12 +24,21 @@ void UseConst(const RESOURCE buf, out uint val) {
val = buf.Load(0);
}
+void UseConstWithStatus(const RESOURCE buf, out uint val) {
+ uint status;
+ val = buf.Load(0, status);
+ val += status;
+}
+
[numthreads(1,1,1)]
void main() {
const RESOURCE local = gBuf;
uint val;
UseConst(local, val);
- // Write the loaded value to a separate buffer so it isn't dead-code
+ uint val2;
+ UseConstWithStatus(local, val2);
+ // Write the loaded values to a separate buffer so they aren't dead-code
// eliminated.
gOut.Store(0, val);
+ gOut.Store(4, val2);
}
>From b5df1572b11aa68fda22a0009120f8e969b2e492 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Fri, 24 Apr 2026 11:23:46 -0700
Subject: [PATCH 3/6] remove const return type, just const methods
---
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 23 +++++++++++--------
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h | 5 ++--
.../test/AST/HLSL/ByteAddressBuffers-AST.hlsl | 10 ++++----
.../test/AST/HLSL/StructuredBuffers-AST.hlsl | 2 +-
clang/test/AST/HLSL/TypedBuffers-AST.hlsl | 2 +-
.../resources/ByteAddressBuffers-methods.hlsl | 8 +++----
6 files changed, 27 insertions(+), 23 deletions(-)
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index 0cdc2538a1bc1..aecf09d4d0bce 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -1393,10 +1393,11 @@ BuiltinTypeDeclBuilder::addArraySubscriptOperators(ResourceDimension Dim) {
DeclarationName Subscript =
AST.DeclarationNames.getCXXOperatorName(OO_Subscript);
- addHandleAccessFunction(Subscript, /*IsConst=*/true, /*IsRef=*/true, IndexTy);
+ addHandleAccessFunction(Subscript, /*IsConstMethod=*/true,
+ /*IsConstReturn=*/true, /*IsRef=*/true, IndexTy);
if (getResourceAttrs().ResourceClass == llvm::dxil::ResourceClass::UAV)
- addHandleAccessFunction(Subscript, /*IsConst=*/false, /*IsRef=*/true,
- IndexTy);
+ addHandleAccessFunction(Subscript, /*IsConstMethod=*/false,
+ /*IsConstReturn=*/false, /*IsRef=*/true, IndexTy);
return *this;
}
@@ -1408,7 +1409,8 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addLoadMethods() {
IdentifierInfo &II = AST.Idents.get("Load", tok::TokenKind::identifier);
DeclarationName Load(&II);
// TODO: We also need versions with status for CheckAccessFullyMapped.
- addHandleAccessFunction(Load, /*IsConst=*/true, /*IsRef=*/false,
+ addHandleAccessFunction(Load, /*IsConstMethod=*/true,
+ /*IsConstReturn=*/false, /*IsRef=*/false,
AST.UnsignedIntTy);
addLoadWithStatusFunction(Load, /*IsConst=*/true);
@@ -1562,7 +1564,8 @@ BuiltinTypeDeclBuilder::addByteAddressBufferLoadMethods() {
IdentifierInfo &II = AST.Idents.get(MethodName, tok::TokenKind::identifier);
DeclarationName Load(&II);
- addHandleAccessFunction(Load, /*IsConst=*/true, /*IsRef=*/false,
+ addHandleAccessFunction(Load, /*IsConstMethod=*/true,
+ /*IsConstReturn=*/false, /*IsRef=*/false,
AST.UnsignedIntTy, ReturnType);
addLoadWithStatusFunction(Load, /*IsConst=*/true, ReturnType);
};
@@ -2232,15 +2235,15 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addLoadWithStatusFunction(
}
BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleAccessFunction(
- DeclarationName &Name, bool IsConst, bool IsRef, QualType IndexTy,
- QualType ElemTy) {
+ DeclarationName &Name, bool IsConstMethod, bool IsConstReturn, bool IsRef,
+ QualType IndexTy, QualType ElemTy) {
assert(!Record->isCompleteDefinition() && "record is already complete");
ASTContext &AST = SemaRef.getASTContext();
using PH = BuiltinTypeMethodBuilder::PlaceHolder;
bool NeedsTypedBuiltin = !ElemTy.isNull();
// The empty QualType is a placeholder. The actual return type is set below.
- BuiltinTypeMethodBuilder MMB(*this, Name, QualType(), IsConst);
+ BuiltinTypeMethodBuilder MMB(*this, Name, QualType(), IsConstMethod);
if (!NeedsTypedBuiltin)
ElemTy = getHandleElementType();
@@ -2253,12 +2256,12 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleAccessFunction(
if (IsRef) {
ReturnTy = AddrSpaceElemTy;
- if (IsConst)
+ if (IsConstReturn)
ReturnTy.addConst();
ReturnTy = AST.getLValueReferenceType(ReturnTy);
} else {
ReturnTy = ElemTy;
- if (IsConst)
+ if (IsConstReturn)
ReturnTy.addConst();
}
MMB.ReturnTy = ReturnTy;
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
index 1ffe5d9a624ef..ed23123016278 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
@@ -114,8 +114,9 @@ class BuiltinTypeDeclBuilder {
BuiltinTypeDeclBuilder &addIncrementCounterMethod();
BuiltinTypeDeclBuilder &addDecrementCounterMethod();
BuiltinTypeDeclBuilder &addHandleAccessFunction(DeclarationName &Name,
- bool IsConst, bool IsRef,
- QualType IndexTy,
+ bool IsConstMethod,
+ bool IsConstReturn,
+ bool IsRef, QualType IndexTy,
QualType ElemTy = QualType());
BuiltinTypeDeclBuilder &
addLoadWithStatusFunction(DeclarationName &Name, bool IsConst,
diff --git a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
index 21c81dd895502..61585d7770d7c 100644
--- a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
@@ -154,7 +154,7 @@ RESOURCE Buffer;
// Load methods
-// CHECK-LOAD: CXXMethodDecl {{.*}} Load 'const unsigned int (unsigned int) const'
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load 'unsigned int (unsigned int) const'
// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
// CHECK-LOAD-NEXT: CompoundStmt
// CHECK-LOAD-NEXT: ReturnStmt
@@ -189,7 +189,7 @@ RESOURCE Buffer;
// CHECK-LOAD-NEXT: CXXScalarValueInitExpr {{.*}} 'unsigned int *'
// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
-// CHECK-LOAD: CXXMethodDecl {{.*}} Load2 'vector<unsigned int, 2> const (unsigned int) const'
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load2 'vector<unsigned int, 2> (unsigned int) const'
// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
// CHECK-LOAD-NEXT: CompoundStmt
// CHECK-LOAD-NEXT: ReturnStmt
@@ -224,7 +224,7 @@ RESOURCE Buffer;
// CHECK-LOAD-NEXT: CXXScalarValueInitExpr {{.*}} 'vector<unsigned int, 2> *'
// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
-// CHECK-LOAD: CXXMethodDecl {{.*}} Load3 'vector<unsigned int, 3> const (unsigned int) const'
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load3 'vector<unsigned int, 3> (unsigned int) const'
// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
// CHECK-LOAD-NEXT: CompoundStmt
// CHECK-LOAD-NEXT: ReturnStmt
@@ -259,7 +259,7 @@ RESOURCE Buffer;
// CHECK-LOAD-NEXT: CXXScalarValueInitExpr {{.*}} 'vector<unsigned int, 3> *'
// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
-// CHECK-LOAD: CXXMethodDecl {{.*}} Load4 'vector<unsigned int, 4> const (unsigned int) const'
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load4 'vector<unsigned int, 4> (unsigned int) const'
// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
// CHECK-LOAD-NEXT: CompoundStmt
// CHECK-LOAD-NEXT: ReturnStmt
@@ -294,7 +294,7 @@ RESOURCE Buffer;
// CHECK-LOAD-NEXT: CXXScalarValueInitExpr {{.*}} 'vector<unsigned int, 4> *'
// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
-// CHECK-LOAD: CXXMethodDecl {{.*}} Load 'const element_type (unsigned int) const'
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load 'element_type (unsigned int) const'
// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
// CHECK-LOAD-NEXT: CompoundStmt
// CHECK-LOAD-NEXT: ReturnStmt
diff --git a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
index bfd99814aa22a..fa1180fc69983 100644
--- a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
@@ -310,7 +310,7 @@ RESOURCE<float> Buffer;
// Load method
-// CHECK-LOAD: CXXMethodDecl {{.*}} Load 'const element_type (unsigned int) const'
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load 'element_type (unsigned int) const'
// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
// CHECK-LOAD-NEXT: CompoundStmt
// CHECK-LOAD-NEXT: ReturnStmt
diff --git a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
index ac564f61c11f7..c27b7360ee81c 100644
--- a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
@@ -197,7 +197,7 @@ RESOURCE<float> Buffer;
// Load method
-// CHECK: CXXMethodDecl {{.*}} Load 'const element_type (unsigned int) const'
+// CHECK: CXXMethodDecl {{.*}} Load 'element_type (unsigned int) const'
// CHECK-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: ReturnStmt
diff --git a/clang/test/CodeGenHLSL/resources/ByteAddressBuffers-methods.hlsl b/clang/test/CodeGenHLSL/resources/ByteAddressBuffers-methods.hlsl
index b91052bd4fa62..caa1fd18fc8e6 100644
--- a/clang/test/CodeGenHLSL/resources/ByteAddressBuffers-methods.hlsl
+++ b/clang/test/CodeGenHLSL/resources/ByteAddressBuffers-methods.hlsl
@@ -19,8 +19,8 @@ export float TestLoad() {
// CHECK: define {{.*}} float @TestLoad()()
// CHECK: call {{.*}} i32 @hlsl::ByteAddressBuffer::Load(unsigned int) const(ptr {{.*}} @Buf, i32 noundef 0)
// CHECK: call {{.*}} <4 x i32> @hlsl::RWByteAddressBuffer::Load4(unsigned int) const(ptr {{.*}} @RWBuf, i32 noundef 4)
-// CHECK: call {{.*}} float @float const hlsl::ByteAddressBuffer::Load<float>(unsigned int) const(ptr {{.*}} @Buf, i32 noundef 20)
-// CHECK: call {{.*}} <4 x float> @float vector[4] const hlsl::RWByteAddressBuffer::Load<float vector[4]>(unsigned int) const(ptr {{.*}} @RWBuf, i32 noundef 24)
+// CHECK: call {{.*}} float @float hlsl::ByteAddressBuffer::Load<float>(unsigned int) const(ptr {{.*}} @Buf, i32 noundef 20)
+// CHECK: call {{.*}} <4 x float> @float vector[4] hlsl::RWByteAddressBuffer::Load<float vector[4]>(unsigned int) const(ptr {{.*}} @RWBuf, i32 noundef 24)
// CHECK: add
// CHECK: ret float
@@ -40,7 +40,7 @@ export float TestLoad() {
// CHECK-NEXT: %[[VEC:.*]] = load <4 x i32>, ptr %[[PTR]]
// CHECK-NEXT: ret <4 x i32> %[[VEC]]
-// CHECK: define {{.*}} float @float const hlsl::ByteAddressBuffer::Load<float>(unsigned int) const(ptr {{.*}} %this, i32 noundef %Index)
+// CHECK: define {{.*}} float @float hlsl::ByteAddressBuffer::Load<float>(unsigned int) const(ptr {{.*}} %this, i32 noundef %Index)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::ByteAddressBuffer", ptr %{{.*}}, i32 0, i32 0
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", i8, 0, 0), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
@@ -48,7 +48,7 @@ export float TestLoad() {
// CHECK-NEXT: %[[VAL:.*]] = load float, ptr %[[PTR]]
// CHECK-NEXT: ret float %[[VAL]]
-// CHECK: define {{.*}} <4 x float> @float vector[4] const hlsl::RWByteAddressBuffer::Load<float vector[4]>(unsigned int) const(ptr {{.*}} %this, i32 noundef %Index)
+// CHECK: define {{.*}} <4 x float> @float vector[4] hlsl::RWByteAddressBuffer::Load<float vector[4]>(unsigned int) const(ptr {{.*}} %this, i32 noundef %Index)
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWByteAddressBuffer", ptr %{{.*}}, i32 0, i32 0
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", i8, 1, 0), ptr %__handle
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
>From ca24da5f2603ed6273aeeacb65cad8529b1bb4b5 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Fri, 24 Apr 2026 15:39:24 -0700
Subject: [PATCH 4/6] rename for consistency!
---
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 8 ++++----
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index aecf09d4d0bce..a9c99654bf9eb 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -1412,7 +1412,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addLoadMethods() {
addHandleAccessFunction(Load, /*IsConstMethod=*/true,
/*IsConstReturn=*/false, /*IsRef=*/false,
AST.UnsignedIntTy);
- addLoadWithStatusFunction(Load, /*IsConst=*/true);
+ addLoadWithStatusFunction(Load, /*IsConstMethod=*/true);
return *this;
}
@@ -1567,7 +1567,7 @@ BuiltinTypeDeclBuilder::addByteAddressBufferLoadMethods() {
addHandleAccessFunction(Load, /*IsConstMethod=*/true,
/*IsConstReturn=*/false, /*IsRef=*/false,
AST.UnsignedIntTy, ReturnType);
- addLoadWithStatusFunction(Load, /*IsConst=*/true, ReturnType);
+ addLoadWithStatusFunction(Load, /*IsConstMethod=*/true, ReturnType);
};
AddLoads("Load", AST.UnsignedIntTy);
@@ -2205,14 +2205,14 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDecrementCounterMethod() {
}
BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addLoadWithStatusFunction(
- DeclarationName &Name, bool IsConst, QualType ReturnTy) {
+ DeclarationName &Name, bool IsConstMethod, QualType ReturnTy) {
assert(!Record->isCompleteDefinition() && "record is already complete");
ASTContext &AST = SemaRef.getASTContext();
using PH = BuiltinTypeMethodBuilder::PlaceHolder;
bool NeedsTypedBuiltin = !ReturnTy.isNull();
// The empty QualType is a placeholder. The actual return type is set below.
- BuiltinTypeMethodBuilder MMB(*this, Name, QualType(), IsConst);
+ BuiltinTypeMethodBuilder MMB(*this, Name, QualType(), IsConstMethod);
if (!NeedsTypedBuiltin)
ReturnTy = getHandleElementType();
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
index ed23123016278..cd47f01e9193e 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
@@ -119,7 +119,7 @@ class BuiltinTypeDeclBuilder {
bool IsRef, QualType IndexTy,
QualType ElemTy = QualType());
BuiltinTypeDeclBuilder &
- addLoadWithStatusFunction(DeclarationName &Name, bool IsConst,
+ addLoadWithStatusFunction(DeclarationName &Name, bool IsConstMethod,
QualType ReturnTy = QualType());
BuiltinTypeDeclBuilder &addStoreFunction(DeclarationName &Name, bool IsConst,
QualType ValueType);
>From 4b24c23ed33bc6755ddc1c39bb0a69c4bd79dfbb Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Mon, 27 Apr 2026 15:53:09 -0700
Subject: [PATCH 5/6] remove param for load functions for const method, assume
it is always true
---
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 29 ++++++++++---------
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h | 6 ++--
2 files changed, 19 insertions(+), 16 deletions(-)
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index a9c99654bf9eb..2522637f5417c 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -1393,11 +1393,12 @@ BuiltinTypeDeclBuilder::addArraySubscriptOperators(ResourceDimension Dim) {
DeclarationName Subscript =
AST.DeclarationNames.getCXXOperatorName(OO_Subscript);
- addHandleAccessFunction(Subscript, /*IsConstMethod=*/true,
+ addHandleAccessFunction(Subscript,
/*IsConstReturn=*/true, /*IsRef=*/true, IndexTy);
if (getResourceAttrs().ResourceClass == llvm::dxil::ResourceClass::UAV)
- addHandleAccessFunction(Subscript, /*IsConstMethod=*/false,
- /*IsConstReturn=*/false, /*IsRef=*/true, IndexTy);
+ addHandleAccessFunction(Subscript,
+ /*IsConstReturn=*/false, /*IsRef=*/true, IndexTy,
+ /*ElemTy=*/QualType(), /*IsConstMethod=*/false);
return *this;
}
@@ -1408,11 +1409,11 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addLoadMethods() {
ASTContext &AST = Record->getASTContext();
IdentifierInfo &II = AST.Idents.get("Load", tok::TokenKind::identifier);
DeclarationName Load(&II);
- // TODO: We also need versions with status for CheckAccessFullyMapped.
- addHandleAccessFunction(Load, /*IsConstMethod=*/true,
+
+ addHandleAccessFunction(Load,
/*IsConstReturn=*/false, /*IsRef=*/false,
AST.UnsignedIntTy);
- addLoadWithStatusFunction(Load, /*IsConstMethod=*/true);
+ addLoadWithStatusFunction(Load);
return *this;
}
@@ -1564,10 +1565,10 @@ BuiltinTypeDeclBuilder::addByteAddressBufferLoadMethods() {
IdentifierInfo &II = AST.Idents.get(MethodName, tok::TokenKind::identifier);
DeclarationName Load(&II);
- addHandleAccessFunction(Load, /*IsConstMethod=*/true,
+ addHandleAccessFunction(Load,
/*IsConstReturn=*/false, /*IsRef=*/false,
AST.UnsignedIntTy, ReturnType);
- addLoadWithStatusFunction(Load, /*IsConstMethod=*/true, ReturnType);
+ addLoadWithStatusFunction(Load, ReturnType);
};
AddLoads("Load", AST.UnsignedIntTy);
@@ -2204,15 +2205,17 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDecrementCounterMethod() {
.finalize();
}
-BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addLoadWithStatusFunction(
- DeclarationName &Name, bool IsConstMethod, QualType ReturnTy) {
+BuiltinTypeDeclBuilder &
+BuiltinTypeDeclBuilder::addLoadWithStatusFunction(DeclarationName &Name,
+ QualType ReturnTy) {
assert(!Record->isCompleteDefinition() && "record is already complete");
ASTContext &AST = SemaRef.getASTContext();
using PH = BuiltinTypeMethodBuilder::PlaceHolder;
bool NeedsTypedBuiltin = !ReturnTy.isNull();
// The empty QualType is a placeholder. The actual return type is set below.
- BuiltinTypeMethodBuilder MMB(*this, Name, QualType(), IsConstMethod);
+ // All load methods will be const.
+ BuiltinTypeMethodBuilder MMB(*this, Name, QualType(), true);
if (!NeedsTypedBuiltin)
ReturnTy = getHandleElementType();
@@ -2235,8 +2238,8 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addLoadWithStatusFunction(
}
BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleAccessFunction(
- DeclarationName &Name, bool IsConstMethod, bool IsConstReturn, bool IsRef,
- QualType IndexTy, QualType ElemTy) {
+ DeclarationName &Name, bool IsConstReturn, bool IsRef, QualType IndexTy,
+ QualType ElemTy, bool IsConstMethod) {
assert(!Record->isCompleteDefinition() && "record is already complete");
ASTContext &AST = SemaRef.getASTContext();
using PH = BuiltinTypeMethodBuilder::PlaceHolder;
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
index cd47f01e9193e..34e51f5d03794 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
@@ -114,12 +114,12 @@ class BuiltinTypeDeclBuilder {
BuiltinTypeDeclBuilder &addIncrementCounterMethod();
BuiltinTypeDeclBuilder &addDecrementCounterMethod();
BuiltinTypeDeclBuilder &addHandleAccessFunction(DeclarationName &Name,
- bool IsConstMethod,
bool IsConstReturn,
bool IsRef, QualType IndexTy,
- QualType ElemTy = QualType());
+ QualType ElemTy = QualType(),
+ bool IsConstMethod = true);
BuiltinTypeDeclBuilder &
- addLoadWithStatusFunction(DeclarationName &Name, bool IsConstMethod,
+ addLoadWithStatusFunction(DeclarationName &Name,
QualType ReturnTy = QualType());
BuiltinTypeDeclBuilder &addStoreFunction(DeclarationName &Name, bool IsConst,
QualType ValueType);
>From 30696ff645ec7c5520868d85017920262669b8ff Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Mon, 27 Apr 2026 16:58:09 -0700
Subject: [PATCH 6/6] drop redundant method for UAVs
---
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 13 ++++----
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h | 3 +-
clang/test/AST/HLSL/OutArgExpr.hlsl | 5 +--
.../test/AST/HLSL/StructuredBuffers-AST.hlsl | 10 +++---
clang/test/AST/HLSL/TypedBuffers-AST.hlsl | 33 +++++++++----------
.../BasicFeatures/MatrixConstructor.hlsl | 12 +++----
.../builtins/VectorElementStore.hlsl | 2 +-
.../res-array-global-subarray-many.hlsl | 4 +--
.../res-array-global-subarray-one.hlsl | 2 +-
.../resources/res-array-global-unbounded.hlsl | 2 +-
.../resources/res-array-local-multi-dim.hlsl | 8 ++---
.../resources/res-array-local1.hlsl | 6 ++--
.../resources/res-array-local2.hlsl | 8 ++---
.../resources/res-array-local3.hlsl | 6 ++--
.../resources/resources-in-structs-array.hlsl | 8 ++---
.../resources-in-structs-inheritance.hlsl | 10 +++---
.../resources/resources-in-structs.hlsl | 4 +--
.../SemaHLSL/Resources/static_resources.hlsl | 6 ++--
18 files changed, 70 insertions(+), 72 deletions(-)
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index 2522637f5417c..ba8e63f01527a 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -1394,11 +1394,9 @@ BuiltinTypeDeclBuilder::addArraySubscriptOperators(ResourceDimension Dim) {
AST.DeclarationNames.getCXXOperatorName(OO_Subscript);
addHandleAccessFunction(Subscript,
- /*IsConstReturn=*/true, /*IsRef=*/true, IndexTy);
- if (getResourceAttrs().ResourceClass == llvm::dxil::ResourceClass::UAV)
- addHandleAccessFunction(Subscript,
- /*IsConstReturn=*/false, /*IsRef=*/true, IndexTy,
- /*ElemTy=*/QualType(), /*IsConstMethod=*/false);
+ /*IsConstReturn=*/getResourceAttrs().ResourceClass !=
+ llvm::dxil::ResourceClass::UAV,
+ /*IsRef=*/true, IndexTy);
return *this;
}
@@ -2239,14 +2237,15 @@ BuiltinTypeDeclBuilder::addLoadWithStatusFunction(DeclarationName &Name,
BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleAccessFunction(
DeclarationName &Name, bool IsConstReturn, bool IsRef, QualType IndexTy,
- QualType ElemTy, bool IsConstMethod) {
+ QualType ElemTy) {
assert(!Record->isCompleteDefinition() && "record is already complete");
ASTContext &AST = SemaRef.getASTContext();
using PH = BuiltinTypeMethodBuilder::PlaceHolder;
bool NeedsTypedBuiltin = !ElemTy.isNull();
// The empty QualType is a placeholder. The actual return type is set below.
- BuiltinTypeMethodBuilder MMB(*this, Name, QualType(), IsConstMethod);
+ // All access methods are const; none of them rebind the resource handle.
+ BuiltinTypeMethodBuilder MMB(*this, Name, QualType(), true);
if (!NeedsTypedBuiltin)
ElemTy = getHandleElementType();
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
index 34e51f5d03794..e69afd67b2618 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
@@ -116,8 +116,7 @@ class BuiltinTypeDeclBuilder {
BuiltinTypeDeclBuilder &addHandleAccessFunction(DeclarationName &Name,
bool IsConstReturn,
bool IsRef, QualType IndexTy,
- QualType ElemTy = QualType(),
- bool IsConstMethod = true);
+ QualType ElemTy = QualType());
BuiltinTypeDeclBuilder &
addLoadWithStatusFunction(DeclarationName &Name,
QualType ReturnTy = QualType());
diff --git a/clang/test/AST/HLSL/OutArgExpr.hlsl b/clang/test/AST/HLSL/OutArgExpr.hlsl
index 04ce635e721bf..64f5369ed7949 100644
--- a/clang/test/AST/HLSL/OutArgExpr.hlsl
+++ b/clang/test/AST/HLSL/OutArgExpr.hlsl
@@ -32,8 +32,9 @@ void zero(out int Z) { Z = 0; }
// AST-NEXT: HLSLOutArgExpr {{.*}} 'int' lvalue inout
// AST-NEXT: OpaqueValueExpr [[LVOpV:0x[0-9a-fA-F]+]] {{.*}} 'hlsl_device float' lvalue
// AST-NEXT: CXXOperatorCallExpr {{.*}} 'hlsl_device float' lvalue '[]'
-// AST-NEXT: ImplicitCastExpr {{.*}} 'hlsl_device float &(*)(unsigned int)' <FunctionToPointerDecay>
-// AST-NEXT: DeclRefExpr {{.*}} 'hlsl_device float &(unsigned int)' lvalue CXXMethod {{.*}} 'operator[]' 'hlsl_device float &(unsigned int)'
+// AST-NEXT: ImplicitCastExpr {{.*}} 'hlsl_device float &(*)(unsigned int) const' <FunctionToPointerDecay>
+// AST-NEXT: DeclRefExpr {{.*}} 'hlsl_device float &(unsigned int) const' lvalue CXXMethod {{.*}} 'operator[]' 'hlsl_device float &(unsigned int) const'
+// AST-NEXT: ImplicitCastExpr {{.*}} 'const hlsl::RWBuffer<float>' lvalue <NoOp>
// AST-NEXT: DeclRefExpr {{.*}} 'RWBuffer<float>':'hlsl::RWBuffer<float>' lvalue Var {{.*}} 'Buf' 'RWBuffer<float>':'hlsl::RWBuffer<float>'
// AST-NEXT: ImplicitCastExpr {{.*}} 'uint':'unsigned int' <LValueToRValue>
// AST-NEXT: DeclRefExpr {{.*}} 'uint':'unsigned int' lvalue ParmVar {{.*}} 'GI' 'uint':'unsigned int'
diff --git a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
index fa1180fc69983..24dc8b87f9316 100644
--- a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
@@ -12,7 +12,7 @@
//
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \
// RUN: -DRESOURCE=RWStructuredBuffer %s | FileCheck -DRESOURCE=RWStructuredBuffer \
-// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-SUBSCRIPT,CHECK-SUBSCRIPT-UAV,CHECK-COUNTER,CHECK-LOAD,CHECK-COUNTER-HANDLE %s
+// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-SUBSCRIPT-UAV,CHECK-COUNTER,CHECK-LOAD,CHECK-COUNTER-HANDLE %s
//
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \
// RUN: -DRESOURCE=AppendStructuredBuffer %s | FileCheck -DRESOURCE=AppendStructuredBuffer \
@@ -36,7 +36,7 @@
//
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \
// RUN: -DRESOURCE=RasterizerOrderedStructuredBuffer %s | FileCheck -DRESOURCE=RasterizerOrderedStructuredBuffer \
-// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-ROV,CHECK-SUBSCRIPT,CHECK-SUBSCRIPT-UAV,CHECK-LOAD,CHECK-COUNTER-HANDLE %s
+// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-ROV,CHECK-SUBSCRIPT-UAV,CHECK-LOAD,CHECK-COUNTER-HANDLE %s
// This test tests two different AST generations for each structured buffer.
// The "EMPTY" test mode verifies the AST generated by forward declaration
@@ -288,7 +288,7 @@ RESOURCE<float> Buffer;
// CHECK-SUBSCRIPT-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-SUBSCRIPT-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
-// CHECK-SUBSCRIPT-UAV: CXXMethodDecl {{.*}} operator[] 'hlsl_device element_type &(unsigned int)'
+// CHECK-SUBSCRIPT-UAV: CXXMethodDecl {{.*}} operator[] 'hlsl_device element_type &(unsigned int) const'
// CHECK-SUBSCRIPT-UAV-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
// CHECK-SUBSCRIPT-UAV-NEXT: CompoundStmt
// CHECK-SUBSCRIPT-UAV-NEXT: ReturnStmt
@@ -301,12 +301,12 @@ RESOURCE<float> Buffer;
// CHECK-SUBSCRIPT-UAV-SAME{LITERAL}: [[hlsl::raw_buffer]]
// CHECK-SUBSCRIPT-UAV-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
// CHECK-SUBSCRIPT-UAV-SAME: ' lvalue .__handle {{.*}}
-// CHECK-SUBSCRIPT-UAV-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-SUBSCRIPT-UAV-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-SUBSCRIPT-UAV-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-SUBSCRIPT-UAV-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl {{.*}} operator[] 'const hlsl_device element_type &(unsigned int) const'
-// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl {{.*}} operator[] 'hlsl_device element_type &(unsigned int)'
+// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl {{.*}} operator[] 'hlsl_device element_type &(unsigned int) const'
// Load method
diff --git a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
index c27b7360ee81c..855c2958a0ce3 100644
--- a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
@@ -162,24 +162,23 @@ RESOURCE<float> Buffer;
// Subscript operators
-// CHECK: CXXMethodDecl {{.*}} operator[] 'const hlsl_device element_type &(unsigned int) const'
-// CHECK-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
-// CHECK-NEXT: CompoundStmt
-// CHECK-NEXT: ReturnStmt
-// CHECK-NEXT: UnaryOperator {{.*}} 'hlsl_device element_type' lvalue prefix '*' cannot overflow
-// CHECK-NEXT: CStyleCastExpr {{.*}} 'hlsl_device element_type *'
-// CHECK-NEXT: CallExpr
-// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept'
-// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
-// CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
+// CHECK-SRV: CXXMethodDecl {{.*}} operator[] 'const hlsl_device element_type &(unsigned int) const'
+// CHECK-SRV-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
+// CHECK-SRV-NEXT: CompoundStmt
+// CHECK-SRV-NEXT: ReturnStmt
+// CHECK-SRV-NEXT: UnaryOperator {{.*}} 'hlsl_device element_type' lvalue prefix '*' cannot overflow
+// CHECK-SRV-NEXT: CStyleCastExpr {{.*}} 'hlsl_device element_type *'
+// CHECK-SRV-NEXT: CallExpr
+// CHECK-SRV-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept'
+// CHECK-SRV-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
-// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
-// CHECK-SAME: ' lvalue .__handle {{.*}}
-// CHECK-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
-// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Index' 'unsigned int'
-// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
+// CHECK-SRV-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SRV-SAME: ' lvalue .__handle {{.*}}
+// CHECK-SRV-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-SRV-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Index' 'unsigned int'
+// CHECK-SRV-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
-// CHECK-UAV: CXXMethodDecl {{.*}} operator[] 'hlsl_device element_type &(unsigned int)'
+// CHECK-UAV: CXXMethodDecl {{.*}} operator[] 'hlsl_device element_type &(unsigned int) const'
// CHECK-UAV-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
// CHECK-UAV-NEXT: CompoundStmt
// CHECK-UAV-NEXT: ReturnStmt
@@ -191,7 +190,7 @@ RESOURCE<float> Buffer;
// CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
// CHECK-UAV-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
// CHECK-UAV-SAME: ' lvalue .__handle {{.*}}
-// CHECK-UAV-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-UAV-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-UAV-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-UAV-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
diff --git a/clang/test/CodeGenHLSL/BasicFeatures/MatrixConstructor.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/MatrixConstructor.hlsl
index 467fb38673d95..7f5f42e63e9db 100644
--- a/clang/test/CodeGenHLSL/BasicFeatures/MatrixConstructor.hlsl
+++ b/clang/test/CodeGenHLSL/BasicFeatures/MatrixConstructor.hlsl
@@ -24,12 +24,12 @@ RWStructuredBuffer<float> In;
// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <6 x float> @_Z5case2v(
// CHECK-SAME: ) #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
-// CHECK-NEXT: [[CALL:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN4hlsl18RWStructuredBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(8) @_ZL2In, i32 noundef 0) #[[ATTR4:[0-9]+]]
-// CHECK-NEXT: [[CALL1:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN4hlsl18RWStructuredBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(8) @_ZL2In, i32 noundef 1) #[[ATTR4]]
-// CHECK-NEXT: [[CALL2:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN4hlsl18RWStructuredBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(8) @_ZL2In, i32 noundef 2) #[[ATTR4]]
-// CHECK-NEXT: [[CALL3:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN4hlsl18RWStructuredBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(8) @_ZL2In, i32 noundef 3) #[[ATTR4]]
-// CHECK-NEXT: [[CALL4:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN4hlsl18RWStructuredBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(8) @_ZL2In, i32 noundef 4) #[[ATTR4]]
-// CHECK-NEXT: [[CALL5:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN4hlsl18RWStructuredBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(8) @_ZL2In, i32 noundef 5) #[[ATTR4]]
+// CHECK-NEXT: [[CALL:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZNK4hlsl18RWStructuredBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(8) @_ZL2In, i32 noundef 0) #[[ATTR4:[0-9]+]]
+// CHECK-NEXT: [[CALL1:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZNK4hlsl18RWStructuredBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(8) @_ZL2In, i32 noundef 1) #[[ATTR4]]
+// CHECK-NEXT: [[CALL2:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZNK4hlsl18RWStructuredBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(8) @_ZL2In, i32 noundef 2) #[[ATTR4]]
+// CHECK-NEXT: [[CALL3:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZNK4hlsl18RWStructuredBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(8) @_ZL2In, i32 noundef 3) #[[ATTR4]]
+// CHECK-NEXT: [[CALL4:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZNK4hlsl18RWStructuredBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(8) @_ZL2In, i32 noundef 4) #[[ATTR4]]
+// CHECK-NEXT: [[CALL5:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZNK4hlsl18RWStructuredBufferIfEixEj(ptr noundef nonnull align 4 dereferenceable(8) @_ZL2In, i32 noundef 5) #[[ATTR4]]
// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[CALL]], align 4
// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <6 x float> poison, float [[TMP0]], i32 0
// CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[CALL1]], align 4
diff --git a/clang/test/CodeGenHLSL/builtins/VectorElementStore.hlsl b/clang/test/CodeGenHLSL/builtins/VectorElementStore.hlsl
index e0c3aa54aaeba..eaec0f1a95de8 100644
--- a/clang/test/CodeGenHLSL/builtins/VectorElementStore.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/VectorElementStore.hlsl
@@ -30,7 +30,7 @@ bool3 test_bool(uint Idx) {
// Test resource vector element store for float.
// CHECK: [[VAL:%.*]] = load float, ptr %Val.addr, align 4
-// CHECK: [[RES_PTR:%.*]] = call {{.*}} ptr @_ZN4hlsl18RWStructuredBufferIDv4_fEixEj(ptr {{.*}} @_ZL3Buf, i32 noundef 0)
+// CHECK: [[RES_PTR:%.*]] = call {{.*}} ptr @_ZNK4hlsl18RWStructuredBufferIDv4_fEixEj(ptr {{.*}} @_ZL3Buf, i32 noundef 0)
// CHECK: [[IDX:%.*]] = load i32, ptr %Idx.addr, align 4
// CHECK: [[PTR:%.*]] = getelementptr <4 x float>, ptr [[RES_PTR]], i32 0, i32 [[IDX]]
// CHECK: store float [[VAL]], ptr [[PTR]], align 4
diff --git a/clang/test/CodeGenHLSL/resources/res-array-global-subarray-many.hlsl b/clang/test/CodeGenHLSL/resources/res-array-global-subarray-many.hlsl
index 036feec39f1dd..e482e660a0e80 100644
--- a/clang/test/CodeGenHLSL/resources/res-array-global-subarray-many.hlsl
+++ b/clang/test/CodeGenHLSL/resources/res-array-global-subarray-many.hlsl
@@ -12,7 +12,7 @@ RWStructuredBuffer<float> Out;
float foo(RWBuffer<float> Arr[3][2]) {
// CHECK-NEXT: %[[Arr_1_Ptr:.*]] = getelementptr inbounds [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %Arr, i32 0, i32 1
// CHECK-NEXT: %[[Arr_1_0_Ptr:.*]] = getelementptr inbounds [2 x %"class.hlsl::RWBuffer"], ptr %[[Arr_1_Ptr]], i32 0, i32 0
-// CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int)(ptr {{.*}} %[[Arr_1_0_Ptr]], i32 noundef 0)
+// CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int) const(ptr {{.*}} %[[Arr_1_0_Ptr]], i32 noundef 0)
// CHECK-NEXT: %[[Value:.*]] = load float, ptr %[[BufPtr]], align 4
// CHECK-NEXT: ret float %[[Value]]
return Arr[1][0][0];
@@ -70,7 +70,7 @@ void main(uint GI : SV_GroupThreadID) {
// CHECK: %[[Ptr_Sub_2:.*]] = getelementptr inbounds [3 x [2 x %"class.hlsl::RWBuffer"]], ptr %Sub, i32 0, i32 2
// CHECK: %[[Ptr_Sub_2_1:.*]] = getelementptr inbounds [2 x %"class.hlsl::RWBuffer"], ptr %[[Ptr_Sub_2]], i32 0, i32 1
-// CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int)(ptr {{.*}} %[[Ptr_Sub_2_1]], i32 noundef 0)
+// CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int) const(ptr {{.*}} %[[Ptr_Sub_2_1]], i32 noundef 0)
// CHECK-NEXT: %[[Sub_2_1_0_Value:.*]] = load float, ptr %[[BufPtr]], align 4
// CHECK-NEXT: store float %[[Sub_2_1_0_Value]], ptr %a, align 4
float a = Sub[2][1][0];
diff --git a/clang/test/CodeGenHLSL/resources/res-array-global-subarray-one.hlsl b/clang/test/CodeGenHLSL/resources/res-array-global-subarray-one.hlsl
index bbd48b7ddea52..f196d87ff1a26 100644
--- a/clang/test/CodeGenHLSL/resources/res-array-global-subarray-one.hlsl
+++ b/clang/test/CodeGenHLSL/resources/res-array-global-subarray-one.hlsl
@@ -37,7 +37,7 @@ void main(uint GI : SV_GroupThreadID) {
RWBuffer<float> Sub[2] = A[3];
// CHECK: %[[Ptr_Sub_1:.*]] = getelementptr inbounds [2 x %"class.hlsl::RWBuffer"], ptr %Sub, i32 0, i32 1
-// CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int)(ptr {{.*}} %[[Ptr_Sub_1]], i32 noundef 0)
+// CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int) const(ptr {{.*}} %[[Ptr_Sub_1]], i32 noundef 0)
// CHECK-NEXT: %[[Sub_1_0_Value:.*]] = load float, ptr %[[BufPtr]], align 4
// CHECK-NEXT: store float %[[Sub_1_0_Value]], ptr %a, align 4
float a = Sub[1][0];
diff --git a/clang/test/CodeGenHLSL/resources/res-array-global-unbounded.hlsl b/clang/test/CodeGenHLSL/resources/res-array-global-unbounded.hlsl
index 66bf71b3b0a35..b123e31a2bbe1 100644
--- a/clang/test/CodeGenHLSL/resources/res-array-global-unbounded.hlsl
+++ b/clang/test/CodeGenHLSL/resources/res-array-global-unbounded.hlsl
@@ -31,7 +31,7 @@ void main(uint GI : SV_GroupIndex) {
// CHECK: @hlsl::RWBuffer<float>::__createFromBinding(unsigned int, unsigned int, int, unsigned int, char const*)
// CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer.0") align {{(4|8)}} %[[Tmp0]],
// CHECK-SAME: i32 noundef 10, i32 noundef 1, i32 noundef 0, i32 noundef 100, ptr noundef @A.str)
- // CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr{{.*}} @hlsl::RWBuffer<float>::operator[](unsigned int)(ptr {{.*}} %[[Tmp0]], i32 noundef 0)
+ // CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr{{.*}} @hlsl::RWBuffer<float>::operator[](unsigned int) const(ptr {{.*}} %[[Tmp0]], i32 noundef 0)
// CHECK-NEXT: %[[Value1:.*]] = load float, ptr{{.*}} %[[BufPtr]], align 4
// CHECK-NEXT: store float %[[Value1]], ptr %a, align 4
float a = A[100][0];
diff --git a/clang/test/CodeGenHLSL/resources/res-array-local-multi-dim.hlsl b/clang/test/CodeGenHLSL/resources/res-array-local-multi-dim.hlsl
index 92dba219f2295..242c6388d9c2e 100644
--- a/clang/test/CodeGenHLSL/resources/res-array-local-multi-dim.hlsl
+++ b/clang/test/CodeGenHLSL/resources/res-array-local-multi-dim.hlsl
@@ -11,15 +11,15 @@ RWBuffer<float> A : register(u10);
RWBuffer<float> B : register(u20);
RWStructuredBuffer<float> Out;
-// NOTE: _ZN4hlsl8RWBufferIfEixEj is the subscript operator for RWBuffer<float> and
-// _ZN4hlsl18RWStructuredBufferIfEixEj is the subscript operator for RWStructuredBuffer<float>
+// NOTE: _ZNK4hlsl8RWBufferIfEixEj is the subscript operator for RWBuffer<float> and
+// _ZNK4hlsl18RWStructuredBufferIfEixEj is the subscript operator for RWStructuredBuffer<float>
// CHECK: define {{.*}} float @_Z3fooA2_A2_N4hlsl8RWBufferIfEE(ptr noundef byval([2 x [2 x %"class.hlsl::RWBuffer"]]) align 4 %Arr)
// CHECK-NEXT: entry:
float foo(RWBuffer<float> Arr[2][2]) {
// CHECK-NEXT: %[[Arr_1_Ptr:.*]] = getelementptr inbounds [2 x [2 x %"class.hlsl::RWBuffer"]], ptr %Arr, i32 0, i32 1
// CHECK-NEXT: %[[Arr_1_1_Ptr:.*]] = getelementptr inbounds [2 x %"class.hlsl::RWBuffer"], ptr %[[Arr_1_Ptr]], i32 0, i32 1
-// CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr @_ZN4hlsl8RWBufferIfEixEj(ptr {{.*}} %[[Arr_1_1_Ptr]], i32 noundef 0)
+// CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr @_ZNK4hlsl8RWBufferIfEixEj(ptr {{.*}} %[[Arr_1_1_Ptr]], i32 noundef 0)
// CHECK-NEXT: %[[Value:.*]] = load float, ptr %[[BufPtr]], align 4
// CHECK-NEXT: ret float %[[Value]]
return Arr[1][1][0];
@@ -58,7 +58,7 @@ void main() {
// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[agg_tmp]], ptr align 4 %L, i32 16, i1 false)
// CHECK-NEXT: %[[ReturnedValue:.*]] = call {{.*}}float @_Z3fooA2_A2_N4hlsl8RWBufferIfEE(ptr noundef byval([2 x [2 x %"class.hlsl::RWBuffer"]]) align 4 %[[agg_tmp]])
-// CHECK-NEXT: %[[OutBufPtr:.*]] = call {{.*}} ptr @_ZN4hlsl18RWStructuredBufferIfEixEj(ptr {{.*}} @_ZL3Out, i32 noundef 0)
+// CHECK-NEXT: %[[OutBufPtr:.*]] = call {{.*}} ptr @_ZNK4hlsl18RWStructuredBufferIfEixEj(ptr {{.*}} @_ZL3Out, i32 noundef 0)
// CHECK-NEXT: store float %[[ReturnedValue]], ptr %[[OutBufPtr]], align 4
// CHECK-NEXT: ret void
Out[0] = foo(L);
diff --git a/clang/test/CodeGenHLSL/resources/res-array-local1.hlsl b/clang/test/CodeGenHLSL/resources/res-array-local1.hlsl
index 9e31f4f150c52..3240bd3e67333 100644
--- a/clang/test/CodeGenHLSL/resources/res-array-local1.hlsl
+++ b/clang/test/CodeGenHLSL/resources/res-array-local1.hlsl
@@ -46,16 +46,16 @@ void main() {
// CHECK: call {{.*}} @_ZN4hlsl8RWBufferIfEaSERKS1_(ptr {{.*}} %[[Ptr3]], ptr {{.*}} @_ZL1C)
Second[2] = C;
- // NOTE: _ZN4hlsl8RWBufferIfEixEj is the subscript operator for RWBuffer<float>
+ // NOTE: _ZNK4hlsl8RWBufferIfEixEj is the subscript operator for RWBuffer<float>
// get First[1][0] value
// CHECK: %[[First_1_Ptr:.*]] = getelementptr inbounds [3 x %"class.hlsl::RWBuffer"], ptr %First, i32 0, i32 1
-// CHECK: %[[BufPtr1:.*]] = call {{.*}} ptr @_ZN4hlsl8RWBufferIfEixEj(ptr {{.*}} %[[First_1_Ptr]], i32 noundef 0)
+// CHECK: %[[BufPtr1:.*]] = call {{.*}} ptr @_ZNK4hlsl8RWBufferIfEixEj(ptr {{.*}} %[[First_1_Ptr]], i32 noundef 0)
// CHECK: %[[Value1:.*]] = load float, ptr %[[BufPtr1]], align 4
// get Second[2][0] value
// CHECK: %[[Second_2_Ptr:.*]] = getelementptr inbounds [4 x %"class.hlsl::RWBuffer"], ptr %Second, i32 0, i32 2
-// CHECK: %[[BufPtr2:.*]] = call {{.*}} ptr @_ZN4hlsl8RWBufferIfEixEj(ptr {{.*}} %[[Second_2_Ptr]], i32 noundef 0)
+// CHECK: %[[BufPtr2:.*]] = call {{.*}} ptr @_ZNK4hlsl8RWBufferIfEixEj(ptr {{.*}} %[[Second_2_Ptr]], i32 noundef 0)
// CHECK: %[[Value2:.*]] = load float, ptr %[[BufPtr2]], align 4
// add them
diff --git a/clang/test/CodeGenHLSL/resources/res-array-local2.hlsl b/clang/test/CodeGenHLSL/resources/res-array-local2.hlsl
index 4a02b9f8ced45..ffed362887426 100644
--- a/clang/test/CodeGenHLSL/resources/res-array-local2.hlsl
+++ b/clang/test/CodeGenHLSL/resources/res-array-local2.hlsl
@@ -8,14 +8,14 @@
RWBuffer<float> A[3] : register(u0);
RWStructuredBuffer<float> Out : register(u0);
-// NOTE: _ZN4hlsl8RWBufferIfEixEj is the subscript operator for RWBuffer<float> and
-// _ZN4hlsl18RWStructuredBufferIfEixEj is the subscript operator for RWStructuredBuffer<float>
+// NOTE: _ZNK4hlsl8RWBufferIfEixEj is the subscript operator for RWBuffer<float> and
+// _ZNK4hlsl18RWStructuredBufferIfEixEj is the subscript operator for RWStructuredBuffer<float>
// CHECK: define {{.*}} float @_Z3fooA3_N4hlsl8RWBufferIfEE(ptr noundef byval([3 x %"class.hlsl::RWBuffer"]) align 4 %LocalA)
// CHECK-NEXT: entry:
float foo(RWBuffer<float> LocalA[3]) {
// CHECK-NEXT: %[[LocalA_2_Ptr:.*]] = getelementptr inbounds [3 x %"class.hlsl::RWBuffer"], ptr %LocalA, i32 0, i32 2
-// CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr @_ZN4hlsl8RWBufferIfEixEj(ptr {{.*}} %[[LocalA_2_Ptr]], i32 noundef 0)
+// CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr @_ZNK4hlsl8RWBufferIfEixEj(ptr {{.*}} %[[LocalA_2_Ptr]], i32 noundef 0)
// CHECK-NEXT: %[[Value:.*]] = load float, ptr %[[BufPtr]], align 4
// CHECK-NEXT: ret float %[[Value]]
return LocalA[2][0];
@@ -30,7 +30,7 @@ void main() {
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[Tmp]], ptr align 4 @_ZL1A, i32 12, i1 false)
// CHECK-NEXT: %[[ReturnedValue:.*]] = call {{.*}} float @_Z3fooA3_N4hlsl8RWBufferIfEE(ptr noundef byval([3 x %"class.hlsl::RWBuffer"]) align 4 %[[Tmp]])
-// CHECK-NEXT: %[[OutBufPtr:.*]] = call {{.*}} ptr @_ZN4hlsl18RWStructuredBufferIfEixEj(ptr {{.*}} @_ZL3Out, i32 noundef 0)
+// CHECK-NEXT: %[[OutBufPtr:.*]] = call {{.*}} ptr @_ZNK4hlsl18RWStructuredBufferIfEixEj(ptr {{.*}} @_ZL3Out, i32 noundef 0)
// CHECK-NEXT: store float %[[ReturnedValue]], ptr %[[OutBufPtr]], align 4
// CHECK-NEXT: ret void
Out[0] = foo(A);
diff --git a/clang/test/CodeGenHLSL/resources/res-array-local3.hlsl b/clang/test/CodeGenHLSL/resources/res-array-local3.hlsl
index 21ca3f4a98f99..a2b297261eb6a 100644
--- a/clang/test/CodeGenHLSL/resources/res-array-local3.hlsl
+++ b/clang/test/CodeGenHLSL/resources/res-array-local3.hlsl
@@ -23,12 +23,12 @@ void SomeFn(RWBuffer<int> B[2], uint Idx, int Val0) {
// CHECK-NEXT: call {{.*}} @_ZN4hlsl8RWBufferIiEaSERKS1_(ptr {{.*}} %[[B_0_Ptr]], ptr {{.*}} @_ZL1Y)
B[0] = Y;
-// NOTE: _ZN4hlsl8RWBufferIiEixEj is the subscript operator for RWBuffer<int>
+// NOTE: _ZNK4hlsl8RWBufferIiEixEj is the subscript operator for RWBuffer<int>
// CHECK-NEXT: %[[Val0:.*]] = load i32, ptr %[[Val0_addr]], align 4
// CHECK-NEXT: %[[B_0_Ptr:.*]] = getelementptr inbounds [2 x %"class.hlsl::RWBuffer"], ptr %B, i32 0, i32 0
// CHECK-NEXT: %[[Idx:.*]] = load i32, ptr %[[Idx_addr]], align 4
-// CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr @_ZN4hlsl8RWBufferIiEixEj(ptr {{.*}} %[[B_0_Ptr]], i32 noundef %[[Idx]])
+// CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr @_ZNK4hlsl8RWBufferIiEixEj(ptr {{.*}} %[[B_0_Ptr]], i32 noundef %[[Idx]])
// CHECK-NEXT: store i32 %[[Val0]], ptr %[[BufPtr]], align 4
B[0][Idx] = Val0;
}
@@ -56,7 +56,7 @@ void main(uint GI : SV_GroupIndex) {
// CHECK-NEXT: %[[A_0_Ptr:.*]] = getelementptr inbounds [2 x %"class.hlsl::RWBuffer"], ptr %A, i32 0, i32 0
// CHECK-NEXT: %[[GI:.*]] = load i32, ptr %[[GI_addr]], align 4
-// CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr @_ZN4hlsl8RWBufferIiEixEj(ptr {{.*}} %[[A_0_Ptr]], i32 noundef %[[GI]])
+// CHECK-NEXT: %[[BufPtr:.*]] = call {{.*}} ptr @_ZNK4hlsl8RWBufferIiEixEj(ptr {{.*}} %[[A_0_Ptr]], i32 noundef %[[GI]])
// CHECK-NEXT: store i32 2, ptr %[[BufPtr]], align 4
A[0][GI] = 2;
}
diff --git a/clang/test/CodeGenHLSL/resources/resources-in-structs-array.hlsl b/clang/test/CodeGenHLSL/resources/resources-in-structs-array.hlsl
index e57cceaaf2a01..0f8e4b9582758 100644
--- a/clang/test/CodeGenHLSL/resources/resources-in-structs-array.hlsl
+++ b/clang/test/CodeGenHLSL/resources/resources-in-structs-array.hlsl
@@ -79,22 +79,22 @@ B bArray[2];
void main() {
// CHECK-NEXT: %[[TMP:.*]] = alloca %"class.hlsl::RWStructuredBuffer", align 4
-// CHECK-NEXT: %[[PTR1:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int)(ptr {{.*}} @arrayOfA.1.Buf, i32 noundef 0)
+// CHECK-NEXT: %[[PTR1:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int) const(ptr {{.*}} @arrayOfA.1.Buf, i32 noundef 0)
// CHECK-NEXT: store float 1.000000e+00, ptr %[[PTR1]]
arrayOfA[1].Buf[0] = 1.0f;
-// CHECK-NEXT: %[[PTR2:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int)(ptr {{.*}} @gArray.1.multiArray.1.0.Buf, i32 noundef 0)
+// CHECK-NEXT: %[[PTR2:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int) const(ptr {{.*}} @gArray.1.multiArray.1.0.Buf, i32 noundef 0)
// CHECK-NEXT: store float 2.000000e+00, ptr %[[PTR2]]
gArray[1].multiArray[1][0].Buf[0] = 2.0f;
-// CHECK-NEXT: %[[PTR3:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int)(ptr {{.*}} @gArray.0.multiArray.0.1.Buf, i32 noundef 0)
+// CHECK-NEXT: %[[PTR3:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int) const(ptr {{.*}} @gArray.0.multiArray.0.1.Buf, i32 noundef 0)
// CHECK-NEXT: store float 3.000000e+00, ptr %[[PTR3]]
gArray[0].multiArray[0][1].Buf[0] = 3.0f;
// Resource array access - first create the resource from binding, then access the element and store to it.
// CHECK-NEXT: call void @hlsl::RWStructuredBuffer<float>::__createFromImplicitBindingWithImplicitCounter(unsigned int, unsigned int, int, unsigned int, char const*, unsigned int)
// CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWStructuredBuffer") align 4 %[[TMP]], i32 noundef 2, i32 noundef 0, i32 noundef 2, i32 noundef 1, ptr noundef @bArray.1.ManyBufs.str, i32 noundef 3)
-// CHECK-NEXT: %[[PTR4:.*]] = call {{.*}} ptr @hlsl::RWStructuredBuffer<float>::operator[](unsigned int)(ptr {{.*}} %[[TMP]], i32 noundef 0)
+// CHECK-NEXT: %[[PTR4:.*]] = call {{.*}} ptr @hlsl::RWStructuredBuffer<float>::operator[](unsigned int) const(ptr {{.*}} %[[TMP]], i32 noundef 0)
// CHECK-NEXT: store float 4.000000e+00, ptr %[[PTR4]], align 4
bArray[1].ManyBufs[1][0] = 4.0f;
}
diff --git a/clang/test/CodeGenHLSL/resources/resources-in-structs-inheritance.hlsl b/clang/test/CodeGenHLSL/resources/resources-in-structs-inheritance.hlsl
index 5b5b8270f8e86..877fd1ca496f5 100644
--- a/clang/test/CodeGenHLSL/resources/resources-in-structs-inheritance.hlsl
+++ b/clang/test/CodeGenHLSL/resources/resources-in-structs-inheritance.hlsl
@@ -97,19 +97,19 @@ void main() {
// CHECK-NEXT: %[[TMP:.*]] = alloca %"class.hlsl::StructuredBuffer.0"
// CHECK-NEXT: %a = alloca float
-// CHECK-NEXT: %[[PTR1:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int)(ptr {{.*}} @"_ZL8c.A::Buf", i32 noundef 0)
+// CHECK-NEXT: %[[PTR1:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int) const(ptr {{.*}} @"_ZL8c.A::Buf", i32 noundef 0)
// CHECK-NEXT: store float 0x3FF3AE1480000000, ptr %[[PTR1:]]
c.Buf[0] = 1.230f;
-// CHECK-NEXT: %[[PTR2:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int)(ptr {{.*}} @c.Buf2, i32 noundef 0)
+// CHECK-NEXT: %[[PTR2:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int) const(ptr {{.*}} @c.Buf2, i32 noundef 0)
// CHECK-NEXT: store float 0x4002B851E0000000, ptr %[[PTR2:]]
c.Buf2[0] = 2.340f;
-// CHECK-NEXT: %[[PTR3:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int)(ptr {{.*}} @"_ZL8d.A::Buf", i32 noundef 0)
+// CHECK-NEXT: %[[PTR3:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int) const(ptr {{.*}} @"_ZL8d.A::Buf", i32 noundef 0)
// CHECK-NEXT: store float 0x400B9999A0000000, ptr %[[PTR3:]]
d.Buf[0] = 3.450f;
-// CHECK-NEXT: %[[PTR4:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int)(ptr {{.*}} @d.A.Buf, i32 noundef 0)
+// CHECK-NEXT: %[[PTR4:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int) const(ptr {{.*}} @d.A.Buf, i32 noundef 0)
// CHECK-NEXT: store float 0x40123D70A0000000, ptr %[[PTR4:]]
d.A.Buf[0] = 4.560f;
@@ -126,7 +126,7 @@ void main() {
// CHECK-NEXT: store float %[[VAL2]], ptr %a
float a = f.SrvBuf[0];
-// CHECK: [[PTR7:.*]]= call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int)(ptr {{.*}} @f.a.Buf, i32 noundef 0)
+// CHECK: [[PTR7:.*]]= call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int) const(ptr {{.*}} @f.a.Buf, i32 noundef 0)
// CHECK: store float %{{.*}}, ptr %call6
f.a.Buf[0] = (float)i + a;
}
diff --git a/clang/test/CodeGenHLSL/resources/resources-in-structs.hlsl b/clang/test/CodeGenHLSL/resources/resources-in-structs.hlsl
index 3502f1d7eca66..96d3d94903fea 100644
--- a/clang/test/CodeGenHLSL/resources/resources-in-structs.hlsl
+++ b/clang/test/CodeGenHLSL/resources/resources-in-structs.hlsl
@@ -59,14 +59,14 @@ C c : register(t10);
[numthreads(1, 1, 1)]
void main() {
-// CHECK: %[[PTR1:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int)(ptr noundef nonnull align 4 dereferenceable(4) @a.Buf, i32 noundef 0)
+// CHECK: %[[PTR1:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int) const(ptr noundef nonnull align 4 dereferenceable(4) @a.Buf, i32 noundef 0)
// CHECK-NEXT: store float 0x3FF3AE1480000000, ptr %[[PTR1]], align 4
a.Buf[0] = 1.230f;
// Resource array access - first create the resource from binding, then access the element and store to it.
// CHECK: call void @hlsl::RWBuffer<float>::__createFromBinding(unsigned int, unsigned int, int, unsigned int, char const*)
// CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer") align 4 %[[TMP1]], i32 noundef 2, i32 noundef 0, i32 noundef 10, i32 noundef 5, ptr noundef @[[bBufsStr]])
-// CHECK-NEXT: %[[PTR2:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int)(ptr {{.*}} %[[TMP1]], i32 noundef 0)
+// CHECK-NEXT: %[[PTR2:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int) const(ptr {{.*}} %[[TMP1]], i32 noundef 0)
// CHECK-NEXT: store float 0x40123D70A0000000, ptr %[[PTR2]], align 4
b.Bufs[5][0] = 4.56f;
diff --git a/clang/test/SemaHLSL/Resources/static_resources.hlsl b/clang/test/SemaHLSL/Resources/static_resources.hlsl
index 0ea64a3cb14a5..219457fd0eafb 100644
--- a/clang/test/SemaHLSL/Resources/static_resources.hlsl
+++ b/clang/test/SemaHLSL/Resources/static_resources.hlsl
@@ -99,15 +99,15 @@ void main() {
// CHECK-SAME: (ptr {{.*}} getelementptr inbounds nuw (i8, ptr @StaticArray, i32 4), ptr {{.*}} @One)
StaticLocal[0] = 123;
-// CHECK-NEXT: %[[PTR0:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int)(ptr {{.*}} @main()::StaticLocal, i32 noundef 0)
+// CHECK-NEXT: %[[PTR0:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int) const(ptr {{.*}} @main()::StaticLocal, i32 noundef 0)
// CHECK-NEXT: store float 1.230000e+02, ptr %[[PTR0]]
StaticOne[1] = 456;
-// CHECK-NEXT: %[[PTR1:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int)(ptr {{.*}}) @StaticOne, i32 noundef 1)
+// CHECK-NEXT: %[[PTR1:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int) const(ptr {{.*}}) @StaticOne, i32 noundef 1)
// CHECK-NEXT: store float 4.560000e+02, ptr %[[PTR1]], align 4
StaticArray[1][2] = 789;
-// CHECK-NEXT: %[[PTR2:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int)
+// CHECK-NEXT: %[[PTR2:.*]] = call {{.*}} ptr @hlsl::RWBuffer<float>::operator[](unsigned int) const
// CHECK-SAME: (ptr {{.*}} getelementptr inbounds nuw (i8, ptr @StaticArray, i32 4), i32 noundef 2)
// CHECK-NEXT: store float 7.890000e+02, ptr %[[PTR2]], align 4
More information about the cfe-commits
mailing list