1 ; RUN: opt -S %s -instsimplify | FileCheck %s 2 3 ; A ==> A -> true 4 define i1 @test(i32 %length.i, i32 %i) { 5 ; CHECK-LABEL: @test 6 ; CHECK: ret i1 true 7 %var29 = icmp slt i32 %i, %length.i 8 %res = icmp uge i1 %var29, %var29 9 ret i1 %res 10 } 11 12 ; i +_{nsw} C_{>0} <s L ==> i <s L -> true 13 define i1 @test2(i32 %length.i, i32 %i) { 14 ; CHECK-LABEL: @test2 15 ; CHECK: ret i1 true 16 %iplus1 = add nsw i32 %i, 1 17 %var29 = icmp slt i32 %i, %length.i 18 %var30 = icmp slt i32 %iplus1, %length.i 19 %res = icmp ule i1 %var30, %var29 20 ret i1 %res 21 } 22 23 ; i + C_{>0} <s L ==> i <s L -> unknown without the nsw 24 define i1 @test2_neg(i32 %length.i, i32 %i) { 25 ; CHECK-LABEL: @test2_neg 26 ; CHECK: ret i1 %res 27 %iplus1 = add i32 %i, 1 28 %var29 = icmp slt i32 %i, %length.i 29 %var30 = icmp slt i32 %iplus1, %length.i 30 %res = icmp ule i1 %var30, %var29 31 ret i1 %res 32 } 33 34 ; sle is not implication 35 define i1 @test2_neg2(i32 %length.i, i32 %i) { 36 ; CHECK-LABEL: @test2_neg2 37 ; CHECK: ret i1 %res 38 %iplus1 = add i32 %i, 1 39 %var29 = icmp slt i32 %i, %length.i 40 %var30 = icmp slt i32 %iplus1, %length.i 41 %res = icmp sle i1 %var30, %var29 42 ret i1 %res 43 } 44 45 ; The binary operator has to be an add 46 define i1 @test2_neg3(i32 %length.i, i32 %i) { 47 ; CHECK-LABEL: @test2_neg3 48 ; CHECK: ret i1 %res 49 %iplus1 = sub nsw i32 %i, 1 50 %var29 = icmp slt i32 %i, %length.i 51 %var30 = icmp slt i32 %iplus1, %length.i 52 %res = icmp ule i1 %var30, %var29 53 ret i1 %res 54 } 55 56 ; i +_{nsw} C_{>0} <s L ==> i <s L -> true 57 ; With an inverted conditional (ule B A rather than canonical ugt A B 58 define i1 @test3(i32 %length.i, i32 %i) { 59 ; CHECK-LABEL: @test3 60 ; CHECK: ret i1 true 61 %iplus1 = add nsw i32 %i, 1 62 %var29 = icmp slt i32 %i, %length.i 63 %var30 = icmp slt i32 %iplus1, %length.i 64 %res = icmp uge i1 %var29, %var30 65 ret i1 %res 66 } 67 68 ; i +_{nuw} C <u L ==> i <u L 69 define i1 @test4(i32 %length.i, i32 %i) { 70 ; CHECK-LABEL: @test4 71 ; CHECK: ret i1 true 72 %iplus1 = add nuw i32 %i, 1 73 %var29 = icmp ult i32 %i, %length.i 74 %var30 = icmp ult i32 %iplus1, %length.i 75 %res = icmp ule i1 %var30, %var29 76 ret i1 %res 77 } 78 79 ; A ==> A for vectors 80 define <4 x i1> @test5(<4 x i1> %vec) { 81 ; CHECK-LABEL: @test5 82 ; CHECK: ret <4 x i1> <i1 true, i1 true, i1 true, i1 true> 83 %res = icmp ule <4 x i1> %vec, %vec 84 ret <4 x i1> %res 85 } 86 87 ; Don't crash on vector inputs - pr25040 88 define <4 x i1> @test6(<4 x i1> %a, <4 x i1> %b) { 89 ; CHECK-LABEL: @test6 90 ; CHECK: ret <4 x i1> %res 91 %res = icmp ule <4 x i1> %a, %b 92 ret <4 x i1> %res 93 } 94 95 ; i +_{nsw} 1 <s L ==> i < L +_{nsw} 1 96 define i1 @test7(i32 %length.i, i32 %i) { 97 ; CHECK-LABEL: @test7( 98 ; CHECK: ret i1 true 99 %iplus1 = add nsw i32 %i, 1 100 %len.plus.one = add nsw i32 %length.i, 1 101 %var29 = icmp slt i32 %i, %len.plus.one 102 %var30 = icmp slt i32 %iplus1, %length.i 103 %res = icmp ule i1 %var30, %var29 104 ret i1 %res 105 } 106 107 ; i +_{nuw} 1 <s L ==> i < L +_{nuw} 1 108 define i1 @test8(i32 %length.i, i32 %i) { 109 ; CHECK-LABEL: @test8( 110 ; CHECK: ret i1 true 111 %iplus1 = add nuw i32 %i, 1 112 %len.plus.one = add nuw i32 %length.i, 1 113 %var29 = icmp ult i32 %i, %len.plus.one 114 %var30 = icmp ult i32 %iplus1, %length.i 115 %res = icmp ule i1 %var30, %var29 116 ret i1 %res 117 } 118 119 ; i +_{nuw} C <s L ==> i < L, even if C is negative 120 define i1 @test9(i32 %length.i, i32 %i) { 121 ; CHECK-LABEL: @test9( 122 ; CHECK: ret i1 true 123 %iplus1 = add nuw i32 %i, -100 124 %var29 = icmp ult i32 %i, %length.i 125 %var30 = icmp ult i32 %iplus1, %length.i 126 %res = icmp ule i1 %var30, %var29 127 ret i1 %res 128 } 129 130 define i1 @test10(i32 %length.i, i32 %x.full) { 131 ; CHECK-LABEL: @test10( 132 ; CHECK: ret i1 true 133 134 %x = and i32 %x.full, 4294901760 ;; 4294901760 == 0xffff0000 135 %large = or i32 %x, 100 136 %small = or i32 %x, 90 137 %known = icmp ult i32 %large, %length.i 138 %to.prove = icmp ult i32 %small, %length.i 139 %res = icmp ule i1 %known, %to.prove 140 ret i1 %res 141 } 142 143 define i1 @test11(i32 %length.i, i32 %x) { 144 ; CHECK-LABEL: @test11( 145 ; CHECK: %res = icmp ule i1 %known, %to.prove 146 ; CHECK: ret i1 %res 147 148 %large = or i32 %x, 100 149 %small = or i32 %x, 90 150 %known = icmp ult i32 %large, %length.i 151 %to.prove = icmp ult i32 %small, %length.i 152 %res = icmp ule i1 %known, %to.prove 153 ret i1 %res 154 } 155 156 define i1 @test12(i32 %length.i, i32 %x.full) { 157 ; CHECK-LABEL: @test12( 158 ; CHECK: %res = icmp ule i1 %known, %to.prove 159 ; CHECK: ret i1 %res 160 161 %x = and i32 %x.full, 4294901760 ;; 4294901760 == 0xffff0000 162 %large = or i32 %x, 65536 ;; 65536 == 0x00010000 163 %small = or i32 %x, 90 164 %known = icmp ult i32 %large, %length.i 165 %to.prove = icmp ult i32 %small, %length.i 166 %res = icmp ule i1 %known, %to.prove 167 ret i1 %res 168 } 169 170 define i1 @test13(i32 %length.i, i32 %x) { 171 ; CHECK-LABEL: @test13( 172 ; CHECK: ret i1 true 173 174 %large = add nuw i32 %x, 100 175 %small = add nuw i32 %x, 90 176 %known = icmp ult i32 %large, %length.i 177 %to.prove = icmp ult i32 %small, %length.i 178 %res = icmp ule i1 %known, %to.prove 179 ret i1 %res 180 } 181 182 define i1 @test14(i32 %length.i, i32 %x.full) { 183 ; CHECK-LABEL: @test14( 184 ; CHECK: ret i1 true 185 186 %x = and i32 %x.full, 4294905615 ;; 4294905615 == 0xffff0f0f 187 %large = or i32 %x, 8224 ;; == 0x2020 188 %small = or i32 %x, 4112 ;; == 0x1010 189 %known = icmp ult i32 %large, %length.i 190 %to.prove = icmp ult i32 %small, %length.i 191 %res = icmp ule i1 %known, %to.prove 192 ret i1 %res 193 } 194 195 define i1 @test15(i32 %length.i, i32 %x) { 196 ; CHECK-LABEL: @test15( 197 ; CHECK: %res = icmp ule i1 %known, %to.prove 198 ; CHECK: ret i1 %res 199 200 %large = add nuw i32 %x, 100 201 %small = add nuw i32 %x, 110 202 %known = icmp ult i32 %large, %length.i 203 %to.prove = icmp ult i32 %small, %length.i 204 %res = icmp ule i1 %known, %to.prove 205 ret i1 %res 206 } 207 208 ; X >=(s) Y == X ==> Y (i1 1 becomes -1 for reasoning) 209 define i1 @test_sge(i32 %length.i, i32 %i) { 210 ; CHECK-LABEL: @test_sge 211 ; CHECK: ret i1 true 212 %iplus1 = add nsw nuw i32 %i, 1 213 %var29 = icmp ult i32 %i, %length.i 214 %var30 = icmp ult i32 %iplus1, %length.i 215 %res = icmp sge i1 %var30, %var29 216 ret i1 %res 217 } 218