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