Skip to content

Commit f9df6bc

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 b8dcf53 commit f9df6bc

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)