337 lines · plain
1// RUN: fir-opt --split-input-file --cfg-conversion %s | FileCheck %s2// RUN: fir-opt --split-input-file --cfg-conversion="set-nsw=false" %s | FileCheck %s --check-prefix=NO-NSW3 4// NO-NSW-NOT: overflow<nsw>5 6func.func @x(%lb : index, %ub : index, %step : index, %b : i1, %addr : !fir.ref<index>) {7 fir.do_loop %iv = %lb to %ub step %step unordered {8 // expect following conditional blocks to get fused9 fir.if %b {10 fir.store %iv to %addr : !fir.ref<index>11 } else {12 %zero = arith.constant 0 : index13 fir.store %zero to %addr : !fir.ref<index>14 }15 }16 return17}18 19func.func private @f2() -> i120 21// CHECK: func @x(%[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index, %[[VAL_2:.*]]: index, %[[VAL_3:.*]]: i1, %[[VAL_4:.*]]: !fir.ref<index>) {22// CHECK: %[[VAL_5:.*]] = arith.subi %[[VAL_1]], %[[VAL_0]] : index23// CHECK: %[[VAL_6:.*]] = arith.addi %[[VAL_5]], %[[VAL_2]] : index24// CHECK: %[[VAL_7:.*]] = arith.divsi %[[VAL_6]], %[[VAL_2]] : index25// CHECK: br ^bb1(%[[VAL_0]], %[[VAL_7]] : index, index)26// CHECK: ^bb1(%[[VAL_8:.*]]: index, %[[VAL_9:.*]]: index):27// CHECK: %[[VAL_10:.*]] = arith.constant 0 : index28// CHECK: %[[VAL_11:.*]] = arith.cmpi sgt, %[[VAL_9]], %[[VAL_10]] : index29// CHECK: cond_br %[[VAL_11]], ^bb2, ^bb630// CHECK: ^bb2:31// CHECK: cond_br %[[VAL_3]], ^bb3, ^bb432// CHECK: ^bb3:33// CHECK: fir.store %[[VAL_8]] to %[[VAL_4]] : !fir.ref<index>34// CHECK: br ^bb535// CHECK: ^bb4:36// CHECK: %[[VAL_12:.*]] = arith.constant 0 : index37// CHECK: fir.store %[[VAL_12]] to %[[VAL_4]] : !fir.ref<index>38// CHECK: br ^bb539// CHECK: ^bb5:40// CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_8]], %[[VAL_2]] overflow<nsw> : index41// CHECK: %[[VAL_14:.*]] = arith.constant 1 : index42// CHECK: %[[VAL_15:.*]] = arith.subi %[[VAL_9]], %[[VAL_14]] : index43// CHECK: br ^bb1(%[[VAL_13]], %[[VAL_15]] : index, index)44// CHECK: ^bb6:45// CHECK: return46// CHECK: }47// CHECK: func private @f2() -> i148 49// -----50 51func.func @x2(%lo : index, %up : index, %ok : i1) {52 %c1 = arith.constant 1 : index53 %unused = fir.iterate_while (%i = %lo to %up step %c1) and (%ok1 = %ok) {54 %ok2 = fir.call @f2() : () -> i155 fir.result %ok2 : i156 }57 return58}59 60func.func private @f3(i16)61 62// CHECK: func @x2(%[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index, %[[VAL_2:.*]]: i1) {63// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index64// CHECK: br ^bb1(%[[VAL_0]], %[[VAL_2]] : index, i1)65// CHECK: ^bb1(%[[VAL_4:.*]]: index, %[[VAL_5:.*]]: i1):66// CHECK: %[[VAL_6:.*]] = arith.constant 0 : index67// CHECK: %[[VAL_7:.*]] = arith.cmpi slt, %[[VAL_6]], %[[VAL_3]] : index68// CHECK: %[[VAL_8:.*]] = arith.cmpi sle, %[[VAL_4]], %[[VAL_1]] : index69// CHECK: %[[VAL_9:.*]] = arith.cmpi slt, %[[VAL_3]], %[[VAL_6]] : index70// CHECK: %[[VAL_10:.*]] = arith.cmpi sle, %[[VAL_1]], %[[VAL_4]] : index71// CHECK: %[[VAL_11:.*]] = arith.andi %[[VAL_7]], %[[VAL_8]] : i172// CHECK: %[[VAL_12:.*]] = arith.andi %[[VAL_9]], %[[VAL_10]] : i173// CHECK: %[[VAL_13:.*]] = arith.ori %[[VAL_11]], %[[VAL_12]] : i174// CHECK: %[[VAL_14:.*]] = arith.andi %[[VAL_5]], %[[VAL_13]] : i175// CHECK: cond_br %[[VAL_14]], ^bb2, ^bb376// CHECK: ^bb2:77// CHECK: %[[VAL_15:.*]] = fir.call @f2() : () -> i178// CHECK: %[[VAL_16:.*]] = arith.addi %[[VAL_4]], %[[VAL_3]] overflow<nsw> : index79// CHECK: br ^bb1(%[[VAL_16]], %[[VAL_15]] : index, i1)80// CHECK: ^bb3:81// CHECK: return82// CHECK: }83// CHECK: func private @f3(i16)84 85// -----86 87// do_loop with an extra loop-carried value88func.func @x3(%lo : index, %up : index) -> i1 {89 %c1 = arith.constant 1 : index90 %ok1 = arith.constant true91 %ok2 = fir.do_loop %i = %lo to %up step %c1 iter_args(%j = %ok1) -> i1 {92 %ok = fir.call @f2() : () -> i193 fir.result %ok : i194 }95 return %ok2 : i196}97 98// CHECK-LABEL: func @x3(99// CHECK-SAME: %[[VAL_0:.*]]: index,100// CHECK-SAME: %[[VAL_1:.*]]: index) -> i1 {101// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index102// CHECK: %[[VAL_3:.*]] = arith.constant true103// CHECK: %[[VAL_4:.*]] = arith.subi %[[VAL_1]], %[[VAL_0]] : index104// CHECK: %[[VAL_5:.*]] = arith.addi %[[VAL_4]], %[[VAL_2]] : index105// CHECK: %[[VAL_6:.*]] = arith.divsi %[[VAL_5]], %[[VAL_2]] : index106// CHECK: br ^bb1(%[[VAL_0]], %[[VAL_3]], %[[VAL_6]] : index, i1, index)107// CHECK: ^bb1(%[[VAL_7:.*]]: index, %[[VAL_8:.*]]: i1, %[[VAL_9:.*]]: index):108// CHECK: %[[VAL_10:.*]] = arith.constant 0 : index109// CHECK: %[[VAL_11:.*]] = arith.cmpi sgt, %[[VAL_9]], %[[VAL_10]] : index110// CHECK: cond_br %[[VAL_11]], ^bb2, ^bb3111// CHECK: ^bb2:112// CHECK: %[[VAL_12:.*]] = fir.call @f2() : () -> i1113// CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_7]], %[[VAL_2]] overflow<nsw> : index114// CHECK: %[[VAL_14:.*]] = arith.constant 1 : index115// CHECK: %[[VAL_15:.*]] = arith.subi %[[VAL_9]], %[[VAL_14]] : index116// CHECK: br ^bb1(%[[VAL_13]], %[[VAL_12]], %[[VAL_15]] : index, i1, index)117// CHECK: ^bb3:118// CHECK: return %[[VAL_8]] : i1119// CHECK: }120 121// -----122 123// iterate_while with an extra loop-carried value124func.func @y3(%lo : index, %up : index) -> i1 {125 %c1 = arith.constant 1 : index126 %ok1 = arith.constant true127 %ok4 = fir.call @f2() : () -> i1128 %ok2:2 = fir.iterate_while (%i = %lo to %up step %c1) and (%ok3 = %ok1) iter_args(%j = %ok4) -> i1 {129 %ok = fir.call @f2() : () -> i1130 fir.result %ok3, %ok : i1, i1131 }132 %andok = arith.andi %ok2#0, %ok2#1 : i1133 return %andok : i1134}135 136func.func private @f4(i32) -> i1137 138// CHECK-LABEL: func @y3(139// CHECK-SAME: %[[VAL_0:.*]]: index,140// CHECK-SAME: %[[VAL_1:.*]]: index) -> i1 {141// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index142// CHECK: %[[VAL_3:.*]] = arith.constant true143// CHECK: %[[VAL_4:.*]] = fir.call @f2() : () -> i1144// CHECK: br ^bb1(%[[VAL_0]], %[[VAL_3]], %[[VAL_4]] : index, i1, i1)145// CHECK: ^bb1(%[[VAL_5:.*]]: index, %[[VAL_6:.*]]: i1, %[[VAL_7:.*]]: i1):146// CHECK: %[[VAL_8:.*]] = arith.constant 0 : index147// CHECK: %[[VAL_9:.*]] = arith.cmpi slt, %[[VAL_8]], %[[VAL_2]] : index148// CHECK: %[[VAL_10:.*]] = arith.cmpi sle, %[[VAL_5]], %[[VAL_1]] : index149// CHECK: %[[VAL_11:.*]] = arith.cmpi slt, %[[VAL_2]], %[[VAL_8]] : index150// CHECK: %[[VAL_12:.*]] = arith.cmpi sle, %[[VAL_1]], %[[VAL_5]] : index151// CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_9]], %[[VAL_10]] : i1152// CHECK: %[[VAL_14:.*]] = arith.andi %[[VAL_11]], %[[VAL_12]] : i1153// CHECK: %[[VAL_15:.*]] = arith.ori %[[VAL_13]], %[[VAL_14]] : i1154// CHECK: %[[VAL_16:.*]] = arith.andi %[[VAL_6]], %[[VAL_15]] : i1155// CHECK: cond_br %[[VAL_16]], ^bb2, ^bb3156// CHECK: ^bb2:157// CHECK: %[[VAL_17:.*]] = fir.call @f2() : () -> i1158// CHECK: %[[VAL_18:.*]] = arith.addi %[[VAL_5]], %[[VAL_2]] overflow<nsw> : index159// CHECK: br ^bb1(%[[VAL_18]], %[[VAL_6]], %[[VAL_17]] : index, i1, i1)160// CHECK: ^bb3:161// CHECK: %[[VAL_19:.*]] = arith.andi %[[VAL_6]], %[[VAL_7]] : i1162// CHECK: return %[[VAL_19]] : i1163// CHECK: }164// CHECK: func private @f4(i32) -> i1165 166// -----167 168// do_loop that returns the final value of the induction169func.func @x4(%lo : index, %up : index) -> index {170 %c1 = arith.constant 1 : index171 %v = fir.do_loop %i = %lo to %up step %c1 -> index {172 %i1 = fir.convert %i : (index) -> i32173 %ok = fir.call @f4(%i1) : (i32) -> i1174 fir.result %i : index175 }176 return %v : index177}178 179// CHECK-LABEL: func @x4(180// CHECK-SAME: %[[VAL_0:.*]]: index,181// CHECK-SAME: %[[VAL_1:.*]]: index) -> index {182// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index183// CHECK: %[[VAL_3:.*]] = arith.subi %[[VAL_1]], %[[VAL_0]] : index184// CHECK: %[[VAL_4:.*]] = arith.addi %[[VAL_3]], %[[VAL_2]] : index185// CHECK: %[[VAL_5:.*]] = arith.divsi %[[VAL_4]], %[[VAL_2]] : index186// CHECK: br ^bb1(%[[VAL_0]], %[[VAL_5]] : index, index)187// CHECK: ^bb1(%[[VAL_6:.*]]: index, %[[VAL_7:.*]]: index):188// CHECK: %[[VAL_8:.*]] = arith.constant 0 : index189// CHECK: %[[VAL_9:.*]] = arith.cmpi sgt, %[[VAL_7]], %[[VAL_8]] : index190// CHECK: cond_br %[[VAL_9]], ^bb2, ^bb3191// CHECK: ^bb2:192// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_6]] : (index) -> i32193// CHECK: %[[VAL_11:.*]] = fir.call @f4(%[[VAL_10]]) : (i32) -> i1194// CHECK: %[[VAL_12:.*]] = arith.addi %[[VAL_6]], %[[VAL_2]] overflow<nsw> : index195// CHECK: %[[VAL_13:.*]] = arith.constant 1 : index196// CHECK: %[[VAL_14:.*]] = arith.subi %[[VAL_7]], %[[VAL_13]] : index197// CHECK: br ^bb1(%[[VAL_12]], %[[VAL_14]] : index, index)198// CHECK: ^bb3:199// CHECK: return %[[VAL_6]] : index200// CHECK: }201 202// -----203 204// iterate_while that returns the final value of both inductions205func.func @y4(%lo : index, %up : index) -> index {206 %c1 = arith.constant 1 : index207 %ok1 = arith.constant true208 %v:2 = fir.iterate_while (%i = %lo to %up step %c1) and (%ok2 = %ok1) -> (index, i1) {209 %i1 = fir.convert %i : (index) -> i32210 %ok = fir.call @f4(%i1) : (i32) -> i1211 fir.result %i, %ok : index, i1212 }213 return %v#0 : index214}215 216// CHECK-LABEL: func @y4(217// CHECK-SAME: %[[VAL_0:.*]]: index,218// CHECK-SAME: %[[VAL_1:.*]]: index) -> index {219// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index220// CHECK: %[[VAL_3:.*]] = arith.constant true221// CHECK: br ^bb1(%[[VAL_0]], %[[VAL_3]] : index, i1)222// CHECK: ^bb1(%[[VAL_4:.*]]: index, %[[VAL_5:.*]]: i1):223// CHECK: %[[VAL_6:.*]] = arith.constant 0 : index224// CHECK: %[[VAL_7:.*]] = arith.cmpi slt, %[[VAL_6]], %[[VAL_2]] : index225// CHECK: %[[VAL_8:.*]] = arith.cmpi sle, %[[VAL_4]], %[[VAL_1]] : index226// CHECK: %[[VAL_9:.*]] = arith.cmpi slt, %[[VAL_2]], %[[VAL_6]] : index227// CHECK: %[[VAL_10:.*]] = arith.cmpi sle, %[[VAL_1]], %[[VAL_4]] : index228// CHECK: %[[VAL_11:.*]] = arith.andi %[[VAL_7]], %[[VAL_8]] : i1229// CHECK: %[[VAL_12:.*]] = arith.andi %[[VAL_9]], %[[VAL_10]] : i1230// CHECK: %[[VAL_13:.*]] = arith.ori %[[VAL_11]], %[[VAL_12]] : i1231// CHECK: %[[VAL_14:.*]] = arith.andi %[[VAL_5]], %[[VAL_13]] : i1232// CHECK: cond_br %[[VAL_14]], ^bb2, ^bb3233// CHECK: ^bb2:234// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_4]] : (index) -> i32235// CHECK: %[[VAL_16:.*]] = fir.call @f4(%[[VAL_15]]) : (i32) -> i1236// CHECK: %[[VAL_17:.*]] = arith.addi %[[VAL_4]], %[[VAL_2]] overflow<nsw> : index237// CHECK: br ^bb1(%[[VAL_17]], %[[VAL_16]] : index, i1)238// CHECK: ^bb3:239// CHECK: return %[[VAL_4]] : index240// CHECK: }241 242// -----243 244// do_loop that returns the final induction value245// and an extra loop-carried value246func.func @x5(%lo : index, %up : index) -> index {247 %c1 = arith.constant 1 : index248 %s1 = arith.constant 42 : i16249 %v:2 = fir.do_loop %i = %lo to %up step %c1 iter_args(%s = %s1) -> (index, i16) {250 %ok = fir.call @f2() : () -> i1251 %s2 = fir.convert %ok : (i1) -> i16252 fir.result %i, %s2 : index, i16253 }254 fir.call @f3(%v#1) : (i16) -> ()255 return %v#0 : index256}257 258// CHECK-LABEL: func @x5(259// CHECK-SAME: %[[VAL_0:.*]]: index,260// CHECK-SAME: %[[VAL_1:.*]]: index) -> index {261// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index262// CHECK: %[[VAL_3:.*]] = arith.constant 42 : i16263// CHECK: %[[VAL_4:.*]] = arith.subi %[[VAL_1]], %[[VAL_0]] : index264// CHECK: %[[VAL_5:.*]] = arith.addi %[[VAL_4]], %[[VAL_2]] : index265// CHECK: %[[VAL_6:.*]] = arith.divsi %[[VAL_5]], %[[VAL_2]] : index266// CHECK: br ^bb1(%[[VAL_0]], %[[VAL_3]], %[[VAL_6]] : index, i16, index)267// CHECK: ^bb1(%[[VAL_7:.*]]: index, %[[VAL_8:.*]]: i16, %[[VAL_9:.*]]: index):268// CHECK: %[[VAL_10:.*]] = arith.constant 0 : index269// CHECK: %[[VAL_11:.*]] = arith.cmpi sgt, %[[VAL_9]], %[[VAL_10]] : index270// CHECK: cond_br %[[VAL_11]], ^bb2, ^bb3271// CHECK: ^bb2:272// CHECK: %[[VAL_12:.*]] = fir.call @f2() : () -> i1273// CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i1) -> i16274// CHECK: %[[VAL_14:.*]] = arith.addi %[[VAL_7]], %[[VAL_2]] overflow<nsw> : index275// CHECK: %[[VAL_15:.*]] = arith.constant 1 : index276// CHECK: %[[VAL_16:.*]] = arith.subi %[[VAL_9]], %[[VAL_15]] : index277// CHECK: br ^bb1(%[[VAL_14]], %[[VAL_13]], %[[VAL_16]] : index, i16, index)278// CHECK: ^bb3:279// CHECK: fir.call @f3(%[[VAL_8]]) : (i16) -> ()280// CHECK: return %[[VAL_7]] : index281// CHECK: }282 283// -----284 285// iterate_while that returns the both induction values286// and an extra loop-carried value287func.func @y5(%lo : index, %up : index) -> index {288 %c1 = arith.constant 1 : index289 %s1 = arith.constant 42 : i16290 %ok1 = arith.constant true291 %v:3 = fir.iterate_while (%i = %lo to %up step %c1) and (%ok2 = %ok1) iter_args(%s = %s1) -> (index, i1, i16) {292 %ok = fir.call @f2() : () -> i1293 %s2 = fir.convert %ok : (i1) -> i16294 fir.result %i, %ok, %s2 : index, i1, i16295 }296 fir.if %v#1 {297 %arg = arith.constant 0 : i32298 %ok4 = fir.call @f4(%arg) : (i32) -> i1299 }300 fir.call @f3(%v#2) : (i16) -> ()301 return %v#0 : index302}303 304// CHECK-LABEL: func @y5(305// CHECK-SAME: %[[VAL_0:.*]]: index,306// CHECK-SAME: %[[VAL_1:.*]]: index) -> index {307// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index308// CHECK: %[[VAL_3:.*]] = arith.constant 42 : i16309// CHECK: %[[VAL_4:.*]] = arith.constant true310// CHECK: br ^bb1(%[[VAL_0]], %[[VAL_4]], %[[VAL_3]] : index, i1, i16)311// CHECK: ^bb1(%[[VAL_5:.*]]: index, %[[VAL_6:.*]]: i1, %[[VAL_7:.*]]: i16):312// CHECK: %[[VAL_8:.*]] = arith.constant 0 : index313// CHECK: %[[VAL_9:.*]] = arith.cmpi slt, %[[VAL_8]], %[[VAL_2]] : index314// CHECK: %[[VAL_10:.*]] = arith.cmpi sle, %[[VAL_5]], %[[VAL_1]] : index315// CHECK: %[[VAL_11:.*]] = arith.cmpi slt, %[[VAL_2]], %[[VAL_8]] : index316// CHECK: %[[VAL_12:.*]] = arith.cmpi sle, %[[VAL_1]], %[[VAL_5]] : index317// CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_9]], %[[VAL_10]] : i1318// CHECK: %[[VAL_14:.*]] = arith.andi %[[VAL_11]], %[[VAL_12]] : i1319// CHECK: %[[VAL_15:.*]] = arith.ori %[[VAL_13]], %[[VAL_14]] : i1320// CHECK: %[[VAL_16:.*]] = arith.andi %[[VAL_6]], %[[VAL_15]] : i1321// CHECK: cond_br %[[VAL_16]], ^bb2, ^bb3322// CHECK: ^bb2:323// CHECK: %[[VAL_17:.*]] = fir.call @f2() : () -> i1324// CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_17]] : (i1) -> i16325// CHECK: %[[VAL_19:.*]] = arith.addi %[[VAL_5]], %[[VAL_2]] overflow<nsw> : index326// CHECK: br ^bb1(%[[VAL_19]], %[[VAL_17]], %[[VAL_18]] : index, i1, i16)327// CHECK: ^bb3:328// CHECK: cond_br %[[VAL_6]], ^bb4, ^bb5329// CHECK: ^bb4:330// CHECK: %[[VAL_20:.*]] = arith.constant 0 : i32331// CHECK: %[[VAL_21:.*]] = fir.call @f4(%[[VAL_20]]) : (i32) -> i1332// CHECK: br ^bb5333// CHECK: ^bb5:334// CHECK: fir.call @f3(%[[VAL_7]]) : (i16) -> ()335// CHECK: return %[[VAL_5]] : index336// CHECK: }337