[mlir][py] Enable loading only specified dialects during creation. (#121421)
[llvm-project.git] / mlir / test / Target / SPIRV / loop.mlir
blobd89600558f56dd5e1c9e875b163327d276eb361d
1 // RUN: mlir-translate -no-implicit-module -split-input-file -test-spirv-roundtrip %s | FileCheck %s
3 // Single loop
5 spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {
6   // for (int i = 0; i < count; ++i) {}
7 // CHECK-LABEL: @loop
8   spirv.func @loop(%count : i32) -> () "None" {
9     %zero = spirv.Constant 0: i32
10     %one = spirv.Constant 1: i32
11     %var = spirv.Variable init(%zero) : !spirv.ptr<i32, Function>
13 // CHECK:        spirv.Branch ^bb1
14 // CHECK-NEXT: ^bb1:
15 // CHECK-NEXT:   spirv.mlir.loop
16     spirv.mlir.loop {
17 // CHECK-NEXT:     spirv.Branch ^bb1
18       spirv.Branch ^header
20 // CHECK-NEXT:   ^bb1:
21     ^header:
22 // CHECK-NEXT:     spirv.Load
23       %val0 = spirv.Load "Function" %var : i32
24 // CHECK-NEXT:     spirv.SLessThan
25       %cmp = spirv.SLessThan %val0, %count : i32
26 // CHECK-NEXT:     spirv.BranchConditional %{{.*}} [1, 1], ^bb2, ^bb4
27       spirv.BranchConditional %cmp [1, 1], ^body, ^merge
29 // CHECK-NEXT:   ^bb2:
30     ^body:
31       // Do nothing
32 // CHECK-NEXT:     spirv.Branch ^bb3
33       spirv.Branch ^continue
35 // CHECK-NEXT:   ^bb3:
36     ^continue:
37 // CHECK-NEXT:     spirv.Load
38       %val1 = spirv.Load "Function" %var : i32
39 // CHECK-NEXT:     spirv.Constant 1
40 // CHECK-NEXT:     spirv.IAdd
41       %add = spirv.IAdd %val1, %one : i32
42 // CHECK-NEXT:     spirv.Store
43       spirv.Store "Function" %var, %add : i32
44 // CHECK-NEXT:     spirv.Branch ^bb1
45       spirv.Branch ^header
47 // CHECK-NEXT:   ^bb4:
48 // CHECK-NEXT:     spirv.mlir.merge
49     ^merge:
50       spirv.mlir.merge
51     }
52     spirv.Return
53   }
55   spirv.func @main() -> () "None" {
56     spirv.Return
57   }
58   spirv.EntryPoint "GLCompute" @main
61 // -----
63 // Single loop with block arguments
65 spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {
66   spirv.GlobalVariable @GV1 bind(0, 0) : !spirv.ptr<!spirv.struct<(!spirv.array<10 x f32, stride=4> [0])>, StorageBuffer>
67   spirv.GlobalVariable @GV2 bind(0, 1) : !spirv.ptr<!spirv.struct<(!spirv.array<10 x f32, stride=4> [0])>, StorageBuffer>
68 // CHECK-LABEL: @loop_kernel
69   spirv.func @loop_kernel() "None" {
70     %0 = spirv.mlir.addressof @GV1 : !spirv.ptr<!spirv.struct<(!spirv.array<10 x f32, stride=4> [0])>, StorageBuffer>
71     %1 = spirv.Constant 0 : i32
72     %2 = spirv.AccessChain %0[%1] : !spirv.ptr<!spirv.struct<(!spirv.array<10 x f32, stride=4> [0])>, StorageBuffer>, i32 -> !spirv.ptr<!spirv.array<10 x f32, stride=4>, StorageBuffer>
73     %3 = spirv.mlir.addressof @GV2 : !spirv.ptr<!spirv.struct<(!spirv.array<10 x f32, stride=4> [0])>, StorageBuffer>
74     %5 = spirv.AccessChain %3[%1] : !spirv.ptr<!spirv.struct<(!spirv.array<10 x f32, stride=4> [0])>, StorageBuffer>, i32 -> !spirv.ptr<!spirv.array<10 x f32, stride=4>, StorageBuffer>
75     %6 = spirv.Constant 4 : i32
76     %7 = spirv.Constant 42 : i32
77     %8 = spirv.Constant 2 : i32
78 // CHECK:        spirv.Branch ^bb1(%{{.*}} : i32)
79 // CHECK-NEXT: ^bb1(%[[OUTARG:.*]]: i32):
80 // CHECK-NEXT:   spirv.mlir.loop {
81     spirv.mlir.loop {
82 // CHECK-NEXT:     spirv.Branch ^bb1(%[[OUTARG]] : i32)
83       spirv.Branch ^header(%6 : i32)
84 // CHECK-NEXT:   ^bb1(%[[HEADARG:.*]]: i32):
85     ^header(%9: i32):
86       %10 = spirv.SLessThan %9, %7 : i32
87 // CHECK:          spirv.BranchConditional %{{.*}}, ^bb2, ^bb3
88       spirv.BranchConditional %10, ^body, ^merge
89 // CHECK-NEXT:   ^bb2:     // pred: ^bb1
90     ^body:
91       %11 = spirv.AccessChain %2[%9] : !spirv.ptr<!spirv.array<10 x f32, stride=4>, StorageBuffer>, i32 -> !spirv.ptr<f32, StorageBuffer>
92       %12 = spirv.Load "StorageBuffer" %11 : f32
93       %13 = spirv.AccessChain %5[%9] : !spirv.ptr<!spirv.array<10 x f32, stride=4>, StorageBuffer>, i32 -> !spirv.ptr<f32, StorageBuffer>
94       spirv.Store "StorageBuffer" %13, %12 : f32
95 // CHECK:          %[[ADD:.*]] = spirv.IAdd
96       %14 = spirv.IAdd %9, %8 : i32
97 // CHECK-NEXT:     spirv.Branch ^bb1(%[[ADD]] : i32)
98       spirv.Branch ^header(%14 : i32)
99 // CHECK-NEXT:   ^bb3:
100     ^merge:
101 // CHECK-NEXT:     spirv.mlir.merge
102       spirv.mlir.merge
103     }
104     spirv.Return
105   }
106   spirv.EntryPoint "GLCompute" @loop_kernel
107   spirv.ExecutionMode @loop_kernel "LocalSize", 1, 1, 1
110 // -----
112 // Nested loop
114 spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {
115   // for (int i = 0; i < count; ++i) {
116   //   for (int j = 0; j < count; ++j) { }
117   // }
118 // CHECK-LABEL: @loop
119   spirv.func @loop(%count : i32) -> () "None" {
120     %zero = spirv.Constant 0: i32
121     %one = spirv.Constant 1: i32
122     %ivar = spirv.Variable init(%zero) : !spirv.ptr<i32, Function>
123     %jvar = spirv.Variable init(%zero) : !spirv.ptr<i32, Function>
125 // CHECK:        spirv.Branch ^bb1
126 // CHECK-NEXT: ^bb1:
127 // CHECK-NEXT:   spirv.mlir.loop control(Unroll)
128     spirv.mlir.loop control(Unroll) {
129 // CHECK-NEXT:     spirv.Branch ^bb1
130       spirv.Branch ^header
132 // CHECK-NEXT:   ^bb1:
133     ^header:
134 // CHECK-NEXT:     spirv.Load
135       %ival0 = spirv.Load "Function" %ivar : i32
136 // CHECK-NEXT:     spirv.SLessThan
137       %icmp = spirv.SLessThan %ival0, %count : i32
138 // CHECK-NEXT:     spirv.BranchConditional %{{.*}}, ^bb2, ^bb5
139       spirv.BranchConditional %icmp, ^body, ^merge
141 // CHECK-NEXT:   ^bb2:
142     ^body:
143 // CHECK-NEXT:     spirv.Constant 0
144 // CHECK-NEXT:           spirv.Store
145       spirv.Store "Function" %jvar, %zero : i32
146 // CHECK-NEXT:     spirv.Branch ^bb3
147 // CHECK-NEXT:   ^bb3:
148 // CHECK-NEXT:     spirv.mlir.loop control(DontUnroll)
149       spirv.mlir.loop control(DontUnroll) {
150 // CHECK-NEXT:       spirv.Branch ^bb1
151         spirv.Branch ^header
153 // CHECK-NEXT:     ^bb1:
154       ^header:
155 // CHECK-NEXT:       spirv.Load
156         %jval0 = spirv.Load "Function" %jvar : i32
157 // CHECK-NEXT:       spirv.SLessThan
158         %jcmp = spirv.SLessThan %jval0, %count : i32
159 // CHECK-NEXT:       spirv.BranchConditional %{{.*}}, ^bb2, ^bb4
160         spirv.BranchConditional %jcmp, ^body, ^merge
162 // CHECK-NEXT:     ^bb2:
163       ^body:
164         // Do nothing
165 // CHECK-NEXT:       spirv.Branch ^bb3
166         spirv.Branch ^continue
168 // CHECK-NEXT:     ^bb3:
169       ^continue:
170 // CHECK-NEXT:       spirv.Load
171         %jval1 = spirv.Load "Function" %jvar : i32
172 // CHECK-NEXT:       spirv.Constant 1
173 // CHECK-NEXT:       spirv.IAdd
174         %add = spirv.IAdd %jval1, %one : i32
175 // CHECK-NEXT:       spirv.Store
176         spirv.Store "Function" %jvar, %add : i32
177 // CHECK-NEXT:       spirv.Branch ^bb1
178         spirv.Branch ^header
180 // CHECK-NEXT:     ^bb4:
181       ^merge:
182 // CHECK-NEXT:       spirv.mlir.merge
183         spirv.mlir.merge
184       } // end inner loop
186 // CHECK:          spirv.Branch ^bb4
187       spirv.Branch ^continue
189 // CHECK-NEXT:   ^bb4:
190     ^continue:
191 // CHECK-NEXT:     spirv.Load
192       %ival1 = spirv.Load "Function" %ivar : i32
193 // CHECK-NEXT:     spirv.Constant 1
194 // CHECK-NEXT:     spirv.IAdd
195       %add = spirv.IAdd %ival1, %one : i32
196 // CHECK-NEXT:     spirv.Store
197       spirv.Store "Function" %ivar, %add : i32
198 // CHECK-NEXT:     spirv.Branch ^bb1
199       spirv.Branch ^header
201 // CHECK-NEXT:   ^bb5:
202 // CHECK-NEXT:     spirv.mlir.merge
203     ^merge:
204       spirv.mlir.merge
205     } // end outer loop
206     spirv.Return
207   }
209   spirv.func @main() -> () "None" {
210     spirv.Return
211   }
212   spirv.EntryPoint "GLCompute" @main
216 // -----
218 // Loop with selection in its header
220 spirv.module Physical64 OpenCL requires #spirv.vce<v1.0, [Kernel, Linkage, Addresses, Int64], []> {
221 // CHECK-LABEL:   @kernel
222 // CHECK-SAME:    (%[[INPUT0:.+]]: i64)
223   spirv.func @kernel(%input: i64) "None" {
224 // CHECK-NEXT:     %[[VAR:.+]] = spirv.Variable : !spirv.ptr<i1, Function>
225 // CHECK-NEXT:     spirv.Branch ^[[BB0:.+]](%[[INPUT0]] : i64)
226 // CHECK-NEXT:   ^[[BB0]](%[[INPUT1:.+]]: i64):
227     %cst0_i64 = spirv.Constant 0 : i64
228     %true = spirv.Constant true
229     %false = spirv.Constant false
230 // CHECK-NEXT:     spirv.mlir.loop {
231     spirv.mlir.loop {
232 // CHECK-NEXT:       spirv.Branch ^[[LOOP_HEADER:.+]](%[[INPUT1]] : i64)
233       spirv.Branch ^loop_header(%input : i64)
234 // CHECK-NEXT:     ^[[LOOP_HEADER]](%[[ARG1:.+]]: i64):
235     ^loop_header(%arg1: i64):
236 // CHECK-NEXT:       spirv.Branch ^[[LOOP_BODY:.+]]
237 // CHECK-NEXT:     ^[[LOOP_BODY]]:
238 // CHECK-NEXT:         %[[C0:.+]] = spirv.Constant 0 : i64
239       %gt = spirv.SGreaterThan %arg1, %cst0_i64 : i64
240 // CHECK-NEXT:         %[[GT:.+]] = spirv.SGreaterThan %[[ARG1]], %[[C0]] : i64
241 // CHECK-NEXT:         spirv.Branch ^[[BB1:.+]]
242 // CHECK-NEXT:     ^[[BB1]]:
243       %var = spirv.Variable : !spirv.ptr<i1, Function>
244 // CHECK-NEXT:       spirv.mlir.selection {
245       spirv.mlir.selection {
246 // CHECK-NEXT:         spirv.BranchConditional %[[GT]], ^[[THEN:.+]], ^[[ELSE:.+]]
247         spirv.BranchConditional %gt, ^then, ^else
248 // CHECK-NEXT:       ^[[THEN]]:
249       ^then:
250 // CHECK-NEXT:         %true = spirv.Constant true
251 // CHECK-NEXT:         spirv.Store "Function" %[[VAR]], %true : i1
252         spirv.Store "Function" %var, %true : i1
253 // CHECK-NEXT:         spirv.Branch ^[[SELECTION_MERGE:.+]]
254         spirv.Branch ^selection_merge
255 // CHECK-NEXT:       ^[[ELSE]]:
256       ^else:
257 // CHECK-NEXT:         %false = spirv.Constant false
258 // CHECK-NEXT:         spirv.Store "Function" %[[VAR]], %false : i1
259         spirv.Store "Function" %var, %false : i1
260 // CHECK-NEXT:         spirv.Branch ^[[SELECTION_MERGE]]
261         spirv.Branch ^selection_merge
262 // CHECK-NEXT:       ^[[SELECTION_MERGE]]:
263       ^selection_merge:
264 // CHECK-NEXT:         spirv.mlir.merge
265         spirv.mlir.merge
266 // CHECK-NEXT:       }
267       }
268 // CHECK-NEXT:       %[[LOAD:.+]] = spirv.Load "Function" %[[VAR]] : i1
269       %load = spirv.Load "Function" %var : i1
270 // CHECK-NEXT:       spirv.BranchConditional %[[LOAD]], ^[[CONTINUE:.+]](%[[ARG1]] : i64), ^[[LOOP_MERGE:.+]]
271       spirv.BranchConditional %load, ^continue(%arg1 : i64), ^loop_merge
272 // CHECK-NEXT:     ^[[CONTINUE]](%[[ARG2:.+]]: i64):
273     ^continue(%arg2: i64):
274 // CHECK-NEXT:       %[[C0:.+]] = spirv.Constant 0 : i64
275 // CHECK-NEXT:       %[[LT:.+]] = spirv.SLessThan %[[ARG2]], %[[C0]] : i64
276       %lt = spirv.SLessThan %arg2, %cst0_i64 : i64
277 // CHECK-NEXT:       spirv.Store "Function" %[[VAR]], %[[LT]] : i1
278       spirv.Store "Function" %var, %lt : i1
279 // CHECK-NEXT:       spirv.Branch ^[[LOOP_HEADER]](%[[ARG2]] : i64)
280       spirv.Branch ^loop_header(%arg2 : i64)
281 // CHECK-NEXT:     ^[[LOOP_MERGE]]:
282     ^loop_merge:
283 // CHECK-NEXT:       spirv.mlir.merge
284       spirv.mlir.merge
285 // CHECK-NEXT:     }
286     }
287 // CHECK-NEXT:     spirv.Return
288     spirv.Return
289   }