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