llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-backend-directx Author: Helena Kotas (hekota) <details> <summary>Changes</summary> The `DXILResourceImplicitBinding` pass uses the results of `DXILResourceBindingAnalysis` to assigns register slots to resources that do not have explicit binding. It replaces all `llvm.dx.resource.handlefromimplicitbinding` calls with `llvm.dx.resource.handlefrombinding` using the newly assigned binding. If a binding cannot be found for a resource, the pass will raise a diagnostic error. Currently this diagnostic message does not include the resource name, which will be addressed in a separate task (#<!-- -->137868). Part 2/2 of #<!-- -->136786 Closes #<!-- -->136786 --- Patch is 26.40 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/138043.diff 16 Files Affected: - (modified) llvm/include/llvm/Analysis/DXILResource.h (+8) - (modified) llvm/include/llvm/InitializePasses.h (+1) - (modified) llvm/lib/Analysis/Analysis.cpp (+1) - (modified) llvm/lib/Analysis/DXILResource.cpp (+53) - (modified) llvm/lib/Target/DirectX/CMakeLists.txt (+1) - (added) llvm/lib/Target/DirectX/DXILResourceImplicitBinding.cpp (+182) - (added) llvm/lib/Target/DirectX/DXILResourceImplicitBinding.h (+29) - (modified) llvm/lib/Target/DirectX/DirectX.h (+6) - (modified) llvm/lib/Target/DirectX/DirectXPassRegistry.def (+1) - (modified) llvm/lib/Target/DirectX/DirectXTargetMachine.cpp (+3) - (added) llvm/test/CodeGen/DirectX/ImplicitBinding/arrays.ll (+41) - (added) llvm/test/CodeGen/DirectX/ImplicitBinding/multiple-spaces.ll (+44) - (added) llvm/test/CodeGen/DirectX/ImplicitBinding/simple.ll (+30) - (added) llvm/test/CodeGen/DirectX/ImplicitBinding/unbounded-arrays-error.ll (+34) - (added) llvm/test/CodeGen/DirectX/ImplicitBinding/unbounded-arrays.ll (+42) - (modified) llvm/test/CodeGen/DirectX/llc-pipeline.ll (+2) ``````````diff diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h index 569f5346b9e36..fd34fdfda4c1c 100644 --- a/llvm/include/llvm/Analysis/DXILResource.h +++ b/llvm/include/llvm/Analysis/DXILResource.h @@ -632,12 +632,15 @@ class DXILResourceBindingInfo { RegisterSpace(uint32_t Space) : Space(Space) { FreeRanges.emplace_back(0, UINT32_MAX); } + // Size == -1 means unbounded array + bool findAvailableBinding(int32_t Size, uint32_t *RegSlot); }; struct BindingSpaces { dxil::ResourceClass ResClass; llvm::SmallVector<RegisterSpace> Spaces; BindingSpaces(dxil::ResourceClass ResClass) : ResClass(ResClass) {} + RegisterSpace &getOrInsertSpace(uint32_t Space); }; private: @@ -658,6 +661,7 @@ class DXILResourceBindingInfo { OverlappingBinding(false) {} bool hasImplicitBinding() const { return ImplicitBinding; } + void setHasImplicitBinding(bool Value) { ImplicitBinding = Value; } bool hasOverlappingBinding() const { return OverlappingBinding; } BindingSpaces &getBindingSpaces(dxil::ResourceClass RC) { @@ -673,6 +677,10 @@ class DXILResourceBindingInfo { } } + // Size == -1 means unbounded array + bool findAvailableBinding(dxil::ResourceClass RC, uint32_t Space, + int32_t Size, uint32_t *RegSlot); + friend class DXILResourceBindingAnalysis; friend class DXILResourceBindingWrapperPass; }; diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index b84c6d6123d58..71db56d922676 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -85,6 +85,7 @@ void initializeDCELegacyPassPass(PassRegistry &); void initializeDXILMetadataAnalysisWrapperPassPass(PassRegistry &); void initializeDXILMetadataAnalysisWrapperPrinterPass(PassRegistry &); void initializeDXILResourceBindingWrapperPassPass(PassRegistry &); +void initializeDXILResourceImplicitBindingLegacyPass(PassRegistry &); void initializeDXILResourceTypeWrapperPassPass(PassRegistry &); void initializeDXILResourceWrapperPassPass(PassRegistry &); void initializeDeadMachineInstructionElimPass(PassRegistry &); diff --git a/llvm/lib/Analysis/Analysis.cpp b/llvm/lib/Analysis/Analysis.cpp index 484a456f49f1b..9f5daf32be9a0 100644 --- a/llvm/lib/Analysis/Analysis.cpp +++ b/llvm/lib/Analysis/Analysis.cpp @@ -27,6 +27,7 @@ void llvm::initializeAnalysis(PassRegistry &Registry) { initializeCallGraphViewerPass(Registry); initializeCycleInfoWrapperPassPass(Registry); initializeDXILMetadataAnalysisWrapperPassPass(Registry); + initializeDXILResourceWrapperPassPass(Registry); initializeDXILResourceBindingWrapperPassPass(Registry); initializeDXILResourceTypeWrapperPassPass(Registry); initializeDXILResourceWrapperPassPass(Registry); diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp index ce8e250a32ebe..34355c81e77b0 100644 --- a/llvm/lib/Analysis/DXILResource.cpp +++ b/llvm/lib/Analysis/DXILResource.cpp @@ -995,6 +995,59 @@ void DXILResourceBindingInfo::populate(Module &M, DXILResourceTypeMap &DRTM) { } } +// returns false if binding could not be found in given space +bool DXILResourceBindingInfo::findAvailableBinding(dxil::ResourceClass RC, + uint32_t Space, int32_t Size, + uint32_t *RegSlot) { + BindingSpaces &BS = getBindingSpaces(RC); + RegisterSpace &RS = BS.getOrInsertSpace(Space); + return RS.findAvailableBinding(Size, RegSlot); +} + +DXILResourceBindingInfo::RegisterSpace & +DXILResourceBindingInfo::BindingSpaces::getOrInsertSpace(uint32_t Space) { + for (auto *I = Spaces.begin(); I != Spaces.end(); ++I) { + if (I->Space == Space) + return *I; + if (I->Space < Space) + continue; + return *Spaces.insert(I, Space); + } + return Spaces.emplace_back(Space); +} + +bool DXILResourceBindingInfo::RegisterSpace::findAvailableBinding( + int32_t Size, uint32_t *RegSlot) { + assert((Size == -1 || Size > 0) && "invalid size"); + + if (FreeRanges.empty()) + return false; + + // unbounded array + if (Size == -1) { + BindingRange &Last = FreeRanges.back(); + if (Last.UpperBound != UINT32_MAX) + // this space is already occupied by an unbounded array + return false; + *RegSlot = Last.LowerBound; + FreeRanges.pop_back(); + return true; + } + + // single resource or fixed-size array + for (BindingRange &R : FreeRanges) { + if (R.UpperBound - R.LowerBound + 1 < (uint32_t)Size) + continue; + *RegSlot = R.LowerBound; + // This might create a range where (LowerBound == UpperBound + 1), but + // that's ok. + R.LowerBound += Size; + return true; + } + + return false; +} + //===----------------------------------------------------------------------===// AnalysisKey DXILResourceTypeAnalysis::Key; diff --git a/llvm/lib/Target/DirectX/CMakeLists.txt b/llvm/lib/Target/DirectX/CMakeLists.txt index 65105d3a5f4c3..9f5550a9a9ce8 100644 --- a/llvm/lib/Target/DirectX/CMakeLists.txt +++ b/llvm/lib/Target/DirectX/CMakeLists.txt @@ -31,6 +31,7 @@ add_llvm_target(DirectXCodeGen DXILPrepare.cpp DXILPrettyPrinter.cpp DXILResourceAccess.cpp + DXILResourceImplicitBinding.cpp DXILShaderFlags.cpp DXILTranslateMetadata.cpp DXILRootSignature.cpp diff --git a/llvm/lib/Target/DirectX/DXILResourceImplicitBinding.cpp b/llvm/lib/Target/DirectX/DXILResourceImplicitBinding.cpp new file mode 100644 index 0000000000000..80293ad7c9716 --- /dev/null +++ b/llvm/lib/Target/DirectX/DXILResourceImplicitBinding.cpp @@ -0,0 +1,182 @@ +//===- DXILResourceImplicitBinding.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 "DXILResourceImplicitBinding.h" +#include "DirectX.h" +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/Analysis/DXILResource.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicsDirectX.h" +#include "llvm/IR/Module.h" +#include "llvm/InitializePasses.h" +#include <cstdint> + +#define DEBUG_TYPE "dxil-resource-implicit-binding" + +using namespace llvm; +using namespace llvm::dxil; + +namespace { + +static void diagnoseImplicitBindingNotFound(CallInst *ImplBindingCall) { + Function *F = ImplBindingCall->getFunction(); + LLVMContext &Context = F->getParent()->getContext(); + // FIXME: include the name of the resource in the error message + // (llvm/llvm-project#137868) + Context.diagnose( + DiagnosticInfoGenericWithLoc("resource cannot be allocated", *F, + ImplBindingCall->getDebugLoc(), DS_Error)); +} + +static bool assignBindings(Module &M, DXILResourceBindingInfo &DRBI, + DXILResourceTypeMap &DRTM) { + struct ImplBindingCall { + int OrderID; + CallInst *Call; + ImplBindingCall(int OrderID, CallInst *Call) + : OrderID(OrderID), Call(Call) {} + }; + SmallVector<ImplBindingCall> Calls; + SmallVector<Function *> FunctionsToMaybeRemove; + + // collect all of the llvm.dx.resource.handlefromImplicitbinding calls + for (Function &F : M.functions()) { + if (!F.isDeclaration()) + continue; + + if (F.getIntrinsicID() != Intrinsic::dx_resource_handlefromimplicitbinding) + continue; + + for (User *U : F.users()) { + if (CallInst *CI = dyn_cast<CallInst>(U)) { + int OrderID = cast<ConstantInt>(CI->getArgOperand(0))->getZExtValue(); + Calls.emplace_back(OrderID, CI); + } + } + FunctionsToMaybeRemove.emplace_back(&F); + } + + // sort all the collected implicit bindings by OrderID + llvm::stable_sort( + Calls, [](auto &LHS, auto &RHS) { return LHS.OrderID < RHS.OrderID; }); + + // iterate over sorted calls, find binding for each new OrderID and replace + // each call with dx_resource_handlefrombinding using the new binding + int LastOrderID = -1; + llvm::TargetExtType *HandleTy = nullptr; + ConstantInt *RegSlotOp = nullptr; + bool AllBindingsAssigned = true; + bool Changed = false; + + for (auto &IB : Calls) { + IRBuilder<> Builder(IB.Call); + + if (IB.OrderID != LastOrderID) { + LastOrderID = IB.OrderID; + HandleTy = cast<TargetExtType>(IB.Call->getType()); + ResourceTypeInfo &RTI = DRTM[HandleTy]; + + uint32_t Space = + cast<ConstantInt>(IB.Call->getArgOperand(1))->getZExtValue(); + int32_t Size = + cast<ConstantInt>(IB.Call->getArgOperand(2))->getZExtValue(); + + uint32_t RegSlot; + RegSlotOp = nullptr; + if (!DRBI.findAvailableBinding(RTI.getResourceClass(), Space, Size, + &RegSlot)) { + diagnoseImplicitBindingNotFound(IB.Call); + AllBindingsAssigned = false; + continue; + } + RegSlotOp = ConstantInt::get(Builder.getInt32Ty(), RegSlot); + } + + if (!RegSlotOp) + continue; + + auto *NewCall = Builder.CreateIntrinsic( + HandleTy, Intrinsic::dx_resource_handlefrombinding, + {IB.Call->getOperand(1), /* space */ + RegSlotOp, /* register slot */ + IB.Call->getOperand(2), /* size */ + IB.Call->getOperand(3), /* index */ + IB.Call->getOperand(4)}); /* non-uniform flag */ + IB.Call->replaceAllUsesWith(NewCall); + IB.Call->eraseFromParent(); + Changed = true; + } + + for (Function *F : FunctionsToMaybeRemove) { + if (F->user_empty()) { + F->eraseFromParent(); + Changed = true; + } + } + + DRBI.setHasImplicitBinding(!AllBindingsAssigned); + return Changed; +} + +} // end anonymous namespace + +PreservedAnalyses DXILResourceImplicitBinding::run(Module &M, + ModuleAnalysisManager &AM) { + + PreservedAnalyses PA; + + DXILResourceBindingInfo &DRBI = AM.getResult<DXILResourceBindingAnalysis>(M); + DXILResourceTypeMap &DRTM = AM.getResult<DXILResourceTypeAnalysis>(M); + if (DRBI.hasImplicitBinding()) + if (assignBindings(M, DRBI, DRTM)) + return PA; + return PreservedAnalyses::all(); +} + +namespace { + +class DXILResourceImplicitBindingLegacy : public ModulePass { +public: + DXILResourceImplicitBindingLegacy() : ModulePass(ID) {} + + bool runOnModule(Module &M) override { + DXILResourceTypeMap &DRTM = + getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap(); + DXILResourceBindingInfo &DRBI = + getAnalysis<DXILResourceBindingWrapperPass>().getBindingInfo(); + + if (DRBI.hasImplicitBinding()) + return assignBindings(M, DRBI, DRTM); + return false; + } + + static char ID; // Pass identification. + void getAnalysisUsage(llvm::AnalysisUsage &AU) const override { + AU.addRequired<DXILResourceTypeWrapperPass>(); + AU.addRequired<DXILResourceBindingWrapperPass>(); + } +}; + +char DXILResourceImplicitBindingLegacy::ID = 0; +} // end anonymous namespace + +INITIALIZE_PASS_BEGIN(DXILResourceImplicitBindingLegacy, DEBUG_TYPE, + "DXIL Resource Implicit Binding", false, false) +INITIALIZE_PASS_DEPENDENCY(DXILResourceTypeWrapperPass) +INITIALIZE_PASS_DEPENDENCY(DXILResourceBindingWrapperPass) +INITIALIZE_PASS_END(DXILResourceImplicitBindingLegacy, DEBUG_TYPE, + "DXIL Resource Implicit Binding", false, false) + +ModulePass *llvm::createDXILResourceImplicitBindingLegacyPass() { + return new DXILResourceImplicitBindingLegacy(); +} diff --git a/llvm/lib/Target/DirectX/DXILResourceImplicitBinding.h b/llvm/lib/Target/DirectX/DXILResourceImplicitBinding.h new file mode 100644 index 0000000000000..86ca9ec6842a0 --- /dev/null +++ b/llvm/lib/Target/DirectX/DXILResourceImplicitBinding.h @@ -0,0 +1,29 @@ +//===- DXILResourceImplicitBindings.h --_____________-----------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// \file Assign register slots to resources without explicit binding. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_DIRECTX_DXILRESOURCEIMPLICITBINDING_H +#define LLVM_LIB_TARGET_DIRECTX_DXILRESOURCEIMPLICITBINDING_H + +#include "llvm/IR/PassManager.h" +#include "llvm/Pass.h" + +namespace llvm { + +class DXILResourceImplicitBinding + : public PassInfoMixin<DXILResourceImplicitBinding> { +public: + PreservedAnalyses run(Module &M, ModuleAnalysisManager &); +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_DIRECTX_DXILRESOURCEIMPLICITBINDING_H diff --git a/llvm/lib/Target/DirectX/DirectX.h b/llvm/lib/Target/DirectX/DirectX.h index f64aaaf65d937..647b8ff42867c 100644 --- a/llvm/lib/Target/DirectX/DirectX.h +++ b/llvm/lib/Target/DirectX/DirectX.h @@ -78,6 +78,12 @@ void initializeDXILResourceAccessLegacyPass(PassRegistry &); /// Pass to update resource accesses to use load/store directly. FunctionPass *createDXILResourceAccessLegacyPass(); +/// Initializer for DXILResourceImplicitBindingLegacyPass +void initializeDXILResourceImplicitBindingLegacyPass(PassRegistry &); + +/// Pass to assign register slots to resources without binding. +ModulePass *createDXILResourceImplicitBindingLegacyPass(); + /// Initializer for DXILTranslateMetadata. void initializeDXILTranslateMetadataLegacyPass(PassRegistry &); diff --git a/llvm/lib/Target/DirectX/DirectXPassRegistry.def b/llvm/lib/Target/DirectX/DirectXPassRegistry.def index da239402d01eb..ef65b96799eae 100644 --- a/llvm/lib/Target/DirectX/DirectXPassRegistry.def +++ b/llvm/lib/Target/DirectX/DirectXPassRegistry.def @@ -30,6 +30,7 @@ MODULE_PASS("dxil-intrinsic-expansion", DXILIntrinsicExpansion()) MODULE_PASS("dxil-op-lower", DXILOpLowering()) MODULE_PASS("dxil-pretty-printer", DXILPrettyPrinterPass(dbgs())) MODULE_PASS("dxil-translate-metadata", DXILTranslateMetadata()) +MODULE_PASS("dxil-resource-implicit-binding", DXILResourceImplicitBinding()) // TODO: rename to print<foo> after NPM switch MODULE_PASS("print-dx-shader-flags", dxil::ShaderFlagsAnalysisPrinter(dbgs())) MODULE_PASS("print<dxil-root-signature>", dxil::RootSignatureAnalysisPrinter(dbgs())) diff --git a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp index d3d1f94f3ab1c..2f2372b779092 100644 --- a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp +++ b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp @@ -21,6 +21,7 @@ #include "DXILOpLowering.h" #include "DXILPrettyPrinter.h" #include "DXILResourceAccess.h" +#include "DXILResourceImplicitBinding.h" #include "DXILRootSignature.h" #include "DXILShaderFlags.h" #include "DXILTranslateMetadata.h" @@ -62,6 +63,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() { initializeDXContainerGlobalsPass(*PR); initializeDXILOpLoweringLegacyPass(*PR); initializeDXILResourceAccessLegacyPass(*PR); + initializeDXILResourceImplicitBindingLegacyPass(*PR); initializeDXILTranslateMetadataLegacyPass(*PR); initializeShaderFlagsAnalysisWrapperPass(*PR); initializeRootSignatureAnalysisWrapperPass(*PR); @@ -99,6 +101,7 @@ class DirectXPassConfig : public TargetPassConfig { FunctionPass *createTargetRegisterAllocator(bool) override { return nullptr; } void addCodeGenPrepare() override { addPass(createDXILFinalizeLinkageLegacyPass()); + addPass(createDXILResourceImplicitBindingLegacyPass()); addPass(createDXILIntrinsicExpansionLegacyPass()); addPass(createDXILCBufferAccessLegacyPass()); addPass(createDXILDataScalarizationLegacyPass()); diff --git a/llvm/test/CodeGen/DirectX/ImplicitBinding/arrays.ll b/llvm/test/CodeGen/DirectX/ImplicitBinding/arrays.ll new file mode 100644 index 0000000000000..6196472cb8374 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ImplicitBinding/arrays.ll @@ -0,0 +1,41 @@ +; RUN: opt -S -dxil-resource-implicit-binding %s | FileCheck %s + +; Resources defined (with random order of handlefromimplicitbinding calls): +; RWBuffer<float> A : register(u2); +; RWBuffer<float> B[4]; // gets u3 because it does not fit before A (range 4) +; RWBuffer<int> C[2]; // gets u0 because it fits before A (range 2) +; RWBuffer<float> E[5]; // gets u7 which is right after B (range 5) + +target triple = "dxil-pc-shadermodel6.6-compute" + +define void @test_arrays() { + +; RWBuffer<float> A : register(u2); + %bufA = call target("dx.TypedBuffer", float, 1, 0, 0) + @llvm.dx.resource.handlefrombinding(i32 0, i32 2, i32 1, i32 0, i1 false) +; no change to llvm.dx.resource.handlefrombinding +; CHECK: %bufA = call target("dx.TypedBuffer", float, 1, 0, 0) +; CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 2, i32 1, i32 0, i1 false) + +; RWBuffer<float> E[2]; + %bufE = call target("dx.TypedBuffer", float, 1, 0, 0) + @llvm.dx.resource.handlefromimplicitbinding(i32 30, i32 0, i32 5, i32 4, i1 false) +; CHECK: %{{.*}} = call target("dx.TypedBuffer", float, 1, 0, 0) +; CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 7, i32 5, i32 4, i1 false) + +; RWBuffer<float> B[4]; + %bufB = call target("dx.TypedBuffer", float, 1, 0, 0) + @llvm.dx.resource.handlefromimplicitbinding(i32 10, i32 0, i32 4, i32 2, i1 false) +; CHECK: %{{.*}} = call target("dx.TypedBuffer", float, 1, 0, 0) +; CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 3, i32 4, i32 2, i1 false) + +; RWBuffer<int> C[2]; + %bufC = call target("dx.TypedBuffer", i32, 1, 0, 0) + @llvm.dx.resource.handlefromimplicitbinding(i32 20, i32 0, i32 2, i32 1, i1 false) +; CHECK: %{{.*}} = call target("dx.TypedBuffer", i32, 1, 0, 0) +; CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_i32_1_0_0t(i32 0, i32 0, i32 2, i32 1, i1 false) + +; CHECK-NOT: @llvm.dx.resource.handlefromimplicitbinding + ret void +} + diff --git a/llvm/test/CodeGen/DirectX/ImplicitBinding/multiple-spaces.ll b/llvm/test/CodeGen/DirectX/ImplicitBinding/multiple-spaces.ll new file mode 100644 index 0000000000000..fce904e45ba09 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ImplicitBinding/multiple-spaces.ll @@ -0,0 +1,44 @@ +; RUN: opt -S -dxil-resource-implicit-binding %s | FileCheck %s + +; Resources defined (with random order of handlefromimplicitbinding calls): +; RWBuffer<float> A : register(u5); // defaults to space0 +; RWBuffer<int> B[]; // gets u6 (unbounded range) +; RWBuffer<float> C[4] : register(space5); // gets u0 in space5 +; RWBuffer<int> D[] : register(space5); // gets u4 in space5 +; RWBuffer<float> E[3] : register(space10); // gets u0, space10 +; StructuredBuffer<int> F : register(space3);; // gets t0 in space3 + +target triple = "dxil-pc-shadermodel6.6-compute" + +define void @test_many_spaces() { + +; RWBuffer<float> A : register(u1); + %bufA = call target("dx.TypedBuffer", float, 1, 0, 0) + @llvm.dx.resource.handlefrombinding(i32 0, i32 1, i32 1, i32 0, i1 false) +; no change to llvm.dx.resource.handlefrombinding +; CHECK: %bufA = call target("dx.TypedBuffer", float, 1, 0, 0) +; CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 1, i32 1, i32 0, i1 false) + +; RWBuffer<float> B[]; +%bufB = call target("dx.TypedBuffer", float, 1, 0, 0) + @llvm.dx.resource.handlefromimplicitbinding(i32 100, i32 0, i32 -1, i32 0, i1 false) +; CHECK: %{{.*}} = call target("dx.TypedBuffer", float, 1, 0, 0) +; CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 6, i32 -1, i32 0, i1 false) + +; RWBuffer<int> C : register(u5); + %bufC = call target("dx.TypedBuffer", i32, 1, 0, 0) + @llvm.dx.resource.handlefrombinding(i32 0, i32 5, i32 1, i32 0, i1 false) +; no change to llvm.dx.resource.handlefrombinding +; CHECK: %bufC = call target("dx.TypedBuffer", i32, 1, 0, 0) +; CHECK-SAME:... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/138043 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits