Skip to content

Commit f9ae8aa

Browse files
authored
[DirectX] Detect resources with identical overlapping binding (#140645)
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 f20423f commit f9ae8aa

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
@@ -920,10 +920,11 @@ void DXILResourceBindingInfo::populate(Module &M, DXILResourceTypeMap &DRTM) {
920920
uint32_t Space;
921921
uint32_t LowerBound;
922922
uint32_t UpperBound;
923+
Value *Name;
923924
Binding(ResourceClass RC, uint32_t Space, uint32_t LowerBound,
924-
uint32_t UpperBound)
925-
: RC(RC), Space(Space), LowerBound(LowerBound), UpperBound(UpperBound) {
926-
}
925+
uint32_t UpperBound, Value *Name)
926+
: RC(RC), Space(Space), LowerBound(LowerBound), UpperBound(UpperBound),
927+
Name(Name) {}
927928
};
928929
SmallVector<Binding> Bindings;
929930

@@ -948,14 +949,15 @@ void DXILResourceBindingInfo::populate(Module &M, DXILResourceTypeMap &DRTM) {
948949
cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
949950
int32_t Size =
950951
cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
952+
Value *Name = CI->getArgOperand(5);
951953

952954
// negative size means unbounded resource array;
953955
// upper bound register overflow should be detected in Sema
954956
assert((Size < 0 || (unsigned)LowerBound + Size - 1 <= UINT32_MAX) &&
955957
"upper bound register overflow");
956958
uint32_t UpperBound = Size < 0 ? UINT32_MAX : LowerBound + Size - 1;
957959
Bindings.emplace_back(RTI.getResourceClass(), Space, LowerBound,
958-
UpperBound);
960+
UpperBound, Name);
959961
}
960962
break;
961963
}
@@ -974,8 +976,9 @@ void DXILResourceBindingInfo::populate(Module &M, DXILResourceTypeMap &DRTM) {
974976

975977
// remove duplicates
976978
Binding *NewEnd = llvm::unique(Bindings, [](auto &LHS, auto &RHS) {
977-
return std::tie(LHS.RC, LHS.Space, LHS.LowerBound, LHS.UpperBound) ==
978-
std::tie(RHS.RC, RHS.Space, RHS.LowerBound, RHS.UpperBound);
979+
return std::tie(LHS.RC, LHS.Space, LHS.LowerBound, LHS.UpperBound,
980+
LHS.Name) == std::tie(RHS.RC, RHS.Space, RHS.LowerBound,
981+
RHS.UpperBound, RHS.Name);
979982
});
980983
if (NewEnd != Bindings.end())
981984
Bindings.erase(NewEnd);
@@ -1015,8 +1018,6 @@ void DXILResourceBindingInfo::populate(Module &M, DXILResourceTypeMap &DRTM) {
10151018
if (B.UpperBound < UINT32_MAX)
10161019
S->FreeRanges.emplace_back(B.UpperBound + 1, UINT32_MAX);
10171020
} else {
1018-
// FIXME: This only detects overlapping bindings that are not an exact
1019-
// match (llvm/llvm-project#110723)
10201021
OverlappingBinding = true;
10211022
if (B.UpperBound < UINT32_MAX)
10221023
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)