[RISCV] Fix the code alignment for GroupFloatVectors. NFC
[llvm-project.git] / mlir / test / Conversion / SCFToGPU / parallel_loop.mlir
blob6630cacc43bf46133eb0d5619412152ad0a39e07
1 // RUN: mlir-opt -convert-parallel-loops-to-gpu -split-input-file -verify-diagnostics %s | FileCheck %s
3 // 2-d parallel loop mapped to block.y and block.x
5 func @parallel_loop_bidy_bidx(%arg0 : index, %arg1 : index, %arg2 : index,
6                               %arg3 : index, %arg4 : index,
7                               %buf : memref<?x?xf32>,
8                               %res : memref<?x?xf32>) {
9   %step = arith.constant 2 : index
10   scf.parallel (%i0, %i1) = (%arg0, %arg1) to (%arg2, %arg3)
11                                           step (%arg4, %step)  {
12     %val = memref.load %buf[%i0, %i1] : memref<?x?xf32>
13     memref.store %val, %res[%i1, %i0] : memref<?x?xf32>
14   } { mapping = [{processor = 1, map = affine_map<(d0) -> (d0)>, bound = affine_map<(d0) -> (d0)>}, {processor = 0, map = affine_map<(d0) -> (d0)>, bound = affine_map<(d0) -> (d0)>}] }
15   return
18 // CHECK:       #[[$MAP0:.*]] = affine_map<(d0)[s0, s1] -> ((d0 - s0) ceildiv s1)>
19 // CHECK:       #[[$MAP1:.*]] = affine_map<(d0)[s0, s1] -> (d0 * s0 + s1)>
21 // CHECK:       module {
22 // CHECK-LABEL:   func @parallel_loop_bidy_bidx(
23 // CHECK-SAME:                                  [[VAL_0:%.*]]: index, [[VAL_1:%.*]]: index, [[VAL_2:%.*]]: index, [[VAL_3:%.*]]: index, [[VAL_4:%.*]]: index, [[VAL_5:%.*]]: memref<?x?xf32>, [[VAL_6:%.*]]: memref<?x?xf32>) {
24 // CHECK:           [[VAL_7:%.*]] = arith.constant 2 : index
25 // CHECK:           [[VAL_8:%.*]] = arith.constant 1 : index
26 // CHECK:           [[VAL_9:%.*]] = affine.apply #[[$MAP0]]([[VAL_2]]){{\[}}[[VAL_0]], [[VAL_4]]]
27 // CHECK:           [[VAL_10:%.*]] = affine.apply #[[$MAP0]]([[VAL_3]]){{\[}}[[VAL_1]], [[VAL_7]]]
28 // CHECK:           gpu.launch blocks([[VAL_11:%.*]], [[VAL_12:%.*]], [[VAL_13:%.*]]) in ([[VAL_14:%.*]] = [[VAL_10]], [[VAL_15:%.*]] = [[VAL_9]], [[VAL_16:%.*]] = [[VAL_8]]) threads([[VAL_17:%.*]], [[VAL_18:%.*]], [[VAL_19:%.*]]) in ([[VAL_20:%.*]] = [[VAL_8]], [[VAL_21:%.*]] = [[VAL_8]], [[VAL_22:%.*]] = [[VAL_8]]) {
29 // CHECK:             [[VAL_23:%.*]] = affine.apply #[[$MAP1]]([[VAL_12]]){{\[}}[[VAL_4]], [[VAL_0]]]
30 // CHECK:             [[VAL_24:%.*]] = affine.apply #[[$MAP1]]([[VAL_11]]){{\[}}[[VAL_7]], [[VAL_1]]]
31 // CHECK:             [[VAL_25:%.*]] = memref.load [[VAL_5]]{{\[}}[[VAL_23]], [[VAL_24]]] : memref<?x?xf32>
32 // CHECK:             memref.store [[VAL_25]], [[VAL_6]]{{\[}}[[VAL_24]], [[VAL_23]]] : memref<?x?xf32>
33 // CHECK:             gpu.terminator
34 // CHECK:           }
35 // CHECK:           return
36 // CHECK:         }
37 // CHECK:       }
39 // -----
41 // tiled 2-d parallel loop mapped to block.y and block.x and thread.y and thread.x.
43 func @parallel_loop_tiled(%arg0 : index, %arg1 : index, %arg2 : index,
44                         %arg3 : index,
45                         %buf : memref<?x?xf32>,
46                         %res : memref<?x?xf32>) {
47   %zero = arith.constant 0 : index
48   %one = arith.constant 1 : index
49   %four = arith.constant 4 : index
50   scf.parallel (%i0, %i1) = (%arg0, %arg1) to (%arg2, %arg3)
51                                           step (%four, %four)  {
52     scf.parallel (%si0, %si1) = (%zero, %zero) to (%four, %four)
53                                             step (%one, %one)  {
54       %idx0 = arith.addi %i0, %si0 : index
55       %idx1 = arith.addi %i1, %si1 : index
56       %val = memref.load %buf[%idx0, %idx1] : memref<?x?xf32>
57       memref.store %val, %res[%idx1, %idx0] : memref<?x?xf32>
58     } { mapping = [
59         {processor = 4, map = affine_map<(d0) -> (d0)>, bound = affine_map<(d0) -> (d0)>},
60         {processor = 3, map = affine_map<(d0) -> (d0)>, bound = affine_map<(d0) -> (d0)>}
61      ] }
62   } { mapping = [
63       {processor = 1, map = affine_map<(d0) -> (d0)>, bound = affine_map<(d0) -> (d0)>},
64       {processor = 0, map = affine_map<(d0) -> (d0)>, bound = affine_map<(d0) -> (d0)>}
65     ] }
66   return
69 // CHECK:       #[[$MAP0:.*]] = affine_map<(d0)[s0, s1] -> ((d0 - s0) ceildiv s1)>
70 // CHECK:       #[[$MAP1:.*]] = affine_map<(d0)[s0, s1] -> (d0 * s0 + s1)>
72 // CHECK:       module {
73 // CHECK-LABEL:   func @parallel_loop_tiled(
74 // CHECK-SAME:                              [[VAL_26:%.*]]: index, [[VAL_27:%.*]]: index, [[VAL_28:%.*]]: index, [[VAL_29:%.*]]: index, [[VAL_30:%.*]]: memref<?x?xf32>, [[VAL_31:%.*]]: memref<?x?xf32>) {
75 // CHECK:           [[VAL_32:%.*]] = arith.constant 0 : index
76 // CHECK:           [[VAL_33:%.*]] = arith.constant 1 : index
77 // CHECK:           [[VAL_34:%.*]] = arith.constant 4 : index
78 // CHECK:           [[VAL_35:%.*]] = arith.constant 1 : index
79 // CHECK:           [[VAL_36:%.*]] = affine.apply #[[$MAP0]]([[VAL_28]]){{\[}}[[VAL_26]], [[VAL_34]]]
80 // CHECK:           [[VAL_37:%.*]] = affine.apply #[[$MAP0]]([[VAL_29]]){{\[}}[[VAL_27]], [[VAL_34]]]
81 // CHECK:           [[VAL_38:%.*]] = affine.apply #[[$MAP0]]([[VAL_34]]){{\[}}[[VAL_32]], [[VAL_33]]]
82 // CHECK:           [[VAL_39:%.*]] = affine.apply #[[$MAP0]]([[VAL_34]]){{\[}}[[VAL_32]], [[VAL_33]]]
83 // CHECK:           gpu.launch blocks([[VAL_40:%.*]], [[VAL_41:%.*]], [[VAL_42:%.*]]) in ([[VAL_43:%.*]] = [[VAL_37]], [[VAL_44:%.*]] = [[VAL_36]], [[VAL_45:%.*]] = [[VAL_35]]) threads([[VAL_46:%.*]], [[VAL_47:%.*]], [[VAL_48:%.*]]) in ([[VAL_49:%.*]] = [[VAL_39]], [[VAL_50:%.*]] = [[VAL_38]], [[VAL_51:%.*]] = [[VAL_35]]) {
84 // CHECK:             [[VAL_52:%.*]] = affine.apply #[[$MAP1]]([[VAL_41]]){{\[}}[[VAL_34]], [[VAL_26]]]
85 // CHECK:             [[VAL_53:%.*]] = affine.apply #[[$MAP1]]([[VAL_40]]){{\[}}[[VAL_34]], [[VAL_27]]]
86 // CHECK:             [[VAL_54:%.*]] = affine.apply #[[$MAP1]]([[VAL_47]]){{\[}}[[VAL_33]], [[VAL_32]]]
87 // CHECK:             [[VAL_55:%.*]] = affine.apply #[[$MAP1]]([[VAL_46]]){{\[}}[[VAL_33]], [[VAL_32]]]
88 // CHECK:             [[VAL_56:%.*]] = arith.addi [[VAL_52]], [[VAL_54]] : index
89 // CHECK:             [[VAL_57:%.*]] = arith.addi [[VAL_53]], [[VAL_55]] : index
90 // CHECK:             [[VAL_58:%.*]] = memref.load [[VAL_30]]{{\[}}[[VAL_56]], [[VAL_57]]] : memref<?x?xf32>
91 // CHECK:             memref.store [[VAL_58]], [[VAL_31]]{{\[}}[[VAL_57]], [[VAL_56]]] : memref<?x?xf32>
92 // CHECK:             gpu.terminator
93 // CHECK:           }
94 // CHECK:           return
95 // CHECK:         }
96 // CHECK:       }
98 // -----
100 // 2-d parallel loop mapped to block.y and sequential
102 func @parallel_loop_bidy_seq(%arg0 : index, %arg1 : index, %arg2 : index,
103                              %arg3 : index, %arg4 : index,
104                              %buf : memref<?x?xf32>,
105                              %res : memref<?x?xf32>) {
106   %step = arith.constant 2 : index
107   scf.parallel (%i0, %i1) = (%arg0, %arg1) to (%arg2, %arg3)
108                                           step (%arg4, %step)  {
109     %val = memref.load %buf[%i0, %i1] : memref<?x?xf32>
110     memref.store %val, %res[%i1, %i0] : memref<?x?xf32>
111   } { mapping = [
112       {processor = 1, map = affine_map<(d0) -> (d0)>, bound = affine_map<(d0) -> (d0)>},
113       {processor = 6, map = affine_map<(d0) -> (d0)>, bound = affine_map<(d0) -> (d0)>}
114     ] }
115   return
118 // CHECK:       #[[$MAP0:.*]] = affine_map<(d0)[s0, s1] -> ((d0 - s0) ceildiv s1)>
119 // CHECK:       #[[$MAP1:.*]] = affine_map<(d0)[s0, s1] -> (d0 * s0 + s1)>
121 // CHECK:       module {
122 // CHECK-LABEL:   func @parallel_loop_bidy_seq(
123 // CHECK-SAME:                                 [[VAL_59:%.*]]: index, [[VAL_60:%.*]]: index, [[VAL_61:%.*]]: index, [[VAL_62:%.*]]: index, [[VAL_63:%.*]]: index, [[VAL_64:%.*]]: memref<?x?xf32>, [[VAL_65:%.*]]: memref<?x?xf32>) {
124 // CHECK:           [[VAL_66:%.*]] = arith.constant 2 : index
125 // CHECK:           [[VAL_67:%.*]] = arith.constant 1 : index
126 // CHECK:           [[VAL_68:%.*]] = affine.apply #[[$MAP0]]([[VAL_61]]){{\[}}[[VAL_59]], [[VAL_63]]]
127 // CHECK:           gpu.launch blocks([[VAL_69:%.*]], [[VAL_70:%.*]], [[VAL_71:%.*]]) in ([[VAL_72:%.*]] = [[VAL_67]], [[VAL_73:%.*]] = [[VAL_68]], [[VAL_74:%.*]] = [[VAL_67]]) threads([[VAL_75:%.*]], [[VAL_76:%.*]], [[VAL_77:%.*]]) in ([[VAL_78:%.*]] = [[VAL_67]], [[VAL_79:%.*]] = [[VAL_67]], [[VAL_80:%.*]] = [[VAL_67]]) {
128 // CHECK:             [[VAL_81:%.*]] = affine.apply #[[$MAP1]]([[VAL_70]]){{\[}}[[VAL_63]], [[VAL_59]]]
129 // CHECK:             scf.for [[VAL_82:%.*]] = [[VAL_60]] to [[VAL_62]] step [[VAL_66]] {
130 // CHECK:               [[VAL_83:%.*]] = memref.load [[VAL_64]]{{\[}}[[VAL_81]], [[VAL_82]]] : memref<?x?xf32>
131 // CHECK:               memref.store [[VAL_83]], [[VAL_65]]{{\[}}[[VAL_82]], [[VAL_81]]] : memref<?x?xf32>
132 // CHECK:             }
133 // CHECK:             gpu.terminator
134 // CHECK:           }
135 // CHECK:           return
136 // CHECK:         }
137 // CHECK:       }
139 // -----
141 // tiled 2-d parallel loop mapped to block.y and seq. and thread.y and seq.
143 func @parallel_loop_tiled_seq(%arg0 : index, %arg1 : index, %arg2 : index,
144                               %arg3 : index,
145                               %buf : memref<?x?xf32>,
146                               %res : memref<?x?xf32>) {
147   %zero = arith.constant 0 : index
148   %one = arith.constant 1 : index
149   %four = arith.constant 4 : index
150   scf.parallel (%i0, %i1) = (%arg0, %arg1) to (%arg2, %arg3)
151                                           step (%four, %four)  {
152     scf.parallel (%si0, %si1) = (%zero, %zero) to (%four, %four)
153                                             step (%one, %one)  {
154       %idx0 = arith.addi %i0, %si0 : index
155       %idx1 = arith.addi %i1, %si1 : index
156       %val = memref.load %buf[%idx0, %idx1] : memref<?x?xf32>
157       memref.store %val, %res[%idx1, %idx0] : memref<?x?xf32>
158     } { mapping = [
159         {processor = 4, map = affine_map<(d0) -> (d0)>, bound = affine_map<(d0) -> (d0)>},
160         {processor = 6, map = affine_map<(d0) -> (d0)>, bound = affine_map<(d0) -> (d0)>}
161       ] }
162   } { mapping = [
163       {processor = 1, map = affine_map<(d0) -> (d0)>, bound = affine_map<(d0) -> (d0)>},
164       {processor = 6, map = affine_map<(d0) -> (d0)>, bound = affine_map<(d0) -> (d0)>}
165     ] }
166   return
169 // CHECK:       #[[$MAP0:.*]] = affine_map<(d0)[s0, s1] -> ((d0 - s0) ceildiv s1)>
170 // CHECK:       #[[$MAP1:.*]] = affine_map<(d0)[s0, s1] -> (d0 * s0 + s1)>
172 // CHECK:       module {
173 // CHECK-LABEL:   func @parallel_loop_tiled_seq(
174 // CHECK-SAME:                                  [[VAL_84:%.*]]: index, [[VAL_85:%.*]]: index, [[VAL_86:%.*]]: index, [[VAL_87:%.*]]: index, [[VAL_88:%.*]]: memref<?x?xf32>, [[VAL_89:%.*]]: memref<?x?xf32>) {
175 // CHECK:           [[VAL_90:%.*]] = arith.constant 0 : index
176 // CHECK:           [[VAL_91:%.*]] = arith.constant 1 : index
177 // CHECK:           [[VAL_92:%.*]] = arith.constant 4 : index
178 // CHECK:           [[VAL_93:%.*]] = arith.constant 1 : index
179 // CHECK:           [[VAL_94:%.*]] = affine.apply #[[$MAP0]]([[VAL_86]]){{\[}}[[VAL_84]], [[VAL_92]]]
180 // CHECK:           [[VAL_95:%.*]] = affine.apply #[[$MAP0]]([[VAL_92]]){{\[}}[[VAL_90]], [[VAL_91]]]
181 // CHECK:           gpu.launch blocks([[VAL_96:%.*]], [[VAL_97:%.*]], [[VAL_98:%.*]]) in ([[VAL_99:%.*]] = [[VAL_93]], [[VAL_100:%.*]] = [[VAL_94]], [[VAL_101:%.*]] = [[VAL_93]]) threads([[VAL_102:%.*]], [[VAL_103:%.*]], [[VAL_104:%.*]]) in ([[VAL_105:%.*]] = [[VAL_93]], [[VAL_106:%.*]] = [[VAL_95]], [[VAL_107:%.*]] = [[VAL_93]]) {
182 // CHECK:             [[VAL_108:%.*]] = affine.apply #[[$MAP1]]([[VAL_97]]){{\[}}[[VAL_92]], [[VAL_84]]]
183 // CHECK:             scf.for [[VAL_109:%.*]] = [[VAL_85]] to [[VAL_87]] step [[VAL_92]] {
184 // CHECK:               [[VAL_110:%.*]] = affine.apply #[[$MAP1]]([[VAL_103]]){{\[}}[[VAL_91]], [[VAL_90]]]
185 // CHECK:               scf.for [[VAL_111:%.*]] = [[VAL_90]] to [[VAL_92]] step [[VAL_91]] {
186 // CHECK:                 [[VAL_112:%.*]] = arith.addi [[VAL_108]], [[VAL_110]] : index
187 // CHECK:                 [[VAL_113:%.*]] = arith.addi [[VAL_109]], [[VAL_111]] : index
188 // CHECK:                 [[VAL_114:%.*]] = memref.load [[VAL_88]]{{\[}}[[VAL_112]], [[VAL_113]]] : memref<?x?xf32>
189 // CHECK:                 memref.store [[VAL_114]], [[VAL_89]]{{\[}}[[VAL_113]], [[VAL_112]]] : memref<?x?xf32>
190 // CHECK:               }
191 // CHECK:             }
192 // CHECK:             gpu.terminator
193 // CHECK:           }
194 // CHECK:           return
195 // CHECK:         }
196 // CHECK:       }
198 // -----
200 #map0 = affine_map<(d0, d1)[s0, s1] -> (d0 * s1 + s0 + d1)>
201 #map1 = affine_map<(d0)[s0] -> (2, -d0 + s0)>
202 #map2 = affine_map<(d0)[s0] -> (3, -d0 + s0)>
203 #map3 = affine_map<(d0, d1)[s0, s1, s2] -> (d0 * s1 + s0 + d1 * s2)>
205 module {
206   func @sum(%arg0: memref<?x?xf32, #map0>, %arg1: memref<?x?xf32, #map0>, %arg2: memref<?x?xf32, #map0>) {
207     %c1 = arith.constant 1 : index
208     %c0 = arith.constant 0 : index
209     %c3 = arith.constant 3 : index
210     %c2 = arith.constant 2 : index
211     %0 = memref.dim %arg0, %c0 : memref<?x?xf32, #map0>
212     %1 = memref.dim %arg0, %c1 : memref<?x?xf32, #map0>
213     scf.parallel (%arg3, %arg4) = (%c0, %c0) to (%0, %1) step (%c2, %c3) {
214       %2 = memref.dim %arg0, %c0 : memref<?x?xf32, #map0>
215       %3 = affine.min #map1(%arg3)[%2]
216       %squared_min = arith.muli %3, %3 : index
217       %4 = memref.dim %arg0, %c1 : memref<?x?xf32, #map0>
218       %5 = affine.min #map2(%arg4)[%4]
219       %6 = memref.subview %arg0[%arg3, %arg4][%squared_min, %5][%c1, %c1] : memref<?x?xf32, #map0> to memref<?x?xf32, #map3>
220       %7 = memref.dim %arg1, %c0 : memref<?x?xf32, #map0>
221       %8 = affine.min #map1(%arg3)[%7]
222       %9 = memref.dim %arg1, %c1 : memref<?x?xf32, #map0>
223       %10 = affine.min #map2(%arg4)[%9]
224       %11 = memref.subview %arg1[%arg3, %arg4][%8, %10][%c1, %c1] : memref<?x?xf32, #map0> to memref<?x?xf32, #map3>
225       %12 = memref.dim %arg2, %c0 : memref<?x?xf32, #map0>
226       %13 = affine.min #map1(%arg3)[%12]
227       %14 = memref.dim %arg2, %c1 : memref<?x?xf32, #map0>
228       %15 = affine.min #map2(%arg4)[%14]
229       %16 = memref.subview %arg2[%arg3, %arg4][%13, %15][%c1, %c1] : memref<?x?xf32, #map0> to memref<?x?xf32, #map3>
230       scf.parallel (%arg5, %arg6) = (%c0, %c0) to (%squared_min, %5) step (%c1, %c1) {
231         %17 = memref.load %6[%arg5, %arg6] : memref<?x?xf32, #map3>
232         %18 = memref.load %11[%arg5, %arg6] : memref<?x?xf32, #map3>
233         %19 = memref.load %16[%arg5, %arg6] : memref<?x?xf32, #map3>
234         %20 = arith.addf %17, %18 : f32
235         memref.store %20, %16[%arg5, %arg6] : memref<?x?xf32, #map3>
236         scf.yield
237       } {mapping = [{bound = affine_map<(d0) -> (d0)>, map = affine_map<(d0) -> (d0)>, processor = 3 : i64}, {bound = affine_map<(d0) -> (d0)>, map = affine_map<(d0) -> (d0)>, processor = 4 : i64}]}
238       scf.yield
239     } {mapping = [{bound = affine_map<(d0) -> (d0)>, map = affine_map<(d0) -> (d0)>, processor = 0 : i64}, {bound = affine_map<(d0) -> (d0)>, map = affine_map<(d0) -> (d0)>, processor = 1 : i64}]}
240     return
241   }
244 // CHECK:       #[[$MAP0:.*]] = affine_map<(d0, d1)[s0, s1] -> (d0 * s1 + s0 + d1)>
245 // CHECK:       #[[$MAP1:.*]] = affine_map<(d0)[s0, s1] -> ((d0 - s0) ceildiv s1)>
246 // CHECK:       #[[$MAP2:.*]] = affine_map<(d0)[s0, s1] -> (d0 * s0 + s1)>
247 // CHECK:       #[[$MAP3:.*]] = affine_map<(d0)[s0] -> (2, -d0 + s0)>
248 // CHECK:       #[[$MAP4:.*]] = affine_map<(d0)[s0] -> (3, -d0 + s0)>
249 // CHECK:       #[[$MAP5:.*]] = affine_map<(d0, d1)[s0, s1, s2] -> (d0 * s1 + s0 + d1 * s2)>
251 // CHECK:       module {
252 // CHECK-LABEL:   func @sum(
253 // CHECK-SAME:              [[VAL_0:%.*]]: memref<?x?xf32, #[[$MAP0]]>, [[VAL_1:%.*]]: memref<?x?xf32, #[[$MAP0]]>, [[VAL_2:%.*]]: memref<?x?xf32, #[[$MAP0]]>) {
254 // CHECK:           %[[C1:.*]] = arith.constant 1 : index
255 // CHECK:           %[[C0:.*]] = arith.constant 0 : index
256 // CHECK:           %[[C3:.*]] = arith.constant 3 : index
257 // CHECK:           %[[C2:.*]] = arith.constant 2 : index
258 // CHECK:           [[VAL_7:%.*]] = memref.dim [[VAL_0]], %[[C0]] : memref<?x?xf32, #[[$MAP0]]>
259 // CHECK:           [[VAL_8:%.*]] = memref.dim [[VAL_0]], %[[C1]] : memref<?x?xf32, #[[$MAP0]]>
260 // CHECK:           [[VAL_9:%.*]] = arith.constant 1 : index
261 // CHECK:           [[VAL_10:%.*]] = affine.apply #[[$MAP1]]([[VAL_7]]){{\[}}%[[C0]], %[[C2]]]
262 // CHECK:           [[VAL_11:%.*]] = affine.apply #[[$MAP1]]([[VAL_8]]){{\[}}%[[C0]], %[[C3]]]
263 // CHECK:           [[VAL_12:%.*]] = arith.constant 4 : index
264 // CHECK:           [[VAL_13:%.*]] = affine.apply #[[$MAP1]]([[VAL_12]]){{\[}}%[[C0]], %[[C1]]]
265 // CHECK:           [[VAL_14:%.*]] = arith.constant 3 : index
266 // CHECK:           [[VAL_15:%.*]] = affine.apply #[[$MAP1]]([[VAL_14]]){{\[}}%[[C0]], %[[C1]]]
267 // CHECK:           gpu.launch blocks([[VAL_16:%.*]], [[VAL_17:%.*]], [[VAL_18:%.*]]) in ([[VAL_19:%.*]] = [[VAL_10]], [[VAL_20:%.*]] = [[VAL_11]], [[VAL_21:%.*]] = [[VAL_9]]) threads([[VAL_22:%.*]], [[VAL_23:%.*]], [[VAL_24:%.*]]) in ([[VAL_25:%.*]] = [[VAL_13]], [[VAL_26:%.*]] = [[VAL_15]], [[VAL_27:%.*]] = [[VAL_9]]) {
268 // CHECK:             [[VAL_28:%.*]] = affine.apply #[[$MAP2]]([[VAL_16]]){{\[}}%[[C2]], %[[C0]]]
269 // CHECK:             [[VAL_29:%.*]] = affine.apply #[[$MAP2]]([[VAL_17]]){{\[}}%[[C3]], %[[C0]]]
270 // CHECK:             [[VAL_30:%.*]] = memref.dim [[VAL_0]], %[[C0]] : memref<?x?xf32, #[[$MAP0]]>
271 // CHECK:             [[VAL_31:%.*]] = affine.min #[[$MAP3]]([[VAL_28]]){{\[}}[[VAL_30]]]
272 // CHECK:             [[VAL_31_SQUARED:%.*]] = arith.muli [[VAL_31]], [[VAL_31]] : index
273 // CHECK:             [[VAL_32:%.*]] = memref.dim [[VAL_0]], %[[C1]] : memref<?x?xf32, #[[$MAP0]]>
274 // CHECK:             [[VAL_33:%.*]] = affine.min #[[$MAP4]]([[VAL_29]]){{\[}}[[VAL_32]]]
275 // CHECK:             [[VAL_34:%.*]] = memref.subview [[VAL_0]]{{\[}}[[VAL_28]], [[VAL_29]]] {{\[}}[[VAL_31_SQUARED]], [[VAL_33]]] {{\[}}%[[C1]], %[[C1]]] : memref<?x?xf32, #[[$MAP0]]> to memref<?x?xf32, #[[$MAP5]]>
276 // CHECK:             [[VAL_35:%.*]] = memref.dim [[VAL_1]], %[[C0]] : memref<?x?xf32, #[[$MAP0]]>
277 // CHECK:             [[VAL_36:%.*]] = affine.min #[[$MAP3]]([[VAL_28]]){{\[}}[[VAL_35]]]
278 // CHECK:             [[VAL_37:%.*]] = memref.dim [[VAL_1]], %[[C1]] : memref<?x?xf32, #[[$MAP0]]>
279 // CHECK:             [[VAL_38:%.*]] = affine.min #[[$MAP4]]([[VAL_29]]){{\[}}[[VAL_37]]]
280 // CHECK:             [[VAL_39:%.*]] = memref.subview [[VAL_1]]{{\[}}[[VAL_28]], [[VAL_29]]] {{\[}}[[VAL_36]], [[VAL_38]]] {{\[}}%[[C1]], %[[C1]]] : memref<?x?xf32, #[[$MAP0]]> to memref<?x?xf32, #[[$MAP5]]>
281 // CHECK:             [[VAL_40:%.*]] = memref.dim [[VAL_2]], %[[C0]] : memref<?x?xf32, #[[$MAP0]]>
282 // CHECK:             [[VAL_41:%.*]] = affine.min #[[$MAP3]]([[VAL_28]]){{\[}}[[VAL_40]]]
283 // CHECK:             [[VAL_42:%.*]] = memref.dim [[VAL_2]], %[[C1]] : memref<?x?xf32, #[[$MAP0]]>
284 // CHECK:             [[VAL_43:%.*]] = affine.min #[[$MAP4]]([[VAL_29]]){{\[}}[[VAL_42]]]
285 // CHECK:             [[VAL_44:%.*]] = memref.subview [[VAL_2]]{{\[}}[[VAL_28]], [[VAL_29]]] {{\[}}[[VAL_41]], [[VAL_43]]] {{\[}}%[[C1]], %[[C1]]] : memref<?x?xf32, #[[$MAP0]]> to memref<?x?xf32, #[[$MAP5]]>
286 // CHECK:             [[VAL_45:%.*]] = affine.apply #[[$MAP2]]([[VAL_22]]){{\[}}%[[C1]], %[[C0]]]
287 // CHECK:             [[VAL_46:%.*]] = arith.cmpi slt, [[VAL_45]], [[VAL_31_SQUARED]] : index
288 // CHECK:             scf.if [[VAL_46]] {
289 // CHECK:               [[VAL_47:%.*]] = affine.apply #[[$MAP2]]([[VAL_23]]){{\[}}%[[C1]], %[[C0]]]
290 // CHECK:               [[VAL_48:%.*]] = arith.cmpi slt, [[VAL_47]], [[VAL_33]] : index
291 // CHECK:               scf.if [[VAL_48]] {
292 // CHECK:                 [[VAL_49:%.*]] = memref.load [[VAL_34]]{{\[}}[[VAL_45]], [[VAL_47]]] : memref<?x?xf32, #[[$MAP5]]>
293 // CHECK:                 [[VAL_50:%.*]] = memref.load [[VAL_39]]{{\[}}[[VAL_45]], [[VAL_47]]] : memref<?x?xf32, #[[$MAP5]]>
294 // CHECK:                 [[VAL_51:%.*]] = memref.load [[VAL_44]]{{\[}}[[VAL_45]], [[VAL_47]]] : memref<?x?xf32, #[[$MAP5]]>
295 // CHECK:                 [[VAL_52:%.*]] = arith.addf [[VAL_49]], [[VAL_50]] : f32
296 // CHECK:                 memref.store [[VAL_52]], [[VAL_44]]{{\[}}[[VAL_45]], [[VAL_47]]] : memref<?x?xf32, #[[$MAP5]]>
297 // CHECK:               }
298 // CHECK:             }
299 // CHECK:             gpu.terminator
300 // CHECK:           }
301 // CHECK:           return
302 // CHECK:         }
303 // CHECK:       }
305 // -----
307 // Optional attribute lowering test
309 func @parallel_loop_optional_attr() {
310   %c0 = arith.constant 0 : index
311   %c1 = arith.constant 1 : index
312   scf.parallel (%i0) = (%c0) to (%c1) step (%c1) {
313   } { mapping = [{processor = 0, map = affine_map<(d0) -> (d0)>, bound = affine_map<(d0) -> (d0)>}], optional_attr = 1 }
314   // CHECK: optional_attr = 1
315   return
318 // -----
320 // Mapping to the same processor twice. Cannot be mapped.
322 func @parallel_double_map(%arg0 : index, %arg1 : index, %arg2 : index,
323                           %arg3 : index,
324                           %buf : memref<?x?xf32>,
325                           %res : memref<?x?xf32>) {
326   %four = arith.constant 4 : index
327   scf.parallel (%i0, %i1) = (%arg0, %arg1) to (%arg2, %arg3)
328                                           step (%four, %four)  {
329   } { mapping = [
330       {processor = 1, map = affine_map<(d0) -> (d0)>, bound = affine_map<(d0) -> (d0)>},
331       {processor = 1, map = affine_map<(d0) -> (d0)>, bound = affine_map<(d0) -> (d0)>}
332     ] }
333   return
336 // CHECK-LABEL: @parallel_double_map
337 // CHECK: scf.parallel
339 // -----
341 // Loop with loop-variant upper bound. Cannot be mapped.
343 func @parallel_loop_loop_variant_bound(%arg0 : index, %arg1 : index, %arg2 : index,
344                                        %arg3 : index,
345                                        %buf : memref<?x?xf32>,
346                                        %res : memref<?x?xf32>) {
347   %zero = arith.constant 0 : index
348   %one = arith.constant 1 : index
349   %four = arith.constant 4 : index
350   scf.parallel (%i0, %i1) = (%arg0, %arg1) to (%arg2, %arg3)
351                                           step (%four, %four)  {
352     scf.parallel (%si0, %si1) = (%zero, %zero) to (%i0, %i1)
353                                             step (%one, %one)  {
354       %idx0 = arith.addi %i0, %si0 : index
355       %idx1 = arith.addi %i1, %si1 : index
356       %val = memref.load %buf[%idx0, %idx1] : memref<?x?xf32>
357       memref.store %val, %res[%idx1, %idx0] : memref<?x?xf32>
358     } { mapping = [
359         {processor = 4, map = affine_map<(d0) -> (d0)>, bound = affine_map<(d0) -> (d0)>},
360         {processor = 6, map = affine_map<(d0) -> (d0)>, bound = affine_map<(d0) -> (d0)>}
361       ] }
362   } { mapping = [
363       {processor = 1, map = affine_map<(d0) -> (d0)>, bound = affine_map<(d0) -> (d0)>},
364       {processor = 6, map = affine_map<(d0) -> (d0)>, bound = affine_map<(d0) -> (d0)>}
365     ] }
366   return
369 // CHECK-LABEL: @parallel_loop_loop_variant_bound
370 // CHECK: scf.parallel
371 // CHECK: scf.parallel
373 // -----
375 // Loop without annotations. Cannot be mapped.
377 func @parallel_no_annotations(%arg0 : index, %arg1 : index, %arg2 : index,
378                               %arg3 : index,
379                               %buf : memref<?x?xf32>,
380                               %res : memref<?x?xf32>) {
381   %four = arith.constant 4 : index
382   scf.parallel (%i0, %i1) = (%arg0, %arg1) to (%arg2, %arg3)
383                                           step (%four, %four)  {
384   }
385   return
388 // CHECK-LABEL: @parallel_no_annotations
389 // CHECK: scf.parallel