1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2 ; RUN: opt < %s -instsimplify -S | FileCheck %s 3 4 ; Fold icmp with a constant operand. 5 6 define i1 @tautological_ule(i8 %x) { 7 ; CHECK-LABEL: @tautological_ule( 8 ; CHECK-NEXT: ret i1 true 9 ; 10 %cmp = icmp ule i8 %x, 255 11 ret i1 %cmp 12 } 13 14 define <2 x i1> @tautological_ule_vec(<2 x i8> %x) { 15 ; CHECK-LABEL: @tautological_ule_vec( 16 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 17 ; 18 %cmp = icmp ule <2 x i8> %x, <i8 255, i8 255> 19 ret <2 x i1> %cmp 20 } 21 22 define i1 @tautological_ugt(i8 %x) { 23 ; CHECK-LABEL: @tautological_ugt( 24 ; CHECK-NEXT: ret i1 false 25 ; 26 %cmp = icmp ugt i8 %x, 255 27 ret i1 %cmp 28 } 29 30 define <2 x i1> @tautological_ugt_vec(<2 x i8> %x) { 31 ; CHECK-LABEL: @tautological_ugt_vec( 32 ; CHECK-NEXT: ret <2 x i1> zeroinitializer 33 ; 34 %cmp = icmp ugt <2 x i8> %x, <i8 255, i8 255> 35 ret <2 x i1> %cmp 36 } 37 38 ; 'urem x, C2' produces [0, C2) 39 define i1 @urem3(i32 %X) { 40 ; CHECK-LABEL: @urem3( 41 ; CHECK-NEXT: ret i1 true 42 ; 43 %A = urem i32 %X, 10 44 %B = icmp ult i32 %A, 15 45 ret i1 %B 46 } 47 48 define <2 x i1> @urem3_vec(<2 x i32> %X) { 49 ; CHECK-LABEL: @urem3_vec( 50 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 51 ; 52 %A = urem <2 x i32> %X, <i32 10, i32 10> 53 %B = icmp ult <2 x i32> %A, <i32 15, i32 15> 54 ret <2 x i1> %B 55 } 56 57 ;'srem x, C2' produces (-|C2|, |C2|) 58 define i1 @srem1(i32 %X) { 59 ; CHECK-LABEL: @srem1( 60 ; CHECK-NEXT: ret i1 false 61 ; 62 %A = srem i32 %X, -5 63 %B = icmp sgt i32 %A, 5 64 ret i1 %B 65 } 66 67 define <2 x i1> @srem1_vec(<2 x i32> %X) { 68 ; CHECK-LABEL: @srem1_vec( 69 ; CHECK-NEXT: ret <2 x i1> zeroinitializer 70 ; 71 %A = srem <2 x i32> %X, <i32 -5, i32 -5> 72 %B = icmp sgt <2 x i32> %A, <i32 5, i32 5> 73 ret <2 x i1> %B 74 } 75 76 ;'udiv C2, x' produces [0, C2] 77 define i1 @udiv5(i32 %X) { 78 ; CHECK-LABEL: @udiv5( 79 ; CHECK-NEXT: ret i1 false 80 ; 81 %A = udiv i32 123, %X 82 %C = icmp ugt i32 %A, 124 83 ret i1 %C 84 } 85 86 define <2 x i1> @udiv5_vec(<2 x i32> %X) { 87 ; CHECK-LABEL: @udiv5_vec( 88 ; CHECK-NEXT: ret <2 x i1> zeroinitializer 89 ; 90 %A = udiv <2 x i32> <i32 123, i32 123>, %X 91 %C = icmp ugt <2 x i32> %A, <i32 124, i32 124> 92 ret <2 x i1> %C 93 } 94 95 ; 'udiv x, C2' produces [0, UINT_MAX / C2] 96 define i1 @udiv1(i32 %X) { 97 ; CHECK-LABEL: @udiv1( 98 ; CHECK-NEXT: ret i1 true 99 ; 100 %A = udiv i32 %X, 1000000 101 %B = icmp ult i32 %A, 5000 102 ret i1 %B 103 } 104 105 define <2 x i1> @udiv1_vec(<2 x i32> %X) { 106 ; CHECK-LABEL: @udiv1_vec( 107 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 108 ; 109 %A = udiv <2 x i32> %X, <i32 1000000, i32 1000000> 110 %B = icmp ult <2 x i32> %A, <i32 5000, i32 5000> 111 ret <2 x i1> %B 112 } 113 114 ; 'sdiv C2, x' produces [-|C2|, |C2|] 115 define i1 @compare_dividend(i32 %a) { 116 ; CHECK-LABEL: @compare_dividend( 117 ; CHECK-NEXT: ret i1 false 118 ; 119 %div = sdiv i32 2, %a 120 %cmp = icmp eq i32 %div, 3 121 ret i1 %cmp 122 } 123 124 define <2 x i1> @compare_dividend_vec(<2 x i32> %a) { 125 ; CHECK-LABEL: @compare_dividend_vec( 126 ; CHECK-NEXT: ret <2 x i1> zeroinitializer 127 ; 128 %div = sdiv <2 x i32> <i32 2, i32 2>, %a 129 %cmp = icmp eq <2 x i32> %div, <i32 3, i32 3> 130 ret <2 x i1> %cmp 131 } 132 133 ; 'sdiv x, C2' produces [INT_MIN / C2, INT_MAX / C2] 134 ; where C2 != -1 and C2 != 0 and C2 != 1 135 define i1 @sdiv1(i32 %X) { 136 ; CHECK-LABEL: @sdiv1( 137 ; CHECK-NEXT: ret i1 true 138 ; 139 %A = sdiv i32 %X, 1000000 140 %B = icmp slt i32 %A, 3000 141 ret i1 %B 142 } 143 144 define <2 x i1> @sdiv1_vec(<2 x i32> %X) { 145 ; CHECK-LABEL: @sdiv1_vec( 146 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 147 ; 148 %A = sdiv <2 x i32> %X, <i32 1000000, i32 1000000> 149 %B = icmp slt <2 x i32> %A, <i32 3000, i32 3000> 150 ret <2 x i1> %B 151 } 152 153 ; 'shl nuw C2, x' produces [C2, C2 << CLZ(C2)] 154 define i1 @shl5(i32 %X) { 155 ; CHECK-LABEL: @shl5( 156 ; CHECK-NEXT: ret i1 true 157 ; 158 %sub = shl nuw i32 4, %X 159 %cmp = icmp ugt i32 %sub, 3 160 ret i1 %cmp 161 } 162 163 define <2 x i1> @shl5_vec(<2 x i32> %X) { 164 ; CHECK-LABEL: @shl5_vec( 165 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 166 ; 167 %sub = shl nuw <2 x i32> <i32 4, i32 4>, %X 168 %cmp = icmp ugt <2 x i32> %sub, <i32 3, i32 3> 169 ret <2 x i1> %cmp 170 } 171 172 ; 'shl nsw C2, x' produces [C2 << CLO(C2)-1, C2] 173 define i1 @shl2(i32 %X) { 174 ; CHECK-LABEL: @shl2( 175 ; CHECK-NEXT: ret i1 false 176 ; 177 %sub = shl nsw i32 -1, %X 178 %cmp = icmp eq i32 %sub, 31 179 ret i1 %cmp 180 } 181 182 define <2 x i1> @shl2_vec(<2 x i32> %X) { 183 ; CHECK-LABEL: @shl2_vec( 184 ; CHECK-NEXT: ret <2 x i1> zeroinitializer 185 ; 186 %sub = shl nsw <2 x i32> <i32 -1, i32 -1>, %X 187 %cmp = icmp eq <2 x i32> %sub, <i32 31, i32 31> 188 ret <2 x i1> %cmp 189 } 190 191 ; 'shl nsw C2, x' produces [C2 << CLO(C2)-1, C2] 192 define i1 @shl4(i32 %X) { 193 ; CHECK-LABEL: @shl4( 194 ; CHECK-NEXT: ret i1 true 195 ; 196 %sub = shl nsw i32 -1, %X 197 %cmp = icmp sle i32 %sub, -1 198 ret i1 %cmp 199 } 200 201 define <2 x i1> @shl4_vec(<2 x i32> %X) { 202 ; CHECK-LABEL: @shl4_vec( 203 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 204 ; 205 %sub = shl nsw <2 x i32> <i32 -1, i32 -1>, %X 206 %cmp = icmp sle <2 x i32> %sub, <i32 -1, i32 -1> 207 ret <2 x i1> %cmp 208 } 209 210 ; 'shl nsw C2, x' produces [C2, C2 << CLZ(C2)-1] 211 define i1 @icmp_shl_nsw_1(i64 %a) { 212 ; CHECK-LABEL: @icmp_shl_nsw_1( 213 ; CHECK-NEXT: ret i1 true 214 ; 215 %shl = shl nsw i64 1, %a 216 %cmp = icmp sge i64 %shl, 0 217 ret i1 %cmp 218 } 219 220 define <2 x i1> @icmp_shl_nsw_1_vec(<2 x i64> %a) { 221 ; CHECK-LABEL: @icmp_shl_nsw_1_vec( 222 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 223 ; 224 %shl = shl nsw <2 x i64> <i64 1, i64 1>, %a 225 %cmp = icmp sge <2 x i64> %shl, zeroinitializer 226 ret <2 x i1> %cmp 227 } 228 229 ; 'shl nsw C2, x' produces [C2 << CLO(C2)-1, C2] 230 define i1 @icmp_shl_nsw_neg1(i64 %a) { 231 ; CHECK-LABEL: @icmp_shl_nsw_neg1( 232 ; CHECK-NEXT: ret i1 false 233 ; 234 %shl = shl nsw i64 -1, %a 235 %cmp = icmp sge i64 %shl, 3 236 ret i1 %cmp 237 } 238 239 define <2 x i1> @icmp_shl_nsw_neg1_vec(<2 x i64> %a) { 240 ; CHECK-LABEL: @icmp_shl_nsw_neg1_vec( 241 ; CHECK-NEXT: ret <2 x i1> zeroinitializer 242 ; 243 %shl = shl nsw <2 x i64> <i64 -1, i64 -1>, %a 244 %cmp = icmp sge <2 x i64> %shl, <i64 3, i64 3> 245 ret <2 x i1> %cmp 246 } 247 248 ; 'lshr x, C2' produces [0, UINT_MAX >> C2] 249 define i1 @lshr2(i32 %x) { 250 ; CHECK-LABEL: @lshr2( 251 ; CHECK-NEXT: ret i1 false 252 ; 253 %s = lshr i32 %x, 30 254 %c = icmp ugt i32 %s, 8 255 ret i1 %c 256 } 257 258 define <2 x i1> @lshr2_vec(<2 x i32> %x) { 259 ; CHECK-LABEL: @lshr2_vec( 260 ; CHECK-NEXT: ret <2 x i1> zeroinitializer 261 ; 262 %s = lshr <2 x i32> %x, <i32 30, i32 30> 263 %c = icmp ugt <2 x i32> %s, <i32 8, i32 8> 264 ret <2 x i1> %c 265 } 266 267 ; 'lshr C2, x' produces [C2 >> (Width-1), C2] 268 define i1 @exact_lshr_ugt_false(i32 %a) { 269 ; CHECK-LABEL: @exact_lshr_ugt_false( 270 ; CHECK-NEXT: ret i1 false 271 ; 272 %shr = lshr exact i32 30, %a 273 %cmp = icmp ult i32 %shr, 15 274 ret i1 %cmp 275 } 276 277 define <2 x i1> @exact_lshr_ugt_false_vec(<2 x i32> %a) { 278 ; CHECK-LABEL: @exact_lshr_ugt_false_vec( 279 ; CHECK-NEXT: ret <2 x i1> zeroinitializer 280 ; 281 %shr = lshr exact <2 x i32> <i32 30, i32 30>, %a 282 %cmp = icmp ult <2 x i32> %shr, <i32 15, i32 15> 283 ret <2 x i1> %cmp 284 } 285 286 ; 'lshr C2, x' produces [C2 >> (Width-1), C2] 287 define i1 @lshr_sgt_false(i32 %a) { 288 ; CHECK-LABEL: @lshr_sgt_false( 289 ; CHECK-NEXT: ret i1 false 290 ; 291 %shr = lshr i32 1, %a 292 %cmp = icmp sgt i32 %shr, 1 293 ret i1 %cmp 294 } 295 296 define <2 x i1> @lshr_sgt_false_vec(<2 x i32> %a) { 297 ; CHECK-LABEL: @lshr_sgt_false_vec( 298 ; CHECK-NEXT: ret <2 x i1> zeroinitializer 299 ; 300 %shr = lshr <2 x i32> <i32 1, i32 1>, %a 301 %cmp = icmp sgt <2 x i32> %shr, <i32 1, i32 1> 302 ret <2 x i1> %cmp 303 } 304 305 ; 'ashr x, C2' produces [INT_MIN >> C2, INT_MAX >> C2] 306 define i1 @ashr2(i32 %x) { 307 ; CHECK-LABEL: @ashr2( 308 ; CHECK-NEXT: ret i1 false 309 ; 310 %s = ashr i32 %x, 30 311 %c = icmp slt i32 %s, -5 312 ret i1 %c 313 } 314 315 define <2 x i1> @ashr2_vec(<2 x i32> %x) { 316 ; CHECK-LABEL: @ashr2_vec( 317 ; CHECK-NEXT: ret <2 x i1> zeroinitializer 318 ; 319 %s = ashr <2 x i32> %x, <i32 30, i32 30> 320 %c = icmp slt <2 x i32> %s, <i32 -5, i32 -5> 321 ret <2 x i1> %c 322 } 323 324 ; 'ashr C2, x' produces [C2, C2 >> (Width-1)] 325 define i1 @ashr_sgt_false(i32 %a) { 326 ; CHECK-LABEL: @ashr_sgt_false( 327 ; CHECK-NEXT: ret i1 false 328 ; 329 %shr = ashr i32 -30, %a 330 %cmp = icmp sgt i32 %shr, -1 331 ret i1 %cmp 332 } 333 334 define <2 x i1> @ashr_sgt_false_vec(<2 x i32> %a) { 335 ; CHECK-LABEL: @ashr_sgt_false_vec( 336 ; CHECK-NEXT: ret <2 x i1> zeroinitializer 337 ; 338 %shr = ashr <2 x i32> <i32 -30, i32 -30>, %a 339 %cmp = icmp sgt <2 x i32> %shr, <i32 -1, i32 -1> 340 ret <2 x i1> %cmp 341 } 342 343 ; 'ashr C2, x' produces [C2, C2 >> (Width-1)] 344 define i1 @exact_ashr_sgt_false(i32 %a) { 345 ; CHECK-LABEL: @exact_ashr_sgt_false( 346 ; CHECK-NEXT: ret i1 false 347 ; 348 %shr = ashr exact i32 -30, %a 349 %cmp = icmp sgt i32 %shr, -15 350 ret i1 %cmp 351 } 352 353 define <2 x i1> @exact_ashr_sgt_false_vec(<2 x i32> %a) { 354 ; CHECK-LABEL: @exact_ashr_sgt_false_vec( 355 ; CHECK-NEXT: ret <2 x i1> zeroinitializer 356 ; 357 %shr = ashr exact <2 x i32> <i32 -30, i32 -30>, %a 358 %cmp = icmp sgt <2 x i32> %shr, <i32 -15, i32 -15> 359 ret <2 x i1> %cmp 360 } 361 362 ; 'or x, C2' produces [C2, UINT_MAX] 363 define i1 @or1(i32 %X) { 364 ; CHECK-LABEL: @or1( 365 ; CHECK-NEXT: ret i1 false 366 ; 367 %A = or i32 %X, 62 368 %B = icmp ult i32 %A, 50 369 ret i1 %B 370 } 371 372 define <2 x i1> @or1_vec(<2 x i32> %X) { 373 ; CHECK-LABEL: @or1_vec( 374 ; CHECK-NEXT: ret <2 x i1> zeroinitializer 375 ; 376 %A = or <2 x i32> %X, <i32 62, i32 62> 377 %B = icmp ult <2 x i32> %A, <i32 50, i32 50> 378 ret <2 x i1> %B 379 } 380 381 ; 'and x, C2' produces [0, C2] 382 define i1 @and1(i32 %X) { 383 ; CHECK-LABEL: @and1( 384 ; CHECK-NEXT: ret i1 false 385 ; 386 %A = and i32 %X, 62 387 %B = icmp ugt i32 %A, 70 388 ret i1 %B 389 } 390 391 define <2 x i1> @and1_vec(<2 x i32> %X) { 392 ; CHECK-LABEL: @and1_vec( 393 ; CHECK-NEXT: ret <2 x i1> zeroinitializer 394 ; 395 %A = and <2 x i32> %X, <i32 62, i32 62> 396 %B = icmp ugt <2 x i32> %A, <i32 70, i32 70> 397 ret <2 x i1> %B 398 } 399 400 ; 'add nuw x, C2' produces [C2, UINT_MAX] 401 define i1 @tautological9(i32 %x) { 402 ; CHECK-LABEL: @tautological9( 403 ; CHECK-NEXT: ret i1 true 404 ; 405 %add = add nuw i32 %x, 13 406 %cmp = icmp ne i32 %add, 12 407 ret i1 %cmp 408 } 409 410 define <2 x i1> @tautological9_vec(<2 x i32> %x) { 411 ; CHECK-LABEL: @tautological9_vec( 412 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 413 ; 414 %add = add nuw <2 x i32> %x, <i32 13, i32 13> 415 %cmp = icmp ne <2 x i32> %add, <i32 12, i32 12> 416 ret <2 x i1> %cmp 417 } 418 419 ; The upper bound of the 'add' is 0. 420 421 define i1 @add_nsw_neg_const1(i32 %x) { 422 ; CHECK-LABEL: @add_nsw_neg_const1( 423 ; CHECK-NEXT: ret i1 false 424 ; 425 %add = add nsw i32 %x, -2147483647 426 %cmp = icmp sgt i32 %add, 0 427 ret i1 %cmp 428 } 429 430 ; InstCombine can fold this, but not InstSimplify. 431 432 define i1 @add_nsw_neg_const2(i32 %x) { 433 ; CHECK-LABEL: @add_nsw_neg_const2( 434 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 %x, -2147483647 435 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[ADD]], -1 436 ; CHECK-NEXT: ret i1 [[CMP]] 437 ; 438 %add = add nsw i32 %x, -2147483647 439 %cmp = icmp sgt i32 %add, -1 440 ret i1 %cmp 441 } 442 443 ; The upper bound of the 'add' is 1 (move the constants to prove we're doing range-based analysis). 444 445 define i1 @add_nsw_neg_const3(i32 %x) { 446 ; CHECK-LABEL: @add_nsw_neg_const3( 447 ; CHECK-NEXT: ret i1 false 448 ; 449 %add = add nsw i32 %x, -2147483646 450 %cmp = icmp sgt i32 %add, 1 451 ret i1 %cmp 452 } 453 454 ; InstCombine can fold this, but not InstSimplify. 455 456 define i1 @add_nsw_neg_const4(i32 %x) { 457 ; CHECK-LABEL: @add_nsw_neg_const4( 458 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 %x, -2147483646 459 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[ADD]], 0 460 ; CHECK-NEXT: ret i1 [[CMP]] 461 ; 462 %add = add nsw i32 %x, -2147483646 463 %cmp = icmp sgt i32 %add, 0 464 ret i1 %cmp 465 } 466 467 ; The upper bound of the 'add' is 2147483647 - 42 = 2147483605 (move the constants again and try a different cmp predicate). 468 469 define i1 @add_nsw_neg_const5(i32 %x) { 470 ; CHECK-LABEL: @add_nsw_neg_const5( 471 ; CHECK-NEXT: ret i1 true 472 ; 473 %add = add nsw i32 %x, -42 474 %cmp = icmp ne i32 %add, 2147483606 475 ret i1 %cmp 476 } 477 478 ; InstCombine can fold this, but not InstSimplify. 479 480 define i1 @add_nsw_neg_const6(i32 %x) { 481 ; CHECK-LABEL: @add_nsw_neg_const6( 482 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 %x, -42 483 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[ADD]], 2147483605 484 ; CHECK-NEXT: ret i1 [[CMP]] 485 ; 486 %add = add nsw i32 %x, -42 487 %cmp = icmp ne i32 %add, 2147483605 488 ret i1 %cmp 489 } 490 491 ; The lower bound of the 'add' is -1. 492 493 define i1 @add_nsw_pos_const1(i32 %x) { 494 ; CHECK-LABEL: @add_nsw_pos_const1( 495 ; CHECK-NEXT: ret i1 false 496 ; 497 %add = add nsw i32 %x, 2147483647 498 %cmp = icmp slt i32 %add, -1 499 ret i1 %cmp 500 } 501 502 ; InstCombine can fold this, but not InstSimplify. 503 504 define i1 @add_nsw_pos_const2(i32 %x) { 505 ; CHECK-LABEL: @add_nsw_pos_const2( 506 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 %x, 2147483647 507 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD]], 0 508 ; CHECK-NEXT: ret i1 [[CMP]] 509 ; 510 %add = add nsw i32 %x, 2147483647 511 %cmp = icmp slt i32 %add, 0 512 ret i1 %cmp 513 } 514 515 ; The lower bound of the 'add' is -2 (move the constants to prove we're doing range-based analysis). 516 517 define i1 @add_nsw_pos_const3(i32 %x) { 518 ; CHECK-LABEL: @add_nsw_pos_const3( 519 ; CHECK-NEXT: ret i1 false 520 ; 521 %add = add nsw i32 %x, 2147483646 522 %cmp = icmp slt i32 %add, -2 523 ret i1 %cmp 524 } 525 526 ; InstCombine can fold this, but not InstSimplify. 527 528 define i1 @add_nsw_pos_const4(i32 %x) { 529 ; CHECK-LABEL: @add_nsw_pos_const4( 530 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 %x, 2147483646 531 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD]], -1 532 ; CHECK-NEXT: ret i1 [[CMP]] 533 ; 534 %add = add nsw i32 %x, 2147483646 535 %cmp = icmp slt i32 %add, -1 536 ret i1 %cmp 537 } 538 539 ; The lower bound of the 'add' is -2147483648 + 42 = -2147483606 (move the constants again and change the cmp predicate). 540 541 define i1 @add_nsw_pos_const5(i32 %x) { 542 ; CHECK-LABEL: @add_nsw_pos_const5( 543 ; CHECK-NEXT: ret i1 false 544 ; 545 %add = add nsw i32 %x, 42 546 %cmp = icmp eq i32 %add, -2147483607 547 ret i1 %cmp 548 } 549 550 ; InstCombine can fold this, but not InstSimplify. 551 552 define i1 @add_nsw_pos_const6(i32 %x) { 553 ; CHECK-LABEL: @add_nsw_pos_const6( 554 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 %x, 42 555 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[ADD]], -2147483606 556 ; CHECK-NEXT: ret i1 [[CMP]] 557 ; 558 %add = add nsw i32 %x, 42 559 %cmp = icmp eq i32 %add, -2147483606 560 ret i1 %cmp 561 } 562 563 ; Verify that vectors work too. 564 565 define <2 x i1> @add_nsw_pos_const5_splat_vec(<2 x i32> %x) { 566 ; CHECK-LABEL: @add_nsw_pos_const5_splat_vec( 567 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 568 ; 569 %add = add nsw <2 x i32> %x, <i32 42, i32 42> 570 %cmp = icmp ne <2 x i32> %add, <i32 -2147483607, i32 -2147483607> 571 ret <2 x i1> %cmp 572 } 573 574 ; PR34838 - https://bugs.llvm.org/show_bug.cgi?id=34838 575 ; The shift is known to create poison, so we can simplify the cmp. 576 577 define i1 @ne_shl_by_constant_produces_poison(i8 %x) { 578 ; CHECK-LABEL: @ne_shl_by_constant_produces_poison( 579 ; CHECK-NEXT: ret i1 true 580 ; 581 %zx = zext i8 %x to i16 ; zx = 0x00xx 582 %xor = xor i16 %zx, 32767 ; xor = 0x7fyy 583 %sub = sub nsw i16 %zx, %xor ; sub = 0x80zz (the top bit is known one) 584 %poison = shl nsw i16 %sub, 2 ; oops! this shl can't be nsw; that's POISON 585 %cmp = icmp ne i16 %poison, 1 586 ret i1 %cmp 587 } 588 589 define i1 @eq_shl_by_constant_produces_poison(i8 %x) { 590 ; CHECK-LABEL: @eq_shl_by_constant_produces_poison( 591 ; CHECK-NEXT: ret i1 false 592 ; 593 %clear_high_bit = and i8 %x, 127 ; 0x7f 594 %set_next_high_bits = or i8 %clear_high_bit, 112 ; 0x70 595 %poison = shl nsw i8 %set_next_high_bits, 3 596 %cmp = icmp eq i8 %poison, 15 597 ret i1 %cmp 598 } 599 600 ; Shift-by-variable that produces poison is more complicated but still possible. 601 ; We guarantee that the shift will change the sign of the shifted value (and 602 ; therefore produce poison) by limiting its range from 1 to 3. 603 604 define i1 @eq_shl_by_variable_produces_poison(i8 %x) { 605 ; CHECK-LABEL: @eq_shl_by_variable_produces_poison( 606 ; CHECK-NEXT: ret i1 false 607 ; 608 %clear_high_bit = and i8 %x, 127 ; 0x7f 609 %set_next_high_bits = or i8 %clear_high_bit, 112 ; 0x70 610 %notundef_shiftamt = and i8 %x, 3 611 %nonzero_shiftamt = or i8 %notundef_shiftamt, 1 612 %poison = shl nsw i8 %set_next_high_bits, %nonzero_shiftamt 613 %cmp = icmp eq i8 %poison, 15 614 ret i1 %cmp 615 } 616 617