[llvm] [DirectX] Implement DXILResourceBindingAnalysis (PR #137258)
Greg Roth via llvm-commits
llvm-commits at lists.llvm.org
Thu May 8 16:20:51 PDT 2025
================
@@ -0,0 +1,245 @@
+//===- llvm/unittests/Target/DirectX/ResourceBindingAnalysisTests.cpp -----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Analysis/DXILResource.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/Passes/PassBuilder.h"
+#include "llvm/Support/DXILABI.h"
+#include "gtest/gtest.h"
+#include <cstdint>
+
+using namespace llvm;
+using namespace llvm::dxil;
+
+namespace {
+class ResourceBindingAnalysisTest : public testing::Test {
+protected:
+ PassBuilder *PB;
+ ModuleAnalysisManager *MAM;
+ LLVMContext *Context;
+
+ virtual void SetUp() {
+ PB = new PassBuilder();
+ MAM = new ModuleAnalysisManager();
+ Context = new LLVMContext();
+ PB->registerModuleAnalyses(*MAM);
+ MAM->registerPass([&] { return DXILResourceBindingAnalysis(); });
+ }
+
+ std::unique_ptr<Module> parseAsm(StringRef Asm) {
+ SMDiagnostic Error;
+ std::unique_ptr<Module> M = parseAssemblyString(Asm, Error, *Context);
+ EXPECT_TRUE(M) << "Bad assembly?: " << Error.getMessage();
+ return M;
+ }
+
+ virtual void TearDown() {
+ delete PB;
+ delete MAM;
+ delete Context;
+ }
+
+ void checkExpectedSpaceAndFreeRanges(
+ DXILResourceBindingInfo::RegisterSpace &RegSpace, uint32_t ExpSpace,
+ ArrayRef<uint32_t> ExpValues) {
+ EXPECT_EQ(RegSpace.Space, ExpSpace);
+ EXPECT_EQ(RegSpace.FreeRanges.size() * 2, ExpValues.size());
+ unsigned I = 0;
+ for (auto &R : RegSpace.FreeRanges) {
+ EXPECT_EQ(R.LowerBound, ExpValues[I]);
+ EXPECT_EQ(R.UpperBound, ExpValues[I + 1]);
+ I += 2;
+ }
+ }
+};
+
+TEST_F(ResourceBindingAnalysisTest, TestTrivialCase) {
+ // RWBuffer<float> Buf : register(u5);
+ StringRef Assembly = R"(
+define void @main() {
+entry:
+ %handle = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 5, i32 1, i32 0, i1 false)
+ ret void
+}
+ )";
+
+ auto M = parseAsm(Assembly);
+
+ DXILResourceBindingInfo &DRBI =
+ MAM->getResult<DXILResourceBindingAnalysis>(*M);
+
+ EXPECT_EQ(false, DRBI.hasImplicitBinding());
+ EXPECT_EQ(false, DRBI.hasOverlappingBinding());
+
+ // check that UAV has exactly one gap
+ DXILResourceBindingInfo::BindingSpaces &UAVSpaces =
+ DRBI.getBindingSpaces(ResourceClass::UAV);
+ EXPECT_EQ(UAVSpaces.ResClass, ResourceClass::UAV);
+ EXPECT_EQ(UAVSpaces.Spaces.size(), 1u);
+ checkExpectedSpaceAndFreeRanges(UAVSpaces.Spaces[0], 0,
+ {0, 4, 6, UINT32_MAX});
+
+ // check that other kinds of register spaces are all available
+ for (auto RC :
+ {ResourceClass::SRV, ResourceClass::CBuffer, ResourceClass::Sampler}) {
+ DXILResourceBindingInfo::BindingSpaces &Spaces = DRBI.getBindingSpaces(RC);
+ EXPECT_EQ(Spaces.ResClass, RC);
+ EXPECT_EQ(Spaces.Spaces.size(), 0u);
+ }
+}
+
+TEST_F(ResourceBindingAnalysisTest, TestManyBindings) {
+ // cbuffer CB : register(b3) { int a; }
+ // RWBuffer<float4> A[5] : register(u10, space20);
+ // StructuredBuffer<int> B : register(t5);
+ // RWBuffer<float> C : register(u5);
+ // StructuredBuffer<int> D[5] : register(t0);
+ // RWBuffer<float> E[2] : register(u2);
----------------
pow2clk wrote:
I don't have any reason to expect that samplers wouldn't work, but it is the only resource class not tested.
https://github.com/llvm/llvm-project/pull/137258
More information about the llvm-commits
mailing list