=?utf-8?q?João?= Saffran <[email protected]>, =?utf-8?q?João?= Saffran <[email protected]>,Joao Saffran <[email protected]>,Joao Saffran <[email protected]>,Joao Saffran <[email protected]>,Joao Saffran <[email protected]>,Joao Saffran <[email protected]>,Joao Saffran <[email protected]>,Joao Saffran <[email protected]>,Joao Saffran <[email protected]>,Joao Saffran <[email protected]> Message-ID: In-Reply-To: <llvm.org/llvm/llvm-project/pull/[email protected]>
https://github.com/joaosaffran updated https://github.com/llvm/llvm-project/pull/186022 >From d006275d84ee06058da410d0bc7236a41340a2e2 Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Wed, 11 Mar 2026 14:17:16 -0700 Subject: [PATCH 01/12] replace -1 with 0 when targeting spirv --- clang/lib/CodeGen/CGHLSLRuntime.cpp | 10 +++--- .../resources/res-array-global-unbounded.hlsl | 17 ++++++---- .../SPIRV/hlsl-resources/unbounded-arr.ll | 33 +++++++++++++++++++ 3 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-resources/unbounded-arr.ll diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index b695d016c0524..04daa5e611412 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -117,11 +117,13 @@ static const ValueDecl *getArrayDecl(const ArraySubscriptExpr *ASE) { } // Get the total size of the array, or -1 if the array is unbounded. -static int getTotalArraySize(ASTContext &AST, const clang::Type *Ty) { +static int getTotalArraySize(ASTContext &AST, llvm::Triple::ArchType Arch, + const clang::Type *Ty) { Ty = Ty->getUnqualifiedDesugaredType(); assert(Ty->isArrayType() && "expected array type"); if (Ty->isIncompleteArrayType()) - return -1; + // Spirv uses 0 to represent unbounded arrays. + return Arch == llvm::Triple::ArchType::dxil ? -1 : 0; return AST.getConstantArrayElementCount(cast<ConstantArrayType>(Ty)); } @@ -1280,7 +1282,7 @@ std::optional<LValue> CGHLSLRuntime::emitResourceArraySubscriptExpr( // Calculate total array size (= range size). llvm::Value *Range = llvm::ConstantInt::getSigned( - CGM.IntTy, getTotalArraySize(AST, ResArrayTy)); + CGM.IntTy, getTotalArraySize(AST, getArch(), ResArrayTy)); // If the result of the subscript operation is a single resource, call the // constructor. @@ -1345,7 +1347,7 @@ bool CGHLSLRuntime::emitResourceArrayCopy(LValue &LHS, Expr *RHSExpr, AggValueSlot::DoesNotOverlap); // Create Value for index and total array size (= range size). - int Size = getTotalArraySize(AST, ResArrayTy); + int Size = getTotalArraySize(AST, getArch(), ResArrayTy); llvm::Value *Zero = llvm::ConstantInt::get(CGM.IntTy, 0); llvm::Value *Range = llvm::ConstantInt::get(CGM.IntTy, Size); diff --git a/clang/test/CodeGenHLSL/resources/res-array-global-unbounded.hlsl b/clang/test/CodeGenHLSL/resources/res-array-global-unbounded.hlsl index 6756a26bfc124..7d5b9626db138 100644 --- a/clang/test/CodeGenHLSL/resources/res-array-global-unbounded.hlsl +++ b/clang/test/CodeGenHLSL/resources/res-array-global-unbounded.hlsl @@ -30,14 +30,15 @@ void main(uint GI : SV_GroupIndex) { // and explicit binding (u10, space1) // 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 -1, i32 noundef 100, ptr noundef @A.str) + // DXIL-SAME: i32 noundef 10, i32 noundef 1, i32 noundef -1, i32 noundef 100, ptr noundef @A.str) + // SPV-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: %[[Value1:.*]] = load float, ptr{{.*}} %[[BufPtr]], align 4 // CHECK-NEXT: store float %[[Value1]], ptr %a, align 4 float a = A[100][0]; // Make sure B[2][3] is translated to a local RWBuffer<int>[4] array where each array element - // is initialized by a constructor call with range -1 and index 52-55 and implicit binding + // is initialized by a constructor call with range 0 and index 52-55 and implicit binding // (space 0, order_id 0) // The first index is calculated from the array dimensions (unbounded x 5 x 4) and indices (2, 3) // as 2 * 5 * 4 + 3 * 4 = 52 and the following indices are sequential. @@ -45,22 +46,26 @@ void main(uint GI : SV_GroupIndex) { // CHECK-NEXT: %[[Ptr_Tmp2_0:.*]] = getelementptr [4 x %"class.hlsl::RWBuffer"], ptr %[[Tmp2]], i32 0, i32 0 // CHECK-NEXT: call void @hlsl::RWBuffer<int>::__createFromImplicitBinding(unsigned int, unsigned int, int, unsigned int, char const*) // CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer") align {{(4|8)}} %[[Ptr_Tmp2_0]], - // CHECK-SAME: i32 noundef 0, i32 noundef 0, i32 noundef -1, i32 noundef 52, ptr noundef @[[BufB]]) + // DXIL-SAME: i32 noundef 0, i32 noundef 0, i32 noundef -1, i32 noundef 52, ptr noundef @[[BufB]]) + // SPV-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 0, i32 noundef 52, ptr noundef @[[BufB]]) // CHECK-NEXT: %[[Ptr_Tmp2_1:.*]] = getelementptr [4 x %"class.hlsl::RWBuffer"], ptr %[[Tmp2]], i32 0, i32 1 // CHECK-NEXT: call void @hlsl::RWBuffer<int>::__createFromImplicitBinding(unsigned int, unsigned int, int, unsigned int, char const*) // CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer") align {{(4|8)}} %[[Ptr_Tmp2_1]], - // CHECK-SAME: i32 noundef 0, i32 noundef 0, i32 noundef -1, i32 noundef 53, ptr noundef @[[BufB]]) + // DXIL-SAME: i32 noundef 0, i32 noundef 0, i32 noundef -1, i32 noundef 53, ptr noundef @[[BufB]]) + // SPV-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 0, i32 noundef 53, ptr noundef @[[BufB]]) // CHECK-NEXT: %[[Ptr_Tmp2_2:.*]] = getelementptr [4 x %"class.hlsl::RWBuffer"], ptr %[[Tmp2]], i32 0, i32 2 // CHECK-NEXT: call void @hlsl::RWBuffer<int>::__createFromImplicitBinding(unsigned int, unsigned int, int, unsigned int, char const*) // CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer") align {{(4|8)}} %[[Ptr_Tmp2_2]], - // CHECK-SAME: i32 noundef 0, i32 noundef 0, i32 noundef -1, i32 noundef 54, ptr noundef @[[BufB]]) + // DXIL-SAME: i32 noundef 0, i32 noundef 0, i32 noundef -1, i32 noundef 54, ptr noundef @[[BufB]]) + // SPV-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 0, i32 noundef 54, ptr noundef @[[BufB]]) // CHECK-NEXT: %[[Ptr_Tmp2_3:.*]] = getelementptr [4 x %"class.hlsl::RWBuffer"], ptr %[[Tmp2]], i32 0, i32 3 // CHECK-NEXT: call void @hlsl::RWBuffer<int>::__createFromImplicitBinding(unsigned int, unsigned int, int, unsigned int, char const*) // CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer") align {{(4|8)}} %[[Ptr_Tmp2_3]], - // CHECK-SAME: i32 noundef 0, i32 noundef 0, i32 noundef -1, i32 noundef 55, ptr noundef @[[BufB]]) + // DXIL-SAME: i32 noundef 0, i32 noundef 0, i32 noundef -1, i32 noundef 55, ptr noundef @[[BufB]]) + // SPV-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 0, i32 noundef 55, ptr noundef @[[BufB]]) // DXIL-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[Tmp1]], ptr align 4 %[[Tmp2]], i32 16, i1 false) // SPV-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[Tmp1]], ptr align 8 %[[Tmp2]], i64 32, i1 false) diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/unbounded-arr.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/unbounded-arr.ll new file mode 100644 index 0000000000000..4f1388a3605fc --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/unbounded-arr.ll @@ -0,0 +1,33 @@ +; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv1.6-vulkan1.3-library %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.6-vulkan1.3-library %s -o - -filetype=obj | spirv-val %} + +; CHECK-DAG: %[[int32:[0-9]+]] = OpTypeInt 32 0 +; CHECK-DAG: %[[rwbuffer:[0-9]+]] = OpTypeImage %[[int32]] Buffer 2 0 0 2 R32i +; CHECK-DAG: OpTypeRuntimeArray %[[rwbuffer]] + +; This IR was emmited from the following HLSL code: +; [[vk::binding(0)]] +; RWBuffer<int> Buf[] : register(u0); +; +; [numthreads(4,2,1)] +; void main(uint GI : SV_GroupIndex) { +; Buf[0][0] = 0; +; } + + + [email protected] = private unnamed_addr constant [4 x i8] c"Buf\00", align 1 + +; Function Attrs: convergent noinline norecurse +define void @main() #0 { +entry: + %2 = call target("spirv.SignedImage", i32, 5, 2, 0, 0, 2, 24) @llvm.spv.resource.handlefrombinding.tspirv.SignedImage_i32_5_2_0_0_2_24t(i32 0, i32 0, i32 0, i32 0, ptr @Buf.str) + %3 = call noundef align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.SignedImage_i32_5_2_0_0_2_24t(target("spirv.SignedImage", i32, 5, 2, 0, 0, 2, 24) %2, i32 0) + store i32 0, ptr addrspace(11) %3, align 4 + ret void +} +; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none) +declare target("spirv.SignedImage", i32, 5, 2, 0, 0, 2, 24) @llvm.spv.resource.handlefrombinding.tspirv.SignedImage_i32_5_2_0_0_2_24t(i32, i32, i32, i32, ptr) #3 + +attributes #0 = { convergent noinline norecurse "hlsl.numthreads"="4,2,1" "hlsl.shader"="compute" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #3 = { nocallback nofree nosync nounwind willreturn memory(none) } >From 201e771e6b272ada59047d17a9988465eff510c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Saffran?= <[email protected]> Date: Wed, 11 Mar 2026 16:00:52 -0700 Subject: [PATCH 02/12] add missing capability emission --- llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index 3e50e4a0e8c80..5e966df6372db 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -6012,6 +6012,10 @@ bool SPIRVInstructionSelector::loadHandleBeforePosition( SC = GR.getPointerStorageClass(ResType); } + if (ResType->getOpcode() == SPIRV::OpTypeImage && ArraySize == 0) + MIRBuilder.buildInstr(SPIRV::OpCapability) + .addImm(SPIRV::Capability::RuntimeDescriptorArrayEXT); + Register VarReg = buildPointerToResource(SPIRVTypeInst(VarType), SC, Set, Binding, ArraySize, IndexReg, Name, MIRBuilder); >From ba10d096c7f6e4341697e67f131293a71de82bc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Saffran?= <[email protected]> Date: Wed, 11 Mar 2026 19:16:32 -0700 Subject: [PATCH 03/12] check if the capabily is being emited --- llvm/test/CodeGen/SPIRV/hlsl-resources/unbounded-arr.ll | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/unbounded-arr.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/unbounded-arr.ll index 4f1388a3605fc..8be0da57a797b 100644 --- a/llvm/test/CodeGen/SPIRV/hlsl-resources/unbounded-arr.ll +++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/unbounded-arr.ll @@ -1,6 +1,7 @@ ; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv1.6-vulkan1.3-library %s -o - | FileCheck %s ; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.6-vulkan1.3-library %s -o - -filetype=obj | spirv-val %} +; CHECK-DAG: OpCapability RuntimeDescriptorArrayEXT ; CHECK-DAG: %[[int32:[0-9]+]] = OpTypeInt 32 0 ; CHECK-DAG: %[[rwbuffer:[0-9]+]] = OpTypeImage %[[int32]] Buffer 2 0 0 2 R32i ; CHECK-DAG: OpTypeRuntimeArray %[[rwbuffer]] >From 1bc576f1bd7e95c9dc8fcae7b7cb5d2f16830c2c Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Thu, 12 Mar 2026 13:01:54 -0700 Subject: [PATCH 04/12] use 0 instead of -1 --- clang/lib/CodeGen/CGHLSLRuntime.cpp | 10 ++++------ .../resources/res-array-global-unbounded.hlsl | 15 +++++---------- llvm/docs/DirectX/DXILResources.rst | 2 +- llvm/lib/Analysis/DXILResource.cpp | 4 +++- .../CodeGen/DirectX/Binding/binding-overlap-6.ll | 2 +- llvm/test/CodeGen/DirectX/CreateHandle.ll | 2 +- .../CodeGen/DirectX/CreateHandleFromBinding.ll | 2 +- .../test/CodeGen/DirectX/Metadata/srv_metadata.ll | 4 ++-- .../test/CodeGen/DirectX/Metadata/uav_metadata.ll | 4 ++-- .../DirectX/ResourceBindingAnalysisTests.cpp | 2 +- 10 files changed, 21 insertions(+), 26 deletions(-) diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index 04daa5e611412..c0f68e29e7e5d 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -117,13 +117,11 @@ static const ValueDecl *getArrayDecl(const ArraySubscriptExpr *ASE) { } // Get the total size of the array, or -1 if the array is unbounded. -static int getTotalArraySize(ASTContext &AST, llvm::Triple::ArchType Arch, - const clang::Type *Ty) { +static int getTotalArraySize(ASTContext &AST, const clang::Type *Ty) { Ty = Ty->getUnqualifiedDesugaredType(); assert(Ty->isArrayType() && "expected array type"); if (Ty->isIncompleteArrayType()) - // Spirv uses 0 to represent unbounded arrays. - return Arch == llvm::Triple::ArchType::dxil ? -1 : 0; + return 0; return AST.getConstantArrayElementCount(cast<ConstantArrayType>(Ty)); } @@ -1282,7 +1280,7 @@ std::optional<LValue> CGHLSLRuntime::emitResourceArraySubscriptExpr( // Calculate total array size (= range size). llvm::Value *Range = llvm::ConstantInt::getSigned( - CGM.IntTy, getTotalArraySize(AST, getArch(), ResArrayTy)); + CGM.IntTy, getTotalArraySize(AST, ResArrayTy)); // If the result of the subscript operation is a single resource, call the // constructor. @@ -1347,7 +1345,7 @@ bool CGHLSLRuntime::emitResourceArrayCopy(LValue &LHS, Expr *RHSExpr, AggValueSlot::DoesNotOverlap); // Create Value for index and total array size (= range size). - int Size = getTotalArraySize(AST, getArch(), ResArrayTy); + int Size = getTotalArraySize(AST, ResArrayTy); llvm::Value *Zero = llvm::ConstantInt::get(CGM.IntTy, 0); llvm::Value *Range = llvm::ConstantInt::get(CGM.IntTy, Size); diff --git a/clang/test/CodeGenHLSL/resources/res-array-global-unbounded.hlsl b/clang/test/CodeGenHLSL/resources/res-array-global-unbounded.hlsl index 7d5b9626db138..66bf71b3b0a35 100644 --- a/clang/test/CodeGenHLSL/resources/res-array-global-unbounded.hlsl +++ b/clang/test/CodeGenHLSL/resources/res-array-global-unbounded.hlsl @@ -30,8 +30,7 @@ void main(uint GI : SV_GroupIndex) { // and explicit binding (u10, space1) // 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]], - // DXIL-SAME: i32 noundef 10, i32 noundef 1, i32 noundef -1, i32 noundef 100, ptr noundef @A.str) - // SPV-SAME: i32 noundef 10, i32 noundef 1, i32 noundef 0, i32 noundef 100, ptr noundef @A.str) + // 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: %[[Value1:.*]] = load float, ptr{{.*}} %[[BufPtr]], align 4 // CHECK-NEXT: store float %[[Value1]], ptr %a, align 4 @@ -46,26 +45,22 @@ void main(uint GI : SV_GroupIndex) { // CHECK-NEXT: %[[Ptr_Tmp2_0:.*]] = getelementptr [4 x %"class.hlsl::RWBuffer"], ptr %[[Tmp2]], i32 0, i32 0 // CHECK-NEXT: call void @hlsl::RWBuffer<int>::__createFromImplicitBinding(unsigned int, unsigned int, int, unsigned int, char const*) // CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer") align {{(4|8)}} %[[Ptr_Tmp2_0]], - // DXIL-SAME: i32 noundef 0, i32 noundef 0, i32 noundef -1, i32 noundef 52, ptr noundef @[[BufB]]) - // SPV-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 0, i32 noundef 52, ptr noundef @[[BufB]]) + // CHECK-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 0, i32 noundef 52, ptr noundef @[[BufB]]) // CHECK-NEXT: %[[Ptr_Tmp2_1:.*]] = getelementptr [4 x %"class.hlsl::RWBuffer"], ptr %[[Tmp2]], i32 0, i32 1 // CHECK-NEXT: call void @hlsl::RWBuffer<int>::__createFromImplicitBinding(unsigned int, unsigned int, int, unsigned int, char const*) // CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer") align {{(4|8)}} %[[Ptr_Tmp2_1]], - // DXIL-SAME: i32 noundef 0, i32 noundef 0, i32 noundef -1, i32 noundef 53, ptr noundef @[[BufB]]) - // SPV-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 0, i32 noundef 53, ptr noundef @[[BufB]]) + // CHECK-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 0, i32 noundef 53, ptr noundef @[[BufB]]) // CHECK-NEXT: %[[Ptr_Tmp2_2:.*]] = getelementptr [4 x %"class.hlsl::RWBuffer"], ptr %[[Tmp2]], i32 0, i32 2 // CHECK-NEXT: call void @hlsl::RWBuffer<int>::__createFromImplicitBinding(unsigned int, unsigned int, int, unsigned int, char const*) // CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer") align {{(4|8)}} %[[Ptr_Tmp2_2]], - // DXIL-SAME: i32 noundef 0, i32 noundef 0, i32 noundef -1, i32 noundef 54, ptr noundef @[[BufB]]) - // SPV-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 0, i32 noundef 54, ptr noundef @[[BufB]]) + // CHECK-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 0, i32 noundef 54, ptr noundef @[[BufB]]) // CHECK-NEXT: %[[Ptr_Tmp2_3:.*]] = getelementptr [4 x %"class.hlsl::RWBuffer"], ptr %[[Tmp2]], i32 0, i32 3 // CHECK-NEXT: call void @hlsl::RWBuffer<int>::__createFromImplicitBinding(unsigned int, unsigned int, int, unsigned int, char const*) // CHECK-SAME: (ptr {{.*}} sret(%"class.hlsl::RWBuffer") align {{(4|8)}} %[[Ptr_Tmp2_3]], - // DXIL-SAME: i32 noundef 0, i32 noundef 0, i32 noundef -1, i32 noundef 55, ptr noundef @[[BufB]]) - // SPV-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 0, i32 noundef 55, ptr noundef @[[BufB]]) + // CHECK-SAME: i32 noundef 0, i32 noundef 0, i32 noundef 0, i32 noundef 55, ptr noundef @[[BufB]]) // DXIL-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[Tmp1]], ptr align 4 %[[Tmp2]], i32 16, i1 false) // SPV-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[Tmp1]], ptr align 8 %[[Tmp2]], i64 32, i1 false) diff --git a/llvm/docs/DirectX/DXILResources.rst b/llvm/docs/DirectX/DXILResources.rst index d1841dfe0afcb..4471a248108cf 100644 --- a/llvm/docs/DirectX/DXILResources.rst +++ b/llvm/docs/DirectX/DXILResources.rst @@ -191,7 +191,7 @@ arguments. * - ``%range_size`` - 3 - ``i32`` - - Range size of the binding, where ``UINT32_MAX (~0U)`` denotes an unbounded range. + - Range size of the binding, where ``0`` denotes an unbounded range. * - ``%index`` - 4 - ``i32`` diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp index f01a6f80161a5..1a93de2f055dc 100644 --- a/llvm/lib/Analysis/DXILResource.cpp +++ b/llvm/lib/Analysis/DXILResource.cpp @@ -891,7 +891,7 @@ void DXILResourceMap::populateResourceInfos(Module &M, ResourceInfo RI = ResourceInfo{/*RecordID=*/0, Space, LowerBound, - Size, HandleTy, Name}; + Size == 0 ? ~0U : Size, HandleTy, Name}; CIToInfos.emplace_back(CI, RI, RTI); } @@ -1071,6 +1071,8 @@ void DXILResourceBindingInfo::populate(Module &M, DXILResourceTypeMap &DRTM) { cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue(); Value *Name = CI->getArgOperand(4); + if(Size == 0) + Size = ~0U; // UINT32_MAX (~0U) size means unbounded resource array; // upper bound register overflow should be detected in Sema assert((Size == UINT32_MAX || diff --git a/llvm/test/CodeGen/DirectX/Binding/binding-overlap-6.ll b/llvm/test/CodeGen/DirectX/Binding/binding-overlap-6.ll index a58e85b4159f1..dcca4feb31dae 100644 --- a/llvm/test/CodeGen/DirectX/Binding/binding-overlap-6.ll +++ b/llvm/test/CodeGen/DirectX/Binding/binding-overlap-6.ll @@ -18,7 +18,7 @@ target triple = "dxil-pc-shadermodel6.3-library" define void @test_overlapping() { entry: %h1 = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 3, i32 0, ptr @A.str) - %h2 = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 4, i32 -1, i32 0, ptr @B.str) + %h2 = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 4, i32 0, i32 0, ptr @B.str) %h3 = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 17, i32 1, i32 0, ptr @C.str) ret void } diff --git a/llvm/test/CodeGen/DirectX/CreateHandle.ll b/llvm/test/CodeGen/DirectX/CreateHandle.ll index 6cca501bb2568..d92f4d369ad94 100644 --- a/llvm/test/CodeGen/DirectX/CreateHandle.ll +++ b/llvm/test/CodeGen/DirectX/CreateHandle.ll @@ -61,7 +61,7 @@ define void @test_buffers() { %typed3_ix = call i32 @some_val() %typed3 = call target("dx.TypedBuffer", <4 x float>, 0, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_v4f32_0_0_0t( - i32 0, i32 7, i32 -1, i32 %typed3_ix, ptr null) + i32 0, i32 7, i32 0, i32 %typed3_ix, ptr null) ; CHECK: %[[IX:.*]] = add i32 %typed3_ix, 7 ; CHECK: call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 0, i32 %[[IX]], i1 false) #[[#ATTR]] diff --git a/llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll b/llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll index 671fcef281314..561193508297b 100644 --- a/llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll +++ b/llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll @@ -66,7 +66,7 @@ define void @test_bindings() { %typed3_ix = call i32 @some_val() %typed3 = call target("dx.TypedBuffer", <4 x float>, 0, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_v4f32_0_0_0t( - i32 0, i32 7, i32 -1, i32 %typed3_ix, ptr null) + i32 0, i32 7, i32 0, i32 %typed3_ix, ptr null) ; CHECK: %[[IX:.*]] = add i32 %typed3_ix, 7 ; CHECK: [[BUF5:%.*]] = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 7, i32 -1, i32 0, i8 0 }, i32 %[[IX]], i1 false) #[[#ATTR]] ; CHECK: call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle [[BUF5]], %dx.types.ResourceProperties { i32 10, i32 1033 }) #[[#ATTR]] diff --git a/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll b/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll index 0062f90326490..ea8f418d4dada 100644 --- a/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll +++ b/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll @@ -80,9 +80,9 @@ define void @test() #0 { ; Buffer<double> C1 = Array[10]; ; Buffer<double> C2 = Array[20]; %Array2_10_h = call target("dx.TypedBuffer", double, 0, 0, 0) - @llvm.dx.resource.handlefrombinding(i32 4, i32 2, i32 -1, i32 10, ptr @Array2.str) + @llvm.dx.resource.handlefrombinding(i32 4, i32 2, i32 0, i32 10, ptr @Array2.str) %Array2_20_h = call target("dx.TypedBuffer", double, 0, 0, 0) - @llvm.dx.resource.handlefrombinding(i32 4, i32 2, i32 -1, i32 20, ptr @Array2.str) + @llvm.dx.resource.handlefrombinding(i32 4, i32 2, i32 0, i32 20, ptr @Array2.str) ret void } diff --git a/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll b/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll index d377a528abca1..0f7d56fb1261e 100644 --- a/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll +++ b/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll @@ -92,9 +92,9 @@ define void @test() #0 { ; RWBuffer<double> C1 = Array[10]; ; RWBuffer<double> C2 = Array[20]; %Array2_10_h = call target("dx.TypedBuffer", double, 1, 0, 0) - @llvm.dx.resource.handlefrombinding(i32 4, i32 2, i32 -1, i32 10, ptr @Array2.str) + @llvm.dx.resource.handlefrombinding(i32 4, i32 2, i32 0, i32 10, ptr @Array2.str) %Array2_20_h = call target("dx.TypedBuffer", double, 1, 0, 0) - @llvm.dx.resource.handlefrombinding(i32 4, i32 2, i32 -1, i32 20, ptr @Array2.str) + @llvm.dx.resource.handlefrombinding(i32 4, i32 2, i32 0, i32 20, ptr @Array2.str) ; Same buffer type as Nine - should have the same type in metadata ; RWBuffer<double> Ten : register(u2); diff --git a/llvm/unittests/Target/DirectX/ResourceBindingAnalysisTests.cpp b/llvm/unittests/Target/DirectX/ResourceBindingAnalysisTests.cpp index 3211c2c702aab..65e1beadf3e38 100644 --- a/llvm/unittests/Target/DirectX/ResourceBindingAnalysisTests.cpp +++ b/llvm/unittests/Target/DirectX/ResourceBindingAnalysisTests.cpp @@ -71,7 +71,7 @@ TEST_F(ResourceBindingAnalysisTest, TestOverlap) { StringRef Assembly = R"( define void @main() { entry: - %handleA = call target("dx.RawBuffer", float, 0, 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 0, i32 -1, i32 100, ptr null) + %handleA = call target("dx.RawBuffer", float, 0, 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 0, i32 0, i32 100, ptr null) %handleB = call target("dx.RawBuffer", float, 0, 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 4, i32 1, i32 0, ptr null) ret void } >From 1d7543ac2935bbb6357c75f55194d7f82a9e81f8 Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Thu, 12 Mar 2026 13:07:09 -0700 Subject: [PATCH 05/12] format --- llvm/lib/Analysis/DXILResource.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp index 1a93de2f055dc..122288ef1e87f 100644 --- a/llvm/lib/Analysis/DXILResource.cpp +++ b/llvm/lib/Analysis/DXILResource.cpp @@ -889,9 +889,9 @@ void DXILResourceMap::populateResourceInfos(Module &M, cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue(); StringRef Name = getResourceNameFromBindingCall(CI); - ResourceInfo RI = - ResourceInfo{/*RecordID=*/0, Space, LowerBound, - Size == 0 ? ~0U : Size, HandleTy, Name}; + ResourceInfo RI = ResourceInfo{ + /*RecordID=*/0, Space, LowerBound, + Size == 0 ? ~0U : Size, HandleTy, Name}; CIToInfos.emplace_back(CI, RI, RTI); } @@ -1071,7 +1071,7 @@ void DXILResourceBindingInfo::populate(Module &M, DXILResourceTypeMap &DRTM) { cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue(); Value *Name = CI->getArgOperand(4); - if(Size == 0) + if (Size == 0) Size = ~0U; // UINT32_MAX (~0U) size means unbounded resource array; // upper bound register overflow should be detected in Sema >From d055cc681ae7e9be4aecb00e9924f7b9e66d0c9c Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Thu, 12 Mar 2026 19:47:33 -0700 Subject: [PATCH 06/12] save ongoing work --- llvm/include/llvm/Analysis/DXILResource.h | 6 ++++-- llvm/lib/Analysis/DXILResource.cpp | 10 ++++------ llvm/lib/Target/DirectX/DXContainerGlobals.cpp | 4 ++-- llvm/test/CodeGen/DirectX/Binding/binding-overlap-7.ll | 2 +- .../test/CodeGen/DirectX/ContainerData/PSVResources.ll | 2 +- llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h index f38de81d76a2c..6e345ea2fb611 100644 --- a/llvm/include/llvm/Analysis/DXILResource.h +++ b/llvm/include/llvm/Analysis/DXILResource.h @@ -384,8 +384,10 @@ class ResourceInfo { return !(*this == RHS); } bool operator<(const ResourceBinding &RHS) const { - return std::tie(RecordID, Space, LowerBound, Size) < - std::tie(RHS.RecordID, RHS.Space, RHS.LowerBound, RHS.Size); + const uint32_t ThisSizeFixed = Size == 0 ? UINT32_MAX : Size; + const uint32_t RHSSizeFixed = Size == 0 ? UINT32_MAX : Size; + return std::tie(RecordID, Space, LowerBound, ThisSizeFixed) < + std::tie(RHS.RecordID, RHS.Space, RHS.LowerBound, RHSSizeFixed); } bool overlapsWith(const ResourceBinding &RHS) const { if (Space != RHS.Space) diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp index 122288ef1e87f..5f342ba80481b 100644 --- a/llvm/lib/Analysis/DXILResource.cpp +++ b/llvm/lib/Analysis/DXILResource.cpp @@ -891,7 +891,7 @@ void DXILResourceMap::populateResourceInfos(Module &M, ResourceInfo RI = ResourceInfo{ /*RecordID=*/0, Space, LowerBound, - Size == 0 ? ~0U : Size, HandleTy, Name}; + Size == 0 , HandleTy, Name}; CIToInfos.emplace_back(CI, RI, RTI); } @@ -1071,16 +1071,14 @@ void DXILResourceBindingInfo::populate(Module &M, DXILResourceTypeMap &DRTM) { cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue(); Value *Name = CI->getArgOperand(4); - if (Size == 0) - Size = ~0U; - // UINT32_MAX (~0U) size means unbounded resource array; + // 0 size means unbounded resource array; // upper bound register overflow should be detected in Sema - assert((Size == UINT32_MAX || + assert((Size == 0 || (uint64_t)LowerBound + (uint64_t)Size - 1ULL <= (uint64_t)UINT32_MAX) && "upper bound register overflow"); uint32_t UpperBound = - Size == UINT32_MAX ? UINT32_MAX : LowerBound + Size - 1; + Size == 0 ? UINT32_MAX : LowerBound + Size - 1; Builder.trackBinding(RTI.getResourceClass(), Space, LowerBound, UpperBound, Name); } diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp index 95577dd668e1e..5fdc498db57e1 100644 --- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp +++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp @@ -194,10 +194,10 @@ void DXContainerGlobals::addResourcesForPSV(Module &M, PSVRuntimeInfo &PSV) { BindInfo.Type = Type; BindInfo.LowerBound = Binding.LowerBound; assert( - (Binding.Size == UINT32_MAX || + (Binding.Size == 0 || (uint64_t)Binding.LowerBound + Binding.Size - 1 <= UINT32_MAX) && "Resource range is too large"); - BindInfo.UpperBound = (Binding.Size == UINT32_MAX) + BindInfo.UpperBound = (Binding.Size == 0) ? UINT32_MAX : Binding.LowerBound + Binding.Size - 1; BindInfo.Space = Binding.Space; diff --git a/llvm/test/CodeGen/DirectX/Binding/binding-overlap-7.ll b/llvm/test/CodeGen/DirectX/Binding/binding-overlap-7.ll index 9c52d6ed3486a..151c770489826 100644 --- a/llvm/test/CodeGen/DirectX/Binding/binding-overlap-7.ll +++ b/llvm/test/CodeGen/DirectX/Binding/binding-overlap-7.ll @@ -29,7 +29,7 @@ entry: ; Buffer<double> C[] : register(t2, space4); %h2 = call target("dx.TypedBuffer", double, 0, 0, 0) - @llvm.dx.resource.handlefrombinding(i32 4, i32 2, i32 -1, i32 10, ptr @C.str) + @llvm.dx.resource.handlefrombinding(i32 4, i32 2, i32 0, i32 10, ptr @C.str) ret void } diff --git a/llvm/test/CodeGen/DirectX/ContainerData/PSVResources.ll b/llvm/test/CodeGen/DirectX/ContainerData/PSVResources.ll index d792078b8cbb7..ea3a02245c1cc 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/PSVResources.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/PSVResources.ll @@ -105,7 +105,7 @@ define void @main() #0 { ; CHECK: UsedByAtomic64: false ; RWBuffer<float4> Buf = BufferArray[100]; %uav3 = call target("dx.TypedBuffer", <4 x float>, 1, 0, 0) - @llvm.dx.resource.handlefrombinding(i32 5, i32 10, i32 -1, i32 100, ptr null) + @llvm.dx.resource.handlefrombinding(i32 5, i32 10, i32 0, i32 100, ptr null) ret void } diff --git a/llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll b/llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll index 561193508297b..482df78617c95 100644 --- a/llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll +++ b/llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll @@ -68,7 +68,7 @@ define void @test_bindings() { @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_v4f32_0_0_0t( i32 0, i32 7, i32 0, i32 %typed3_ix, ptr null) ; CHECK: %[[IX:.*]] = add i32 %typed3_ix, 7 - ; CHECK: [[BUF5:%.*]] = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 7, i32 -1, i32 0, i8 0 }, i32 %[[IX]], i1 false) #[[#ATTR]] + ; CHECK: [[BUF5:%.*]] = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 7, i32 0, i32 0, i8 0 }, i32 %[[IX]], i1 false) #[[#ATTR]] ; CHECK: call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle [[BUF5]], %dx.types.ResourceProperties { i32 10, i32 1033 }) #[[#ATTR]] ; cbuffer cb0 : register(b0) { int4 i; float4 f; } >From 962c03bc36eaeb40213ca80bbb4993b8ec8c3229 Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Thu, 12 Mar 2026 19:54:09 -0700 Subject: [PATCH 07/12] fix typo --- llvm/lib/Analysis/DXILResource.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp index 5f342ba80481b..b24bda743ef02 100644 --- a/llvm/lib/Analysis/DXILResource.cpp +++ b/llvm/lib/Analysis/DXILResource.cpp @@ -891,7 +891,7 @@ void DXILResourceMap::populateResourceInfos(Module &M, ResourceInfo RI = ResourceInfo{ /*RecordID=*/0, Space, LowerBound, - Size == 0 , HandleTy, Name}; + Size, HandleTy, Name}; CIToInfos.emplace_back(CI, RI, RTI); } >From ebba1bfe7556438cbba5355075a558db2d2461ec Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Thu, 12 Mar 2026 19:58:56 -0700 Subject: [PATCH 08/12] fix preatty print --- llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp index 9da3bdb8d59b2..12e54ad2cc73e 100644 --- a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp +++ b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp @@ -214,7 +214,7 @@ struct FormatBindingSize void format(llvm::raw_ostream &OS, StringRef Style) override { uint32_t Size = Item.getBinding().Size; - if (Size == std::numeric_limits<uint32_t>::max()) + if (Size == 0) OS << "unbounded"; else OS << Size; >From b5b7338b410c3e4a5723f37b49b27814e8364592 Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Thu, 12 Mar 2026 20:04:16 -0700 Subject: [PATCH 09/12] fix issue --- llvm/include/llvm/Analysis/DXILResource.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h index 6e345ea2fb611..bf1e6adefe412 100644 --- a/llvm/include/llvm/Analysis/DXILResource.h +++ b/llvm/include/llvm/Analysis/DXILResource.h @@ -392,7 +392,7 @@ class ResourceInfo { bool overlapsWith(const ResourceBinding &RHS) const { if (Space != RHS.Space) return false; - if (Size == UINT32_MAX) + if (Size == 0) return LowerBound < RHS.LowerBound; return LowerBound + Size - 1 >= RHS.LowerBound; } >From 47b165da2c5681c9231ee4dd49d1f11f2d2a47fe Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Thu, 12 Mar 2026 20:39:20 -0700 Subject: [PATCH 10/12] pass another test --- llvm/lib/Target/DirectX/DXILOpLowering.cpp | 5 ++--- llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp index 0c0830cc92aa7..794bae8fd3a34 100644 --- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp +++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp @@ -354,9 +354,8 @@ class OpLowerer { // For `CreateHandleFromBinding` we need the upper bound rather than the // size, so we need to be careful about the difference for "unbounded". - uint32_t Unbounded = std::numeric_limits<uint32_t>::max(); - uint32_t UpperBound = Binding.Size == Unbounded - ? Unbounded + uint32_t UpperBound = Binding.Size == 0 + ? std::numeric_limits<uint32_t>::max() : Binding.LowerBound + Binding.Size - 1; Constant *ResBind = OpBuilder.getResBind(Binding.LowerBound, UpperBound, Binding.Space, RC); diff --git a/llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll b/llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll index 482df78617c95..561193508297b 100644 --- a/llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll +++ b/llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll @@ -68,7 +68,7 @@ define void @test_bindings() { @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_v4f32_0_0_0t( i32 0, i32 7, i32 0, i32 %typed3_ix, ptr null) ; CHECK: %[[IX:.*]] = add i32 %typed3_ix, 7 - ; CHECK: [[BUF5:%.*]] = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 7, i32 0, i32 0, i8 0 }, i32 %[[IX]], i1 false) #[[#ATTR]] + ; CHECK: [[BUF5:%.*]] = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 7, i32 -1, i32 0, i8 0 }, i32 %[[IX]], i1 false) #[[#ATTR]] ; CHECK: call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle [[BUF5]], %dx.types.ResourceProperties { i32 10, i32 1033 }) #[[#ATTR]] ; cbuffer cb0 : register(b0) { int4 i; float4 f; } >From 9ff661894f1fdaa586747828713d020ece998c9a Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Mon, 16 Mar 2026 10:34:49 -0700 Subject: [PATCH 11/12] format --- llvm/lib/Analysis/DXILResource.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp index b24bda743ef02..259a7a994b28f 100644 --- a/llvm/lib/Analysis/DXILResource.cpp +++ b/llvm/lib/Analysis/DXILResource.cpp @@ -889,9 +889,9 @@ void DXILResourceMap::populateResourceInfos(Module &M, cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue(); StringRef Name = getResourceNameFromBindingCall(CI); - ResourceInfo RI = ResourceInfo{ - /*RecordID=*/0, Space, LowerBound, - Size, HandleTy, Name}; + ResourceInfo RI = + ResourceInfo{/*RecordID=*/0, Space, LowerBound, + Size, HandleTy, Name}; CIToInfos.emplace_back(CI, RI, RTI); } @@ -1073,12 +1073,10 @@ void DXILResourceBindingInfo::populate(Module &M, DXILResourceTypeMap &DRTM) { // 0 size means unbounded resource array; // upper bound register overflow should be detected in Sema - assert((Size == 0 || - (uint64_t)LowerBound + (uint64_t)Size - 1ULL <= - (uint64_t)UINT32_MAX) && + assert((Size == 0 || (uint64_t)LowerBound + (uint64_t)Size - 1ULL <= + (uint64_t)UINT32_MAX) && "upper bound register overflow"); - uint32_t UpperBound = - Size == 0 ? UINT32_MAX : LowerBound + Size - 1; + uint32_t UpperBound = Size == 0 ? UINT32_MAX : LowerBound + Size - 1; Builder.trackBinding(RTI.getResourceClass(), Space, LowerBound, UpperBound, Name); } >From 4cecb043c45bf09c9ba5e97962ce6f767ab5b70c Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Mon, 16 Mar 2026 11:54:08 -0700 Subject: [PATCH 12/12] fix metadata and simplify < operator --- llvm/include/llvm/Analysis/DXILResource.h | 11 +++++++---- llvm/lib/Analysis/DXILResource.cpp | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h index bf1e6adefe412..0c4ada4aba079 100644 --- a/llvm/include/llvm/Analysis/DXILResource.h +++ b/llvm/include/llvm/Analysis/DXILResource.h @@ -384,10 +384,13 @@ class ResourceInfo { return !(*this == RHS); } bool operator<(const ResourceBinding &RHS) const { - const uint32_t ThisSizeFixed = Size == 0 ? UINT32_MAX : Size; - const uint32_t RHSSizeFixed = Size == 0 ? UINT32_MAX : Size; - return std::tie(RecordID, Space, LowerBound, ThisSizeFixed) < - std::tie(RHS.RecordID, RHS.Space, RHS.LowerBound, RHSSizeFixed); + // a size of 0 indicates unbounded. Adjusting the size to UINT32_MAX + // guarantees a well ordered results. + const bool LHSIsUnbounded = Size == 0; + const bool RHSIsUnbounded = RHS.Size == 0; + return std::tie(RecordID, Space, LowerBound, LHSIsUnbounded, Size) < + std::tie(RHS.RecordID, RHS.Space, RHS.LowerBound, RHSIsUnbounded, + RHS.Size); } bool overlapsWith(const ResourceBinding &RHS) const { if (Space != RHS.Space) diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp index 259a7a994b28f..a427a261d82d3 100644 --- a/llvm/lib/Analysis/DXILResource.cpp +++ b/llvm/lib/Analysis/DXILResource.cpp @@ -692,7 +692,7 @@ MDTuple *ResourceInfo::getAsMetadata(Module &M, MDVals.push_back(MDString::get(Ctx, Name)); MDVals.push_back(getIntMD(Binding.Space)); MDVals.push_back(getIntMD(Binding.LowerBound)); - MDVals.push_back(getIntMD(Binding.Size)); + MDVals.push_back(getIntMD(Binding.Size == 0 ? ~0u : Binding.Size)); if (RTI.isCBuffer()) { MDVals.push_back(getIntMD(RTI.getCBufferSize(DL))); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
