Skip to content

Commit 8d55009

Browse files
committed
[DirectX] Detect resources with identical overlapping binding
This change uses resource name during DXIL resource binding analysis to detect when two (or more) resources have identical overlapping binding. The DXIL resource analysis just detects that there is a problem with the binding and sets the `hasOverlappingBinding` flag. Full error reporting will happen later in DXILPostOptimizationValidation pass (#110723).
1 parent 61c8945 commit 8d55009

File tree

2 files changed

+14
-15
lines changed

2 files changed

+14
-15
lines changed

llvm/lib/Analysis/DXILResource.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -892,10 +892,11 @@ void DXILResourceBindingInfo::populate(Module &M, DXILResourceTypeMap &DRTM) {
892892
uint32_t Space;
893893
uint32_t LowerBound;
894894
uint32_t UpperBound;
895+
Value *Name;
895896
Binding(ResourceClass RC, uint32_t Space, uint32_t LowerBound,
896-
uint32_t UpperBound)
897-
: RC(RC), Space(Space), LowerBound(LowerBound), UpperBound(UpperBound) {
898-
}
897+
uint32_t UpperBound, Value *Name)
898+
: RC(RC), Space(Space), LowerBound(LowerBound), UpperBound(UpperBound),
899+
Name(Name) {}
899900
};
900901
SmallVector<Binding> Bindings;
901902

@@ -920,14 +921,15 @@ void DXILResourceBindingInfo::populate(Module &M, DXILResourceTypeMap &DRTM) {
920921
cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
921922
int32_t Size =
922923
cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
924+
Value *Name = CI->getArgOperand(5);
923925

924926
// negative size means unbounded resource array;
925927
// upper bound register overflow should be detected in Sema
926928
assert((Size < 0 || (unsigned)LowerBound + Size - 1 <= UINT32_MAX) &&
927929
"upper bound register overflow");
928930
uint32_t UpperBound = Size < 0 ? UINT32_MAX : LowerBound + Size - 1;
929931
Bindings.emplace_back(RTI.getResourceClass(), Space, LowerBound,
930-
UpperBound);
932+
UpperBound, Name);
931933
}
932934
break;
933935
}
@@ -946,8 +948,9 @@ void DXILResourceBindingInfo::populate(Module &M, DXILResourceTypeMap &DRTM) {
946948

947949
// remove duplicates
948950
Binding *NewEnd = llvm::unique(Bindings, [](auto &LHS, auto &RHS) {
949-
return std::tie(LHS.RC, LHS.Space, LHS.LowerBound, LHS.UpperBound) ==
950-
std::tie(RHS.RC, RHS.Space, RHS.LowerBound, RHS.UpperBound);
951+
return std::tie(LHS.RC, LHS.Space, LHS.LowerBound, LHS.UpperBound,
952+
LHS.Name) == std::tie(RHS.RC, RHS.Space, RHS.LowerBound,
953+
RHS.UpperBound, RHS.Name);
951954
});
952955
if (NewEnd != Bindings.end())
953956
Bindings.erase(NewEnd);
@@ -987,8 +990,6 @@ void DXILResourceBindingInfo::populate(Module &M, DXILResourceTypeMap &DRTM) {
987990
if (B.UpperBound < UINT32_MAX)
988991
S->FreeRanges.emplace_back(B.UpperBound + 1, UINT32_MAX);
989992
} else {
990-
// FIXME: This only detects overlapping bindings that are not an exact
991-
// match (llvm/llvm-project#110723)
992993
OverlappingBinding = true;
993994
if (B.UpperBound < UINT32_MAX)
994995
LastFreeRange.LowerBound =

llvm/unittests/Target/DirectX/ResourceBindingAnalysisTests.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,6 @@ TEST_F(ResourceBindingAnalysisTest, TestUnboundedAndOverlap) {
167167
// StructuredBuffer<float> C[] : register(t0, space2);
168168
// StructuredBuffer<float> D : register(t4, space2); /* overlapping */
169169
StringRef Assembly = R"(
170-
%__cblayout_CB = type <{ i32 }>
171170
define void @main() {
172171
entry:
173172
%handleA = call target("dx.RawBuffer", float, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 5, i32 -1, i32 10, i1 false, ptr null)
@@ -198,11 +197,12 @@ TEST_F(ResourceBindingAnalysisTest, TestExactOverlap) {
198197
// StructuredBuffer<float> A : register(t5);
199198
// StructuredBuffer<float> B : register(t5);
200199
StringRef Assembly = R"(
201-
%__cblayout_CB = type <{ i32 }>
200+
@A.str = private unnamed_addr constant [2 x i8] c"A\00", align 1
201+
@B.str = private unnamed_addr constant [2 x i8] c"B\00", align 1
202202
define void @main() {
203203
entry:
204-
%handleA = call target("dx.RawBuffer", float, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 5, i32 1, i32 0, i1 false, ptr null)
205-
%handleB = call target("dx.RawBuffer", float, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 5, i32 1, i32 0, i1 false, ptr null)
204+
%handleA = call target("dx.RawBuffer", float, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 5, i32 1, i32 0, i1 false, ptr @A.str)
205+
%handleB = call target("dx.RawBuffer", float, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 5, i32 1, i32 0, i1 false, ptr @B.str)
206206
ret void
207207
}
208208
)";
@@ -213,9 +213,7 @@ define void @main() {
213213
MAM->getResult<DXILResourceBindingAnalysis>(*M);
214214

215215
EXPECT_EQ(false, DRBI.hasImplicitBinding());
216-
// FIXME (XFAIL): detecting overlap of two resource with identical binding
217-
// is not yet supported (llvm/llvm-project#110723).
218-
EXPECT_EQ(false, DRBI.hasOverlappingBinding());
216+
EXPECT_EQ(true, DRBI.hasOverlappingBinding());
219217

220218
DXILResourceBindingInfo::BindingSpaces &SRVSpaces =
221219
DRBI.getBindingSpaces(ResourceClass::SRV);

0 commit comments

Comments
 (0)