1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; This test makes sure that all icmp instructions are eliminated. 3; RUN: opt < %s -passes=instcombine -S | FileCheck %s 4 5@X = external global i32 6 7declare void @use(i1) 8 9define i1 @test1(i32 %A) { 10; CHECK-LABEL: @test1( 11; CHECK-NEXT: ret i1 false 12; 13 %B = icmp eq i32 %A, %A 14 ; Never true 15 %C = icmp eq ptr @X, null 16 %D = and i1 %B, %C 17 ret i1 %D 18} 19 20define i1 @test1_logical(i32 %A) { 21; CHECK-LABEL: @test1_logical( 22; CHECK-NEXT: ret i1 false 23; 24 %B = icmp eq i32 %A, %A 25 ; Never true 26 %C = icmp eq ptr @X, null 27 %D = select i1 %B, i1 %C, i1 false 28 ret i1 %D 29} 30 31define i1 @test2(i32 %A) { 32; CHECK-LABEL: @test2( 33; CHECK-NEXT: ret i1 true 34; 35 %B = icmp ne i32 %A, %A 36 ; Never false 37 %C = icmp ne ptr @X, null 38 %D = or i1 %B, %C 39 ret i1 %D 40} 41 42define i1 @test2_logical(i32 %A) { 43; CHECK-LABEL: @test2_logical( 44; CHECK-NEXT: ret i1 true 45; 46 %B = icmp ne i32 %A, %A 47 ; Never false 48 %C = icmp ne ptr @X, null 49 %D = select i1 %B, i1 true, i1 %C 50 ret i1 %D 51} 52 53define i1 @test3(i32 %A) { 54; CHECK-LABEL: @test3( 55; CHECK-NEXT: ret i1 false 56; 57 %B = icmp slt i32 %A, %A 58 ret i1 %B 59} 60 61 62define i1 @test4(i32 %A) { 63; CHECK-LABEL: @test4( 64; CHECK-NEXT: ret i1 false 65; 66 %B = icmp sgt i32 %A, %A 67 ret i1 %B 68} 69 70define i1 @test5(i32 %A) { 71; CHECK-LABEL: @test5( 72; CHECK-NEXT: ret i1 true 73; 74 %B = icmp sle i32 %A, %A 75 ret i1 %B 76} 77 78define i1 @test6(i32 %A) { 79; CHECK-LABEL: @test6( 80; CHECK-NEXT: ret i1 true 81; 82 %B = icmp sge i32 %A, %A 83 ret i1 %B 84} 85 86define i1 @test7(i32 %A) { 87; CHECK-LABEL: @test7( 88; CHECK-NEXT: ret i1 true 89; 90 %B = icmp uge i32 %A, 0 91 ret i1 %B 92} 93 94define i1 @test8(i32 %A) { 95; CHECK-LABEL: @test8( 96; CHECK-NEXT: ret i1 false 97; 98 %B = icmp ult i32 %A, 0 99 ret i1 %B 100} 101 102;; test operations on boolean values these should all be eliminated$a 103define i1 @test9(i1 %A) { 104; CHECK-LABEL: @test9( 105; CHECK-NEXT: ret i1 false 106; 107 %B = icmp ult i1 %A, false 108 ret i1 %B 109} 110 111define i1 @test10(i1 %A) { 112; CHECK-LABEL: @test10( 113; CHECK-NEXT: ret i1 false 114; 115 %B = icmp ugt i1 %A, true 116 ret i1 %B 117} 118 119define i1 @test11(i1 %A) { 120; CHECK-LABEL: @test11( 121; CHECK-NEXT: ret i1 true 122; 123 %B = icmp ule i1 %A, true 124 ret i1 %B 125} 126 127define i1 @test12(i1 %A) { 128; CHECK-LABEL: @test12( 129; CHECK-NEXT: ret i1 true 130; 131 %B = icmp uge i1 %A, false 132 ret i1 %B 133} 134 135define i1 @test13(i1 %A, i1 %B) { 136; CHECK-LABEL: @test13( 137; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[B:%.*]], true 138; CHECK-NEXT: [[C:%.*]] = or i1 [[A:%.*]], [[TMP1]] 139; CHECK-NEXT: ret i1 [[C]] 140; 141 %C = icmp uge i1 %A, %B 142 ret i1 %C 143} 144 145define <2 x i1> @test13vec(<2 x i1> %A, <2 x i1> %B) { 146; CHECK-LABEL: @test13vec( 147; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i1> [[B:%.*]], splat (i1 true) 148; CHECK-NEXT: [[C:%.*]] = or <2 x i1> [[A:%.*]], [[TMP1]] 149; CHECK-NEXT: ret <2 x i1> [[C]] 150; 151 %C = icmp uge <2 x i1> %A, %B 152 ret <2 x i1> %C 153} 154 155define i1 @test14(i1 %A, i1 %B) { 156; CHECK-LABEL: @test14( 157; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[A:%.*]], [[B:%.*]] 158; CHECK-NEXT: [[C:%.*]] = xor i1 [[TMP1]], true 159; CHECK-NEXT: ret i1 [[C]] 160; 161 %C = icmp eq i1 %A, %B 162 ret i1 %C 163} 164 165define <3 x i1> @test14vec(<3 x i1> %A, <3 x i1> %B) { 166; CHECK-LABEL: @test14vec( 167; CHECK-NEXT: [[TMP1:%.*]] = xor <3 x i1> [[A:%.*]], [[B:%.*]] 168; CHECK-NEXT: [[C:%.*]] = xor <3 x i1> [[TMP1]], splat (i1 true) 169; CHECK-NEXT: ret <3 x i1> [[C]] 170; 171 %C = icmp eq <3 x i1> %A, %B 172 ret <3 x i1> %C 173} 174 175define i1 @bool_eq0(i64 %a) { 176; CHECK-LABEL: @bool_eq0( 177; CHECK-NEXT: [[AND:%.*]] = icmp sgt i64 [[A:%.*]], 1 178; CHECK-NEXT: ret i1 [[AND]] 179; 180 %b = icmp sgt i64 %a, 0 181 %c = icmp eq i64 %a, 1 182 %notc = icmp eq i1 %c, false 183 %and = and i1 %b, %notc 184 ret i1 %and 185} 186 187define i1 @bool_eq0_logical(i64 %a) { 188; CHECK-LABEL: @bool_eq0_logical( 189; CHECK-NEXT: [[AND:%.*]] = icmp sgt i64 [[A:%.*]], 1 190; CHECK-NEXT: ret i1 [[AND]] 191; 192 %b = icmp sgt i64 %a, 0 193 %c = icmp eq i64 %a, 1 194 %notc = icmp eq i1 %c, false 195 %and = select i1 %b, i1 %notc, i1 false 196 ret i1 %and 197} 198 199; This is equivalent to the previous test. 200 201define i1 @xor_of_icmps(i64 %a) { 202; CHECK-LABEL: @xor_of_icmps( 203; CHECK-NEXT: [[XOR:%.*]] = icmp sgt i64 [[A:%.*]], 1 204; CHECK-NEXT: ret i1 [[XOR]] 205; 206 %b = icmp sgt i64 %a, 0 207 %c = icmp eq i64 %a, 1 208 %xor = xor i1 %c, %b 209 ret i1 %xor 210} 211 212; This is also equivalent to the previous test. 213 214define i1 @xor_of_icmps_commute(i64 %a) { 215; CHECK-LABEL: @xor_of_icmps_commute( 216; CHECK-NEXT: [[XOR:%.*]] = icmp sgt i64 [[A:%.*]], 1 217; CHECK-NEXT: ret i1 [[XOR]] 218; 219 %b = icmp sgt i64 %a, 0 220 %c = icmp eq i64 %a, 1 221 %xor = xor i1 %b, %c 222 ret i1 %xor 223} 224 225define i1 @xor_of_icmps_to_ne(i64 %a) { 226; CHECK-LABEL: @xor_of_icmps_to_ne( 227; CHECK-NEXT: [[XOR:%.*]] = icmp ne i64 [[A:%.*]], 5 228; CHECK-NEXT: ret i1 [[XOR]] 229; 230 %b = icmp sgt i64 %a, 4 231 %c = icmp slt i64 %a, 6 232 %xor = xor i1 %b, %c 233 ret i1 %xor 234} 235 236define i1 @xor_of_icmps_to_ne_commute(i64 %a) { 237; CHECK-LABEL: @xor_of_icmps_to_ne_commute( 238; CHECK-NEXT: [[XOR:%.*]] = icmp ne i64 [[A:%.*]], 5 239; CHECK-NEXT: ret i1 [[XOR]] 240; 241 %c = icmp sgt i64 %a, 4 242 %b = icmp slt i64 %a, 6 243 %xor = xor i1 %b, %c 244 ret i1 %xor 245} 246 247define i1 @xor_of_icmps_neg_to_ne(i64 %a) { 248; CHECK-LABEL: @xor_of_icmps_neg_to_ne( 249; CHECK-NEXT: [[XOR:%.*]] = icmp ne i64 [[A:%.*]], -5 250; CHECK-NEXT: ret i1 [[XOR]] 251; 252 %b = icmp sgt i64 %a, -6 253 %c = icmp slt i64 %a, -4 254 %xor = xor i1 %b, %c 255 ret i1 %xor 256} 257 258define <2 x i1> @xor_of_icmps_to_ne_vector(<2 x i64> %a) { 259; CHECK-LABEL: @xor_of_icmps_to_ne_vector( 260; CHECK-NEXT: [[XOR:%.*]] = icmp ne <2 x i64> [[A:%.*]], splat (i64 5) 261; CHECK-NEXT: ret <2 x i1> [[XOR]] 262; 263 %b = icmp sgt <2 x i64> %a, <i64 4, i64 4> 264 %c = icmp slt <2 x i64> %a, <i64 6, i64 6> 265 %xor = xor <2 x i1> %b, %c 266 ret <2 x i1> %xor 267} 268 269define i1 @xor_of_icmps_to_ne_no_common_operand(i64 %a, i64 %z) { 270; CHECK-LABEL: @xor_of_icmps_to_ne_no_common_operand( 271; CHECK-NEXT: [[B:%.*]] = icmp sgt i64 [[Z:%.*]], 4 272; CHECK-NEXT: [[C:%.*]] = icmp slt i64 [[A:%.*]], 6 273; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[B]], [[C]] 274; CHECK-NEXT: ret i1 [[XOR]] 275; 276 %b = icmp sgt i64 %z, 4 277 %c = icmp slt i64 %a, 6 278 %xor = xor i1 %b, %c 279 ret i1 %xor 280} 281 282define i1 @xor_of_icmps_to_ne_extra_use_one(i64 %a) { 283; CHECK-LABEL: @xor_of_icmps_to_ne_extra_use_one( 284; CHECK-NEXT: [[B:%.*]] = icmp sgt i64 [[A:%.*]], 4 285; CHECK-NEXT: call void @use(i1 [[B]]) 286; CHECK-NEXT: [[XOR:%.*]] = icmp ne i64 [[A]], 5 287; CHECK-NEXT: ret i1 [[XOR]] 288; 289 %b = icmp sgt i64 %a, 4 290 %c = icmp slt i64 %a, 6 291 call void @use(i1 %b) 292 %xor = xor i1 %b, %c 293 ret i1 %xor 294} 295 296define i1 @xor_of_icmps_to_ne_extra_use_two(i64 %a) { 297; CHECK-LABEL: @xor_of_icmps_to_ne_extra_use_two( 298; CHECK-NEXT: [[B:%.*]] = icmp sgt i64 [[A:%.*]], 4 299; CHECK-NEXT: [[C:%.*]] = icmp slt i64 [[A]], 6 300; CHECK-NEXT: call void @use(i1 [[B]]) 301; CHECK-NEXT: call void @use(i1 [[C]]) 302; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[B]], [[C]] 303; CHECK-NEXT: ret i1 [[XOR]] 304; 305 %b = icmp sgt i64 %a, 4 306 %c = icmp slt i64 %a, 6 307 call void @use(i1 %b) 308 call void @use(i1 %c) 309 %xor = xor i1 %b, %c 310 ret i1 %xor 311} 312 313define i1 @xor_of_icmps_to_eq(i8 %a) { 314; CHECK-LABEL: @xor_of_icmps_to_eq( 315; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A:%.*]], 127 316; CHECK-NEXT: ret i1 [[C]] 317; 318 %c = icmp sgt i8 %a, 126 319 %b = icmp slt i8 %a, 128 320 %xor = xor i1 %b, %c 321 ret i1 %xor 322} 323 324; https://bugs.llvm.org/show_bug.cgi?id=2844 325 326define i32 @PR2844(i32 %x) { 327; CHECK-LABEL: @PR2844( 328; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0 329; CHECK-NEXT: [[B:%.*]] = icmp sgt i32 [[X]], -638208502 330; CHECK-NEXT: [[OR_NOT:%.*]] = and i1 [[A]], [[B]] 331; CHECK-NEXT: [[SEL:%.*]] = zext i1 [[OR_NOT]] to i32 332; CHECK-NEXT: ret i32 [[SEL]] 333; 334 %A = icmp eq i32 %x, 0 335 %B = icmp slt i32 %x, -638208501 336 %or = or i1 %A, %B 337 %sel = select i1 %or, i32 0, i32 1 338 ret i32 %sel 339} 340 341define i32 @PR2844_logical(i32 %x) { 342; CHECK-LABEL: @PR2844_logical( 343; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0 344; CHECK-NEXT: [[B:%.*]] = icmp sgt i32 [[X]], -638208502 345; CHECK-NEXT: [[OR_NOT:%.*]] = and i1 [[A]], [[B]] 346; CHECK-NEXT: [[SEL:%.*]] = zext i1 [[OR_NOT]] to i32 347; CHECK-NEXT: ret i32 [[SEL]] 348; 349 %A = icmp eq i32 %x, 0 350 %B = icmp slt i32 %x, -638208501 351 %or = select i1 %A, i1 true, i1 %B 352 %sel = select i1 %or, i32 0, i32 1 353 ret i32 %sel 354} 355 356define i1 @test16(i32 %A) { 357; CHECK-LABEL: @test16( 358; CHECK-NEXT: ret i1 false 359; 360 %B = and i32 %A, 5 361 ; Is never true 362 %C = icmp eq i32 %B, 8 363 ret i1 %C 364} 365 366define i1 @test17(i8 %A) { 367; CHECK-LABEL: @test17( 368; CHECK-NEXT: ret i1 false 369; 370 %B = or i8 %A, 1 371 ; Always false 372 %C = icmp eq i8 %B, 2 373 ret i1 %C 374} 375 376define i1 @test18(i1 %C, i32 %a) { 377; CHECK-LABEL: @test18( 378; CHECK-NEXT: entry: 379; CHECK-NEXT: br i1 [[C:%.*]], label [[ENDIF:%.*]], label [[ELSE:%.*]] 380; CHECK: else: 381; CHECK-NEXT: br label [[ENDIF]] 382; CHECK: endif: 383; CHECK-NEXT: ret i1 true 384; 385entry: 386 br i1 %C, label %endif, label %else 387 388else: 389 br label %endif 390 391endif: 392 %b.0 = phi i32 [ 0, %entry ], [ 1, %else ] 393 %tmp.4 = icmp slt i32 %b.0, 123 394 ret i1 %tmp.4 395} 396 397define i1 @test19(i1 %A, i1 %B) { 398; CHECK-LABEL: @test19( 399; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[A:%.*]], [[B:%.*]] 400; CHECK-NEXT: [[C:%.*]] = xor i1 [[TMP1]], true 401; CHECK-NEXT: ret i1 [[C]] 402; 403 %a = zext i1 %A to i32 404 %b = zext i1 %B to i32 405 %C = icmp eq i32 %a, %b 406 ret i1 %C 407} 408 409define i32 @test20(i32 %A) { 410; CHECK-LABEL: @test20( 411; CHECK-NEXT: [[B:%.*]] = and i32 [[A:%.*]], 1 412; CHECK-NEXT: ret i32 [[B]] 413; 414 %B = and i32 %A, 1 415 %C = icmp ne i32 %B, 0 416 %D = zext i1 %C to i32 417 ret i32 %D 418} 419 420define <2 x i32> @test20vec(<2 x i32> %A) { 421; CHECK-LABEL: @test20vec( 422; CHECK-NEXT: [[D:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 1) 423; CHECK-NEXT: ret <2 x i32> [[D]] 424; 425 %B = and <2 x i32> %A, <i32 1, i32 1> 426 %C = icmp ne <2 x i32> %B, zeroinitializer 427 %D = zext <2 x i1> %C to <2 x i32> 428 ret <2 x i32> %D 429} 430 431define i32 @test21(i32 %a) { 432; CHECK-LABEL: @test21( 433; CHECK-NEXT: [[TMP_6:%.*]] = lshr i32 [[A:%.*]], 2 434; CHECK-NEXT: [[TMP_6_LOBIT:%.*]] = and i32 [[TMP_6]], 1 435; CHECK-NEXT: ret i32 [[TMP_6_LOBIT]] 436; 437 %tmp.6 = and i32 %a, 4 438 %not.tmp.7 = icmp ne i32 %tmp.6, 0 439 %retval = zext i1 %not.tmp.7 to i32 440 ret i32 %retval 441} 442 443define <2 x i32> @test21vec(<2 x i32> %a) { 444; CHECK-LABEL: @test21vec( 445; CHECK-NEXT: [[TMP_6:%.*]] = lshr <2 x i32> [[A:%.*]], splat (i32 2) 446; CHECK-NEXT: [[TMP_6_LOBIT:%.*]] = and <2 x i32> [[TMP_6]], splat (i32 1) 447; CHECK-NEXT: ret <2 x i32> [[TMP_6_LOBIT]] 448; 449 %tmp.6 = and <2 x i32> %a, <i32 4, i32 4> 450 %not.tmp.7 = icmp ne <2 x i32> %tmp.6, zeroinitializer 451 %retval = zext <2 x i1> %not.tmp.7 to <2 x i32> 452 ret <2 x i32> %retval 453} 454 455define i1 @test22(i32 %A, i32 %X) { 456; CHECK-LABEL: @test22( 457; CHECK-NEXT: ret i1 true 458; 459 %B = and i32 %A, 100663295 460 %C = icmp ult i32 %B, 268435456 461 %Y = and i32 %X, 7 462 %Z = icmp sgt i32 %Y, -1 463 %R = or i1 %C, %Z 464 ret i1 %R 465} 466 467define i1 @test22_logical(i32 %A, i32 %X) { 468; CHECK-LABEL: @test22_logical( 469; CHECK-NEXT: ret i1 true 470; 471 %B = and i32 %A, 100663295 472 %C = icmp ult i32 %B, 268435456 473 %Y = and i32 %X, 7 474 %Z = icmp sgt i32 %Y, -1 475 %R = select i1 %C, i1 true, i1 %Z 476 ret i1 %R 477} 478 479define i32 @test23(i32 %a) { 480; CHECK-LABEL: @test23( 481; CHECK-NEXT: [[TMP_1:%.*]] = and i32 [[A:%.*]], 1 482; CHECK-NEXT: [[TMP_3:%.*]] = xor i32 [[TMP_1]], 1 483; CHECK-NEXT: ret i32 [[TMP_3]] 484; 485 %tmp.1 = and i32 %a, 1 486 %tmp.2 = icmp eq i32 %tmp.1, 0 487 %tmp.3 = zext i1 %tmp.2 to i32 488 ret i32 %tmp.3 489} 490 491define <2 x i32> @test23vec(<2 x i32> %a) { 492; CHECK-LABEL: @test23vec( 493; CHECK-NEXT: [[TMP_1:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 1) 494; CHECK-NEXT: [[TMP_3:%.*]] = xor <2 x i32> [[TMP_1]], splat (i32 1) 495; CHECK-NEXT: ret <2 x i32> [[TMP_3]] 496; 497 %tmp.1 = and <2 x i32> %a, <i32 1, i32 1> 498 %tmp.2 = icmp eq <2 x i32> %tmp.1, zeroinitializer 499 %tmp.3 = zext <2 x i1> %tmp.2 to <2 x i32> 500 ret <2 x i32> %tmp.3 501} 502 503define i32 @test24(i32 %a) { 504; CHECK-LABEL: @test24( 505; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[A:%.*]], 2 506; CHECK-NEXT: [[DOTLOBIT:%.*]] = and i32 [[TMP1]], 1 507; CHECK-NEXT: [[TMP_3:%.*]] = xor i32 [[DOTLOBIT]], 1 508; CHECK-NEXT: ret i32 [[TMP_3]] 509; 510 %tmp1 = and i32 %a, 4 511 %tmp.1 = lshr i32 %tmp1, 2 512 %tmp.2 = icmp eq i32 %tmp.1, 0 513 %tmp.3 = zext i1 %tmp.2 to i32 514 ret i32 %tmp.3 515} 516 517define <2 x i32> @test24vec(<2 x i32> %a) { 518; CHECK-LABEL: @test24vec( 519; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[A:%.*]], splat (i32 2) 520; CHECK-NEXT: [[DOTLOBIT:%.*]] = and <2 x i32> [[TMP1]], splat (i32 1) 521; CHECK-NEXT: [[TMP_3:%.*]] = xor <2 x i32> [[DOTLOBIT]], splat (i32 1) 522; CHECK-NEXT: ret <2 x i32> [[TMP_3]] 523; 524 %tmp1 = and <2 x i32> %a, <i32 4, i32 4> 525 %tmp.1 = lshr <2 x i32> %tmp1, <i32 2, i32 2> 526 %tmp.2 = icmp eq <2 x i32> %tmp.1, zeroinitializer 527 %tmp.3 = zext <2 x i1> %tmp.2 to <2 x i32> 528 ret <2 x i32> %tmp.3 529} 530 531define i1 @test25(i32 %A) { 532; CHECK-LABEL: @test25( 533; CHECK-NEXT: ret i1 false 534; 535 %B = and i32 %A, 2 536 %C = icmp ugt i32 %B, 2 537 ret i1 %C 538} 539