1// RUN: mlir-opt -int-range-optimizations %s | FileCheck %s 2 3// CHECK-LABEL: func @constant 4// CHECK: %[[cst:.*]] = "test.constant"() <{value = 3 : index} 5// CHECK: return %[[cst]] 6func.func @constant() -> index { 7 %0 = test.with_bounds { umin = 3 : index, umax = 3 : index, 8 smin = 3 : index, smax = 3 : index} : index 9 func.return %0 : index 10} 11 12// CHECK-LABEL: func @increment 13// CHECK: %[[cst:.*]] = "test.constant"() <{value = 4 : index} 14// CHECK: return %[[cst]] 15func.func @increment() -> index { 16 %0 = test.with_bounds { umin = 3 : index, umax = 3 : index, smin = 0 : index, smax = 0x7fffffffffffffff : index } : index 17 %1 = test.increment %0 : index 18 func.return %1 : index 19} 20 21// CHECK-LABEL: func @maybe_increment 22// CHECK: test.reflect_bounds {smax = 4 : index, smin = 3 : index, umax = 4 : index, umin = 3 : index} 23func.func @maybe_increment(%arg0 : i1) -> index { 24 %0 = test.with_bounds { umin = 3 : index, umax = 3 : index, 25 smin = 3 : index, smax = 3 : index} : index 26 %1 = scf.if %arg0 -> index { 27 scf.yield %0 : index 28 } else { 29 %2 = test.increment %0 : index 30 scf.yield %2 : index 31 } 32 %3 = test.reflect_bounds %1 : index 33 func.return %3 : index 34} 35 36// CHECK-LABEL: func @maybe_increment_br 37// CHECK: test.reflect_bounds {smax = 4 : index, smin = 3 : index, umax = 4 : index, umin = 3 : index} 38func.func @maybe_increment_br(%arg0 : i1) -> index { 39 %0 = test.with_bounds { umin = 3 : index, umax = 3 : index, 40 smin = 3 : index, smax = 3 : index} : index 41 cf.cond_br %arg0, ^bb0, ^bb1 42^bb0: 43 %1 = test.increment %0 : index 44 cf.br ^bb2(%1 : index) 45^bb1: 46 cf.br ^bb2(%0 : index) 47^bb2(%2 : index): 48 %3 = test.reflect_bounds %2 : index 49 func.return %3 : index 50} 51 52// CHECK-LABEL: func @for_bounds 53// CHECK: test.reflect_bounds {smax = 1 : index, smin = 0 : index, umax = 1 : index, umin = 0 : index} 54func.func @for_bounds() -> index { 55 %c0 = test.with_bounds { umin = 0 : index, umax = 0 : index, 56 smin = 0 : index, smax = 0 : index} : index 57 %c1 = test.with_bounds { umin = 1 : index, umax = 1 : index, 58 smin = 1 : index, smax = 1 : index} : index 59 %c2 = test.with_bounds { umin = 2 : index, umax = 2 : index, 60 smin = 2 : index, smax = 2 : index} : index 61 62 %0 = scf.for %arg0 = %c0 to %c2 step %c1 iter_args(%arg2 = %c0) -> index { 63 scf.yield %arg0 : index 64 } 65 %1 = test.reflect_bounds %0 : index 66 func.return %1 : index 67} 68 69// CHECK-LABEL: func @no_analysis_of_loop_variants 70// CHECK: test.reflect_bounds {smax = 9223372036854775807 : index, smin = -9223372036854775808 : index, umax = -1 : index, umin = 0 : index} 71func.func @no_analysis_of_loop_variants() -> index { 72 %c0 = test.with_bounds { umin = 0 : index, umax = 0 : index, 73 smin = 0 : index, smax = 0 : index} : index 74 %c1 = test.with_bounds { umin = 1 : index, umax = 1 : index, 75 smin = 1 : index, smax = 1 : index} : index 76 %c2 = test.with_bounds { umin = 2 : index, umax = 2 : index, 77 smin = 2 : index, smax = 2 : index} : index 78 79 %0 = scf.for %arg0 = %c0 to %c2 step %c1 iter_args(%arg2 = %c0) -> index { 80 %1 = test.increment %arg2 : index 81 scf.yield %1 : index 82 } 83 %2 = test.reflect_bounds %0 : index 84 func.return %2 : index 85} 86 87// CHECK-LABEL: func @region_args 88// CHECK: test.reflect_bounds {smax = 4 : index, smin = 3 : index, umax = 4 : index, umin = 3 : index} 89func.func @region_args() { 90 test.with_bounds_region { umin = 3 : index, umax = 4 : index, 91 smin = 3 : index, smax = 4 : index } %arg0 : index { 92 %0 = test.reflect_bounds %arg0 : index 93 } 94 func.return 95} 96 97// CHECK-LABEL: func @func_args_unbound 98// CHECK: test.reflect_bounds {smax = 9223372036854775807 : index, smin = -9223372036854775808 : index, umax = -1 : index, umin = 0 : index} 99func.func @func_args_unbound(%arg0 : index) -> index { 100 %0 = test.reflect_bounds %arg0 : index 101 func.return %0 : index 102} 103 104// CHECK-LABEL: func @propagate_across_while_loop_false() 105func.func @propagate_across_while_loop_false() -> index { 106 // CHECK: %[[C1:.*]] = "test.constant"() <{value = 1 107 %0 = test.with_bounds { umin = 0 : index, umax = 0 : index, 108 smin = 0 : index, smax = 0 : index } : index 109 %1 = scf.while : () -> index { 110 %false = arith.constant false 111 scf.condition(%false) %0 : index 112 } do { 113 ^bb0(%i1: index): 114 scf.yield 115 } 116 // CHECK: return %[[C1]] 117 %2 = test.increment %1 : index 118 return %2 : index 119} 120 121// CHECK-LABEL: func @propagate_across_while_loop 122func.func @propagate_across_while_loop(%arg0 : i1) -> index { 123 // CHECK: %[[C1:.*]] = "test.constant"() <{value = 1 124 %0 = test.with_bounds { umin = 0 : index, umax = 0 : index, 125 smin = 0 : index, smax = 0 : index } : index 126 %1 = scf.while : () -> index { 127 scf.condition(%arg0) %0 : index 128 } do { 129 ^bb0(%i1: index): 130 scf.yield 131 } 132 // CHECK: return %[[C1]] 133 %2 = test.increment %1 : index 134 return %2 : index 135} 136 137// CHECK-LABEL: func @dont_propagate_across_infinite_loop() 138func.func @dont_propagate_across_infinite_loop() -> index { 139 // CHECK: %[[C0:.*]] = "test.constant"() <{value = 0 140 %0 = test.with_bounds { umin = 0 : index, umax = 0 : index, 141 smin = 0 : index, smax = 0 : index } : index 142 // CHECK: %[[loopRes:.*]] = scf.while 143 %1 = scf.while : () -> index { 144 %true = arith.constant true 145 // CHECK: scf.condition(%{{.*}}) %[[C0]] 146 scf.condition(%true) %0 : index 147 } do { 148 ^bb0(%i1: index): 149 scf.yield 150 } 151 // CHECK: %[[ret:.*]] = test.reflect_bounds %[[loopRes]] : index 152 %2 = test.reflect_bounds %1 : index 153 // CHECK: return %[[ret]] 154 return %2 : index 155} 156 157