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 6define 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 14define <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 22define 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 30define <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) 39define 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 48define <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|) 58define 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 67define <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] 77define 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 86define <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] 96define 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 105define <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|] 115define 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 124define <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 135define 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 144define <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)] 154define 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 163define <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] 173define 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 182define <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] 192define 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 201define <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] 211define 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 220define <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] 230define 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 239define <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] 249define 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 258define <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] 268define 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 277define <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] 287define 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 296define <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] 306define 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 315define <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)] 325define 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 334define <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)] 344define 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 353define <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] 363define 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 372define <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; Single bit OR. 382define i1 @or2_true(i8 %x) { 383; CHECK-LABEL: @or2_true( 384; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], 64 385; CHECK-NEXT: [[Z:%.*]] = icmp sge i8 [[Y]], -64 386; CHECK-NEXT: ret i1 [[Z]] 387; 388 %y = or i8 %x, 64 389 %z = icmp sge i8 %y, -64 390 ret i1 %z 391} 392 393define i1 @or2_unknown(i8 %x) { 394; CHECK-LABEL: @or2_unknown( 395; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], 64 396; CHECK-NEXT: [[Z:%.*]] = icmp sgt i8 [[Y]], -64 397; CHECK-NEXT: ret i1 [[Z]] 398; 399 %y = or i8 %x, 64 400 %z = icmp sgt i8 %y, -64 401 ret i1 %z 402} 403 404; Multi bit OR. 405; 78 = 0b01001110; -50 = 0b11001110 406define i1 @or3_true(i8 %x) { 407; CHECK-LABEL: @or3_true( 408; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], 78 409; CHECK-NEXT: [[Z:%.*]] = icmp sge i8 [[Y]], -50 410; CHECK-NEXT: ret i1 [[Z]] 411; 412 %y = or i8 %x, 78 413 %z = icmp sge i8 %y, -50 414 ret i1 %z 415} 416 417define i1 @or3_unknown(i8 %x) { 418; CHECK-LABEL: @or3_unknown( 419; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], 78 420; CHECK-NEXT: [[Z:%.*]] = icmp sgt i8 [[Y]], -50 421; CHECK-NEXT: ret i1 [[Z]] 422; 423 %y = or i8 %x, 78 424 %z = icmp sgt i8 %y, -50 425 ret i1 %z 426} 427 428; OR with sign bit. 429define i1 @or4_true(i8 %x) { 430; CHECK-LABEL: @or4_true( 431; CHECK-NEXT: ret i1 true 432; 433 %y = or i8 %x, -64 434 %z = icmp sge i8 %y, -64 435 ret i1 %z 436} 437 438define i1 @or4_unknown(i8 %x) { 439; CHECK-LABEL: @or4_unknown( 440; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], -64 441; CHECK-NEXT: [[Z:%.*]] = icmp sgt i8 [[Y]], -64 442; CHECK-NEXT: ret i1 [[Z]] 443; 444 %y = or i8 %x, -64 445 %z = icmp sgt i8 %y, -64 446 ret i1 %z 447} 448 449; If sign bit is set, signed & unsigned ranges are the same. 450define i1 @or5_true(i8 %x) { 451; CHECK-LABEL: @or5_true( 452; CHECK-NEXT: ret i1 true 453; 454 %y = or i8 %x, -64 455 %z = icmp uge i8 %y, -64 456 ret i1 %z 457} 458 459define i1 @or5_unknown(i8 %x) { 460; CHECK-LABEL: @or5_unknown( 461; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], -64 462; CHECK-NEXT: [[Z:%.*]] = icmp ugt i8 [[Y]], -64 463; CHECK-NEXT: ret i1 [[Z]] 464; 465 %y = or i8 %x, -64 466 %z = icmp ugt i8 %y, -64 467 ret i1 %z 468} 469 470; 'and x, C2' produces [0, C2] 471define i1 @and1(i32 %X) { 472; CHECK-LABEL: @and1( 473; CHECK-NEXT: ret i1 false 474; 475 %A = and i32 %X, 62 476 %B = icmp ugt i32 %A, 70 477 ret i1 %B 478} 479 480define <2 x i1> @and1_vec(<2 x i32> %X) { 481; CHECK-LABEL: @and1_vec( 482; CHECK-NEXT: ret <2 x i1> zeroinitializer 483; 484 %A = and <2 x i32> %X, <i32 62, i32 62> 485 %B = icmp ugt <2 x i32> %A, <i32 70, i32 70> 486 ret <2 x i1> %B 487} 488 489; If the sign bit is not set, signed and unsigned ranges are the same. 490define i1 @and2(i32 %X) { 491; CHECK-LABEL: @and2( 492; CHECK-NEXT: ret i1 false 493; 494 %A = and i32 %X, 62 495 %B = icmp sgt i32 %A, 70 496 ret i1 %B 497} 498 499; -75 = 0b10110101, 53 = 0b00110101 500define i1 @and3_true1(i8 %x) { 501; CHECK-LABEL: @and3_true1( 502; CHECK-NEXT: [[Y:%.*]] = and i8 [[X:%.*]], -75 503; CHECK-NEXT: [[Z:%.*]] = icmp sge i8 [[Y]], -75 504; CHECK-NEXT: ret i1 [[Z]] 505; 506 %y = and i8 %x, -75 507 %z = icmp sge i8 %y, -75 508 ret i1 %z 509} 510 511define i1 @and3_unknown1(i8 %x) { 512; CHECK-LABEL: @and3_unknown1( 513; CHECK-NEXT: [[Y:%.*]] = and i8 [[X:%.*]], -75 514; CHECK-NEXT: [[Z:%.*]] = icmp sgt i8 [[Y]], -75 515; CHECK-NEXT: ret i1 [[Z]] 516; 517 %y = and i8 %x, -75 518 %z = icmp sgt i8 %y, -75 519 ret i1 %z 520} 521 522define i1 @and3_true2(i8 %x) { 523; CHECK-LABEL: @and3_true2( 524; CHECK-NEXT: [[Y:%.*]] = and i8 [[X:%.*]], -75 525; CHECK-NEXT: [[Z:%.*]] = icmp sle i8 [[Y]], 53 526; CHECK-NEXT: ret i1 [[Z]] 527; 528 %y = and i8 %x, -75 529 %z = icmp sle i8 %y, 53 530 ret i1 %z 531} 532 533define i1 @and3_unknown2(i8 %x) { 534; CHECK-LABEL: @and3_unknown2( 535; CHECK-NEXT: [[Y:%.*]] = and i8 [[X:%.*]], -75 536; CHECK-NEXT: [[Z:%.*]] = icmp slt i8 [[Y]], 53 537; CHECK-NEXT: ret i1 [[Z]] 538; 539 %y = and i8 %x, -75 540 %z = icmp slt i8 %y, 53 541 ret i1 %z 542} 543 544; 'add nuw x, C2' produces [C2, UINT_MAX] 545define i1 @tautological9(i32 %x) { 546; CHECK-LABEL: @tautological9( 547; CHECK-NEXT: ret i1 true 548; 549 %add = add nuw i32 %x, 13 550 %cmp = icmp ne i32 %add, 12 551 ret i1 %cmp 552} 553 554define <2 x i1> @tautological9_vec(<2 x i32> %x) { 555; CHECK-LABEL: @tautological9_vec( 556; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 557; 558 %add = add nuw <2 x i32> %x, <i32 13, i32 13> 559 %cmp = icmp ne <2 x i32> %add, <i32 12, i32 12> 560 ret <2 x i1> %cmp 561} 562 563; The upper bound of the 'add' is 0. 564 565define i1 @add_nsw_neg_const1(i32 %x) { 566; CHECK-LABEL: @add_nsw_neg_const1( 567; CHECK-NEXT: ret i1 false 568; 569 %add = add nsw i32 %x, -2147483647 570 %cmp = icmp sgt i32 %add, 0 571 ret i1 %cmp 572} 573 574; InstCombine can fold this, but not InstSimplify. 575 576define i1 @add_nsw_neg_const2(i32 %x) { 577; CHECK-LABEL: @add_nsw_neg_const2( 578; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], -2147483647 579; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[ADD]], -1 580; CHECK-NEXT: ret i1 [[CMP]] 581; 582 %add = add nsw i32 %x, -2147483647 583 %cmp = icmp sgt i32 %add, -1 584 ret i1 %cmp 585} 586 587; The upper bound of the 'add' is 1 (move the constants to prove we're doing range-based analysis). 588 589define i1 @add_nsw_neg_const3(i32 %x) { 590; CHECK-LABEL: @add_nsw_neg_const3( 591; CHECK-NEXT: ret i1 false 592; 593 %add = add nsw i32 %x, -2147483646 594 %cmp = icmp sgt i32 %add, 1 595 ret i1 %cmp 596} 597 598; InstCombine can fold this, but not InstSimplify. 599 600define i1 @add_nsw_neg_const4(i32 %x) { 601; CHECK-LABEL: @add_nsw_neg_const4( 602; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], -2147483646 603; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[ADD]], 0 604; CHECK-NEXT: ret i1 [[CMP]] 605; 606 %add = add nsw i32 %x, -2147483646 607 %cmp = icmp sgt i32 %add, 0 608 ret i1 %cmp 609} 610 611; The upper bound of the 'add' is 2147483647 - 42 = 2147483605 (move the constants again and try a different cmp predicate). 612 613define i1 @add_nsw_neg_const5(i32 %x) { 614; CHECK-LABEL: @add_nsw_neg_const5( 615; CHECK-NEXT: ret i1 true 616; 617 %add = add nsw i32 %x, -42 618 %cmp = icmp ne i32 %add, 2147483606 619 ret i1 %cmp 620} 621 622; InstCombine can fold this, but not InstSimplify. 623 624define i1 @add_nsw_neg_const6(i32 %x) { 625; CHECK-LABEL: @add_nsw_neg_const6( 626; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], -42 627; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[ADD]], 2147483605 628; CHECK-NEXT: ret i1 [[CMP]] 629; 630 %add = add nsw i32 %x, -42 631 %cmp = icmp ne i32 %add, 2147483605 632 ret i1 %cmp 633} 634 635; The lower bound of the 'add' is -1. 636 637define i1 @add_nsw_pos_const1(i32 %x) { 638; CHECK-LABEL: @add_nsw_pos_const1( 639; CHECK-NEXT: ret i1 false 640; 641 %add = add nsw i32 %x, 2147483647 642 %cmp = icmp slt i32 %add, -1 643 ret i1 %cmp 644} 645 646; InstCombine can fold this, but not InstSimplify. 647 648define i1 @add_nsw_pos_const2(i32 %x) { 649; CHECK-LABEL: @add_nsw_pos_const2( 650; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], 2147483647 651; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD]], 0 652; CHECK-NEXT: ret i1 [[CMP]] 653; 654 %add = add nsw i32 %x, 2147483647 655 %cmp = icmp slt i32 %add, 0 656 ret i1 %cmp 657} 658 659; The lower bound of the 'add' is -2 (move the constants to prove we're doing range-based analysis). 660 661define i1 @add_nsw_pos_const3(i32 %x) { 662; CHECK-LABEL: @add_nsw_pos_const3( 663; CHECK-NEXT: ret i1 false 664; 665 %add = add nsw i32 %x, 2147483646 666 %cmp = icmp slt i32 %add, -2 667 ret i1 %cmp 668} 669 670; InstCombine can fold this, but not InstSimplify. 671 672define i1 @add_nsw_pos_const4(i32 %x) { 673; CHECK-LABEL: @add_nsw_pos_const4( 674; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], 2147483646 675; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD]], -1 676; CHECK-NEXT: ret i1 [[CMP]] 677; 678 %add = add nsw i32 %x, 2147483646 679 %cmp = icmp slt i32 %add, -1 680 ret i1 %cmp 681} 682 683; The lower bound of the 'add' is -2147483648 + 42 = -2147483606 (move the constants again and change the cmp predicate). 684 685define i1 @add_nsw_pos_const5(i32 %x) { 686; CHECK-LABEL: @add_nsw_pos_const5( 687; CHECK-NEXT: ret i1 false 688; 689 %add = add nsw i32 %x, 42 690 %cmp = icmp eq i32 %add, -2147483607 691 ret i1 %cmp 692} 693 694; InstCombine can fold this, but not InstSimplify. 695 696define i1 @add_nsw_pos_const6(i32 %x) { 697; CHECK-LABEL: @add_nsw_pos_const6( 698; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], 42 699; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[ADD]], -2147483606 700; CHECK-NEXT: ret i1 [[CMP]] 701; 702 %add = add nsw i32 %x, 42 703 %cmp = icmp eq i32 %add, -2147483606 704 ret i1 %cmp 705} 706 707; Verify that vectors work too. 708 709define <2 x i1> @add_nsw_pos_const5_splat_vec(<2 x i32> %x) { 710; CHECK-LABEL: @add_nsw_pos_const5_splat_vec( 711; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 712; 713 %add = add nsw <2 x i32> %x, <i32 42, i32 42> 714 %cmp = icmp ne <2 x i32> %add, <i32 -2147483607, i32 -2147483607> 715 ret <2 x i1> %cmp 716} 717 718; PR34838 - https://bugs.llvm.org/show_bug.cgi?id=34838 719; The shift is known to create poison, so we can simplify the cmp. 720 721define i1 @ne_shl_by_constant_produces_poison(i8 %x) { 722; CHECK-LABEL: @ne_shl_by_constant_produces_poison( 723; CHECK-NEXT: ret i1 true 724; 725 %zx = zext i8 %x to i16 ; zx = 0x00xx 726 %xor = xor i16 %zx, 32767 ; xor = 0x7fyy 727 %sub = sub nsw i16 %zx, %xor ; sub = 0x80zz (the top bit is known one) 728 %poison = shl nsw i16 %sub, 2 ; oops! this shl can't be nsw; that's POISON 729 %cmp = icmp ne i16 %poison, 1 730 ret i1 %cmp 731} 732 733define i1 @eq_shl_by_constant_produces_poison(i8 %x) { 734; CHECK-LABEL: @eq_shl_by_constant_produces_poison( 735; CHECK-NEXT: ret i1 false 736; 737 %clear_high_bit = and i8 %x, 127 ; 0x7f 738 %set_next_high_bits = or i8 %clear_high_bit, 112 ; 0x70 739 %poison = shl nsw i8 %set_next_high_bits, 3 740 %cmp = icmp eq i8 %poison, 15 741 ret i1 %cmp 742} 743 744; Shift-by-variable that produces poison is more complicated but still possible. 745; We guarantee that the shift will change the sign of the shifted value (and 746; therefore produce poison) by limiting its range from 1 to 3. 747 748define i1 @eq_shl_by_variable_produces_poison(i8 %x) { 749; CHECK-LABEL: @eq_shl_by_variable_produces_poison( 750; CHECK-NEXT: ret i1 false 751; 752 %clear_high_bit = and i8 %x, 127 ; 0x7f 753 %set_next_high_bits = or i8 %clear_high_bit, 112 ; 0x70 754 %notundef_shiftamt = and i8 %x, 3 755 %nonzero_shiftamt = or i8 %notundef_shiftamt, 1 756 %poison = shl nsw i8 %set_next_high_bits, %nonzero_shiftamt 757 %cmp = icmp eq i8 %poison, 15 758 ret i1 %cmp 759} 760 761