Skip to content

Commit 8a431c8

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). (cherry picked from commit 8d55009)
1 parent a2ab9ed commit 8a431c8

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

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

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

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