xref: /llvm-project/mlir/test/Conversion/SCFToEmitC/for.mlir (revision 977d744b21d06415ac872258bf86e026d8eb487f)
1// RUN: mlir-opt -allow-unregistered-dialect -convert-scf-to-emitc %s | FileCheck %s
2
3func.func @simple_std_for_loop(%arg0 : index, %arg1 : index, %arg2 : index) {
4  scf.for %i0 = %arg0 to %arg1 step %arg2 {
5    %c1 = arith.constant 1 : index
6  }
7  return
8}
9// CHECK-LABEL: func.func @simple_std_for_loop(
10// CHECK-SAME:      %[[ARG_0:.*]]: index, %[[ARG_1:.*]]: index, %[[ARG_2:.*]]: index) {
11// CHECK-NEXT:    %[[VAL_2:.*]] = builtin.unrealized_conversion_cast %[[ARG_2]] : index to !emitc.size_t
12// CHECK-NEXT:    %[[VAL_1:.*]] = builtin.unrealized_conversion_cast %[[ARG_1]] : index to !emitc.size_t
13// CHECK-NEXT:    %[[VAL_0:.*]] = builtin.unrealized_conversion_cast %[[ARG_0]] : index to !emitc.size_t
14// CHECK-NEXT:    emitc.for %[[VAL_3:.*]] = %[[VAL_0]] to %[[VAL_1]] step %[[VAL_2]] : !emitc.size_t {
15// CHECK-NEXT:      %[[VAL_4:.*]] = arith.constant 1 : index
16// CHECK-NEXT:    }
17// CHECK-NEXT:    return
18// CHECK-NEXT:  }
19
20func.func @simple_std_2_for_loops(%arg0 : index, %arg1 : index, %arg2 : index) {
21  scf.for %i0 = %arg0 to %arg1 step %arg2 {
22    %c1 = arith.constant 1 : index
23    scf.for %i1 = %arg0 to %arg1 step %arg2 {
24      %c1_0 = arith.constant 1 : index
25    }
26  }
27  return
28}
29// CHECK-LABEL: func.func @simple_std_2_for_loops(
30// CHECK-SAME:      %[[ARG_0:.*]]: index, %[[ARG_1:.*]]: index, %[[ARG_2:.*]]: index) {
31// CHECK-NEXT:    %[[VAL_2:.*]] = builtin.unrealized_conversion_cast %[[ARG_2]] : index to !emitc.size_t
32// CHECK-NEXT:    %[[VAL_1:.*]] = builtin.unrealized_conversion_cast %[[ARG_1]] : index to !emitc.size_t
33// CHECK-NEXT:    %[[VAL_0:.*]] = builtin.unrealized_conversion_cast %[[ARG_0]] : index to !emitc.size_t
34// CHECK-NEXT:    emitc.for %[[VAL_3:.*]] = %[[VAL_0]] to %[[VAL_1]] step %[[VAL_2]] : !emitc.size_t {
35// CHECK-NEXT:      %[[VAL_4:.*]] = arith.constant 1 : index
36// CHECK-NEXT:      for %[[VAL_5:.*]] = %[[VAL_0]] to %[[VAL_1]] step %[[VAL_2]] : !emitc.size_t {
37// CHECK-NEXT:        %[[VAL_6:.*]] = arith.constant 1 : index
38// CHECK-NEXT:      }
39// CHECK-NEXT:    }
40// CHECK-NEXT:    return
41// CHECK-NEXT:  }
42
43func.func @for_yield(%arg0 : index, %arg1 : index, %arg2 : index) -> (f32, f32) {
44  %s0 = arith.constant 0.0 : f32
45  %s1 = arith.constant 1.0 : f32
46  %result:2 = scf.for %i0 = %arg0 to %arg1 step %arg2 iter_args(%si = %s0, %sj = %s1) -> (f32, f32) {
47    %sn = arith.addf %si, %sj : f32
48    scf.yield %sn, %sn : f32, f32
49  }
50  return %result#0, %result#1 : f32, f32
51}
52// CHECK-LABEL: func.func @for_yield(
53// CHECK-SAME:      %[[ARG_0:.*]]: index, %[[ARG_1:.*]]: index, %[[ARG_2:.*]]: index) -> (f32, f32) {
54// CHECK-NEXT:    %[[VAL_2:.*]] = builtin.unrealized_conversion_cast %[[ARG_2]] : index to !emitc.size_t
55// CHECK-NEXT:    %[[VAL_1:.*]] = builtin.unrealized_conversion_cast %[[ARG_1]] : index to !emitc.size_t
56// CHECK-NEXT:    %[[VAL_0:.*]] = builtin.unrealized_conversion_cast %[[ARG_0]] : index to !emitc.size_t
57// CHECK-NEXT:    %[[VAL_3:.*]] = arith.constant 0.000000e+00 : f32
58// CHECK-NEXT:    %[[VAL_4:.*]] = arith.constant 1.000000e+00 : f32
59// CHECK-NEXT:    %[[VAL_5:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<f32>
60// CHECK-NEXT:    %[[VAL_6:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<f32>
61// CHECK-NEXT:    emitc.assign %[[VAL_3]] : f32 to %[[VAL_5]] : <f32>
62// CHECK-NEXT:    emitc.assign %[[VAL_4]] : f32 to %[[VAL_6]] : <f32>
63// CHECK-NEXT:    emitc.for %[[VAL_7:.*]] = %[[VAL_0]] to %[[VAL_1]] step %[[VAL_2]] : !emitc.size_t {
64// CHECK-NEXT:      %[[VAL_8:.*]] = load %[[VAL_5]] : <f32>
65// CHECK-NEXT:      %[[VAL_9:.*]] = load %[[VAL_6]] : <f32>
66// CHECK-NEXT:      %[[VAL_10:.*]] = arith.addf %[[VAL_8]], %[[VAL_9]] : f32
67// CHECK-NEXT:      assign %[[VAL_10]] : f32 to %[[VAL_5]] : <f32>
68// CHECK-NEXT:      assign %[[VAL_10]] : f32 to %[[VAL_6]] : <f32>
69// CHECK-NEXT:    }
70// CHECK-NEXT:    %[[VAL_11:.*]] = emitc.load %[[VAL_5]] : <f32>
71// CHECK-NEXT:    %[[VAL_12:.*]] = emitc.load %[[VAL_6]] : <f32>
72// CHECK-NEXT:    return %[[VAL_11]], %[[VAL_12]] : f32, f32
73// CHECK-NEXT:  }
74
75func.func @nested_for_yield(%arg0 : index, %arg1 : index, %arg2 : index) -> f32 {
76  %s0 = arith.constant 1.0 : f32
77  %r = scf.for %i0 = %arg0 to %arg1 step %arg2 iter_args(%iter = %s0) -> (f32) {
78    %result = scf.for %i1 = %arg0 to %arg1 step %arg2 iter_args(%si = %iter) -> (f32) {
79      %sn = arith.addf %si, %si : f32
80      scf.yield %sn : f32
81    }
82    scf.yield %result : f32
83  }
84  return %r : f32
85}
86// CHECK-LABEL: func.func @nested_for_yield(
87// CHECK-SAME:      %[[ARG_0:.*]]: index, %[[ARG_1:.*]]: index, %[[ARG_2:.*]]: index) -> f32 {
88// CHECK-NEXT:    %[[VAL_2:.*]] = builtin.unrealized_conversion_cast %[[ARG_2]] : index to !emitc.size_t
89// CHECK-NEXT:    %[[VAL_1:.*]] = builtin.unrealized_conversion_cast %[[ARG_1]] : index to !emitc.size_t
90// CHECK-NEXT:    %[[VAL_0:.*]] = builtin.unrealized_conversion_cast %[[ARG_0]] : index to !emitc.size_t
91// CHECK-NEXT:    %[[VAL_3:.*]] = arith.constant 1.000000e+00 : f32
92// CHECK-NEXT:    %[[VAL_4:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<f32>
93// CHECK-NEXT:    emitc.assign %[[VAL_3]] : f32 to %[[VAL_4]] : <f32>
94// CHECK-NEXT:    emitc.for %[[VAL_5:.*]] = %[[VAL_0]] to %[[VAL_1]] step %[[VAL_2]] : !emitc.size_t {
95// CHECK-NEXT:      %[[VAL_6:.*]] = load %[[VAL_4]] : <f32>
96// CHECK-NEXT:      %[[VAL_7:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<f32>
97// CHECK-NEXT:      assign %[[VAL_6]] : f32 to %[[VAL_7]] : <f32>
98// CHECK-NEXT:      for %[[VAL_8:.*]] = %[[VAL_0]] to %[[VAL_1]] step %[[VAL_2]] : !emitc.size_t {
99// CHECK-NEXT:        %[[VAL_9:.*]] = load %[[VAL_7]] : <f32>
100// CHECK-NEXT:        %[[VAL_10:.*]] = arith.addf %[[VAL_9]], %[[VAL_9]] : f32
101// CHECK-NEXT:        assign %[[VAL_10]] : f32 to %[[VAL_7]] : <f32>
102// CHECK-NEXT:      }
103// CHECK-NEXT:      %[[VAL_11:.*]] = load %[[VAL_7]] : <f32>
104// CHECK-NEXT:      assign %[[VAL_11]] : f32 to %[[VAL_4]] : <f32>
105// CHECK-NEXT:    }
106// CHECK-NEXT:    %[[VAL_12:.*]] = emitc.load %[[VAL_4]] : <f32>
107// CHECK-NEXT:    return %[[VAL_12]] : f32
108// CHECK-NEXT:  }
109
110func.func @for_yield_index(%arg0 : index, %arg1 : index, %arg2 : index) -> index {
111  %zero = arith.constant 0 : index
112  %r = scf.for %i0 = %arg0 to %arg1 step %arg2 iter_args(%acc = %zero) -> index {
113    scf.yield %acc : index
114  }
115  return %r : index
116}
117
118// CHECK-LABEL: func.func @for_yield_index(
119// CHECK-SAME: %[[ARG_0:.*]]: index, %[[ARG_1:.*]]: index, %[[ARG_2:.*]]: index) -> index {
120// CHECK:     %[[VAL_0:.*]] = builtin.unrealized_conversion_cast %[[ARG_2]] : index to !emitc.size_t
121// CHECK:     %[[VAL_1:.*]] = builtin.unrealized_conversion_cast %[[ARG_1]] : index to !emitc.size_t
122// CHECK:     %[[VAL_2:.*]] = builtin.unrealized_conversion_cast %[[ARG_0]] : index to !emitc.size_t
123// CHECK:     %[[C0:.*]] = arith.constant 0 : index
124// CHECK:     %[[VAL_3:.*]] = builtin.unrealized_conversion_cast %[[C0]] : index to !emitc.size_t
125// CHECK:     %[[VAL_4:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<!emitc.size_t>
126// CHECK:     emitc.assign %[[VAL_3]] : !emitc.size_t to %[[VAL_4]] : <!emitc.size_t>
127// CHECK:     emitc.for %[[VAL_5:.*]] = %[[VAL_2]] to %[[VAL_1]] step %[[VAL_0]] : !emitc.size_t {
128// CHECK:       %[[V:.*]] = load %[[VAL_4]] : <!emitc.size_t>
129// CHECK:       assign %[[V]] : !emitc.size_t to %[[VAL_4]] : <!emitc.size_t>
130// CHECK:     }
131// CHECK:     %[[V2:.*]] = emitc.load %[[VAL_4]] : <!emitc.size_t>
132// CHECK:     %[[VAL_8:.*]] = builtin.unrealized_conversion_cast %[[V2]] : !emitc.size_t to index
133// CHECK:     return %[[VAL_8]] : index
134// CHECK:   }
135
136
137func.func @for_yield_update_loop_carried_var(%arg0 : index, %arg1 : index, %arg2 : index) -> index {
138   %zero = arith.constant 0 : index
139   %r = scf.for %i0 = %arg0 to %arg1 step %arg2 iter_args(%acc = %zero) -> index {
140     %sn = arith.addi %acc, %acc : index
141     scf.yield %sn: index
142   }
143   return %r : index
144 }
145
146// CHECK-LABEL: func.func @for_yield_update_loop_carried_var(
147// CHECK-SAME:  %[[ARG_0:.*]]: index, %[[ARG_1:.*]]: index, %[[ARG_2:.*]]: index) -> index {
148// CHECK:   %[[VAL_0:.*]] = builtin.unrealized_conversion_cast %[[ARG_2]] : index to !emitc.size_t
149// CHECK:   %[[VAL_1:.*]] = builtin.unrealized_conversion_cast %[[ARG_1]] : index to !emitc.size_t
150// CHECK:   %[[VAL_2:.*]] = builtin.unrealized_conversion_cast %[[ARG_0]] : index to !emitc.size_t
151// CHECK:   %[[C0:.*]] = arith.constant 0 : index
152// CHECK:   %[[VAL_3:.*]] = builtin.unrealized_conversion_cast %[[C0]] : index to !emitc.size_t
153// CHECK:   %[[VAL_4:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<!emitc.size_t>
154// CHECK:   emitc.assign %[[VAL_3]] : !emitc.size_t to %[[VAL_4]] : <!emitc.size_t>
155// CHECK:   emitc.for %[[ARG_3:.*]] = %[[VAL_2]] to %[[VAL_1]] step %[[VAL_0]] : !emitc.size_t {
156// CHECK:     %[[V:.*]] = load %[[VAL_4]] : <!emitc.size_t>
157// CHECK:     %[[VAL_5:.*]] = builtin.unrealized_conversion_cast %[[V]] : !emitc.size_t to index
158// CHECK:     %[[VAL_6:.*]] = arith.addi %[[VAL_5]], %[[VAL_5]] : index
159// CHECK:     %[[VAL_8:.*]] = builtin.unrealized_conversion_cast %[[VAL_6]] : index to !emitc.size_t
160// CHECK:     assign %[[VAL_8]] : !emitc.size_t to %[[VAL_4]] : <!emitc.size_t>
161// CHECK:   }
162// CHECK:   %[[V2:.*]] = emitc.load %[[VAL_4]] : <!emitc.size_t>
163// CHECK:   %[[VAL_9:.*]] = builtin.unrealized_conversion_cast %[[V2]] : !emitc.size_t to index
164// CHECK:   return %[[VAL_9]] : index
165// CHECK: }
166