llvm-project/llvm/test/Analysis/DXILResource/buffer-frombinding.ll
Justin Bogner 51ede55ee2
Re-Apply "[DXIL][Analysis] Implement enough of DXILResourceAnalysis for buffers" (#104517)
Some build configs allow `llvm_unreachable` in a constexpr context, but
not all, so these functions that map a fully covered enum to a string
can't be constexpr. This version fixes that by dropping constexpr from
those functions.

This reverts commit fcc318ff7960d7de8cbac56eb4f32b44b5261677, reapplying
28d577ecefa1557f5dea5566bf33b885c563d14b.

Original message follows:

This implements the DXILResourceAnalysis pass for `dx.TypedBuffer` and
`dx.RawBuffer` types. This should be sufficient to lower
`dx.handle.fromBinding` for this set of types, but it leaves a number of
TODOs around for other resource types.

This also includes a straightforward `print` method in `ResourceInfo` to
make the analysis testable. This is deliberately different than the
printer in `lib/Target/DirectX/DXILResource.cpp`, which attempts to
print bindings in a format compatible with the comments `dxc` prints. We
will eventually want to make that functionality driven by this analysis
pass, but it isn't sufficient for testing so we need both.
2024-08-16 11:36:41 -07:00

127 lines
4.1 KiB
LLVM

; RUN: opt -S -disable-output -passes="print<dxil-resource>" < %s 2>&1 | FileCheck %s
@G = external constant <4 x float>, align 4
define void @test_typedbuffer() {
; RWBuffer<float4> Buf : register(u5, space3)
%typed0 = call target("dx.TypedBuffer", <4 x float>, 1, 0, 0)
@llvm.dx.handle.fromBinding.tdx.TypedBuffer_f32_1_0(
i32 3, i32 5, i32 1, i32 0, i1 false)
; CHECK: Binding for %typed0
; CHECK: Symbol: ptr undef
; CHECK: Name: ""
; CHECK: Binding:
; CHECK: Record ID: 0
; CHECK: Space: 3
; CHECK: Lower Bound: 5
; CHECK: Size: 1
; CHECK: Class: UAV
; CHECK: Kind: TypedBuffer
; CHECK: Globally Coherent: 0
; CHECK: HasCounter: 0
; CHECK: IsROV: 0
; CHECK: Element Type: f32
; CHECK: Element Count: 4
; RWBuffer<int> Buf : register(u7, space2)
%typed1 = call target("dx.TypedBuffer", i32, 1, 0, 1)
@llvm.dx.handle.fromBinding.tdx.TypedBuffer_i32_1_0t(
i32 2, i32 7, i32 1, i32 0, i1 false)
; CHECK: Binding for %typed1
; CHECK: Symbol: ptr undef
; CHECK: Name: ""
; CHECK: Binding:
; CHECK: Record ID: 1
; CHECK: Space: 2
; CHECK: Lower Bound: 7
; CHECK: Size: 1
; CHECK: Class: UAV
; CHECK: Kind: TypedBuffer
; CHECK: Globally Coherent: 0
; CHECK: HasCounter: 0
; CHECK: IsROV: 0
; CHECK: Element Type: i32
; CHECK: Element Count: 1
; Buffer<uint4> Buf[24] : register(t3, space5)
%typed2 = call target("dx.TypedBuffer", <4 x i32>, 0, 0, 0)
@llvm.dx.handle.fromBinding.tdx.TypedBuffer_i32_0_0t(
i32 2, i32 7, i32 24, i32 0, i1 false)
; CHECK: Binding for %typed2
; CHECK: Symbol: ptr undef
; CHECK: Name: ""
; CHECK: Binding:
; CHECK: Record ID: 0
; CHECK: Space: 2
; CHECK: Lower Bound: 7
; CHECK: Size: 24
; CHECK: Class: SRV
; CHECK: Kind: TypedBuffer
; CHECK: Element Type: u32
; CHECK: Element Count: 4
ret void
}
define void @test_structbuffer() {
; struct S { float4 a; uint4 b; };
; StructuredBuffer<S> Buf : register(t2, space4)
%struct0 = call target("dx.RawBuffer", {<4 x float>, <4 x i32>}, 0, 0)
@llvm.dx.handle.fromBinding.tdx.RawBuffer_sl_v4f32v4i32s_0_0t(
i32 4, i32 2, i32 1, i32 0, i1 false)
; CHECK: Binding for %struct0
; CHECK: Symbol: ptr undef
; CHECK: Name: ""
; CHECK: Binding:
; CHECK: Record ID: 1
; CHECK: Space: 4
; CHECK: Lower Bound: 2
; CHECK: Size: 1
; CHECK: Class: SRV
; CHECK: Kind: StructuredBuffer
; CHECK: Buffer Stride: 32
; CHECK: Alignment: 4
ret void
}
define void @test_bytebuffer() {
; ByteAddressBuffer Buf : register(t8, space1)
%byteaddr0 = call target("dx.RawBuffer", i8, 0, 0)
@llvm.dx.handle.fromBinding.tdx.RawBuffer_i8_0_0t(
i32 1, i32 8, i32 1, i32 0, i1 false)
; CHECK: Binding for %byteaddr0
; CHECK: Symbol: ptr undef
; CHECK: Name: ""
; CHECK: Binding:
; CHECK: Record ID: 2
; CHECK: Space: 1
; CHECK: Lower Bound: 8
; CHECK: Size: 1
; CHECK: Class: SRV
; CHECK: Kind: RawBuffer
ret void
}
; Note: We need declarations for each handle.fromBinding in the same
; order as they appear in source to ensure that we can put our CHECK
; lines along side the thing they're checking.
declare target("dx.TypedBuffer", <4 x float>, 1, 0, 0)
@llvm.dx.handle.fromBinding.tdx.TypedBuffer_v4f32_1_0_0t(
i32, i32, i32, i32, i1) #0
declare target("dx.TypedBuffer", i32, 1, 0, 1)
@llvm.dx.handle.fromBinding.tdx.TypedBuffer_i32_1_0_1t(
i32, i32, i32, i32, i1) #0
declare target("dx.TypedBuffer", <4 x i32>, 0, 0, 0)
@llvm.dx.handle.fromBinding.tdx.TypedBuffer_v4i32_0_0_0t(
i32, i32, i32, i32, i1) #0
declare target("dx.RawBuffer", { <4 x float>, <4 x i32> }, 0, 0)
@llvm.dx.handle.fromBinding.tdx.RawBuffer_sl_v4f32v4i32s_0_0t(
i32, i32, i32, i32, i1) #0
declare target("dx.RawBuffer", i8, 0, 0)
@llvm.dx.handle.fromBinding.tdx.RawBuffer_i8_0_0t(
i32, i32, i32, i32, i1) #0
attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) }