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 <2 x i1> @tautological_ule_vec_partial_undef(<2 x i8> %x) { 23; CHECK-LABEL: @tautological_ule_vec_partial_undef( 24; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 25; 26 %cmp = icmp ule <2 x i8> %x, <i8 255, i8 undef> 27 ret <2 x i1> %cmp 28} 29 30define i1 @tautological_ugt(i8 %x) { 31; CHECK-LABEL: @tautological_ugt( 32; CHECK-NEXT: ret i1 false 33; 34 %cmp = icmp ugt i8 %x, 255 35 ret i1 %cmp 36} 37 38define <2 x i1> @tautological_ugt_vec(<2 x i8> %x) { 39; CHECK-LABEL: @tautological_ugt_vec( 40; CHECK-NEXT: ret <2 x i1> zeroinitializer 41; 42 %cmp = icmp ugt <2 x i8> %x, <i8 255, i8 255> 43 ret <2 x i1> %cmp 44} 45 46define <2 x i1> @tautological_ugt_vec_partial_undef(<2 x i8> %x) { 47; CHECK-LABEL: @tautological_ugt_vec_partial_undef( 48; CHECK-NEXT: ret <2 x i1> zeroinitializer 49; 50 %cmp = icmp ugt <2 x i8> %x, <i8 undef, i8 255> 51 ret <2 x i1> %cmp 52} 53 54; 'urem x, C2' produces [0, C2) 55define i1 @urem3(i32 %X) { 56; CHECK-LABEL: @urem3( 57; CHECK-NEXT: ret i1 true 58; 59 %A = urem i32 %X, 10 60 %B = icmp ult i32 %A, 15 61 ret i1 %B 62} 63 64define <2 x i1> @urem3_vec(<2 x i32> %X) { 65; CHECK-LABEL: @urem3_vec( 66; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 67; 68 %A = urem <2 x i32> %X, <i32 10, i32 10> 69 %B = icmp ult <2 x i32> %A, <i32 15, i32 15> 70 ret <2 x i1> %B 71} 72 73define <2 x i1> @urem3_vec_partial_undef(<2 x i32> %X) { 74; CHECK-LABEL: @urem3_vec_partial_undef( 75; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 76; 77 %A = urem <2 x i32> %X, <i32 10, i32 10> 78 %B = icmp ult <2 x i32> %A, <i32 undef, i32 15> 79 ret <2 x i1> %B 80} 81 82;'srem x, C2' produces (-|C2|, |C2|) 83define i1 @srem1(i32 %X) { 84; CHECK-LABEL: @srem1( 85; CHECK-NEXT: ret i1 false 86; 87 %A = srem i32 %X, -5 88 %B = icmp sgt i32 %A, 5 89 ret i1 %B 90} 91 92define <2 x i1> @srem1_vec(<2 x i32> %X) { 93; CHECK-LABEL: @srem1_vec( 94; CHECK-NEXT: ret <2 x i1> zeroinitializer 95; 96 %A = srem <2 x i32> %X, <i32 -5, i32 -5> 97 %B = icmp sgt <2 x i32> %A, <i32 5, i32 5> 98 ret <2 x i1> %B 99} 100 101define <2 x i1> @srem1_vec_partial_undef(<2 x i32> %X) { 102; CHECK-LABEL: @srem1_vec_partial_undef( 103; CHECK-NEXT: ret <2 x i1> zeroinitializer 104; 105 %A = srem <2 x i32> %X, <i32 -5, i32 -5> 106 %B = icmp sgt <2 x i32> %A, <i32 5, i32 undef> 107 ret <2 x i1> %B 108} 109 110;'udiv C2, x' produces [0, C2] 111define i1 @udiv5(i32 %X) { 112; CHECK-LABEL: @udiv5( 113; CHECK-NEXT: ret i1 false 114; 115 %A = udiv i32 123, %X 116 %C = icmp ugt i32 %A, 124 117 ret i1 %C 118} 119 120define <2 x i1> @udiv5_vec(<2 x i32> %X) { 121; CHECK-LABEL: @udiv5_vec( 122; CHECK-NEXT: ret <2 x i1> zeroinitializer 123; 124 %A = udiv <2 x i32> <i32 123, i32 123>, %X 125 %C = icmp ugt <2 x i32> %A, <i32 124, i32 124> 126 ret <2 x i1> %C 127} 128 129; 'udiv x, C2' produces [0, UINT_MAX / C2] 130define i1 @udiv1(i32 %X) { 131; CHECK-LABEL: @udiv1( 132; CHECK-NEXT: ret i1 true 133; 134 %A = udiv i32 %X, 1000000 135 %B = icmp ult i32 %A, 5000 136 ret i1 %B 137} 138 139define <2 x i1> @udiv1_vec(<2 x i32> %X) { 140; CHECK-LABEL: @udiv1_vec( 141; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 142; 143 %A = udiv <2 x i32> %X, <i32 1000000, i32 1000000> 144 %B = icmp ult <2 x i32> %A, <i32 5000, i32 5000> 145 ret <2 x i1> %B 146} 147 148; 'sdiv C2, x' produces [-|C2|, |C2|] 149define i1 @compare_dividend(i32 %a) { 150; CHECK-LABEL: @compare_dividend( 151; CHECK-NEXT: ret i1 false 152; 153 %div = sdiv i32 2, %a 154 %cmp = icmp eq i32 %div, 3 155 ret i1 %cmp 156} 157 158define <2 x i1> @compare_dividend_vec(<2 x i32> %a) { 159; CHECK-LABEL: @compare_dividend_vec( 160; CHECK-NEXT: ret <2 x i1> zeroinitializer 161; 162 %div = sdiv <2 x i32> <i32 2, i32 2>, %a 163 %cmp = icmp eq <2 x i32> %div, <i32 3, i32 3> 164 ret <2 x i1> %cmp 165} 166 167; 'sdiv x, C2' produces [INT_MIN / C2, INT_MAX / C2] 168; where C2 != -1 and C2 != 0 and C2 != 1 169define i1 @sdiv1(i32 %X) { 170; CHECK-LABEL: @sdiv1( 171; CHECK-NEXT: ret i1 true 172; 173 %A = sdiv i32 %X, 1000000 174 %B = icmp slt i32 %A, 3000 175 ret i1 %B 176} 177 178define <2 x i1> @sdiv1_vec(<2 x i32> %X) { 179; CHECK-LABEL: @sdiv1_vec( 180; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 181; 182 %A = sdiv <2 x i32> %X, <i32 1000000, i32 1000000> 183 %B = icmp slt <2 x i32> %A, <i32 3000, i32 3000> 184 ret <2 x i1> %B 185} 186 187; 'shl nuw C2, x' produces [C2, C2 << CLZ(C2)] 188define i1 @shl5(i32 %X) { 189; CHECK-LABEL: @shl5( 190; CHECK-NEXT: ret i1 true 191; 192 %sub = shl nuw i32 4, %X 193 %cmp = icmp ugt i32 %sub, 3 194 ret i1 %cmp 195} 196 197define <2 x i1> @shl5_vec(<2 x i32> %X) { 198; CHECK-LABEL: @shl5_vec( 199; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 200; 201 %sub = shl nuw <2 x i32> <i32 4, i32 4>, %X 202 %cmp = icmp ugt <2 x i32> %sub, <i32 3, i32 3> 203 ret <2 x i1> %cmp 204} 205 206define <2 x i1> @shl5_vec_partial_undef(<2 x i32> %X) { 207; CHECK-LABEL: @shl5_vec_partial_undef( 208; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 209; 210 %sub = shl nuw <2 x i32> <i32 4, i32 4>, %X 211 %cmp = icmp ugt <2 x i32> %sub, <i32 undef, i32 3> 212 ret <2 x i1> %cmp 213} 214 215; 'shl nsw C2, x' produces [C2 << CLO(C2)-1, C2] 216define i1 @shl2(i32 %X) { 217; CHECK-LABEL: @shl2( 218; CHECK-NEXT: ret i1 false 219; 220 %sub = shl nsw i32 -1, %X 221 %cmp = icmp eq i32 %sub, 31 222 ret i1 %cmp 223} 224 225define <2 x i1> @shl2_vec(<2 x i32> %X) { 226; CHECK-LABEL: @shl2_vec( 227; CHECK-NEXT: ret <2 x i1> zeroinitializer 228; 229 %sub = shl nsw <2 x i32> <i32 -1, i32 -1>, %X 230 %cmp = icmp eq <2 x i32> %sub, <i32 31, i32 31> 231 ret <2 x i1> %cmp 232} 233 234; 'shl nsw C2, x' produces [C2 << CLO(C2)-1, C2] 235define i1 @shl4(i32 %X) { 236; CHECK-LABEL: @shl4( 237; CHECK-NEXT: ret i1 true 238; 239 %sub = shl nsw i32 -1, %X 240 %cmp = icmp sle i32 %sub, -1 241 ret i1 %cmp 242} 243 244define <2 x i1> @shl4_vec(<2 x i32> %X) { 245; CHECK-LABEL: @shl4_vec( 246; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 247; 248 %sub = shl nsw <2 x i32> <i32 -1, i32 -1>, %X 249 %cmp = icmp sle <2 x i32> %sub, <i32 -1, i32 -1> 250 ret <2 x i1> %cmp 251} 252 253; 'shl nsw C2, x' produces [C2, C2 << CLZ(C2)-1] 254define i1 @icmp_shl_nsw_1(i64 %a) { 255; CHECK-LABEL: @icmp_shl_nsw_1( 256; CHECK-NEXT: ret i1 true 257; 258 %shl = shl nsw i64 1, %a 259 %cmp = icmp sge i64 %shl, 0 260 ret i1 %cmp 261} 262 263define <2 x i1> @icmp_shl_nsw_1_vec(<2 x i64> %a) { 264; CHECK-LABEL: @icmp_shl_nsw_1_vec( 265; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 266; 267 %shl = shl nsw <2 x i64> <i64 1, i64 1>, %a 268 %cmp = icmp sge <2 x i64> %shl, zeroinitializer 269 ret <2 x i1> %cmp 270} 271 272; 'shl nsw C2, x' produces [C2 << CLO(C2)-1, C2] 273define i1 @icmp_shl_nsw_neg1(i64 %a) { 274; CHECK-LABEL: @icmp_shl_nsw_neg1( 275; CHECK-NEXT: ret i1 false 276; 277 %shl = shl nsw i64 -1, %a 278 %cmp = icmp sge i64 %shl, 3 279 ret i1 %cmp 280} 281 282define <2 x i1> @icmp_shl_nsw_neg1_vec(<2 x i64> %a) { 283; CHECK-LABEL: @icmp_shl_nsw_neg1_vec( 284; CHECK-NEXT: ret <2 x i1> zeroinitializer 285; 286 %shl = shl nsw <2 x i64> <i64 -1, i64 -1>, %a 287 %cmp = icmp sge <2 x i64> %shl, <i64 3, i64 3> 288 ret <2 x i1> %cmp 289} 290 291; 'lshr x, C2' produces [0, UINT_MAX >> C2] 292define i1 @lshr2(i32 %x) { 293; CHECK-LABEL: @lshr2( 294; CHECK-NEXT: ret i1 false 295; 296 %s = lshr i32 %x, 30 297 %c = icmp ugt i32 %s, 8 298 ret i1 %c 299} 300 301define <2 x i1> @lshr2_vec(<2 x i32> %x) { 302; CHECK-LABEL: @lshr2_vec( 303; CHECK-NEXT: ret <2 x i1> zeroinitializer 304; 305 %s = lshr <2 x i32> %x, <i32 30, i32 30> 306 %c = icmp ugt <2 x i32> %s, <i32 8, i32 8> 307 ret <2 x i1> %c 308} 309 310; 'lshr C2, x' produces [C2 >> (Width-1), C2] 311define i1 @exact_lshr_ugt_false(i32 %a) { 312; CHECK-LABEL: @exact_lshr_ugt_false( 313; CHECK-NEXT: ret i1 false 314; 315 %shr = lshr exact i32 30, %a 316 %cmp = icmp ult i32 %shr, 15 317 ret i1 %cmp 318} 319 320define <2 x i1> @exact_lshr_ugt_false_vec(<2 x i32> %a) { 321; CHECK-LABEL: @exact_lshr_ugt_false_vec( 322; CHECK-NEXT: ret <2 x i1> zeroinitializer 323; 324 %shr = lshr exact <2 x i32> <i32 30, i32 30>, %a 325 %cmp = icmp ult <2 x i32> %shr, <i32 15, i32 15> 326 ret <2 x i1> %cmp 327} 328 329; 'lshr C2, x' produces [C2 >> (Width-1), C2] 330define i1 @lshr_sgt_false(i32 %a) { 331; CHECK-LABEL: @lshr_sgt_false( 332; CHECK-NEXT: ret i1 false 333; 334 %shr = lshr i32 1, %a 335 %cmp = icmp sgt i32 %shr, 1 336 ret i1 %cmp 337} 338 339define <2 x i1> @lshr_sgt_false_vec(<2 x i32> %a) { 340; CHECK-LABEL: @lshr_sgt_false_vec( 341; CHECK-NEXT: ret <2 x i1> zeroinitializer 342; 343 %shr = lshr <2 x i32> <i32 1, i32 1>, %a 344 %cmp = icmp sgt <2 x i32> %shr, <i32 1, i32 1> 345 ret <2 x i1> %cmp 346} 347 348; 'ashr x, C2' produces [INT_MIN >> C2, INT_MAX >> C2] 349define i1 @ashr2(i32 %x) { 350; CHECK-LABEL: @ashr2( 351; CHECK-NEXT: ret i1 false 352; 353 %s = ashr i32 %x, 30 354 %c = icmp slt i32 %s, -5 355 ret i1 %c 356} 357 358define <2 x i1> @ashr2_vec(<2 x i32> %x) { 359; CHECK-LABEL: @ashr2_vec( 360; CHECK-NEXT: ret <2 x i1> zeroinitializer 361; 362 %s = ashr <2 x i32> %x, <i32 30, i32 30> 363 %c = icmp slt <2 x i32> %s, <i32 -5, i32 -5> 364 ret <2 x i1> %c 365} 366 367; 'ashr C2, x' produces [C2, C2 >> (Width-1)] 368define i1 @ashr_sgt_false(i32 %a) { 369; CHECK-LABEL: @ashr_sgt_false( 370; CHECK-NEXT: ret i1 false 371; 372 %shr = ashr i32 -30, %a 373 %cmp = icmp sgt i32 %shr, -1 374 ret i1 %cmp 375} 376 377define <2 x i1> @ashr_sgt_false_vec(<2 x i32> %a) { 378; CHECK-LABEL: @ashr_sgt_false_vec( 379; CHECK-NEXT: ret <2 x i1> zeroinitializer 380; 381 %shr = ashr <2 x i32> <i32 -30, i32 -30>, %a 382 %cmp = icmp sgt <2 x i32> %shr, <i32 -1, i32 -1> 383 ret <2 x i1> %cmp 384} 385 386; 'ashr C2, x' produces [C2, C2 >> (Width-1)] 387define i1 @exact_ashr_sgt_false(i32 %a) { 388; CHECK-LABEL: @exact_ashr_sgt_false( 389; CHECK-NEXT: ret i1 false 390; 391 %shr = ashr exact i32 -30, %a 392 %cmp = icmp sgt i32 %shr, -15 393 ret i1 %cmp 394} 395 396define <2 x i1> @exact_ashr_sgt_false_vec(<2 x i32> %a) { 397; CHECK-LABEL: @exact_ashr_sgt_false_vec( 398; CHECK-NEXT: ret <2 x i1> zeroinitializer 399; 400 %shr = ashr exact <2 x i32> <i32 -30, i32 -30>, %a 401 %cmp = icmp sgt <2 x i32> %shr, <i32 -15, i32 -15> 402 ret <2 x i1> %cmp 403} 404 405; 'or x, C2' produces [C2, UINT_MAX] 406define i1 @or1(i32 %X) { 407; CHECK-LABEL: @or1( 408; CHECK-NEXT: ret i1 false 409; 410 %A = or i32 %X, 62 411 %B = icmp ult i32 %A, 50 412 ret i1 %B 413} 414 415define <2 x i1> @or1_vec(<2 x i32> %X) { 416; CHECK-LABEL: @or1_vec( 417; CHECK-NEXT: ret <2 x i1> zeroinitializer 418; 419 %A = or <2 x i32> %X, <i32 62, i32 62> 420 %B = icmp ult <2 x i32> %A, <i32 50, i32 50> 421 ret <2 x i1> %B 422} 423 424define <2 x i1> @or1_vec_partial_undef(<2 x i32> %X) { 425; CHECK-LABEL: @or1_vec_partial_undef( 426; CHECK-NEXT: ret <2 x i1> zeroinitializer 427; 428 %A = or <2 x i32> %X, <i32 62, i32 62> 429 %B = icmp ult <2 x i32> %A, <i32 undef, i32 50> 430 ret <2 x i1> %B 431} 432 433; Single bit OR. 434define i1 @or2_true(i8 %x) { 435; CHECK-LABEL: @or2_true( 436; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], 64 437; CHECK-NEXT: [[Z:%.*]] = icmp sge i8 [[Y]], -64 438; CHECK-NEXT: ret i1 [[Z]] 439; 440 %y = or i8 %x, 64 441 %z = icmp sge i8 %y, -64 442 ret i1 %z 443} 444 445define i1 @or2_unknown(i8 %x) { 446; CHECK-LABEL: @or2_unknown( 447; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], 64 448; CHECK-NEXT: [[Z:%.*]] = icmp sgt i8 [[Y]], -64 449; CHECK-NEXT: ret i1 [[Z]] 450; 451 %y = or i8 %x, 64 452 %z = icmp sgt i8 %y, -64 453 ret i1 %z 454} 455 456; Multi bit OR. 457; 78 = 0b01001110; -50 = 0b11001110 458define i1 @or3_true(i8 %x) { 459; CHECK-LABEL: @or3_true( 460; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], 78 461; CHECK-NEXT: [[Z:%.*]] = icmp sge i8 [[Y]], -50 462; CHECK-NEXT: ret i1 [[Z]] 463; 464 %y = or i8 %x, 78 465 %z = icmp sge i8 %y, -50 466 ret i1 %z 467} 468 469define i1 @or3_unknown(i8 %x) { 470; CHECK-LABEL: @or3_unknown( 471; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], 78 472; CHECK-NEXT: [[Z:%.*]] = icmp sgt i8 [[Y]], -50 473; CHECK-NEXT: ret i1 [[Z]] 474; 475 %y = or i8 %x, 78 476 %z = icmp sgt i8 %y, -50 477 ret i1 %z 478} 479 480; OR with sign bit. 481define i1 @or4_true(i8 %x) { 482; CHECK-LABEL: @or4_true( 483; CHECK-NEXT: ret i1 true 484; 485 %y = or i8 %x, -64 486 %z = icmp sge i8 %y, -64 487 ret i1 %z 488} 489 490define i1 @or4_unknown(i8 %x) { 491; CHECK-LABEL: @or4_unknown( 492; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], -64 493; CHECK-NEXT: [[Z:%.*]] = icmp sgt i8 [[Y]], -64 494; CHECK-NEXT: ret i1 [[Z]] 495; 496 %y = or i8 %x, -64 497 %z = icmp sgt i8 %y, -64 498 ret i1 %z 499} 500 501; If sign bit is set, signed & unsigned ranges are the same. 502define i1 @or5_true(i8 %x) { 503; CHECK-LABEL: @or5_true( 504; CHECK-NEXT: ret i1 true 505; 506 %y = or i8 %x, -64 507 %z = icmp uge i8 %y, -64 508 ret i1 %z 509} 510 511define i1 @or5_unknown(i8 %x) { 512; CHECK-LABEL: @or5_unknown( 513; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], -64 514; CHECK-NEXT: [[Z:%.*]] = icmp ugt i8 [[Y]], -64 515; CHECK-NEXT: ret i1 [[Z]] 516; 517 %y = or i8 %x, -64 518 %z = icmp ugt i8 %y, -64 519 ret i1 %z 520} 521 522; 'and x, C2' produces [0, C2] 523define i1 @and1(i32 %X) { 524; CHECK-LABEL: @and1( 525; CHECK-NEXT: ret i1 false 526; 527 %A = and i32 %X, 62 528 %B = icmp ugt i32 %A, 70 529 ret i1 %B 530} 531 532define <2 x i1> @and1_vec(<2 x i32> %X) { 533; CHECK-LABEL: @and1_vec( 534; CHECK-NEXT: ret <2 x i1> zeroinitializer 535; 536 %A = and <2 x i32> %X, <i32 62, i32 62> 537 %B = icmp ugt <2 x i32> %A, <i32 70, i32 70> 538 ret <2 x i1> %B 539} 540 541; If the sign bit is not set, signed and unsigned ranges are the same. 542define i1 @and2(i32 %X) { 543; CHECK-LABEL: @and2( 544; CHECK-NEXT: ret i1 false 545; 546 %A = and i32 %X, 62 547 %B = icmp sgt i32 %A, 70 548 ret i1 %B 549} 550 551; -75 = 0b10110101, 53 = 0b00110101 552define i1 @and3_true1(i8 %x) { 553; CHECK-LABEL: @and3_true1( 554; CHECK-NEXT: [[Y:%.*]] = and i8 [[X:%.*]], -75 555; CHECK-NEXT: [[Z:%.*]] = icmp sge i8 [[Y]], -75 556; CHECK-NEXT: ret i1 [[Z]] 557; 558 %y = and i8 %x, -75 559 %z = icmp sge i8 %y, -75 560 ret i1 %z 561} 562 563define i1 @and3_unknown1(i8 %x) { 564; CHECK-LABEL: @and3_unknown1( 565; CHECK-NEXT: [[Y:%.*]] = and i8 [[X:%.*]], -75 566; CHECK-NEXT: [[Z:%.*]] = icmp sgt i8 [[Y]], -75 567; CHECK-NEXT: ret i1 [[Z]] 568; 569 %y = and i8 %x, -75 570 %z = icmp sgt i8 %y, -75 571 ret i1 %z 572} 573 574define i1 @and3_true2(i8 %x) { 575; CHECK-LABEL: @and3_true2( 576; CHECK-NEXT: [[Y:%.*]] = and i8 [[X:%.*]], -75 577; CHECK-NEXT: [[Z:%.*]] = icmp sle i8 [[Y]], 53 578; CHECK-NEXT: ret i1 [[Z]] 579; 580 %y = and i8 %x, -75 581 %z = icmp sle i8 %y, 53 582 ret i1 %z 583} 584 585define i1 @and3_unknown2(i8 %x) { 586; CHECK-LABEL: @and3_unknown2( 587; CHECK-NEXT: [[Y:%.*]] = and i8 [[X:%.*]], -75 588; CHECK-NEXT: [[Z:%.*]] = icmp slt i8 [[Y]], 53 589; CHECK-NEXT: ret i1 [[Z]] 590; 591 %y = and i8 %x, -75 592 %z = icmp slt i8 %y, 53 593 ret i1 %z 594} 595 596; 'add nuw x, C2' produces [C2, UINT_MAX] 597define i1 @tautological9(i32 %x) { 598; CHECK-LABEL: @tautological9( 599; CHECK-NEXT: ret i1 true 600; 601 %add = add nuw i32 %x, 13 602 %cmp = icmp ne i32 %add, 12 603 ret i1 %cmp 604} 605 606define <2 x i1> @tautological9_vec(<2 x i32> %x) { 607; CHECK-LABEL: @tautological9_vec( 608; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 609; 610 %add = add nuw <2 x i32> %x, <i32 13, i32 13> 611 %cmp = icmp ne <2 x i32> %add, <i32 12, i32 12> 612 ret <2 x i1> %cmp 613} 614 615; The upper bound of the 'add' is 0. 616 617define i1 @add_nsw_neg_const1(i32 %x) { 618; CHECK-LABEL: @add_nsw_neg_const1( 619; CHECK-NEXT: ret i1 false 620; 621 %add = add nsw i32 %x, -2147483647 622 %cmp = icmp sgt i32 %add, 0 623 ret i1 %cmp 624} 625 626; InstCombine can fold this, but not InstSimplify. 627 628define i1 @add_nsw_neg_const2(i32 %x) { 629; CHECK-LABEL: @add_nsw_neg_const2( 630; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], -2147483647 631; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[ADD]], -1 632; CHECK-NEXT: ret i1 [[CMP]] 633; 634 %add = add nsw i32 %x, -2147483647 635 %cmp = icmp sgt i32 %add, -1 636 ret i1 %cmp 637} 638 639; The upper bound of the 'add' is 1 (move the constants to prove we're doing range-based analysis). 640 641define i1 @add_nsw_neg_const3(i32 %x) { 642; CHECK-LABEL: @add_nsw_neg_const3( 643; CHECK-NEXT: ret i1 false 644; 645 %add = add nsw i32 %x, -2147483646 646 %cmp = icmp sgt i32 %add, 1 647 ret i1 %cmp 648} 649 650; InstCombine can fold this, but not InstSimplify. 651 652define i1 @add_nsw_neg_const4(i32 %x) { 653; CHECK-LABEL: @add_nsw_neg_const4( 654; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], -2147483646 655; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[ADD]], 0 656; CHECK-NEXT: ret i1 [[CMP]] 657; 658 %add = add nsw i32 %x, -2147483646 659 %cmp = icmp sgt i32 %add, 0 660 ret i1 %cmp 661} 662 663; The upper bound of the 'add' is 2147483647 - 42 = 2147483605 (move the constants again and try a different cmp predicate). 664 665define i1 @add_nsw_neg_const5(i32 %x) { 666; CHECK-LABEL: @add_nsw_neg_const5( 667; CHECK-NEXT: ret i1 true 668; 669 %add = add nsw i32 %x, -42 670 %cmp = icmp ne i32 %add, 2147483606 671 ret i1 %cmp 672} 673 674; InstCombine can fold this, but not InstSimplify. 675 676define i1 @add_nsw_neg_const6(i32 %x) { 677; CHECK-LABEL: @add_nsw_neg_const6( 678; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], -42 679; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[ADD]], 2147483605 680; CHECK-NEXT: ret i1 [[CMP]] 681; 682 %add = add nsw i32 %x, -42 683 %cmp = icmp ne i32 %add, 2147483605 684 ret i1 %cmp 685} 686 687; The lower bound of the 'add' is -1. 688 689define i1 @add_nsw_pos_const1(i32 %x) { 690; CHECK-LABEL: @add_nsw_pos_const1( 691; CHECK-NEXT: ret i1 false 692; 693 %add = add nsw i32 %x, 2147483647 694 %cmp = icmp slt i32 %add, -1 695 ret i1 %cmp 696} 697 698; InstCombine can fold this, but not InstSimplify. 699 700define i1 @add_nsw_pos_const2(i32 %x) { 701; CHECK-LABEL: @add_nsw_pos_const2( 702; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], 2147483647 703; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD]], 0 704; CHECK-NEXT: ret i1 [[CMP]] 705; 706 %add = add nsw i32 %x, 2147483647 707 %cmp = icmp slt i32 %add, 0 708 ret i1 %cmp 709} 710 711; The lower bound of the 'add' is -2 (move the constants to prove we're doing range-based analysis). 712 713define i1 @add_nsw_pos_const3(i32 %x) { 714; CHECK-LABEL: @add_nsw_pos_const3( 715; CHECK-NEXT: ret i1 false 716; 717 %add = add nsw i32 %x, 2147483646 718 %cmp = icmp slt i32 %add, -2 719 ret i1 %cmp 720} 721 722; InstCombine can fold this, but not InstSimplify. 723 724define i1 @add_nsw_pos_const4(i32 %x) { 725; CHECK-LABEL: @add_nsw_pos_const4( 726; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], 2147483646 727; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD]], -1 728; CHECK-NEXT: ret i1 [[CMP]] 729; 730 %add = add nsw i32 %x, 2147483646 731 %cmp = icmp slt i32 %add, -1 732 ret i1 %cmp 733} 734 735; The lower bound of the 'add' is -2147483648 + 42 = -2147483606 (move the constants again and change the cmp predicate). 736 737define i1 @add_nsw_pos_const5(i32 %x) { 738; CHECK-LABEL: @add_nsw_pos_const5( 739; CHECK-NEXT: ret i1 false 740; 741 %add = add nsw i32 %x, 42 742 %cmp = icmp eq i32 %add, -2147483607 743 ret i1 %cmp 744} 745 746; InstCombine can fold this, but not InstSimplify. 747 748define i1 @add_nsw_pos_const6(i32 %x) { 749; CHECK-LABEL: @add_nsw_pos_const6( 750; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], 42 751; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[ADD]], -2147483606 752; CHECK-NEXT: ret i1 [[CMP]] 753; 754 %add = add nsw i32 %x, 42 755 %cmp = icmp eq i32 %add, -2147483606 756 ret i1 %cmp 757} 758 759; Verify that vectors work too. 760 761define <2 x i1> @add_nsw_pos_const5_splat_vec(<2 x i32> %x) { 762; CHECK-LABEL: @add_nsw_pos_const5_splat_vec( 763; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 764; 765 %add = add nsw <2 x i32> %x, <i32 42, i32 42> 766 %cmp = icmp ne <2 x i32> %add, <i32 -2147483607, i32 -2147483607> 767 ret <2 x i1> %cmp 768} 769 770; PR34838 - https://bugs.llvm.org/show_bug.cgi?id=34838 771; The shift is known to create poison, so we can simplify the cmp. 772 773define i1 @ne_shl_by_constant_produces_poison(i8 %x) { 774; CHECK-LABEL: @ne_shl_by_constant_produces_poison( 775; CHECK-NEXT: ret i1 true 776; 777 %zx = zext i8 %x to i16 ; zx = 0x00xx 778 %xor = xor i16 %zx, 32767 ; xor = 0x7fyy 779 %sub = sub nsw i16 %zx, %xor ; sub = 0x80zz (the top bit is known one) 780 %poison = shl nsw i16 %sub, 2 ; oops! this shl can't be nsw; that's POISON 781 %cmp = icmp ne i16 %poison, 1 782 ret i1 %cmp 783} 784 785define i1 @eq_shl_by_constant_produces_poison(i8 %x) { 786; CHECK-LABEL: @eq_shl_by_constant_produces_poison( 787; CHECK-NEXT: ret i1 false 788; 789 %clear_high_bit = and i8 %x, 127 ; 0x7f 790 %set_next_high_bits = or i8 %clear_high_bit, 112 ; 0x70 791 %poison = shl nsw i8 %set_next_high_bits, 3 792 %cmp = icmp eq i8 %poison, 15 793 ret i1 %cmp 794} 795 796; Shift-by-variable that produces poison is more complicated but still possible. 797; We guarantee that the shift will change the sign of the shifted value (and 798; therefore produce poison) by limiting its range from 1 to 3. 799 800define i1 @eq_shl_by_variable_produces_poison(i8 %x) { 801; CHECK-LABEL: @eq_shl_by_variable_produces_poison( 802; CHECK-NEXT: ret i1 false 803; 804 %clear_high_bit = and i8 %x, 127 ; 0x7f 805 %set_next_high_bits = or i8 %clear_high_bit, 112 ; 0x70 806 %notundef_shiftamt = and i8 %x, 3 807 %nonzero_shiftamt = or i8 %notundef_shiftamt, 1 808 %poison = shl nsw i8 %set_next_high_bits, %nonzero_shiftamt 809 %cmp = icmp eq i8 %poison, 15 810 ret i1 %cmp 811} 812 813; No overflow, so mul constant must be a factor of cmp constant. 814 815define i1 @mul_nuw_urem_cmp_constant1(i8 %x) { 816; CHECK-LABEL: @mul_nuw_urem_cmp_constant1( 817; CHECK-NEXT: ret i1 false 818; 819 %m = mul nuw i8 %x, 43 820 %r = icmp eq i8 %m, 42 821 ret i1 %r 822} 823 824; Invert predicate and check vector type. 825 826define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat(<2 x i8> %x) { 827; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat( 828; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 829; 830 %m = mul nuw <2 x i8> %x, <i8 45, i8 45> 831 %r = icmp ne <2 x i8> %m, <i8 15, i8 15> 832 ret <2 x i1> %r 833} 834 835; Undefs in vector constants are ok. 836 837define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat_undef1(<2 x i8> %x) { 838; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat_undef1( 839; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 840; 841 %m = mul nuw <2 x i8> %x, <i8 45, i8 45> 842 %r = icmp ne <2 x i8> %m, <i8 15, i8 undef> 843 ret <2 x i1> %r 844} 845 846; Undefs in vector constants are ok. 847 848define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat_undef2(<2 x i8> %x) { 849; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat_undef2( 850; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 851; 852 %m = mul nuw <2 x i8> %x, <i8 undef, i8 45> 853 %r = icmp ne <2 x i8> %m, <i8 15, i8 15> 854 ret <2 x i1> %r 855} 856 857; Check "negative" numbers (constants should be analyzed as unsigned). 858 859define i1 @mul_nuw_urem_cmp_constant2(i8 %x) { 860; CHECK-LABEL: @mul_nuw_urem_cmp_constant2( 861; CHECK-NEXT: ret i1 false 862; 863 %m = mul nuw i8 %x, -42 864 %r = icmp eq i8 %m, -84 865 ret i1 %r 866} 867 868; Negative test - require nuw. 869 870define i1 @mul_urem_cmp_constant1(i8 %x) { 871; CHECK-LABEL: @mul_urem_cmp_constant1( 872; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], 43 873; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], 42 874; CHECK-NEXT: ret i1 [[R]] 875; 876 %m = mul i8 %x, 43 877 %r = icmp eq i8 %m, 42 878 ret i1 %r 879} 880 881; Negative test - x could be 0. 882 883define i1 @mul_nuw_urem_cmp_constant0(i8 %x) { 884; CHECK-LABEL: @mul_nuw_urem_cmp_constant0( 885; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[X:%.*]], 23 886; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], 0 887; CHECK-NEXT: ret i1 [[R]] 888; 889 %m = mul nuw i8 %x, 23 890 %r = icmp eq i8 %m, 0 891 ret i1 %r 892} 893 894; Negative test - cmp constant is multiple of mul constant. 895 896define i1 @mul_nuw_urem_cmp_constant_is_0(i8 %x) { 897; CHECK-LABEL: @mul_nuw_urem_cmp_constant_is_0( 898; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[X:%.*]], 42 899; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], 84 900; CHECK-NEXT: ret i1 [[R]] 901; 902 %m = mul nuw i8 %x, 42 903 %r = icmp eq i8 %m, 84 904 ret i1 %r 905} 906 907; Negative test - cmp constant is multiple (treated as unsigned). 908 909define i1 @mul_nuw_urem_cmp_neg_constant_is_0(i8 %x) { 910; CHECK-LABEL: @mul_nuw_urem_cmp_neg_constant_is_0( 911; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[X:%.*]], 43 912; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], -127 913; CHECK-NEXT: ret i1 [[R]] 914; 915 %m = mul nuw i8 %x, 43 916 %r = icmp eq i8 %m, -127 917 ret i1 %r 918} 919 920; No overflow, so mul constant must be a factor of cmp constant. 921 922define i1 @mul_nsw_srem_cmp_constant1(i8 %x) { 923; CHECK-LABEL: @mul_nsw_srem_cmp_constant1( 924; CHECK-NEXT: ret i1 false 925; 926 %m = mul nsw i8 %x, 43 927 %r = icmp eq i8 %m, 45 928 ret i1 %r 929} 930 931; Invert predicate and check vector type. 932 933define <2 x i1> @mul_nsw_srem_cmp_constant_vec_splat(<2 x i8> %x) { 934; CHECK-LABEL: @mul_nsw_srem_cmp_constant_vec_splat( 935; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 936; 937 %m = mul nsw <2 x i8> %x, <i8 45, i8 45> 938 %r = icmp ne <2 x i8> %m, <i8 15, i8 15> 939 ret <2 x i1> %r 940} 941 942; Undefs in vector constants are ok. 943 944define <2 x i1> @mul_nsw_srem_cmp_constant_vec_splat_undef1(<2 x i8> %x) { 945; CHECK-LABEL: @mul_nsw_srem_cmp_constant_vec_splat_undef1( 946; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 947; 948 %m = mul nsw <2 x i8> %x, <i8 45, i8 45> 949 %r = icmp ne <2 x i8> %m, <i8 15, i8 undef> 950 ret <2 x i1> %r 951} 952 953; Undefs in vector constants are ok. 954 955define <2 x i1> @mul_nsw_srem_cmp_constant_vec_splat_undef2(<2 x i8> %x) { 956; CHECK-LABEL: @mul_nsw_srem_cmp_constant_vec_splat_undef2( 957; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 958; 959 %m = mul nsw <2 x i8> %x, <i8 undef, i8 45> 960 %r = icmp ne <2 x i8> %m, <i8 15, i8 15> 961 ret <2 x i1> %r 962} 963 964; Check negative numbers (constants should be analyzed as signed). 965 966define i1 @mul_nsw_srem_cmp_constant2(i8 %x) { 967; CHECK-LABEL: @mul_nsw_srem_cmp_constant2( 968; CHECK-NEXT: ret i1 false 969; 970 %m = mul nsw i8 %x, 43 971 %r = icmp eq i8 %m, -127 972 ret i1 %r 973} 974 975; Negative test - require nsw. 976 977define i1 @mul_srem_cmp_constant1(i8 %x) { 978; CHECK-LABEL: @mul_srem_cmp_constant1( 979; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], 43 980; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], 42 981; CHECK-NEXT: ret i1 [[R]] 982; 983 %m = mul i8 %x, 43 984 %r = icmp eq i8 %m, 42 985 ret i1 %r 986} 987 988; Negative test - x could be 0. 989 990define i1 @mul_nsw_srem_cmp_constant0(i8 %x) { 991; CHECK-LABEL: @mul_nsw_srem_cmp_constant0( 992; CHECK-NEXT: [[M:%.*]] = mul nsw i8 [[X:%.*]], 23 993; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], 0 994; CHECK-NEXT: ret i1 [[R]] 995; 996 %m = mul nsw i8 %x, 23 997 %r = icmp eq i8 %m, 0 998 ret i1 %r 999} 1000 1001; Negative test - cmp constant is multiple of mul constant. 1002 1003define i1 @mul_nsw_srem_cmp_constant_is_0(i8 %x) { 1004; CHECK-LABEL: @mul_nsw_srem_cmp_constant_is_0( 1005; CHECK-NEXT: [[M:%.*]] = mul nsw i8 [[X:%.*]], 42 1006; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], 84 1007; CHECK-NEXT: ret i1 [[R]] 1008; 1009 %m = mul nsw i8 %x, 42 1010 %r = icmp eq i8 %m, 84 1011 ret i1 %r 1012} 1013 1014; Negative test - cmp constant is multiple (treated as signed). 1015 1016define i1 @mul_nsw_srem_cmp_neg_constant_is_0(i8 %x) { 1017; CHECK-LABEL: @mul_nsw_srem_cmp_neg_constant_is_0( 1018; CHECK-NEXT: [[M:%.*]] = mul nsw i8 [[X:%.*]], -42 1019; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], -84 1020; CHECK-NEXT: ret i1 [[R]] 1021; 1022 %m = mul nsw i8 %x, -42 1023 %r = icmp eq i8 %m, -84 1024 ret i1 %r 1025} 1026 1027; Don't crash trying to div/rem-by-zero. 1028 1029define i1 @mul_nsw_by_zero(i8 %x) { 1030; CHECK-LABEL: @mul_nsw_by_zero( 1031; CHECK-NEXT: bb1: 1032; CHECK-NEXT: br label [[BB3:%.*]] 1033; CHECK: bb2: 1034; CHECK-NEXT: ret i1 false 1035; CHECK: bb3: 1036; CHECK-NEXT: br label [[BB2:%.*]] 1037; 1038bb1: 1039 br label %bb3 1040bb2: 1041 %r = icmp eq i8 %m, 45 1042 ret i1 %r 1043bb3: 1044 %m = mul nsw i8 %x, 0 1045 br label %bb2 1046} 1047 1048; Don't crash trying to div/rem-by-zero. 1049 1050define i1 @mul_nuw_by_zero(i8 %x) { 1051; CHECK-LABEL: @mul_nuw_by_zero( 1052; CHECK-NEXT: bb1: 1053; CHECK-NEXT: br label [[BB3:%.*]] 1054; CHECK: bb2: 1055; CHECK-NEXT: ret i1 false 1056; CHECK: bb3: 1057; CHECK-NEXT: br label [[BB2:%.*]] 1058; 1059bb1: 1060 br label %bb3 1061bb2: 1062 %r = icmp eq i8 %m, 45 1063 ret i1 %r 1064bb3: 1065 %m = mul nuw i8 %x, 0 1066 br label %bb2 1067} 1068