xref: /llvm-project/mlir/test/Target/SPIRV/constant.mlir (revision 2dab551d649cb57127f7b3bea183f069883d76e4)
1// RUN: mlir-translate -no-implicit-module -test-spirv-roundtrip %s | FileCheck %s
2
3spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {
4  // CHECK-LABEL: @bool_const
5  spirv.func @bool_const() -> () "None" {
6    // CHECK: spirv.Constant true
7    %0 = spirv.Constant true
8    // CHECK: spirv.Constant false
9    %1 = spirv.Constant false
10
11    %2 = spirv.Variable init(%0): !spirv.ptr<i1, Function>
12    %3 = spirv.Variable init(%1): !spirv.ptr<i1, Function>
13    spirv.Return
14  }
15
16  // CHECK-LABEL: @i32_const
17  spirv.func @i32_const() -> () "None" {
18    // CHECK: spirv.Constant 0 : i32
19    %0 = spirv.Constant  0 : i32
20    // CHECK: spirv.Constant 10 : i32
21    %1 = spirv.Constant 10 : i32
22    // CHECK: spirv.Constant -5 : i32
23    %2 = spirv.Constant -5 : i32
24
25    %3 = spirv.IAdd %0, %1 : i32
26    %4 = spirv.IAdd %2, %3 : i32
27    spirv.Return
28  }
29
30  // CHECK-LABEL: @si32_const
31  spirv.func @si32_const() -> () "None" {
32    // CHECK: spirv.Constant 0 : si32
33    %0 = spirv.Constant  0 : si32
34    // CHECK: spirv.Constant 10 : si32
35    %1 = spirv.Constant 10 : si32
36    // CHECK: spirv.Constant -5 : si32
37    %2 = spirv.Constant -5 : si32
38
39    %3 = spirv.IAdd %0, %1 : si32
40    %4 = spirv.IAdd %2, %3 : si32
41    spirv.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  spirv.func @ui32_const() -> () "None" {
49    // CHECK: spirv.Constant 0 : i32
50    %0 = spirv.Constant  0 : ui32
51    // CHECK: spirv.Constant 10 : i32
52    %1 = spirv.Constant 10 : ui32
53    // CHECK: spirv.Constant -5 : i32
54    %2 = spirv.Constant 4294967291 : ui32
55
56    %3 = spirv.IAdd %0, %1 : ui32
57    %4 = spirv.IAdd %2, %3 : ui32
58    spirv.Return
59  }
60
61  // CHECK-LABEL: @i64_const
62  spirv.func @i64_const() -> () "None" {
63    // CHECK: spirv.Constant 4294967296 : i64
64    %0 = spirv.Constant           4294967296 : i64 //  2^32
65    // CHECK: spirv.Constant -4294967296 : i64
66    %1 = spirv.Constant          -4294967296 : i64 // -2^32
67    // CHECK: spirv.Constant 9223372036854775807 : i64
68    %2 = spirv.Constant  9223372036854775807 : i64 //  2^63 - 1
69    // CHECK: spirv.Constant -9223372036854775808 : i64
70    %3 = spirv.Constant -9223372036854775808 : i64 // -2^63
71
72    %4 = spirv.IAdd %0, %1 : i64
73    %5 = spirv.IAdd %2, %3 : i64
74    spirv.Return
75  }
76
77  // CHECK-LABEL: @i16_const
78  spirv.func @i16_const() -> () "None" {
79    // CHECK: spirv.Constant -32768 : i16
80    %0 = spirv.Constant -32768 : i16 // -2^15
81    // CHECK: spirv.Constant 32767 : i16
82    %1 = spirv.Constant 32767 : i16 //  2^15 - 1
83
84    %2 = spirv.IAdd %0, %1 : i16
85    spirv.Return
86  }
87
88  // CHECK-LABEL: @i8_const
89  spirv.func @i8_const() -> () "None" {
90    // CHECK: spirv.Constant 0 : i8
91    %0 = spirv.Constant 0 : i8
92    // CHECK: spirv.Constant -1 : i8
93    %1 = spirv.Constant 255 : i8
94
95    // CHECK: spirv.Constant 0 : si8
96    %2 = spirv.Constant 0 : si8
97    // CHECK: spirv.Constant 127 : si8
98    %3 = spirv.Constant 127 : si8
99    // CHECK: spirv.Constant -128 : si8
100    %4 = spirv.Constant -128 : si8
101
102    // CHECK: spirv.Constant 0 : i8
103    %5 = spirv.Constant 0 : ui8
104    // CHECK: spirv.Constant -1 : i8
105    %6 = spirv.Constant 255 : ui8
106
107    %10 = spirv.IAdd %0, %1: i8
108    %11 = spirv.IAdd %2, %3: si8
109    %12 = spirv.IAdd %3, %4: si8
110    %13 = spirv.IAdd %5, %6: ui8
111    spirv.Return
112  }
113
114  // CHECK-LABEL: @float_const
115  spirv.func @float_const() -> () "None" {
116    // CHECK: spirv.Constant 0.000000e+00 : f32
117    %0 = spirv.Constant 0. : f32
118    // CHECK: spirv.Constant 1.000000e+00 : f32
119    %1 = spirv.Constant 1. : f32
120    // CHECK: spirv.Constant -0.000000e+00 : f32
121    %2 = spirv.Constant -0. : f32
122    // CHECK: spirv.Constant -1.000000e+00 : f32
123    %3 = spirv.Constant -1. : f32
124    // CHECK: spirv.Constant 7.500000e-01 : f32
125    %4 = spirv.Constant 0.75 : f32
126    // CHECK: spirv.Constant -2.500000e-01 : f32
127    %5 = spirv.Constant -0.25 : f32
128
129    %6 = spirv.FAdd %0, %1 : f32
130    %7 = spirv.FAdd %2, %3 : f32
131    %8 = spirv.FAdd %4, %5 : f32
132    spirv.Return
133  }
134
135  // CHECK-LABEL: @double_const
136  spirv.func @double_const() -> () "None" {
137    // TODO: test range boundary values
138    // CHECK: spirv.Constant 1.024000e+03 : f64
139    %0 = spirv.Constant 1024. : f64
140    // CHECK: spirv.Constant -1.024000e+03 : f64
141    %1 = spirv.Constant -1024. : f64
142
143    %2 = spirv.FAdd %0, %1 : f64
144    spirv.Return
145  }
146
147  // CHECK-LABEL: @half_const
148  spirv.func @half_const() -> () "None" {
149    // CHECK: spirv.Constant 5.120000e+02 : f16
150    %0 = spirv.Constant 512. : f16
151    // CHECK: spirv.Constant -5.120000e+02 : f16
152    %1 = spirv.Constant -512. : f16
153
154    %2 = spirv.FAdd %0, %1 : f16
155    spirv.Return
156  }
157
158  // CHECK-LABEL: @bool_vector_const
159  spirv.func @bool_vector_const() -> () "None" {
160    // CHECK: spirv.Constant dense<false> : vector<2xi1>
161    %0 = spirv.Constant dense<false> : vector<2xi1>
162    // CHECK: spirv.Constant dense<true> : vector<3xi1>
163    %1 = spirv.Constant dense<true> : vector<3xi1>
164    // CHECK: spirv.Constant dense<[false, true]> : vector<2xi1>
165    %2 = spirv.Constant dense<[false, true]> : vector<2xi1>
166
167    %3 = spirv.Variable init(%0): !spirv.ptr<vector<2xi1>, Function>
168    %4 = spirv.Variable init(%1): !spirv.ptr<vector<3xi1>, Function>
169    %5 = spirv.Variable init(%2): !spirv.ptr<vector<2xi1>, Function>
170    spirv.Return
171  }
172
173  // CHECK-LABEL: @int_vector_const
174  spirv.func @int_vector_const() -> () "None" {
175    // CHECK: spirv.Constant dense<0> : vector<3xi32>
176    %0 = spirv.Constant dense<0> : vector<3xi32>
177    // CHECK: spirv.Constant dense<1> : vector<3xi32>
178    %1 = spirv.Constant dense<1> : vector<3xi32>
179    // CHECK: spirv.Constant dense<[2, -3, 4]> : vector<3xi32>
180    %2 = spirv.Constant dense<[2, -3, 4]> : vector<3xi32>
181
182    %3 = spirv.IAdd %0, %1 : vector<3xi32>
183    %4 = spirv.IAdd %2, %3 : vector<3xi32>
184    spirv.Return
185  }
186
187  // CHECK-LABEL: @fp_vector_const
188  spirv.func @fp_vector_const() -> () "None" {
189    // CHECK: spirv.Constant dense<0.000000e+00> : vector<4xf32>
190    %0 = spirv.Constant dense<0.> : vector<4xf32>
191    // CHECK: spirv.Constant dense<-1.500000e+01> : vector<4xf32>
192    %1 = spirv.Constant dense<-15.> : vector<4xf32>
193    // CHECK: spirv.Constant dense<[7.500000e-01, -2.500000e-01, 1.000000e+01, 4.200000e+01]> : vector<4xf32>
194    %2 = spirv.Constant dense<[0.75, -0.25, 10., 42.]> : vector<4xf32>
195
196    %3 = spirv.FAdd %0, %1 : vector<4xf32>
197    %4 = spirv.FAdd %2, %3 : vector<4xf32>
198    spirv.Return
199  }
200
201  // CHECK-LABEL: @ui64_array_const
202  spirv.func @ui64_array_const() -> (!spirv.array<3xui64>) "None" {
203    // CHECK: spirv.Constant [5, 6, 7] : !spirv.array<3 x i64>
204    %0 = spirv.Constant [5 : ui64, 6 : ui64, 7 : ui64] : !spirv.array<3 x ui64>
205
206    spirv.ReturnValue %0: !spirv.array<3xui64>
207  }
208
209  // CHECK-LABEL: @si32_array_const
210  spirv.func @si32_array_const() -> (!spirv.array<3xsi32>) "None" {
211    // CHECK: spirv.Constant [5 : si32, 6 : si32, 7 : si32] : !spirv.array<3 x si32>
212    %0 = spirv.Constant [5 : si32, 6 : si32, 7 : si32] : !spirv.array<3 x si32>
213
214    spirv.ReturnValue %0 : !spirv.array<3xsi32>
215  }
216  // CHECK-LABEL: @float_array_const
217  spirv.func @float_array_const() -> (!spirv.array<2 x vector<2xf32>>) "None" {
218    // CHECK: spirv.Constant [dense<3.000000e+00> : vector<2xf32>, dense<[4.000000e+00, 5.000000e+00]> : vector<2xf32>] : !spirv.array<2 x vector<2xf32>>
219    %0 = spirv.Constant [dense<3.0> : vector<2xf32>, dense<[4., 5.]> : vector<2xf32>] : !spirv.array<2 x vector<2xf32>>
220
221    spirv.ReturnValue %0 : !spirv.array<2 x vector<2xf32>>
222  }
223
224  // CHECK-LABEL: @ignore_not_used_const
225  spirv.func @ignore_not_used_const() -> () "None" {
226    %0 = spirv.Constant false
227    // CHECK-NEXT: spirv.Return
228    spirv.Return
229  }
230
231  // CHECK-LABEL: @materialize_const_at_each_use
232  spirv.func @materialize_const_at_each_use() -> (i32) "None" {
233    // CHECK: %[[USE1:.*]] = spirv.Constant 42 : i32
234    // CHECK: %[[USE2:.*]] = spirv.Constant 42 : i32
235    // CHECK: spirv.IAdd %[[USE1]], %[[USE2]]
236    %0 = spirv.Constant 42 : i32
237    %1 = spirv.IAdd %0, %0 : i32
238    spirv.ReturnValue %1 : i32
239  }
240
241  // CHECK-LABEL: @const_variable
242  spirv.func @const_variable(%arg0 : i32, %arg1 : i32) -> () "None" {
243    // CHECK: %[[CONST:.*]] = spirv.Constant 5 : i32
244    // CHECK: spirv.Variable init(%[[CONST]]) : !spirv.ptr<i32, Function>
245    // CHECK: spirv.IAdd %arg0, %arg1
246    %0 = spirv.IAdd %arg0, %arg1 : i32
247    %1 = spirv.Constant 5 : i32
248    %2 = spirv.Variable init(%1) : !spirv.ptr<i32, Function>
249    %3 = spirv.Load "Function" %2 : i32
250    %4 = spirv.IAdd %0, %3 : i32
251    spirv.Return
252  }
253
254  // CHECK-LABEL: @multi_dimensions_const
255  spirv.func @multi_dimensions_const() -> (!spirv.array<2 x !spirv.array<2 x !spirv.array<3 x i32, stride=4>, stride=12>, stride=24>) "None" {
256    // CHECK: spirv.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]]] : !spirv.array<2 x !spirv.array<2 x !spirv.array<3 x i32, stride=4>, stride=12>, stride=24>
257    %0 = spirv.Constant dense<[[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]> : tensor<2x2x3xi32> : !spirv.array<2 x !spirv.array<2 x !spirv.array<3 x i32, stride=4>, stride=12>, stride=24>
258    spirv.ReturnValue %0 : !spirv.array<2 x !spirv.array<2 x !spirv.array<3 x i32, stride=4>, stride=12>, stride=24>
259  }
260
261  // CHECK-LABEL: @multi_dimensions_splat_const
262  spirv.func @multi_dimensions_splat_const() -> (!spirv.array<2 x !spirv.array<2 x !spirv.array<3 x i32, stride=4>, stride=12>, stride=24>) "None" {
263    // CHECK: spirv.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]]] : !spirv.array<2 x !spirv.array<2 x !spirv.array<3 x i32, stride=4>, stride=12>, stride=24>
264    %0 = spirv.Constant dense<1> : tensor<2x2x3xi32> : !spirv.array<2 x !spirv.array<2 x !spirv.array<3 x i32, stride=4>, stride=12>, stride=24>
265    spirv.ReturnValue %0 : !spirv.array<2 x !spirv.array<2 x !spirv.array<3 x i32, stride=4>, stride=12>, stride=24>
266  }
267
268  // CHECK-LABEL: @signless_int_const_bit_extension
269  spirv.func @signless_int_const_bit_extension() -> (i16) "None" {
270    // CHECK: spirv.Constant -1 : i16
271    %signless_minus_one = spirv.Constant -1 : i16
272    spirv.ReturnValue %signless_minus_one : i16
273  }
274  // CHECK-LABEL: @signed_int_const_bit_extension
275  spirv.func @signed_int_const_bit_extension() -> (si16) "None" {
276    // CHECK: spirv.Constant -1 : si16
277    %signed_minus_one = spirv.Constant -1 : si16
278    spirv.ReturnValue %signed_minus_one : si16
279  }
280}
281