2211 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s --check-prefixes=CHECK,CONSTVEC3; RUN: opt < %s -passes=instcombine -S -use-constant-int-for-fixed-length-splat | FileCheck %s --check-prefixes=CHECK,CONSTSPLAT4 5target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n32:64"6declare void @use(i32)7 8; Should be eliminated9define i32 @test12(i32 %A) {10; CHECK-LABEL: @test12(11; CHECK-NEXT: [[C:%.*]] = and i32 [[A:%.*]], 812; CHECK-NEXT: ret i32 [[C]]13;14 %B = or i32 %A, 415 %C = and i32 %B, 816 ret i32 %C17}18 19define i32 @test13(i32 %A) {20; CHECK-LABEL: @test13(21; CHECK-NEXT: ret i32 822;23 %B = or i32 %A, 1224 ; Always equal to 825 %C = and i32 %B, 826 ret i32 %C27}28 29define i1 @test14(i32 %A, i32 %B) {30; CHECK-LABEL: @test14(31; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]32; CHECK-NEXT: ret i1 [[D]]33;34 %C1 = icmp ult i32 %A, %B35 %C2 = icmp ugt i32 %A, %B36 ; (A < B) | (A > B) === A != B37 %D = or i1 %C1, %C238 ret i1 %D39}40 41define i1 @test14_commuted(i32 %A, i32 %B) {42; CHECK-LABEL: @test14_commuted(43; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[B:%.*]], [[A:%.*]]44; CHECK-NEXT: ret i1 [[D]]45;46 %C1 = icmp ult i32 %A, %B47 %C2 = icmp ult i32 %B, %A48 ; (A < B) | (A > B) === A != B49 %D = or i1 %C1, %C250 ret i1 %D51}52 53define i1 @test14_logical(i32 %A, i32 %B) {54; CHECK-LABEL: @test14_logical(55; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]56; CHECK-NEXT: ret i1 [[D]]57;58 %C1 = icmp ult i32 %A, %B59 %C2 = icmp ugt i32 %A, %B60 ; (A < B) | (A > B) === A != B61 %D = select i1 %C1, i1 true, i1 %C262 ret i1 %D63}64 65define i1 @test15(i32 %A, i32 %B) {66; CHECK-LABEL: @test15(67; CHECK-NEXT: [[D:%.*]] = icmp ule i32 [[A:%.*]], [[B:%.*]]68; CHECK-NEXT: ret i1 [[D]]69;70 %C1 = icmp ult i32 %A, %B71 %C2 = icmp eq i32 %A, %B72 ; (A < B) | (A == B) === A <= B73 %D = or i1 %C1, %C274 ret i1 %D75}76 77define i1 @test15_logical(i32 %A, i32 %B) {78; CHECK-LABEL: @test15_logical(79; CHECK-NEXT: [[D:%.*]] = icmp ule i32 [[A:%.*]], [[B:%.*]]80; CHECK-NEXT: ret i1 [[D]]81;82 %C1 = icmp ult i32 %A, %B83 %C2 = icmp eq i32 %A, %B84 ; (A < B) | (A == B) === A <= B85 %D = select i1 %C1, i1 true, i1 %C286 ret i1 %D87}88 89define i32 @test16(i32 %A) {90; CHECK-LABEL: @test16(91; CHECK-NEXT: ret i32 [[A:%.*]]92;93 %B = and i32 %A, 194 ; -2 = ~195 %C = and i32 %A, -296 ; %D = and int %B, -1 == %B97 %D = or i32 %B, %C98 ret i32 %D99}100 101define i32 @test17(i32 %A) {102; CHECK-LABEL: @test17(103; CHECK-NEXT: [[D:%.*]] = and i32 [[A:%.*]], 5104; CHECK-NEXT: ret i32 [[D]]105;106 %B = and i32 %A, 1107 %C = and i32 %A, 4108 ; %D = and int %B, 5109 %D = or i32 %B, %C110 ret i32 %D111}112 113define i1 @test18(i32 %A) {114; CHECK-LABEL: @test18(115; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], -100116; CHECK-NEXT: [[D:%.*]] = icmp ult i32 [[TMP1]], -50117; CHECK-NEXT: ret i1 [[D]]118;119 %B = icmp sge i32 %A, 100120 %C = icmp slt i32 %A, 50121 %D = or i1 %B, %C122 ret i1 %D123}124 125define i1 @test18_logical(i32 %A) {126; CHECK-LABEL: @test18_logical(127; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], -100128; CHECK-NEXT: [[D:%.*]] = icmp ult i32 [[TMP1]], -50129; CHECK-NEXT: ret i1 [[D]]130;131 %B = icmp sge i32 %A, 100132 %C = icmp slt i32 %A, 50133 %D = select i1 %B, i1 true, i1 %C134 ret i1 %D135}136 137define <2 x i1> @test18vec(<2 x i32> %A) {138; CHECK-LABEL: @test18vec(139; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[A:%.*]], splat (i32 -100)140; CHECK-NEXT: [[D:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 -50)141; CHECK-NEXT: ret <2 x i1> [[D]]142;143 %B = icmp sge <2 x i32> %A, <i32 100, i32 100>144 %C = icmp slt <2 x i32> %A, <i32 50, i32 50>145 %D = or <2 x i1> %B, %C146 ret <2 x i1> %D147}148 149define i32 @test20(i32 %x) {150; CHECK-LABEL: @test20(151; CHECK-NEXT: ret i32 [[X:%.*]]152;153 %y = and i32 %x, 123154 %z = or i32 %y, %x155 ret i32 %z156}157 158; TODO: This should combine to t1 + 2.159define i32 @test21(i32 %t1) {160; CHECK-LABEL: @test21(161; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[T1:%.*]], -2162; CHECK-NEXT: [[T3:%.*]] = add i32 [[TMP1]], 2163; CHECK-NEXT: [[T5:%.*]] = and i32 [[T1]], 1164; CHECK-NEXT: [[T6:%.*]] = or disjoint i32 [[T5]], [[T3]]165; CHECK-NEXT: ret i32 [[T6]]166;167 %t1.mask1 = add i32 %t1, 2168 %t3 = and i32 %t1.mask1, -2169 %t5 = and i32 %t1, 1170 ;; add tmp.1, 2171 %t6 = or i32 %t5, %t3172 ret i32 %t6173}174 175define i32 @test22(i32 %B) {176; CHECK-LABEL: @test22(177; CHECK-NEXT: ret i32 [[B:%.*]]178;179 %ELIM41 = and i32 %B, 1180 %ELIM7 = and i32 %B, -2181 %ELIM5 = or i32 %ELIM41, %ELIM7182 ret i32 %ELIM5183}184 185define i16 @test23(i16 %A) {186; CHECK-LABEL: @test23(187; CHECK-NEXT: [[B:%.*]] = lshr i16 [[A:%.*]], 1188; CHECK-NEXT: [[D:%.*]] = xor i16 [[B]], -24575189; CHECK-NEXT: ret i16 [[D]]190;191 %B = lshr i16 %A, 1192 ;; fold or into xor193 %C = or i16 %B, -32768194 %D = xor i16 %C, 8193195 ret i16 %D196}197 198define <2 x i16> @test23vec(<2 x i16> %A) {199; CHECK-LABEL: @test23vec(200; CHECK-NEXT: [[B:%.*]] = lshr <2 x i16> [[A:%.*]], splat (i16 1)201; CHECK-NEXT: [[D:%.*]] = xor <2 x i16> [[B]], splat (i16 -24575)202; CHECK-NEXT: ret <2 x i16> [[D]]203;204 %B = lshr <2 x i16> %A, <i16 1, i16 1>205 ;; fold or into xor206 %C = or <2 x i16> %B, <i16 -32768, i16 -32768>207 %D = xor <2 x i16> %C, <i16 8193, i16 8193>208 ret <2 x i16> %D209}210 211; PR3266 & PR5276212define i1 @test25(i32 %A, i32 %B) {213; CHECK-LABEL: @test25(214; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A:%.*]], 0215; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[B:%.*]], 57216; CHECK-NEXT: [[E_NOT:%.*]] = and i1 [[C]], [[D]]217; CHECK-NEXT: ret i1 [[E_NOT]]218;219 %C = icmp eq i32 %A, 0220 %D = icmp eq i32 %B, 57221 %E = or i1 %C, %D222 %F = xor i1 %E, -1223 ret i1 %F224}225 226define i1 @test25_logical(i32 %A, i32 %B) {227; CHECK-LABEL: @test25_logical(228; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A:%.*]], 0229; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[B:%.*]], 57230; CHECK-NEXT: [[E_NOT:%.*]] = select i1 [[C]], i1 [[D]], i1 false231; CHECK-NEXT: ret i1 [[E_NOT]]232;233 %C = icmp eq i32 %A, 0234 %D = icmp eq i32 %B, 57235 %E = select i1 %C, i1 true, i1 %D236 %F = xor i1 %E, -1237 ret i1 %F238}239 240; PR5634241define i1 @and_icmp_eq_0(i32 %A, i32 %B) {242; CHECK-LABEL: @and_icmp_eq_0(243; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]244; CHECK-NEXT: [[D:%.*]] = icmp eq i32 [[TMP1]], 0245; CHECK-NEXT: ret i1 [[D]]246;247 %C1 = icmp eq i32 %A, 0248 %C2 = icmp eq i32 %B, 0249 ; (A == 0) & (A == 0) --> (A|B) == 0250 %D = and i1 %C1, %C2251 ret i1 %D252}253 254define <2 x i1> @and_icmp_eq_0_vector(<2 x i32> %A, <2 x i32> %B) {255; CHECK-LABEL: @and_icmp_eq_0_vector(256; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]257; CHECK-NEXT: [[D:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer258; CHECK-NEXT: ret <2 x i1> [[D]]259;260 %C1 = icmp eq <2 x i32> %A, zeroinitializer261 %C2 = icmp eq <2 x i32> %B, zeroinitializer262 %D = and <2 x i1> %C1, %C2263 ret <2 x i1> %D264}265 266define <2 x i1> @and_icmp_eq_0_vector_poison1(<2 x i32> %A, <2 x i32> %B) {267; CHECK-LABEL: @and_icmp_eq_0_vector_poison1(268; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]269; CHECK-NEXT: [[D:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer270; CHECK-NEXT: ret <2 x i1> [[D]]271;272 %C1 = icmp eq <2 x i32> %A, <i32 0, i32 poison>273 %C2 = icmp eq <2 x i32> %B, <i32 0, i32 poison>274 %D = and <2 x i1> %C1, %C2275 ret <2 x i1> %D276}277 278define <2 x i1> @and_icmp_eq_0_vector_poison2(<2 x i32> %A, <2 x i32> %B) {279; CHECK-LABEL: @and_icmp_eq_0_vector_poison2(280; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]281; CHECK-NEXT: [[D:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer282; CHECK-NEXT: ret <2 x i1> [[D]]283;284 %C1 = icmp eq <2 x i32> %A, <i32 0, i32 poison>285 %C2 = icmp eq <2 x i32> %B, <i32 poison, i32 0>286 %D = and <2 x i1> %C1, %C2287 ret <2 x i1> %D288}289 290define i1 @and_icmp_eq_0_logical(i32 %A, i32 %B) {291; CHECK-LABEL: @and_icmp_eq_0_logical(292; CHECK-NEXT: [[C1:%.*]] = icmp eq i32 [[A:%.*]], 0293; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[B:%.*]], 0294; CHECK-NEXT: [[D:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false295; CHECK-NEXT: ret i1 [[D]]296;297 %C1 = icmp eq i32 %A, 0298 %C2 = icmp eq i32 %B, 0299 ; (A == 0) & (A == 0) --> (A|B) == 0300 %D = select i1 %C1, i1 %C2, i1 false301 ret i1 %D302}303 304define i1 @test27(ptr %A, ptr %B) {305; CHECK-LABEL: @test27(306; CHECK-NEXT: [[TMP1:%.*]] = icmp eq ptr [[A:%.*]], null307; CHECK-NEXT: [[TMP2:%.*]] = icmp eq ptr [[B:%.*]], null308; CHECK-NEXT: [[E:%.*]] = and i1 [[TMP1]], [[TMP2]]309; CHECK-NEXT: ret i1 [[E]]310;311 %C1 = ptrtoint ptr %A to i32312 %C2 = ptrtoint ptr %B to i32313 %D = or i32 %C1, %C2314 %E = icmp eq i32 %D, 0315 ret i1 %E316}317 318define <2 x i1> @test27vec(<2 x ptr> %A, <2 x ptr> %B) {319; CHECK-LABEL: @test27vec(320; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x ptr> [[A:%.*]], zeroinitializer321; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x ptr> [[B:%.*]], zeroinitializer322; CHECK-NEXT: [[E:%.*]] = and <2 x i1> [[TMP1]], [[TMP2]]323; CHECK-NEXT: ret <2 x i1> [[E]]324;325 %C1 = ptrtoint <2 x ptr> %A to <2 x i32>326 %C2 = ptrtoint <2 x ptr> %B to <2 x i32>327 %D = or <2 x i32> %C1, %C2328 %E = icmp eq <2 x i32> %D, zeroinitializer329 ret <2 x i1> %E330}331 332; PR5634333define i1 @test28(i32 %A, i32 %B) {334; CHECK-LABEL: @test28(335; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]336; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[TMP1]], 0337; CHECK-NEXT: ret i1 [[D]]338;339 %C1 = icmp ne i32 %A, 0340 %C2 = icmp ne i32 %B, 0341 ; (A != 0) | (A != 0) --> (A|B) != 0342 %D = or i1 %C1, %C2343 ret i1 %D344}345 346define i1 @test28_logical(i32 %A, i32 %B) {347; CHECK-LABEL: @test28_logical(348; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[A:%.*]], 0349; CHECK-NEXT: [[C2:%.*]] = icmp ne i32 [[B:%.*]], 0350; CHECK-NEXT: [[D:%.*]] = select i1 [[C1]], i1 true, i1 [[C2]]351; CHECK-NEXT: ret i1 [[D]]352;353 %C1 = icmp ne i32 %A, 0354 %C2 = icmp ne i32 %B, 0355 ; (A != 0) | (A != 0) --> (A|B) != 0356 %D = select i1 %C1, i1 true, i1 %C2357 ret i1 %D358}359 360define i1 @test29(ptr %A, ptr %B) {361; CHECK-LABEL: @test29(362; CHECK-NEXT: [[TMP1:%.*]] = icmp ne ptr [[A:%.*]], null363; CHECK-NEXT: [[TMP2:%.*]] = icmp ne ptr [[B:%.*]], null364; CHECK-NEXT: [[E:%.*]] = or i1 [[TMP1]], [[TMP2]]365; CHECK-NEXT: ret i1 [[E]]366;367 %C1 = ptrtoint ptr %A to i32368 %C2 = ptrtoint ptr %B to i32369 %D = or i32 %C1, %C2370 %E = icmp ne i32 %D, 0371 ret i1 %E372}373 374define <2 x i1> @test29vec(<2 x ptr> %A, <2 x ptr> %B) {375; CHECK-LABEL: @test29vec(376; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x ptr> [[A:%.*]], zeroinitializer377; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x ptr> [[B:%.*]], zeroinitializer378; CHECK-NEXT: [[E:%.*]] = or <2 x i1> [[TMP1]], [[TMP2]]379; CHECK-NEXT: ret <2 x i1> [[E]]380;381 %C1 = ptrtoint <2 x ptr> %A to <2 x i32>382 %C2 = ptrtoint <2 x ptr> %B to <2 x i32>383 %D = or <2 x i32> %C1, %C2384 %E = icmp ne <2 x i32> %D, zeroinitializer385 ret <2 x i1> %E386}387 388; PR4216389define i32 @test30(i32 %A) {390; CHECK-LABEL: @test30(391; CHECK-NEXT: [[D:%.*]] = and i32 [[A:%.*]], -58312392; CHECK-NEXT: [[E:%.*]] = or disjoint i32 [[D]], 32962393; CHECK-NEXT: ret i32 [[E]]394;395 %B = or i32 %A, 32962 ; 0b1000_0000_1100_0010396 %C = and i32 %A, -65536 ; 0xffff0000397 %D = and i32 %B, 40186 ; 0b1001_1100_1111_1010398 %E = or i32 %D, %C399 ret i32 %E400}401 402define <2 x i32> @test30vec(<2 x i32> %A) {403; CONSTVEC-LABEL: @test30vec(404; CONSTVEC-NEXT: [[TMP1:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 -58312)405; CONSTVEC-NEXT: [[E:%.*]] = or disjoint <2 x i32> [[TMP1]], splat (i32 32962)406; CONSTVEC-NEXT: ret <2 x i32> [[E]]407;408; CONSTSPLAT-LABEL: @test30vec(409; CONSTSPLAT-NEXT: [[D:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 -58312)410; CONSTSPLAT-NEXT: [[E:%.*]] = or disjoint <2 x i32> [[D]], splat (i32 32962)411; CONSTSPLAT-NEXT: ret <2 x i32> [[E]]412;413 %B = or <2 x i32> %A, <i32 32962, i32 32962>414 %C = and <2 x i32> %A, <i32 -65536, i32 -65536>415 %D = and <2 x i32> %B, <i32 40186, i32 40186>416 %E = or <2 x i32> %D, %C417 ret <2 x i32> %E418}419 420; PR4216421define i64 @test31(i64 %A) {422; CHECK-LABEL: @test31(423; CHECK-NEXT: [[E:%.*]] = and i64 [[A:%.*]], 4294908984424; CHECK-NEXT: [[F:%.*]] = or disjoint i64 [[E]], 32962425; CHECK-NEXT: ret i64 [[F]]426;427 %B = or i64 %A, 194428 %D = and i64 %B, 250429 430 %C = or i64 %A, 32768431 %E = and i64 %C, 4294941696432 433 %F = or i64 %D, %E434 ret i64 %F435}436 437define <2 x i64> @test31vec(<2 x i64> %A) {438; CHECK-LABEL: @test31vec(439; CHECK-NEXT: [[E:%.*]] = and <2 x i64> [[A:%.*]], splat (i64 4294908984)440; CHECK-NEXT: [[F:%.*]] = or disjoint <2 x i64> [[E]], splat (i64 32962)441; CHECK-NEXT: ret <2 x i64> [[F]]442;443 %B = or <2 x i64> %A, <i64 194, i64 194>444 %D = and <2 x i64> %B, <i64 250, i64 250>445 446 %C = or <2 x i64> %A, <i64 32768, i64 32768>447 %E = and <2 x i64> %C, <i64 4294941696, i64 4294941696>448 449 %F = or <2 x i64> %D, %E450 ret <2 x i64> %F451}452 453; codegen is mature enough to handle vector selects.454define <4 x i32> @test32(<4 x i1> %and.i1352, <4 x i32> %vecinit6.i176, <4 x i32> %vecinit6.i191) {455; CHECK-LABEL: @test32(456; CHECK-NEXT: [[OR_I:%.*]] = select <4 x i1> [[AND_I1352:%.*]], <4 x i32> [[VECINIT6_I176:%.*]], <4 x i32> [[VECINIT6_I191:%.*]]457; CHECK-NEXT: ret <4 x i32> [[OR_I]]458;459 %and.i135 = sext <4 x i1> %and.i1352 to <4 x i32>460 %and.i129 = and <4 x i32> %vecinit6.i176, %and.i135461 %neg.i = xor <4 x i32> %and.i135, <i32 -1, i32 -1, i32 -1, i32 -1>462 %and.i = and <4 x i32> %vecinit6.i191, %neg.i463 %or.i = or <4 x i32> %and.i, %and.i129464 ret <4 x i32> %or.i465}466 467define i1 @test33(i1 %X, i1 %Y) {468; CHECK-LABEL: @test33(469; CHECK-NEXT: [[A:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]470; CHECK-NEXT: ret i1 [[A]]471;472 %a = or i1 %X, %Y473 %b = or i1 %a, %X474 ret i1 %b475}476 477define i1 @test33_logical(i1 %X, i1 %Y) {478; CHECK-LABEL: @test33_logical(479; CHECK-NEXT: [[A:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]]480; CHECK-NEXT: ret i1 [[A]]481;482 %a = select i1 %X, i1 true, i1 %Y483 %b = select i1 %a, i1 true, i1 %X484 ret i1 %b485}486 487define i32 @test34(i32 %X, i32 %Y) {488; CHECK-LABEL: @test34(489; CHECK-NEXT: [[A:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]490; CHECK-NEXT: ret i32 [[A]]491;492 %a = or i32 %X, %Y493 %b = or i32 %Y, %a494 ret i32 %b495}496 497define i32 @test35(i32 %a, i32 %b) {498; CHECK-LABEL: @test35(499; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]500; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 1135501; CHECK-NEXT: ret i32 [[TMP2]]502;503 %1 = or i32 %a, 1135504 %2 = or i32 %1, %b505 ret i32 %2506}507 508define i1 @test36(i32 %x) {509; CHECK-LABEL: @test36(510; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -23511; CHECK-NEXT: [[RET2:%.*]] = icmp ult i32 [[TMP1]], 3512; CHECK-NEXT: ret i1 [[RET2]]513;514 %cmp1 = icmp eq i32 %x, 23515 %cmp2 = icmp eq i32 %x, 24516 %ret1 = or i1 %cmp1, %cmp2517 %cmp3 = icmp eq i32 %x, 25518 %ret2 = or i1 %ret1, %cmp3519 ret i1 %ret2520}521 522define i1 @test36_logical(i32 %x) {523; CHECK-LABEL: @test36_logical(524; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -23525; CHECK-NEXT: [[RET2:%.*]] = icmp ult i32 [[TMP1]], 3526; CHECK-NEXT: ret i1 [[RET2]]527;528 %cmp1 = icmp eq i32 %x, 23529 %cmp2 = icmp eq i32 %x, 24530 %ret1 = select i1 %cmp1, i1 true, i1 %cmp2531 %cmp3 = icmp eq i32 %x, 25532 %ret2 = select i1 %ret1, i1 true, i1 %cmp3533 ret i1 %ret2534}535 536define i1 @test37(i32 %x) {537; CHECK-LABEL: @test37(538; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 7539; CHECK-NEXT: [[RET1:%.*]] = icmp ult i32 [[TMP1]], 31540; CHECK-NEXT: ret i1 [[RET1]]541;542 %add1 = add i32 %x, 7543 %cmp1 = icmp ult i32 %add1, 30544 %cmp2 = icmp eq i32 %x, 23545 %ret1 = or i1 %cmp1, %cmp2546 ret i1 %ret1547}548 549define i1 @test37_logical(i32 %x) {550; CHECK-LABEL: @test37_logical(551; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 7552; CHECK-NEXT: [[RET1:%.*]] = icmp ult i32 [[TMP1]], 31553; CHECK-NEXT: ret i1 [[RET1]]554;555 %add1 = add i32 %x, 7556 %cmp1 = icmp ult i32 %add1, 30557 %cmp2 = icmp eq i32 %x, 23558 %ret1 = select i1 %cmp1, i1 true, i1 %cmp2559 ret i1 %ret1560}561 562define <2 x i1> @test37_uniform(<2 x i32> %x) {563; CHECK-LABEL: @test37_uniform(564; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], splat (i32 7)565; CHECK-NEXT: [[RET1:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 31)566; CHECK-NEXT: ret <2 x i1> [[RET1]]567;568 %add1 = add <2 x i32> %x, <i32 7, i32 7>569 %cmp1 = icmp ult <2 x i32> %add1, <i32 30, i32 30>570 %cmp2 = icmp eq <2 x i32> %x, <i32 23, i32 23>571 %ret1 = or <2 x i1> %cmp1, %cmp2572 ret <2 x i1> %ret1573}574 575define <2 x i1> @test37_poison(<2 x i32> %x) {576; CHECK-LABEL: @test37_poison(577; CHECK-NEXT: [[ADD1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 poison>578; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i32> [[ADD1]], <i32 30, i32 poison>579; CHECK-NEXT: [[CMP2:%.*]] = icmp eq <2 x i32> [[X]], <i32 23, i32 poison>580; CHECK-NEXT: [[RET1:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]581; CHECK-NEXT: ret <2 x i1> [[RET1]]582;583 %add1 = add <2 x i32> %x, <i32 7, i32 poison>584 %cmp1 = icmp ult <2 x i32> %add1, <i32 30, i32 poison>585 %cmp2 = icmp eq <2 x i32> %x, <i32 23, i32 poison>586 %ret1 = or <2 x i1> %cmp1, %cmp2587 ret <2 x i1> %ret1588}589 590define i1 @test38(i32 %x) {591; CHECK-LABEL: @test38(592; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 7593; CHECK-NEXT: [[RET1:%.*]] = icmp ult i32 [[TMP1]], 31594; CHECK-NEXT: ret i1 [[RET1]]595;596 %add1 = add i32 %x, 7597 %cmp1 = icmp eq i32 %x, 23598 %cmp2 = icmp ult i32 %add1, 30599 %ret1 = or i1 %cmp1, %cmp2600 ret i1 %ret1601}602 603define i1 @test38_logical(i32 %x) {604; CHECK-LABEL: @test38_logical(605; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 7606; CHECK-NEXT: [[RET1:%.*]] = icmp ult i32 [[TMP1]], 31607; CHECK-NEXT: ret i1 [[RET1]]608;609 %add1 = add i32 %x, 7610 %cmp1 = icmp eq i32 %x, 23611 %cmp2 = icmp ult i32 %add1, 30612 %ret1 = select i1 %cmp1, i1 true, i1 %cmp2613 ret i1 %ret1614}615 616define <2 x i1> @test38_nonuniform(<2 x i32> %x) {617; CHECK-LABEL: @test38_nonuniform(618; CHECK-NEXT: [[ADD1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 24>619; CHECK-NEXT: [[CMP1:%.*]] = icmp eq <2 x i32> [[X]], <i32 23, i32 8>620; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i32> [[ADD1]], <i32 30, i32 32>621; CHECK-NEXT: [[RET1:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]622; CHECK-NEXT: ret <2 x i1> [[RET1]]623;624 %add1 = add <2 x i32> %x, <i32 7, i32 24>625 %cmp1 = icmp eq <2 x i32> %x, <i32 23, i32 8>626 %cmp2 = icmp ult <2 x i32> %add1, <i32 30, i32 32>627 %ret1 = or <2 x i1> %cmp1, %cmp2628 ret <2 x i1> %ret1629}630 631; (~A & B) | A --> A | B632 633define i32 @test39a(i32 %a, float %b) {634; CHECK-LABEL: @test39a(635; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42636; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32637; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]638; CHECK-NEXT: ret i32 [[OR]]639;640 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering641 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering642 %nota = xor i32 %a1, -1643 %and = and i32 %nota, %b1644 %or = or i32 %and, %a1645 ret i32 %or646}647 648; Commute 'and' operands:649; (B & ~A) | A --> A | B650 651define i32 @test39b(i32 %a, float %b) {652; CHECK-LABEL: @test39b(653; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42654; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32655; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]656; CHECK-NEXT: ret i32 [[OR]]657;658 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering659 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering660 %nota = xor i32 %a1, -1661 %and = and i32 %b1, %nota662 %or = or i32 %and, %a1663 ret i32 %or664}665 666; Commute 'or' operands:667; A | (~A & B) --> A | B668 669define i32 @test39c(i32 %a, float %b) {670; CHECK-LABEL: @test39c(671; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42672; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32673; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]674; CHECK-NEXT: ret i32 [[OR]]675;676 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering677 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering678 %nota = xor i32 %a1, -1679 %and = and i32 %nota, %b1680 %or = or i32 %a1, %and681 ret i32 %or682}683 684; Commute 'and' operands:685; A | (B & ~A) --> A | B686 687define i32 @test39d(i32 %a, float %b) {688; CHECK-LABEL: @test39d(689; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42690; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32691; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]692; CHECK-NEXT: ret i32 [[OR]]693;694 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering695 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering696 %nota = xor i32 %a1, -1697 %and = and i32 %b1, %nota698 %or = or i32 %a1, %and699 ret i32 %or700}701 702define i32 @test40(i32 %a, i32 %b) {703; CHECK-LABEL: @test40(704; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1705; CHECK-NEXT: [[OR:%.*]] = or i32 [[B:%.*]], [[XOR]]706; CHECK-NEXT: ret i32 [[OR]]707;708 %and = and i32 %a, %b709 %xor = xor i32 %a, -1710 %or = or i32 %and, %xor711 ret i32 %or712}713 714define i32 @test40b(i32 %a, i32 %b) {715; CHECK-LABEL: @test40b(716; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1717; CHECK-NEXT: [[OR:%.*]] = or i32 [[B:%.*]], [[XOR]]718; CHECK-NEXT: ret i32 [[OR]]719;720 %and = and i32 %b, %a721 %xor = xor i32 %a, -1722 %or = or i32 %and, %xor723 ret i32 %or724}725 726define i32 @test40c(i32 %a, i32 %b) {727; CHECK-LABEL: @test40c(728; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1729; CHECK-NEXT: [[OR:%.*]] = or i32 [[B:%.*]], [[XOR]]730; CHECK-NEXT: ret i32 [[OR]]731;732 %and = and i32 %b, %a733 %xor = xor i32 %a, -1734 %or = or i32 %xor, %and735 ret i32 %or736}737 738define i32 @test40d(i32 %a, i32 %b) {739; CHECK-LABEL: @test40d(740; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1741; CHECK-NEXT: [[OR:%.*]] = or i32 [[B:%.*]], [[XOR]]742; CHECK-NEXT: ret i32 [[OR]]743;744 %and = and i32 %a, %b745 %xor = xor i32 %a, -1746 %or = or i32 %xor, %and747 ret i32 %or748}749 750define i32 @test45(i32 %x, i32 %y, i32 %z) {751; CHECK-LABEL: @test45(752; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Z:%.*]]753; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], [[Y:%.*]]754; CHECK-NEXT: ret i32 [[OR1]]755;756 %or = or i32 %y, %z757 %and = and i32 %x, %or758 %or1 = or i32 %and, %y759 ret i32 %or1760}761 762define i32 @test45_uses1(i32 %x, i32 %y, i32 %z) {763; CHECK-LABEL: @test45_uses1(764; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[Z:%.*]]765; CHECK-NEXT: call void @use(i32 [[OR]])766; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Z]]767; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], [[Y]]768; CHECK-NEXT: ret i32 [[OR1]]769;770 %or = or i32 %y, %z771 call void @use(i32 %or)772 %and = and i32 %x, %or773 %or1 = or i32 %and, %y774 ret i32 %or1775}776 777define i32 @test45_uses2(i32 %x, i32 %y, i32 %z) {778; CHECK-LABEL: @test45_uses2(779; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[Z:%.*]]780; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[OR]]781; CHECK-NEXT: call void @use(i32 [[AND]])782; CHECK-NEXT: [[OR1:%.*]] = or i32 [[AND]], [[Y]]783; CHECK-NEXT: ret i32 [[OR1]]784;785 %or = or i32 %y, %z786 %and = and i32 %x, %or787 call void @use(i32 %and)788 %or1 = or i32 %and, %y789 ret i32 %or1790}791 792define i32 @test45_commuted1(i32 %x, i32 %y, i32 %z) {793; CHECK-LABEL: @test45_commuted1(794; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]795; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Z:%.*]], [[X:%.*]]796; CHECK-NEXT: [[OR1:%.*]] = or i32 [[YY]], [[TMP1]]797; CHECK-NEXT: ret i32 [[OR1]]798;799 %yy = mul i32 %y, %y ; thwart complexity-based ordering800 %or = or i32 %yy, %z801 %and = and i32 %or, %x802 %or1 = or i32 %yy, %and803 ret i32 %or1804}805 806define i32 @test45_commuted2(i32 %x, i32 %y, i32 %z) {807; CHECK-LABEL: @test45_commuted2(808; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]809; CHECK-NEXT: [[XX:%.*]] = mul i32 [[X:%.*]], [[X]]810; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[XX]], [[Z:%.*]]811; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], [[YY]]812; CHECK-NEXT: ret i32 [[OR1]]813;814 %yy = mul i32 %y, %y ; thwart complexity-based ordering815 %xx = mul i32 %x, %x ; thwart complexity-based ordering816 %or = or i32 %yy, %z817 %and = and i32 %xx, %or818 %or1 = or i32 %and, %yy819 ret i32 %or1820}821 822define i32 @test45_commuted3(i32 %x, i32 %y, i32 %z) {823; CHECK-LABEL: @test45_commuted3(824; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]825; CHECK-NEXT: [[ZZ:%.*]] = mul i32 [[Z:%.*]], [[Z]]826; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ZZ]], [[X:%.*]]827; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], [[YY]]828; CHECK-NEXT: ret i32 [[OR1]]829;830 %yy = mul i32 %y, %y ; thwart complexity-based ordering831 %zz = mul i32 %z, %z ; thwart complexity-based ordering832 %or = or i32 %zz, %yy833 %and = and i32 %or, %x834 %or1 = or i32 %and, %yy835 ret i32 %or1836}837 838define i1 @test46(i8 signext %c) {839; CHECK-LABEL: @test46(840; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33841; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65842; CHECK-NEXT: [[OR:%.*]] = icmp ult i8 [[TMP2]], 26843; CHECK-NEXT: ret i1 [[OR]]844;845 %c.off = add i8 %c, -97846 %cmp1 = icmp ult i8 %c.off, 26847 %c.off17 = add i8 %c, -65848 %cmp2 = icmp ult i8 %c.off17, 26849 %or = or i1 %cmp1, %cmp2850 ret i1 %or851}852 853define i1 @test46_logical(i8 signext %c) {854; CHECK-LABEL: @test46_logical(855; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33856; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65857; CHECK-NEXT: [[OR:%.*]] = icmp ult i8 [[TMP2]], 26858; CHECK-NEXT: ret i1 [[OR]]859;860 %c.off = add i8 %c, -97861 %cmp1 = icmp ult i8 %c.off, 26862 %c.off17 = add i8 %c, -65863 %cmp2 = icmp ult i8 %c.off17, 26864 %or = select i1 %cmp1, i1 true, i1 %cmp2865 ret i1 %or866}867 868define <2 x i1> @test46_uniform(<2 x i8> %c) {869; CHECK-LABEL: @test46_uniform(870; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[C:%.*]], splat (i8 -33)871; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i8> [[TMP1]], splat (i8 -65)872; CHECK-NEXT: [[OR:%.*]] = icmp ult <2 x i8> [[TMP2]], splat (i8 26)873; CHECK-NEXT: ret <2 x i1> [[OR]]874;875 %c.off = add <2 x i8> %c, <i8 -97, i8 -97>876 %cmp1 = icmp ult <2 x i8> %c.off, <i8 26, i8 26>877 %c.off17 = add <2 x i8> %c, <i8 -65, i8 -65>878 %cmp2 = icmp ult <2 x i8> %c.off17, <i8 26, i8 26>879 %or = or <2 x i1> %cmp1, %cmp2880 ret <2 x i1> %or881}882 883define <2 x i1> @test46_poison(<2 x i8> %c) {884; CHECK-LABEL: @test46_poison(885; CHECK-NEXT: [[C_OFF:%.*]] = add <2 x i8> [[C:%.*]], <i8 -97, i8 poison>886; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i8> [[C_OFF]], <i8 26, i8 poison>887; CHECK-NEXT: [[C_OFF17:%.*]] = add <2 x i8> [[C]], <i8 -65, i8 poison>888; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i8> [[C_OFF17]], <i8 26, i8 poison>889; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]890; CHECK-NEXT: ret <2 x i1> [[OR]]891;892 %c.off = add <2 x i8> %c, <i8 -97, i8 poison>893 %cmp1 = icmp ult <2 x i8> %c.off, <i8 26, i8 poison>894 %c.off17 = add <2 x i8> %c, <i8 -65, i8 poison>895 %cmp2 = icmp ult <2 x i8> %c.off17, <i8 26, i8 poison>896 %or = or <2 x i1> %cmp1, %cmp2897 ret <2 x i1> %or898}899 900; This is the variant of the above pattern where one of the ranges is901; represented with an add.902define i1 @two_ranges_to_mask_and_range_degenerate(i16 %x) {903; CHECK-LABEL: @two_ranges_to_mask_and_range_degenerate(904; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[X:%.*]], -20905; CHECK-NEXT: [[OR:%.*]] = icmp ult i16 [[TMP1]], 12906; CHECK-NEXT: ret i1 [[OR]]907;908 %cmp1 = icmp ult i16 %x, 12909 %cmp2 = icmp uge i16 %x, 16910 %cmp3 = icmp ult i16 %x, 28911 %and = and i1 %cmp2, %cmp3912 %or = or i1 %cmp1, %and913 ret i1 %or914}915 916define i1 @test47(i8 signext %c) {917; CHECK-LABEL: @test47(918; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33919; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65920; CHECK-NEXT: [[OR:%.*]] = icmp ult i8 [[TMP2]], 27921; CHECK-NEXT: ret i1 [[OR]]922;923 %c.off = add i8 %c, -65924 %cmp1 = icmp ule i8 %c.off, 26925 %c.off17 = add i8 %c, -97926 %cmp2 = icmp ule i8 %c.off17, 26927 %or = or i1 %cmp1, %cmp2928 ret i1 %or929}930 931define i1 @test47_logical(i8 signext %c) {932; CHECK-LABEL: @test47_logical(933; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33934; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65935; CHECK-NEXT: [[OR:%.*]] = icmp ult i8 [[TMP2]], 27936; CHECK-NEXT: ret i1 [[OR]]937;938 %c.off = add i8 %c, -65939 %cmp1 = icmp ule i8 %c.off, 26940 %c.off17 = add i8 %c, -97941 %cmp2 = icmp ule i8 %c.off17, 26942 %or = select i1 %cmp1, i1 true, i1 %cmp2943 ret i1 %or944}945 946define <2 x i1> @test47_nonuniform(<2 x i8> %c) {947; CHECK-LABEL: @test47_nonuniform(948; CHECK-NEXT: [[C_OFF:%.*]] = add <2 x i8> [[C:%.*]], <i8 -65, i8 -97>949; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i8> [[C_OFF]], splat (i8 27)950; CHECK-NEXT: [[C_OFF17:%.*]] = add <2 x i8> [[C]], <i8 -97, i8 -65>951; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i8> [[C_OFF17]], splat (i8 27)952; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]953; CHECK-NEXT: ret <2 x i1> [[OR]]954;955 %c.off = add <2 x i8> %c, <i8 -65, i8 -97>956 %cmp1 = icmp ule <2 x i8> %c.off, <i8 26, i8 26>957 %c.off17 = add <2 x i8> %c, <i8 -97, i8 -65>958 %cmp2 = icmp ule <2 x i8> %c.off17, <i8 26, i8 26>959 %or = or <2 x i1> %cmp1, %cmp2960 ret <2 x i1> %or961}962 963define i32 @test49(i1 %C) {964; CHECK-LABEL: @test49(965; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 1019, i32 123966; CHECK-NEXT: ret i32 [[V]]967;968 %A = select i1 %C, i32 1000, i32 10969 %V = or i32 %A, 123970 ret i32 %V971}972 973define <2 x i32> @test49vec(i1 %C) {974; CHECK-LABEL: @test49vec(975; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> splat (i32 1019), <2 x i32> splat (i32 123)976; CHECK-NEXT: ret <2 x i32> [[V]]977;978 %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>979 %V = or <2 x i32> %A, <i32 123, i32 123>980 ret <2 x i32> %V981}982 983define <2 x i32> @test49vec2(i1 %C) {984; CHECK-LABEL: @test49vec2(985; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1019, i32 2509>, <2 x i32> <i32 123, i32 351>986; CHECK-NEXT: ret <2 x i32> [[V]]987;988 %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30>989 %V = or <2 x i32> %A, <i32 123, i32 333>990 ret <2 x i32> %V991}992 993define i32 @test50(i1 %which) {994; CHECK-LABEL: @test50(995; CHECK-NEXT: entry:996; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]997; CHECK: delay:998; CHECK-NEXT: br label [[FINAL]]999; CHECK: final:1000; CHECK-NEXT: [[A:%.*]] = phi i32 [ 1019, [[ENTRY:%.*]] ], [ 123, [[DELAY]] ]1001; CHECK-NEXT: ret i32 [[A]]1002;1003entry:1004 br i1 %which, label %final, label %delay1005 1006delay:1007 br label %final1008 1009final:1010 %A = phi i32 [ 1000, %entry ], [ 10, %delay ]1011 %value = or i32 %A, 1231012 ret i32 %value1013}1014 1015define <2 x i32> @test50vec(i1 %which) {1016; CHECK-LABEL: @test50vec(1017; CHECK-NEXT: entry:1018; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]1019; CHECK: delay:1020; CHECK-NEXT: br label [[FINAL]]1021; CHECK: final:1022; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ splat (i32 1019), [[ENTRY:%.*]] ], [ splat (i32 123), [[DELAY]] ]1023; CHECK-NEXT: ret <2 x i32> [[A]]1024;1025entry:1026 br i1 %which, label %final, label %delay1027 1028delay:1029 br label %final1030 1031final:1032 %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ]1033 %value = or <2 x i32> %A, <i32 123, i32 123>1034 ret <2 x i32> %value1035}1036 1037define <2 x i32> @test50vec2(i1 %which) {1038; CHECK-LABEL: @test50vec2(1039; CHECK-NEXT: entry:1040; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]1041; CHECK: delay:1042; CHECK-NEXT: br label [[FINAL]]1043; CHECK: final:1044; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1019, i32 2509>, [[ENTRY:%.*]] ], [ <i32 123, i32 351>, [[DELAY]] ]1045; CHECK-NEXT: ret <2 x i32> [[A]]1046;1047entry:1048 br i1 %which, label %final, label %delay1049 1050delay:1051 br label %final1052 1053final:1054 %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ]1055 %value = or <2 x i32> %A, <i32 123, i32 333>1056 ret <2 x i32> %value1057}1058 1059; In the next 4 tests, vary the types and predicates for extra coverage.1060; (X | (Y & ~X)) -> (X | Y), where 'not' is an inverted cmp1061 1062define i1 @or_andn_cmp_1(i32 %a, i32 %b, i32 %c) {1063; CHECK-LABEL: @or_andn_cmp_1(1064; CHECK-NEXT: [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]1065; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 421066; CHECK-NEXT: [[OR:%.*]] = or i1 [[X]], [[Y]]1067; CHECK-NEXT: ret i1 [[OR]]1068;1069 %x = icmp sgt i32 %a, %b1070 %x_inv = icmp sle i32 %a, %b1071 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering1072 %and = and i1 %y, %x_inv1073 %or = or i1 %x, %and1074 ret i1 %or1075}1076 1077define i1 @or_andn_cmp_1_logical(i32 %a, i32 %b, i32 %c) {1078; CHECK-LABEL: @or_andn_cmp_1_logical(1079; CHECK-NEXT: [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]1080; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 421081; CHECK-NEXT: [[OR:%.*]] = select i1 [[X]], i1 true, i1 [[Y]]1082; CHECK-NEXT: ret i1 [[OR]]1083;1084 %x = icmp sgt i32 %a, %b1085 %x_inv = icmp sle i32 %a, %b1086 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering1087 %and = select i1 %y, i1 %x_inv, i1 false1088 %or = select i1 %x, i1 true, i1 %and1089 ret i1 %or1090}1091 1092; Commute the 'or':1093; ((Y & ~X) | X) -> (X | Y), where 'not' is an inverted cmp1094 1095define <2 x i1> @or_andn_cmp_2(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) {1096; CHECK-LABEL: @or_andn_cmp_2(1097; CHECK-NEXT: [[X:%.*]] = icmp sge <2 x i32> [[A:%.*]], [[B:%.*]]1098; CHECK-NEXT: [[Y:%.*]] = icmp ugt <2 x i32> [[C:%.*]], <i32 42, i32 47>1099; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[Y]], [[X]]1100; CHECK-NEXT: ret <2 x i1> [[OR]]1101;1102 %x = icmp sge <2 x i32> %a, %b1103 %x_inv = icmp slt <2 x i32> %a, %b1104 %y = icmp ugt <2 x i32> %c, <i32 42, i32 47> ; thwart complexity-based ordering1105 %and = and <2 x i1> %y, %x_inv1106 %or = or <2 x i1> %and, %x1107 ret <2 x i1> %or1108}1109 1110; Commute the 'and':1111; (X | (~X & Y)) -> (X | Y), where 'not' is an inverted cmp1112 1113define i1 @or_andn_cmp_3(i72 %a, i72 %b, i72 %c) {1114; CHECK-LABEL: @or_andn_cmp_3(1115; CHECK-NEXT: [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]1116; CHECK-NEXT: [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 421117; CHECK-NEXT: [[OR:%.*]] = or i1 [[X]], [[Y]]1118; CHECK-NEXT: ret i1 [[OR]]1119;1120 %x = icmp ugt i72 %a, %b1121 %x_inv = icmp ule i72 %a, %b1122 %y = icmp ugt i72 %c, 42 ; thwart complexity-based ordering1123 %and = and i1 %x_inv, %y1124 %or = or i1 %x, %and1125 ret i1 %or1126}1127 1128define i1 @or_andn_cmp_3_logical(i72 %a, i72 %b, i72 %c) {1129; CHECK-LABEL: @or_andn_cmp_3_logical(1130; CHECK-NEXT: [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]1131; CHECK-NEXT: [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 421132; CHECK-NEXT: [[OR:%.*]] = select i1 [[X]], i1 true, i1 [[Y]]1133; CHECK-NEXT: ret i1 [[OR]]1134;1135 %x = icmp ugt i72 %a, %b1136 %x_inv = icmp ule i72 %a, %b1137 %y = icmp ugt i72 %c, 42 ; thwart complexity-based ordering1138 %and = select i1 %x_inv, i1 %y, i1 false1139 %or = select i1 %x, i1 true, i1 %and1140 ret i1 %or1141}1142 1143; Commute the 'or':1144; ((~X & Y) | X) -> (X | Y), where 'not' is an inverted cmp1145 1146define <3 x i1> @or_andn_cmp_4(<3 x i32> %a, <3 x i32> %b, <3 x i32> %c) {1147; CHECK-LABEL: @or_andn_cmp_4(1148; CHECK-NEXT: [[X:%.*]] = icmp eq <3 x i32> [[A:%.*]], [[B:%.*]]1149; CHECK-NEXT: [[Y:%.*]] = icmp ugt <3 x i32> [[C:%.*]], <i32 42, i32 43, i32 -1>1150; CHECK-NEXT: [[OR:%.*]] = or <3 x i1> [[Y]], [[X]]1151; CHECK-NEXT: ret <3 x i1> [[OR]]1152;1153 %x = icmp eq <3 x i32> %a, %b1154 %x_inv = icmp ne <3 x i32> %a, %b1155 %y = icmp ugt <3 x i32> %c, <i32 42, i32 43, i32 -1> ; thwart complexity-based ordering1156 %and = and <3 x i1> %x_inv, %y1157 %or = or <3 x i1> %and, %x1158 ret <3 x i1> %or1159}1160 1161; In the next 4 tests, vary the types and predicates for extra coverage.1162; (~X | (Y & X)) -> (~X | Y), where 'not' is an inverted cmp1163 1164define i1 @orn_and_cmp_1(i37 %a, i37 %b, i37 %c) {1165; CHECK-LABEL: @orn_and_cmp_1(1166; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]1167; CHECK-NEXT: [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 421168; CHECK-NEXT: [[OR:%.*]] = or i1 [[X_INV]], [[Y]]1169; CHECK-NEXT: ret i1 [[OR]]1170;1171 %x = icmp sgt i37 %a, %b1172 %x_inv = icmp sle i37 %a, %b1173 %y = icmp ugt i37 %c, 42 ; thwart complexity-based ordering1174 %and = and i1 %y, %x1175 %or = or i1 %x_inv, %and1176 ret i1 %or1177}1178 1179define i1 @orn_and_cmp_1_logical(i37 %a, i37 %b, i37 %c) {1180; CHECK-LABEL: @orn_and_cmp_1_logical(1181; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]1182; CHECK-NEXT: [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 421183; CHECK-NEXT: [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y]]1184; CHECK-NEXT: ret i1 [[OR]]1185;1186 %x = icmp sgt i37 %a, %b1187 %x_inv = icmp sle i37 %a, %b1188 %y = icmp ugt i37 %c, 42 ; thwart complexity-based ordering1189 %and = select i1 %y, i1 %x, i1 false1190 %or = select i1 %x_inv, i1 true, i1 %and1191 ret i1 %or1192}1193 1194; Commute the 'or':1195; ((Y & X) | ~X) -> (~X | Y), where 'not' is an inverted cmp1196 1197define i1 @orn_and_cmp_2(i16 %a, i16 %b, i16 %c) {1198; CHECK-LABEL: @orn_and_cmp_2(1199; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]1200; CHECK-NEXT: [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 421201; CHECK-NEXT: [[OR:%.*]] = or i1 [[Y]], [[X_INV]]1202; CHECK-NEXT: ret i1 [[OR]]1203;1204 %x = icmp sge i16 %a, %b1205 %x_inv = icmp slt i16 %a, %b1206 %y = icmp ugt i16 %c, 42 ; thwart complexity-based ordering1207 %and = and i1 %y, %x1208 %or = or i1 %and, %x_inv1209 ret i1 %or1210}1211 1212define i1 @orn_and_cmp_2_logical(i16 %a, i16 %b, i16 %c) {1213; CHECK-LABEL: @orn_and_cmp_2_logical(1214; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]1215; CHECK-NEXT: [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 421216; CHECK-NEXT: [[OR:%.*]] = select i1 [[Y]], i1 true, i1 [[X_INV]]1217; CHECK-NEXT: ret i1 [[OR]]1218;1219 %x = icmp sge i16 %a, %b1220 %x_inv = icmp slt i16 %a, %b1221 %y = icmp ugt i16 %c, 42 ; thwart complexity-based ordering1222 %and = select i1 %y, i1 %x, i1 false1223 %or = select i1 %and, i1 true, i1 %x_inv1224 ret i1 %or1225}1226 1227; Commute the 'and':1228; (~X | (X & Y)) -> (~X | Y), where 'not' is an inverted cmp1229 1230define <4 x i1> @orn_and_cmp_3(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {1231; CHECK-LABEL: @orn_and_cmp_3(1232; CHECK-NEXT: [[X_INV:%.*]] = icmp ule <4 x i32> [[A:%.*]], [[B:%.*]]1233; CHECK-NEXT: [[Y:%.*]] = icmp ugt <4 x i32> [[C:%.*]], <i32 42, i32 0, i32 1, i32 -1>1234; CHECK-NEXT: [[OR:%.*]] = or <4 x i1> [[X_INV]], [[Y]]1235; CHECK-NEXT: ret <4 x i1> [[OR]]1236;1237 %x = icmp ugt <4 x i32> %a, %b1238 %x_inv = icmp ule <4 x i32> %a, %b1239 %y = icmp ugt <4 x i32> %c, <i32 42, i32 0, i32 1, i32 -1> ; thwart complexity-based ordering1240 %and = and <4 x i1> %x, %y1241 %or = or <4 x i1> %x_inv, %and1242 ret <4 x i1> %or1243}1244 1245; Commute the 'or':1246; ((X & Y) | ~X) -> (~X | Y), where 'not' is an inverted cmp1247 1248define i1 @orn_and_cmp_4(i32 %a, i32 %b, i32 %c) {1249; CHECK-LABEL: @orn_and_cmp_4(1250; CHECK-NEXT: [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]1251; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 421252; CHECK-NEXT: [[OR:%.*]] = or i1 [[Y]], [[X_INV]]1253; CHECK-NEXT: ret i1 [[OR]]1254;1255 %x = icmp eq i32 %a, %b1256 %x_inv = icmp ne i32 %a, %b1257 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering1258 %and = and i1 %x, %y1259 %or = or i1 %and, %x_inv1260 ret i1 %or1261}1262 1263define i1 @orn_and_cmp_4_logical(i32 %a, i32 %b, i32 %c) {1264; CHECK-LABEL: @orn_and_cmp_4_logical(1265; CHECK-NEXT: [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]1266; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 421267; CHECK-NEXT: [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y]]1268; CHECK-NEXT: ret i1 [[OR]]1269;1270 %x = icmp eq i32 %a, %b1271 %x_inv = icmp ne i32 %a, %b1272 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering1273 %and = select i1 %x, i1 %y, i1 false1274 %or = select i1 %and, i1 true, i1 %x_inv1275 ret i1 %or1276}1277 1278; The constant vectors are inverses. Make sure we can turn this into a select without crashing trying to truncate the constant to 16xi1.1279define <16 x i1> @test51(<16 x i1> %arg, <16 x i1> %arg1) {1280; CHECK-LABEL: @test51(1281; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <16 x i1> [[ARG:%.*]], <16 x i1> [[ARG1:%.*]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 20, i32 5, i32 6, i32 23, i32 24, i32 9, i32 10, i32 27, i32 28, i32 29, i32 30, i32 31>1282; CHECK-NEXT: ret <16 x i1> [[TMP3]]1283;1284 %tmp = and <16 x i1> %arg, <i1 true, i1 true, i1 true, i1 true, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false>1285 %tmp2 = and <16 x i1> %arg1, <i1 false, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 true, i1 true, i1 true>1286 %tmp3 = or <16 x i1> %tmp, %tmp21287 ret <16 x i1> %tmp31288}1289 1290; This would infinite loop because it reaches a transform1291; that was not expecting a constant-foldable value.1292 1293define i32 @PR46712(i1 %x, i1 %y, i1 %b, i64 %z) {1294; CHECK-LABEL: @PR46712(1295; CHECK-NEXT: entry:1296; CHECK-NEXT: br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]]1297; CHECK: true:1298; CHECK-NEXT: [[BOOL5_NOT:%.*]] = icmp eq i64 [[Z:%.*]], 01299; CHECK-NEXT: [[TMP0:%.*]] = zext i1 [[BOOL5_NOT]] to i321300; CHECK-NEXT: br label [[END]]1301; CHECK: end:1302; CHECK-NEXT: [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP0]], [[TRUE]] ]1303; CHECK-NEXT: ret i32 [[T5]]1304;1305entry:1306 %t2 = or i1 %x, %y1307 %conv = sext i1 %t2 to i321308 %cmp = icmp sge i32 %conv, 11309 %conv2 = zext i1 %cmp to i641310 br i1 %b, label %true, label %end1311 1312true:1313 %bool4 = icmp eq i64 %conv2, 01314 %bool5 = icmp ne i64 %z, 01315 %and = and i1 %bool4, %bool51316 %sel = select i1 %and, i1 false, i1 true1317 br label %end1318 1319end:1320 %t5 = phi i1 [ 0, %entry ], [ %sel, %true ]1321 %conv8 = zext i1 %t5 to i321322 ret i32 %conv81323}1324 1325define i32 @PR46712_logical(i1 %x, i1 %y, i1 %b, i64 %z) {1326; CHECK-LABEL: @PR46712_logical(1327; CHECK-NEXT: entry:1328; CHECK-NEXT: br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]]1329; CHECK: true:1330; CHECK-NEXT: [[BOOL5_NOT:%.*]] = icmp eq i64 [[Z:%.*]], 01331; CHECK-NEXT: [[TMP0:%.*]] = zext i1 [[BOOL5_NOT]] to i321332; CHECK-NEXT: br label [[END]]1333; CHECK: end:1334; CHECK-NEXT: [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP0]], [[TRUE]] ]1335; CHECK-NEXT: ret i32 [[T5]]1336;1337entry:1338 %t2 = select i1 %x, i1 true, i1 %y1339 %conv = sext i1 %t2 to i321340 %cmp = icmp sge i32 %conv, 11341 %conv2 = zext i1 %cmp to i641342 br i1 %b, label %true, label %end1343 1344true:1345 %bool4 = icmp eq i64 %conv2, 01346 %bool5 = icmp ne i64 %z, 01347 %and = select i1 %bool4, i1 %bool5, i1 false1348 %sel = select i1 %and, i1 false, i1 true1349 br label %end1350 1351end:1352 %t5 = phi i1 [ 0, %entry ], [ %sel, %true ]1353 %conv8 = zext i1 %t5 to i321354 ret i32 %conv81355}1356 1357; (~x & y) | ~(x | y) --> ~x1358define i32 @PR38929(i32 %0, i32 %1) {1359; CHECK-LABEL: @PR38929(1360; CHECK-NEXT: [[TMP3:%.*]] = xor i32 [[TMP0:%.*]], -11361; CHECK-NEXT: ret i32 [[TMP3]]1362;1363 %3 = xor i32 %0, -11364 %4 = and i32 %3, %11365 %5 = or i32 %1, %01366 %6 = xor i32 %5, -11367 %7 = or i32 %4, %61368 ret i32 %71369}1370 1371define i32 @test1(i32 %x, i32 %y) {1372; CHECK-LABEL: @test1(1373; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]1374; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -11375; CHECK-NEXT: ret i32 [[OR1]]1376;1377 %xor = xor i32 %y, %x1378 %or = or i32 %y, %x1379 %neg = xor i32 %or, -11380 %or1 = or i32 %xor, %neg1381 ret i32 %or11382}1383 1384define i32 @test2(i32 %x, i32 %y) {1385; CHECK-LABEL: @test2(1386; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]1387; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -11388; CHECK-NEXT: ret i32 [[OR1]]1389;1390 %or = or i32 %x, %y1391 %neg = xor i32 %or, -11392 %xor = xor i32 %y, %x1393 %or1 = or i32 %xor, %neg1394 ret i32 %or11395}1396 1397define i32 @test3(i32 %x, i32 %y) {1398; CHECK-LABEL: @test3(1399; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]1400; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -11401; CHECK-NEXT: ret i32 [[OR1]]1402;1403 %or = or i32 %y, %x1404 %neg = xor i32 %or, -11405 %xor = xor i32 %x, %y1406 %or1 = or i32 %xor, %neg1407 ret i32 %or11408}1409 1410define <2 x i32> @test4_vec(<2 x i32> %x, <2 x i32> %y) {1411; CHECK-LABEL: @test4_vec(1412; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[Y:%.*]], [[X:%.*]]1413; CHECK-NEXT: [[OR1:%.*]] = xor <2 x i32> [[TMP1]], splat (i32 -1)1414; CHECK-NEXT: ret <2 x i32> [[OR1]]1415;1416 %or = or <2 x i32> %y, %x1417 %neg = xor <2 x i32> %or, <i32 -1, i32 -1>1418 %xor = xor <2 x i32> %y, %x1419 %or1 = or <2 x i32> %xor, %neg1420 ret <2 x i32> %or11421}1422 1423define i32 @test5_use(i32 %x, i32 %y) {1424; CHECK-LABEL: @test5_use(1425; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]1426; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[OR]], -11427; CHECK-NEXT: call void @use(i32 [[NEG]])1428; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y]], [[X]]1429; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -11430; CHECK-NEXT: ret i32 [[OR1]]1431;1432 %or = or i32 %y, %x1433 %neg = xor i32 %or, -11434 %xor = xor i32 %y, %x1435 call void @use(i32 %neg)1436 %or1 = or i32 %xor, %neg1437 ret i32 %or11438}1439 1440define i32 @test5_use2(i32 %x, i32 %y) {1441; CHECK-LABEL: @test5_use2(1442; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]1443; CHECK-NEXT: call void @use(i32 [[XOR]])1444; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y]], [[X]]1445; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -11446; CHECK-NEXT: ret i32 [[OR1]]1447;1448 %or = or i32 %y, %x1449 %neg = xor i32 %or, -11450 %xor = xor i32 %y, %x1451 call void @use(i32 %xor)1452 %or1 = or i32 %xor, %neg1453 ret i32 %or11454}1455define i32 @test5_use3(i32 %x, i32 %y) {1456; CHECK-LABEL: @test5_use3(1457; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]1458; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[OR]], -11459; CHECK-NEXT: call void @use(i32 [[NEG]])1460; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y]], [[X]]1461; CHECK-NEXT: call void @use(i32 [[XOR]])1462; CHECK-NEXT: [[OR1:%.*]] = or i32 [[XOR]], [[NEG]]1463; CHECK-NEXT: ret i32 [[OR1]]1464;1465 %or = or i32 %y, %x1466 %neg = xor i32 %or, -11467 call void @use(i32 %neg)1468 %xor = xor i32 %y, %x1469 call void @use(i32 %xor)1470 %or1 = or i32 %xor, %neg1471 ret i32 %or11472}1473 1474define i8 @ashr_bitwidth_mask(i8 %x, i8 %y) {1475; CHECK-LABEL: @ashr_bitwidth_mask(1476; CHECK-NEXT: [[SIGN:%.*]] = ashr i8 [[X:%.*]], 71477; CHECK-NEXT: [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]]1478; CHECK-NEXT: ret i8 [[R]]1479;1480 %sign = ashr i8 %x, 71481 %r = or i8 %sign, %y1482 ret i8 %r1483}1484 1485define <2 x i8> @ashr_bitwidth_mask_vec_commute(<2 x i8> %x, <2 x i8> %py) {1486; CHECK-LABEL: @ashr_bitwidth_mask_vec_commute(1487; CHECK-NEXT: [[Y:%.*]] = mul <2 x i8> [[PY:%.*]], <i8 42, i8 2>1488; CHECK-NEXT: [[SIGN:%.*]] = ashr <2 x i8> [[X:%.*]], splat (i8 7)1489; CHECK-NEXT: [[R:%.*]] = or <2 x i8> [[Y]], [[SIGN]]1490; CHECK-NEXT: ret <2 x i8> [[R]]1491;1492 %y = mul <2 x i8> %py, <i8 42, i8 2> ; thwart complexity-based ordering1493 %sign = ashr <2 x i8> %x, <i8 7, i8 7>1494 %r = or <2 x i8> %y, %sign1495 ret <2 x i8> %r1496}1497 1498define i32 @ashr_bitwidth_mask_use(i32 %x, i32 %y) {1499; CHECK-LABEL: @ashr_bitwidth_mask_use(1500; CHECK-NEXT: [[SIGN:%.*]] = ashr i32 [[X:%.*]], 71501; CHECK-NEXT: call void @use(i32 [[SIGN]])1502; CHECK-NEXT: [[R:%.*]] = or i32 [[SIGN]], [[Y:%.*]]1503; CHECK-NEXT: ret i32 [[R]]1504;1505 %sign = ashr i32 %x, 71506 call void @use(i32 %sign)1507 %r = or i32 %sign, %y1508 ret i32 %r1509}1510 1511define i8 @ashr_not_bitwidth_mask(i8 %x, i8 %y) {1512; CHECK-LABEL: @ashr_not_bitwidth_mask(1513; CHECK-NEXT: [[SIGN:%.*]] = ashr i8 [[X:%.*]], 61514; CHECK-NEXT: [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]]1515; CHECK-NEXT: ret i8 [[R]]1516;1517 %sign = ashr i8 %x, 61518 %r = or i8 %sign, %y1519 ret i8 %r1520}1521 1522define i8 @lshr_bitwidth_mask(i8 %x, i8 %y) {1523; CHECK-LABEL: @lshr_bitwidth_mask(1524; CHECK-NEXT: [[SIGN:%.*]] = lshr i8 [[X:%.*]], 71525; CHECK-NEXT: [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]]1526; CHECK-NEXT: ret i8 [[R]]1527;1528 %sign = lshr i8 %x, 71529 %r = or i8 %sign, %y1530 ret i8 %r1531}1532 1533define i1 @cmp_overlap(i32 %x) {1534; CHECK-LABEL: @cmp_overlap(1535; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[X:%.*]], 11536; CHECK-NEXT: ret i1 [[R]]1537;1538 %isneg = icmp slt i32 %x, 01539 %negx = sub i32 0, %x1540 %isnotneg = icmp sgt i32 %negx, -11541 %r = or i1 %isneg, %isnotneg1542 ret i1 %r1543}1544 1545define <2 x i1> @cmp_overlap_splat(<2 x i5> %x) {1546; CHECK-LABEL: @cmp_overlap_splat(1547; CHECK-NEXT: [[R:%.*]] = icmp slt <2 x i5> [[X:%.*]], splat (i5 1)1548; CHECK-NEXT: ret <2 x i1> [[R]]1549;1550 %isneg = icmp slt <2 x i5> %x, zeroinitializer1551 %negx = sub <2 x i5> zeroinitializer, %x1552 %isnotneg = icmp sgt <2 x i5> %negx, <i5 -1, i5 -1>1553 %r = or <2 x i1> %isneg, %isnotneg1554 ret <2 x i1> %r1555}1556 1557define i32 @mul_no_common_bits(i32 %p1, i32 %p2) {1558; CHECK-LABEL: @mul_no_common_bits(1559; CHECK-NEXT: [[X:%.*]] = and i32 [[P1:%.*]], 71560; CHECK-NEXT: [[Y:%.*]] = shl i32 [[P2:%.*]], 31561; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i32 [[Y]], 11562; CHECK-NEXT: [[R:%.*]] = mul i32 [[X]], [[TMP1]]1563; CHECK-NEXT: ret i32 [[R]]1564;1565 %x = and i32 %p1, 71566 %y = shl i32 %p2, 31567 %m = mul i32 %x, %y1568 %r = or i32 %m, %x1569 ret i32 %r1570}1571 1572define i32 @mul_no_common_bits_const_op(i32 %p) {1573; CHECK-LABEL: @mul_no_common_bits_const_op(1574; CHECK-NEXT: [[X:%.*]] = and i32 [[P:%.*]], 71575; CHECK-NEXT: [[R:%.*]] = mul nuw nsw i32 [[X]], 251576; CHECK-NEXT: ret i32 [[R]]1577;1578 %x = and i32 %p, 71579 %m = mul i32 %x, 241580 %r = or i32 %m, %x1581 ret i32 %r1582}1583 1584define <2 x i12> @mul_no_common_bits_commute(<2 x i12> %p) {1585; CHECK-LABEL: @mul_no_common_bits_commute(1586; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i12> [[P:%.*]] to <2 x i1>1587; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[TMP1]], <2 x i12> <i12 15, i12 17>, <2 x i12> zeroinitializer1588; CHECK-NEXT: ret <2 x i12> [[R]]1589;1590 %x = and <2 x i12> %p, <i12 1, i12 1>1591 %m = mul <2 x i12> %x, <i12 14, i12 16>1592 %r = or <2 x i12> %x, %m1593 ret <2 x i12> %r1594}1595 1596define i32 @mul_no_common_bits_commute2(i32 %p1, i32 %p2) {1597; CHECK-LABEL: @mul_no_common_bits_commute2(1598; CHECK-NEXT: [[X:%.*]] = and i32 [[P1:%.*]], 71599; CHECK-NEXT: [[Y:%.*]] = shl i32 [[P2:%.*]], 31600; CHECK-NEXT: [[M:%.*]] = mul i32 [[Y]], [[X]]1601; CHECK-NEXT: [[R:%.*]] = or disjoint i32 [[M]], [[X]]1602; CHECK-NEXT: ret i32 [[R]]1603;1604 %x = and i32 %p1, 71605 %y = shl i32 %p2, 31606 %m = mul i32 %y, %x1607 %r = or i32 %m, %x1608 ret i32 %r1609}1610 1611define i32 @mul_no_common_bits_disjoint(i32 %x, i32 %y) {1612; CHECK-LABEL: @mul_no_common_bits_disjoint(1613; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[Y:%.*]], 11614; CHECK-NEXT: [[R:%.*]] = mul i32 [[X:%.*]], [[TMP1]]1615; CHECK-NEXT: ret i32 [[R]]1616;1617 %m = mul i32 %x, %y1618 %r = or disjoint i32 %m, %x1619 ret i32 %r1620}1621 1622define i32 @mul_no_common_bits_const_op_disjoint(i32 %x, i32 %y) {1623; CHECK-LABEL: @mul_no_common_bits_const_op_disjoint(1624; CHECK-NEXT: [[R:%.*]] = mul i32 [[X:%.*]], 251625; CHECK-NEXT: ret i32 [[R]]1626;1627 %m = mul i32 %x, 241628 %r = or disjoint i32 %m, %x1629 ret i32 %r1630}1631 1632; negative test - extra use requires extra instructions1633 1634define i32 @mul_no_common_bits_uses(i32 %p1, i32 %p2) {1635; CHECK-LABEL: @mul_no_common_bits_uses(1636; CHECK-NEXT: [[X:%.*]] = and i32 [[P1:%.*]], 71637; CHECK-NEXT: [[Y:%.*]] = shl i32 [[P2:%.*]], 31638; CHECK-NEXT: [[M:%.*]] = mul i32 [[X]], [[Y]]1639; CHECK-NEXT: call void @use(i32 [[M]])1640; CHECK-NEXT: [[R:%.*]] = or disjoint i32 [[M]], [[X]]1641; CHECK-NEXT: ret i32 [[R]]1642;1643 %x = and i32 %p1, 71644 %y = shl i32 %p2, 31645 %m = mul i32 %x, %y1646 call void @use(i32 %m)1647 %r = or i32 %m, %x1648 ret i32 %r1649}1650 1651; negative test - probably not good to create an extra mul1652 1653define i32 @mul_no_common_bits_const_op_uses(i32 %p) {1654; CHECK-LABEL: @mul_no_common_bits_const_op_uses(1655; CHECK-NEXT: [[X:%.*]] = and i32 [[P:%.*]], 71656; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[X]], 241657; CHECK-NEXT: call void @use(i32 [[M]])1658; CHECK-NEXT: [[R:%.*]] = or disjoint i32 [[M]], [[X]]1659; CHECK-NEXT: ret i32 [[R]]1660;1661 %x = and i32 %p, 71662 %m = mul i32 %x, 241663 call void @use(i32 %m)1664 %r = or i32 %m, %x1665 ret i32 %r1666}1667 1668; negative test - %x and %m may have set 3rd bit1669 1670define i32 @mul_common_bits(i32 %p) {1671; CHECK-LABEL: @mul_common_bits(1672; CHECK-NEXT: [[X:%.*]] = and i32 [[P:%.*]], 71673; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[X]], 121674; CHECK-NEXT: [[R:%.*]] = or i32 [[M]], [[X]]1675; CHECK-NEXT: ret i32 [[R]]1676;1677 %x = and i32 %p, 71678 %m = mul i32 %x, 121679 %r = or i32 %m, %x1680 ret i32 %r1681}1682 1683define <4 x i1> @and_or_not_or_logical_vec(<4 x i32> %ap, <4 x i32> %bp) {1684; CHECK-LABEL: @and_or_not_or_logical_vec(1685; CHECK-NEXT: [[A:%.*]] = icmp ne <4 x i32> [[AP:%.*]], zeroinitializer1686; CHECK-NEXT: ret <4 x i1> [[A]]1687;1688 %A = icmp eq <4 x i32> %ap, zeroinitializer1689 %B = icmp eq <4 x i32> %bp, zeroinitializer1690 %V = xor <4 x i1> %A, <i1 true, i1 true, i1 true, i1 true>1691 %X = select <4 x i1> %B, <4 x i1> %V, <4 x i1> zeroinitializer1692 %W = or <4 x i1> %B, %A1693 %Y = xor <4 x i1> %W, <i1 true, i1 true, i1 true, i1 true>1694 %Z = or <4 x i1> %X, %Y1695 ret <4 x i1> %Z1696}1697 1698; Make sure SimplifyDemandedBits drops the disjoint flag.1699define i8 @drop_disjoint(i8 %x) {1700; CHECK-LABEL: @drop_disjoint(1701; CHECK-NEXT: [[B:%.*]] = or i8 [[X:%.*]], 11702; CHECK-NEXT: ret i8 [[B]]1703;1704 %a = and i8 %x, -21705 %b = or disjoint i8 %a, 11706 ret i8 %b1707}1708 1709; Make sure we drop disjoint when combining the Ors.1710define i32 @assoc_cast_assoc_disjoint(i16 %x) {1711; CHECK-LABEL: @assoc_cast_assoc_disjoint(1712; CHECK-NEXT: [[B:%.*]] = zext i16 [[X:%.*]] to i321713; CHECK-NEXT: [[C:%.*]] = or i32 [[B]], 655371714; CHECK-NEXT: ret i32 [[C]]1715;1716 %a = or i16 %x, 11717 %b = zext i16 %a to i321718 %c = or disjoint i32 %b, 655361719 ret i32 %c1720}1721 1722; (X & C1) | C2 -> X & (C1 | C2) iff (X & C2) == C21723define i32 @test_or_and_disjoint(i32 %a) {1724; CHECK-LABEL: @test_or_and_disjoint(1725; CHECK-NEXT: [[A0:%.*]] = and i32 [[A:%.*]], 241726; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A0]], 81727; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]1728; CHECK: if.then:1729; CHECK-NEXT: [[A2:%.*]] = and i32 [[A]], 151730; CHECK-NEXT: ret i32 [[A2]]1731; CHECK: if.else:1732; CHECK-NEXT: ret i32 01733;1734 %a0 = and i32 %a, 241735 %cmp = icmp eq i32 %a0, 81736 br i1 %cmp, label %if.then, label %if.else1737if.then:1738 %a1 = and i32 %a, 71739 %a2 = or i32 %a1, 81740 ret i32 %a21741if.else:1742 ret i32 01743}1744 1745define i32 @test_or_and_mixed(i32 %a) {1746; CHECK-LABEL: @test_or_and_mixed(1747; CHECK-NEXT: [[A0:%.*]] = and i32 [[A:%.*]], 271748; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A0]], 111749; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]1750; CHECK: if.then:1751; CHECK-NEXT: [[A2:%.*]] = and i32 [[A]], 151752; CHECK-NEXT: ret i32 [[A2]]1753; CHECK: if.else:1754; CHECK-NEXT: ret i32 01755;1756 %a0 = and i32 %a, 271757 %cmp = icmp eq i32 %a0, 111758 br i1 %cmp, label %if.then, label %if.else1759if.then:1760 %a1 = and i32 %a, 71761 %a2 = or i32 %a1, 111762 ret i32 %a21763if.else:1764 ret i32 01765}1766 1767; Negative tests1768 1769define i32 @test_or_and_disjoint_fail(i32 %a) {1770; CHECK-LABEL: @test_or_and_disjoint_fail(1771; CHECK-NEXT: [[A0:%.*]] = and i32 [[A:%.*]], 241772; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A0]], 161773; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]1774; CHECK: if.then:1775; CHECK-NEXT: [[A1:%.*]] = and i32 [[A]], 71776; CHECK-NEXT: [[A2:%.*]] = or disjoint i32 [[A1]], 81777; CHECK-NEXT: ret i32 [[A2]]1778; CHECK: if.else:1779; CHECK-NEXT: ret i32 01780;1781 %a0 = and i32 %a, 241782 %cmp = icmp eq i32 %a0, 161783 br i1 %cmp, label %if.then, label %if.else1784if.then:1785 %a1 = and i32 %a, 71786 %a2 = or i32 %a1, 81787 ret i32 %a21788if.else:1789 ret i32 01790}1791 1792define i32 @test_or_and_disjoint_multiuse(i32 %a) {1793; CHECK-LABEL: @test_or_and_disjoint_multiuse(1794; CHECK-NEXT: [[A0:%.*]] = and i32 [[A:%.*]], 241795; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A0]], 81796; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]1797; CHECK: if.then:1798; CHECK-NEXT: [[A1:%.*]] = and i32 [[A]], 71799; CHECK-NEXT: call void @use(i32 [[A1]])1800; CHECK-NEXT: [[A2:%.*]] = or disjoint i32 [[A1]], 81801; CHECK-NEXT: ret i32 [[A2]]1802; CHECK: if.else:1803; CHECK-NEXT: ret i32 01804;1805 %a0 = and i32 %a, 241806 %cmp = icmp eq i32 %a0, 81807 br i1 %cmp, label %if.then, label %if.else1808if.then:1809 %a1 = and i32 %a, 71810 call void @use(i32 %a1)1811 %a2 = or i32 %a1, 81812 ret i32 %a21813if.else:1814 ret i32 01815}1816 1817; Tests from PR765541818define i32 @test_or_and_xor_constant(i32 %x, i32 %y) {1819; CHECK-LABEL: @test_or_and_xor_constant(1820; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]1821; CHECK-NEXT: [[D:%.*]] = and i32 [[TMP1]], -21474836481822; CHECK-NEXT: ret i32 [[D]]1823;1824 %a = and i32 %x, -21474836481825 %b = xor i32 %a, -21474836481826 %c = and i32 %b, %y1827 %d = or i32 %c, %a1828 ret i32 %d1829}1830 1831define i32 @test_or_and_xor(i32 %a, i32 %b, i32 %c) {1832; CHECK-LABEL: @test_or_and_xor(1833; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]1834; CHECK-NEXT: [[OR:%.*]] = or i32 [[TMP1]], [[A:%.*]]1835; CHECK-NEXT: ret i32 [[OR]]1836;1837 %xor = xor i32 %a, %b1838 %and = and i32 %xor, %c1839 %or = or i32 %and, %a1840 ret i32 %or1841}1842 1843define i32 @test_or_and_xor_commuted1(i32 %a, i32 %b, i32 %c) {1844; CHECK-LABEL: @test_or_and_xor_commuted1(1845; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]1846; CHECK-NEXT: [[OR:%.*]] = or i32 [[TMP1]], [[A:%.*]]1847; CHECK-NEXT: ret i32 [[OR]]1848;1849 %xor = xor i32 %b, %a1850 %and = and i32 %xor, %c1851 %or = or i32 %and, %a1852 ret i32 %or1853}1854 1855define i32 @test_or_and_xor_commuted2(i32 %a, i32 %b, i32 %c) {1856; CHECK-LABEL: @test_or_and_xor_commuted2(1857; CHECK-NEXT: [[CC:%.*]] = mul i32 [[C:%.*]], [[C]]1858; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[CC]], [[B:%.*]]1859; CHECK-NEXT: [[OR:%.*]] = or i32 [[TMP1]], [[A:%.*]]1860; CHECK-NEXT: ret i32 [[OR]]1861;1862 %cc = mul i32 %c, %c1863 %xor = xor i32 %a, %b1864 %and = and i32 %cc, %xor1865 %or = or i32 %and, %a1866 ret i32 %or1867}1868 1869define i32 @test_or_and_xor_commuted3(i32 %a, i32 %b, i32 %c) {1870; CHECK-LABEL: @test_or_and_xor_commuted3(1871; CHECK-NEXT: [[AA:%.*]] = mul i32 [[A:%.*]], [[A]]1872; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]1873; CHECK-NEXT: [[OR:%.*]] = or i32 [[AA]], [[TMP1]]1874; CHECK-NEXT: ret i32 [[OR]]1875;1876 %aa = mul i32 %a, %a1877 %xor = xor i32 %aa, %b1878 %and = and i32 %xor, %c1879 %or = or i32 %aa, %and1880 ret i32 %or1881}1882 1883define i32 @test_or_and_xor_multiuse1(i32 %a, i32 %b, i32 %c) {1884; CHECK-LABEL: @test_or_and_xor_multiuse1(1885; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]1886; CHECK-NEXT: call void @use(i32 [[XOR]])1887; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B]], [[C:%.*]]1888; CHECK-NEXT: [[OR:%.*]] = or i32 [[TMP1]], [[A]]1889; CHECK-NEXT: ret i32 [[OR]]1890;1891 %xor = xor i32 %a, %b1892 call void @use(i32 %xor)1893 %and = and i32 %xor, %c1894 %or = or i32 %and, %a1895 ret i32 %or1896}1897 1898; Negative tests1899 1900define i32 @test_or_and_xor_mismatched_op(i32 %a, i32 %b, i32 %c, i32 %d) {1901; CHECK-LABEL: @test_or_and_xor_mismatched_op(1902; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]1903; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR]], [[C:%.*]]1904; CHECK-NEXT: [[OR:%.*]] = or i32 [[AND]], [[D:%.*]]1905; CHECK-NEXT: ret i32 [[OR]]1906;1907 %xor = xor i32 %a, %b1908 %and = and i32 %xor, %c1909 %or = or i32 %and, %d1910 ret i32 %or1911}1912 1913define i32 @test_or_and_xor_multiuse2(i32 %a, i32 %b, i32 %c) {1914; CHECK-LABEL: @test_or_and_xor_multiuse2(1915; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]1916; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR]], [[C:%.*]]1917; CHECK-NEXT: call void @use(i32 [[AND]])1918; CHECK-NEXT: [[OR:%.*]] = or i32 [[AND]], [[A]]1919; CHECK-NEXT: ret i32 [[OR]]1920;1921 %xor = xor i32 %a, %b1922 %and = and i32 %xor, %c1923 call void @use(i32 %and)1924 %or = or i32 %and, %a1925 ret i32 %or1926}1927 1928define i32 @test_or_add_xor(i32 %a, i32 %b, i32 %c) {1929; CHECK-LABEL: @test_or_add_xor(1930; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]1931; CHECK-NEXT: [[ADD:%.*]] = add i32 [[XOR]], [[C:%.*]]1932; CHECK-NEXT: [[OR:%.*]] = or i32 [[ADD]], [[A]]1933; CHECK-NEXT: ret i32 [[OR]]1934;1935 %xor = xor i32 %a, %b1936 %add = add i32 %xor, %c1937 %or = or i32 %add, %a1938 ret i32 %or1939}1940 1941define i32 @test_or_and_and_multiuse(i32 %a, i32 %b, i32 %c) {1942; CHECK-LABEL: @test_or_and_and_multiuse(1943; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]1944; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C:%.*]]1945; CHECK-NEXT: call void @use(i32 [[AND1]])1946; CHECK-NEXT: call void @use(i32 [[AND2]])1947; CHECK-NEXT: ret i32 [[A]]1948;1949 %and1 = and i32 %a, %b1950 %and2 = and i32 %and1, %c1951 call void @use(i32 %and1)1952 call void @use(i32 %and2)1953 %or = or i32 %and2, %a1954 ret i32 %or1955}1956 1957define i32 @or_xor_and(i32 %x, i32 %y, i32 %z) {1958; CHECK-LABEL: @or_xor_and(1959; CHECK-NEXT: [[OR1:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]1960; CHECK-NEXT: ret i32 [[OR1]]1961;1962 %and = and i32 %y, %z1963 %xor = xor i32 %x, %and1964 %or1 = or i32 %xor, %y1965 ret i32 %or11966}1967 1968define i32 @or_xor_and_uses1(i32 %x, i32 %y, i32 %z) {1969; CHECK-LABEL: @or_xor_and_uses1(1970; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[Z:%.*]]1971; CHECK-NEXT: call void @use(i32 [[AND]])1972; CHECK-NEXT: [[OR1:%.*]] = or i32 [[X:%.*]], [[Y]]1973; CHECK-NEXT: ret i32 [[OR1]]1974;1975 %and = and i32 %y, %z1976 call void @use(i32 %and)1977 %xor = xor i32 %x, %and1978 %or1 = or i32 %xor, %y1979 ret i32 %or11980}1981 1982define i32 @or_xor_and_uses2(i32 %x, i32 %y, i32 %z) {1983; CHECK-LABEL: @or_xor_and_uses2(1984; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[Z:%.*]]1985; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[AND]]1986; CHECK-NEXT: call void @use(i32 [[XOR]])1987; CHECK-NEXT: [[OR1:%.*]] = or i32 [[X]], [[Y]]1988; CHECK-NEXT: ret i32 [[OR1]]1989;1990 %and = and i32 %y, %z1991 %xor = xor i32 %x, %and1992 call void @use(i32 %xor)1993 %or1 = or i32 %xor, %y1994 ret i32 %or11995}1996 1997define i32 @or_xor_and_commuted1(i32 %x, i32 %y, i32 %z) {1998; CHECK-LABEL: @or_xor_and_commuted1(1999; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]2000; CHECK-NEXT: [[OR1:%.*]] = or i32 [[YY]], [[X:%.*]]2001; CHECK-NEXT: ret i32 [[OR1]]2002;2003 %yy = mul i32 %y, %y ; thwart complexity-based ordering2004 %and = and i32 %yy, %z2005 %xor = xor i32 %and, %x2006 %or1 = or i32 %yy, %xor2007 ret i32 %or12008}2009 2010define i32 @or_xor_and_commuted2(i32 %x, i32 %y, i32 %z) {2011; CHECK-LABEL: @or_xor_and_commuted2(2012; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]2013; CHECK-NEXT: [[XX:%.*]] = mul i32 [[X:%.*]], [[X]]2014; CHECK-NEXT: [[OR1:%.*]] = or i32 [[XX]], [[YY]]2015; CHECK-NEXT: ret i32 [[OR1]]2016;2017 %yy = mul i32 %y, %y ; thwart complexity-based ordering2018 %xx = mul i32 %x, %x ; thwart complexity-based ordering2019 %and = and i32 %yy, %z2020 %xor = xor i32 %xx, %and2021 %or1 = or i32 %xor, %yy2022 ret i32 %or12023}2024 2025define i32 @or_xor_and_commuted3(i32 %x, i32 %y, i32 %z) {2026; CHECK-LABEL: @or_xor_and_commuted3(2027; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]2028; CHECK-NEXT: [[OR1:%.*]] = or i32 [[X:%.*]], [[YY]]2029; CHECK-NEXT: ret i32 [[OR1]]2030;2031 %yy = mul i32 %y, %y ; thwart complexity-based ordering2032 %zz = mul i32 %z, %z ; thwart complexity-based ordering2033 %and = and i32 %zz, %yy2034 %xor = xor i32 %and, %x2035 %or1 = or i32 %xor, %yy2036 ret i32 %or12037}2038 2039define i1 @or_truncs(i8 %x) {2040; CHECK-LABEL: @or_truncs(2041; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 12042; CHECK-NEXT: [[OR1:%.*]] = icmp ne i8 [[TMP1]], 02043; CHECK-NEXT: ret i1 [[OR1]]2044;2045 %trunc1 = trunc i8 %x to i12046 %trunc2 = trunc i8 %x to i12047 %or1 = or i1 %trunc1, %trunc22048 ret i1 %or12049}2050 2051define i32 @or_zext_constant(i8 %a) {2052; CHECK-LABEL: @or_zext_constant(2053; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[A:%.*]], 12054; CHECK-NEXT: [[AND:%.*]] = zext i8 [[TMP1]] to i322055; CHECK-NEXT: ret i32 [[AND]]2056;2057 %zext = zext i8 %a to i322058 %or = or i32 %zext, 12059 ret i32 %or2060}2061 2062define i32 @or_zext_minus_constant(i8 %a) {2063; CHECK-LABEL: @or_zext_minus_constant(2064; CHECK-NEXT: [[OR:%.*]] = zext i8 [[TMP1:%.*]] to i322065; CHECK-NEXT: [[OR1:%.*]] = or i32 [[OR]], -92066; CHECK-NEXT: ret i32 [[OR1]]2067;2068 %zext = zext i8 %a to i322069 %or = or i32 %zext, -92070 ret i32 %or2071}2072 2073define i32 @or_zext_nneg_constant(i8 %a) {2074; CHECK-LABEL: @or_zext_nneg_constant(2075; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[A:%.*]], 92076; CHECK-NEXT: [[AND:%.*]] = zext nneg i8 [[TMP1]] to i322077; CHECK-NEXT: ret i32 [[AND]]2078;2079 %zext = zext nneg i8 %a to i322080 %or = or i32 %zext, 92081 ret i32 %or2082}2083 2084define <4 x i32> @or_zext_nneg_constant_splat(<4 x i8> %a) {2085; CHECK-LABEL: @or_zext_nneg_constant_splat(2086; CHECK-NEXT: [[TMP1:%.*]] = or <4 x i8> [[A:%.*]], splat (i8 9)2087; CHECK-NEXT: [[OR:%.*]] = zext nneg <4 x i8> [[TMP1]] to <4 x i32>2088; CHECK-NEXT: ret <4 x i32> [[OR]]2089;2090 %zext = zext nneg <4 x i8> %a to <4 x i32>2091 %or = or <4 x i32> %zext, splat (i32 9)2092 ret <4 x i32> %or2093}2094 2095define i32 @or_zext_nneg_minus_constant(i8 %a) {2096; CHECK-LABEL: @or_zext_nneg_minus_constant(2097; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[A:%.*]], -92098; CHECK-NEXT: [[ZEXT:%.*]] = sext i8 [[TMP1]] to i322099; CHECK-NEXT: ret i32 [[ZEXT]]2100;2101 %zext = zext nneg i8 %a to i322102 %or = or i32 %zext, -92103 ret i32 %or2104}2105 2106define <4 x i32> @or_zext_nneg_minus_constant_splat(<4 x i8> %a) {2107; CHECK-LABEL: @or_zext_nneg_minus_constant_splat(2108; CHECK-NEXT: [[TMP1:%.*]] = or <4 x i8> [[A:%.*]], splat (i8 -9)2109; CHECK-NEXT: [[OR:%.*]] = sext <4 x i8> [[TMP1]] to <4 x i32>2110; CHECK-NEXT: ret <4 x i32> [[OR]]2111;2112 %zext = zext nneg <4 x i8> %a to <4 x i32>2113 %or = or <4 x i32> %zext, splat (i32 -9)2114 ret <4 x i32> %or2115}2116 2117define i8 @or_positive_minus_non_positive_to_abs(i8 %a){2118; CHECK-LABEL: @or_positive_minus_non_positive_to_abs(2119; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.abs.i8(i8 [[A:%.*]], i1 false)2120; CHECK-NEXT: ret i8 [[TMP2]]2121;2122 %b = icmp sgt i8 %a, 02123 %mask = sext i1 %b to i82124 %neg = sub i8 0, %a2125 %mask_inv = xor i8 %mask, -12126 %c = and i8 %neg, %mask_inv2127 %d = and i8 %a, %mask2128 %or = or i8 %c, %d2129 ret i8 %or2130}2131 2132; TODO: Fold to smax https://alive2.llvm.org/ce/z/wDiDh22133define i8 @or_select_smax_neg_to_abs(i8 %a){2134; CHECK-LABEL: @or_select_smax_neg_to_abs(2135; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[A:%.*]], 02136; CHECK-NEXT: [[NEG:%.*]] = sub nsw i8 0, [[A]]2137; CHECK-NEXT: [[OR:%.*]] = select i1 [[SGT0]], i8 0, i8 [[NEG]]2138; CHECK-NEXT: ret i8 [[OR]]2139;2140 %sgt0 = icmp sgt i8 %a, 02141 %neg = sub nsw i8 0, %a2142 %sel = select i1 %sgt0, i8 0, i8 %neg2143 ret i8 %sel2144}2145 2146; TODO: Fold to abs https://alive2.llvm.org/ce/z/DybfHG2147define i8 @or_select_smax_smax_to_abs(i8 %a){2148; CHECK-LABEL: @or_select_smax_smax_to_abs(2149; CHECK-NEXT: [[NEG:%.*]] = sub nsw i8 0, [[A:%.*]]2150; CHECK-NEXT: [[SEL:%.*]] = call i8 @llvm.smax.i8(i8 [[NEG]], i8 0)2151; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[A]], i8 0)2152; CHECK-NEXT: [[OR:%.*]] = or i8 [[SEL]], [[MAX]]2153; CHECK-NEXT: ret i8 [[OR]]2154;2155 %neg = sub nsw i8 0, %a2156 %sel = call i8 @llvm.smax.i8(i8 %neg, i8 0)2157 %max = call i8 @llvm.smax.i8(i8 %a, i8 0)2158 %or = or i8 %sel, %max2159 ret i8 %or2160}2161 2162declare i8 @llvm.abs.i8(i8, i1)2163declare <2 x i8> @llvm.abs.v2i8(<2 x i8>, i1)2164 2165define <2 x i8> @or_sgt_select_smax_to_abs(<2 x i8> %a){2166; CHECK-LABEL: @or_sgt_select_smax_to_abs(2167; CHECK-NEXT: [[OR:%.*]] = call <2 x i8> @llvm.abs.v2i8(<2 x i8> [[A:%.*]], i1 false)2168; CHECK-NEXT: ret <2 x i8> [[OR]]2169;2170 %sgt0 = icmp sgt <2 x i8> %a, zeroinitializer2171 %neg = sub <2 x i8> zeroinitializer, %a2172 %sel = select <2 x i1> %sgt0, <2 x i8> zeroinitializer, <2 x i8> %neg2173 %max = call <2 x i8> @llvm.smax.v2i8(<2 x i8> %a, <2 x i8> zeroinitializer)2174 %or = or <2 x i8> %sel, %max2175 ret <2 x i8> %or2176}2177 2178define <2 x i8> @or_slt_select_smax_to_abs(<2 x i8> %a){2179; CHECK-LABEL: @or_slt_select_smax_to_abs(2180; CHECK-NEXT: [[OR:%.*]] = call <2 x i8> @llvm.abs.v2i8(<2 x i8> [[A:%.*]], i1 false)2181; CHECK-NEXT: ret <2 x i8> [[OR]]2182;2183 %slt0 = icmp slt <2 x i8> %a, zeroinitializer2184 %neg = sub <2 x i8> zeroinitializer, %a2185 %sel = select <2 x i1> %slt0, <2 x i8> %neg, <2 x i8> zeroinitializer2186 %max = call <2 x i8> @llvm.smax.v2i8(<2 x i8> %a, <2 x i8> zeroinitializer)2187 %or = or <2 x i8> %sel, %max2188 ret <2 x i8> %or2189}2190 2191; negative test - %d has multiple uses. %or is not folded to abs.2192 2193define <2 x i8> @or_select_smax_multi_uses(<2 x i8> %a){2194; CHECK-LABEL: @or_select_smax_multi_uses(2195; CHECK-NEXT: [[B:%.*]] = icmp sgt <2 x i8> [[A:%.*]], zeroinitializer2196; CHECK-NEXT: [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[A]]2197; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[B]], <2 x i8> zeroinitializer, <2 x i8> [[NEG]]2198; CHECK-NEXT: [[D:%.*]] = call <2 x i8> @llvm.smax.v2i8(<2 x i8> [[A]], <2 x i8> zeroinitializer)2199; CHECK-NEXT: [[OR1:%.*]] = or <2 x i8> [[C]], [[D]]2200; CHECK-NEXT: [[OR:%.*]] = add <2 x i8> [[OR1]], [[D]]2201; CHECK-NEXT: ret <2 x i8> [[OR]]2202;2203 %sgt0 = icmp sgt <2 x i8> %a, zeroinitializer2204 %neg = sub <2 x i8> zeroinitializer, %a2205 %sel = select <2 x i1> %sgt0, <2 x i8> zeroinitializer, <2 x i8> %neg2206 %max = call <2 x i8> @llvm.smax.v2i8(<2 x i8> %a, <2 x i8> zeroinitializer)2207 %or = or <2 x i8> %sel, %max2208 %add = add <2 x i8> %or, %max2209 ret <2 x i8> %add2210}2211