1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=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> splat (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_poison(<2 x i8> %x) { 23; CHECK-LABEL: @tautological_ule_vec_partial_poison( 24; CHECK-NEXT: ret <2 x i1> splat (i1 true) 25; 26 %cmp = icmp ule <2 x i8> %x, <i8 255, i8 poison> 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_poison(<2 x i8> %x) { 47; CHECK-LABEL: @tautological_ugt_vec_partial_poison( 48; CHECK-NEXT: ret <2 x i1> zeroinitializer 49; 50 %cmp = icmp ugt <2 x i8> %x, <i8 poison, 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> splat (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_poison(<2 x i32> %X) { 74; CHECK-LABEL: @urem3_vec_partial_poison( 75; CHECK-NEXT: ret <2 x i1> splat (i1 true) 76; 77 %A = urem <2 x i32> %X, <i32 10, i32 10> 78 %B = icmp ult <2 x i32> %A, <i32 poison, 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_poison(<2 x i32> %X) { 102; CHECK-LABEL: @srem1_vec_partial_poison( 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 poison> 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> splat (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> splat (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> splat (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_poison(<2 x i32> %X) { 207; CHECK-LABEL: @shl5_vec_partial_poison( 208; CHECK-NEXT: ret <2 x i1> splat (i1 true) 209; 210 %sub = shl nuw <2 x i32> <i32 4, i32 4>, %X 211 %cmp = icmp ugt <2 x i32> %sub, <i32 poison, 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> splat (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> splat (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_poison(<2 x i32> %X) { 425; CHECK-LABEL: @or1_vec_partial_poison( 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 poison, 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> splat (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 626define i1 @add_nsw_sgt(i8 %x) { 627; CHECK-LABEL: @add_nsw_sgt( 628; CHECK-NEXT: ret i1 true 629; 630 %add = add nsw i8 %x, 5 631 %cmp = icmp sgt i8 %add, -124 632 ret i1 %cmp 633} 634 635; nuw should not inhibit the fold. 636 637define i1 @add_nsw_nuw_sgt(i8 %x) { 638; CHECK-LABEL: @add_nsw_nuw_sgt( 639; CHECK-NEXT: ret i1 true 640; 641 %add = add nsw nuw i8 %x, 5 642 %cmp = icmp sgt i8 %add, -124 643 ret i1 %cmp 644} 645 646; negative test - minimum x is -128, so add could be -124. 647 648define i1 @add_nsw_sgt_limit(i8 %x) { 649; CHECK-LABEL: @add_nsw_sgt_limit( 650; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[X:%.*]], 4 651; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[ADD]], -124 652; CHECK-NEXT: ret i1 [[CMP]] 653; 654 %add = add nsw i8 %x, 4 655 %cmp = icmp sgt i8 %add, -124 656 ret i1 %cmp 657} 658 659define i1 @add_nsw_slt(i8 %x) { 660; CHECK-LABEL: @add_nsw_slt( 661; CHECK-NEXT: ret i1 false 662; 663 %add = add nsw i8 %x, 5 664 %cmp = icmp slt i8 %add, -123 665 ret i1 %cmp 666} 667 668; nuw should not inhibit the fold. 669 670define i1 @add_nsw_nuw_slt(i8 %x) { 671; CHECK-LABEL: @add_nsw_nuw_slt( 672; CHECK-NEXT: ret i1 false 673; 674 %add = add nsw nuw i8 %x, 5 675 %cmp = icmp slt i8 %add, -123 676 ret i1 %cmp 677} 678 679; negative test - minimum x is -128, so add could be -123. 680 681define i1 @add_nsw_slt_limit(i8 %x) { 682; CHECK-LABEL: @add_nsw_slt_limit( 683; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[X:%.*]], 5 684; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[ADD]], -122 685; CHECK-NEXT: ret i1 [[CMP]] 686; 687 %add = add nsw i8 %x, 5 688 %cmp = icmp slt i8 %add, -122 689 ret i1 %cmp 690} 691 692; InstCombine can fold this, but not InstSimplify. 693 694define i1 @add_nsw_neg_const2(i32 %x) { 695; CHECK-LABEL: @add_nsw_neg_const2( 696; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], -2147483647 697; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[ADD]], -1 698; CHECK-NEXT: ret i1 [[CMP]] 699; 700 %add = add nsw i32 %x, -2147483647 701 %cmp = icmp sgt i32 %add, -1 702 ret i1 %cmp 703} 704 705; The upper bound of the 'add' is 1 (move the constants to prove we're doing range-based analysis). 706 707define i1 @add_nsw_neg_const3(i32 %x) { 708; CHECK-LABEL: @add_nsw_neg_const3( 709; CHECK-NEXT: ret i1 false 710; 711 %add = add nsw i32 %x, -2147483646 712 %cmp = icmp sgt i32 %add, 1 713 ret i1 %cmp 714} 715 716; InstCombine can fold this, but not InstSimplify. 717 718define i1 @add_nsw_neg_const4(i32 %x) { 719; CHECK-LABEL: @add_nsw_neg_const4( 720; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], -2147483646 721; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[ADD]], 0 722; CHECK-NEXT: ret i1 [[CMP]] 723; 724 %add = add nsw i32 %x, -2147483646 725 %cmp = icmp sgt i32 %add, 0 726 ret i1 %cmp 727} 728 729; The upper bound of the 'add' is 2147483647 - 42 = 2147483605 (move the constants again and try a different cmp predicate). 730 731define i1 @add_nsw_neg_const5(i32 %x) { 732; CHECK-LABEL: @add_nsw_neg_const5( 733; CHECK-NEXT: ret i1 true 734; 735 %add = add nsw i32 %x, -42 736 %cmp = icmp ne i32 %add, 2147483606 737 ret i1 %cmp 738} 739 740; InstCombine can fold this, but not InstSimplify. 741 742define i1 @add_nsw_neg_const6(i32 %x) { 743; CHECK-LABEL: @add_nsw_neg_const6( 744; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], -42 745; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[ADD]], 2147483605 746; CHECK-NEXT: ret i1 [[CMP]] 747; 748 %add = add nsw i32 %x, -42 749 %cmp = icmp ne i32 %add, 2147483605 750 ret i1 %cmp 751} 752 753; The lower bound of the 'add' is -1. 754 755define i1 @add_nsw_pos_const1(i32 %x) { 756; CHECK-LABEL: @add_nsw_pos_const1( 757; CHECK-NEXT: ret i1 false 758; 759 %add = add nsw i32 %x, 2147483647 760 %cmp = icmp slt i32 %add, -1 761 ret i1 %cmp 762} 763 764; InstCombine can fold this, but not InstSimplify. 765 766define i1 @add_nsw_pos_const2(i32 %x) { 767; CHECK-LABEL: @add_nsw_pos_const2( 768; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], 2147483647 769; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD]], 0 770; CHECK-NEXT: ret i1 [[CMP]] 771; 772 %add = add nsw i32 %x, 2147483647 773 %cmp = icmp slt i32 %add, 0 774 ret i1 %cmp 775} 776 777; The lower bound of the 'add' is -2 (move the constants to prove we're doing range-based analysis). 778 779define i1 @add_nsw_pos_const3(i32 %x) { 780; CHECK-LABEL: @add_nsw_pos_const3( 781; CHECK-NEXT: ret i1 false 782; 783 %add = add nsw i32 %x, 2147483646 784 %cmp = icmp slt i32 %add, -2 785 ret i1 %cmp 786} 787 788; InstCombine can fold this, but not InstSimplify. 789 790define i1 @add_nsw_pos_const4(i32 %x) { 791; CHECK-LABEL: @add_nsw_pos_const4( 792; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], 2147483646 793; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ADD]], -1 794; CHECK-NEXT: ret i1 [[CMP]] 795; 796 %add = add nsw i32 %x, 2147483646 797 %cmp = icmp slt i32 %add, -1 798 ret i1 %cmp 799} 800 801; The lower bound of the 'add' is -2147483648 + 42 = -2147483606 (move the constants again and change the cmp predicate). 802 803define i1 @add_nsw_pos_const5(i32 %x) { 804; CHECK-LABEL: @add_nsw_pos_const5( 805; CHECK-NEXT: ret i1 false 806; 807 %add = add nsw i32 %x, 42 808 %cmp = icmp eq i32 %add, -2147483607 809 ret i1 %cmp 810} 811 812; InstCombine can fold this, but not InstSimplify. 813 814define i1 @add_nsw_pos_const6(i32 %x) { 815; CHECK-LABEL: @add_nsw_pos_const6( 816; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], 42 817; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[ADD]], -2147483606 818; CHECK-NEXT: ret i1 [[CMP]] 819; 820 %add = add nsw i32 %x, 42 821 %cmp = icmp eq i32 %add, -2147483606 822 ret i1 %cmp 823} 824 825; Verify that vectors work too. 826 827define <2 x i1> @add_nsw_pos_const5_splat_vec(<2 x i32> %x) { 828; CHECK-LABEL: @add_nsw_pos_const5_splat_vec( 829; CHECK-NEXT: ret <2 x i1> splat (i1 true) 830; 831 %add = add nsw <2 x i32> %x, <i32 42, i32 42> 832 %cmp = icmp ne <2 x i32> %add, <i32 -2147483607, i32 -2147483607> 833 ret <2 x i1> %cmp 834} 835 836; PR34838 - https://bugs.llvm.org/show_bug.cgi?id=34838 837; The shift is known to create poison, so we can simplify the cmp. 838 839define i1 @ne_shl_by_constant_produces_poison(i8 %x) { 840; CHECK-LABEL: @ne_shl_by_constant_produces_poison( 841; CHECK-NEXT: ret i1 poison 842; 843 %zx = zext i8 %x to i16 ; zx = 0x00xx 844 %xor = xor i16 %zx, 32767 ; xor = 0x7fyy 845 %sub = sub nsw i16 %zx, %xor ; sub = 0x80zz (the top bit is known one) 846 %poison = shl nsw i16 %sub, 2 ; oops! this shl can't be nsw; that's POISON 847 %cmp = icmp ne i16 %poison, 1 848 ret i1 %cmp 849} 850 851define i1 @eq_shl_by_constant_produces_poison(i8 %x) { 852; CHECK-LABEL: @eq_shl_by_constant_produces_poison( 853; CHECK-NEXT: ret i1 poison 854; 855 %clear_high_bit = and i8 %x, 127 ; 0x7f 856 %set_next_high_bits = or i8 %clear_high_bit, 112 ; 0x70 857 %poison = shl nsw i8 %set_next_high_bits, 3 858 %cmp = icmp eq i8 %poison, 15 859 ret i1 %cmp 860} 861 862; Shift-by-variable that produces poison is more complicated but still possible. 863; We guarantee that the shift will change the sign of the shifted value (and 864; therefore produce poison) by limiting its range from 1 to 3. 865 866define i1 @eq_shl_by_variable_produces_poison(i8 %x) { 867; CHECK-LABEL: @eq_shl_by_variable_produces_poison( 868; CHECK-NEXT: ret i1 poison 869; 870 %clear_high_bit = and i8 %x, 127 ; 0x7f 871 %set_next_high_bits = or i8 %clear_high_bit, 112 ; 0x70 872 %notundef_shiftamt = and i8 %x, 3 873 %nonzero_shiftamt = or i8 %notundef_shiftamt, 1 874 %poison = shl nsw i8 %set_next_high_bits, %nonzero_shiftamt 875 %cmp = icmp eq i8 %poison, 15 876 ret i1 %cmp 877} 878 879; No overflow, so mul constant must be a factor of cmp constant. 880 881define i1 @mul_nuw_urem_cmp_constant1(i8 %x) { 882; CHECK-LABEL: @mul_nuw_urem_cmp_constant1( 883; CHECK-NEXT: ret i1 false 884; 885 %m = mul nuw i8 %x, 43 886 %r = icmp eq i8 %m, 42 887 ret i1 %r 888} 889 890; Invert predicate and check vector type. 891 892define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat(<2 x i8> %x) { 893; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat( 894; CHECK-NEXT: ret <2 x i1> splat (i1 true) 895; 896 %m = mul nuw <2 x i8> %x, <i8 45, i8 45> 897 %r = icmp ne <2 x i8> %m, <i8 15, i8 15> 898 ret <2 x i1> %r 899} 900 901; Undefs in vector constants are ok. 902 903define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat_poison1(<2 x i8> %x) { 904; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat_poison1( 905; CHECK-NEXT: ret <2 x i1> splat (i1 true) 906; 907 %m = mul nuw <2 x i8> %x, <i8 45, i8 45> 908 %r = icmp ne <2 x i8> %m, <i8 15, i8 poison> 909 ret <2 x i1> %r 910} 911 912; Undefs in vector constants are ok. 913 914define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat_poison2(<2 x i8> %x) { 915; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat_poison2( 916; CHECK-NEXT: ret <2 x i1> splat (i1 true) 917; 918 %m = mul nuw <2 x i8> %x, <i8 poison, i8 45> 919 %r = icmp ne <2 x i8> %m, <i8 15, i8 15> 920 ret <2 x i1> %r 921} 922 923; Check "negative" numbers (constants should be analyzed as unsigned). 924 925define i1 @mul_nuw_urem_cmp_constant2(i8 %x) { 926; CHECK-LABEL: @mul_nuw_urem_cmp_constant2( 927; CHECK-NEXT: ret i1 false 928; 929 %m = mul nuw i8 %x, -42 930 %r = icmp eq i8 %m, -84 931 ret i1 %r 932} 933 934; Negative test - require nuw. 935 936define i1 @mul_urem_cmp_constant1(i8 %x) { 937; CHECK-LABEL: @mul_urem_cmp_constant1( 938; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], 43 939; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], 42 940; CHECK-NEXT: ret i1 [[R]] 941; 942 %m = mul i8 %x, 43 943 %r = icmp eq i8 %m, 42 944 ret i1 %r 945} 946 947; Negative test - x could be 0. 948 949define i1 @mul_nuw_urem_cmp_constant0(i8 %x) { 950; CHECK-LABEL: @mul_nuw_urem_cmp_constant0( 951; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[X:%.*]], 23 952; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], 0 953; CHECK-NEXT: ret i1 [[R]] 954; 955 %m = mul nuw i8 %x, 23 956 %r = icmp eq i8 %m, 0 957 ret i1 %r 958} 959 960; Negative test - cmp constant is multiple of mul constant. 961 962define i1 @mul_nuw_urem_cmp_constant_is_0(i8 %x) { 963; CHECK-LABEL: @mul_nuw_urem_cmp_constant_is_0( 964; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[X:%.*]], 42 965; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], 84 966; CHECK-NEXT: ret i1 [[R]] 967; 968 %m = mul nuw i8 %x, 42 969 %r = icmp eq i8 %m, 84 970 ret i1 %r 971} 972 973; Negative test - cmp constant is multiple (treated as unsigned). 974 975define i1 @mul_nuw_urem_cmp_neg_constant_is_0(i8 %x) { 976; CHECK-LABEL: @mul_nuw_urem_cmp_neg_constant_is_0( 977; CHECK-NEXT: [[M:%.*]] = mul nuw i8 [[X:%.*]], 43 978; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], -127 979; CHECK-NEXT: ret i1 [[R]] 980; 981 %m = mul nuw i8 %x, 43 982 %r = icmp eq i8 %m, -127 983 ret i1 %r 984} 985 986; No overflow, so mul constant must be a factor of cmp constant. 987 988define i1 @mul_nsw_srem_cmp_constant1(i8 %x) { 989; CHECK-LABEL: @mul_nsw_srem_cmp_constant1( 990; CHECK-NEXT: ret i1 false 991; 992 %m = mul nsw i8 %x, 43 993 %r = icmp eq i8 %m, 45 994 ret i1 %r 995} 996 997; Invert predicate and check vector type. 998 999define <2 x i1> @mul_nsw_srem_cmp_constant_vec_splat(<2 x i8> %x) { 1000; CHECK-LABEL: @mul_nsw_srem_cmp_constant_vec_splat( 1001; CHECK-NEXT: ret <2 x i1> splat (i1 true) 1002; 1003 %m = mul nsw <2 x i8> %x, <i8 45, i8 45> 1004 %r = icmp ne <2 x i8> %m, <i8 15, i8 15> 1005 ret <2 x i1> %r 1006} 1007 1008; Undefs in vector constants are ok. 1009 1010define <2 x i1> @mul_nsw_srem_cmp_constant_vec_splat_poison1(<2 x i8> %x) { 1011; CHECK-LABEL: @mul_nsw_srem_cmp_constant_vec_splat_poison1( 1012; CHECK-NEXT: ret <2 x i1> splat (i1 true) 1013; 1014 %m = mul nsw <2 x i8> %x, <i8 45, i8 45> 1015 %r = icmp ne <2 x i8> %m, <i8 15, i8 poison> 1016 ret <2 x i1> %r 1017} 1018 1019; Undefs in vector constants are ok. 1020 1021define <2 x i1> @mul_nsw_srem_cmp_constant_vec_splat_poison2(<2 x i8> %x) { 1022; CHECK-LABEL: @mul_nsw_srem_cmp_constant_vec_splat_poison2( 1023; CHECK-NEXT: ret <2 x i1> splat (i1 true) 1024; 1025 %m = mul nsw <2 x i8> %x, <i8 poison, i8 45> 1026 %r = icmp ne <2 x i8> %m, <i8 15, i8 15> 1027 ret <2 x i1> %r 1028} 1029 1030; Check negative numbers (constants should be analyzed as signed). 1031 1032define i1 @mul_nsw_srem_cmp_constant2(i8 %x) { 1033; CHECK-LABEL: @mul_nsw_srem_cmp_constant2( 1034; CHECK-NEXT: ret i1 false 1035; 1036 %m = mul nsw i8 %x, 43 1037 %r = icmp eq i8 %m, -127 1038 ret i1 %r 1039} 1040 1041; Negative test - require nsw. 1042 1043define i1 @mul_srem_cmp_constant1(i8 %x) { 1044; CHECK-LABEL: @mul_srem_cmp_constant1( 1045; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], 43 1046; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], 42 1047; CHECK-NEXT: ret i1 [[R]] 1048; 1049 %m = mul i8 %x, 43 1050 %r = icmp eq i8 %m, 42 1051 ret i1 %r 1052} 1053 1054; Negative test - x could be 0. 1055 1056define i1 @mul_nsw_srem_cmp_constant0(i8 %x) { 1057; CHECK-LABEL: @mul_nsw_srem_cmp_constant0( 1058; CHECK-NEXT: [[M:%.*]] = mul nsw i8 [[X:%.*]], 23 1059; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], 0 1060; CHECK-NEXT: ret i1 [[R]] 1061; 1062 %m = mul nsw i8 %x, 23 1063 %r = icmp eq i8 %m, 0 1064 ret i1 %r 1065} 1066 1067; Negative test - cmp constant is multiple of mul constant. 1068 1069define i1 @mul_nsw_srem_cmp_constant_is_0(i8 %x) { 1070; CHECK-LABEL: @mul_nsw_srem_cmp_constant_is_0( 1071; CHECK-NEXT: [[M:%.*]] = mul nsw i8 [[X:%.*]], 42 1072; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], 84 1073; CHECK-NEXT: ret i1 [[R]] 1074; 1075 %m = mul nsw i8 %x, 42 1076 %r = icmp eq i8 %m, 84 1077 ret i1 %r 1078} 1079 1080; Negative test - cmp constant is multiple (treated as signed). 1081 1082define i1 @mul_nsw_srem_cmp_neg_constant_is_0(i8 %x) { 1083; CHECK-LABEL: @mul_nsw_srem_cmp_neg_constant_is_0( 1084; CHECK-NEXT: [[M:%.*]] = mul nsw i8 [[X:%.*]], -42 1085; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], -84 1086; CHECK-NEXT: ret i1 [[R]] 1087; 1088 %m = mul nsw i8 %x, -42 1089 %r = icmp eq i8 %m, -84 1090 ret i1 %r 1091} 1092 1093; Don't crash trying to div/rem-by-zero. 1094 1095define i1 @mul_nsw_by_zero(i8 %x) { 1096; CHECK-LABEL: @mul_nsw_by_zero( 1097; CHECK-NEXT: bb1: 1098; CHECK-NEXT: br label [[BB3:%.*]] 1099; CHECK: bb2: 1100; CHECK-NEXT: ret i1 false 1101; CHECK: bb3: 1102; CHECK-NEXT: br label [[BB2:%.*]] 1103; 1104bb1: 1105 br label %bb3 1106bb2: 1107 %r = icmp eq i8 %m, 45 1108 ret i1 %r 1109bb3: 1110 %m = mul nsw i8 %x, 0 1111 br label %bb2 1112} 1113 1114; Don't crash trying to div/rem-by-zero. 1115 1116define i1 @mul_nuw_by_zero(i8 %x) { 1117; CHECK-LABEL: @mul_nuw_by_zero( 1118; CHECK-NEXT: bb1: 1119; CHECK-NEXT: br label [[BB3:%.*]] 1120; CHECK: bb2: 1121; CHECK-NEXT: ret i1 false 1122; CHECK: bb3: 1123; CHECK-NEXT: br label [[BB2:%.*]] 1124; 1125bb1: 1126 br label %bb3 1127bb2: 1128 %r = icmp eq i8 %m, 45 1129 ret i1 %r 1130bb3: 1131 %m = mul nuw i8 %x, 0 1132 br label %bb2 1133} 1134 1135 1136define <2 x i1> @heterogeneous_constvector(<2 x i8> %x) { 1137; CHECK-LABEL: @heterogeneous_constvector( 1138; CHECK-NEXT: ret <2 x i1> zeroinitializer 1139; 1140 %c = icmp ult <2 x i8> %x, <i8 undef, i8 poison> 1141 ret <2 x i1> %c 1142} 1143 1144define i1 @icmp_eq_constant_range_attr(i8 range(i8 0, 10) %i) { 1145; CHECK-LABEL: @icmp_eq_constant_range_attr( 1146; CHECK-NEXT: ret i1 false 1147; 1148 %cmp = icmp eq i8 %i, 10 1149 ret i1 %cmp 1150} 1151 1152define i1 @neg_icmp_eq_constant_range_attr(i8 range(i8 0, 11) %i) { 1153; CHECK-LABEL: @neg_icmp_eq_constant_range_attr( 1154; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I:%.*]], 10 1155; CHECK-NEXT: ret i1 [[CMP]] 1156; 1157 %cmp = icmp eq i8 %i, 10 1158 ret i1 %cmp 1159} 1160 1161declare range(i8 1, 0) i8 @returns_non_ten_range_helper() 1162declare range(i8 -1, 1) i8 @returns_contain_ten_range_helper() 1163 1164define i1 @icmp_eq_constant_range_return() { 1165; CHECK-LABEL: @icmp_eq_constant_range_return( 1166; CHECK-NEXT: [[I:%.*]] = call i8 @returns_non_ten_range_helper() 1167; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I]], 10 1168; CHECK-NEXT: ret i1 [[CMP]] 1169; 1170 %i = call i8 @returns_non_ten_range_helper() 1171 %cmp = icmp eq i8 %i, 10 1172 ret i1 %cmp 1173} 1174 1175define i1 @neg_icmp_eq_constant_range_return() { 1176; CHECK-LABEL: @neg_icmp_eq_constant_range_return( 1177; CHECK-NEXT: [[I:%.*]] = call i8 @returns_contain_ten_range_helper() 1178; CHECK-NEXT: ret i1 false 1179; 1180 %i = call i8 @returns_contain_ten_range_helper() 1181 %cmp = icmp eq i8 %i, 10 1182 ret i1 %cmp 1183} 1184 1185declare i8 @returns_i8_helper() 1186 1187define i1 @icmp_eq_constant_range_call() { 1188; CHECK-LABEL: @icmp_eq_constant_range_call( 1189; CHECK-NEXT: [[I:%.*]] = call range(i8 0, 10) i8 @returns_i8_helper() 1190; CHECK-NEXT: ret i1 false 1191; 1192 %i = call range(i8 0, 10) i8 @returns_i8_helper() 1193 %cmp = icmp eq i8 %i, 10 1194 ret i1 %cmp 1195} 1196 1197define i1 @neg_icmp_eq_constant_range_call() { 1198; CHECK-LABEL: @neg_icmp_eq_constant_range_call( 1199; CHECK-NEXT: [[I:%.*]] = call range(i8 0, 11) i8 @returns_i8_helper() 1200; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I]], 10 1201; CHECK-NEXT: ret i1 [[CMP]] 1202; 1203 %i = call range(i8 0, 11) i8 @returns_i8_helper() 1204 %cmp = icmp eq i8 %i, 10 1205 ret i1 %cmp 1206} 1207 1208define <2 x i1> @icmp_eq_constant_range_attr_vec(<2 x i8> range(i8 0, 10) %i) { 1209; CHECK-LABEL: @icmp_eq_constant_range_attr_vec( 1210; CHECK-NEXT: ret <2 x i1> zeroinitializer 1211; 1212 %cmp = icmp eq <2 x i8> %i, <i8 10, i8 10> 1213 ret <2 x i1> %cmp 1214} 1215 1216define <2 x i1> @neg_icmp_eq_constant_range_attr_vec(<2 x i8> range(i8 0, 11) %i) { 1217; CHECK-LABEL: @neg_icmp_eq_constant_range_attr_vec( 1218; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[I:%.*]], splat (i8 10) 1219; CHECK-NEXT: ret <2 x i1> [[CMP]] 1220; 1221 %cmp = icmp eq <2 x i8> %i, <i8 10, i8 10> 1222 ret <2 x i1> %cmp 1223} 1224 1225declare range(i8 0, 10) <2 x i8> @returns_non_ten_range_helper_vec() 1226declare range(i8 0, 11) <2 x i8> @returns_contain_ten_range_helper_vec() 1227 1228define <2 x i1> @icmp_eq_constant_range_return_vec() { 1229; CHECK-LABEL: @icmp_eq_constant_range_return_vec( 1230; CHECK-NEXT: [[I:%.*]] = call <2 x i8> @returns_non_ten_range_helper_vec() 1231; CHECK-NEXT: ret <2 x i1> zeroinitializer 1232; 1233 %i = call <2 x i8> @returns_non_ten_range_helper_vec() 1234 %cmp = icmp eq <2 x i8> %i, <i8 10, i8 10> 1235 ret <2 x i1> %cmp 1236} 1237 1238define <2 x i1> @neg_icmp_eq_constant_range_return_vec() { 1239; CHECK-LABEL: @neg_icmp_eq_constant_range_return_vec( 1240; CHECK-NEXT: [[I:%.*]] = call <2 x i8> @returns_contain_ten_range_helper_vec() 1241; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[I]], splat (i8 10) 1242; CHECK-NEXT: ret <2 x i1> [[CMP]] 1243; 1244 %i = call <2 x i8> @returns_contain_ten_range_helper_vec() 1245 %cmp = icmp eq <2 x i8> %i, <i8 10, i8 10> 1246 ret <2 x i1> %cmp 1247} 1248 1249declare <2 x i8> @returns_i8_helper_vec() 1250 1251define <2 x i1> @icmp_eq_constant_range_call_vec() { 1252; CHECK-LABEL: @icmp_eq_constant_range_call_vec( 1253; CHECK-NEXT: [[I:%.*]] = call range(i8 0, 10) <2 x i8> @returns_i8_helper_vec() 1254; CHECK-NEXT: ret <2 x i1> zeroinitializer 1255; 1256 %i = call range(i8 0, 10) <2 x i8> @returns_i8_helper_vec() 1257 %cmp = icmp eq <2 x i8> %i, <i8 10, i8 10> 1258 ret <2 x i1> %cmp 1259} 1260 1261define <2 x i1> @neg_icmp_eq_constant_range_call_vec() { 1262; CHECK-LABEL: @neg_icmp_eq_constant_range_call_vec( 1263; CHECK-NEXT: [[I:%.*]] = call range(i8 0, 11) <2 x i8> @returns_i8_helper_vec() 1264; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[I]], splat (i8 10) 1265; CHECK-NEXT: ret <2 x i1> [[CMP]] 1266; 1267 %i = call range(i8 0, 11) <2 x i8> @returns_i8_helper_vec() 1268 %cmp = icmp eq <2 x i8> %i, <i8 10, i8 10> 1269 ret <2 x i1> %cmp 1270} 1271