Files
clang-p2996/llvm/test/CodeGen/DirectX/BufferLoadDouble.ll
Sarah Spall 7f34d3acba [DirectX] Add support for typedBufferLoad and Store for RWBuffer<double2> and RWBuffer<double> (#139996)
typedBufferLoad of double/double2 is expanded to a typedBufferLoad of a
<2 x i32>/<4 x i32> and asdouble
typedBufferStore of a double/double2 is expanded to a splitdouble and a
typedBufferStore of a <2 x i32>/<4 x i32>
Add tests showing result of intrinsic expansion for typedBufferLoad and
typedBufferStore
Add tests showing dxil op lowering can handle typedBufferLoad and
typedBufferStore where the target type doesn't match the typedBufferLoad
and typedBufferStore type
Closes #104423
2025-05-30 08:16:19 -07:00

91 lines
4.6 KiB
LLVM

; RUN: opt -S -dxil-intrinsic-expansion %s | FileCheck %s
target triple = "dxil-pc-shadermodel6.6-compute"
define void @loadf64() {
; check the handle from binding is unchanged
; CHECK: [[B:%.*]] = call target("dx.TypedBuffer", double, 1, 0, 0)
; CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f64_1_0_0t(
; CHECK-SAME: i32 0, i32 1, i32 1, i32 0, i1 false, ptr null)
%buffer = call target("dx.TypedBuffer", double, 1, 0, 0)
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f64_1_0_0t(
i32 0, i32 1, i32 1, i32 0, i1 false, ptr null)
; check we load an <2 x i32> instead of a double
; CHECK-NOT: call {double, i1} @llvm.dx.resource.load.typedbuffer
; CHECK: [[L0:%.*]] = call { <2 x i32>, i1 }
; CHECK-SAME: @llvm.dx.resource.load.typedbuffer.v2i32.tdx.TypedBuffer_f64_1_0_0t(
; CHECK-SAME: target("dx.TypedBuffer", double, 1, 0, 0) [[B]], i32 0)
%load0 = call {double, i1} @llvm.dx.resource.load.typedbuffer(
target("dx.TypedBuffer", double, 1, 0, 0) %buffer, i32 0)
; check we extract the two i32 and construct a double
; CHECK: [[D0:%.*]] = extractvalue { <2 x i32>, i1 } [[L0]], 0
; CHECK: [[Lo:%.*]] = extractelement <2 x i32> [[D0]], i32 0
; CHECK: [[Hi:%.*]] = extractelement <2 x i32> [[D0]], i32 1
; CHECK: [[DBL:%.*]] = call double @llvm.dx.asdouble.i32(i32 [[Lo]], i32 [[Hi]])
; CHECK-NOT: extractvalue { double, i1 }
%data0 = extractvalue {double, i1} %load0, 0
ret void
}
define void @loadv2f64() {
; check the handle from binding is unchanged
; CHECK: [[B:%.*]] = call target("dx.TypedBuffer", <2 x double>, 1, 0, 0)
; CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_v2f64_1_0_0t(
; CHECK-SAME: i32 0, i32 1, i32 1, i32 0, i1 false, ptr null)
%buffer = call target("dx.TypedBuffer", <2 x double>, 1, 0, 0)
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_v2f64_1_0_0t(
i32 0, i32 1, i32 1, i32 0, i1 false, ptr null)
; check we load an <4 x i32> instead of a double2
; CHECK: [[L0:%.*]] = call { <4 x i32>, i1 }
; CHECK-SAME: @llvm.dx.resource.load.typedbuffer.v4i32.tdx.TypedBuffer_v2f64_1_0_0t(
; CHECK-SAME: target("dx.TypedBuffer", <2 x double>, 1, 0, 0) [[B]], i32 0)
%load0 = call { <2 x double>, i1 } @llvm.dx.resource.load.typedbuffer(
target("dx.TypedBuffer", <2 x double>, 1, 0, 0) %buffer, i32 0)
; check we extract the 4 i32 and construct a <2 x double>
; CHECK: [[D0:%.*]] = extractvalue { <4 x i32>, i1 } [[L0]], 0
; CHECK: [[Lo1:%.*]] = extractelement <4 x i32> [[D0]], i32 0
; CHECK: [[Hi1:%.*]] = extractelement <4 x i32> [[D0]], i32 1
; CHECK: [[Lo2:%.*]] = extractelement <4 x i32> [[D0]], i32 2
; CHECK: [[Hi2:%.*]] = extractelement <4 x i32> [[D0]], i32 3
; CHECK: [[Dbl1:%.*]] = call double @llvm.dx.asdouble.i32(i32 [[Lo1]], i32 [[Hi1]])
; CHECK: [[Vec:%.*]] = insertelement <2 x double> poison, double [[Dbl1]], i32 0
; CHECK: [[Dbl2:%.*]] = call double @llvm.dx.asdouble.i32(i32 [[Lo2]], i32 [[Hi2]])
; CHECK: [[Vec2:%.*]] = insertelement <2 x double> [[Vec]], double [[Dbl2]], i32 1
; CHECK-NOT: extractvalue { <2 x double>, i1 }
%data0 = extractvalue { <2 x double>, i1 } %load0, 0
ret void
}
; show we properly handle extracting the check bit
define void @loadf64WithCheckBit() {
; check the handle from binding is unchanged
; CHECK: [[B:%.*]] = call target("dx.TypedBuffer", double, 1, 0, 0)
; CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f64_1_0_0t(
; CHECK-SAME: i32 0, i32 1, i32 1, i32 0, i1 false, ptr null)
%buffer = call target("dx.TypedBuffer", double, 1, 0, 0)
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f64_1_0_0t(
i32 0, i32 1, i32 1, i32 0, i1 false, ptr null)
; check we load an <2 x i32> instead of a double
; CHECK-NOT: call {double, i1} @llvm.dx.resource.load.typedbuffer
; CHECK: [[L0:%.*]] = call { <2 x i32>, i1 }
; CHECK-SAME: @llvm.dx.resource.load.typedbuffer.v2i32.tdx.TypedBuffer_f64_1_0_0t(
; CHECK-SAME: target("dx.TypedBuffer", double, 1, 0, 0) [[B]], i32 0)
%load0 = call {double, i1} @llvm.dx.resource.load.typedbuffer(
target("dx.TypedBuffer", double, 1, 0, 0) %buffer, i32 0)
; check we extract the two i32 and construct a double
; CHECK: [[D0:%.*]] = extractvalue { <2 x i32>, i1 } [[L0]], 0
; CHECK: [[Lo:%.*]] = extractelement <2 x i32> [[D0]], i32 0
; CHECK: [[Hi:%.*]] = extractelement <2 x i32> [[D0]], i32 1
; CHECK: [[DBL:%.*]] = call double @llvm.dx.asdouble.i32(i32 [[Lo]], i32 [[Hi]])
%data0 = extractvalue {double, i1} %load0, 0
; CHECK: extractvalue { <2 x i32>, i1 } [[L0]], 1
; CHECK-NOT: extractvalue { double, i1 }
%cb = extractvalue {double, i1} %load0, 1
ret void
}