1// RUN: fir-opt --split-input-file --cfg-conversion %s | FileCheck %s 2 3func.func @x(%lb : index, %ub : index, %step : index, %b : i1, %addr : !fir.ref<index>) { 4 fir.do_loop %iv = %lb to %ub step %step unordered { 5 // expect following conditional blocks to get fused 6 fir.if %b { 7 fir.store %iv to %addr : !fir.ref<index> 8 } else { 9 %zero = arith.constant 0 : index 10 fir.store %zero to %addr : !fir.ref<index> 11 } 12 } 13 return 14} 15 16func.func private @f2() -> i1 17 18// CHECK: func @x(%[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index, %[[VAL_2:.*]]: index, %[[VAL_3:.*]]: i1, %[[VAL_4:.*]]: !fir.ref<index>) { 19// CHECK: %[[VAL_5:.*]] = arith.subi %[[VAL_1]], %[[VAL_0]] : index 20// CHECK: %[[VAL_6:.*]] = arith.addi %[[VAL_5]], %[[VAL_2]] : index 21// CHECK: %[[VAL_7:.*]] = arith.divsi %[[VAL_6]], %[[VAL_2]] : index 22// CHECK: br ^bb1(%[[VAL_0]], %[[VAL_7]] : index, index) 23// CHECK: ^bb1(%[[VAL_8:.*]]: index, %[[VAL_9:.*]]: index): 24// CHECK: %[[VAL_10:.*]] = arith.constant 0 : index 25// CHECK: %[[VAL_11:.*]] = arith.cmpi sgt, %[[VAL_9]], %[[VAL_10]] : index 26// CHECK: cond_br %[[VAL_11]], ^bb2, ^bb6 27// CHECK: ^bb2: 28// CHECK: cond_br %[[VAL_3]], ^bb3, ^bb4 29// CHECK: ^bb3: 30// CHECK: fir.store %[[VAL_8]] to %[[VAL_4]] : !fir.ref<index> 31// CHECK: br ^bb5 32// CHECK: ^bb4: 33// CHECK: %[[VAL_12:.*]] = arith.constant 0 : index 34// CHECK: fir.store %[[VAL_12]] to %[[VAL_4]] : !fir.ref<index> 35// CHECK: br ^bb5 36// CHECK: ^bb5: 37// CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_8]], %[[VAL_2]] : index 38// CHECK: %[[VAL_14:.*]] = arith.constant 1 : index 39// CHECK: %[[VAL_15:.*]] = arith.subi %[[VAL_9]], %[[VAL_14]] : index 40// CHECK: br ^bb1(%[[VAL_13]], %[[VAL_15]] : index, index) 41// CHECK: ^bb6: 42// CHECK: return 43// CHECK: } 44// CHECK: func private @f2() -> i1 45 46// ----- 47 48func.func @x2(%lo : index, %up : index, %ok : i1) { 49 %c1 = arith.constant 1 : index 50 %unused = fir.iterate_while (%i = %lo to %up step %c1) and (%ok1 = %ok) { 51 %ok2 = fir.call @f2() : () -> i1 52 fir.result %ok2 : i1 53 } 54 return 55} 56 57func.func private @f3(i16) 58 59// CHECK: func @x2(%[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index, %[[VAL_2:.*]]: i1) { 60// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index 61// CHECK: br ^bb1(%[[VAL_0]], %[[VAL_2]] : index, i1) 62// CHECK: ^bb1(%[[VAL_4:.*]]: index, %[[VAL_5:.*]]: i1): 63// CHECK: %[[VAL_6:.*]] = arith.constant 0 : index 64// CHECK: %[[VAL_7:.*]] = arith.cmpi slt, %[[VAL_6]], %[[VAL_3]] : index 65// CHECK: %[[VAL_8:.*]] = arith.cmpi sle, %[[VAL_4]], %[[VAL_1]] : index 66// CHECK: %[[VAL_9:.*]] = arith.cmpi slt, %[[VAL_3]], %[[VAL_6]] : index 67// CHECK: %[[VAL_10:.*]] = arith.cmpi sle, %[[VAL_1]], %[[VAL_4]] : index 68// CHECK: %[[VAL_11:.*]] = arith.andi %[[VAL_7]], %[[VAL_8]] : i1 69// CHECK: %[[VAL_12:.*]] = arith.andi %[[VAL_9]], %[[VAL_10]] : i1 70// CHECK: %[[VAL_13:.*]] = arith.ori %[[VAL_11]], %[[VAL_12]] : i1 71// CHECK: %[[VAL_14:.*]] = arith.andi %[[VAL_5]], %[[VAL_13]] : i1 72// CHECK: cond_br %[[VAL_14]], ^bb2, ^bb3 73// CHECK: ^bb2: 74// CHECK: %[[VAL_15:.*]] = fir.call @f2() : () -> i1 75// CHECK: %[[VAL_16:.*]] = arith.addi %[[VAL_4]], %[[VAL_3]] : index 76// CHECK: br ^bb1(%[[VAL_16]], %[[VAL_15]] : index, i1) 77// CHECK: ^bb3: 78// CHECK: return 79// CHECK: } 80// CHECK: func private @f3(i16) 81 82// ----- 83 84// do_loop with an extra loop-carried value 85func.func @x3(%lo : index, %up : index) -> i1 { 86 %c1 = arith.constant 1 : index 87 %ok1 = arith.constant true 88 %ok2 = fir.do_loop %i = %lo to %up step %c1 iter_args(%j = %ok1) -> i1 { 89 %ok = fir.call @f2() : () -> i1 90 fir.result %ok : i1 91 } 92 return %ok2 : i1 93} 94 95// CHECK-LABEL: func @x3( 96// CHECK-SAME: %[[VAL_0:.*]]: index, 97// CHECK-SAME: %[[VAL_1:.*]]: index) -> i1 { 98// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index 99// CHECK: %[[VAL_3:.*]] = arith.constant true 100// CHECK: %[[VAL_4:.*]] = arith.subi %[[VAL_1]], %[[VAL_0]] : index 101// CHECK: %[[VAL_5:.*]] = arith.addi %[[VAL_4]], %[[VAL_2]] : index 102// CHECK: %[[VAL_6:.*]] = arith.divsi %[[VAL_5]], %[[VAL_2]] : index 103// CHECK: br ^bb1(%[[VAL_0]], %[[VAL_3]], %[[VAL_6]] : index, i1, index) 104// CHECK: ^bb1(%[[VAL_7:.*]]: index, %[[VAL_8:.*]]: i1, %[[VAL_9:.*]]: index): 105// CHECK: %[[VAL_10:.*]] = arith.constant 0 : index 106// CHECK: %[[VAL_11:.*]] = arith.cmpi sgt, %[[VAL_9]], %[[VAL_10]] : index 107// CHECK: cond_br %[[VAL_11]], ^bb2, ^bb3 108// CHECK: ^bb2: 109// CHECK: %[[VAL_12:.*]] = fir.call @f2() : () -> i1 110// CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_7]], %[[VAL_2]] : index 111// CHECK: %[[VAL_14:.*]] = arith.constant 1 : index 112// CHECK: %[[VAL_15:.*]] = arith.subi %[[VAL_9]], %[[VAL_14]] : index 113// CHECK: br ^bb1(%[[VAL_13]], %[[VAL_12]], %[[VAL_15]] : index, i1, index) 114// CHECK: ^bb3: 115// CHECK: return %[[VAL_8]] : i1 116// CHECK: } 117 118// ----- 119 120// iterate_while with an extra loop-carried value 121func.func @y3(%lo : index, %up : index) -> i1 { 122 %c1 = arith.constant 1 : index 123 %ok1 = arith.constant true 124 %ok4 = fir.call @f2() : () -> i1 125 %ok2:2 = fir.iterate_while (%i = %lo to %up step %c1) and (%ok3 = %ok1) iter_args(%j = %ok4) -> i1 { 126 %ok = fir.call @f2() : () -> i1 127 fir.result %ok3, %ok : i1, i1 128 } 129 %andok = arith.andi %ok2#0, %ok2#1 : i1 130 return %andok : i1 131} 132 133func.func private @f4(i32) -> i1 134 135// CHECK-LABEL: func @y3( 136// CHECK-SAME: %[[VAL_0:.*]]: index, 137// CHECK-SAME: %[[VAL_1:.*]]: index) -> i1 { 138// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index 139// CHECK: %[[VAL_3:.*]] = arith.constant true 140// CHECK: %[[VAL_4:.*]] = fir.call @f2() : () -> i1 141// CHECK: br ^bb1(%[[VAL_0]], %[[VAL_3]], %[[VAL_4]] : index, i1, i1) 142// CHECK: ^bb1(%[[VAL_5:.*]]: index, %[[VAL_6:.*]]: i1, %[[VAL_7:.*]]: i1): 143// CHECK: %[[VAL_8:.*]] = arith.constant 0 : index 144// CHECK: %[[VAL_9:.*]] = arith.cmpi slt, %[[VAL_8]], %[[VAL_2]] : index 145// CHECK: %[[VAL_10:.*]] = arith.cmpi sle, %[[VAL_5]], %[[VAL_1]] : index 146// CHECK: %[[VAL_11:.*]] = arith.cmpi slt, %[[VAL_2]], %[[VAL_8]] : index 147// CHECK: %[[VAL_12:.*]] = arith.cmpi sle, %[[VAL_1]], %[[VAL_5]] : index 148// CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_9]], %[[VAL_10]] : i1 149// CHECK: %[[VAL_14:.*]] = arith.andi %[[VAL_11]], %[[VAL_12]] : i1 150// CHECK: %[[VAL_15:.*]] = arith.ori %[[VAL_13]], %[[VAL_14]] : i1 151// CHECK: %[[VAL_16:.*]] = arith.andi %[[VAL_6]], %[[VAL_15]] : i1 152// CHECK: cond_br %[[VAL_16]], ^bb2, ^bb3 153// CHECK: ^bb2: 154// CHECK: %[[VAL_17:.*]] = fir.call @f2() : () -> i1 155// CHECK: %[[VAL_18:.*]] = arith.addi %[[VAL_5]], %[[VAL_2]] : index 156// CHECK: br ^bb1(%[[VAL_18]], %[[VAL_6]], %[[VAL_17]] : index, i1, i1) 157// CHECK: ^bb3: 158// CHECK: %[[VAL_19:.*]] = arith.andi %[[VAL_6]], %[[VAL_7]] : i1 159// CHECK: return %[[VAL_19]] : i1 160// CHECK: } 161// CHECK: func private @f4(i32) -> i1 162 163// ----- 164 165// do_loop that returns the final value of the induction 166func.func @x4(%lo : index, %up : index) -> index { 167 %c1 = arith.constant 1 : index 168 %v = fir.do_loop %i = %lo to %up step %c1 -> index { 169 %i1 = fir.convert %i : (index) -> i32 170 %ok = fir.call @f4(%i1) : (i32) -> i1 171 fir.result %i : index 172 } 173 return %v : index 174} 175 176// CHECK-LABEL: func @x4( 177// CHECK-SAME: %[[VAL_0:.*]]: index, 178// CHECK-SAME: %[[VAL_1:.*]]: index) -> index { 179// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index 180// CHECK: %[[VAL_3:.*]] = arith.subi %[[VAL_1]], %[[VAL_0]] : index 181// CHECK: %[[VAL_4:.*]] = arith.addi %[[VAL_3]], %[[VAL_2]] : index 182// CHECK: %[[VAL_5:.*]] = arith.divsi %[[VAL_4]], %[[VAL_2]] : index 183// CHECK: br ^bb1(%[[VAL_0]], %[[VAL_5]] : index, index) 184// CHECK: ^bb1(%[[VAL_6:.*]]: index, %[[VAL_7:.*]]: index): 185// CHECK: %[[VAL_8:.*]] = arith.constant 0 : index 186// CHECK: %[[VAL_9:.*]] = arith.cmpi sgt, %[[VAL_7]], %[[VAL_8]] : index 187// CHECK: cond_br %[[VAL_9]], ^bb2, ^bb3 188// CHECK: ^bb2: 189// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_6]] : (index) -> i32 190// CHECK: %[[VAL_11:.*]] = fir.call @f4(%[[VAL_10]]) : (i32) -> i1 191// CHECK: %[[VAL_12:.*]] = arith.addi %[[VAL_6]], %[[VAL_2]] : index 192// CHECK: %[[VAL_13:.*]] = arith.constant 1 : index 193// CHECK: %[[VAL_14:.*]] = arith.subi %[[VAL_7]], %[[VAL_13]] : index 194// CHECK: br ^bb1(%[[VAL_12]], %[[VAL_14]] : index, index) 195// CHECK: ^bb3: 196// CHECK: return %[[VAL_6]] : index 197// CHECK: } 198 199// ----- 200 201// iterate_while that returns the final value of both inductions 202func.func @y4(%lo : index, %up : index) -> index { 203 %c1 = arith.constant 1 : index 204 %ok1 = arith.constant true 205 %v:2 = fir.iterate_while (%i = %lo to %up step %c1) and (%ok2 = %ok1) -> (index, i1) { 206 %i1 = fir.convert %i : (index) -> i32 207 %ok = fir.call @f4(%i1) : (i32) -> i1 208 fir.result %i, %ok : index, i1 209 } 210 return %v#0 : index 211} 212 213// CHECK-LABEL: func @y4( 214// CHECK-SAME: %[[VAL_0:.*]]: index, 215// CHECK-SAME: %[[VAL_1:.*]]: index) -> index { 216// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index 217// CHECK: %[[VAL_3:.*]] = arith.constant true 218// CHECK: br ^bb1(%[[VAL_0]], %[[VAL_3]] : index, i1) 219// CHECK: ^bb1(%[[VAL_4:.*]]: index, %[[VAL_5:.*]]: i1): 220// CHECK: %[[VAL_6:.*]] = arith.constant 0 : index 221// CHECK: %[[VAL_7:.*]] = arith.cmpi slt, %[[VAL_6]], %[[VAL_2]] : index 222// CHECK: %[[VAL_8:.*]] = arith.cmpi sle, %[[VAL_4]], %[[VAL_1]] : index 223// CHECK: %[[VAL_9:.*]] = arith.cmpi slt, %[[VAL_2]], %[[VAL_6]] : index 224// CHECK: %[[VAL_10:.*]] = arith.cmpi sle, %[[VAL_1]], %[[VAL_4]] : index 225// CHECK: %[[VAL_11:.*]] = arith.andi %[[VAL_7]], %[[VAL_8]] : i1 226// CHECK: %[[VAL_12:.*]] = arith.andi %[[VAL_9]], %[[VAL_10]] : i1 227// CHECK: %[[VAL_13:.*]] = arith.ori %[[VAL_11]], %[[VAL_12]] : i1 228// CHECK: %[[VAL_14:.*]] = arith.andi %[[VAL_5]], %[[VAL_13]] : i1 229// CHECK: cond_br %[[VAL_14]], ^bb2, ^bb3 230// CHECK: ^bb2: 231// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_4]] : (index) -> i32 232// CHECK: %[[VAL_16:.*]] = fir.call @f4(%[[VAL_15]]) : (i32) -> i1 233// CHECK: %[[VAL_17:.*]] = arith.addi %[[VAL_4]], %[[VAL_2]] : index 234// CHECK: br ^bb1(%[[VAL_17]], %[[VAL_16]] : index, i1) 235// CHECK: ^bb3: 236// CHECK: return %[[VAL_4]] : index 237// CHECK: } 238 239// ----- 240 241// do_loop that returns the final induction value 242// and an extra loop-carried value 243func.func @x5(%lo : index, %up : index) -> index { 244 %c1 = arith.constant 1 : index 245 %s1 = arith.constant 42 : i16 246 %v:2 = fir.do_loop %i = %lo to %up step %c1 iter_args(%s = %s1) -> (index, i16) { 247 %ok = fir.call @f2() : () -> i1 248 %s2 = fir.convert %ok : (i1) -> i16 249 fir.result %i, %s2 : index, i16 250 } 251 fir.call @f3(%v#1) : (i16) -> () 252 return %v#0 : index 253} 254 255// CHECK-LABEL: func @x5( 256// CHECK-SAME: %[[VAL_0:.*]]: index, 257// CHECK-SAME: %[[VAL_1:.*]]: index) -> index { 258// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index 259// CHECK: %[[VAL_3:.*]] = arith.constant 42 : i16 260// CHECK: %[[VAL_4:.*]] = arith.subi %[[VAL_1]], %[[VAL_0]] : index 261// CHECK: %[[VAL_5:.*]] = arith.addi %[[VAL_4]], %[[VAL_2]] : index 262// CHECK: %[[VAL_6:.*]] = arith.divsi %[[VAL_5]], %[[VAL_2]] : index 263// CHECK: br ^bb1(%[[VAL_0]], %[[VAL_3]], %[[VAL_6]] : index, i16, index) 264// CHECK: ^bb1(%[[VAL_7:.*]]: index, %[[VAL_8:.*]]: i16, %[[VAL_9:.*]]: index): 265// CHECK: %[[VAL_10:.*]] = arith.constant 0 : index 266// CHECK: %[[VAL_11:.*]] = arith.cmpi sgt, %[[VAL_9]], %[[VAL_10]] : index 267// CHECK: cond_br %[[VAL_11]], ^bb2, ^bb3 268// CHECK: ^bb2: 269// CHECK: %[[VAL_12:.*]] = fir.call @f2() : () -> i1 270// CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i1) -> i16 271// CHECK: %[[VAL_14:.*]] = arith.addi %[[VAL_7]], %[[VAL_2]] : index 272// CHECK: %[[VAL_15:.*]] = arith.constant 1 : index 273// CHECK: %[[VAL_16:.*]] = arith.subi %[[VAL_9]], %[[VAL_15]] : index 274// CHECK: br ^bb1(%[[VAL_14]], %[[VAL_13]], %[[VAL_16]] : index, i16, index) 275// CHECK: ^bb3: 276// CHECK: fir.call @f3(%[[VAL_8]]) : (i16) -> () 277// CHECK: return %[[VAL_7]] : index 278// CHECK: } 279 280// ----- 281 282// iterate_while that returns the both induction values 283// and an extra loop-carried value 284func.func @y5(%lo : index, %up : index) -> index { 285 %c1 = arith.constant 1 : index 286 %s1 = arith.constant 42 : i16 287 %ok1 = arith.constant true 288 %v:3 = fir.iterate_while (%i = %lo to %up step %c1) and (%ok2 = %ok1) iter_args(%s = %s1) -> (index, i1, i16) { 289 %ok = fir.call @f2() : () -> i1 290 %s2 = fir.convert %ok : (i1) -> i16 291 fir.result %i, %ok, %s2 : index, i1, i16 292 } 293 fir.if %v#1 { 294 %arg = arith.constant 0 : i32 295 %ok4 = fir.call @f4(%arg) : (i32) -> i1 296 } 297 fir.call @f3(%v#2) : (i16) -> () 298 return %v#0 : index 299} 300 301// CHECK-LABEL: func @y5( 302// CHECK-SAME: %[[VAL_0:.*]]: index, 303// CHECK-SAME: %[[VAL_1:.*]]: index) -> index { 304// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index 305// CHECK: %[[VAL_3:.*]] = arith.constant 42 : i16 306// CHECK: %[[VAL_4:.*]] = arith.constant true 307// CHECK: br ^bb1(%[[VAL_0]], %[[VAL_4]], %[[VAL_3]] : index, i1, i16) 308// CHECK: ^bb1(%[[VAL_5:.*]]: index, %[[VAL_6:.*]]: i1, %[[VAL_7:.*]]: i16): 309// CHECK: %[[VAL_8:.*]] = arith.constant 0 : index 310// CHECK: %[[VAL_9:.*]] = arith.cmpi slt, %[[VAL_8]], %[[VAL_2]] : index 311// CHECK: %[[VAL_10:.*]] = arith.cmpi sle, %[[VAL_5]], %[[VAL_1]] : index 312// CHECK: %[[VAL_11:.*]] = arith.cmpi slt, %[[VAL_2]], %[[VAL_8]] : index 313// CHECK: %[[VAL_12:.*]] = arith.cmpi sle, %[[VAL_1]], %[[VAL_5]] : index 314// CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_9]], %[[VAL_10]] : i1 315// CHECK: %[[VAL_14:.*]] = arith.andi %[[VAL_11]], %[[VAL_12]] : i1 316// CHECK: %[[VAL_15:.*]] = arith.ori %[[VAL_13]], %[[VAL_14]] : i1 317// CHECK: %[[VAL_16:.*]] = arith.andi %[[VAL_6]], %[[VAL_15]] : i1 318// CHECK: cond_br %[[VAL_16]], ^bb2, ^bb3 319// CHECK: ^bb2: 320// CHECK: %[[VAL_17:.*]] = fir.call @f2() : () -> i1 321// CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_17]] : (i1) -> i16 322// CHECK: %[[VAL_19:.*]] = arith.addi %[[VAL_5]], %[[VAL_2]] : index 323// CHECK: br ^bb1(%[[VAL_19]], %[[VAL_17]], %[[VAL_18]] : index, i1, i16) 324// CHECK: ^bb3: 325// CHECK: cond_br %[[VAL_6]], ^bb4, ^bb5 326// CHECK: ^bb4: 327// CHECK: %[[VAL_20:.*]] = arith.constant 0 : i32 328// CHECK: %[[VAL_21:.*]] = fir.call @f4(%[[VAL_20]]) : (i32) -> i1 329// CHECK: br ^bb5 330// CHECK: ^bb5: 331// CHECK: fir.call @f3(%[[VAL_7]]) : (i16) -> () 332// CHECK: return %[[VAL_5]] : index 333// CHECK: } 334