294 lines · plain
1// RUN: mlir-opt -allow-unregistered-dialect -convert-scf-to-emitc %s | FileCheck %s2// RUN: mlir-opt -allow-unregistered-dialect -convert-to-emitc="filter-dialects=scf" %s | FileCheck %s3 4emitc.func @payload_one_result(%arg: i32) -> i32 {5 %result = add %arg, %arg : (i32, i32) -> i326 return %result : i327}8 9func.func @one_result() -> i32 {10 %init = emitc.literal "1.0" : i3211 %var = emitc.literal "1.0" : i3212 %exit = emitc.literal "10.0" : i3213 14 %res = scf.while (%arg1 = %init) : (i32) -> i32 {15 %sum = emitc.add %arg1, %var : (i32, i32) -> i3216 %condition = emitc.cmp lt, %sum, %exit : (i32, i32) -> i117 %next = emitc.add %arg1, %arg1 : (i32, i32) -> i3218 scf.condition(%condition) %next : i3219 } do {20 ^bb0(%arg2: i32):21 %next_arg1 = emitc.call @payload_one_result(%arg2) : (i32) -> i3222 scf.yield %next_arg1 : i3223 }24 25 return %res : i3226}27// CHECK-LABEL: emitc.func @payload_one_result(28// CHECK-SAME: %[[ARG0:.*]]: i32) -> i32 {29// CHECK: %[[VAL_0:.*]] = add %[[ARG0]], %[[ARG0]] : (i32, i32) -> i3230// CHECK: return %[[VAL_0]] : i3231// CHECK: }32 33// CHECK-LABEL: func.func @one_result() -> i32 {34// CHECK: %[[VAL_0:.*]] = emitc.literal "1.0" : i3235// CHECK: %[[VAL_1:.*]] = emitc.literal "1.0" : i3236// CHECK: %[[VAL_2:.*]] = emitc.literal "10.0" : i3237// CHECK: %[[VAL_3:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>38// CHECK: %[[VAL_4:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>39// CHECK: emitc.assign %[[VAL_0]] : i32 to %[[VAL_4]] : <i32>40// CHECK: %[[VAL_5:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i1>41// CHECK: emitc.do {42// CHECK: %[[VAL_6:.*]] = load %[[VAL_4]] : <i32>43// CHECK: %[[VAL_7:.*]] = add %[[VAL_6]], %[[VAL_1]] : (i32, i32) -> i3244// CHECK: %[[VAL_8:.*]] = cmp lt, %[[VAL_7]], %[[VAL_2]] : (i32, i32) -> i145// CHECK: %[[VAL_9:.*]] = add %[[VAL_6]], %[[VAL_6]] : (i32, i32) -> i3246// CHECK: assign %[[VAL_9]] : i32 to %[[VAL_3]] : <i32>47// CHECK: assign %[[VAL_8]] : i1 to %[[VAL_5]] : <i1>48// CHECK: if %[[VAL_8]] {49// CHECK: %[[VAL_10:.*]] = call @payload_one_result(%[[VAL_9]]) : (i32) -> i3250// CHECK: assign %[[VAL_10]] : i32 to %[[VAL_4]] : <i32>51// CHECK: }52// CHECK: } while {53// CHECK: %[[VAL_11:.*]] = expression %[[VAL_5]] : (!emitc.lvalue<i1>) -> i1 {54// CHECK: %[[VAL_12:.*]] = load %[[VAL_5]] : <i1>55// CHECK: yield %[[VAL_12]] : i156// CHECK: }57// CHECK: yield %[[VAL_11]] : i158// CHECK: }59// CHECK: %[[VAL_13:.*]] = emitc.load %[[VAL_3]] : <i32>60// CHECK: return %[[VAL_13]] : i3261// CHECK: }62 63emitc.func @payload_two_results(%arg: i32) -> i32 {64 %result = add %arg, %arg : (i32, i32) -> i3265 return %result : i3266}67 68func.func @two_results() -> i32 {69 %init = emitc.literal "1.0" : i3270 %exit = emitc.literal "10.0" : i3271 72 %res1, %res2 = scf.while (%arg1_1 = %init, %arg1_2 = %init) : (i32, i32) -> (i32, i32) {73 %sum = emitc.add %arg1_1, %arg1_2 : (i32, i32) -> i3274 %condition = emitc.cmp lt, %sum, %exit : (i32, i32) -> i175 scf.condition(%condition) %init, %arg1_2 : i32, i3276 } do {77 ^bb0(%arg2_1 : i32, %arg2_2 : i32):78 %next1 = emitc.call @payload_two_results(%arg2_1) : (i32) -> i3279 %next2 = emitc.call @payload_two_results(%arg2_2) : (i32) -> i3280 scf.yield %next1, %next2 : i32, i3281 }82 83 return %res1 : i3284}85// CHECK-LABEL: emitc.func @payload_two_results(86// CHECK-SAME: %[[ARG0:.*]]: i32) -> i32 {87// CHECK: %[[VAL_0:.*]] = add %[[ARG0]], %[[ARG0]] : (i32, i32) -> i3288// CHECK: return %[[VAL_0]] : i3289// CHECK: }90 91// CHECK-LABEL: func.func @two_results() -> i32 {92// CHECK: %[[VAL_0:.*]] = emitc.literal "1.0" : i3293// CHECK: %[[VAL_1:.*]] = emitc.literal "10.0" : i3294// CHECK: %[[VAL_2:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>95// CHECK: %[[VAL_3:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>96// CHECK: %[[VAL_4:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>97// CHECK: emitc.assign %[[VAL_0]] : i32 to %[[VAL_4]] : <i32>98// CHECK: %[[VAL_5:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>99// CHECK: emitc.assign %[[VAL_0]] : i32 to %[[VAL_5]] : <i32>100// CHECK: %[[VAL_6:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i1>101// CHECK: emitc.do {102// CHECK: %[[VAL_7:.*]] = load %[[VAL_4]] : <i32>103// CHECK: %[[VAL_8:.*]] = load %[[VAL_5]] : <i32>104// CHECK: %[[VAL_9:.*]] = add %[[VAL_7]], %[[VAL_8]] : (i32, i32) -> i32105// CHECK: %[[VAL_10:.*]] = cmp lt, %[[VAL_9]], %[[VAL_1]] : (i32, i32) -> i1106// CHECK: assign %[[VAL_0]] : i32 to %[[VAL_2]] : <i32>107// CHECK: assign %[[VAL_8]] : i32 to %[[VAL_3]] : <i32>108// CHECK: assign %[[VAL_10]] : i1 to %[[VAL_6]] : <i1>109// CHECK: if %[[VAL_10]] {110// CHECK: %[[VAL_11:.*]] = call @payload_two_results(%[[VAL_0]]) : (i32) -> i32111// CHECK: %[[VAL_12:.*]] = call @payload_two_results(%[[VAL_8]]) : (i32) -> i32112// CHECK: assign %[[VAL_11]] : i32 to %[[VAL_4]] : <i32>113// CHECK: assign %[[VAL_12]] : i32 to %[[VAL_5]] : <i32>114// CHECK: }115// CHECK: } while {116// CHECK: %[[VAL_13:.*]] = expression %[[VAL_6]] : (!emitc.lvalue<i1>) -> i1 {117// CHECK: %[[VAL_14:.*]] = load %[[VAL_6]] : <i1>118// CHECK: yield %[[VAL_14]] : i1119// CHECK: }120// CHECK: yield %[[VAL_13]] : i1121// CHECK: }122// CHECK: %[[VAL_15:.*]] = emitc.load %[[VAL_2]] : <i32>123// CHECK: %[[VAL_16:.*]] = emitc.load %[[VAL_3]] : <i32>124// CHECK: return %[[VAL_15]] : i32125// CHECK: }126 127emitc.func @payload_double_use(%arg: i32) -> i32 {128 %result = add %arg, %arg : (i32, i32) -> i32129 return %result : i32130}131 132emitc.func @foo_with_side_effect(%arg: i32, %p : !emitc.ptr<i32>) -> i32 {133 %sum = add %arg, %arg : (i32, i32) -> i32134 emitc.verbatim "{}[0] = {};" args %p, %sum : !emitc.ptr<i32>, i32135 return %sum : i32136}137 138func.func @double_use(%p : !emitc.ptr<i32>) -> i32 {139 %init = emitc.literal "1.0" : i32140 %var = emitc.literal "1.0" : i32141 %exit = emitc.literal "10.0" : i32142 %res = scf.while (%arg1 = %init) : (i32) -> i32 {143 %used_twice = emitc.call @foo_with_side_effect(%arg1, %p) : (i32, !emitc.ptr<i32>) -> i32144 %prod = emitc.add %used_twice, %used_twice : (i32, i32) -> i32145 %sum = emitc.add %arg1, %prod : (i32, i32) -> i32146 %condition = emitc.cmp lt, %sum, %exit : (i32, i32) -> i1147 scf.condition(%condition) %arg1 : i32148 } do {149 ^bb0(%arg2: i32):150 %next_arg1 = emitc.call @payload_double_use(%arg2) : (i32) -> i32151 scf.yield %next_arg1 : i32152 }153 return %res : i32154}155// CHECK-LABEL: emitc.func @payload_double_use(156// CHECK-SAME: %[[ARG0:.*]]: i32) -> i32 {157// CHECK: %[[VAL_0:.*]] = add %[[ARG0]], %[[ARG0]] : (i32, i32) -> i32158// CHECK: return %[[VAL_0]] : i32159// CHECK: }160 161// CHECK-LABEL: emitc.func @foo_with_side_effect(162// CHECK-SAME: %[[ARG0:.*]]: i32,163// CHECK-SAME: %[[ARG1:.*]]: !emitc.ptr<i32>) -> i32 {164// CHECK: %[[VAL_0:.*]] = add %[[ARG0]], %[[ARG0]] : (i32, i32) -> i32165// CHECK: verbatim "{}[0] = {};" args %[[ARG1]], %[[VAL_0]] : !emitc.ptr<i32>, i32166// CHECK: return %[[VAL_0]] : i32167// CHECK: }168 169// CHECK-LABEL: func.func @double_use(170// CHECK-SAME: %[[ARG0:.*]]: !emitc.ptr<i32>) -> i32 {171// CHECK: %[[VAL_0:.*]] = emitc.literal "1.0" : i32172// CHECK: %[[VAL_1:.*]] = emitc.literal "1.0" : i32173// CHECK: %[[VAL_2:.*]] = emitc.literal "10.0" : i32174// CHECK: %[[VAL_3:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>175// CHECK: %[[VAL_4:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>176// CHECK: emitc.assign %[[VAL_0]] : i32 to %[[VAL_4]] : <i32>177// CHECK: %[[VAL_5:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i1>178// CHECK: emitc.do {179// CHECK: %[[VAL_6:.*]] = load %[[VAL_4]] : <i32>180// CHECK: %[[VAL_7:.*]] = call @foo_with_side_effect(%[[VAL_6]], %[[ARG0]]) : (i32, !emitc.ptr<i32>) -> i32181// CHECK: %[[VAL_8:.*]] = add %[[VAL_7]], %[[VAL_7]] : (i32, i32) -> i32182// CHECK: %[[VAL_9:.*]] = add %[[VAL_6]], %[[VAL_8]] : (i32, i32) -> i32183// CHECK: %[[VAL_10:.*]] = cmp lt, %[[VAL_9]], %[[VAL_2]] : (i32, i32) -> i1184// CHECK: assign %[[VAL_6]] : i32 to %[[VAL_3]] : <i32>185// CHECK: assign %[[VAL_10]] : i1 to %[[VAL_5]] : <i1>186// CHECK: if %[[VAL_10]] {187// CHECK: %[[VAL_11:.*]] = call @payload_double_use(%[[VAL_6]]) : (i32) -> i32188// CHECK: assign %[[VAL_11]] : i32 to %[[VAL_4]] : <i32>189// CHECK: }190// CHECK: } while {191// CHECK: %[[VAL_12:.*]] = expression %[[VAL_5]] : (!emitc.lvalue<i1>) -> i1 {192// CHECK: %[[VAL_13:.*]] = load %[[VAL_5]] : <i1>193// CHECK: yield %[[VAL_13]] : i1194// CHECK: }195// CHECK: yield %[[VAL_12]] : i1196// CHECK: }197// CHECK: %[[VAL_14:.*]] = emitc.load %[[VAL_3]] : <i32>198// CHECK: return %[[VAL_14]] : i32199// CHECK: }200 201emitc.func @payload_empty_after_region() -> i1 {202 %true = emitc.literal "true" : i1203 return %true : i1204}205 206func.func @empty_after_region() {207 scf.while () : () -> () {208 %condition = emitc.call @payload_empty_after_region() : () -> i1209 scf.condition(%condition)210 } do {211 ^bb0():212 scf.yield213 }214 return215}216// CHECK-LABEL: emitc.func @payload_empty_after_region() -> i1 {217// CHECK: %[[VAL_0:.*]] = literal "true" : i1218// CHECK: return %[[VAL_0]] : i1219// CHECK: }220 221// CHECK-LABEL: func.func @empty_after_region() {222// CHECK: %[[VAL_0:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i1>223// CHECK: emitc.do {224// CHECK: %[[VAL_1:.*]] = call @payload_empty_after_region() : () -> i1225// CHECK: assign %[[VAL_1]] : i1 to %[[VAL_0]] : <i1>226// CHECK: } while {227// CHECK: %[[VAL_2:.*]] = expression %[[VAL_0]] : (!emitc.lvalue<i1>) -> i1 {228// CHECK: %[[VAL_3:.*]] = load %[[VAL_0]] : <i1>229// CHECK: yield %[[VAL_3]] : i1230// CHECK: }231// CHECK: yield %[[VAL_2]] : i1232// CHECK: }233// CHECK: return234// CHECK: }235 236emitc.func @payload_different_number_of_vars(%arg0: i32) -> i32 {237 %0 = add %arg0, %arg0 : (i32, i32) -> i32238 return %0 : i32239}240func.func @different_number_of_vars() -> (i32, i32) {241 %init = emitc.literal "1.0" : i32242 %var = emitc.literal "7.0" : i32243 %exit = emitc.literal "10.0" : i32244 %res, %res2 = scf.while (%arg1 = %init) : (i32) -> (i32, i32) {245 %sum = emitc.add %arg1, %var : (i32, i32) -> i32246 %condition = emitc.cmp lt, %sum, %exit : (i32, i32) -> i1247 %next = emitc.add %arg1, %arg1 : (i32, i32) -> i32248 scf.condition(%condition) %next, %sum : i32, i32249 } do {250 ^bb0(%arg2: i32, %arg3 : i32):251 %next_arg1 = emitc.call @payload_different_number_of_vars(%arg2) : (i32) -> i32252 scf.yield %next_arg1 : i32253 }254 return %res, %res2 : i32, i32255}256// CHECK-LABEL: emitc.func @payload_different_number_of_vars(257// CHECK-SAME: %[[ARG0:.*]]: i32) -> i32 {258// CHECK: %[[VAL_0:.*]] = add %[[ARG0]], %[[ARG0]] : (i32, i32) -> i32259// CHECK: return %[[VAL_0]] : i32260// CHECK: }261 262// CHECK-LABEL: func.func @different_number_of_vars() -> (i32, i32) {263// CHECK: %[[VAL_0:.*]] = emitc.literal "1.0" : i32264// CHECK: %[[VAL_1:.*]] = emitc.literal "7.0" : i32265// CHECK: %[[VAL_2:.*]] = emitc.literal "10.0" : i32266// CHECK: %[[VAL_3:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>267// CHECK: %[[VAL_4:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>268// CHECK: %[[VAL_5:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i32>269// CHECK: emitc.assign %[[VAL_0]] : i32 to %[[VAL_5]] : <i32>270// CHECK: %[[VAL_6:.*]] = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<i1>271// CHECK: emitc.do {272// CHECK: %[[VAL_7:.*]] = load %[[VAL_5]] : <i32>273// CHECK: %[[VAL_8:.*]] = add %[[VAL_7]], %[[VAL_1]] : (i32, i32) -> i32274// CHECK: %[[VAL_9:.*]] = cmp lt, %[[VAL_8]], %[[VAL_2]] : (i32, i32) -> i1275// CHECK: %[[VAL_10:.*]] = add %[[VAL_7]], %[[VAL_7]] : (i32, i32) -> i32276// CHECK: assign %[[VAL_10]] : i32 to %[[VAL_3]] : <i32>277// CHECK: assign %[[VAL_8]] : i32 to %[[VAL_4]] : <i32>278// CHECK: assign %[[VAL_9]] : i1 to %[[VAL_6]] : <i1>279// CHECK: if %[[VAL_9]] {280// CHECK: %[[VAL_11:.*]] = call @payload_different_number_of_vars(%[[VAL_10]]) : (i32) -> i32281// CHECK: assign %[[VAL_11]] : i32 to %[[VAL_5]] : <i32>282// CHECK: }283// CHECK: } while {284// CHECK: %[[VAL_12:.*]] = expression %[[VAL_6]] : (!emitc.lvalue<i1>) -> i1 {285// CHECK: %[[VAL_13:.*]] = load %[[VAL_6]] : <i1>286// CHECK: yield %[[VAL_13]] : i1287// CHECK: }288// CHECK: yield %[[VAL_12]] : i1289// CHECK: }290// CHECK: %[[VAL_14:.*]] = emitc.load %[[VAL_3]] : <i32>291// CHECK: %[[VAL_15:.*]] = emitc.load %[[VAL_4]] : <i32>292// CHECK: return %[[VAL_14]], %[[VAL_15]] : i32, i32293// CHECK: }294