1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4; There should be no 'and' instructions left in any test. 5 6define i32 @test1(i32 %A) { 7; CHECK-LABEL: @test1( 8; CHECK-NEXT: ret i32 0 9; 10 %B = and i32 %A, 0 11 ret i32 %B 12} 13 14define i32 @test2(i32 %A) { 15; CHECK-LABEL: @test2( 16; CHECK-NEXT: ret i32 %A 17; 18 %B = and i32 %A, -1 19 ret i32 %B 20} 21 22define i1 @test3(i1 %A) { 23; CHECK-LABEL: @test3( 24; CHECK-NEXT: ret i1 false 25; 26 %B = and i1 %A, false 27 ret i1 %B 28} 29 30define i1 @test4(i1 %A) { 31; CHECK-LABEL: @test4( 32; CHECK-NEXT: ret i1 %A 33; 34 %B = and i1 %A, true 35 ret i1 %B 36} 37 38define i32 @test5(i32 %A) { 39; CHECK-LABEL: @test5( 40; CHECK-NEXT: ret i32 %A 41; 42 %B = and i32 %A, %A 43 ret i32 %B 44} 45 46define i1 @test6(i1 %A) { 47; CHECK-LABEL: @test6( 48; CHECK-NEXT: ret i1 %A 49; 50 %B = and i1 %A, %A 51 ret i1 %B 52} 53 54; A & ~A == 0 55define i32 @test7(i32 %A) { 56; CHECK-LABEL: @test7( 57; CHECK-NEXT: ret i32 0 58; 59 %NotA = xor i32 %A, -1 60 %B = and i32 %A, %NotA 61 ret i32 %B 62} 63 64; AND associates 65define i8 @test8(i8 %A) { 66; CHECK-LABEL: @test8( 67; CHECK-NEXT: ret i8 0 68; 69 %B = and i8 %A, 3 70 %C = and i8 %B, 4 71 ret i8 %C 72} 73 74; Test of sign bit, convert to setle %A, 0 75define i1 @test9(i32 %A) { 76; CHECK-LABEL: @test9( 77; CHECK-NEXT: [[C:%.*]] = icmp slt i32 %A, 0 78; CHECK-NEXT: ret i1 [[C]] 79; 80 %B = and i32 %A, -2147483648 81 %C = icmp ne i32 %B, 0 82 ret i1 %C 83} 84 85; Test of sign bit, convert to setle %A, 0 86define i1 @test9a(i32 %A) { 87; CHECK-LABEL: @test9a( 88; CHECK-NEXT: [[C:%.*]] = icmp slt i32 %A, 0 89; CHECK-NEXT: ret i1 [[C]] 90; 91 %B = and i32 %A, -2147483648 92 %C = icmp ne i32 %B, 0 93 ret i1 %C 94} 95 96define i32 @test10(i32 %A) { 97; CHECK-LABEL: @test10( 98; CHECK-NEXT: ret i32 1 99; 100 %B = and i32 %A, 12 101 %C = xor i32 %B, 15 102 ; (X ^ C1) & C2 --> (X & C2) ^ (C1&C2) 103 %D = and i32 %C, 1 104 ret i32 %D 105} 106 107define i32 @test11(i32 %A, i32* %P) { 108; CHECK-LABEL: @test11( 109; CHECK-NEXT: [[B:%.*]] = or i32 %A, 3 110; CHECK-NEXT: [[C:%.*]] = xor i32 [[B]], 12 111; CHECK-NEXT: store i32 [[C]], i32* %P, align 4 112; CHECK-NEXT: ret i32 3 113; 114 %B = or i32 %A, 3 115 %C = xor i32 %B, 12 116 ; additional use of C 117 store i32 %C, i32* %P 118 ; %C = and uint %B, 3 --> 3 119 %D = and i32 %C, 3 120 ret i32 %D 121} 122 123define i1 @test12(i32 %A, i32 %B) { 124; CHECK-LABEL: @test12( 125; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 %A, %B 126; CHECK-NEXT: ret i1 [[TMP1]] 127; 128 %C1 = icmp ult i32 %A, %B 129 %C2 = icmp ule i32 %A, %B 130 ; (A < B) & (A <= B) === (A < B) 131 %D = and i1 %C1, %C2 132 ret i1 %D 133} 134 135define i1 @test13(i32 %A, i32 %B) { 136; CHECK-LABEL: @test13( 137; CHECK-NEXT: ret i1 false 138; 139 %C1 = icmp ult i32 %A, %B 140 %C2 = icmp ugt i32 %A, %B 141 ; (A < B) & (A > B) === false 142 %D = and i1 %C1, %C2 143 ret i1 %D 144} 145 146define i1 @test14(i8 %A) { 147; CHECK-LABEL: @test14( 148; CHECK-NEXT: [[C:%.*]] = icmp slt i8 %A, 0 149; CHECK-NEXT: ret i1 [[C]] 150; 151 %B = and i8 %A, -128 152 %C = icmp ne i8 %B, 0 153 ret i1 %C 154} 155 156define i8 @test15(i8 %A) { 157; CHECK-LABEL: @test15( 158; CHECK-NEXT: ret i8 0 159; 160 %B = lshr i8 %A, 7 161 ; Always equals zero 162 %C = and i8 %B, 2 163 ret i8 %C 164} 165 166define i8 @test16(i8 %A) { 167; CHECK-LABEL: @test16( 168; CHECK-NEXT: ret i8 0 169; 170 %B = shl i8 %A, 2 171 %C = and i8 %B, 3 172 ret i8 %C 173} 174 175define i1 @test18(i32 %A) { 176; CHECK-LABEL: @test18( 177; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 %A, 127 178; CHECK-NEXT: ret i1 [[C]] 179; 180 %B = and i32 %A, -128 181 ;; C >= 128 182 %C = icmp ne i32 %B, 0 183 ret i1 %C 184} 185 186define <2 x i1> @test18_vec(<2 x i32> %A) { 187; CHECK-LABEL: @test18_vec( 188; CHECK-NEXT: [[C:%.*]] = icmp ugt <2 x i32> %A, <i32 127, i32 127> 189; CHECK-NEXT: ret <2 x i1> [[C]] 190; 191 %B = and <2 x i32> %A, <i32 -128, i32 -128> 192 %C = icmp ne <2 x i32> %B, zeroinitializer 193 ret <2 x i1> %C 194} 195 196define i1 @test18a(i8 %A) { 197; CHECK-LABEL: @test18a( 198; CHECK-NEXT: [[C:%.*]] = icmp ult i8 %A, 2 199; CHECK-NEXT: ret i1 [[C]] 200; 201 %B = and i8 %A, -2 202 %C = icmp eq i8 %B, 0 203 ret i1 %C 204} 205 206define <2 x i1> @test18a_vec(<2 x i8> %A) { 207; CHECK-LABEL: @test18a_vec( 208; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i8> %A, <i8 2, i8 2> 209; CHECK-NEXT: ret <2 x i1> [[C]] 210; 211 %B = and <2 x i8> %A, <i8 -2, i8 -2> 212 %C = icmp eq <2 x i8> %B, zeroinitializer 213 ret <2 x i1> %C 214} 215 216define i32 @test19(i32 %A) { 217; CHECK-LABEL: @test19( 218; CHECK-NEXT: [[B:%.*]] = shl i32 %A, 3 219; CHECK-NEXT: ret i32 [[B]] 220; 221 %B = shl i32 %A, 3 222 ;; Clearing a zero bit 223 %C = and i32 %B, -2 224 ret i32 %C 225} 226 227define i8 @test20(i8 %A) { 228; CHECK-LABEL: @test20( 229; CHECK-NEXT: [[C:%.*]] = lshr i8 %A, 7 230; CHECK-NEXT: ret i8 [[C]] 231; 232 %C = lshr i8 %A, 7 233 ;; Unneeded 234 %D = and i8 %C, 1 235 ret i8 %D 236} 237 238define i1 @test23(i32 %A) { 239; CHECK-LABEL: @test23( 240; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 %A, 2 241; CHECK-NEXT: ret i1 [[TMP1]] 242; 243 %B = icmp sgt i32 %A, 1 244 %C = icmp sle i32 %A, 2 245 %D = and i1 %B, %C 246 ret i1 %D 247} 248 249; FIXME: Vectors should fold too. 250define <2 x i1> @test23vec(<2 x i32> %A) { 251; CHECK-LABEL: @test23vec( 252; CHECK-NEXT: [[B:%.*]] = icmp sgt <2 x i32> %A, <i32 1, i32 1> 253; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i32> %A, <i32 3, i32 3> 254; CHECK-NEXT: [[D:%.*]] = and <2 x i1> [[B]], [[C]] 255; CHECK-NEXT: ret <2 x i1> [[D]] 256; 257 %B = icmp sgt <2 x i32> %A, <i32 1, i32 1> 258 %C = icmp sle <2 x i32> %A, <i32 2, i32 2> 259 %D = and <2 x i1> %B, %C 260 ret <2 x i1> %D 261} 262 263define i1 @test24(i32 %A) { 264; CHECK-LABEL: @test24( 265; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 %A, 2 266; CHECK-NEXT: ret i1 [[TMP1]] 267; 268 %B = icmp sgt i32 %A, 1 269 %C = icmp ne i32 %A, 2 270 ;; A > 2 271 %D = and i1 %B, %C 272 ret i1 %D 273} 274 275define i1 @test25(i32 %A) { 276; CHECK-LABEL: @test25( 277; CHECK-NEXT: [[A_OFF:%.*]] = add i32 %A, -50 278; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A_OFF]], 50 279; CHECK-NEXT: ret i1 [[TMP1]] 280; 281 %B = icmp sge i32 %A, 50 282 %C = icmp slt i32 %A, 100 283 %D = and i1 %B, %C 284 ret i1 %D 285} 286 287; FIXME: Vectors should fold too. 288define <2 x i1> @test25vec(<2 x i32> %A) { 289; CHECK-LABEL: @test25vec( 290; CHECK-NEXT: [[B:%.*]] = icmp sgt <2 x i32> %A, <i32 49, i32 49> 291; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i32> %A, <i32 100, i32 100> 292; CHECK-NEXT: [[D:%.*]] = and <2 x i1> [[B]], [[C]] 293; CHECK-NEXT: ret <2 x i1> [[D]] 294; 295 %B = icmp sge <2 x i32> %A, <i32 50, i32 50> 296 %C = icmp slt <2 x i32> %A, <i32 100, i32 100> 297 %D = and <2 x i1> %B, %C 298 ret <2 x i1> %D 299} 300 301define i8 @test27(i8 %A) { 302; CHECK-LABEL: @test27( 303; CHECK-NEXT: ret i8 0 304; 305 %B = and i8 %A, 4 306 %C = sub i8 %B, 16 307 ;; 0xF0 308 %D = and i8 %C, -16 309 %E = add i8 %D, 16 310 ret i8 %E 311} 312 313;; This is just a zero-extending shr. 314define i32 @test28(i32 %X) { 315; CHECK-LABEL: @test28( 316; CHECK-NEXT: [[Y1:%.*]] = lshr i32 %X, 24 317; CHECK-NEXT: ret i32 [[Y1]] 318; 319 ;; Sign extend 320 %Y = ashr i32 %X, 24 321 ;; Mask out sign bits 322 %Z = and i32 %Y, 255 323 ret i32 %Z 324} 325 326define i32 @test29(i8 %X) { 327; CHECK-LABEL: @test29( 328; CHECK-NEXT: [[Y:%.*]] = zext i8 %X to i32 329; CHECK-NEXT: ret i32 [[Y]] 330; 331 %Y = zext i8 %X to i32 332 ;; Zero extend makes this unneeded. 333 %Z = and i32 %Y, 255 334 ret i32 %Z 335} 336 337define i32 @test30(i1 %X) { 338; CHECK-LABEL: @test30( 339; CHECK-NEXT: [[Y:%.*]] = zext i1 %X to i32 340; CHECK-NEXT: ret i32 [[Y]] 341; 342 %Y = zext i1 %X to i32 343 %Z = and i32 %Y, 1 344 ret i32 %Z 345} 346 347define i32 @test31(i1 %X) { 348; CHECK-LABEL: @test31( 349; CHECK-NEXT: [[Y:%.*]] = zext i1 %X to i32 350; CHECK-NEXT: [[Z:%.*]] = shl nuw nsw i32 [[Y]], 4 351; CHECK-NEXT: ret i32 [[Z]] 352; 353 %Y = zext i1 %X to i32 354 %Z = shl i32 %Y, 4 355 %A = and i32 %Z, 16 356 ret i32 %A 357} 358 359; Demanded bit analysis allows us to eliminate the add. 360 361define <2 x i32> @and_demanded_bits_splat_vec(<2 x i32> %x) { 362; CHECK-LABEL: @and_demanded_bits_splat_vec( 363; CHECK-NEXT: [[Z:%.*]] = and <2 x i32> %x, <i32 7, i32 7> 364; CHECK-NEXT: ret <2 x i32> [[Z]] 365; 366 %y = add <2 x i32> %x, <i32 8, i32 8> 367 %z = and <2 x i32> %y, <i32 7, i32 7> 368 ret <2 x i32> %z 369} 370 371; zext (x >> 8) has all zeros in the high 24-bits: 0x000000xx 372; (y | 255) has all ones in the low 8-bits: 0xyyyyyyff 373; 'and' of those is all known bits - it's just 'z'. 374 375define i32 @and_zext_demanded(i16 %x, i32 %y) { 376; CHECK-LABEL: @and_zext_demanded( 377; CHECK-NEXT: [[S:%.*]] = lshr i16 %x, 8 378; CHECK-NEXT: [[Z:%.*]] = zext i16 [[S]] to i32 379; CHECK-NEXT: ret i32 [[Z]] 380; 381 %s = lshr i16 %x, 8 382 %z = zext i16 %s to i32 383 %o = or i32 %y, 255 384 %a = and i32 %o, %z 385 ret i32 %a 386} 387 388define i32 @test32(i32 %In) { 389; CHECK-LABEL: @test32( 390; CHECK-NEXT: ret i32 0 391; 392 %Y = and i32 %In, 16 393 %Z = lshr i32 %Y, 2 394 %A = and i32 %Z, 1 395 ret i32 %A 396} 397 398;; Code corresponding to one-bit bitfield ^1. 399define i32 @test33(i32 %b) { 400; CHECK-LABEL: @test33( 401; CHECK-NEXT: [[TMP_13:%.*]] = xor i32 %b, 1 402; CHECK-NEXT: ret i32 [[TMP_13]] 403; 404 %tmp.4.mask = and i32 %b, 1 405 %tmp.10 = xor i32 %tmp.4.mask, 1 406 %tmp.12 = and i32 %b, -2 407 %tmp.13 = or i32 %tmp.12, %tmp.10 408 ret i32 %tmp.13 409} 410 411define i32 @test33b(i32 %b) { 412; CHECK-LABEL: @test33b( 413; CHECK-NEXT: [[TMP_13:%.*]] = xor i32 [[B:%.*]], 1 414; CHECK-NEXT: ret i32 [[TMP_13]] 415; 416 %tmp.4.mask = and i32 %b, 1 417 %tmp.10 = xor i32 %tmp.4.mask, 1 418 %tmp.12 = and i32 %b, -2 419 %tmp.13 = or i32 %tmp.10, %tmp.12 420 ret i32 %tmp.13 421} 422 423define <2 x i32> @test33vec(<2 x i32> %b) { 424; CHECK-LABEL: @test33vec( 425; CHECK-NEXT: [[TMP_13:%.*]] = xor <2 x i32> [[B:%.*]], <i32 1, i32 1> 426; CHECK-NEXT: ret <2 x i32> [[TMP_13]] 427; 428 %tmp.4.mask = and <2 x i32> %b, <i32 1, i32 1> 429 %tmp.10 = xor <2 x i32> %tmp.4.mask, <i32 1, i32 1> 430 %tmp.12 = and <2 x i32> %b, <i32 -2, i32 -2> 431 %tmp.13 = or <2 x i32> %tmp.12, %tmp.10 432 ret <2 x i32> %tmp.13 433} 434 435define <2 x i32> @test33vecb(<2 x i32> %b) { 436; CHECK-LABEL: @test33vecb( 437; CHECK-NEXT: [[TMP_13:%.*]] = xor <2 x i32> [[B:%.*]], <i32 1, i32 1> 438; CHECK-NEXT: ret <2 x i32> [[TMP_13]] 439; 440 %tmp.4.mask = and <2 x i32> %b, <i32 1, i32 1> 441 %tmp.10 = xor <2 x i32> %tmp.4.mask, <i32 1, i32 1> 442 %tmp.12 = and <2 x i32> %b, <i32 -2, i32 -2> 443 %tmp.13 = or <2 x i32> %tmp.10, %tmp.12 444 ret <2 x i32> %tmp.13 445} 446 447define i32 @test34(i32 %A, i32 %B) { 448; CHECK-LABEL: @test34( 449; CHECK-NEXT: ret i32 %B 450; 451 %tmp.2 = or i32 %B, %A 452 %tmp.4 = and i32 %tmp.2, %B 453 ret i32 %tmp.4 454} 455 456; FIXME: This test should only need -instsimplify (ValueTracking / computeKnownBits), not -instcombine. 457 458define <2 x i32> @PR24942(<2 x i32> %x) { 459; CHECK-LABEL: @PR24942( 460; CHECK-NEXT: ret <2 x i32> zeroinitializer 461; 462 %lshr = lshr <2 x i32> %x, <i32 31, i32 31> 463 %and = and <2 x i32> %lshr, <i32 2, i32 2> 464 ret <2 x i32> %and 465} 466 467define i64 @test35(i32 %X) { 468; CHECK-LABEL: @test35( 469; CHECK-NEXT: %[[sub:.*]] = sub i32 0, %X 470; CHECK-NEXT: %[[and:.*]] = and i32 %[[sub]], 240 471; CHECK-NEXT: %[[cst:.*]] = zext i32 %[[and]] to i64 472; CHECK-NEXT: ret i64 %[[cst]] 473 %zext = zext i32 %X to i64 474 %zsub = sub i64 0, %zext 475 %res = and i64 %zsub, 240 476 ret i64 %res 477} 478 479define i64 @test36(i32 %X) { 480; CHECK-LABEL: @test36( 481; CHECK-NEXT: %[[sub:.*]] = add i32 %X, 7 482; CHECK-NEXT: %[[and:.*]] = and i32 %[[sub]], 240 483; CHECK-NEXT: %[[cst:.*]] = zext i32 %[[and]] to i64 484; CHECK-NEXT: ret i64 %[[cst]] 485 %zext = zext i32 %X to i64 486 %zsub = add i64 %zext, 7 487 %res = and i64 %zsub, 240 488 ret i64 %res 489} 490 491define i64 @test37(i32 %X) { 492; CHECK-LABEL: @test37( 493; CHECK-NEXT: %[[sub:.*]] = mul i32 %X, 7 494; CHECK-NEXT: %[[and:.*]] = and i32 %[[sub]], 240 495; CHECK-NEXT: %[[cst:.*]] = zext i32 %[[and]] to i64 496; CHECK-NEXT: ret i64 %[[cst]] 497 %zext = zext i32 %X to i64 498 %zsub = mul i64 %zext, 7 499 %res = and i64 %zsub, 240 500 ret i64 %res 501} 502 503define i64 @test38(i32 %X) { 504; CHECK-LABEL: @test38( 505; CHECK-NEXT: %[[and:.*]] = and i32 %X, 240 506; CHECK-NEXT: %[[cst:.*]] = zext i32 %[[and]] to i64 507; CHECK-NEXT: ret i64 %[[cst]] 508 %zext = zext i32 %X to i64 509 %zsub = xor i64 %zext, 7 510 %res = and i64 %zsub, 240 511 ret i64 %res 512} 513 514define i64 @test39(i32 %X) { 515; CHECK-LABEL: @test39( 516; CHECK-NEXT: %[[and:.*]] = and i32 %X, 240 517; CHECK-NEXT: %[[cst:.*]] = zext i32 %[[and]] to i64 518; CHECK-NEXT: ret i64 %[[cst]] 519 %zext = zext i32 %X to i64 520 %zsub = or i64 %zext, 7 521 %res = and i64 %zsub, 240 522 ret i64 %res 523} 524 525define i32 @test40(i1 %C) { 526; CHECK-LABEL: @test40( 527; CHECK-NEXT: [[A:%.*]] = select i1 [[C:%.*]], i32 104, i32 10 528; CHECK-NEXT: ret i32 [[A]] 529; 530 %A = select i1 %C, i32 1000, i32 10 531 %V = and i32 %A, 123 532 ret i32 %V 533} 534 535define <2 x i32> @test40vec(i1 %C) { 536; CHECK-LABEL: @test40vec( 537; CHECK-NEXT: [[A:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 104, i32 104>, <2 x i32> <i32 10, i32 10> 538; CHECK-NEXT: ret <2 x i32> [[A]] 539; 540 %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10> 541 %V = and <2 x i32> %A, <i32 123, i32 123> 542 ret <2 x i32> %V 543} 544 545define <2 x i32> @test40vec2(i1 %C) { 546; CHECK-LABEL: @test40vec2( 547; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 104, i32 324>, <2 x i32> <i32 10, i32 12> 548; CHECK-NEXT: ret <2 x i32> [[V]] 549; 550 %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30> 551 %V = and <2 x i32> %A, <i32 123, i32 333> 552 ret <2 x i32> %V 553} 554 555define i32 @test41(i1 %which) { 556; CHECK-LABEL: @test41( 557; CHECK-NEXT: entry: 558; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 559; CHECK: delay: 560; CHECK-NEXT: br label [[FINAL]] 561; CHECK: final: 562; CHECK-NEXT: [[A:%.*]] = phi i32 [ 104, [[ENTRY:%.*]] ], [ 10, [[DELAY]] ] 563; CHECK-NEXT: ret i32 [[A]] 564; 565entry: 566 br i1 %which, label %final, label %delay 567 568delay: 569 br label %final 570 571final: 572 %A = phi i32 [ 1000, %entry ], [ 10, %delay ] 573 %value = and i32 %A, 123 574 ret i32 %value 575} 576 577define <2 x i32> @test41vec(i1 %which) { 578; CHECK-LABEL: @test41vec( 579; CHECK-NEXT: entry: 580; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 581; CHECK: delay: 582; CHECK-NEXT: br label [[FINAL]] 583; CHECK: final: 584; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 104, i32 104>, [[ENTRY:%.*]] ], [ <i32 10, i32 10>, [[DELAY]] ] 585; CHECK-NEXT: ret <2 x i32> [[A]] 586; 587entry: 588 br i1 %which, label %final, label %delay 589 590delay: 591 br label %final 592 593final: 594 %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ] 595 %value = and <2 x i32> %A, <i32 123, i32 123> 596 ret <2 x i32> %value 597} 598 599define <2 x i32> @test41vec2(i1 %which) { 600; CHECK-LABEL: @test41vec2( 601; CHECK-NEXT: entry: 602; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 603; CHECK: delay: 604; CHECK-NEXT: br label [[FINAL]] 605; CHECK: final: 606; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 104, i32 324>, [[ENTRY:%.*]] ], [ <i32 10, i32 12>, [[DELAY]] ] 607; CHECK-NEXT: ret <2 x i32> [[A]] 608; 609entry: 610 br i1 %which, label %final, label %delay 611 612delay: 613 br label %final 614 615final: 616 %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ] 617 %value = and <2 x i32> %A, <i32 123, i32 333> 618 ret <2 x i32> %value 619} 620 621define i32 @test42(i32 %a, i32 %c, i32 %d) { 622; CHECK-LABEL: @test42( 623; CHECK-NEXT: [[FORCE:%.*]] = mul i32 [[C:%.*]], [[D:%.*]] 624; CHECK-NEXT: [[AND:%.*]] = and i32 [[FORCE]], [[A:%.*]] 625; CHECK-NEXT: ret i32 [[AND]] 626; 627 %force = mul i32 %c, %d ; forces the complexity sorting 628 %or = or i32 %a, %force 629 %nota = xor i32 %a, -1 630 %xor = xor i32 %nota, %force 631 %and = and i32 %xor, %or 632 ret i32 %and 633} 634 635define i32 @test43(i32 %a, i32 %c, i32 %d) { 636; CHECK-LABEL: @test43( 637; CHECK-NEXT: [[FORCE:%.*]] = mul i32 [[C:%.*]], [[D:%.*]] 638; CHECK-NEXT: [[AND:%.*]] = and i32 [[FORCE]], [[A:%.*]] 639; CHECK-NEXT: ret i32 [[AND]] 640; 641 %force = mul i32 %c, %d ; forces the complexity sorting 642 %or = or i32 %a, %force 643 %nota = xor i32 %a, -1 644 %xor = xor i32 %nota, %force 645 %and = and i32 %or, %xor 646 ret i32 %and 647} 648 649; (~y | x) & y -> x & y 650define i32 @test44(i32 %x, i32 %y) nounwind { 651; CHECK-LABEL: @test44( 652; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 653; CHECK-NEXT: ret i32 [[A]] 654; 655 %n = xor i32 %y, -1 656 %o = or i32 %n, %x 657 %a = and i32 %o, %y 658 ret i32 %a 659} 660 661; (x | ~y) & y -> x & y 662define i32 @test45(i32 %x, i32 %y) nounwind { 663; CHECK-LABEL: @test45( 664; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 665; CHECK-NEXT: ret i32 [[A]] 666; 667 %n = xor i32 %y, -1 668 %o = or i32 %x, %n 669 %a = and i32 %o, %y 670 ret i32 %a 671} 672 673; y & (~y | x) -> y | x 674define i32 @test46(i32 %x, i32 %y) nounwind { 675; CHECK-LABEL: @test46( 676; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 677; CHECK-NEXT: ret i32 [[A]] 678; 679 %n = xor i32 %y, -1 680 %o = or i32 %n, %x 681 %a = and i32 %y, %o 682 ret i32 %a 683} 684 685; y & (x | ~y) -> y | x 686define i32 @test47(i32 %x, i32 %y) nounwind { 687; CHECK-LABEL: @test47( 688; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 689; CHECK-NEXT: ret i32 [[A]] 690; 691 %n = xor i32 %y, -1 692 %o = or i32 %x, %n 693 %a = and i32 %y, %o 694 ret i32 %a 695} 696 697; In the next 4 tests, vary the types and predicates for extra coverage. 698; (X & (Y | ~X)) -> (X & Y), where 'not' is an inverted cmp 699 700define i1 @and_orn_cmp_1(i32 %a, i32 %b, i32 %c) { 701; CHECK-LABEL: @and_orn_cmp_1( 702; CHECK-NEXT: [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]] 703; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42 704; CHECK-NEXT: [[AND:%.*]] = and i1 [[X]], [[Y]] 705; CHECK-NEXT: ret i1 [[AND]] 706; 707 %x = icmp sgt i32 %a, %b 708 %x_inv = icmp sle i32 %a, %b 709 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering 710 %or = or i1 %y, %x_inv 711 %and = and i1 %x, %or 712 ret i1 %and 713} 714 715; Commute the 'and': 716; ((Y | ~X) & X) -> (X & Y), where 'not' is an inverted cmp 717 718define <2 x i1> @and_orn_cmp_2(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) { 719; CHECK-LABEL: @and_orn_cmp_2( 720; CHECK-NEXT: [[X:%.*]] = icmp sge <2 x i32> [[A:%.*]], [[B:%.*]] 721; CHECK-NEXT: [[Y:%.*]] = icmp ugt <2 x i32> [[C:%.*]], <i32 42, i32 47> 722; CHECK-NEXT: [[AND:%.*]] = and <2 x i1> [[Y]], [[X]] 723; CHECK-NEXT: ret <2 x i1> [[AND]] 724; 725 %x = icmp sge <2 x i32> %a, %b 726 %x_inv = icmp slt <2 x i32> %a, %b 727 %y = icmp ugt <2 x i32> %c, <i32 42, i32 47> ; thwart complexity-based ordering 728 %or = or <2 x i1> %y, %x_inv 729 %and = and <2 x i1> %or, %x 730 ret <2 x i1> %and 731} 732 733; Commute the 'or': 734; (X & (~X | Y)) -> (X & Y), where 'not' is an inverted cmp 735 736define i1 @and_orn_cmp_3(i72 %a, i72 %b, i72 %c) { 737; CHECK-LABEL: @and_orn_cmp_3( 738; CHECK-NEXT: [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]] 739; CHECK-NEXT: [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42 740; CHECK-NEXT: [[AND:%.*]] = and i1 [[X]], [[Y]] 741; CHECK-NEXT: ret i1 [[AND]] 742; 743 %x = icmp ugt i72 %a, %b 744 %x_inv = icmp ule i72 %a, %b 745 %y = icmp ugt i72 %c, 42 ; thwart complexity-based ordering 746 %or = or i1 %x_inv, %y 747 %and = and i1 %x, %or 748 ret i1 %and 749} 750 751; Commute the 'and': 752; ((~X | Y) & X) -> (X & Y), where 'not' is an inverted cmp 753 754define <3 x i1> @or_andn_cmp_4(<3 x i32> %a, <3 x i32> %b, <3 x i32> %c) { 755; CHECK-LABEL: @or_andn_cmp_4( 756; CHECK-NEXT: [[X:%.*]] = icmp eq <3 x i32> [[A:%.*]], [[B:%.*]] 757; CHECK-NEXT: [[Y:%.*]] = icmp ugt <3 x i32> [[C:%.*]], <i32 42, i32 43, i32 -1> 758; CHECK-NEXT: [[AND:%.*]] = and <3 x i1> [[Y]], [[X]] 759; CHECK-NEXT: ret <3 x i1> [[AND]] 760; 761 %x = icmp eq <3 x i32> %a, %b 762 %x_inv = icmp ne <3 x i32> %a, %b 763 %y = icmp ugt <3 x i32> %c, <i32 42, i32 43, i32 -1> ; thwart complexity-based ordering 764 %or = or <3 x i1> %x_inv, %y 765 %and = and <3 x i1> %or, %x 766 ret <3 x i1> %and 767} 768 769; In the next 4 tests, vary the types and predicates for extra coverage. 770; (~X & (Y | X)) -> (~X & Y), where 'not' is an inverted cmp 771 772define i1 @andn_or_cmp_1(i37 %a, i37 %b, i37 %c) { 773; CHECK-LABEL: @andn_or_cmp_1( 774; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]] 775; CHECK-NEXT: [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42 776; CHECK-NEXT: [[AND:%.*]] = and i1 [[X_INV]], [[Y]] 777; CHECK-NEXT: ret i1 [[AND]] 778; 779 %x = icmp sgt i37 %a, %b 780 %x_inv = icmp sle i37 %a, %b 781 %y = icmp ugt i37 %c, 42 ; thwart complexity-based ordering 782 %or = or i1 %y, %x 783 %and = and i1 %x_inv, %or 784 ret i1 %and 785} 786 787; Commute the 'and': 788; ((Y | X) & ~X) -> (~X & Y), where 'not' is an inverted cmp 789 790define i1 @andn_or_cmp_2(i16 %a, i16 %b, i16 %c) { 791; CHECK-LABEL: @andn_or_cmp_2( 792; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]] 793; CHECK-NEXT: [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42 794; CHECK-NEXT: [[AND:%.*]] = and i1 [[Y]], [[X_INV]] 795; CHECK-NEXT: ret i1 [[AND]] 796; 797 %x = icmp sge i16 %a, %b 798 %x_inv = icmp slt i16 %a, %b 799 %y = icmp ugt i16 %c, 42 ; thwart complexity-based ordering 800 %or = or i1 %y, %x 801 %and = and i1 %or, %x_inv 802 ret i1 %and 803} 804 805; Commute the 'or': 806; (~X & (X | Y)) -> (~X & Y), where 'not' is an inverted cmp 807 808define <4 x i1> @andn_or_cmp_3(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 809; CHECK-LABEL: @andn_or_cmp_3( 810; CHECK-NEXT: [[X_INV:%.*]] = icmp ule <4 x i32> [[A:%.*]], [[B:%.*]] 811; CHECK-NEXT: [[Y:%.*]] = icmp ugt <4 x i32> [[C:%.*]], <i32 42, i32 0, i32 1, i32 -1> 812; CHECK-NEXT: [[AND:%.*]] = and <4 x i1> [[X_INV]], [[Y]] 813; CHECK-NEXT: ret <4 x i1> [[AND]] 814; 815 %x = icmp ugt <4 x i32> %a, %b 816 %x_inv = icmp ule <4 x i32> %a, %b 817 %y = icmp ugt <4 x i32> %c, <i32 42, i32 0, i32 1, i32 -1> ; thwart complexity-based ordering 818 %or = or <4 x i1> %x, %y 819 %and = and <4 x i1> %x_inv, %or 820 ret <4 x i1> %and 821} 822 823; Commute the 'and': 824; ((X | Y) & ~X) -> (~X & Y), where 'not' is an inverted cmp 825 826define i1 @andn_or_cmp_4(i32 %a, i32 %b, i32 %c) { 827; CHECK-LABEL: @andn_or_cmp_4( 828; CHECK-NEXT: [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]] 829; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42 830; CHECK-NEXT: [[AND:%.*]] = and i1 [[Y]], [[X_INV]] 831; CHECK-NEXT: ret i1 [[AND]] 832; 833 %x = icmp eq i32 %a, %b 834 %x_inv = icmp ne i32 %a, %b 835 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering 836 %or = or i1 %x, %y 837 %and = and i1 %or, %x_inv 838 ret i1 %and 839} 840