1+ ; RUN: opt -S -dxil-intrinsic-expansion %s | FileCheck %s
2+
3+ target triple = "dxil-pc-shadermodel6.6-compute"
4+
5+ define void @loadf64 () {
6+ ; check the handle from binding is unchanged
7+ ; CHECK: [[B:%.*]] = call target("dx.TypedBuffer", double, 1, 0, 0)
8+ ; CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f64_1_0_0t(
9+ ; CHECK-SAME: i32 0, i32 1, i32 1, i32 0, i1 false, ptr null)
10+ %buffer = call target ("dx.TypedBuffer" , double , 1 , 0 , 0 )
11+ @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f64_1_0_0t (
12+ i32 0 , i32 1 , i32 1 , i32 0 , i1 false , ptr null )
13+
14+ ; check we load an <2 x i32> instead of a double
15+ ; CHECK-NOT: call {double, i1} @llvm.dx.resource.load.typedbuffer
16+ ; CHECK: [[L0:%.*]] = call { <2 x i32>, i1 }
17+ ; CHECK-SAME: @llvm.dx.resource.load.typedbuffer.v2i32.tdx.TypedBuffer_f64_1_0_0t(
18+ ; CHECK-SAME: target("dx.TypedBuffer", double, 1, 0, 0) [[B]], i32 0)
19+ %load0 = call {double , i1 } @llvm.dx.resource.load.typedbuffer (
20+ target ("dx.TypedBuffer" , double , 1 , 0 , 0 ) %buffer , i32 0 )
21+
22+ ; check we extract the two i32 and construct a double
23+ ; CHECK: [[D0:%.*]] = extractvalue { <2 x i32>, i1 } [[L0]], 0
24+ ; CHECK: [[Lo:%.*]] = extractelement <2 x i32> [[D0]], i32 0
25+ ; CHECK: [[Hi:%.*]] = extractelement <2 x i32> [[D0]], i32 1
26+ ; CHECK: [[DBL:%.*]] = call double @llvm.dx.asdouble.i32(i32 [[Lo]], i32 [[Hi]])
27+ ; CHECK-NOT: extractvalue { double, i1 }
28+ %data0 = extractvalue {double , i1 } %load0 , 0
29+ ret void
30+ }
31+
32+ define void @loadv2f64 () {
33+ ; check the handle from binding is unchanged
34+ ; CHECK: [[B:%.*]] = call target("dx.TypedBuffer", <2 x double>, 1, 0, 0)
35+ ; CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_v2f64_1_0_0t(
36+ ; CHECK-SAME: i32 0, i32 1, i32 1, i32 0, i1 false, ptr null)
37+ %buffer = call target ("dx.TypedBuffer" , <2 x double >, 1 , 0 , 0 )
38+ @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_v2f64_1_0_0t (
39+ i32 0 , i32 1 , i32 1 , i32 0 , i1 false , ptr null )
40+
41+ ; check we load an <4 x i32> instead of a double2
42+ ; CHECK: [[L0:%.*]] = call { <4 x i32>, i1 }
43+ ; CHECK-SAME: @llvm.dx.resource.load.typedbuffer.v4i32.tdx.TypedBuffer_v2f64_1_0_0t(
44+ ; CHECK-SAME: target("dx.TypedBuffer", <2 x double>, 1, 0, 0) [[B]], i32 0)
45+ %load0 = call { <2 x double >, i1 } @llvm.dx.resource.load.typedbuffer (
46+ target ("dx.TypedBuffer" , <2 x double >, 1 , 0 , 0 ) %buffer , i32 0 )
47+
48+ ; check we extract the 4 i32 and construct a <2 x double>
49+ ; CHECK: [[D0:%.*]] = extractvalue { <4 x i32>, i1 } [[L0]], 0
50+ ; CHECK: [[Lo1:%.*]] = extractelement <4 x i32> [[D0]], i32 0
51+ ; CHECK: [[Hi1:%.*]] = extractelement <4 x i32> [[D0]], i32 1
52+ ; CHECK: [[Lo2:%.*]] = extractelement <4 x i32> [[D0]], i32 2
53+ ; CHECK: [[Hi2:%.*]] = extractelement <4 x i32> [[D0]], i32 3
54+ ; CHECK: [[Dbl1:%.*]] = call double @llvm.dx.asdouble.i32(i32 [[Lo1]], i32 [[Hi1]])
55+ ; CHECK: [[Vec:%.*]] = insertelement <2 x double> poison, double [[Dbl1]], i32 0
56+ ; CHECK: [[Dbl2:%.*]] = call double @llvm.dx.asdouble.i32(i32 [[Lo2]], i32 [[Hi2]])
57+ ; CHECK: [[Vec2:%.*]] = insertelement <2 x double> [[Vec]], double [[Dbl2]], i32 1
58+ ; CHECK-NOT: extractvalue { <2 x double>, i1 }
59+ %data0 = extractvalue { <2 x double >, i1 } %load0 , 0
60+ ret void
61+ }
62+
63+ ; show we properly handle extracting the check bit
64+ define void @loadf64WithCheckBit () {
65+ ; check the handle from binding is unchanged
66+ ; CHECK: [[B:%.*]] = call target("dx.TypedBuffer", double, 1, 0, 0)
67+ ; CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f64_1_0_0t(
68+ ; CHECK-SAME: i32 0, i32 1, i32 1, i32 0, i1 false, ptr null)
69+ %buffer = call target ("dx.TypedBuffer" , double , 1 , 0 , 0 )
70+ @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f64_1_0_0t (
71+ i32 0 , i32 1 , i32 1 , i32 0 , i1 false , ptr null )
72+
73+ ; check we load an <2 x i32> instead of a double
74+ ; CHECK-NOT: call {double, i1} @llvm.dx.resource.load.typedbuffer
75+ ; CHECK: [[L0:%.*]] = call { <2 x i32>, i1 }
76+ ; CHECK-SAME: @llvm.dx.resource.load.typedbuffer.v2i32.tdx.TypedBuffer_f64_1_0_0t(
77+ ; CHECK-SAME: target("dx.TypedBuffer", double, 1, 0, 0) [[B]], i32 0)
78+ %load0 = call {double , i1 } @llvm.dx.resource.load.typedbuffer (
79+ target ("dx.TypedBuffer" , double , 1 , 0 , 0 ) %buffer , i32 0 )
80+
81+ ; check we extract the two i32 and construct a double
82+ ; CHECK: [[D0:%.*]] = extractvalue { <2 x i32>, i1 } [[L0]], 0
83+ ; CHECK: [[Lo:%.*]] = extractelement <2 x i32> [[D0]], i32 0
84+ ; CHECK: [[Hi:%.*]] = extractelement <2 x i32> [[D0]], i32 1
85+ ; CHECK: [[DBL:%.*]] = call double @llvm.dx.asdouble.i32(i32 [[Lo]], i32 [[Hi]])
86+ %data0 = extractvalue {double , i1 } %load0 , 0
87+ ; CHECK: extractvalue { <2 x i32>, i1 } [[L0]], 1
88+ ; CHECK-NOT: extractvalue { double, i1 }
89+ %cb = extractvalue {double , i1 } %load0 , 1
90+ ret void
91+ }
0 commit comments