1// RUN: mlir-translate -test-spirv-roundtrip %s | FileCheck %s
2
3spv.module Logical GLSL450 requires #spv.vce<v1.0, [Shader], []> {
4  // CHECK-LABEL: @bool_const
5  spv.func @bool_const() -> () "None" {
6    // CHECK: spv.constant true
7    %0 = spv.constant true
8    // CHECK: spv.constant false
9    %1 = spv.constant false
10
11    %2 = spv.Variable init(%0): !spv.ptr<i1, Function>
12    %3 = spv.Variable init(%1): !spv.ptr<i1, Function>
13    spv.Return
14  }
15
16  // CHECK-LABEL: @i32_const
17  spv.func @i32_const() -> () "None" {
18    // CHECK: spv.constant 0 : i32
19    %0 = spv.constant  0 : i32
20    // CHECK: spv.constant 10 : i32
21    %1 = spv.constant 10 : i32
22    // CHECK: spv.constant -5 : i32
23    %2 = spv.constant -5 : i32
24
25    %3 = spv.IAdd %0, %1 : i32
26    %4 = spv.IAdd %2, %3 : i32
27    spv.Return
28  }
29
30  // CHECK-LABEL: @si32_const
31  spv.func @si32_const() -> () "None" {
32    // CHECK: spv.constant 0 : si32
33    %0 = spv.constant  0 : si32
34    // CHECK: spv.constant 10 : si32
35    %1 = spv.constant 10 : si32
36    // CHECK: spv.constant -5 : si32
37    %2 = spv.constant -5 : si32
38
39    %3 = spv.IAdd %0, %1 : si32
40    %4 = spv.IAdd %2, %3 : si32
41    spv.Return
42  }
43
44  // CHECK-LABEL: @ui32_const
45  // We cannot differentiate signless vs. unsigned integers in SPIR-V blob
46  // because they all use 1 as the signedness bit. So we always treat them
47  // as signless integers.
48  spv.func @ui32_const() -> () "None" {
49    // CHECK: spv.constant 0 : i32
50    %0 = spv.constant  0 : ui32
51    // CHECK: spv.constant 10 : i32
52    %1 = spv.constant 10 : ui32
53    // CHECK: spv.constant -5 : i32
54    %2 = spv.constant 4294967291 : ui32
55
56    %3 = spv.IAdd %0, %1 : ui32
57    %4 = spv.IAdd %2, %3 : ui32
58    spv.Return
59  }
60
61  // CHECK-LABEL: @i64_const
62  spv.func @i64_const() -> () "None" {
63    // CHECK: spv.constant 4294967296 : i64
64    %0 = spv.constant           4294967296 : i64 //  2^32
65    // CHECK: spv.constant -4294967296 : i64
66    %1 = spv.constant          -4294967296 : i64 // -2^32
67    // CHECK: spv.constant 9223372036854775807 : i64
68    %2 = spv.constant  9223372036854775807 : i64 //  2^63 - 1
69    // CHECK: spv.constant -9223372036854775808 : i64
70    %3 = spv.constant -9223372036854775808 : i64 // -2^63
71
72    %4 = spv.IAdd %0, %1 : i64
73    %5 = spv.IAdd %2, %3 : i64
74    spv.Return
75  }
76
77  // CHECK-LABEL: @i16_const
78  spv.func @i16_const() -> () "None" {
79    // CHECK: spv.constant -32768 : i16
80    %0 = spv.constant -32768 : i16 // -2^15
81    // CHECK: spv.constant 32767 : i16
82    %1 = spv.constant 32767 : i16 //  2^15 - 1
83
84    %2 = spv.IAdd %0, %1 : i16
85    spv.Return
86  }
87
88  // CHECK-LABEL: @float_const
89  spv.func @float_const() -> () "None" {
90    // CHECK: spv.constant 0.000000e+00 : f32
91    %0 = spv.constant 0. : f32
92    // CHECK: spv.constant 1.000000e+00 : f32
93    %1 = spv.constant 1. : f32
94    // CHECK: spv.constant -0.000000e+00 : f32
95    %2 = spv.constant -0. : f32
96    // CHECK: spv.constant -1.000000e+00 : f32
97    %3 = spv.constant -1. : f32
98    // CHECK: spv.constant 7.500000e-01 : f32
99    %4 = spv.constant 0.75 : f32
100    // CHECK: spv.constant -2.500000e-01 : f32
101    %5 = spv.constant -0.25 : f32
102
103    %6 = spv.FAdd %0, %1 : f32
104    %7 = spv.FAdd %2, %3 : f32
105    %8 = spv.FAdd %4, %5 : f32
106    spv.Return
107  }
108
109  // CHECK-LABEL: @double_const
110  spv.func @double_const() -> () "None" {
111    // TODO: test range boundary values
112    // CHECK: spv.constant 1.024000e+03 : f64
113    %0 = spv.constant 1024. : f64
114    // CHECK: spv.constant -1.024000e+03 : f64
115    %1 = spv.constant -1024. : f64
116
117    %2 = spv.FAdd %0, %1 : f64
118    spv.Return
119  }
120
121  // CHECK-LABEL: @half_const
122  spv.func @half_const() -> () "None" {
123    // CHECK: spv.constant 5.120000e+02 : f16
124    %0 = spv.constant 512. : f16
125    // CHECK: spv.constant -5.120000e+02 : f16
126    %1 = spv.constant -512. : f16
127
128    %2 = spv.FAdd %0, %1 : f16
129    spv.Return
130  }
131
132  // CHECK-LABEL: @bool_vector_const
133  spv.func @bool_vector_const() -> () "None" {
134    // CHECK: spv.constant dense<false> : vector<2xi1>
135    %0 = spv.constant dense<false> : vector<2xi1>
136    // CHECK: spv.constant dense<[true, true, true]> : vector<3xi1>
137    %1 = spv.constant dense<true> : vector<3xi1>
138    // CHECK: spv.constant dense<[false, true]> : vector<2xi1>
139    %2 = spv.constant dense<[false, true]> : vector<2xi1>
140
141    %3 = spv.Variable init(%0): !spv.ptr<vector<2xi1>, Function>
142    %4 = spv.Variable init(%1): !spv.ptr<vector<3xi1>, Function>
143    %5 = spv.Variable init(%2): !spv.ptr<vector<2xi1>, Function>
144    spv.Return
145  }
146
147  // CHECK-LABEL: @int_vector_const
148  spv.func @int_vector_const() -> () "None" {
149    // CHECK: spv.constant dense<0> : vector<3xi32>
150    %0 = spv.constant dense<0> : vector<3xi32>
151    // CHECK: spv.constant dense<1> : vector<3xi32>
152    %1 = spv.constant dense<1> : vector<3xi32>
153    // CHECK: spv.constant dense<[2, -3, 4]> : vector<3xi32>
154    %2 = spv.constant dense<[2, -3, 4]> : vector<3xi32>
155
156    %3 = spv.IAdd %0, %1 : vector<3xi32>
157    %4 = spv.IAdd %2, %3 : vector<3xi32>
158    spv.Return
159  }
160
161  // CHECK-LABEL: @fp_vector_const
162  spv.func @fp_vector_const() -> () "None" {
163    // CHECK: spv.constant dense<0.000000e+00> : vector<4xf32>
164    %0 = spv.constant dense<0.> : vector<4xf32>
165    // CHECK: spv.constant dense<-1.500000e+01> : vector<4xf32>
166    %1 = spv.constant dense<-15.> : vector<4xf32>
167    // CHECK: spv.constant dense<[7.500000e-01, -2.500000e-01, 1.000000e+01, 4.200000e+01]> : vector<4xf32>
168    %2 = spv.constant dense<[0.75, -0.25, 10., 42.]> : vector<4xf32>
169
170    %3 = spv.FAdd %0, %1 : vector<4xf32>
171    %4 = spv.FAdd %2, %3 : vector<4xf32>
172    spv.Return
173  }
174
175  // CHECK-LABEL: @ui64_array_const
176  spv.func @ui64_array_const() -> (!spv.array<3xui64>) "None" {
177    // CHECK: spv.constant [5, 6, 7] : !spv.array<3 x i64>
178    %0 = spv.constant [5 : ui64, 6 : ui64, 7 : ui64] : !spv.array<3 x ui64>
179
180    spv.ReturnValue %0: !spv.array<3xui64>
181  }
182
183  // CHECK-LABEL: @si32_array_const
184  spv.func @si32_array_const() -> (!spv.array<3xsi32>) "None" {
185    // CHECK: spv.constant [5 : si32, 6 : si32, 7 : si32] : !spv.array<3 x si32>
186    %0 = spv.constant [5 : si32, 6 : si32, 7 : si32] : !spv.array<3 x si32>
187
188    spv.ReturnValue %0 : !spv.array<3xsi32>
189  }
190  // CHECK-LABEL: @float_array_const
191  spv.func @float_array_const() -> (!spv.array<2 x vector<2xf32>>) "None" {
192    // CHECK: spv.constant [dense<3.000000e+00> : vector<2xf32>, dense<[4.000000e+00, 5.000000e+00]> : vector<2xf32>] : !spv.array<2 x vector<2xf32>>
193    %0 = spv.constant [dense<3.0> : vector<2xf32>, dense<[4., 5.]> : vector<2xf32>] : !spv.array<2 x vector<2xf32>>
194
195    spv.ReturnValue %0 : !spv.array<2 x vector<2xf32>>
196  }
197
198  // CHECK-LABEL: @ignore_not_used_const
199  spv.func @ignore_not_used_const() -> () "None" {
200    %0 = spv.constant false
201    // CHECK-NEXT: spv.Return
202    spv.Return
203  }
204
205  // CHECK-LABEL: @materialize_const_at_each_use
206  spv.func @materialize_const_at_each_use() -> (i32) "None" {
207    // CHECK: %[[USE1:.*]] = spv.constant 42 : i32
208    // CHECK: %[[USE2:.*]] = spv.constant 42 : i32
209    // CHECK: spv.IAdd %[[USE1]], %[[USE2]]
210    %0 = spv.constant 42 : i32
211    %1 = spv.IAdd %0, %0 : i32
212    spv.ReturnValue %1 : i32
213  }
214
215  // CHECK-LABEL: @const_variable
216  spv.func @const_variable(%arg0 : i32, %arg1 : i32) -> () "None" {
217    // CHECK: %[[CONST:.*]] = spv.constant 5 : i32
218    // CHECK: spv.Variable init(%[[CONST]]) : !spv.ptr<i32, Function>
219    // CHECK: spv.IAdd %arg0, %arg1
220    %0 = spv.IAdd %arg0, %arg1 : i32
221    %1 = spv.constant 5 : i32
222    %2 = spv.Variable init(%1) : !spv.ptr<i32, Function>
223    %3 = spv.Load "Function" %2 : i32
224    %4 = spv.IAdd %0, %3 : i32
225    spv.Return
226  }
227
228  // CHECK-LABEL: @multi_dimensions_const
229  spv.func @multi_dimensions_const() -> (!spv.array<2 x !spv.array<2 x !spv.array<3 x i32, stride=4>, stride=12>, stride=24>) "None" {
230    // CHECK: spv.constant {{\[}}{{\[}}[1 : i32, 2 : i32, 3 : i32], [4 : i32, 5 : i32, 6 : i32]], {{\[}}[7 : i32, 8 : i32, 9 : i32], [10 : i32, 11 : i32, 12 : i32]]] : !spv.array<2 x !spv.array<2 x !spv.array<3 x i32, stride=4>, stride=12>, stride=24>
231    %0 = spv.constant dense<[[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]> : tensor<2x2x3xi32> : !spv.array<2 x !spv.array<2 x !spv.array<3 x i32, stride=4>, stride=12>, stride=24>
232    spv.ReturnValue %0 : !spv.array<2 x !spv.array<2 x !spv.array<3 x i32, stride=4>, stride=12>, stride=24>
233  }
234
235  // CHECK-LABEL: @multi_dimensions_splat_const
236  spv.func @multi_dimensions_splat_const() -> (!spv.array<2 x !spv.array<2 x !spv.array<3 x i32, stride=4>, stride=12>, stride=24>) "None" {
237    // CHECK: spv.constant {{\[}}{{\[}}[1 : i32, 1 : i32, 1 : i32], [1 : i32, 1 : i32, 1 : i32]], {{\[}}[1 : i32, 1 : i32, 1 : i32], [1 : i32, 1 : i32, 1 : i32]]] : !spv.array<2 x !spv.array<2 x !spv.array<3 x i32, stride=4>, stride=12>, stride=24>
238    %0 = spv.constant dense<1> : tensor<2x2x3xi32> : !spv.array<2 x !spv.array<2 x !spv.array<3 x i32, stride=4>, stride=12>, stride=24>
239    spv.ReturnValue %0 : !spv.array<2 x !spv.array<2 x !spv.array<3 x i32, stride=4>, stride=12>, stride=24>
240  }
241}
242