brintos

brintos / llvm-project-archived public Read only

0
0
Text · 182.3 KiB · db117aa Raw
5424 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; PR18225 6target datalayout = "e-p:64:64-p1:16:16-p2:32:32:32-p3:64:64:64"7 8define i1 @test5(i1 %C) {9; CHECK-LABEL: define i1 @test5(10; CHECK-SAME: i1 [[C:%.*]]) {11; CHECK-NEXT:    [[NOT_C:%.*]] = xor i1 [[C]], true12; CHECK-NEXT:    ret i1 [[NOT_C]]13;14  %V = select i1 %C, i1 false, i1 true15  ret i1 %V16}17 18define i32 @test6(i1 %C) {19; CHECK-LABEL: define i32 @test6(20; CHECK-SAME: i1 [[C:%.*]]) {21; CHECK-NEXT:    [[V:%.*]] = zext i1 [[C]] to i3222; CHECK-NEXT:    ret i32 [[V]]23;24  %V = select i1 %C, i32 1, i32 025  ret i32 %V26}27 28define i1 @trueval_is_true(i1 %C, i1 %X) {29; CHECK-LABEL: define i1 @trueval_is_true(30; CHECK-SAME: i1 [[C:%.*]], i1 [[X:%.*]]) {31; CHECK-NEXT:    [[R:%.*]] = select i1 [[C]], i1 true, i1 [[X]]32; CHECK-NEXT:    ret i1 [[R]]33;34  %R = select i1 %C, i1 true, i1 %X35  ret i1 %R36}37 38define <2 x i1> @trueval_is_true_vec(<2 x i1> %C, <2 x i1> %X) {39; CHECK-LABEL: define <2 x i1> @trueval_is_true_vec(40; CHECK-SAME: <2 x i1> [[C:%.*]], <2 x i1> [[X:%.*]]) {41; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[C]], <2 x i1> splat (i1 true), <2 x i1> [[X]]42; CHECK-NEXT:    ret <2 x i1> [[R]]43;44  %R = select <2 x i1> %C, <2 x i1> <i1 true, i1 true>, <2 x i1> %X45  ret <2 x i1> %R46}47 48define <2 x i1> @trueval_is_true_vec_poison_elt(<2 x i1> %C, <2 x i1> %X) {49; CHECK-LABEL: define <2 x i1> @trueval_is_true_vec_poison_elt(50; CHECK-SAME: <2 x i1> [[C:%.*]], <2 x i1> [[X:%.*]]) {51; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[C]], <2 x i1> <i1 poison, i1 true>, <2 x i1> [[X]]52; CHECK-NEXT:    ret <2 x i1> [[R]]53;54  %R = select <2 x i1> %C, <2 x i1> <i1 poison, i1 true>, <2 x i1> %X55  ret <2 x i1> %R56}57 58define i1 @test8(i1 %C, i1 %X) {59; CHECK-LABEL: define i1 @test8(60; CHECK-SAME: i1 [[C:%.*]], i1 [[X:%.*]]) {61; CHECK-NEXT:    [[R:%.*]] = select i1 [[C]], i1 [[X]], i1 false62; CHECK-NEXT:    ret i1 [[R]]63;64  %R = select i1 %C, i1 %X, i1 false65  ret i1 %R66}67 68define <2 x i1> @test8vec(<2 x i1> %C, <2 x i1> %X) {69; CHECK-LABEL: define <2 x i1> @test8vec(70; CHECK-SAME: <2 x i1> [[C:%.*]], <2 x i1> [[X:%.*]]) {71; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[C]], <2 x i1> [[X]], <2 x i1> zeroinitializer72; CHECK-NEXT:    ret <2 x i1> [[R]]73;74  %R = select <2 x i1> %C, <2 x i1> %X, <2 x i1> <i1 false, i1 false>75  ret <2 x i1> %R76}77 78define <vscale x 2 x i1> @test8vvec(<vscale x 2 x i1> %C, <vscale x 2 x i1> %X) {79; CHECK-LABEL: define <vscale x 2 x i1> @test8vvec(80; CHECK-SAME: <vscale x 2 x i1> [[C:%.*]], <vscale x 2 x i1> [[X:%.*]]) {81; CHECK-NEXT:    [[R:%.*]] = select <vscale x 2 x i1> [[C]], <vscale x 2 x i1> [[X]], <vscale x 2 x i1> zeroinitializer82; CHECK-NEXT:    ret <vscale x 2 x i1> [[R]]83;84  %R = select <vscale x 2 x i1> %C, <vscale x 2 x i1> %X, <vscale x 2 x i1> zeroinitializer85  ret <vscale x 2 x i1> %R86}87 88define i1 @test9(i1 %C, i1 %X) {89; CHECK-LABEL: define i1 @test9(90; CHECK-SAME: i1 [[C:%.*]], i1 [[X:%.*]]) {91; CHECK-NEXT:    [[NOT_C:%.*]] = xor i1 [[C]], true92; CHECK-NEXT:    [[R:%.*]] = select i1 [[NOT_C]], i1 [[X]], i1 false93; CHECK-NEXT:    ret i1 [[R]]94;95  %R = select i1 %C, i1 false, i1 %X96  ret i1 %R97}98 99define <2 x i1> @test9vec(<2 x i1> %C, <2 x i1> %X) {100; CHECK-LABEL: define <2 x i1> @test9vec(101; CHECK-SAME: <2 x i1> [[C:%.*]], <2 x i1> [[X:%.*]]) {102; CHECK-NEXT:    [[NOT_C:%.*]] = xor <2 x i1> [[C]], splat (i1 true)103; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[NOT_C]], <2 x i1> [[X]], <2 x i1> zeroinitializer104; CHECK-NEXT:    ret <2 x i1> [[R]]105;106  %R = select <2 x i1> %C, <2 x i1> <i1 false, i1 false>, <2 x i1> %X107  ret <2 x i1> %R108}109 110define <vscale x 2 x i1> @test9vvec(<vscale x 2 x i1> %C, <vscale x 2 x i1> %X) {111; CHECK-LABEL: define <vscale x 2 x i1> @test9vvec(112; CHECK-SAME: <vscale x 2 x i1> [[C:%.*]], <vscale x 2 x i1> [[X:%.*]]) {113; CHECK-NEXT:    [[NOT_C:%.*]] = xor <vscale x 2 x i1> [[C]], splat (i1 true)114; CHECK-NEXT:    [[R:%.*]] = select <vscale x 2 x i1> [[NOT_C]], <vscale x 2 x i1> [[X]], <vscale x 2 x i1> zeroinitializer115; CHECK-NEXT:    ret <vscale x 2 x i1> [[R]]116;117  %R = select <vscale x 2 x i1> %C, <vscale x 2 x i1> zeroinitializer, <vscale x 2 x i1> %X118  ret <vscale x 2 x i1> %R119}120 121define i1 @test10(i1 %C, i1 %X) {122; CHECK-LABEL: define i1 @test10(123; CHECK-SAME: i1 [[C:%.*]], i1 [[X:%.*]]) {124; CHECK-NEXT:    [[NOT_C:%.*]] = xor i1 [[C]], true125; CHECK-NEXT:    [[R:%.*]] = select i1 [[NOT_C]], i1 true, i1 [[X]]126; CHECK-NEXT:    ret i1 [[R]]127;128  %R = select i1 %C, i1 %X, i1 true129  ret i1 %R130}131 132define <2 x i1> @test10vec(<2 x i1> %C, <2 x i1> %X) {133; CHECK-LABEL: define <2 x i1> @test10vec(134; CHECK-SAME: <2 x i1> [[C:%.*]], <2 x i1> [[X:%.*]]) {135; CHECK-NEXT:    [[NOT_C:%.*]] = xor <2 x i1> [[C]], splat (i1 true)136; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[NOT_C]], <2 x i1> splat (i1 true), <2 x i1> [[X]]137; CHECK-NEXT:    ret <2 x i1> [[R]]138;139  %R = select <2 x i1> %C, <2 x i1> %X, <2 x i1> <i1 true, i1 true>140  ret <2 x i1> %R141}142 143define i1 @test23(i1 %a, i1 %b) {144; CHECK-LABEL: define i1 @test23(145; CHECK-SAME: i1 [[A:%.*]], i1 [[B:%.*]]) {146; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i1 [[B]], i1 false147; CHECK-NEXT:    ret i1 [[C]]148;149  %c = select i1 %a, i1 %b, i1 %a150  ret i1 %c151}152 153define <2 x i1> @test23vec(<2 x i1> %a, <2 x i1> %b) {154; CHECK-LABEL: define <2 x i1> @test23vec(155; CHECK-SAME: <2 x i1> [[A:%.*]], <2 x i1> [[B:%.*]]) {156; CHECK-NEXT:    [[C:%.*]] = select <2 x i1> [[A]], <2 x i1> [[B]], <2 x i1> zeroinitializer157; CHECK-NEXT:    ret <2 x i1> [[C]]158;159  %c = select <2 x i1> %a, <2 x i1> %b, <2 x i1> %a160  ret <2 x i1> %c161}162 163define i1 @test24(i1 %a, i1 %b) {164; CHECK-LABEL: define i1 @test24(165; CHECK-SAME: i1 [[A:%.*]], i1 [[B:%.*]]) {166; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i1 true, i1 [[B]]167; CHECK-NEXT:    ret i1 [[C]]168;169  %c = select i1 %a, i1 %a, i1 %b170  ret i1 %c171}172 173define <2 x i1> @test24vec(<2 x i1> %a, <2 x i1> %b) {174; CHECK-LABEL: define <2 x i1> @test24vec(175; CHECK-SAME: <2 x i1> [[A:%.*]], <2 x i1> [[B:%.*]]) {176; CHECK-NEXT:    [[C:%.*]] = select <2 x i1> [[A]], <2 x i1> splat (i1 true), <2 x i1> [[B]]177; CHECK-NEXT:    ret <2 x i1> [[C]]178;179  %c = select <2 x i1> %a, <2 x i1> %a, <2 x i1> %b180  ret <2 x i1> %c181}182 183define i1 @test62(i1 %A, i1 %B) {184; CHECK-LABEL: define i1 @test62(185; CHECK-SAME: i1 [[A:%.*]], i1 [[B:%.*]]) {186; CHECK-NEXT:    [[NOT_A:%.*]] = xor i1 [[A]], true187; CHECK-NEXT:    [[C:%.*]] = select i1 [[NOT_A]], i1 [[B]], i1 false188; CHECK-NEXT:    ret i1 [[C]]189;190  %not = xor i1 %A, true191  %C = select i1 %A, i1 %not, i1 %B192  ret i1 %C193}194 195define <2 x i1> @test62vec(<2 x i1> %A, <2 x i1> %B) {196; CHECK-LABEL: define <2 x i1> @test62vec(197; CHECK-SAME: <2 x i1> [[A:%.*]], <2 x i1> [[B:%.*]]) {198; CHECK-NEXT:    [[NOT_A:%.*]] = xor <2 x i1> [[A]], splat (i1 true)199; CHECK-NEXT:    [[C:%.*]] = select <2 x i1> [[NOT_A]], <2 x i1> [[B]], <2 x i1> zeroinitializer200; CHECK-NEXT:    ret <2 x i1> [[C]]201;202  %not = xor <2 x i1> %A, <i1 true, i1 true>203  %C = select <2 x i1> %A, <2 x i1> %not, <2 x i1> %B204  ret <2 x i1> %C205}206 207define i1 @test63(i1 %A, i1 %B) {208; CHECK-LABEL: define i1 @test63(209; CHECK-SAME: i1 [[A:%.*]], i1 [[B:%.*]]) {210; CHECK-NEXT:    [[NOT_A:%.*]] = xor i1 [[A]], true211; CHECK-NEXT:    [[C:%.*]] = select i1 [[NOT_A]], i1 true, i1 [[B]]212; CHECK-NEXT:    ret i1 [[C]]213;214  %not = xor i1 %A, true215  %C = select i1 %A, i1 %B, i1 %not216  ret i1 %C217}218 219define <2 x i1> @test63vec(<2 x i1> %A, <2 x i1> %B) {220; CHECK-LABEL: define <2 x i1> @test63vec(221; CHECK-SAME: <2 x i1> [[A:%.*]], <2 x i1> [[B:%.*]]) {222; CHECK-NEXT:    [[NOT_A:%.*]] = xor <2 x i1> [[A]], splat (i1 true)223; CHECK-NEXT:    [[C:%.*]] = select <2 x i1> [[NOT_A]], <2 x i1> splat (i1 true), <2 x i1> [[B]]224; CHECK-NEXT:    ret <2 x i1> [[C]]225;226  %not = xor <2 x i1> %A, <i1 true, i1 true>227  %C = select <2 x i1> %A, <2 x i1> %B, <2 x i1> %not228  ret <2 x i1> %C229}230 231define i32 @test11(i32 %a) {232; CHECK-LABEL: define i32 @test11(233; CHECK-SAME: i32 [[A:%.*]]) {234; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[A]], 0235; CHECK-NEXT:    [[R:%.*]] = zext i1 [[C]] to i32236; CHECK-NEXT:    ret i32 [[R]]237;238  %C = icmp eq i32 %a, 0239  %R = select i1 %C, i32 0, i32 1240  ret i32 %R241}242 243define i32 @test12(i1 %cond, i32 %a) {244; CHECK-LABEL: define i32 @test12(245; CHECK-SAME: i1 [[COND:%.*]], i32 [[A:%.*]]) {246; CHECK-NEXT:    [[B:%.*]] = zext i1 [[COND]] to i32247; CHECK-NEXT:    [[C:%.*]] = or i32 [[A]], [[B]]248; CHECK-NEXT:    ret i32 [[C]]249;250  %b = or i32 %a, 1251  %c = select i1 %cond, i32 %b, i32 %a252  ret i32 %c253}254 255define <2 x i32> @test12vec(<2 x i1> %cond, <2 x i32> %a) {256; CHECK-LABEL: define <2 x i32> @test12vec(257; CHECK-SAME: <2 x i1> [[COND:%.*]], <2 x i32> [[A:%.*]]) {258; CHECK-NEXT:    [[B:%.*]] = zext <2 x i1> [[COND]] to <2 x i32>259; CHECK-NEXT:    [[C:%.*]] = or <2 x i32> [[A]], [[B]]260; CHECK-NEXT:    ret <2 x i32> [[C]]261;262  %b = or <2 x i32> %a, <i32 1, i32 1>263  %c = select <2 x i1> %cond, <2 x i32> %b, <2 x i32> %a264  ret <2 x i32> %c265}266 267define i32 @test12a(i1 %cond, i32 %a) {268; CHECK-LABEL: define i32 @test12a(269; CHECK-SAME: i1 [[COND:%.*]], i32 [[A:%.*]]) {270; CHECK-NEXT:    [[B:%.*]] = zext i1 [[COND]] to i32271; CHECK-NEXT:    [[C:%.*]] = ashr i32 [[A]], [[B]]272; CHECK-NEXT:    ret i32 [[C]]273;274  %b = ashr i32 %a, 1275  %c = select i1 %cond, i32 %b, i32 %a276  ret i32 %c277}278 279define <2 x i32> @test12avec(<2 x i1> %cond, <2 x i32> %a) {280; CHECK-LABEL: define <2 x i32> @test12avec(281; CHECK-SAME: <2 x i1> [[COND:%.*]], <2 x i32> [[A:%.*]]) {282; CHECK-NEXT:    [[B:%.*]] = zext <2 x i1> [[COND]] to <2 x i32>283; CHECK-NEXT:    [[C:%.*]] = ashr <2 x i32> [[A]], [[B]]284; CHECK-NEXT:    ret <2 x i32> [[C]]285;286  %b = ashr <2 x i32> %a, <i32 1, i32 1>287  %c = select <2 x i1> %cond, <2 x i32> %b, <2 x i32> %a288  ret <2 x i32> %c289}290 291define i32 @test12b(i1 %cond, i32 %a) {292; CHECK-LABEL: define i32 @test12b(293; CHECK-SAME: i1 [[COND:%.*]], i32 [[A:%.*]]) {294; CHECK-NEXT:    [[NOT_COND:%.*]] = xor i1 [[COND]], true295; CHECK-NEXT:    [[B:%.*]] = zext i1 [[NOT_COND]] to i32296; CHECK-NEXT:    [[D:%.*]] = ashr i32 [[A]], [[B]]297; CHECK-NEXT:    ret i32 [[D]]298;299  %b = ashr i32 %a, 1300  %d = select i1 %cond, i32 %a, i32 %b301  ret i32 %d302}303 304define <2 x i32> @test12bvec(<2 x i1> %cond, <2 x i32> %a) {305; CHECK-LABEL: define <2 x i32> @test12bvec(306; CHECK-SAME: <2 x i1> [[COND:%.*]], <2 x i32> [[A:%.*]]) {307; CHECK-NEXT:    [[NOT_COND:%.*]] = xor <2 x i1> [[COND]], splat (i1 true)308; CHECK-NEXT:    [[B:%.*]] = zext <2 x i1> [[NOT_COND]] to <2 x i32>309; CHECK-NEXT:    [[D:%.*]] = ashr <2 x i32> [[A]], [[B]]310; CHECK-NEXT:    ret <2 x i32> [[D]]311;312  %b = ashr <2 x i32> %a, <i32 1, i32 1>313  %d = select <2 x i1> %cond, <2 x i32> %a, <2 x i32> %b314  ret <2 x i32> %d315}316 317define i32 @test13(i32 %a, i32 %b) {318; CHECK-LABEL: define i32 @test13(319; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {320; CHECK-NEXT:    ret i32 [[B]]321;322  %C = icmp eq i32 %a, %b323  %V = select i1 %C, i32 %a, i32 %b324  ret i32 %V325}326 327define i32 @test13a(i32 %a, i32 %b) {328; CHECK-LABEL: define i32 @test13a(329; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {330; CHECK-NEXT:    ret i32 [[A]]331;332  %C = icmp ne i32 %a, %b333  %V = select i1 %C, i32 %a, i32 %b334  ret i32 %V335}336 337define i32 @test13b(i32 %a, i32 %b) {338; CHECK-LABEL: define i32 @test13b(339; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {340; CHECK-NEXT:    ret i32 [[A]]341;342  %C = icmp eq i32 %a, %b343  %V = select i1 %C, i32 %b, i32 %a344  ret i32 %V345}346 347define i1 @test14a(i1 %C, i32 %X) {348; CHECK-LABEL: define i1 @test14a(349; CHECK-SAME: i1 [[C:%.*]], i32 [[X:%.*]]) {350; CHECK-NEXT:    [[R1:%.*]] = icmp slt i32 [[X]], 1351; CHECK-NEXT:    [[NOT_C:%.*]] = xor i1 [[C]], true352; CHECK-NEXT:    [[R:%.*]] = select i1 [[NOT_C]], i1 true, i1 [[R1]]353; CHECK-NEXT:    ret i1 [[R]]354;355  %V = select i1 %C, i32 %X, i32 0356  ; (X < 1) | !C357  %R = icmp slt i32 %V, 1358  ret i1 %R359}360 361define i1 @test14b(i1 %C, i32 %X) {362; CHECK-LABEL: define i1 @test14b(363; CHECK-SAME: i1 [[C:%.*]], i32 [[X:%.*]]) {364; CHECK-NEXT:    [[R1:%.*]] = icmp slt i32 [[X]], 1365; CHECK-NEXT:    [[R:%.*]] = select i1 [[C]], i1 true, i1 [[R1]]366; CHECK-NEXT:    ret i1 [[R]]367;368  %V = select i1 %C, i32 0, i32 %X369  ; (X < 1) | C370  %R = icmp slt i32 %V, 1371  ret i1 %R372}373 374define i32 @test16(i1 %C, ptr %P) {375; CHECK-LABEL: define i32 @test16(376; CHECK-SAME: i1 [[C:%.*]], ptr [[P:%.*]]) {377; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P]], align 4378; CHECK-NEXT:    ret i32 [[V]]379;380  %P2 = select i1 %C, ptr %P, ptr null381  %V = load i32, ptr %P2382  ret i32 %V383}384 385;; It may be legal to load from a null address in a non-zero address space386define i32 @test16_neg(i1 %C, ptr addrspace(1) %P) {387; CHECK-LABEL: define i32 @test16_neg(388; CHECK-SAME: i1 [[C:%.*]], ptr addrspace(1) [[P:%.*]]) {389; CHECK-NEXT:    [[P2:%.*]] = select i1 [[C]], ptr addrspace(1) [[P]], ptr addrspace(1) null390; CHECK-NEXT:    [[V:%.*]] = load i32, ptr addrspace(1) [[P2]], align 4391; CHECK-NEXT:    ret i32 [[V]]392;393  %P2 = select i1 %C, ptr addrspace(1) %P, ptr addrspace(1) null394  %V = load i32, ptr addrspace(1) %P2395  ret i32 %V396}397 398define i32 @test16_neg2(i1 %C, ptr addrspace(1) %P) {399; CHECK-LABEL: define i32 @test16_neg2(400; CHECK-SAME: i1 [[C:%.*]], ptr addrspace(1) [[P:%.*]]) {401; CHECK-NEXT:    [[P2:%.*]] = select i1 [[C]], ptr addrspace(1) null, ptr addrspace(1) [[P]]402; CHECK-NEXT:    [[V:%.*]] = load i32, ptr addrspace(1) [[P2]], align 4403; CHECK-NEXT:    ret i32 [[V]]404;405  %P2 = select i1 %C, ptr addrspace(1) null, ptr addrspace(1) %P406  %V = load i32, ptr addrspace(1) %P2407  ret i32 %V408}409 410;; It may be legal to load from a null address with null pointer valid attribute.411define i32 @test16_no_null_opt(i1 %C, ptr %P) #0 {412; CHECK-LABEL: define i32 @test16_no_null_opt(413; CHECK-SAME: i1 [[C:%.*]], ptr [[P:%.*]]) #[[ATTR0:[0-9]+]] {414; CHECK-NEXT:    [[P2:%.*]] = select i1 [[C]], ptr [[P]], ptr null415; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P2]], align 4416; CHECK-NEXT:    ret i32 [[V]]417;418  %P2 = select i1 %C, ptr %P, ptr null419  %V = load i32, ptr %P2420  ret i32 %V421}422 423define i32 @test16_no_null_opt_2(i1 %C, ptr %P) #0 {424; CHECK-LABEL: define i32 @test16_no_null_opt_2(425; CHECK-SAME: i1 [[C:%.*]], ptr [[P:%.*]]) #[[ATTR0]] {426; CHECK-NEXT:    [[P2:%.*]] = select i1 [[C]], ptr null, ptr [[P]]427; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P2]], align 4428; CHECK-NEXT:    ret i32 [[V]]429;430  %P2 = select i1 %C, ptr null, ptr %P431  %V = load i32, ptr %P2432  ret i32 %V433}434 435attributes #0 = { null_pointer_is_valid }436 437define i1 @test17(ptr %X, i1 %C) {438; CHECK-LABEL: define i1 @test17(439; CHECK-SAME: ptr [[X:%.*]], i1 [[C:%.*]]) {440; CHECK-NEXT:    [[RV1:%.*]] = icmp eq ptr [[X]], null441; CHECK-NEXT:    [[NOT_C:%.*]] = xor i1 [[C]], true442; CHECK-NEXT:    [[RV:%.*]] = select i1 [[NOT_C]], i1 true, i1 [[RV1]]443; CHECK-NEXT:    ret i1 [[RV]]444;445  %R = select i1 %C, ptr %X, ptr null446  %RV = icmp eq ptr %R, null447  ret i1 %RV448}449 450define i32 @test18(i32 %X, i32 %Y, i1 %C) {451; CHECK-LABEL: define i32 @test18(452; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i1 [[C:%.*]]) {453; CHECK-NEXT:    [[V:%.*]] = sdiv i32 [[Y]], [[X]]454; CHECK-NEXT:    ret i32 [[V]]455;456  %R = select i1 %C, i32 %X, i32 0457  %V = sdiv i32 %Y, %R458  ret i32 %V459}460 461define i32 @test19(i32 %x) {462; CHECK-LABEL: define i32 @test19(463; CHECK-SAME: i32 [[X:%.*]]) {464; CHECK-NEXT:    [[X_LOBIT:%.*]] = ashr i32 [[X]], 31465; CHECK-NEXT:    ret i32 [[X_LOBIT]]466;467  %t = icmp ugt i32 %x, 2147483647468  %retval = select i1 %t, i32 -1, i32 0469  ret i32 %retval470}471 472define i32 @test20(i32 %x) {473; CHECK-LABEL: define i32 @test20(474; CHECK-SAME: i32 [[X:%.*]]) {475; CHECK-NEXT:    [[X_LOBIT:%.*]] = ashr i32 [[X]], 31476; CHECK-NEXT:    ret i32 [[X_LOBIT]]477;478  %t = icmp slt i32 %x, 0479  %retval = select i1 %t, i32 -1, i32 0480  ret i32 %retval481}482 483define i64 @test21(i32 %x) {484; CHECK-LABEL: define i64 @test21(485; CHECK-SAME: i32 [[X:%.*]]) {486; CHECK-NEXT:    [[X_LOBIT:%.*]] = ashr i32 [[X]], 31487; CHECK-NEXT:    [[RETVAL:%.*]] = sext i32 [[X_LOBIT]] to i64488; CHECK-NEXT:    ret i64 [[RETVAL]]489;490  %t = icmp slt i32 %x, 0491  %retval = select i1 %t, i64 -1, i64 0492  ret i64 %retval493}494 495define i16 @test22(i32 %x) {496; CHECK-LABEL: define i16 @test22(497; CHECK-SAME: i32 [[X:%.*]]) {498; CHECK-NEXT:    [[X_LOBIT:%.*]] = ashr i32 [[X]], 31499; CHECK-NEXT:    [[RETVAL:%.*]] = trunc nsw i32 [[X_LOBIT]] to i16500; CHECK-NEXT:    ret i16 [[RETVAL]]501;502  %t = icmp slt i32 %x, 0503  %retval = select i1 %t, i16 -1, i16 0504  ret i16 %retval505}506 507define i32 @test25(i1 %c)  {508; CHECK-LABEL: define i32 @test25(509; CHECK-SAME: i1 [[C:%.*]]) {510; CHECK-NEXT:  [[ENTRY:.*]]:511; CHECK-NEXT:    br i1 [[C]], label %[[JUMP:.*]], label %[[RET:.*]]512; CHECK:       [[JUMP]]:513; CHECK-NEXT:    br label %[[RET]]514; CHECK:       [[RET]]:515; CHECK-NEXT:    [[B:%.*]] = phi i32 [ 10, %[[JUMP]] ], [ 20, %[[ENTRY]] ]516; CHECK-NEXT:    ret i32 [[B]]517;518entry:519  br i1 %c, label %jump, label %ret520jump:521  br label %ret522ret:523  %a = phi i1 [true, %jump], [false, %entry]524  %b = select i1 %a, i32 10, i32 20525  ret i32 %b526}527 528define i32 @test26(i1 %cond)  {529; CHECK-LABEL: define i32 @test26(530; CHECK-SAME: i1 [[COND:%.*]]) {531; CHECK-NEXT:  [[ENTRY:.*]]:532; CHECK-NEXT:    br i1 [[COND]], label %[[JUMP:.*]], label %[[RET:.*]]533; CHECK:       [[JUMP]]:534; CHECK-NEXT:    br label %[[RET]]535; CHECK:       [[RET]]:536; CHECK-NEXT:    [[B:%.*]] = phi i32 [ 20, %[[ENTRY]] ], [ 10, %[[JUMP]] ]537; CHECK-NEXT:    ret i32 [[B]]538;539entry:540  br i1 %cond, label %jump, label %ret541jump:542  %c = or i1 false, false543  br label %ret544ret:545  %a = phi i1 [true, %entry], [%c, %jump]546  %b = select i1 %a, i32 20, i32 10547  ret i32 %b548}549 550define i32 @test26_logical(i1 %cond)  {551; CHECK-LABEL: define i32 @test26_logical(552; CHECK-SAME: i1 [[COND:%.*]]) {553; CHECK-NEXT:  [[ENTRY:.*]]:554; CHECK-NEXT:    br i1 [[COND]], label %[[JUMP:.*]], label %[[RET:.*]]555; CHECK:       [[JUMP]]:556; CHECK-NEXT:    br label %[[RET]]557; CHECK:       [[RET]]:558; CHECK-NEXT:    [[B:%.*]] = phi i32 [ 20, %[[ENTRY]] ], [ 10, %[[JUMP]] ]559; CHECK-NEXT:    ret i32 [[B]]560;561entry:562  br i1 %cond, label %jump, label %ret563jump:564  %c = select i1 false, i1 true, i1 false565  br label %ret566ret:567  %a = phi i1 [true, %entry], [%c, %jump]568  %b = select i1 %a, i32 20, i32 10569  ret i32 %b570}571 572define i32 @test27(i1 %c, i32 %A, i32 %B)  {573; CHECK-LABEL: define i32 @test27(574; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {575; CHECK-NEXT:  [[ENTRY:.*]]:576; CHECK-NEXT:    br i1 [[C]], label %[[JUMP:.*]], label %[[RET:.*]]577; CHECK:       [[JUMP]]:578; CHECK-NEXT:    br label %[[RET]]579; CHECK:       [[RET]]:580; CHECK-NEXT:    [[S:%.*]] = phi i32 [ [[A]], %[[JUMP]] ], [ [[B]], %[[ENTRY]] ]581; CHECK-NEXT:    ret i32 [[S]]582;583entry:584  br i1 %c, label %jump, label %ret585jump:586  br label %ret587ret:588  %p = phi i1 [true, %jump], [false, %entry]589  %s = select i1 %p, i32 %A, i32 %B590  ret i32 %s591}592 593define i32 @test28(i1 %cond, i32 %A, i32 %B)  {594; CHECK-LABEL: define i32 @test28(595; CHECK-SAME: i1 [[COND:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {596; CHECK-NEXT:  [[ENTRY:.*]]:597; CHECK-NEXT:    br i1 [[COND]], label %[[JUMP:.*]], label %[[RET:.*]]598; CHECK:       [[JUMP]]:599; CHECK-NEXT:    br label %[[RET]]600; CHECK:       [[RET]]:601; CHECK-NEXT:    [[S:%.*]] = phi i32 [ [[A]], %[[JUMP]] ], [ [[B]], %[[ENTRY]] ]602; CHECK-NEXT:    ret i32 [[S]]603;604entry:605  br i1 %cond, label %jump, label %ret606jump:607  br label %ret608ret:609  %c = phi i32 [%A, %jump], [%B, %entry]610  %p = phi i1 [true, %jump], [false, %entry]611  %s = select i1 %p, i32 %A, i32 %c612  ret i32 %s613}614 615define i32 @test29(i1 %cond, i32 %A, i32 %B)  {616; CHECK-LABEL: define i32 @test29(617; CHECK-SAME: i1 [[COND:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {618; CHECK-NEXT:  [[ENTRY:.*]]:619; CHECK-NEXT:    br i1 [[COND]], label %[[JUMP:.*]], label %[[RET:.*]]620; CHECK:       [[JUMP]]:621; CHECK-NEXT:    br label %[[RET]]622; CHECK:       [[RET]]:623; CHECK-NEXT:    [[S:%.*]] = phi i32 [ [[A]], %[[JUMP]] ], [ [[B]], %[[ENTRY]] ]624; CHECK-NEXT:    br label %[[NEXT:.*]]625; CHECK:       [[NEXT]]:626; CHECK-NEXT:    ret i32 [[S]]627;628entry:629  br i1 %cond, label %jump, label %ret630jump:631  br label %ret632ret:633  %c = phi i32 [%A, %jump], [%B, %entry]634  %p = phi i1 [true, %jump], [false, %entry]635  br label %next636 637next:638  %s = select i1 %p, i32 %A, i32 %c639  ret i32 %s640}641 642; SMAX(SMAX(x, y), x) -> SMAX(x, y)643define i32 @test30(i32 %x, i32 %y) {644; CHECK-LABEL: define i32 @test30(645; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {646; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.smax.i32(i32 [[X]], i32 [[Y]])647; CHECK-NEXT:    ret i32 [[COND]]648;649  %cmp = icmp sgt i32 %x, %y650  %cond = select i1 %cmp, i32 %x, i32 %y651  %cmp5 = icmp sgt i32 %cond, %x652  %retval = select i1 %cmp5, i32 %cond, i32 %x653  ret i32 %retval654}655 656; UMAX(UMAX(x, y), x) -> UMAX(x, y)657define i32 @test31(i32 %x, i32 %y) {658; CHECK-LABEL: define i32 @test31(659; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {660; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]])661; CHECK-NEXT:    ret i32 [[COND]]662;663  %cmp = icmp ugt i32 %x, %y664  %cond = select i1 %cmp, i32 %x, i32 %y665  %cmp5 = icmp ugt i32 %cond, %x666  %retval = select i1 %cmp5, i32 %cond, i32 %x667  ret i32 %retval668}669 670; SMIN(SMIN(x, y), x) -> SMIN(x, y)671define i32 @test32(i32 %x, i32 %y) {672; CHECK-LABEL: define i32 @test32(673; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {674; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.smin.i32(i32 [[X]], i32 [[Y]])675; CHECK-NEXT:    ret i32 [[COND]]676;677  %cmp = icmp sgt i32 %x, %y678  %cond = select i1 %cmp, i32 %y, i32 %x679  %cmp5 = icmp sgt i32 %cond, %x680  %retval = select i1 %cmp5, i32 %x, i32 %cond681  ret i32 %retval682}683 684; MAX(MIN(x, y), x) -> x685define i32 @test33(i32 %x, i32 %y) {686; CHECK-LABEL: define i32 @test33(687; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {688; CHECK-NEXT:    ret i32 [[X]]689;690  %cmp = icmp sgt i32 %x, %y691  %cond = select i1 %cmp, i32 %y, i32 %x692  %cmp5 = icmp sgt i32 %cond, %x693  %retval = select i1 %cmp5, i32 %cond, i32 %x694  ret i32 %retval695}696 697; MIN(MAX(x, y), x) -> x698define i32 @test34(i32 %x, i32 %y) {699; CHECK-LABEL: define i32 @test34(700; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {701; CHECK-NEXT:    ret i32 [[X]]702;703  %cmp = icmp sgt i32 %x, %y704  %cond = select i1 %cmp, i32 %x, i32 %y705  %cmp5 = icmp sgt i32 %cond, %x706  %retval = select i1 %cmp5, i32 %x, i32 %cond707  ret i32 %retval708}709 710define i1 @test38(i1 %cond) {711; CHECK-LABEL: define i1 @test38(712; CHECK-SAME: i1 [[COND:%.*]]) {713; CHECK-NEXT:    ret i1 false714;715  %zero = alloca i32716  %one = alloca i32717  %ptr = select i1 %cond, ptr %zero, ptr %one718  %isnull = icmp eq ptr %ptr, null719  ret i1 %isnull720}721 722define i1 @test39(i1 %cond, double %x) {723; CHECK-LABEL: define i1 @test39(724; CHECK-SAME: i1 [[COND:%.*]], double [[X:%.*]]) {725; CHECK-NEXT:    ret i1 true726;727  %s = select i1 %cond, double %x, double 0x7FF0000000000000   ; RHS = +infty728  %cmp = fcmp ule double %x, %s729  ret i1 %cmp730}731 732define i1 @test40(i1 %cond) {733; CHECK-LABEL: define i1 @test40(734; CHECK-SAME: i1 [[COND:%.*]]) {735; CHECK-NEXT:    ret i1 false736;737  %a = alloca i32738  %b = alloca i32739  %c = alloca i32740  %s = select i1 %cond, ptr %a, ptr %b741  %r = icmp eq ptr %s, %c742  ret i1 %r743}744 745define i32 @test41(i1 %cond, i32 %x, i32 %y) {746; CHECK-LABEL: define i32 @test41(747; CHECK-SAME: i1 [[COND:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) {748; CHECK-NEXT:    [[R:%.*]] = and i32 [[Y]], [[X]]749; CHECK-NEXT:    ret i32 [[R]]750;751  %z = and i32 %x, %y752  %s = select i1 %cond, i32 %y, i32 %z753  %r = and i32 %x, %s754  ret i32 %r755}756 757define i32 @test42(i32 %x, i32 %y) {758; CHECK-LABEL: define i32 @test42(759; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {760; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[X]], 0761; CHECK-NEXT:    [[B:%.*]] = sext i1 [[COND]] to i32762; CHECK-NEXT:    [[C:%.*]] = add i32 [[Y]], [[B]]763; CHECK-NEXT:    ret i32 [[C]]764;765  %b = add i32 %y, -1766  %cond = icmp eq i32 %x, 0767  %c = select i1 %cond, i32 %b, i32 %y768  ret i32 %c769}770 771define <2 x i32> @test42vec(<2 x i32> %x, <2 x i32> %y) {772; CHECK-LABEL: define <2 x i32> @test42vec(773; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) {774; CHECK-NEXT:    [[COND:%.*]] = icmp eq <2 x i32> [[X]], zeroinitializer775; CHECK-NEXT:    [[B:%.*]] = sext <2 x i1> [[COND]] to <2 x i32>776; CHECK-NEXT:    [[C:%.*]] = add <2 x i32> [[Y]], [[B]]777; CHECK-NEXT:    ret <2 x i32> [[C]]778;779  %b = add <2 x i32> %y, <i32 -1, i32 -1>780  %cond = icmp eq <2 x i32> %x, zeroinitializer781  %c = select <2 x i1> %cond, <2 x i32> %b, <2 x i32> %y782  ret <2 x i32> %c783}784 785; PR8994786 787; This select instruction can't be eliminated because trying to do so would788; change the number of vector elements. This used to assert.789define i48 @test51(<3 x i1> %icmp, <3 x i16> %t) {790; CHECK-LABEL: define i48 @test51(791; CHECK-SAME: <3 x i1> [[ICMP:%.*]], <3 x i16> [[T:%.*]]) {792; CHECK-NEXT:    [[SELECT:%.*]] = select <3 x i1> [[ICMP]], <3 x i16> zeroinitializer, <3 x i16> [[T]]793; CHECK-NEXT:    [[T2:%.*]] = bitcast <3 x i16> [[SELECT]] to i48794; CHECK-NEXT:    ret i48 [[T2]]795;796  %select = select <3 x i1> %icmp, <3 x i16> zeroinitializer, <3 x i16> %t797  %t2 = bitcast <3 x i16> %select to i48798  ret i48 %t2799}800 801define <vscale x 4 x float> @bitcast_select_bitcast(<vscale x 4 x i1> %icmp, <vscale x 4 x i32> %a, <vscale x 4 x float> %b) {802; CHECK-LABEL: define <vscale x 4 x float> @bitcast_select_bitcast(803; CHECK-SAME: <vscale x 4 x i1> [[ICMP:%.*]], <vscale x 4 x i32> [[A:%.*]], <vscale x 4 x float> [[B:%.*]]) {804; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <vscale x 4 x i32> [[A]] to <vscale x 4 x float>805; CHECK-NEXT:    [[BC2:%.*]] = select <vscale x 4 x i1> [[ICMP]], <vscale x 4 x float> [[B]], <vscale x 4 x float> [[TMP1]]806; CHECK-NEXT:    ret <vscale x 4 x float> [[BC2]]807;808  %bc1 = bitcast <vscale x 4 x float> %b to <vscale x 4 x i32>809  %select = select <vscale x 4 x i1> %icmp, <vscale x 4 x i32> %bc1, <vscale x 4 x i32> %a810  %bc2 = bitcast <vscale x 4 x i32> %select to <vscale x 4 x float>811  ret <vscale x 4 x float> %bc2812}813 814define void @select_oneuse_bitcast(<vscale x 4 x float> %a, <vscale x 4 x float> %b, <vscale x 4 x i32> %c, <vscale x 4 x i32> %d, ptr %ptr1) {815; CHECK-LABEL: define void @select_oneuse_bitcast(816; CHECK-SAME: <vscale x 4 x float> [[A:%.*]], <vscale x 4 x float> [[B:%.*]], <vscale x 4 x i32> [[C:%.*]], <vscale x 4 x i32> [[D:%.*]], ptr [[PTR1:%.*]]) {817; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <vscale x 4 x i32> [[C]], [[D]]818; CHECK-NEXT:    [[SEL1_V:%.*]] = select <vscale x 4 x i1> [[CMP]], <vscale x 4 x float> [[A]], <vscale x 4 x float> [[B]]819; CHECK-NEXT:    store <vscale x 4 x float> [[SEL1_V]], ptr [[PTR1]], align 16820; CHECK-NEXT:    ret void821;822  %cmp = icmp ult <vscale x 4 x i32> %c, %d823  %bc1 = bitcast <vscale x 4 x float> %a to <vscale x 4 x i32>824  %bc2 = bitcast <vscale x 4 x float> %b to <vscale x 4 x i32>825  %sel1 = select <vscale x 4 x i1> %cmp, <vscale x 4 x i32> %bc1, <vscale x 4 x i32> %bc2826  store <vscale x 4 x i32> %sel1, ptr %ptr1827  ret void828}829 830; Allow select promotion even if there are multiple uses of bitcasted ops.831; Hoisting the selects allows later pattern matching to see that these are min/max ops.832 833define void @min_max_bitcast(<4 x float> %a, <4 x float> %b, ptr %ptr1, ptr %ptr2) {834; CHECK-LABEL: define void @min_max_bitcast(835; CHECK-SAME: <4 x float> [[A:%.*]], <4 x float> [[B:%.*]], ptr [[PTR1:%.*]], ptr [[PTR2:%.*]]) {836; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <4 x float> [[A]], [[B]]837; CHECK-NEXT:    [[SEL1_V:%.*]] = select <4 x i1> [[CMP]], <4 x float> [[A]], <4 x float> [[B]]838; CHECK-NEXT:    [[SEL2_V:%.*]] = select <4 x i1> [[CMP]], <4 x float> [[B]], <4 x float> [[A]]839; CHECK-NEXT:    store <4 x float> [[SEL1_V]], ptr [[PTR1]], align 16840; CHECK-NEXT:    store <4 x float> [[SEL2_V]], ptr [[PTR2]], align 16841; CHECK-NEXT:    ret void842;843  %cmp = fcmp olt <4 x float> %a, %b844  %bc1 = bitcast <4 x float> %a to <4 x i32>845  %bc2 = bitcast <4 x float> %b to <4 x i32>846  %sel1 = select <4 x i1> %cmp, <4 x i32> %bc1, <4 x i32> %bc2847  %sel2 = select <4 x i1> %cmp, <4 x i32> %bc2, <4 x i32> %bc1848  store <4 x i32> %sel1, ptr %ptr1849  store <4 x i32> %sel2, ptr %ptr2850  ret void851}852 853define void @min_max_bitcast1(<vscale x 4 x float> %a, <vscale x 4 x float> %b, ptr %ptr1, ptr %ptr2) {854; CHECK-LABEL: define void @min_max_bitcast1(855; CHECK-SAME: <vscale x 4 x float> [[A:%.*]], <vscale x 4 x float> [[B:%.*]], ptr [[PTR1:%.*]], ptr [[PTR2:%.*]]) {856; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <vscale x 4 x float> [[A]], [[B]]857; CHECK-NEXT:    [[SEL1_V:%.*]] = select <vscale x 4 x i1> [[CMP]], <vscale x 4 x float> [[A]], <vscale x 4 x float> [[B]]858; CHECK-NEXT:    [[SEL2_V:%.*]] = select <vscale x 4 x i1> [[CMP]], <vscale x 4 x float> [[B]], <vscale x 4 x float> [[A]]859; CHECK-NEXT:    store <vscale x 4 x float> [[SEL1_V]], ptr [[PTR1]], align 16860; CHECK-NEXT:    store <vscale x 4 x float> [[SEL2_V]], ptr [[PTR2]], align 16861; CHECK-NEXT:    ret void862;863  %cmp = fcmp olt <vscale x 4 x float> %a, %b864  %bc1 = bitcast <vscale x 4 x float> %a to <vscale x 4 x i32>865  %bc2 = bitcast <vscale x 4 x float> %b to <vscale x 4 x i32>866  %sel1 = select <vscale x 4 x i1> %cmp, <vscale x 4 x i32> %bc1, <vscale x 4 x i32> %bc2867  %sel2 = select <vscale x 4 x i1> %cmp, <vscale x 4 x i32> %bc2, <vscale x 4 x i32> %bc1868  store <vscale x 4 x i32> %sel1, ptr %ptr1869  store <vscale x 4 x i32> %sel2, ptr %ptr2870  ret void871}872 873; To avoid potential backend problems, we don't do the same transform for other casts.874 875define void @truncs_before_selects(<4 x float> %f1, <4 x float> %f2, <4 x i64> %a, <4 x i64> %b, ptr %ptr1, ptr %ptr2) {876; CHECK-LABEL: define void @truncs_before_selects(877; CHECK-SAME: <4 x float> [[F1:%.*]], <4 x float> [[F2:%.*]], <4 x i64> [[A:%.*]], <4 x i64> [[B:%.*]], ptr [[PTR1:%.*]], ptr [[PTR2:%.*]]) {878; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <4 x float> [[F1]], [[F2]]879; CHECK-NEXT:    [[BC1:%.*]] = trunc <4 x i64> [[A]] to <4 x i32>880; CHECK-NEXT:    [[BC2:%.*]] = trunc <4 x i64> [[B]] to <4 x i32>881; CHECK-NEXT:    [[SEL1:%.*]] = select <4 x i1> [[CMP]], <4 x i32> [[BC1]], <4 x i32> [[BC2]]882; CHECK-NEXT:    [[SEL2:%.*]] = select <4 x i1> [[CMP]], <4 x i32> [[BC2]], <4 x i32> [[BC1]]883; CHECK-NEXT:    store <4 x i32> [[SEL1]], ptr [[PTR1]], align 16884; CHECK-NEXT:    store <4 x i32> [[SEL2]], ptr [[PTR2]], align 16885; CHECK-NEXT:    ret void886;887  %cmp = fcmp olt <4 x float> %f1, %f2888  %bc1 = trunc <4 x i64> %a to <4 x i32>889  %bc2 = trunc <4 x i64> %b to <4 x i32>890  %sel1 = select <4 x i1> %cmp, <4 x i32> %bc1, <4 x i32> %bc2891  %sel2 = select <4 x i1> %cmp, <4 x i32> %bc2, <4 x i32> %bc1892  store <4 x i32> %sel1, ptr %ptr1, align 16893  store <4 x i32> %sel2, ptr %ptr2, align 16894  ret void895}896 897; PR8575898 899define i32 @test52(i32 %n, i32 %m) {900; CHECK-LABEL: define i32 @test52(901; CHECK-SAME: i32 [[N:%.*]], i32 [[M:%.*]]) {902; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N]], [[M]]903; CHECK-NEXT:    [[STOREMERGE:%.*]] = select i1 [[CMP]], i32 1, i32 6904; CHECK-NEXT:    ret i32 [[STOREMERGE]]905;906  %cmp = icmp sgt i32 %n, %m907  %. = select i1 %cmp, i32 1, i32 3908  %add = add nsw i32 %., 3909  %storemerge = select i1 %cmp, i32 %., i32 %add910  ret i32 %storemerge911}912 913; PR9454914 915define i32 @test53(i32 %x) {916; CHECK-LABEL: define i32 @test53(917; CHECK-SAME: i32 [[X:%.*]]) {918; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X]], -3919; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0920; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 2, i32 1921; CHECK-NEXT:    ret i32 [[SEL]]922;923  %and = and i32 %x, 2924  %cmp = icmp eq i32 %and, %x925  %sel = select i1 %cmp, i32 2, i32 1926  ret i32 %sel927}928 929define i32 @test54(i32 %X, i32 %Y) {930; CHECK-LABEL: define i32 @test54(931; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {932; CHECK-NEXT:    [[B:%.*]] = icmp ne i32 [[X]], 0933; CHECK-NEXT:    [[C:%.*]] = zext i1 [[B]] to i32934; CHECK-NEXT:    ret i32 [[C]]935;936  %A = ashr exact i32 %X, %Y937  %B = icmp eq i32 %A, 0938  %C = select i1 %B, i32 %A, i32 1939  ret i32 %C940}941 942define i1 @test55(i1 %X, i32 %Y, i32 %Z) {943; CHECK-LABEL: define i1 @test55(944; CHECK-SAME: i1 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {945; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[Y]], 0946; CHECK-NEXT:    ret i1 [[C]]947;948  %A = ashr exact i32 %Y, %Z949  %B = select i1 %X, i32 %Y, i32 %A950  %C = icmp eq i32 %B, 0951  ret i1 %C952}953 954define i32 @test56(i16 %x) {955; CHECK-LABEL: define i32 @test56(956; CHECK-SAME: i16 [[X:%.*]]) {957; CHECK-NEXT:    [[CONV:%.*]] = zext i16 [[X]] to i32958; CHECK-NEXT:    ret i32 [[CONV]]959;960  %tobool = icmp eq i16 %x, 0961  %conv = zext i16 %x to i32962  %cond = select i1 %tobool, i32 0, i32 %conv963  ret i32 %cond964}965 966define i32 @test57(i32 %x, i32 %y) {967; CHECK-LABEL: define i32 @test57(968; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {969; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i32 [[Y]]970; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y_FR]]971; CHECK-NEXT:    ret i32 [[AND]]972;973  %and = and i32 %x, %y974  %tobool = icmp eq i32 %x, 0975  %.and = select i1 %tobool, i32 0, i32 %and976  ret i32 %.and977}978 979define i32 @test58(i16 %x) {980; CHECK-LABEL: define i32 @test58(981; CHECK-SAME: i16 [[X:%.*]]) {982; CHECK-NEXT:    [[CONV:%.*]] = zext i16 [[X]] to i32983; CHECK-NEXT:    ret i32 [[CONV]]984;985  %tobool = icmp ne i16 %x, 1986  %conv = zext i16 %x to i32987  %cond = select i1 %tobool, i32 %conv, i32 1988  ret i32 %cond989}990 991define i32 @test59(i32 %x, i32 %y) {992; CHECK-LABEL: define i32 @test59(993; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {994; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]995; CHECK-NEXT:    ret i32 [[AND]]996;997  %and = and i32 %x, %y998  %tobool = icmp ne i32 %x, %y999  %.and = select i1 %tobool, i32 %and, i32 %y1000  ret i32 %.and1001}1002 1003define i1 @test60(i32 %x, ptr %y) {1004; CHECK-LABEL: define i1 @test60(1005; CHECK-SAME: i32 [[X:%.*]], ptr [[Y:%.*]]) {1006; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X]], 01007; CHECK-NEXT:    [[LOAD:%.*]] = load i1, ptr [[Y]], align 11008; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[X]], 11009; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i1 [[LOAD]], i1 [[CMP1]]1010; CHECK-NEXT:    ret i1 [[SEL]]1011;1012  %cmp = icmp eq i32 %x, 01013  %load = load i1, ptr %y, align 11014  %cmp1 = icmp slt i32 %x, 11015  %sel = select i1 %cmp, i1 %load, i1 %cmp11016  ret i1 %sel1017}1018 1019@glbl = constant i32 101020define i32 @test61(ptr %ptr) {1021; CHECK-LABEL: define i32 @test61(1022; CHECK-SAME: ptr [[PTR:%.*]]) {1023; CHECK-NEXT:    ret i32 101024;1025  %A = load i32, ptr %ptr1026  %B = icmp eq ptr %ptr, @glbl1027  %C = select i1 %B, i32 %A, i32 101028  ret i32 %C1029}1030 1031; PR141311032define void @test64(i32 %p, i16 %b, i1 %c1) noreturn {1033; CHECK-LABEL: define void @test64(1034; CHECK-SAME: i32 [[P:%.*]], i16 [[B:%.*]], i1 [[C1:%.*]]) #[[ATTR1:[0-9]+]] {1035; CHECK-NEXT:  [[ENTRY:.*:]]1036; CHECK-NEXT:    br i1 [[C1]], label %[[LOR_RHS:.*]], label %[[LOR_END:.*]]1037; CHECK:       [[LOR_RHS]]:1038; CHECK-NEXT:    br label %[[LOR_END]]1039; CHECK:       [[LOR_END]]:1040; CHECK-NEXT:    br i1 poison, label %[[COND_END17:.*]], label %[[COND_FALSE16:.*]]1041; CHECK:       [[COND_FALSE16]]:1042; CHECK-NEXT:    br label %[[COND_END17]]1043; CHECK:       [[COND_END17]]:1044; CHECK-NEXT:    br label %[[WHILE_BODY:.*]]1045; CHECK:       [[WHILE_BODY]]:1046; CHECK-NEXT:    br label %[[WHILE_BODY]]1047;1048entry:1049  %p.addr.0.insert.mask = and i32 %p, -655361050  %conv2 = and i32 %p, 655351051  br i1 %c1, label %lor.rhs, label %lor.end1052 1053lor.rhs:1054  %p.addr.0.extract.trunc = trunc i32 %p.addr.0.insert.mask to i161055  %phitmp = zext i16 %p.addr.0.extract.trunc to i321056  br label %lor.end1057 1058lor.end:1059  %t.1 = phi i32 [ 0, %entry ], [ %phitmp, %lor.rhs ]1060  %conv6 = zext i16 %b to i321061  %div = udiv i32 %conv6, %t.11062  %tobool8 = icmp eq i32 %div, 01063  %cmp = icmp eq i32 %t.1, 01064  %cmp12 = icmp ult i32 %conv2, 21065  %cmp.sink = select i1 %tobool8, i1 %cmp12, i1 %cmp1066  br i1 %cmp.sink, label %cond.end17, label %cond.false161067 1068cond.false16:1069  br label %cond.end171070 1071cond.end17:1072  br label %while.body1073 1074while.body:1075  br label %while.body1076}1077 1078@under_aligned = external global i32, align 11079 1080; The load here must not be speculated around the select. One side of the1081; select is trivially dereferenceable but may have a lower alignment than the1082; load does.1083define i32 @test76(i1 %flag, ptr %x) {1084; CHECK-LABEL: define i32 @test76(1085; CHECK-SAME: i1 [[FLAG:%.*]], ptr [[X:%.*]]) {1086; CHECK-NEXT:    store i32 0, ptr [[X]], align 41087; CHECK-NEXT:    [[P:%.*]] = select i1 [[FLAG]], ptr @under_aligned, ptr [[X]]1088; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P]], align 41089; CHECK-NEXT:    ret i32 [[V]]1090;1091  store i32 0, ptr %x1092  %p = select i1 %flag, ptr @under_aligned, ptr %x1093  %v = load i32, ptr %p1094  ret i32 %v1095}1096 1097declare void @scribble_on_i32(ptr)1098 1099; The load here must not be speculated around the select. One side of the1100; select is trivially dereferenceable but may have a lower alignment than the1101; load does.1102 1103define i32 @test77(i1 %flag, ptr %x) {1104; CHECK-LABEL: define i32 @test77(1105; CHECK-SAME: i1 [[FLAG:%.*]], ptr [[X:%.*]]) {1106; CHECK-NEXT:    [[UNDER_ALIGNED:%.*]] = alloca i32, align 11107; CHECK-NEXT:    call void @scribble_on_i32(ptr nonnull [[UNDER_ALIGNED]])1108; CHECK-NEXT:    store i32 0, ptr [[X]], align 41109; CHECK-NEXT:    [[P:%.*]] = select i1 [[FLAG]], ptr [[UNDER_ALIGNED]], ptr [[X]]1110; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P]], align 41111; CHECK-NEXT:    ret i32 [[V]]1112;1113  %under_aligned = alloca i32, align 11114  call void @scribble_on_i32(ptr %under_aligned)1115  store i32 0, ptr %x1116  %p = select i1 %flag, ptr %under_aligned, ptr %x1117  %v = load i32, ptr %p1118  ret i32 %v1119}1120 1121define i32 @test78(i1 %flag, ptr %x, ptr %y, ptr %z) {1122; Test that we can speculate the loads around the select even when we can't1123; fold the load completely away.1124; CHECK-LABEL: define i32 @test78(1125; CHECK-SAME: i1 [[FLAG:%.*]], ptr [[X:%.*]], ptr [[Y:%.*]], ptr [[Z:%.*]]) {1126; CHECK-NEXT:  [[ENTRY:.*:]]1127; CHECK-NEXT:    store i32 0, ptr [[X]], align 41128; CHECK-NEXT:    store i32 0, ptr [[Y]], align 41129; CHECK-NEXT:    store i32 42, ptr [[Z]], align 41130; CHECK-NEXT:    [[X_VAL:%.*]] = load i32, ptr [[X]], align 41131; CHECK-NEXT:    [[Y_VAL:%.*]] = load i32, ptr [[Y]], align 41132; CHECK-NEXT:    [[V:%.*]] = select i1 [[FLAG]], i32 [[X_VAL]], i32 [[Y_VAL]]1133; CHECK-NEXT:    ret i32 [[V]]1134;1135entry:1136  store i32 0, ptr %x1137  store i32 0, ptr %y1138  ; Block forwarding by storing to %z which could alias either %x or %y.1139  store i32 42, ptr %z1140  %p = select i1 %flag, ptr %x, ptr %y1141  %v = load i32, ptr %p1142  ret i32 %v1143}1144 1145; Test that we can speculate the loads around the select even when we can't1146; fold the load completely away.1147define i32 @test78_deref(i1 %flag, ptr dereferenceable(4) align 4 %x, ptr dereferenceable(4) align 4 %y, ptr %z) nofree nosync {1148; CHECK-LABEL: define i32 @test78_deref(1149; CHECK-SAME: i1 [[FLAG:%.*]], ptr align 4 dereferenceable(4) [[X:%.*]], ptr align 4 dereferenceable(4) [[Y:%.*]], ptr [[Z:%.*]]) #[[ATTR2:[0-9]+]] {1150; CHECK-NEXT:    [[X_VAL:%.*]] = load i32, ptr [[X]], align 41151; CHECK-NEXT:    [[Y_VAL:%.*]] = load i32, ptr [[Y]], align 41152; CHECK-NEXT:    [[V:%.*]] = select i1 [[FLAG]], i32 [[X_VAL]], i32 [[Y_VAL]]1153; CHECK-NEXT:    ret i32 [[V]]1154;1155  %p = select i1 %flag, ptr %x, ptr %y1156  %v = load i32, ptr %p1157  ret i32 %v1158}1159 1160; The same as @test78 but we can't speculate the load because it can trap1161; if under-aligned.1162define i32 @test78_neg(i1 %flag, ptr %x, ptr %y, ptr %z) {1163; CHECK-LABEL: define i32 @test78_neg(1164; CHECK-SAME: i1 [[FLAG:%.*]], ptr [[X:%.*]], ptr [[Y:%.*]], ptr [[Z:%.*]]) {1165; CHECK-NEXT:    store i32 0, ptr [[X]], align 41166; CHECK-NEXT:    store i32 0, ptr [[Y]], align 41167; CHECK-NEXT:    store i32 42, ptr [[Z]], align 41168; CHECK-NEXT:    [[P:%.*]] = select i1 [[FLAG]], ptr [[X]], ptr [[Y]]1169; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P]], align 161170; CHECK-NEXT:    ret i32 [[V]]1171;1172  store i32 0, ptr %x1173  store i32 0, ptr %y1174  ; Block forwarding by storing to %z which could alias either %x or %y.1175  store i32 42, ptr %z1176  %p = select i1 %flag, ptr %x, ptr %y1177  %v = load i32, ptr %p, align 161178  ret i32 %v1179}1180 1181; The same as @test78_deref but we can't speculate the load because1182; one of the arguments is not sufficiently dereferenceable.1183define i32 @test78_deref_neg(i1 %flag, ptr dereferenceable(2) %x, ptr dereferenceable(4) %y, ptr %z) nofree nosync {1184; CHECK-LABEL: define i32 @test78_deref_neg(1185; CHECK-SAME: i1 [[FLAG:%.*]], ptr dereferenceable(2) [[X:%.*]], ptr dereferenceable(4) [[Y:%.*]], ptr [[Z:%.*]]) #[[ATTR2]] {1186; CHECK-NEXT:    [[P:%.*]] = select i1 [[FLAG]], ptr [[X]], ptr [[Y]]1187; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P]], align 41188; CHECK-NEXT:    ret i32 [[V]]1189;1190  %p = select i1 %flag, ptr %x, ptr %y1191  %v = load i32, ptr %p1192  ret i32 %v1193}1194 1195; Test that we can speculate the loads around the select even when we can't1196; fold the load completely away.1197define float @test79(i1 %flag, ptr %x, ptr %y, ptr %z) {1198; CHECK-LABEL: define float @test79(1199; CHECK-SAME: i1 [[FLAG:%.*]], ptr [[X:%.*]], ptr [[Y:%.*]], ptr [[Z:%.*]]) {1200; CHECK-NEXT:    store i32 0, ptr [[X]], align 41201; CHECK-NEXT:    store i32 0, ptr [[Y]], align 41202; CHECK-NEXT:    store i32 42, ptr [[Z]], align 41203; CHECK-NEXT:    [[X_VAL:%.*]] = load float, ptr [[X]], align 41204; CHECK-NEXT:    [[Y_VAL:%.*]] = load float, ptr [[Y]], align 41205; CHECK-NEXT:    [[V:%.*]] = select i1 [[FLAG]], float [[X_VAL]], float [[Y_VAL]]1206; CHECK-NEXT:    ret float [[V]]1207;1208  store i32 0, ptr %x1209  store i32 0, ptr %y1210  ; Block forwarding by storing to %z which could alias either %x or %y.1211  store i32 42, ptr %z1212  %p = select i1 %flag, ptr %x, ptr %y1213  %v = load float, ptr %p1214  ret float %v1215}1216 1217; Test that when we speculate the loads around the select they fold throug1218; load->load folding and load->store folding.1219define i32 @test80(i1 %flag) {1220; CHECK-LABEL: define i32 @test80(1221; CHECK-SAME: i1 [[FLAG:%.*]]) {1222; CHECK-NEXT:    [[X:%.*]] = alloca i32, align 41223; CHECK-NEXT:    [[Y:%.*]] = alloca i32, align 41224; CHECK-NEXT:    call void @scribble_on_i32(ptr nonnull [[X]])1225; CHECK-NEXT:    call void @scribble_on_i32(ptr nonnull [[Y]])1226; CHECK-NEXT:    [[T:%.*]] = load i32, ptr [[X]], align 41227; CHECK-NEXT:    store i32 [[T]], ptr [[Y]], align 41228; CHECK-NEXT:    ret i32 [[T]]1229;1230  %x = alloca i321231  %y = alloca i321232  call void @scribble_on_i32(ptr %x)1233  call void @scribble_on_i32(ptr %y)1234  %t = load i32, ptr %x1235  store i32 %t, ptr %y1236  %p = select i1 %flag, ptr %x, ptr %y1237  %v = load i32, ptr %p1238  ret i32 %v1239}1240 1241; Test that we can speculate the load around the select even though they use1242; differently typed pointers.1243define float @test81(i1 %flag) {1244; CHECK-LABEL: define float @test81(1245; CHECK-SAME: i1 [[FLAG:%.*]]) {1246; CHECK-NEXT:    [[X:%.*]] = alloca float, align 41247; CHECK-NEXT:    [[Y:%.*]] = alloca i32, align 41248; CHECK-NEXT:    call void @scribble_on_i32(ptr nonnull [[X]])1249; CHECK-NEXT:    call void @scribble_on_i32(ptr nonnull [[Y]])1250; CHECK-NEXT:    [[T:%.*]] = load i32, ptr [[X]], align 41251; CHECK-NEXT:    store i32 [[T]], ptr [[Y]], align 41252; CHECK-NEXT:    [[V:%.*]] = bitcast i32 [[T]] to float1253; CHECK-NEXT:    ret float [[V]]1254;1255  %x = alloca float1256  %y = alloca i321257  call void @scribble_on_i32(ptr %x)1258  call void @scribble_on_i32(ptr %y)1259  %t = load i32, ptr %x1260  store i32 %t, ptr %y1261  %p = select i1 %flag, ptr %x, ptr %y1262  %v = load float, ptr %p1263  ret float %v1264}1265 1266; Test that we can speculate the load around the select even though they use1267; differently typed pointers.1268define i32 @test82(i1 %flag) {1269; CHECK-LABEL: define i32 @test82(1270; CHECK-SAME: i1 [[FLAG:%.*]]) {1271; CHECK-NEXT:    [[X:%.*]] = alloca float, align 41272; CHECK-NEXT:    [[Y:%.*]] = alloca i32, align 41273; CHECK-NEXT:    call void @scribble_on_i32(ptr nonnull [[X]])1274; CHECK-NEXT:    call void @scribble_on_i32(ptr nonnull [[Y]])1275; CHECK-NEXT:    [[T:%.*]] = load float, ptr [[X]], align 41276; CHECK-NEXT:    store float [[T]], ptr [[Y]], align 41277; CHECK-NEXT:    [[V:%.*]] = bitcast float [[T]] to i321278; CHECK-NEXT:    ret i32 [[V]]1279;1280  %x = alloca float1281  %y = alloca i321282  call void @scribble_on_i32(ptr %x)1283  call void @scribble_on_i32(ptr %y)1284  %t = load float, ptr %x1285  store float %t, ptr %y1286  %p = select i1 %flag, ptr %x, ptr %y1287  %v = load i32, ptr %p1288  ret i32 %v1289}1290 1291declare void @scribble_on_i64(ptr)1292declare void @scribble_on_i128(ptr)1293 1294; Test that we can speculate the load around the select even though they use1295; differently typed pointers and requires inttoptr casts.1296define ptr @test83(i1 %flag) {1297; CHECK-LABEL: define ptr @test83(1298; CHECK-SAME: i1 [[FLAG:%.*]]) {1299; CHECK-NEXT:    [[X:%.*]] = alloca ptr, align 81300; CHECK-NEXT:    [[Y:%.*]] = alloca i64, align 81301; CHECK-NEXT:    call void @scribble_on_i64(ptr nonnull [[X]])1302; CHECK-NEXT:    call void @scribble_on_i64(ptr nonnull [[Y]])1303; CHECK-NEXT:    [[T:%.*]] = load i64, ptr [[X]], align 41304; CHECK-NEXT:    store i64 [[T]], ptr [[Y]], align 41305; CHECK-NEXT:    [[V:%.*]] = inttoptr i64 [[T]] to ptr1306; CHECK-NEXT:    ret ptr [[V]]1307;1308  %x = alloca ptr1309  %y = alloca i641310  call void @scribble_on_i64(ptr %x)1311  call void @scribble_on_i64(ptr %y)1312  %t = load i64, ptr %x1313  store i64 %t, ptr %y1314  %p = select i1 %flag, ptr %x, ptr %y1315  %v = load ptr, ptr %p1316  ret ptr %v1317}1318 1319; Test that we can speculate the load around the select even though they use1320; differently typed pointers and requires a ptrtoint cast.1321define i64 @test84(i1 %flag) {1322; CHECK-LABEL: define i64 @test84(1323; CHECK-SAME: i1 [[FLAG:%.*]]) {1324; CHECK-NEXT:    [[X:%.*]] = alloca ptr, align 81325; CHECK-NEXT:    [[Y:%.*]] = alloca i64, align 81326; CHECK-NEXT:    call void @scribble_on_i64(ptr nonnull [[X]])1327; CHECK-NEXT:    call void @scribble_on_i64(ptr nonnull [[Y]])1328; CHECK-NEXT:    [[T:%.*]] = load ptr, ptr [[X]], align 81329; CHECK-NEXT:    store ptr [[T]], ptr [[Y]], align 81330; CHECK-NEXT:    [[V:%.*]] = ptrtoint ptr [[T]] to i641331; CHECK-NEXT:    ret i64 [[V]]1332;1333  %x = alloca ptr1334  %y = alloca i641335  call void @scribble_on_i64(ptr %x)1336  call void @scribble_on_i64(ptr %y)1337  %t = load ptr, ptr %x1338  store ptr %t, ptr %y1339  %p = select i1 %flag, ptr %x, ptr %y1340  %v = load i64, ptr %p1341  ret i64 %v1342}1343 1344; Test that we can't speculate the load around the select. The load of the1345; pointer doesn't load all of the stored integer bits. We could fix this, but it1346; would require endianness checks and other nastiness.1347define ptr @test85(i1 %flag) {1348; CHECK-LABEL: define ptr @test85(1349; CHECK-SAME: i1 [[FLAG:%.*]]) {1350; CHECK-NEXT:    [[X:%.*]] = alloca [2 x ptr], align 81351; CHECK-NEXT:    [[Y:%.*]] = alloca i128, align 81352; CHECK-NEXT:    call void @scribble_on_i128(ptr nonnull [[X]])1353; CHECK-NEXT:    call void @scribble_on_i128(ptr nonnull [[Y]])1354; CHECK-NEXT:    [[T:%.*]] = load i128, ptr [[X]], align 41355; CHECK-NEXT:    store i128 [[T]], ptr [[Y]], align 41356; CHECK-NEXT:    [[X_VAL:%.*]] = load ptr, ptr [[X]], align 81357; CHECK-NEXT:    [[Y_VAL:%.*]] = load ptr, ptr [[Y]], align 81358; CHECK-NEXT:    [[V:%.*]] = select i1 [[FLAG]], ptr [[X_VAL]], ptr [[Y_VAL]]1359; CHECK-NEXT:    ret ptr [[V]]1360;1361  %x = alloca [2 x ptr]1362  %y = alloca i1281363  call void @scribble_on_i128(ptr %x)1364  call void @scribble_on_i128(ptr %y)1365  %t = load i128, ptr %x1366  store i128 %t, ptr %y1367  %p = select i1 %flag, ptr %x, ptr %y1368  %v = load ptr, ptr %p1369  ret ptr %v1370}1371 1372; Test that we can't speculate the load around the select when the integer size1373; is larger than the pointer size. The store of the pointer doesn't store to all1374; the bits of the integer.1375define i128 @test86(i1 %flag) {1376; CHECK-LABEL: define i128 @test86(1377; CHECK-SAME: i1 [[FLAG:%.*]]) {1378; CHECK-NEXT:    [[X:%.*]] = alloca [2 x ptr], align 81379; CHECK-NEXT:    [[Y:%.*]] = alloca i128, align 81380; CHECK-NEXT:    call void @scribble_on_i128(ptr nonnull [[X]])1381; CHECK-NEXT:    call void @scribble_on_i128(ptr nonnull [[Y]])1382; CHECK-NEXT:    [[T:%.*]] = load ptr, ptr [[X]], align 81383; CHECK-NEXT:    store ptr [[T]], ptr [[Y]], align 81384; CHECK-NEXT:    [[X_VAL:%.*]] = load i128, ptr [[X]], align 41385; CHECK-NEXT:    [[Y_VAL:%.*]] = load i128, ptr [[Y]], align 41386; CHECK-NEXT:    [[V:%.*]] = select i1 [[FLAG]], i128 [[X_VAL]], i128 [[Y_VAL]]1387; CHECK-NEXT:    ret i128 [[V]]1388;1389  %x = alloca [2 x ptr]1390  %y = alloca i1281391  call void @scribble_on_i128(ptr %x)1392  call void @scribble_on_i128(ptr %y)1393  %t = load ptr, ptr %x1394  store ptr %t, ptr %y1395  %p = select i1 %flag, ptr %x, ptr %y1396  %v = load i128, ptr %p1397  ret i128 %v1398}1399 1400define i32 @test_select_select0(i32 %a, i32 %r0, i32 %r1, i32 %v1, i32 %v2) {1401; CHECK-LABEL: define i32 @test_select_select0(1402; CHECK-SAME: i32 [[A:%.*]], i32 [[R0:%.*]], i32 [[R1:%.*]], i32 [[V1:%.*]], i32 [[V2:%.*]]) {1403; CHECK-NEXT:    [[C0_NOT:%.*]] = icmp slt i32 [[A]], [[V1]]1404; CHECK-NEXT:    [[S0:%.*]] = select i1 [[C0_NOT]], i32 [[R1]], i32 [[R0]]1405; CHECK-NEXT:    [[C1:%.*]] = icmp slt i32 [[A]], [[V2]]1406; CHECK-NEXT:    [[S1:%.*]] = select i1 [[C1]], i32 [[S0]], i32 [[R1]]1407; CHECK-NEXT:    ret i32 [[S1]]1408;1409  %c0 = icmp sge i32 %a, %v11410  %s0 = select i1 %c0, i32 %r0, i32 %r11411  %c1 = icmp slt i32 %a, %v21412  %s1 = select i1 %c1, i32 %s0, i32 %r11413  ret i32 %s11414}1415 1416define i32 @test_select_select1(i32 %a, i32 %r0, i32 %r1, i32 %v1, i32 %v2) {1417; CHECK-LABEL: define i32 @test_select_select1(1418; CHECK-SAME: i32 [[A:%.*]], i32 [[R0:%.*]], i32 [[R1:%.*]], i32 [[V1:%.*]], i32 [[V2:%.*]]) {1419; CHECK-NEXT:    [[C0_NOT:%.*]] = icmp slt i32 [[A]], [[V1]]1420; CHECK-NEXT:    [[S0:%.*]] = select i1 [[C0_NOT]], i32 [[R1]], i32 [[R0]]1421; CHECK-NEXT:    [[C1:%.*]] = icmp slt i32 [[A]], [[V2]]1422; CHECK-NEXT:    [[S1:%.*]] = select i1 [[C1]], i32 [[R0]], i32 [[S0]]1423; CHECK-NEXT:    ret i32 [[S1]]1424;1425  %c0 = icmp sge i32 %a, %v11426  %s0 = select i1 %c0, i32 %r0, i32 %r11427  %c1 = icmp slt i32 %a, %v21428  %s1 = select i1 %c1, i32 %r0, i32 %s01429  ret i32 %s11430}1431 1432define i32 @PR23757(i32 %x) {1433; CHECK-LABEL: define i32 @PR23757(1434; CHECK-SAME: i32 [[X:%.*]]) {1435; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X]], 11436; CHECK-NEXT:    ret i32 [[ADD]]1437;1438  %cmp = icmp eq i32 %x, 21474836471439  %add = add nsw i32 %x, 11440  %sel = select i1 %cmp, i32 -2147483648, i32 %add1441  ret i32 %sel1442}1443 1444define i32 @PR23757_swapped(i32 %x) {1445; CHECK-LABEL: define i32 @PR23757_swapped(1446; CHECK-SAME: i32 [[X:%.*]]) {1447; CHECK-NEXT:    ret i32 -21474836481448;1449  %cmp = icmp eq i32 %x, 21474836471450  %add = add nsw i32 %x, 11451  %sel = select i1 %cmp, i32 %add, i32 -21474836481452  ret i32 %sel1453}1454 1455define i32 @PR23757_ne(i32 %x, ptr %p) {1456; CHECK-LABEL: define i32 @PR23757_ne(1457; CHECK-SAME: i32 [[X:%.*]], ptr [[P:%.*]]) {1458; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X]], 21474836471459; CHECK-NEXT:    store i1 [[CMP]], ptr [[P]], align 11460; CHECK-NEXT:    ret i32 -21474836481461;1462  %cmp = icmp ne i32 %x, 21474836471463  store i1 %cmp, ptr %p   ; thwart predicate canonicalization1464  %add = add nsw i32 %x, 11465  %sel = select i1 %cmp, i32 -2147483648, i32 %add1466  ret i32 %sel1467}1468 1469define i32 @PR23757_ne_swapped(i32 %x, ptr %p) {1470; CHECK-LABEL: define i32 @PR23757_ne_swapped(1471; CHECK-SAME: i32 [[X:%.*]], ptr [[P:%.*]]) {1472; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X]], 21474836471473; CHECK-NEXT:    store i1 [[CMP]], ptr [[P]], align 11474; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X]], 11475; CHECK-NEXT:    ret i32 [[ADD]]1476;1477  %cmp = icmp ne i32 %x, 21474836471478  store i1 %cmp, ptr %p   ; thwart predicate canonicalization1479  %add = add nsw i32 %x, 11480  %sel = select i1 %cmp, i32 %add, i32 -21474836481481  ret i32 %sel1482}1483 1484; max(max(~a, -1), -1) --> ~min(a, 0)1485 1486define i32 @PR27137(i32 %a) {1487; CHECK-LABEL: define i32 @PR27137(1488; CHECK-SAME: i32 [[A:%.*]]) {1489; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[A]], i32 0)1490; CHECK-NEXT:    [[S1:%.*]] = xor i32 [[TMP1]], -11491; CHECK-NEXT:    ret i32 [[S1]]1492;1493  %not_a = xor i32 %a, -11494  %c0 = icmp slt i32 %a, 01495  %s0 = select i1 %c0, i32 %not_a, i32 -11496  %c1 = icmp sgt i32 %s0, -11497  %s1 = select i1 %c1, i32 %s0, i32 -11498  ret i32 %s11499}1500 1501; ub-safe negation pattern1502define i32 @PR27817(i32 %x) {1503; CHECK-LABEL: define i32 @PR27817(1504; CHECK-SAME: i32 [[X:%.*]]) {1505; CHECK-NEXT:    [[SUB:%.*]] = sub i32 0, [[X]]1506; CHECK-NEXT:    ret i32 [[SUB]]1507;1508  %cmp = icmp eq i32 %x, -21474836481509  %sub = sub i32 0, %x1510  %sel = select i1 %cmp, i32 -2147483648, i32 %sub1511  ret i32 %sel1512}1513 1514define i32 @PR27817_nsw(i32 %x) {1515; CHECK-LABEL: define i32 @PR27817_nsw(1516; CHECK-SAME: i32 [[X:%.*]]) {1517; CHECK-NEXT:    [[SUB:%.*]] = sub i32 0, [[X]]1518; CHECK-NEXT:    ret i32 [[SUB]]1519;1520  %cmp = icmp eq i32 %x, -21474836481521  %sub = sub nsw i32 0, %x1522  %sel = select i1 %cmp, i32 -2147483648, i32 %sub1523  ret i32 %sel1524}1525 1526define <2 x i32> @PR27817_nsw_vec(<2 x i32> %x) {1527; CHECK-LABEL: define <2 x i32> @PR27817_nsw_vec(1528; CHECK-SAME: <2 x i32> [[X:%.*]]) {1529; CHECK-NEXT:    [[SUB:%.*]] = sub <2 x i32> zeroinitializer, [[X]]1530; CHECK-NEXT:    ret <2 x i32> [[SUB]]1531;1532  %cmp = icmp eq <2 x i32> %x, <i32 -2147483648, i32 -2147483648>1533  %sub = sub nsw <2 x i32> zeroinitializer, %x1534  %sel = select <2 x i1> %cmp, <2 x i32> <i32 -2147483648, i32 -2147483648>, <2 x i32> %sub1535  ret <2 x i32> %sel1536}1537 1538define i32 @select_icmp_slt0_xor(i32 %x) {1539; CHECK-LABEL: define i32 @select_icmp_slt0_xor(1540; CHECK-SAME: i32 [[X:%.*]]) {1541; CHECK-NEXT:    [[X_XOR:%.*]] = or i32 [[X]], -21474836481542; CHECK-NEXT:    ret i32 [[X_XOR]]1543;1544  %cmp = icmp slt i32 %x, zeroinitializer1545  %xor = xor i32 %x, 21474836481546  %x.xor = select i1 %cmp, i32 %x, i32 %xor1547  ret i32 %x.xor1548}1549 1550define <2 x i32> @select_icmp_slt0_xor_vec(<2 x i32> %x) {1551; CHECK-LABEL: define <2 x i32> @select_icmp_slt0_xor_vec(1552; CHECK-SAME: <2 x i32> [[X:%.*]]) {1553; CHECK-NEXT:    [[X_XOR:%.*]] = or <2 x i32> [[X]], splat (i32 -2147483648)1554; CHECK-NEXT:    ret <2 x i32> [[X_XOR]]1555;1556  %cmp = icmp slt <2 x i32> %x, zeroinitializer1557  %xor = xor <2 x i32> %x, <i32 2147483648, i32 2147483648>1558  %x.xor = select <2 x i1> %cmp, <2 x i32> %x, <2 x i32> %xor1559  ret <2 x i32> %x.xor1560}1561 1562define <4 x i32> @canonicalize_to_shuffle(<4 x i32> %a, <4 x i32> %b) {1563; CHECK-LABEL: define <4 x i32> @canonicalize_to_shuffle(1564; CHECK-SAME: <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]) {1565; CHECK-NEXT:    [[SEL:%.*]] = shufflevector <4 x i32> [[A]], <4 x i32> [[B]], <4 x i32> <i32 0, i32 5, i32 6, i32 3>1566; CHECK-NEXT:    ret <4 x i32> [[SEL]]1567;1568  %sel = select <4 x i1> <i1 true, i1 false, i1 false, i1 true>, <4 x i32> %a, <4 x i32> %b1569  ret <4 x i32> %sel1570}1571 1572; Undef elements of the select condition may not be translated into undef elements of a shuffle mask1573; because undef in a shuffle mask means we can return anything, not just one of the selected values.1574; https://bugs.llvm.org/show_bug.cgi?id=324861575 1576define <4 x i32> @undef_elts_in_condition(<4 x i32> %a, <4 x i32> %b) {1577; CHECK-LABEL: define <4 x i32> @undef_elts_in_condition(1578; CHECK-SAME: <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]) {1579; CHECK-NEXT:    [[SEL:%.*]] = select <4 x i1> <i1 true, i1 undef, i1 false, i1 undef>, <4 x i32> [[A]], <4 x i32> [[B]]1580; CHECK-NEXT:    ret <4 x i32> [[SEL]]1581;1582  %sel = select <4 x i1> <i1 true, i1 undef, i1 false, i1 undef>, <4 x i32> %a, <4 x i32> %b1583  ret <4 x i32> %sel1584}1585 1586; Don't die or try if the condition mask is a constant expression or contains a constant expression.1587 1588@g = global i32 01589 1590define <4 x i32> @cannot_canonicalize_to_shuffle1(<4 x i32> %a, <4 x i32> %b) {1591; CHECK-LABEL: define <4 x i32> @cannot_canonicalize_to_shuffle1(1592; CHECK-SAME: <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]) {1593; CHECK-NEXT:    [[SEL:%.*]] = select <4 x i1> bitcast (i4 ptrtoint (ptr @g to i4) to <4 x i1>), <4 x i32> [[A]], <4 x i32> [[B]]1594; CHECK-NEXT:    ret <4 x i32> [[SEL]]1595;1596  %sel = select <4 x i1> bitcast (i4 ptrtoint (ptr @g to i4) to <4 x i1>), <4 x i32> %a, <4 x i32> %b1597  ret <4 x i32> %sel1598}1599 1600define <4 x i32> @cannot_canonicalize_to_shuffle2(<4 x i32> %a, <4 x i32> %b) {1601; CHECK-LABEL: define <4 x i32> @cannot_canonicalize_to_shuffle2(1602; CHECK-SAME: <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]) {1603; CHECK-NEXT:    [[SEL:%.*]] = select <4 x i1> <i1 true, i1 undef, i1 false, i1 ptrtoint (ptr @g to i1)>, <4 x i32> [[A]], <4 x i32> [[B]]1604; CHECK-NEXT:    ret <4 x i32> [[SEL]]1605;1606  %sel = select <4 x i1> <i1 true, i1 undef, i1 false, i1 ptrtoint (ptr @g to i1)>, <4 x i32> %a, <4 x i32> %b1607  ret <4 x i32> %sel1608}1609 1610declare void @llvm.assume(i1)1611 1612define i8 @assume_cond_true(i1 %cond, i8 %x, i8 %y) {1613; CHECK-LABEL: define i8 @assume_cond_true(1614; CHECK-SAME: i1 [[COND:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]]) {1615; CHECK-NEXT:    call void @llvm.assume(i1 [[COND]])1616; CHECK-NEXT:    ret i8 [[X]]1617;1618  call void @llvm.assume(i1 %cond)1619  %sel = select i1 %cond, i8 %x, i8 %y1620  ret i8 %sel1621}1622 1623; computeKnownBitsFromAssume() understands the 'not' of an assumed condition.1624 1625define i8 @assume_cond_false(i1 %cond, i8 %x, i8 %y) {1626; CHECK-LABEL: define i8 @assume_cond_false(1627; CHECK-SAME: i1 [[COND:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]]) {1628; CHECK-NEXT:    [[NOTCOND:%.*]] = xor i1 [[COND]], true1629; CHECK-NEXT:    call void @llvm.assume(i1 [[NOTCOND]])1630; CHECK-NEXT:    ret i8 [[Y]]1631;1632  %notcond = xor i1 %cond, true1633  call void @llvm.assume(i1 %notcond)1634  %sel = select i1 %cond, i8 %x, i8 %y1635  ret i8 %sel1636}1637 1638; Test case to make sure we don't consider an all ones float values for converting the select into a sext.1639define <4 x float> @PR33721(<4 x float> %w) {1640; CHECK-LABEL: define <4 x float> @PR33721(1641; CHECK-SAME: <4 x float> [[W:%.*]]) {1642; CHECK-NEXT:  [[ENTRY:.*:]]1643; CHECK-NEXT:    [[TMP0:%.*]] = fcmp ole <4 x float> [[W]], zeroinitializer1644; CHECK-NEXT:    [[TMP1:%.*]] = select <4 x i1> [[TMP0]], <4 x float> splat (float 0xFFFFFFFFE0000000), <4 x float> zeroinitializer1645; CHECK-NEXT:    ret <4 x float> [[TMP1]]1646;1647entry:1648  %0 = fcmp ole <4 x float> %w, zeroinitializer1649  %1 = select <4 x i1> %0, <4 x float> <float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000>, <4 x float> zeroinitializer1650  ret <4 x float> %11651}1652 1653; select(C, binop(select(C, X, Y), W), Z) -> select(C, binop(X, W), Z)1654define i8 @test87(i1 %cond, i8 %w, i8 %x, i8 %y, i8 %z) {1655; CHECK-LABEL: define i8 @test87(1656; CHECK-SAME: i1 [[COND:%.*]], i8 [[W:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {1657; CHECK-NEXT:    [[B:%.*]] = add i8 [[X]], [[W]]1658; CHECK-NEXT:    [[C:%.*]] = select i1 [[COND]], i8 [[B]], i8 [[Z]]1659; CHECK-NEXT:    ret i8 [[C]]1660;1661  %a = select i1 %cond, i8 %x, i8 %y1662  %b = add i8 %a, %w1663  %c = select i1 %cond, i8 %b, i8 %z1664  ret i8 %c1665}1666 1667; select(C, binop(select(C, X, Y), W), Z) -> select(C, Z, binop(Y, W))1668define i8 @test88(i1 %cond, i8 %w, i8 %x, i8 %y, i8 %z) {1669; CHECK-LABEL: define i8 @test88(1670; CHECK-SAME: i1 [[COND:%.*]], i8 [[W:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {1671; CHECK-NEXT:    [[B:%.*]] = sub i8 [[Y]], [[W]]1672; CHECK-NEXT:    [[C:%.*]] = select i1 [[COND]], i8 [[Z]], i8 [[B]]1673; CHECK-NEXT:    ret i8 [[C]]1674;1675  %a = select i1 %cond, i8 %x, i8 %y1676  %b = sub i8 %a, %w1677  %c = select i1 %cond, i8 %z, i8 %b1678  ret i8 %c1679}1680 1681; select(C, Z, binop(W, select(C, X, Y))) -> select(C, binop(X, W), Z)1682define i8 @test89(i1 %cond, i8 %w, i8 %x, i8 %y, i8 %z) {1683; CHECK-LABEL: define i8 @test89(1684; CHECK-SAME: i1 [[COND:%.*]], i8 [[W:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {1685; CHECK-NEXT:    [[B:%.*]] = and i8 [[W]], [[X]]1686; CHECK-NEXT:    [[C:%.*]] = select i1 [[COND]], i8 [[B]], i8 [[Z]]1687; CHECK-NEXT:    ret i8 [[C]]1688;1689  %a = select i1 %cond, i8 %x, i8 %y1690  %b = and i8 %w, %a1691  %c = select i1 %cond, i8 %b, i8 %z1692  ret i8 %c1693}1694 1695; select(C, Z, binop(W, select(C, X, Y))) -> select(C, Z, binop(W, Y))1696define i8 @test90(i1 %cond, i8 %w, i8 %x, i8 %y, i8 %z) {1697; CHECK-LABEL: define i8 @test90(1698; CHECK-SAME: i1 [[COND:%.*]], i8 [[W:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {1699; CHECK-NEXT:    [[B:%.*]] = or i8 [[W]], [[Y]]1700; CHECK-NEXT:    [[C:%.*]] = select i1 [[COND]], i8 [[Z]], i8 [[B]]1701; CHECK-NEXT:    ret i8 [[C]]1702;1703  %a = select i1 %cond, i8 %x, i8 %y1704  %b = or i8 %w, %a1705  %c = select i1 %cond, i8 %z, i8 %b1706  ret i8 %c1707}1708 1709define i32 @test_shl_zext_bool(i1 %t) {1710; CHECK-LABEL: define i32 @test_shl_zext_bool(1711; CHECK-SAME: i1 [[T:%.*]]) {1712; CHECK-NEXT:    [[R:%.*]] = select i1 [[T]], i32 4, i32 01713; CHECK-NEXT:    ret i32 [[R]]1714;1715  %r = select i1 %t, i32 4, i32 01716  ret i32 %r1717}1718 1719define <2 x i32> @test_shl_zext_bool_splat(<2 x i1> %t) {1720; CHECK-LABEL: define <2 x i32> @test_shl_zext_bool_splat(1721; CHECK-SAME: <2 x i1> [[T:%.*]]) {1722; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[T]], <2 x i32> splat (i32 8), <2 x i32> zeroinitializer1723; CHECK-NEXT:    ret <2 x i32> [[R]]1724;1725  %r = select <2 x i1> %t, <2 x i32> <i32 8, i32 8>, <2 x i32> zeroinitializer1726  ret <2 x i32> %r1727}1728 1729define <2 x i32> @test_shl_zext_bool_vec(<2 x i1> %t) {1730; CHECK-LABEL: define <2 x i32> @test_shl_zext_bool_vec(1731; CHECK-SAME: <2 x i1> [[T:%.*]]) {1732; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[T]], <2 x i32> <i32 4, i32 8>, <2 x i32> zeroinitializer1733; CHECK-NEXT:    ret <2 x i32> [[R]]1734;1735  %r = select <2 x i1> %t, <2 x i32> <i32 4, i32 8>, <2 x i32> zeroinitializer1736  ret <2 x i32> %r1737}1738 1739define float @copysign1(float %x) {1740; CHECK-LABEL: define float @copysign1(1741; CHECK-SAME: float [[X:%.*]]) {1742; CHECK-NEXT:    [[R:%.*]] = call float @llvm.copysign.f32(float 1.000000e+00, float [[X]])1743; CHECK-NEXT:    ret float [[R]]1744;1745  %i = bitcast float %x to i321746  %ispos = icmp sgt i32 %i, -11747  %r = select i1 %ispos, float 1.0, float -1.01748  ret float %r1749}1750 1751define float @copysign1_fmf(float %x) {1752; CHECK-LABEL: define float @copysign1_fmf(1753; CHECK-SAME: float [[X:%.*]]) {1754; CHECK-NEXT:    [[R:%.*]] = call float @llvm.copysign.f32(float 1.000000e+00, float [[X]])1755; CHECK-NEXT:    ret float [[R]]1756;1757  %i = bitcast float %x to i321758  %ispos = icmp sgt i32 %i, -11759  %r = select nsz ninf i1 %ispos, float 1.0, float -1.01760  ret float %r1761}1762 1763define <2 x float> @copysign2(<2 x float> %x) {1764; CHECK-LABEL: define <2 x float> @copysign2(1765; CHECK-SAME: <2 x float> [[X:%.*]]) {1766; CHECK-NEXT:    [[TMP1:%.*]] = fneg <2 x float> [[X]]1767; CHECK-NEXT:    [[R:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> splat (float 4.200000e+01), <2 x float> [[TMP1]])1768; CHECK-NEXT:    ret <2 x float> [[R]]1769;1770  %i = bitcast <2 x float> %x to <2 x i32>1771  %isneg = icmp slt <2 x i32> %i, zeroinitializer1772  %r = select nsz <2 x i1> %isneg, <2 x float> <float 42.0, float 42.0>, <2 x float> <float -42.0, float -42.0>1773  ret <2 x float> %r1774}1775 1776define float @copysign3(float %x) {1777; CHECK-LABEL: define float @copysign3(1778; CHECK-SAME: float [[X:%.*]]) {1779; CHECK-NEXT:    [[TMP1:%.*]] = fneg float [[X]]1780; CHECK-NEXT:    [[R:%.*]] = call float @llvm.copysign.f32(float 4.300000e+01, float [[TMP1]])1781; CHECK-NEXT:    ret float [[R]]1782;1783  %i = bitcast float %x to i321784  %ispos = icmp ult i32 %i, 21474836481785  %r = select fast i1 %ispos, float -43.0, float 43.01786  ret float %r1787}1788 1789define <2 x float> @copysign_vec_poison(<2 x float> %x) {1790; CHECK-LABEL: define <2 x float> @copysign_vec_poison(1791; CHECK-SAME: <2 x float> [[X:%.*]]) {1792; CHECK-NEXT:    [[TMP1:%.*]] = fneg <2 x float> [[X]]1793; CHECK-NEXT:    [[R:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> splat (float 4.200000e+01), <2 x float> [[TMP1]])1794; CHECK-NEXT:    ret <2 x float> [[R]]1795;1796  %i = bitcast <2 x float> %x to <2 x i32>1797  %isneg = icmp ugt <2 x i32> %i, <i32 2147483647, i32 2147483647>1798  %r = select arcp nnan <2 x i1> %isneg, <2 x float> <float 42.0, float poison>, <2 x float> <float -42.0, float -42.0>1799  ret <2 x float> %r1800}1801 1802define <2 x float> @copysign_vec_poison1(<2 x float> %x) {1803; CHECK-LABEL: define <2 x float> @copysign_vec_poison1(1804; CHECK-SAME: <2 x float> [[X:%.*]]) {1805; CHECK-NEXT:    [[R:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> splat (float 4.200000e+01), <2 x float> [[X]])1806; CHECK-NEXT:    ret <2 x float> [[R]]1807;1808  %i = bitcast <2 x float> %x to <2 x i32>1809  %isneg = icmp ult <2 x i32> %i, <i32 2147483648, i32 2147483648>1810  %r = select arcp nnan <2 x i1> %isneg, <2 x float> <float 42.0, float 42.0>, <2 x float> <float poison, float -42.0>1811  ret <2 x float> %r1812}1813 1814define <2 x float> @copysign_vec_poison3(<2 x float> %x) {1815; CHECK-LABEL: define <2 x float> @copysign_vec_poison3(1816; CHECK-SAME: <2 x float> [[X:%.*]]) {1817; CHECK-NEXT:    [[R:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> splat (float 4.200000e+01), <2 x float> [[X]])1818; CHECK-NEXT:    ret <2 x float> [[R]]1819;1820  %i = bitcast <2 x float> %x to <2 x i32>1821  %isneg = icmp ugt <2 x i32> %i, <i32 2147483647, i32 2147483647>1822  %r = select arcp nnan <2 x i1> %isneg, <2 x float> <float -42.0, float poison>, <2 x float> <float +42.0, float poison>1823  ret <2 x float> %r1824}1825 1826declare void @use1(i1)1827 1828; Negative test1829 1830define float @copysign_extra_use(float %x) {1831; CHECK-LABEL: define float @copysign_extra_use(1832; CHECK-SAME: float [[X:%.*]]) {1833; CHECK-NEXT:    [[I:%.*]] = bitcast float [[X]] to i321834; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[I]], 01835; CHECK-NEXT:    call void @use1(i1 [[ISNEG]])1836; CHECK-NEXT:    [[R:%.*]] = select i1 [[ISNEG]], float -4.400000e+01, float 4.400000e+011837; CHECK-NEXT:    ret float [[R]]1838;1839  %i = bitcast float %x to i321840  %isneg = icmp ugt i32 %i, 21474836471841  call void @use1(i1 %isneg)1842  %r = select i1 %isneg, float -44.0, float 44.01843  ret float %r1844}1845 1846; Negative test1847 1848define float @copysign_type_mismatch(double %x) {1849; CHECK-LABEL: define float @copysign_type_mismatch(1850; CHECK-SAME: double [[X:%.*]]) {1851; CHECK-NEXT:    [[I:%.*]] = bitcast double [[X]] to i641852; CHECK-NEXT:    [[ISPOS:%.*]] = icmp sgt i64 [[I]], -11853; CHECK-NEXT:    [[R:%.*]] = select i1 [[ISPOS]], float 1.000000e+00, float -1.000000e+001854; CHECK-NEXT:    ret float [[R]]1855;1856  %i = bitcast double %x to i641857  %ispos = icmp sgt i64 %i, -11858  %r = select i1 %ispos, float 1.0, float -1.01859  ret float %r1860}1861 1862; Negative test1863 1864define <2 x float> @copysign_type_mismatch2(<2 x float> %x) {1865; CHECK-LABEL: define <2 x float> @copysign_type_mismatch2(1866; CHECK-SAME: <2 x float> [[X:%.*]]) {1867; CHECK-NEXT:    [[I:%.*]] = bitcast <2 x float> [[X]] to i641868; CHECK-NEXT:    [[ISPOS:%.*]] = icmp sgt i64 [[I]], -11869; CHECK-NEXT:    [[R:%.*]] = select i1 [[ISPOS]], <2 x float> splat (float 1.000000e+00), <2 x float> splat (float -1.000000e+00)1870; CHECK-NEXT:    ret <2 x float> [[R]]1871;1872  %i = bitcast <2 x float> %x to i641873  %ispos = icmp sgt i64 %i, -11874  %r = select i1 %ispos, <2 x float> <float 1.0, float 1.0>, <2 x float> <float -1.0, float -1.0>1875  ret <2 x float> %r1876}1877 1878; Negative test1879 1880define float @copysign_wrong_cmp(float %x) {1881; CHECK-LABEL: define float @copysign_wrong_cmp(1882; CHECK-SAME: float [[X:%.*]]) {1883; CHECK-NEXT:    [[I:%.*]] = bitcast float [[X]] to i321884; CHECK-NEXT:    [[ISPOS:%.*]] = icmp sgt i32 [[I]], 01885; CHECK-NEXT:    [[R:%.*]] = select i1 [[ISPOS]], float 1.000000e+00, float -1.000000e+001886; CHECK-NEXT:    ret float [[R]]1887;1888  %i = bitcast float %x to i321889  %ispos = icmp sgt i32 %i, 01890  %r = select i1 %ispos, float 1.0, float -1.01891  ret float %r1892}1893 1894; Negative test1895 1896define float @copysign_wrong_const(float %x) {1897; CHECK-LABEL: define float @copysign_wrong_const(1898; CHECK-SAME: float [[X:%.*]]) {1899; CHECK-NEXT:    [[I:%.*]] = bitcast float [[X]] to i321900; CHECK-NEXT:    [[ISPOS:%.*]] = icmp sgt i32 [[I]], -11901; CHECK-NEXT:    [[R:%.*]] = select i1 [[ISPOS]], float 2.000000e+00, float -1.000000e+001902; CHECK-NEXT:    ret float [[R]]1903;1904  %i = bitcast float %x to i321905  %ispos = icmp sgt i32 %i, -11906  %r = select i1 %ispos, float 2.0, float -1.01907  ret float %r1908}1909 1910; TODO: we can replace select with a Phi.1911define i32 @select_dominating_cond(i1 %cond, i32 %x, i32 %y) {1912; CHECK-LABEL: define i32 @select_dominating_cond(1913; CHECK-SAME: i1 [[COND:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) {1914; CHECK-NEXT:  [[ENTRY:.*:]]1915; CHECK-NEXT:    br i1 [[COND]], label %[[IF_TRUE:.*]], label %[[IF_FALSE:.*]]1916; CHECK:       [[IF_TRUE]]:1917; CHECK-NEXT:    br label %[[MERGE:.*]]1918; CHECK:       [[IF_FALSE]]:1919; CHECK-NEXT:    br label %[[MERGE]]1920; CHECK:       [[MERGE]]:1921; CHECK-NEXT:    [[S:%.*]] = phi i32 [ [[Y]], %[[IF_FALSE]] ], [ [[X]], %[[IF_TRUE]] ]1922; CHECK-NEXT:    ret i32 [[S]]1923;1924entry:1925  br i1 %cond, label %if.true, label %if.false1926 1927if.true:1928  br label %merge1929 1930if.false:1931  br label %merge1932 1933merge:1934  %s = select i1 %cond, i32 %x, i32 %y1935  ret i32 %s1936}1937 1938define i32 @select_dominating_inverted(i1 %cond, i32 %x, i32 %y) {1939; CHECK-LABEL: define i32 @select_dominating_inverted(1940; CHECK-SAME: i1 [[COND:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) {1941; CHECK-NEXT:  [[ENTRY:.*:]]1942; CHECK-NEXT:    br i1 [[COND]], label %[[IF_FALSE:.*]], label %[[IF_TRUE:.*]]1943; CHECK:       [[IF_TRUE]]:1944; CHECK-NEXT:    br label %[[MERGE:.*]]1945; CHECK:       [[IF_FALSE]]:1946; CHECK-NEXT:    br label %[[MERGE]]1947; CHECK:       [[MERGE]]:1948; CHECK-NEXT:    [[S:%.*]] = phi i32 [ [[X]], %[[IF_FALSE]] ], [ [[Y]], %[[IF_TRUE]] ]1949; CHECK-NEXT:    ret i32 [[S]]1950;1951entry:1952  %inverted = xor i1 %cond, 11953  br i1 %inverted, label %if.true, label %if.false1954 1955if.true:1956  br label %merge1957 1958if.false:1959  br label %merge1960 1961merge:1962  %s = select i1 %cond, i32 %x, i32 %y1963  ret i32 %s1964}1965 1966; More complex CFG: the block with select has multiple predecessors.1967define i32 @select_dominating_cond_multiple_preds(i1 %cond, i1 %cond2, i1 %cond3, i32 %x, i32 %y) {1968; CHECK-LABEL: define i32 @select_dominating_cond_multiple_preds(1969; CHECK-SAME: i1 [[COND:%.*]], i1 [[COND2:%.*]], i1 [[COND3:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) {1970; CHECK-NEXT:  [[ENTRY:.*:]]1971; CHECK-NEXT:    br i1 [[COND]], label %[[IF_TRUE:.*]], label %[[IF_FALSE:.*]]1972; CHECK:       [[IF_TRUE]]:1973; CHECK-NEXT:    br i1 [[COND2]], label %[[IF_TRUE_1:.*]], label %[[IF_TRUE_2:.*]]1974; CHECK:       [[IF_TRUE_1]]:1975; CHECK-NEXT:    br label %[[MERGE:.*]]1976; CHECK:       [[IF_TRUE_2]]:1977; CHECK-NEXT:    br label %[[MERGE]]1978; CHECK:       [[IF_FALSE]]:1979; CHECK-NEXT:    br i1 [[COND3]], label %[[IF_FALSE_1:.*]], label %[[EXIT:.*]]1980; CHECK:       [[IF_FALSE_1]]:1981; CHECK-NEXT:    br label %[[MERGE]]1982; CHECK:       [[MERGE]]:1983; CHECK-NEXT:    [[S:%.*]] = phi i32 [ [[Y]], %[[IF_FALSE_1]] ], [ [[X]], %[[IF_TRUE_2]] ], [ [[X]], %[[IF_TRUE_1]] ]1984; CHECK-NEXT:    ret i32 [[S]]1985; CHECK:       [[EXIT]]:1986; CHECK-NEXT:    ret i32 01987;1988entry:1989  br i1 %cond, label %if.true, label %if.false1990 1991if.true:1992  br i1 %cond2, label %if.true.1, label %if.true.21993 1994if.true.1:1995  br label %merge1996 1997if.true.2:1998  br label %merge1999 2000if.false:2001  br i1 %cond3, label %if.false.1, label %exit2002 2003if.false.1:2004  br label %merge2005 2006merge:2007  %s = select i1 %cond, i32 %x, i32 %y2008  ret i32 %s2009 2010exit:2011  ret i32 02012}2013 2014; More complex CFG for inverted case: the block with select has multiple predecessors.2015define i32 @select_dominating_cond_inverted_multiple_preds(i1 %cond, i1 %cond2, i1 %cond3, i32 %x, i32 %y) {2016; CHECK-LABEL: define i32 @select_dominating_cond_inverted_multiple_preds(2017; CHECK-SAME: i1 [[COND:%.*]], i1 [[COND2:%.*]], i1 [[COND3:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) {2018; CHECK-NEXT:  [[ENTRY:.*:]]2019; CHECK-NEXT:    br i1 [[COND]], label %[[IF_FALSE:.*]], label %[[IF_TRUE:.*]]2020; CHECK:       [[IF_TRUE]]:2021; CHECK-NEXT:    br i1 [[COND2]], label %[[IF_TRUE_1:.*]], label %[[IF_TRUE_2:.*]]2022; CHECK:       [[IF_TRUE_1]]:2023; CHECK-NEXT:    br label %[[MERGE:.*]]2024; CHECK:       [[IF_TRUE_2]]:2025; CHECK-NEXT:    br label %[[MERGE]]2026; CHECK:       [[IF_FALSE]]:2027; CHECK-NEXT:    br i1 [[COND3]], label %[[IF_FALSE_1:.*]], label %[[EXIT:.*]]2028; CHECK:       [[IF_FALSE_1]]:2029; CHECK-NEXT:    br label %[[MERGE]]2030; CHECK:       [[MERGE]]:2031; CHECK-NEXT:    [[S:%.*]] = phi i32 [ [[X]], %[[IF_FALSE_1]] ], [ [[Y]], %[[IF_TRUE_2]] ], [ [[Y]], %[[IF_TRUE_1]] ]2032; CHECK-NEXT:    ret i32 [[S]]2033; CHECK:       [[EXIT]]:2034; CHECK-NEXT:    ret i32 02035;2036entry:2037  %inverted = xor i1 %cond, 12038  br i1 %inverted, label %if.true, label %if.false2039 2040if.true:2041  br i1 %cond2, label %if.true.1, label %if.true.22042 2043if.true.1:2044  br label %merge2045 2046if.true.2:2047  br label %merge2048 2049if.false:2050  br i1 %cond3, label %if.false.1, label %exit2051 2052if.false.1:2053  br label %merge2054 2055merge:2056  %s = select i1 %cond, i32 %x, i32 %y2057  ret i32 %s2058 2059exit:2060  ret i32 02061}2062 2063; More complex CFG for inverted case: the block with select has multiple predecessors that can duplicate.2064define i32 @select_dominating_cond_inverted_multiple_duplicating_preds(i1 %cond, i32 %cond2, i1 %cond3, i32 %x, i32 %y) {2065; CHECK-LABEL: define i32 @select_dominating_cond_inverted_multiple_duplicating_preds(2066; CHECK-SAME: i1 [[COND:%.*]], i32 [[COND2:%.*]], i1 [[COND3:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) {2067; CHECK-NEXT:  [[ENTRY:.*:]]2068; CHECK-NEXT:    br i1 [[COND]], label %[[IF_FALSE:.*]], label %[[IF_TRUE:.*]]2069; CHECK:       [[IF_TRUE]]:2070; CHECK-NEXT:    switch i32 [[COND2]], label %[[SWITCH_CASE_1:.*]] [2071; CHECK-NEXT:      i32 1, label %[[MERGE:.*]]2072; CHECK-NEXT:      i32 2, label %[[MERGE]]2073; CHECK-NEXT:      i32 3, label %[[MERGE]]2074; CHECK-NEXT:    ]2075; CHECK:       [[SWITCH_CASE_1]]:2076; CHECK-NEXT:    br label %[[MERGE]]2077; CHECK:       [[IF_FALSE]]:2078; CHECK-NEXT:    br i1 [[COND3]], label %[[IF_FALSE_1:.*]], label %[[EXIT:.*]]2079; CHECK:       [[IF_FALSE_1]]:2080; CHECK-NEXT:    br label %[[MERGE]]2081; CHECK:       [[MERGE]]:2082; CHECK-NEXT:    [[S:%.*]] = phi i32 [ [[X]], %[[IF_FALSE_1]] ], [ [[Y]], %[[SWITCH_CASE_1]] ], [ [[Y]], %[[IF_TRUE]] ], [ [[Y]], %[[IF_TRUE]] ], [ [[Y]], %[[IF_TRUE]] ]2083; CHECK-NEXT:    ret i32 [[S]]2084; CHECK:       [[EXIT]]:2085; CHECK-NEXT:    ret i32 02086;2087entry:2088  %inverted = xor i1 %cond, 12089  br i1 %inverted, label %if.true, label %if.false2090 2091if.true:2092  switch i32 %cond2, label %switch.case.1 [2093  i32 1, label %merge2094  i32 2, label %merge2095  i32 3, label %merge2096  ]2097 2098switch.case.1:2099  br label %merge2100 2101if.false:2102  br i1 %cond3, label %if.false.1, label %exit2103 2104if.false.1:2105  br label %merge2106 2107merge:2108  %s = select i1 %cond, i32 %x, i32 %y2109  ret i32 %s2110 2111exit:2112  ret i32 02113}2114 2115; Negative test: currently we take condition from IDom, but might be willing to expand it in the future.2116define i32 @select_not_imm_dominating_cond_neg(i1 %cond, i32 %x, i32 %y) {2117; CHECK-LABEL: define i32 @select_not_imm_dominating_cond_neg(2118; CHECK-SAME: i1 [[COND:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) {2119; CHECK-NEXT:  [[ENTRY:.*:]]2120; CHECK-NEXT:    br i1 [[COND]], label %[[IF_TRUE:.*]], label %[[IF_FALSE:.*]]2121; CHECK:       [[IF_TRUE]]:2122; CHECK-NEXT:    br label %[[MERGE:.*]]2123; CHECK:       [[IF_FALSE]]:2124; CHECK-NEXT:    br label %[[MERGE]]2125; CHECK:       [[MERGE]]:2126; CHECK-NEXT:    br label %[[EXIT:.*]]2127; CHECK:       [[EXIT]]:2128; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND]], i32 [[X]], i32 [[Y]]2129; CHECK-NEXT:    ret i32 [[S]]2130;2131entry:2132  br i1 %cond, label %if.true, label %if.false2133 2134if.true:2135  br label %merge2136 2137if.false:2138  br label %merge2139 2140merge:2141  br label %exit2142 2143exit:2144  %s = select i1 %cond, i32 %x, i32 %y2145  ret i32 %s2146}2147 2148; Shows how we can leverage dominance to eliminate duplicating selects.2149define i32 @select_dominance_chain(i1 %cond, i32 %x, i32 %y) {2150; CHECK-LABEL: define i32 @select_dominance_chain(2151; CHECK-SAME: i1 [[COND:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) {2152; CHECK-NEXT:  [[ENTRY:.*:]]2153; CHECK-NEXT:    br i1 [[COND]], label %[[IF_TRUE_1:.*]], label %[[IF_FALSE_1:.*]]2154; CHECK:       [[IF_TRUE_1]]:2155; CHECK-NEXT:    br label %[[MERGE_1:.*]]2156; CHECK:       [[IF_FALSE_1]]:2157; CHECK-NEXT:    br label %[[MERGE_1]]2158; CHECK:       [[MERGE_1]]:2159; CHECK-NEXT:    br i1 [[COND]], label %[[IF_TRUE_2:.*]], label %[[IF_FALSE_2:.*]]2160; CHECK:       [[IF_TRUE_2]]:2161; CHECK-NEXT:    br label %[[MERGE_2:.*]]2162; CHECK:       [[IF_FALSE_2]]:2163; CHECK-NEXT:    br label %[[MERGE_2]]2164; CHECK:       [[MERGE_2]]:2165; CHECK-NEXT:    br i1 [[COND]], label %[[IF_TRUE_3:.*]], label %[[IF_FALSE_3:.*]]2166; CHECK:       [[IF_TRUE_3]]:2167; CHECK-NEXT:    br label %[[MERGE_3:.*]]2168; CHECK:       [[IF_FALSE_3]]:2169; CHECK-NEXT:    br label %[[MERGE_3]]2170; CHECK:       [[MERGE_3]]:2171; CHECK-NEXT:    [[S_1:%.*]] = phi i32 [ [[Y]], %[[IF_FALSE_3]] ], [ [[X]], %[[IF_TRUE_3]] ]2172; CHECK-NEXT:    [[SUM_2:%.*]] = mul i32 [[S_1]], 32173; CHECK-NEXT:    ret i32 [[SUM_2]]2174;2175entry:2176  br i1 %cond, label %if.true.1, label %if.false.12177 2178if.true.1:2179  br label %merge.12180 2181if.false.1:2182  br label %merge.12183 2184merge.1:2185  %s.1 = select i1 %cond, i32 %x, i32 %y2186  br i1 %cond, label %if.true.2, label %if.false.22187 2188if.true.2:2189  br label %merge.22190 2191if.false.2:2192  br label %merge.22193 2194merge.2:2195  %s.2 = select i1 %cond, i32 %x, i32 %y2196  br i1 %cond, label %if.true.3, label %if.false.32197 2198if.true.3:2199  br label %merge.32200 2201if.false.3:2202  br label %merge.32203 2204merge.3:2205  %s.3 = select i1 %cond, i32 %x, i32 %y2206  %sum.1 = add i32 %s.1, %s.22207  %sum.2 = add i32 %sum.1, %s.32208  ret i32 %sum.22209}2210 2211; TODO: We can replace select with a Phi and then sink a and b to respective2212; branches.2213define i32 @select_dominating_cond_and_sink(i1 %cond, i32 %x, i32 %y) {2214; CHECK-LABEL: define i32 @select_dominating_cond_and_sink(2215; CHECK-SAME: i1 [[COND:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) {2216; CHECK-NEXT:  [[ENTRY:.*:]]2217; CHECK-NEXT:    br i1 [[COND]], label %[[IF_TRUE:.*]], label %[[IF_FALSE:.*]]2218; CHECK:       [[IF_TRUE]]:2219; CHECK-NEXT:    br label %[[MERGE:.*]]2220; CHECK:       [[IF_FALSE]]:2221; CHECK-NEXT:    br label %[[MERGE]]2222; CHECK:       [[MERGE]]:2223; CHECK-NEXT:    [[B:%.*]] = mul i32 [[X]], [[Y]]2224; CHECK-NEXT:    [[A:%.*]] = add i32 [[X]], [[Y]]2225; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]]2226; CHECK-NEXT:    ret i32 [[S]]2227;2228entry:2229  %a = add i32 %x, %y2230  %b = mul i32 %x, %y2231  br i1 %cond, label %if.true, label %if.false2232 2233if.true:2234  br label %merge2235 2236if.false:2237  br label %merge2238 2239merge:2240  %s = select i1 %cond, i32 %a, i32 %b2241  ret i32 %s2242}2243 2244define i32 @select_dominating_cond_same_labels(i1 %cond) {2245; CHECK-LABEL: define i32 @select_dominating_cond_same_labels(2246; CHECK-SAME: i1 [[COND:%.*]]) {2247; CHECK-NEXT:  [[ENTRY:.*:]]2248; CHECK-NEXT:    br i1 false, label %[[EXIT:.*]], label %[[EXIT]]2249; CHECK:       [[EXIT]]:2250; CHECK-NEXT:    [[RESULT:%.*]] = select i1 [[COND]], i32 123, i32 4562251; CHECK-NEXT:    ret i32 [[RESULT]]2252;2253entry:2254  %result = select i1 %cond, i32 123, i32 4562255  br i1 %cond, label %exit, label %exit2256exit:2257  ret i32 %result2258}2259 2260define i32 @select_phi_same_condition(i1 %cond, i32 %x, i32 %y, i32 %z) {2261; CHECK-LABEL: define i32 @select_phi_same_condition(2262; CHECK-SAME: i1 [[COND:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {2263; CHECK-NEXT:  [[ENTRY:.*:]]2264; CHECK-NEXT:    br i1 [[COND]], label %[[IF_TRUE:.*]], label %[[IF_FALSE:.*]]2265; CHECK:       [[IF_TRUE]]:2266; CHECK-NEXT:    br label %[[MERGE:.*]]2267; CHECK:       [[IF_FALSE]]:2268; CHECK-NEXT:    br label %[[MERGE]]2269; CHECK:       [[MERGE]]:2270; CHECK-NEXT:    [[S:%.*]] = phi i32 [ [[X]], %[[IF_TRUE]] ], [ [[Z]], %[[IF_FALSE]] ]2271; CHECK-NEXT:    ret i32 [[S]]2272;2273entry:2274  br i1 %cond, label %if.true, label %if.false2275 2276if.true:2277  br label %merge2278 2279if.false:2280  br label %merge2281 2282merge:2283  %phi = phi i32 [0, %if.true], [%z, %if.false]2284  %s = select i1 %cond, i32 %x, i32 %phi2285  ret i32 %s2286}2287 2288 2289; TODO: Replace with phi[a, c] and sink them to respective branches.2290define i32 @select_phi_same_condition_sink(i1 %cond, i32 %x, i32 %y, i32 %z) {2291; CHECK-LABEL: define i32 @select_phi_same_condition_sink(2292; CHECK-SAME: i1 [[COND:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {2293; CHECK-NEXT:  [[ENTRY:.*:]]2294; CHECK-NEXT:    br i1 [[COND]], label %[[IF_TRUE:.*]], label %[[IF_FALSE:.*]]2295; CHECK:       [[IF_TRUE]]:2296; CHECK-NEXT:    br label %[[MERGE:.*]]2297; CHECK:       [[IF_FALSE]]:2298; CHECK-NEXT:    [[B:%.*]] = mul i32 [[X]], [[Z]]2299; CHECK-NEXT:    br label %[[MERGE]]2300; CHECK:       [[MERGE]]:2301; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 0, %[[IF_TRUE]] ], [ [[B]], %[[IF_FALSE]] ]2302; CHECK-NEXT:    [[A:%.*]] = add i32 [[X]], [[Y]]2303; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[PHI]]2304; CHECK-NEXT:    ret i32 [[S]]2305;2306entry:2307  %a = add i32 %x, %y2308  %b = mul i32 %x, %z2309  br i1 %cond, label %if.true, label %if.false2310 2311if.true:2312  br label %merge2313 2314if.false:2315  br label %merge2316 2317merge:2318  %phi = phi i32 [0, %if.true], [%b, %if.false]2319  %s = select i1 %cond, i32 %a, i32 %phi2320  ret i32 %s2321}2322 2323declare i32 @__gxx_personality_v0(...)2324declare i1 @foo()2325 2326define i32 @test_invoke_neg(i32 %x, i32 %y) nounwind uwtable ssp personality ptr @__gxx_personality_v0 {2327; CHECK-LABEL: define i32 @test_invoke_neg(2328; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) #[[ATTR4:[0-9]+]] personality ptr @__gxx_personality_v0 {2329; CHECK-NEXT:  [[ENTRY:.*:]]2330; CHECK-NEXT:    [[COND:%.*]] = invoke i1 @foo()2331; CHECK-NEXT:            to label %[[INVOKE_CONT:.*]] unwind label %[[LPAD:.*]]2332; CHECK:       [[INVOKE_CONT]]:2333; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], i32 [[X]], i32 [[Y]]2334; CHECK-NEXT:    ret i32 [[SEL]]2335; CHECK:       [[LPAD]]:2336; CHECK-NEXT:    [[LP:%.*]] = landingpad { i1, i32 }2337; CHECK-NEXT:            filter [0 x i1] zeroinitializer2338; CHECK-NEXT:    unreachable2339;2340entry:2341  %cond = invoke i1 @foo()2342  to label %invoke.cont unwind label %lpad2343 2344invoke.cont:2345  %sel = select i1 %cond, i32 %x, i32 %y2346  ret i32 %sel2347 2348lpad:2349  %lp = landingpad { i1, i32 }2350  filter [0 x i1] zeroinitializer2351  unreachable2352}2353 2354declare i32 @bar()2355 2356define i32 @test_invoke_2_neg(i1 %cond, i32 %x, i32 %y) nounwind uwtable ssp personality ptr @__gxx_personality_v0 {2357; CHECK-LABEL: define i32 @test_invoke_2_neg(2358; CHECK-SAME: i1 [[COND:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) #[[ATTR4]] personality ptr @__gxx_personality_v0 {2359; CHECK-NEXT:  [[ENTRY:.*:]]2360; CHECK-NEXT:    br i1 [[COND]], label %[[IF_TRUE:.*]], label %[[IF_FALSE:.*]]2361; CHECK:       [[IF_TRUE]]:2362; CHECK-NEXT:    br label %[[MERGE:.*]]2363; CHECK:       [[IF_FALSE]]:2364; CHECK-NEXT:    [[RESULT:%.*]] = invoke i32 @bar()2365; CHECK-NEXT:            to label %[[MERGE]] unwind label %[[LPAD:.*]]2366; CHECK:       [[MERGE]]:2367; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 0, %[[IF_TRUE]] ], [ [[RESULT]], %[[IF_FALSE]] ]2368; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], i32 1, i32 [[PHI]]2369; CHECK-NEXT:    ret i32 [[SEL]]2370; CHECK:       [[LPAD]]:2371; CHECK-NEXT:    [[LP:%.*]] = landingpad { i1, i32 }2372; CHECK-NEXT:            filter [0 x i1] zeroinitializer2373; CHECK-NEXT:    unreachable2374;2375entry:2376  br i1 %cond, label %if.true, label %if.false2377 2378if.true:2379  br label %merge2380 2381if.false:2382  %result = invoke i32 @bar()2383  to label %merge unwind label %lpad2384 2385merge:2386  %phi = phi i32 [ 0, %if.true ], [ %result, %if.false ]2387  %sel = select i1 %cond, i32 1, i32 %phi2388  ret i32 %sel2389 2390lpad:2391  %lp = landingpad { i1, i32 }2392  filter [0 x i1] zeroinitializer2393  unreachable2394}2395 2396define i32 @select_phi_same_condition_switch(i1 %cond, i32 %x, i32 %y) {2397; CHECK-LABEL: define i32 @select_phi_same_condition_switch(2398; CHECK-SAME: i1 [[COND:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) {2399; CHECK-NEXT:  [[ENTRY:.*:]]2400; CHECK-NEXT:    br i1 [[COND]], label %[[IF_TRUE:.*]], label %[[IF_FALSE:.*]]2401; CHECK:       [[IF_TRUE]]:2402; CHECK-NEXT:    switch i32 [[X]], label %[[EXIT:.*]] [2403; CHECK-NEXT:      i32 1, label %[[MERGE:.*]]2404; CHECK-NEXT:      i32 2, label %[[MERGE]]2405; CHECK-NEXT:    ]2406; CHECK:       [[EXIT]]:2407; CHECK-NEXT:    ret i32 02408; CHECK:       [[IF_FALSE]]:2409; CHECK-NEXT:    br label %[[MERGE]]2410; CHECK:       [[MERGE]]:2411; CHECK-NEXT:    [[S:%.*]] = phi i32 [ [[X]], %[[IF_TRUE]] ], [ [[X]], %[[IF_TRUE]] ], [ [[Y]], %[[IF_FALSE]] ]2412; CHECK-NEXT:    ret i32 [[S]]2413;2414entry:2415  br i1 %cond, label %if.true, label %if.false2416 2417if.true:2418  switch i32 %x, label %exit [2419  i32 1, label %merge2420  i32 2, label %merge2421  ]2422 2423exit:2424  ret i32 02425 2426if.false:2427  br label %merge2428 2429merge:2430  %phi = phi i32 [0, %if.true], [0, %if.true], [%y, %if.false]2431  %s = select i1 %cond, i32 %x, i32 %phi2432  ret i32 %s2433}2434 2435define i32 @transit_different_values_through_phi(i1 %cond, i1 %cond2) {2436; CHECK-LABEL: define i32 @transit_different_values_through_phi(2437; CHECK-SAME: i1 [[COND:%.*]], i1 [[COND2:%.*]]) {2438; CHECK-NEXT:  [[ENTRY:.*:]]2439; CHECK-NEXT:    br i1 [[COND]], label %[[IF_TRUE:.*]], label %[[IF_FALSE:.*]]2440; CHECK:       [[IF_TRUE]]:2441; CHECK-NEXT:    br i1 [[COND2]], label %[[IF_TRUE_1:.*]], label %[[IF_TRUE_2:.*]]2442; CHECK:       [[IF_TRUE_1]]:2443; CHECK-NEXT:    br label %[[MERGE:.*]]2444; CHECK:       [[IF_TRUE_2]]:2445; CHECK-NEXT:    br label %[[MERGE]]2446; CHECK:       [[IF_FALSE]]:2447; CHECK-NEXT:    br label %[[MERGE]]2448; CHECK:       [[MERGE]]:2449; CHECK-NEXT:    [[S:%.*]] = phi i32 [ 1, %[[IF_TRUE_1]] ], [ 2, %[[IF_TRUE_2]] ], [ 3, %[[IF_FALSE]] ]2450; CHECK-NEXT:    ret i32 [[S]]2451; CHECK:       [[EXIT:.*:]]2452; CHECK-NEXT:    ret i32 02453;2454entry:2455  br i1 %cond, label %if.true, label %if.false2456 2457if.true:2458  br i1 %cond2, label %if.true.1, label %if.true.22459 2460if.true.1:2461  br label %merge2462 2463if.true.2:2464  br label %merge2465 2466if.false:2467  br label %merge2468 2469merge:2470  %p = phi i32 [ 1, %if.true.1 ], [ 2, %if.true.2 ], [ 4, %if.false ]2471  %s = select i1 %cond, i32 %p, i32 32472  ret i32 %s2473 2474exit:2475  ret i32 02476}2477 2478define i32 @select_phi_degenerate(i1 %cond, i1 %cond2) {2479; CHECK-LABEL: define i32 @select_phi_degenerate(2480; CHECK-SAME: i1 [[COND:%.*]], i1 [[COND2:%.*]]) {2481; CHECK-NEXT:  [[ENTRY:.*]]:2482; CHECK-NEXT:    br i1 [[COND]], label %[[LOOP:.*]], label %[[EXIT:.*]]2483; CHECK:       [[LOOP]]:2484; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_INC:%.*]], %[[LOOP]] ]2485; CHECK-NEXT:    [[IV_INC]] = add i32 [[IV]], 12486; CHECK-NEXT:    br i1 [[COND2]], label %[[LOOP]], label %[[EXIT2:.*]]2487; CHECK:       [[EXIT]]:2488; CHECK-NEXT:    ret i32 02489; CHECK:       [[EXIT2]]:2490; CHECK-NEXT:    ret i32 [[IV_INC]]2491;2492entry:2493  br i1 %cond, label %loop, label %exit2494 2495loop:2496  %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]2497  %select = select i1 %cond, i32 %iv, i32 -12498  %iv.inc = add i32 %select, 12499  br i1 %cond2, label %loop, label %exit22500 2501exit:2502  ret i32 02503 2504exit2:2505  ret i32 %iv.inc2506}2507 2508define i32 @test_select_into_phi_not_idom(i1 %cond, i32 %A, i32 %B)  {2509; CHECK-LABEL: define i32 @test_select_into_phi_not_idom(2510; CHECK-SAME: i1 [[COND:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {2511; CHECK-NEXT:  [[ENTRY:.*:]]2512; CHECK-NEXT:    br i1 [[COND]], label %[[IF_TRUE:.*]], label %[[IF_FALSE:.*]]2513; CHECK:       [[IF_TRUE]]:2514; CHECK-NEXT:    br label %[[MERGE:.*]]2515; CHECK:       [[IF_FALSE]]:2516; CHECK-NEXT:    br label %[[MERGE]]2517; CHECK:       [[MERGE]]:2518; CHECK-NEXT:    br label %[[EXIT:.*]]2519; CHECK:       [[EXIT]]:2520; CHECK-NEXT:    ret i32 [[A]]2521;2522entry:2523  br i1 %cond, label %if.true, label %if.false2524 2525if.true:2526  br label %merge2527 2528if.false:2529  br label %merge2530 2531merge:2532  %phi = phi i32 [%A, %if.true], [%B, %if.false]2533  br label %exit2534 2535exit:2536  %sel = select i1 %cond, i32 %phi, i32 %A2537  ret i32 %sel2538}2539 2540define i32 @test_select_into_phi_not_idom_2(i1 %cond, i32 %A, i32 %B)  {2541; CHECK-LABEL: define i32 @test_select_into_phi_not_idom_2(2542; CHECK-SAME: i1 [[COND:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {2543; CHECK-NEXT:  [[ENTRY:.*:]]2544; CHECK-NEXT:    br i1 [[COND]], label %[[IF_TRUE:.*]], label %[[IF_FALSE:.*]]2545; CHECK:       [[IF_TRUE]]:2546; CHECK-NEXT:    br label %[[MERGE:.*]]2547; CHECK:       [[IF_FALSE]]:2548; CHECK-NEXT:    br label %[[MERGE]]2549; CHECK:       [[MERGE]]:2550; CHECK-NEXT:    br label %[[EXIT:.*]]2551; CHECK:       [[EXIT]]:2552; CHECK-NEXT:    ret i32 [[B]]2553;2554entry:2555  br i1 %cond, label %if.true, label %if.false2556 2557if.true:2558  br label %merge2559 2560if.false:2561  br label %merge2562 2563merge:2564  %phi = phi i32 [%A, %if.true], [%B, %if.false]2565  br label %exit2566 2567exit:2568  %sel = select i1 %cond, i32 %B, i32 %phi2569  ret i32 %sel2570}2571 2572define i32 @test_select_into_phi_not_idom_inverted(i1 %cond, i32 %A, i32 %B)  {2573; CHECK-LABEL: define i32 @test_select_into_phi_not_idom_inverted(2574; CHECK-SAME: i1 [[COND:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {2575; CHECK-NEXT:  [[ENTRY:.*:]]2576; CHECK-NEXT:    br i1 [[COND]], label %[[IF_FALSE:.*]], label %[[IF_TRUE:.*]]2577; CHECK:       [[IF_TRUE]]:2578; CHECK-NEXT:    br label %[[MERGE:.*]]2579; CHECK:       [[IF_FALSE]]:2580; CHECK-NEXT:    br label %[[MERGE]]2581; CHECK:       [[MERGE]]:2582; CHECK-NEXT:    [[SEL:%.*]] = phi i32 [ [[A]], %[[IF_TRUE]] ], [ [[B]], %[[IF_FALSE]] ]2583; CHECK-NEXT:    br label %[[EXIT:.*]]2584; CHECK:       [[EXIT]]:2585; CHECK-NEXT:    ret i32 [[SEL]]2586;2587entry:2588  %inverted = xor i1 %cond, 12589  br i1 %inverted, label %if.true, label %if.false2590 2591if.true:2592  br label %merge2593 2594if.false:2595  br label %merge2596 2597merge:2598  %phi = phi i32 [%A, %if.true], [%B, %if.false]2599  br label %exit2600 2601exit:2602  %sel = select i1 %cond, i32 %phi, i32 %A2603  ret i32 %sel2604}2605 2606define i32 @test_select_into_phi_not_idom_inverted_2(i1 %cond, i32 %A, i32 %B)  {2607; CHECK-LABEL: define i32 @test_select_into_phi_not_idom_inverted_2(2608; CHECK-SAME: i1 [[COND:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {2609; CHECK-NEXT:  [[ENTRY:.*:]]2610; CHECK-NEXT:    br i1 [[COND]], label %[[IF_FALSE:.*]], label %[[IF_TRUE:.*]]2611; CHECK:       [[IF_TRUE]]:2612; CHECK-NEXT:    br label %[[MERGE:.*]]2613; CHECK:       [[IF_FALSE]]:2614; CHECK-NEXT:    br label %[[MERGE]]2615; CHECK:       [[MERGE]]:2616; CHECK-NEXT:    [[SEL:%.*]] = phi i32 [ [[A]], %[[IF_TRUE]] ], [ [[B]], %[[IF_FALSE]] ]2617; CHECK-NEXT:    br label %[[EXIT:.*]]2618; CHECK:       [[EXIT]]:2619; CHECK-NEXT:    ret i32 [[SEL]]2620;2621entry:2622  %inverted = xor i1 %cond, 12623  br i1 %inverted, label %if.true, label %if.false2624 2625if.true:2626  br label %merge2627 2628if.false:2629  br label %merge2630 2631merge:2632  %phi = phi i32 [%A, %if.true], [%B, %if.false]2633  br label %exit2634 2635exit:2636  %sel = select i1 %cond, i32 %B, i32 %phi2637  ret i32 %sel2638}2639 2640define i32 @test_select_into_phi_not_idom_no_dom_input_1(i1 %cond, i32 %A, i32 %B, ptr %p)  {2641; CHECK-LABEL: define i32 @test_select_into_phi_not_idom_no_dom_input_1(2642; CHECK-SAME: i1 [[COND:%.*]], i32 [[A:%.*]], i32 [[B:%.*]], ptr [[P:%.*]]) {2643; CHECK-NEXT:  [[ENTRY:.*:]]2644; CHECK-NEXT:    br i1 [[COND]], label %[[IF_TRUE:.*]], label %[[IF_FALSE:.*]]2645; CHECK:       [[IF_TRUE]]:2646; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[P]], align 42647; CHECK-NEXT:    br label %[[MERGE:.*]]2648; CHECK:       [[IF_FALSE]]:2649; CHECK-NEXT:    br label %[[MERGE]]2650; CHECK:       [[MERGE]]:2651; CHECK-NEXT:    [[SEL:%.*]] = phi i32 [ [[C]], %[[IF_TRUE]] ], [ [[A]], %[[IF_FALSE]] ]2652; CHECK-NEXT:    br label %[[EXIT:.*]]2653; CHECK:       [[EXIT]]:2654; CHECK-NEXT:    ret i32 [[SEL]]2655;2656entry:2657  br i1 %cond, label %if.true, label %if.false2658 2659if.true:2660  %C = load i32, ptr %p2661  br label %merge2662 2663if.false:2664  br label %merge2665 2666merge:2667  %phi = phi i32 [%C, %if.true], [%B, %if.false]2668  br label %exit2669 2670exit:2671  %sel = select i1 %cond, i32 %phi, i32 %A2672  ret i32 %sel2673}2674 2675define i32 @test_select_into_phi_not_idom_no_dom_input_2(i1 %cond, i32 %A, i32 %B, ptr %p)  {2676; CHECK-LABEL: define i32 @test_select_into_phi_not_idom_no_dom_input_2(2677; CHECK-SAME: i1 [[COND:%.*]], i32 [[A:%.*]], i32 [[B:%.*]], ptr [[P:%.*]]) {2678; CHECK-NEXT:  [[ENTRY:.*:]]2679; CHECK-NEXT:    br i1 [[COND]], label %[[IF_TRUE:.*]], label %[[IF_FALSE:.*]]2680; CHECK:       [[IF_TRUE]]:2681; CHECK-NEXT:    br label %[[MERGE:.*]]2682; CHECK:       [[IF_FALSE]]:2683; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[P]], align 42684; CHECK-NEXT:    br label %[[MERGE]]2685; CHECK:       [[MERGE]]:2686; CHECK-NEXT:    [[SEL:%.*]] = phi i32 [ [[B]], %[[IF_TRUE]] ], [ [[C]], %[[IF_FALSE]] ]2687; CHECK-NEXT:    br label %[[EXIT:.*]]2688; CHECK:       [[EXIT]]:2689; CHECK-NEXT:    ret i32 [[SEL]]2690;2691entry:2692  br i1 %cond, label %if.true, label %if.false2693 2694if.true:2695  br label %merge2696 2697if.false:2698  %C = load i32, ptr %p2699  br label %merge2700 2701merge:2702  %phi = phi i32 [%A, %if.true], [%C, %if.false]2703  br label %exit2704 2705exit:2706  %sel = select i1 %cond, i32 %B, i32 %phi2707  ret i32 %sel2708}2709 2710; Negative tests to ensure we don't remove selects with undef true/false values.2711; See https://bugs.llvm.org/show_bug.cgi?id=316332712; https://lists.llvm.org/pipermail/llvm-dev/2016-October/106182.html2713; https://reviews.llvm.org/D833602714define i32 @false_undef(i1 %cond, i32 %x) {2715; CHECK-LABEL: define i32 @false_undef(2716; CHECK-SAME: i1 [[COND:%.*]], i32 [[X:%.*]]) {2717; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND]], i32 [[X]], i32 undef2718; CHECK-NEXT:    ret i32 [[S]]2719;2720  %s = select i1 %cond, i32 %x, i32 undef2721  ret i32 %s2722}2723 2724define i32 @true_undef(i1 %cond, i32 %x) {2725; CHECK-LABEL: define i32 @true_undef(2726; CHECK-SAME: i1 [[COND:%.*]], i32 [[X:%.*]]) {2727; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND]], i32 undef, i32 [[X]]2728; CHECK-NEXT:    ret i32 [[S]]2729;2730  %s = select i1 %cond, i32 undef, i32 %x2731  ret i32 %s2732}2733 2734define <2 x i32> @false_undef_vec(i1 %cond, <2 x i32> %x) {2735; CHECK-LABEL: define <2 x i32> @false_undef_vec(2736; CHECK-SAME: i1 [[COND:%.*]], <2 x i32> [[X:%.*]]) {2737; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND]], <2 x i32> [[X]], <2 x i32> undef2738; CHECK-NEXT:    ret <2 x i32> [[S]]2739;2740  %s = select i1 %cond, <2 x i32> %x, <2 x i32> undef2741  ret <2 x i32> %s2742}2743 2744define <2 x i32> @true_undef_vec(i1 %cond, <2 x i32> %x) {2745; CHECK-LABEL: define <2 x i32> @true_undef_vec(2746; CHECK-SAME: i1 [[COND:%.*]], <2 x i32> [[X:%.*]]) {2747; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND]], <2 x i32> undef, <2 x i32> [[X]]2748; CHECK-NEXT:    ret <2 x i32> [[S]]2749;2750  %s = select i1 %cond, <2 x i32> undef, <2 x i32> %x2751  ret <2 x i32> %s2752}2753 2754define i8 @cond_freeze(i8 %x, i8 %y) {2755; CHECK-LABEL: define i8 @cond_freeze(2756; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {2757; CHECK-NEXT:    ret i8 [[Y]]2758;2759  %cond.fr = freeze i1 undef2760  %s = select i1 %cond.fr, i8 %x, i8 %y2761  ret i8 %s2762}2763 2764define i8 @cond_freeze_constant_false_val(i8 %x) {2765; CHECK-LABEL: define i8 @cond_freeze_constant_false_val(2766; CHECK-SAME: i8 [[X:%.*]]) {2767; CHECK-NEXT:    ret i8 12768;2769  %cond.fr = freeze i1 undef2770  %s = select i1 %cond.fr, i8 %x, i8 12771  ret i8 %s2772}2773 2774define i8 @cond_freeze_constant_true_val(i8 %x) {2775; CHECK-LABEL: define i8 @cond_freeze_constant_true_val(2776; CHECK-SAME: i8 [[X:%.*]]) {2777; CHECK-NEXT:    ret i8 12778;2779  %cond.fr = freeze i1 undef2780  %s = select i1 %cond.fr, i8 1, i8 %x2781  ret i8 %s2782}2783 2784define i8 @cond_freeze_both_arms_constant() {2785; CHECK-LABEL: define i8 @cond_freeze_both_arms_constant() {2786; CHECK-NEXT:    ret i8 422787;2788  %cond.fr = freeze i1 undef2789  %s = select i1 %cond.fr, i8 42, i8 32790  ret i8 %s2791}2792 2793define <2 x i8> @cond_freeze_constant_true_val_vec(<2 x i8> %x) {2794; CHECK-LABEL: define <2 x i8> @cond_freeze_constant_true_val_vec(2795; CHECK-SAME: <2 x i8> [[X:%.*]]) {2796; CHECK-NEXT:    ret <2 x i8> <i8 1, i8 2>2797;2798  %cond.fr = freeze <2 x i1> <i1 undef, i1 undef>2799  %s = select <2 x i1> %cond.fr, <2 x i8> <i8 1, i8 2>, <2 x i8> %x2800  ret <2 x i8> %s2801}2802 2803define <2 x i8> @partial_cond_freeze_constant_true_val_vec(<2 x i8> %x) {2804; CHECK-LABEL: define <2 x i8> @partial_cond_freeze_constant_true_val_vec(2805; CHECK-SAME: <2 x i8> [[X:%.*]]) {2806; CHECK-NEXT:    ret <2 x i8> <i8 1, i8 2>2807;2808  %cond.fr = freeze <2 x i1> <i1 true, i1 undef>2809  %s = select <2 x i1> %cond.fr, <2 x i8> <i8 1, i8 2>, <2 x i8> %x2810  ret <2 x i8> %s2811}2812 2813define <2 x i8> @partial_cond_freeze_constant_false_val_vec(<2 x i8> %x) {2814; CHECK-LABEL: define <2 x i8> @partial_cond_freeze_constant_false_val_vec(2815; CHECK-SAME: <2 x i8> [[X:%.*]]) {2816; CHECK-NEXT:    ret <2 x i8> [[X]]2817;2818  %cond.fr = freeze <2 x i1> <i1 true, i1 undef>2819  %s = select <2 x i1> %cond.fr, <2 x i8> %x, <2 x i8> <i8 1, i8 2>2820  ret <2 x i8> %s2821}2822 2823define <2 x i8> @partial_cond_freeze_both_arms_constant_vec() {2824; CHECK-LABEL: define <2 x i8> @partial_cond_freeze_both_arms_constant_vec() {2825; CHECK-NEXT:    ret <2 x i8> <i8 42, i8 43>2826;2827  %cond.fr = freeze <2 x i1> <i1 false, i1 undef>2828  %s = select <2 x i1> %cond.fr, <2 x i8> <i8 1, i8 2>, <2 x i8> <i8 42, i8 43>2829  ret <2 x i8> %s2830}2831 2832declare void @foo2(i8, i8)2833 2834define void @cond_freeze_multipleuses(i8 %x, i8 %y) {2835; CHECK-LABEL: define void @cond_freeze_multipleuses(2836; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {2837; CHECK-NEXT:    call void @foo2(i8 [[Y]], i8 [[X]])2838; CHECK-NEXT:    ret void2839;2840  %cond.fr = freeze i1 undef2841  %s = select i1 %cond.fr, i8 %x, i8 %y2842  %s2 = select i1 %cond.fr, i8 %y, i8 %x2843  call void @foo2(i8 %s, i8 %s2)2844  ret void2845}2846 2847define i32 @select_freeze_icmp_eq(i32 %x, i32 %y) {2848; CHECK-LABEL: define i32 @select_freeze_icmp_eq(2849; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {2850; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i32 [[Y]]2851; CHECK-NEXT:    ret i32 [[Y_FR]]2852;2853  %c = icmp eq i32 %x, %y2854  %c.fr = freeze i1 %c2855  %v = select i1 %c.fr, i32 %x, i32 %y2856  ret i32 %v2857}2858 2859define i32 @select_freeze_icmp_ne(i32 %x, i32 %y) {2860; CHECK-LABEL: define i32 @select_freeze_icmp_ne(2861; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {2862; CHECK-NEXT:    [[X_FR:%.*]] = freeze i32 [[X]]2863; CHECK-NEXT:    ret i32 [[X_FR]]2864;2865  %c = icmp ne i32 %x, %y2866  %c.fr = freeze i1 %c2867  %v = select i1 %c.fr, i32 %x, i32 %y2868  ret i32 %v2869}2870 2871define i32 @select_freeze_icmp_else(i32 %x, i32 %y) {2872; CHECK-LABEL: define i32 @select_freeze_icmp_else(2873; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {2874; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i32 [[Y]]2875; CHECK-NEXT:    [[X_FR:%.*]] = freeze i32 [[X]]2876; CHECK-NEXT:    [[V:%.*]] = call i32 @llvm.umin.i32(i32 [[X_FR]], i32 [[Y_FR]])2877; CHECK-NEXT:    ret i32 [[V]]2878;2879  %c = icmp ult i32 %x, %y2880  %c.fr = freeze i1 %c2881  %v = select i1 %c.fr, i32 %x, i32 %y2882  ret i32 %v2883}2884 2885declare void @use_i1_i32(i1, i32)2886 2887define void @select_freeze_icmp_multuses(i32 %x, i32 %y) {2888; CHECK-LABEL: define void @select_freeze_icmp_multuses(2889; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {2890; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i32 [[Y]]2891; CHECK-NEXT:    [[V:%.*]] = freeze i32 [[X]]2892; CHECK-NEXT:    [[C_FR:%.*]] = icmp ne i32 [[V]], [[Y_FR]]2893; CHECK-NEXT:    call void @use_i1_i32(i1 [[C_FR]], i32 [[V]])2894; CHECK-NEXT:    ret void2895;2896  %c = icmp ne i32 %x, %y2897  %c.fr = freeze i1 %c2898  %v = select i1 %c.fr, i32 %x, i32 %y2899  call void @use_i1_i32(i1 %c.fr, i32 %v)2900  ret void2901}2902 2903define i32 @pr47322_more_poisonous_replacement(i32 %arg) {2904; CHECK-LABEL: define i32 @pr47322_more_poisonous_replacement(2905; CHECK-SAME: i32 [[ARG:%.*]]) {2906; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[ARG]], 02907; CHECK-NEXT:    [[TRAILING:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[ARG]], i1 true)2908; CHECK-NEXT:    [[SHIFTED:%.*]] = lshr exact i32 [[ARG]], [[TRAILING]]2909; CHECK-NEXT:    [[R1_SROA_0_1:%.*]] = select i1 [[CMP]], i32 0, i32 [[SHIFTED]]2910; CHECK-NEXT:    ret i32 [[R1_SROA_0_1]]2911;2912  %cmp = icmp eq i32 %arg, 02913  %trailing = call i32 @llvm.cttz.i32(i32 %arg, i1 true)2914  %shifted = lshr i32 %arg, %trailing2915  %r1.sroa.0.1 = select i1 %cmp, i32 0, i32 %shifted2916  ret i32 %r1.sroa.0.12917}2918 2919define i8 @select_replacement_add_eq(i8 %x, i8 %y) {2920; CHECK-LABEL: define i8 @select_replacement_add_eq(2921; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {2922; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X]], 12923; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 2, i8 [[Y]]2924; CHECK-NEXT:    ret i8 [[SEL]]2925;2926  %cmp = icmp eq i8 %x, 12927  %add = add i8 %x, 12928  %sel = select i1 %cmp, i8 %add, i8 %y2929  ret i8 %sel2930}2931 2932define <2 x i8> @select_replacement_add_eq_vec(<2 x i8> %x, <2 x i8> %y) {2933; CHECK-LABEL: define <2 x i8> @select_replacement_add_eq_vec(2934; CHECK-SAME: <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {2935; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[X]], splat (i8 1)2936; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> splat (i8 2), <2 x i8> [[Y]]2937; CHECK-NEXT:    ret <2 x i8> [[SEL]]2938;2939  %cmp = icmp eq <2 x i8> %x, <i8 1, i8 1>2940  %add = add <2 x i8> %x, <i8 1, i8 1>2941  %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y2942  ret <2 x i8> %sel2943}2944 2945define <2 x i8> @select_replacement_add_eq_vec_nonuniform(<2 x i8> %x, <2 x i8> %y) {2946; CHECK-LABEL: define <2 x i8> @select_replacement_add_eq_vec_nonuniform(2947; CHECK-SAME: <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {2948; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[X]], <i8 1, i8 2>2949; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> <i8 4, i8 6>, <2 x i8> [[Y]]2950; CHECK-NEXT:    ret <2 x i8> [[SEL]]2951;2952  %cmp = icmp eq <2 x i8> %x, <i8 1, i8 2>2953  %add = add <2 x i8> %x, <i8 3, i8 4>2954  %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y2955  ret <2 x i8> %sel2956}2957 2958define <2 x i8> @select_replacement_add_eq_vec_poison(<2 x i8> %x, <2 x i8> %y) {2959; CHECK-LABEL: define <2 x i8> @select_replacement_add_eq_vec_poison(2960; CHECK-SAME: <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {2961; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[X]], <i8 1, i8 poison>2962; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> <i8 2, i8 poison>, <2 x i8> [[Y]]2963; CHECK-NEXT:    ret <2 x i8> [[SEL]]2964;2965  %cmp = icmp eq <2 x i8> %x, <i8 1, i8 poison>2966  %add = add <2 x i8> %x, <i8 1, i8 1>2967  %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y2968  ret <2 x i8> %sel2969}2970 2971define <2 x i8> @select_replacement_add_eq_vec_undef(<2 x i8> %x, <2 x i8> %y) {2972; CHECK-LABEL: define <2 x i8> @select_replacement_add_eq_vec_undef(2973; CHECK-SAME: <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {2974; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[X]], <i8 1, i8 undef>2975; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i8> [[X]], splat (i8 1)2976; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[ADD]], <2 x i8> [[Y]]2977; CHECK-NEXT:    ret <2 x i8> [[SEL]]2978;2979  %cmp = icmp eq <2 x i8> %x, <i8 1, i8 undef>2980  %add = add <2 x i8> %x, <i8 1, i8 1>2981  %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y2982  ret <2 x i8> %sel2983}2984 2985define <2 x i8> @select_replacement_add_eq_vec_undef_okay(<2 x i8> %x, <2 x i8> %y) {2986; CHECK-LABEL: define <2 x i8> @select_replacement_add_eq_vec_undef_okay(2987; CHECK-SAME: <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {2988; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[X]], splat (i8 1)2989; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> <i8 2, i8 undef>, <2 x i8> [[Y]]2990; CHECK-NEXT:    ret <2 x i8> [[SEL]]2991;2992  %cmp = icmp eq <2 x i8> %x, <i8 1, i8 1>2993  %add = add <2 x i8> %x, <i8 1, i8 undef>2994  %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y2995  ret <2 x i8> %sel2996}2997 2998 2999define <2 x i8> @select_replacement_add_eq_vec_undef_okay_todo(<2 x i8> %x, <2 x i8> %y) {3000; CHECK-LABEL: define <2 x i8> @select_replacement_add_eq_vec_undef_okay_todo(3001; CHECK-SAME: <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {3002; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[X]], <i8 1, i8 undef>3003; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i8> [[X]], <i8 1, i8 undef>3004; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[ADD]], <2 x i8> [[Y]]3005; CHECK-NEXT:    ret <2 x i8> [[SEL]]3006;3007  %cmp = icmp eq <2 x i8> %x, <i8 1, i8 undef>3008  %add = add <2 x i8> %x, <i8 1, i8 undef>3009  %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y3010  ret <2 x i8> %sel3011}3012 3013define <2 x i8> @select_replacement_xor_eq_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {3014; CHECK-LABEL: define <2 x i8> @select_replacement_xor_eq_vec(3015; CHECK-SAME: <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]], <2 x i8> [[Z:%.*]]) {3016; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[X]], [[Y]]3017; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> zeroinitializer, <2 x i8> [[Z]]3018; CHECK-NEXT:    ret <2 x i8> [[SEL]]3019;3020  %cmp = icmp eq <2 x i8> %x, %y3021  %add = xor <2 x i8> %x, %y3022  %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %z3023  ret <2 x i8> %sel3024}3025 3026 3027define i8 @select_replacement_add_ne(i8 %x, i8 %y) {3028; CHECK-LABEL: define i8 @select_replacement_add_ne(3029; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {3030; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[X]], 13031; CHECK-NEXT:    call void @use(i1 [[CMP]])3032; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 [[Y]], i8 23033; CHECK-NEXT:    ret i8 [[SEL]]3034;3035  %cmp = icmp ne i8 %x, 13036  call void @use(i1 %cmp)3037  %add = add i8 %x, 13038  %sel = select i1 %cmp, i8 %y, i8 %add3039  ret i8 %sel3040}3041 3042define i8 @select_replacement_add_nuw(i8 %x, i8 %y) {3043; CHECK-LABEL: define i8 @select_replacement_add_nuw(3044; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {3045; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X]], 13046; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 2, i8 [[Y]]3047; CHECK-NEXT:    ret i8 [[SEL]]3048;3049  %cmp = icmp eq i8 %x, 13050  %add = add nuw i8 %x, 13051  %sel = select i1 %cmp, i8 %add, i8 %y3052  ret i8 %sel3053}3054 3055define i8 @select_replacement_sub_noundef(i8 %x, i8 noundef %y, i8 %z) {3056; CHECK-LABEL: define i8 @select_replacement_sub_noundef(3057; CHECK-SAME: i8 [[X:%.*]], i8 noundef [[Y:%.*]], i8 [[Z:%.*]]) {3058; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X]], [[Y]]3059; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 0, i8 [[Z]]3060; CHECK-NEXT:    ret i8 [[SEL]]3061;3062  %cmp = icmp eq i8 %x, %y3063  %sub = sub i8 %x, %y3064  %sel = select i1 %cmp, i8 %sub, i8 %z3065  ret i8 %sel3066}3067 3068define i8 @select_replacement_sub_noundef_but_may_be_poison(i8 %x, i8 noundef %yy, i8 %z) {3069; CHECK-LABEL: define i8 @select_replacement_sub_noundef_but_may_be_poison(3070; CHECK-SAME: i8 [[X:%.*]], i8 noundef [[YY:%.*]], i8 [[Z:%.*]]) {3071; CHECK-NEXT:    [[Y:%.*]] = shl nuw i8 [[YY]], 13072; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X]], [[Y]]3073; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 0, i8 [[Z]]3074; CHECK-NEXT:    ret i8 [[SEL]]3075;3076  %y = shl nuw i8 %yy, 13077  %cmp = icmp eq i8 %x, %y3078  %sub = sub i8 %x, %y3079  %sel = select i1 %cmp, i8 %sub, i8 %z3080  ret i8 %sel3081}3082 3083; TODO: The transform is also safe without noundef.3084define i8 @select_replacement_sub(i8 %x, i8 %y, i8 %z) {3085; CHECK-LABEL: define i8 @select_replacement_sub(3086; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {3087; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X]], [[Y]]3088; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 0, i8 [[Z]]3089; CHECK-NEXT:    ret i8 [[SEL]]3090;3091  %cmp = icmp eq i8 %x, %y3092  %sub = sub i8 %x, %y3093  %sel = select i1 %cmp, i8 %sub, i8 %z3094  ret i8 %sel3095}3096 3097; FIXME: This is safe to fold.3098define i8 @select_replacement_shift_noundef(i8 %x, i8 %y, i8 %z) {3099; CHECK-LABEL: define i8 @select_replacement_shift_noundef(3100; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {3101; CHECK-NEXT:    [[SHR:%.*]] = lshr exact i8 [[X]], 13102; CHECK-NEXT:    call void @use_i8(i8 noundef [[SHR]])3103; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[SHR]], [[Y]]3104; CHECK-NEXT:    [[SHL:%.*]] = shl i8 [[Y]], 13105; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 [[SHL]], i8 [[Z]]3106; CHECK-NEXT:    ret i8 [[SEL]]3107;3108  %shr = lshr exact i8 %x, 13109  call void @use_i8(i8 noundef %shr)3110  %cmp = icmp eq i8 %shr, %y3111  %shl = shl i8 %y, 13112  %sel = select i1 %cmp, i8 %shl, i8 %z3113  ret i8 %sel3114}3115 3116; TODO: The transform is also safe without noundef.3117define i8 @select_replacement_shift(i8 %x, i8 %y, i8 %z) {3118; CHECK-LABEL: define i8 @select_replacement_shift(3119; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {3120; CHECK-NEXT:    [[SHR:%.*]] = lshr exact i8 [[X]], 13121; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[SHR]], [[Y]]3122; CHECK-NEXT:    [[SHL:%.*]] = shl i8 [[Y]], 13123; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 [[SHL]], i8 [[Z]]3124; CHECK-NEXT:    ret i8 [[SEL]]3125;3126  %shr = lshr exact i8 %x, 13127  %cmp = icmp eq i8 %shr, %y3128  %shl = shl i8 %y, 13129  %sel = select i1 %cmp, i8 %shl, i8 %z3130  ret i8 %sel3131}3132 3133define i8 @select_replacement_loop(i8 %x, i8 %y, i8 %z) {3134; CHECK-LABEL: define i8 @select_replacement_loop(3135; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {3136; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X]], [[Y]]3137; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 [[X]], i8 [[Z]]3138; CHECK-NEXT:    ret i8 [[SEL]]3139;3140  %cmp = icmp eq i8 %x, %y3141  %sel = select i1 %cmp, i8 %x, i8 %z3142  ret i8 %sel3143}3144 3145define i32 @select_replacement_loop2(i32 %arg, i32 %arg2) {3146; CHECK-LABEL: define i32 @select_replacement_loop2(3147; CHECK-SAME: i32 [[ARG:%.*]], i32 [[ARG2:%.*]]) {3148; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[ARG]], [[ARG2]]3149; CHECK-NEXT:    ret i32 [[DIV]]3150;3151  %div = udiv i32 %arg, %arg23152  %mul = mul nsw i32 %div, %arg23153  %cmp = icmp eq i32 %mul, %arg3154  %sel = select i1 %cmp, i32 %div, i32 undef3155  ret i32 %sel3156}3157 3158define i8 @select_replacement_loop3(i32 noundef %x) {3159; CHECK-LABEL: define i8 @select_replacement_loop3(3160; CHECK-SAME: i32 noundef [[X:%.*]]) {3161; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i32 [[X]] to i83162; CHECK-NEXT:    [[REV:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[TRUNC]])3163; CHECK-NEXT:    [[EXT:%.*]] = zext i8 [[REV]] to i323164; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X]], [[EXT]]3165; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 [[TRUNC]], i8 03166; CHECK-NEXT:    ret i8 [[SEL]]3167;3168  %trunc = trunc i32 %x to i83169  %rev = call i8 @llvm.bitreverse.i8(i8 %trunc)3170  %ext = zext i8 %rev to i323171  %cmp = icmp eq i32 %ext, %x3172  %sel = select i1 %cmp, i8 %trunc, i8 03173  ret i8 %sel3174}3175 3176define i16 @select_replacement_loop4(i16 noundef %p_12) {3177; CHECK-LABEL: define i16 @select_replacement_loop4(3178; CHECK-SAME: i16 noundef [[P_12:%.*]]) {3179; CHECK-NEXT:    [[TMP1:%.*]] = call i16 @llvm.umin.i16(i16 [[P_12]], i16 2)3180; CHECK-NEXT:    [[AND3:%.*]] = and i16 [[TMP1]], 13181; CHECK-NEXT:    ret i16 [[AND3]]3182;3183  %cmp1 = icmp ult i16 %p_12, 23184  %and1 = and i16 %p_12, 13185  %and2 = select i1 %cmp1, i16 %and1, i16 03186  %cmp2 = icmp eq i16 %and2, %p_123187  %and3 = select i1 %cmp2, i16 %and1, i16 03188  ret i16 %and33189}3190 3191define ptr @select_replacement_gep_inbounds(ptr %base, i64 %offset) {3192; CHECK-LABEL: define ptr @select_replacement_gep_inbounds(3193; CHECK-SAME: ptr [[BASE:%.*]], i64 [[OFFSET:%.*]]) {3194; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[BASE]], i64 [[OFFSET]]3195; CHECK-NEXT:    ret ptr [[GEP]]3196;3197  %cmp = icmp eq i64 %offset, 03198  %gep = getelementptr inbounds i8, ptr %base, i64 %offset3199  %sel = select i1 %cmp, ptr %base, ptr %gep3200  ret ptr %sel3201}3202 3203define i8 @replace_false_op_eq_shl_or_disjoint(i8 %x) {3204; CHECK-LABEL: define i8 @replace_false_op_eq_shl_or_disjoint(3205; CHECK-SAME: i8 [[X:%.*]]) {3206; CHECK-NEXT:    [[SHL:%.*]] = shl i8 [[X]], 33207; CHECK-NEXT:    [[OR:%.*]] = or i8 [[X]], [[SHL]]3208; CHECK-NEXT:    ret i8 [[OR]]3209;3210  %eq0 = icmp eq i8 %x, -13211  %shl = shl i8 %x, 33212  %or = or disjoint i8 %x, %shl3213  %sel = select i1 %eq0, i8 -1, i8 %or3214  ret i8 %sel3215}3216 3217define i8 @select_or_disjoint_eq(i8 %x, i8 %y) {3218; CHECK-LABEL: define i8 @select_or_disjoint_eq(3219; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {3220; CHECK-NEXT:    [[OR:%.*]] = or i8 [[X]], [[Y]]3221; CHECK-NEXT:    ret i8 [[OR]]3222;3223  %cmp = icmp eq i8 %x, %y3224  %or = or disjoint i8 %x, %y3225  %sel = select i1 %cmp, i8 %x, i8 %or3226  ret i8 %sel3227}3228 3229define <2 x i1> @partial_true_undef_condval(<2 x i1> %x) {3230; CHECK-LABEL: define <2 x i1> @partial_true_undef_condval(3231; CHECK-SAME: <2 x i1> [[X:%.*]]) {3232; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 poison>3233;3234  %r = select <2 x i1> <i1 true, i1 poison>, <2 x i1> <i1 true, i1 poison>, <2 x i1> %x3235  ret <2 x i1> %r3236}3237 3238define <2 x i1> @partial_false_undef_condval(<2 x i1> %x) {3239; CHECK-LABEL: define <2 x i1> @partial_false_undef_condval(3240; CHECK-SAME: <2 x i1> [[X:%.*]]) {3241; CHECK-NEXT:    ret <2 x i1> <i1 false, i1 poison>3242;3243  %r = select <2 x i1> <i1 false, i1 poison>, <2 x i1> %x, <2 x i1> <i1 false, i1 poison>3244  ret <2 x i1> %r3245}3246 3247; select (x == 0), 0, x * y --> freeze(y) * x3248define i32 @mul_select_eq_zero(i32 %x, i32 %y) {3249; CHECK-LABEL: define i32 @mul_select_eq_zero(3250; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {3251; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i32 [[Y]]3252; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X]], [[Y_FR]]3253; CHECK-NEXT:    ret i32 [[M]]3254;3255  %c = icmp eq i32 %x, 03256  %m = mul i32 %x, %y3257  %r = select i1 %c, i32 0, i32 %m3258  ret i32 %r3259}3260 3261; select (y == 0), 0, x * y --> freeze(x) * y3262define i32 @mul_select_eq_zero_commute(i32 %x, i32 %y) {3263; CHECK-LABEL: define i32 @mul_select_eq_zero_commute(3264; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {3265; CHECK-NEXT:    [[X_FR:%.*]] = freeze i32 [[X]]3266; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X_FR]], [[Y]]3267; CHECK-NEXT:    ret i32 [[M]]3268;3269  %c = icmp eq i32 %y, 03270  %m = mul i32 %x, %y3271  %r = select i1 %c, i32 0, i32 %m3272  ret i32 %r3273}3274 3275; Check that mul's flags preserved during the transformation.3276define i32 @mul_select_eq_zero_copy_flags(i32 %x, i32 %y) {3277; CHECK-LABEL: define i32 @mul_select_eq_zero_copy_flags(3278; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {3279; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i32 [[Y]]3280; CHECK-NEXT:    [[M:%.*]] = mul nuw nsw i32 [[X]], [[Y_FR]]3281; CHECK-NEXT:    ret i32 [[M]]3282;3283  %c = icmp eq i32 %x, 03284  %m = mul nuw nsw i32 %x, %y3285  %r = select i1 %c, i32 0, i32 %m3286  ret i32 %r3287}3288 3289; Check that the transformation could be applied after condition's inversion.3290; select (x != 0), x * y, 0 --> freeze(y) * x3291define i32 @mul_select_ne_zero(i32 %x, i32 %y) {3292; CHECK-LABEL: define i32 @mul_select_ne_zero(3293; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {3294; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[X]], 03295; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i32 [[Y]]3296; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X]], [[Y_FR]]3297; CHECK-NEXT:    call void @use(i1 [[C]])3298; CHECK-NEXT:    ret i32 [[M]]3299;3300  %c = icmp ne i32 %x, 03301  %m = mul i32 %x, %y3302  %r = select i1 %c, i32 %m, i32 03303  call void @use(i1 %c)3304  ret i32 %r3305}3306 3307; Check that if one of a select's branches returns undef then3308; an expression could be folded into mul as if there was a 0 instead of undef.3309; select (x == 0), undef, x * y --> freeze(y) * x3310define i32 @mul_select_eq_zero_sel_undef(i32 %x, i32 %y) {3311; CHECK-LABEL: define i32 @mul_select_eq_zero_sel_undef(3312; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {3313; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i32 [[Y]]3314; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X]], [[Y_FR]]3315; CHECK-NEXT:    ret i32 [[M]]3316;3317  %c = icmp eq i32 %x, 03318  %m = mul i32 %x, %y3319  %r = select i1 %c, i32 undef, i32 %m3320  ret i32 %r3321}3322 3323; Check that the transformation is applied disregard to a number3324; of expression's users.3325define i32 @mul_select_eq_zero_multiple_users(i32 %x, i32 %y) {3326; CHECK-LABEL: define i32 @mul_select_eq_zero_multiple_users(3327; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {3328; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i32 [[Y]]3329; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X]], [[Y_FR]]3330; CHECK-NEXT:    call void @use_i32(i32 [[M]])3331; CHECK-NEXT:    call void @use_i32(i32 [[M]])3332; CHECK-NEXT:    call void @use_i32(i32 [[M]])3333; CHECK-NEXT:    ret i32 [[M]]3334;3335  %m = mul i32 %x, %y3336  call void @use_i32(i32 %m)3337  %c = icmp eq i32 %x, 03338  %r = select i1 %c, i32 0, i32 %m3339  call void @use_i32(i32 %m)3340  call void @use_i32(i32 %r)3341  ret i32 %r3342}3343 3344; Negative test: select's condition is unrelated to multiplied values,3345; so the transformation should not be applied.3346define i32 @mul_select_eq_zero_unrelated_condition(i32 %x, i32 %y, i32 %z) {3347; CHECK-LABEL: define i32 @mul_select_eq_zero_unrelated_condition(3348; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {3349; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[Z]], 03350; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X]], [[Y]]3351; CHECK-NEXT:    [[R:%.*]] = select i1 [[C]], i32 0, i32 [[M]]3352; CHECK-NEXT:    ret i32 [[R]]3353;3354  %c = icmp eq i32 %z, 03355  %m = mul i32 %x, %y3356  %r = select i1 %c, i32 0, i32 %m3357  ret i32 %r3358}3359 3360; select (<k x elt> x == 0), <k x elt> 0, <k x elt> x * y --> freeze(y) * x3361define <4 x i32> @mul_select_eq_zero_vector(<4 x i32> %x, <4 x i32> %y) {3362; CHECK-LABEL: define <4 x i32> @mul_select_eq_zero_vector(3363; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) {3364; CHECK-NEXT:    [[Y_FR:%.*]] = freeze <4 x i32> [[Y]]3365; CHECK-NEXT:    [[M:%.*]] = mul <4 x i32> [[X]], [[Y_FR]]3366; CHECK-NEXT:    ret <4 x i32> [[M]]3367;3368  %c = icmp eq <4 x i32> %x, zeroinitializer3369  %m = mul <4 x i32> %x, %y3370  %r = select <4 x i1> %c, <4 x i32> zeroinitializer, <4 x i32> %m3371  ret <4 x i32> %r3372}3373 3374; Check that a select is folded into multiplication if condition's operand3375; is a vector consisting of zeros and poisons.3376; select (<k x elt> x == {0, poison, ...}), <k x elt> 0, <k x elt> x * y --> freeze(y) * x3377define <2 x i32> @mul_select_eq_poison_vector(<2 x i32> %x, <2 x i32> %y) {3378; CHECK-LABEL: define <2 x i32> @mul_select_eq_poison_vector(3379; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) {3380; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i32> [[X]], <i32 0, i32 poison>3381; CHECK-NEXT:    [[M:%.*]] = mul <2 x i32> [[X]], [[Y]]3382; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[C]], <2 x i32> <i32 0, i32 42>, <2 x i32> [[M]]3383; CHECK-NEXT:    ret <2 x i32> [[R]]3384;3385  %c = icmp eq <2 x i32> %x, <i32 0, i32 poison>3386  %m = mul <2 x i32> %x, %y3387  %r = select <2 x i1> %c, <2 x i32> <i32 0, i32 42>, <2 x i32> %m3388  ret <2 x i32> %r3389}3390 3391; Check that a select is folded into multiplication if other select's operand3392; is a vector consisting of zeros and poisons.3393; select (<k x elt> x == 0), <k x elt> {0, poison, ...}, <k x elt> x * y --> freeze(y) * x3394define <2 x i32> @mul_select_eq_zero_sel_poison_vector(<2 x i32> %x, <2 x i32> %y) {3395; CHECK-LABEL: define <2 x i32> @mul_select_eq_zero_sel_poison_vector(3396; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) {3397; CHECK-NEXT:    [[Y_FR:%.*]] = freeze <2 x i32> [[Y]]3398; CHECK-NEXT:    [[M:%.*]] = mul <2 x i32> [[X]], [[Y_FR]]3399; CHECK-NEXT:    ret <2 x i32> [[M]]3400;3401  %c = icmp eq <2 x i32> %x, zeroinitializer3402  %m = mul <2 x i32> %x, %y3403  %r = select <2 x i1> %c, <2 x i32> <i32 0, i32 poison>, <2 x i32> %m3404  ret <2 x i32> %r3405}3406 3407; Negative test: select should not be folded into mul because3408; condition's operand and select's operand do not merge into zero vector.3409define <2 x i32> @mul_select_eq_poison_vector_not_merging_to_zero(<2 x i32> %x, <2 x i32> %y) {3410; CHECK-LABEL: define <2 x i32> @mul_select_eq_poison_vector_not_merging_to_zero(3411; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) {3412; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i32> [[X]], <i32 0, i32 poison>3413; CHECK-NEXT:    [[M:%.*]] = mul <2 x i32> [[X]], [[Y]]3414; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[C]], <2 x i32> <i32 1, i32 0>, <2 x i32> [[M]]3415; CHECK-NEXT:    ret <2 x i32> [[R]]3416;3417  %c = icmp eq <2 x i32> %x, <i32 0, i32 poison>3418  %m = mul <2 x i32> %x, %y3419  %r = select <2 x i1> %c, <2 x i32> <i32 1, i32 0>, <2 x i32> %m3420  ret <2 x i32> %r3421}3422 3423define i8 @ne0_is_all_ones(i8 %x) {3424; CHECK-LABEL: define i8 @ne0_is_all_ones(3425; CHECK-SAME: i8 [[X:%.*]]) {3426; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i8 [[X]], 03427; CHECK-NEXT:    [[R:%.*]] = sext i1 [[TMP1]] to i83428; CHECK-NEXT:    ret i8 [[R]]3429;3430  %negx = sub i8 0, %x3431  %ugt1 = icmp ugt i8 %x, 13432  %r = select i1 %ugt1, i8 -1, i8 %negx3433  ret i8 %r3434}3435 3436define i8 @ne0_is_all_ones_use1(i8 %x) {3437; CHECK-LABEL: define i8 @ne0_is_all_ones_use1(3438; CHECK-SAME: i8 [[X:%.*]]) {3439; CHECK-NEXT:    [[NEGX:%.*]] = sub i8 0, [[X]]3440; CHECK-NEXT:    call void @use_i8(i8 [[NEGX]])3441; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i8 [[X]], 03442; CHECK-NEXT:    [[R:%.*]] = sext i1 [[TMP1]] to i83443; CHECK-NEXT:    ret i8 [[R]]3444;3445  %negx = sub i8 0, %x3446  call void @use_i8(i8 %negx)3447  %ugt1 = icmp ugt i8 %x, 13448  %r = select i1 %ugt1, i8 -1, i8 %negx3449  ret i8 %r3450}3451 3452; negative test3453 3454define i8 @ne0_is_all_ones_use2(i8 %x) {3455; CHECK-LABEL: define i8 @ne0_is_all_ones_use2(3456; CHECK-SAME: i8 [[X:%.*]]) {3457; CHECK-NEXT:    [[NEGX:%.*]] = sub i8 0, [[X]]3458; CHECK-NEXT:    [[UGT1:%.*]] = icmp ugt i8 [[X]], 13459; CHECK-NEXT:    call void @use(i1 [[UGT1]])3460; CHECK-NEXT:    [[R:%.*]] = select i1 [[UGT1]], i8 -1, i8 [[NEGX]]3461; CHECK-NEXT:    ret i8 [[R]]3462;3463  %negx = sub i8 0, %x3464  %ugt1 = icmp ugt i8 %x, 13465  call void @use(i1 %ugt1)3466  %r = select i1 %ugt1, i8 -1, i8 %negx3467  ret i8 %r3468}3469 3470; negative test3471 3472define i8 @ne0_is_all_ones_wrong_pred(i8 %x) {3473; CHECK-LABEL: define i8 @ne0_is_all_ones_wrong_pred(3474; CHECK-SAME: i8 [[X:%.*]]) {3475; CHECK-NEXT:    [[NEGX:%.*]] = sub i8 0, [[X]]3476; CHECK-NEXT:    [[UGT1:%.*]] = icmp sgt i8 [[X]], 23477; CHECK-NEXT:    [[R:%.*]] = select i1 [[UGT1]], i8 -1, i8 [[NEGX]]3478; CHECK-NEXT:    ret i8 [[R]]3479;3480  %negx = sub i8 0, %x3481  %ugt1 = icmp sgt i8 %x, 23482  %r = select i1 %ugt1, i8 -1, i8 %negx3483  ret i8 %r3484}3485 3486; negative test3487 3488define i8 @ne0_is_all_ones_wrong_cmp(i8 %x) {3489; CHECK-LABEL: define i8 @ne0_is_all_ones_wrong_cmp(3490; CHECK-SAME: i8 [[X:%.*]]) {3491; CHECK-NEXT:    [[NEGX:%.*]] = sub i8 0, [[X]]3492; CHECK-NEXT:    [[UGT1:%.*]] = icmp ugt i8 [[X]], 23493; CHECK-NEXT:    [[R:%.*]] = select i1 [[UGT1]], i8 -1, i8 [[NEGX]]3494; CHECK-NEXT:    ret i8 [[R]]3495;3496  %negx = sub i8 0, %x3497  %ugt1 = icmp ugt i8 %x, 23498  %r = select i1 %ugt1, i8 -1, i8 %negx3499  ret i8 %r3500}3501 3502; negative test3503 3504define i8 @ne0_is_all_ones_wrong_sel(i8 %x) {3505; CHECK-LABEL: define i8 @ne0_is_all_ones_wrong_sel(3506; CHECK-SAME: i8 [[X:%.*]]) {3507; CHECK-NEXT:    [[NEGX:%.*]] = sub i8 0, [[X]]3508; CHECK-NEXT:    [[UGT1:%.*]] = icmp ugt i8 [[X]], 23509; CHECK-NEXT:    [[R:%.*]] = select i1 [[UGT1]], i8 1, i8 [[NEGX]]3510; CHECK-NEXT:    ret i8 [[R]]3511;3512  %negx = sub i8 0, %x3513  %ugt1 = icmp ugt i8 %x, 23514  %r = select i1 %ugt1, i8 1, i8 %negx3515  ret i8 %r3516}3517 3518define <2 x i8> @ne0_is_all_ones_swap_vec(<2 x i8> %x) {3519; CHECK-LABEL: define <2 x i8> @ne0_is_all_ones_swap_vec(3520; CHECK-SAME: <2 x i8> [[X:%.*]]) {3521; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <2 x i8> [[X]], zeroinitializer3522; CHECK-NEXT:    [[R:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8>3523; CHECK-NEXT:    ret <2 x i8> [[R]]3524;3525  %negx = sub <2 x i8> zeroinitializer, %x3526  %ult2 = icmp ult <2 x i8> %x, <i8 2, i8 2>3527  %r = select <2 x i1> %ult2, <2 x i8> %negx, <2 x i8> <i8 -1, i8 -1>3528  ret <2 x i8> %r3529}3530 3531define <2 x i8> @ne0_is_all_ones_swap_vec_poison(<2 x i8> %x) {3532; CHECK-LABEL: define <2 x i8> @ne0_is_all_ones_swap_vec_poison(3533; CHECK-SAME: <2 x i8> [[X:%.*]]) {3534; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <2 x i8> [[X]], zeroinitializer3535; CHECK-NEXT:    [[R:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8>3536; CHECK-NEXT:    ret <2 x i8> [[R]]3537;3538  %negx = sub <2 x i8> <i8 0, i8 poison>, %x3539  %ult2 = icmp ult <2 x i8> %x, <i8 2, i8 poison>3540  %r = select <2 x i1> %ult2, <2 x i8> %negx, <2 x i8> <i8 -1, i8 poison>3541  ret <2 x i8> %r3542}3543 3544define i64 @udiv_of_select_constexpr(i1 %c, i64 %x) {3545; CHECK-LABEL: define i64 @udiv_of_select_constexpr(3546; CHECK-SAME: i1 [[C:%.*]], i64 [[X:%.*]]) {3547; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C]], i64 [[X]], i64 ptrtoint (ptr @glbl to i64)3548; CHECK-NEXT:    [[OP:%.*]] = udiv i64 [[SEL]], 33549; CHECK-NEXT:    ret i64 [[OP]]3550;3551  %sel = select i1 %c, i64 %x, i64 ptrtoint (ptr @glbl to i64)3552  %op = udiv i64 %sel, 33553  ret i64 %op3554}3555 3556define i64 @udiv_of_select_constexpr_commuted(i1 %c, i64 %x) {3557; CHECK-LABEL: define i64 @udiv_of_select_constexpr_commuted(3558; CHECK-SAME: i1 [[C:%.*]], i64 [[X:%.*]]) {3559; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C]], i64 ptrtoint (ptr @glbl to i64), i64 [[X]]3560; CHECK-NEXT:    [[OP:%.*]] = udiv i64 [[SEL]], 33561; CHECK-NEXT:    ret i64 [[OP]]3562;3563  %sel = select i1 %c, i64 ptrtoint (ptr @glbl to i64), i64 %x3564  %op = udiv i64 %sel, 33565  ret i64 %op3566}3567 3568declare void @use(i1)3569declare void @use_i8(i8)3570declare void @use_i32(i32)3571declare i32 @llvm.cttz.i32(i32, i1 immarg)3572 3573define i32 @select_cond_zext_cond(i1 %cond, i32 %b) {3574; CHECK-LABEL: define i32 @select_cond_zext_cond(3575; CHECK-SAME: i1 [[COND:%.*]], i32 [[B:%.*]]) {3576; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], i32 1, i32 [[B]]3577; CHECK-NEXT:    ret i32 [[SEL]]3578;3579  %zext = zext i1 %cond to i323580  %sel = select i1 %cond, i32 %zext, i32 %b3581  ret i32 %sel3582}3583 3584define <2 x i32> @select_cond_zext_cond_vec(<2 x i1> %cond, <2 x i32> %b) {3585; CHECK-LABEL: define <2 x i32> @select_cond_zext_cond_vec(3586; CHECK-SAME: <2 x i1> [[COND:%.*]], <2 x i32> [[B:%.*]]) {3587; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[COND]], <2 x i32> splat (i32 1), <2 x i32> [[B]]3588; CHECK-NEXT:    ret <2 x i32> [[SEL]]3589;3590  %zext = zext <2 x i1> %cond to <2 x i32>3591  %sel = select <2 x i1> %cond, <2 x i32> %zext, <2 x i32> %b3592  ret <2 x i32> %sel3593}3594 3595define i32 @select_cond_sext_cond(i1 %cond, i32 %b) {3596; CHECK-LABEL: define i32 @select_cond_sext_cond(3597; CHECK-SAME: i1 [[COND:%.*]], i32 [[B:%.*]]) {3598; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], i32 -1, i32 [[B]]3599; CHECK-NEXT:    ret i32 [[SEL]]3600;3601  %sext = sext i1 %cond to i323602  %sel = select i1 %cond, i32 %sext, i32 %b3603  ret i32 %sel3604}3605 3606define <2 x i32> @select_cond_sext_cond_vec(<2 x i1> %cond, <2 x i32> %b) {3607; CHECK-LABEL: define <2 x i32> @select_cond_sext_cond_vec(3608; CHECK-SAME: <2 x i1> [[COND:%.*]], <2 x i32> [[B:%.*]]) {3609; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[COND]], <2 x i32> splat (i32 -1), <2 x i32> [[B]]3610; CHECK-NEXT:    ret <2 x i32> [[SEL]]3611;3612  %sext = sext <2 x i1> %cond to <2 x i32>3613  %sel = select <2 x i1> %cond, <2 x i32> %sext, <2 x i32> %b3614  ret <2 x i32> %sel3615}3616 3617define i32 @select_cond_val_zext_cond(i1 %cond, i32 %b) {3618; CHECK-LABEL: define i32 @select_cond_val_zext_cond(3619; CHECK-SAME: i1 [[COND:%.*]], i32 [[B:%.*]]) {3620; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], i32 [[B]], i32 03621; CHECK-NEXT:    ret i32 [[SEL]]3622;3623  %zext = zext i1 %cond to i323624  %sel = select i1 %cond, i32 %b, i32 %zext3625  ret i32 %sel3626}3627 3628define <2 x i32> @select_cond_val_zext_cond_vec(<2 x i1> %cond, <2 x i32> %b) {3629; CHECK-LABEL: define <2 x i32> @select_cond_val_zext_cond_vec(3630; CHECK-SAME: <2 x i1> [[COND:%.*]], <2 x i32> [[B:%.*]]) {3631; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[COND]], <2 x i32> [[B]], <2 x i32> zeroinitializer3632; CHECK-NEXT:    ret <2 x i32> [[SEL]]3633;3634  %zext = zext <2 x i1> %cond to <2 x i32>3635  %sel = select <2 x i1> %cond, <2 x i32> %b, <2 x i32> %zext3636  ret <2 x i32> %sel3637}3638 3639define i32 @select_cond_val_sext_cond(i1 %cond, i32 %b) {3640; CHECK-LABEL: define i32 @select_cond_val_sext_cond(3641; CHECK-SAME: i1 [[COND:%.*]], i32 [[B:%.*]]) {3642; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], i32 [[B]], i32 03643; CHECK-NEXT:    ret i32 [[SEL]]3644;3645  %sext = sext i1 %cond to i323646  %sel = select i1 %cond, i32 %b, i32 %sext3647  ret i32 %sel3648}3649 3650define i32 @select_cond_zext_not_cond_val(i1 %cond, i32 %b) {3651; CHECK-LABEL: define i32 @select_cond_zext_not_cond_val(3652; CHECK-SAME: i1 [[COND:%.*]], i32 [[B:%.*]]) {3653; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], i32 0, i32 [[B]]3654; CHECK-NEXT:    ret i32 [[SEL]]3655;3656  %not_cond = xor i1 %cond, true3657  %zext = zext i1 %not_cond to i323658  %sel = select i1 %cond, i32 %zext, i32 %b3659  ret i32 %sel3660}3661 3662define i32 @select_cond_sext_not_cond_val(i1 %cond, i32 %b) {3663; CHECK-LABEL: define i32 @select_cond_sext_not_cond_val(3664; CHECK-SAME: i1 [[COND:%.*]], i32 [[B:%.*]]) {3665; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], i32 0, i32 [[B]]3666; CHECK-NEXT:    ret i32 [[SEL]]3667;3668  %not_cond = xor i1 %cond, true3669  %sext = sext i1 %not_cond to i323670  %sel = select i1 %cond, i32 %sext, i32 %b3671  ret i32 %sel3672}3673 3674 3675define i32 @select_cond_val_zext_not_cond(i1 %cond, i32 %b) {3676; CHECK-LABEL: define i32 @select_cond_val_zext_not_cond(3677; CHECK-SAME: i1 [[COND:%.*]], i32 [[B:%.*]]) {3678; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], i32 [[B]], i32 13679; CHECK-NEXT:    ret i32 [[SEL]]3680;3681  %not_cond = xor i1 %cond, true3682  %zext = zext i1 %not_cond to i323683  %sel = select i1 %cond, i32 %b, i32 %zext3684  ret i32 %sel3685}3686 3687define i32 @select_cond_val_sext_not_cond(i1 %cond, i32 %b) {3688; CHECK-LABEL: define i32 @select_cond_val_sext_not_cond(3689; CHECK-SAME: i1 [[COND:%.*]], i32 [[B:%.*]]) {3690; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], i32 [[B]], i32 -13691; CHECK-NEXT:    ret i32 [[SEL]]3692;3693  %not_cond = xor i1 %cond, true3694  %sext = sext i1 %not_cond to i323695  %sel = select i1 %cond, i32 %b, i32 %sext3696  ret i32 %sel3697}3698 3699define i32 @select_cond_not_cond_cond1(i1 %cond) {3700; CHECK-LABEL: define i32 @select_cond_not_cond_cond1(3701; CHECK-SAME: i1 [[COND:%.*]]) {3702; CHECK-NEXT:    ret i32 03703;3704  %z = zext i1 %cond to i323705  %not_cond = xor i1 %cond, true3706  %s = sext i1 %not_cond to i323707  %v = select i1 %cond, i32 %s, i32 %z3708  ret i32 %v3709}3710 3711define i32 @select_cond_not_cond_cond2(i1 %cond) {3712; CHECK-LABEL: define i32 @select_cond_not_cond_cond2(3713; CHECK-SAME: i1 [[COND:%.*]]) {3714; CHECK-NEXT:    ret i32 03715;3716  %z = sext i1 %cond to i323717  %not_cond = xor i1 %cond, true3718  %s = zext i1 %not_cond to i323719  %v = select i1 %cond, i32 %s, i32 %z3720  ret i32 %v3721}3722 3723; This previously crashed due to Constant::getUniqueInteger not handling3724; scalable vector splat ConstantExprs.3725define <vscale x 2 x i32> @and_constant_select_svec(<vscale x 2 x i32> %x, <vscale x 2 x i1> %cond) {3726; CHECK-LABEL: define <vscale x 2 x i32> @and_constant_select_svec(3727; CHECK-SAME: <vscale x 2 x i32> [[X:%.*]], <vscale x 2 x i1> [[COND:%.*]]) {3728; CHECK-NEXT:    [[A:%.*]] = and <vscale x 2 x i32> [[X]], splat (i32 1)3729; CHECK-NEXT:    [[B:%.*]] = select <vscale x 2 x i1> [[COND]], <vscale x 2 x i32> [[A]], <vscale x 2 x i32> [[X]]3730; CHECK-NEXT:    ret <vscale x 2 x i32> [[B]]3731;3732  %a = and <vscale x 2 x i32> %x, splat (i32 1)3733  %b = select <vscale x 2 x i1> %cond, <vscale x 2 x i32> %a, <vscale x 2 x i32> %x3734  ret <vscale x 2 x i32> %b3735}3736 3737define <vscale x 2 x i32> @scalable_sign_bits(<vscale x 2 x i8> %x) {3738; CHECK-LABEL: define <vscale x 2 x i32> @scalable_sign_bits(3739; CHECK-SAME: <vscale x 2 x i8> [[X:%.*]]) {3740; CHECK-NEXT:    [[A:%.*]] = sext <vscale x 2 x i8> [[X]] to <vscale x 2 x i32>3741; CHECK-NEXT:    [[B:%.*]] = shl nsw <vscale x 2 x i32> [[A]], splat (i32 16)3742; CHECK-NEXT:    ret <vscale x 2 x i32> [[B]]3743;3744  %a = sext <vscale x 2 x i8> %x to <vscale x 2 x i32>3745  %b = shl <vscale x 2 x i32> %a, splat (i32 16)3746  ret <vscale x 2 x i32> %b3747}3748 3749define <vscale x 2 x i1> @scalable_non_zero(<vscale x 2 x i32> %x) {3750; CHECK-LABEL: define <vscale x 2 x i1> @scalable_non_zero(3751; CHECK-SAME: <vscale x 2 x i32> [[X:%.*]]) {3752; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <vscale x 2 x i32> [[X]], splat (i32 56)3753; CHECK-NEXT:    ret <vscale x 2 x i1> [[CMP]]3754;3755  %a = or <vscale x 2 x i32> %x, splat (i32 1)3756  %b = add <vscale x 2 x i32> %a, splat (i32 -1)3757  %cmp = icmp ult <vscale x 2 x i32> %b, splat (i32 56)3758  ret <vscale x 2 x i1> %cmp3759}3760 3761define i32 @clamp_umin(i32 %x) {3762; CHECK-LABEL: define i32 @clamp_umin(3763; CHECK-SAME: i32 [[X:%.*]]) {3764; CHECK-NEXT:    [[SEL:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 1)3765; CHECK-NEXT:    ret i32 [[SEL]]3766;3767  %cmp = icmp eq i32 %x, 03768  %sel = select i1 %cmp, i32 1, i32 %x3769  ret i32 %sel3770}3771 3772define i32 @clamp_umin_use(i32 %x) {3773; CHECK-LABEL: define i32 @clamp_umin_use(3774; CHECK-SAME: i32 [[X:%.*]]) {3775; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X]], 03776; CHECK-NEXT:    call void @use1(i1 [[CMP]])3777; CHECK-NEXT:    [[SEL:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 1)3778; CHECK-NEXT:    ret i32 [[SEL]]3779;3780  %cmp = icmp eq i32 %x, 03781  call void @use1(i1 %cmp)3782  %sel = select i1 %cmp, i32 1, i32 %x3783  ret i32 %sel3784}3785 3786; negative test - wrong cmp constant3787 3788define i32 @not_clamp_umin1(i32 %x) {3789; CHECK-LABEL: define i32 @not_clamp_umin1(3790; CHECK-SAME: i32 [[X:%.*]]) {3791; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X]], 23792; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 1, i32 [[X]]3793; CHECK-NEXT:    ret i32 [[SEL]]3794;3795  %cmp = icmp eq i32 %x, 23796  %sel = select i1 %cmp, i32 1, i32 %x3797  ret i32 %sel3798}3799 3800; negative test - wrong select constant3801 3802define i32 @not_clamp_umin2(i32 %x) {3803; CHECK-LABEL: define i32 @not_clamp_umin2(3804; CHECK-SAME: i32 [[X:%.*]]) {3805; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X]], 03806; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1, i32 [[X]]3807; CHECK-NEXT:    ret i32 [[SEL]]3808;3809  %cmp = icmp eq i32 %x, 03810  %sel = select i1 %cmp, i32 -1, i32 %x3811  ret i32 %sel3812}3813 3814define <2 x i8> @clamp_umaxval(<2 x i8> %x) {3815; CHECK-LABEL: define <2 x i8> @clamp_umaxval(3816; CHECK-SAME: <2 x i8> [[X:%.*]]) {3817; CHECK-NEXT:    [[SEL:%.*]] = call <2 x i8> @llvm.umin.v2i8(<2 x i8> [[X]], <2 x i8> splat (i8 -2))3818; CHECK-NEXT:    ret <2 x i8> [[SEL]]3819;3820  %cmp = icmp eq <2 x i8> %x, <i8 255, i8 255>3821  %sel = select <2 x i1> %cmp, <2 x i8> <i8 254, i8 254>, <2 x i8> %x3822  ret <2 x i8> %sel3823}3824 3825; negative test - wrong cmp constant3826 3827define i8 @not_clamp_umax1(i8 %x) {3828; CHECK-LABEL: define i8 @not_clamp_umax1(3829; CHECK-SAME: i8 [[X:%.*]]) {3830; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X]], -33831; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 -2, i8 [[X]]3832; CHECK-NEXT:    ret i8 [[SEL]]3833;3834  %cmp = icmp eq i8 %x, 2533835  %sel = select i1 %cmp, i8 254, i8 %x3836  ret i8 %sel3837}3838 3839; negative test - wrong select constant3840 3841define i8 @not_clamp_umax2(i8 %x) {3842; CHECK-LABEL: define i8 @not_clamp_umax2(3843; CHECK-SAME: i8 [[X:%.*]]) {3844; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X]], -13845; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 1, i8 [[X]]3846; CHECK-NEXT:    ret i8 [[SEL]]3847;3848  %cmp = icmp eq i8 %x, 2553849  %sel = select i1 %cmp, i8 1, i8 %x3850  ret i8 %sel3851}3852 3853define i8 @clamp_smin(i8 %x) {3854; CHECK-LABEL: define i8 @clamp_smin(3855; CHECK-SAME: i8 [[X:%.*]]) {3856; CHECK-NEXT:    [[SEL:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 -127)3857; CHECK-NEXT:    ret i8 [[SEL]]3858;3859  %cmp = icmp eq i8 %x, -1283860  %sel = select i1 %cmp, i8 -127, i8 %x3861  ret i8 %sel3862}3863 3864define i8 @clamp_smin_use(i8 %x) {3865; CHECK-LABEL: define i8 @clamp_smin_use(3866; CHECK-SAME: i8 [[X:%.*]]) {3867; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X]], -1283868; CHECK-NEXT:    call void @use1(i1 [[CMP]])3869; CHECK-NEXT:    [[SEL:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 -127)3870; CHECK-NEXT:    ret i8 [[SEL]]3871;3872  %cmp = icmp eq i8 %x, -1283873  call void @use1(i1 %cmp)3874  %sel = select i1 %cmp, i8 -127, i8 %x3875  ret i8 %sel3876}3877 3878; negative test - wrong cmp constant3879 3880define i8 @not_clamp_smin1(i8 %x) {3881; CHECK-LABEL: define i8 @not_clamp_smin1(3882; CHECK-SAME: i8 [[X:%.*]]) {3883; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X]], 1273884; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 -127, i8 [[X]]3885; CHECK-NEXT:    ret i8 [[SEL]]3886;3887  %cmp = icmp eq i8 %x, 1273888  %sel = select i1 %cmp, i8 -127, i8 %x3889  ret i8 %sel3890}3891 3892; negative test - wrong select constant3893 3894define i8 @not_clamp_smin2(i8 %x) {3895; CHECK-LABEL: define i8 @not_clamp_smin2(3896; CHECK-SAME: i8 [[X:%.*]]) {3897; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X]], -1283898; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 -1, i8 [[X]]3899; CHECK-NEXT:    ret i8 [[SEL]]3900;3901  %cmp = icmp eq i8 %x, -1283902  %sel = select i1 %cmp, i8 -1, i8 %x3903  ret i8 %sel3904}3905 3906define <2 x i8> @clamp_smaxval(<2 x i8> %x) {3907; CHECK-LABEL: define <2 x i8> @clamp_smaxval(3908; CHECK-SAME: <2 x i8> [[X:%.*]]) {3909; CHECK-NEXT:    [[SEL:%.*]] = call <2 x i8> @llvm.smin.v2i8(<2 x i8> [[X]], <2 x i8> splat (i8 126))3910; CHECK-NEXT:    ret <2 x i8> [[SEL]]3911;3912  %cmp = icmp eq <2 x i8> %x, <i8 127, i8 127>3913  %sel = select <2 x i1> %cmp, <2 x i8> <i8 126, i8 126>, <2 x i8> %x3914  ret <2 x i8> %sel3915}3916 3917; negative test - wrong cmp constant3918 3919define i8 @not_clamp_smax1(i8 %x) {3920; CHECK-LABEL: define i8 @not_clamp_smax1(3921; CHECK-SAME: i8 [[X:%.*]]) {3922; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X]], -1283923; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 126, i8 [[X]]3924; CHECK-NEXT:    ret i8 [[SEL]]3925;3926  %cmp = icmp eq i8 %x, -1283927  %sel = select i1 %cmp, i8 126, i8 %x3928  ret i8 %sel3929}3930 3931; negative test - wrong select constant3932 3933define i8 @not_clamp_smax2(i8 %x) {3934; CHECK-LABEL: define i8 @not_clamp_smax2(3935; CHECK-SAME: i8 [[X:%.*]]) {3936; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X]], 1273937; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i8 125, i8 [[X]]3938; CHECK-NEXT:    ret i8 [[SEL]]3939;3940  %cmp = icmp eq i8 %x, 1273941  %sel = select i1 %cmp, i8 125, i8 %x3942  ret i8 %sel3943}3944 3945; Used to infinite loop.3946define i32 @pr61361(i32 %arg) {3947; CHECK-LABEL: define i32 @pr61361(3948; CHECK-SAME: i32 [[ARG:%.*]]) {3949; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[ARG]], 03950; CHECK-NEXT:    [[SEL2:%.*]] = select i1 [[CMP2]], i32 16777215, i32 03951; CHECK-NEXT:    ret i32 [[SEL2]]3952;3953  %cmp1 = icmp eq i32 %arg, 13954  %sel1 = select i1 %cmp1, i32 0, i32 335544313955  %cmp2 = icmp eq i32 %arg, 03956  %sel2 = select i1 %cmp2, i32 %sel1, i32 03957  %ashr = ashr i32 %sel2, 13958  ret i32 %ashr3959}3960 3961define i32 @pr62088() {3962; CHECK-LABEL: define i32 @pr62088() {3963; CHECK-NEXT:  [[ENTRY:.*]]:3964; CHECK-NEXT:    br label %[[LOOP:.*]]3965; CHECK:       [[LOOP]]:3966; CHECK-NEXT:    [[NOT2:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ -2, %[[LOOP]] ]3967; CHECK-NEXT:    [[H_0:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ 1, %[[LOOP]] ]3968; CHECK-NEXT:    [[XOR:%.*]] = or disjoint i32 [[H_0]], [[NOT2]]3969; CHECK-NEXT:    [[SUB5:%.*]] = sub i32 -1824888657, [[XOR]]3970; CHECK-NEXT:    [[XOR6:%.*]] = xor i32 [[SUB5]], -12609140253971; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[XOR6]], 8248551203972; CHECK-NEXT:    br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]3973; CHECK:       [[EXIT]]:3974; CHECK-NEXT:    ret i32 [[H_0]]3975;3976entry:3977  br label %loop3978 3979loop:3980  %not2 = phi i32 [ 0, %entry ], [ -2, %loop ]3981  %i.0 = phi i32 [ 0, %entry ], [ %shr, %loop ]3982  %h.0 = phi i32 [ 0, %entry ], [ 1, %loop ]3983  %i.0.fr = freeze i32 %i.03984  %sext = shl i32 %i.0.fr, 163985  %conv = ashr exact i32 %sext, 163986  %not = xor i32 %conv, -13987  %and = and i32 %h.0, 13988  %rem.urem = sub nsw i32 %and, %conv3989  %rem.cmp = icmp ult i32 %and, %conv3990  %rem = select i1 %rem.cmp, i32 %not, i32 %rem.urem3991  %xor = xor i32 %rem, %not23992  %sub = sub nsw i32 0, %xor3993  %sub5 = sub i32 -1824888657, %xor3994  %xor6 = xor i32 %sub5, -12609140253995  %cmp = icmp slt i32 %xor6, 8248551203996  %shr = ashr i32 %xor6, 403997  br i1 %cmp, label %loop, label %exit3998 3999exit:4000  ret i32 %rem4001}4002 4003; Select icmp and/or/xor4004; https://alive2.llvm.org/ce/z/QXQDwF4005; X&Y==C?X|Y:X^Y, X&Y==C?X^Y:X|Y4006; TODO: X&Y==0 could imply no_common_bit to TrueValue4007define i32 @src_and_eq_0_or_xor(i32 %x, i32 %y) {4008; CHECK-LABEL: define i32 @src_and_eq_0_or_xor(4009; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4010; CHECK-NEXT:  [[ENTRY:.*:]]4011; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]4012; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 04013; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]4014; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]4015; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[XOR]]4016; CHECK-NEXT:    ret i32 [[COND]]4017;4018entry:4019  %and = and i32 %y, %x4020  %cmp = icmp eq i32 %and, 04021  %or = or i32 %y, %x4022  %xor = xor i32 %y, %x4023  %cond = select i1 %cmp, i32 %or, i32 %xor4024  ret i32 %cond4025}4026 4027; TODO: X&Y==0 could imply no_common_bit to TrueValue4028define i32 @src_and_eq_0_xor_or(i32 %x, i32 %y) {4029; CHECK-LABEL: define i32 @src_and_eq_0_xor_or(4030; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4031; CHECK-NEXT:  [[ENTRY:.*:]]4032; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]4033; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 04034; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]4035; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]4036; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[OR]]4037; CHECK-NEXT:    ret i32 [[COND]]4038;4039entry:4040  %and = and i32 %y, %x4041  %cmp = icmp eq i32 %and, 04042  %xor = xor i32 %y, %x4043  %or = or i32 %y, %x4044  %cond = select i1 %cmp, i32 %xor, i32 %or4045  ret i32 %cond4046}4047 4048; TODO: X&Y==-1 could imply all_common_bit to TrueValue4049define i32 @src_and_eq_neg1_or_xor(i32 %x, i32 %y) {4050; CHECK-LABEL: define i32 @src_and_eq_neg1_or_xor(4051; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4052; CHECK-NEXT:  [[ENTRY:.*:]]4053; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]4054; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], -14055; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]4056; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 -1, i32 [[XOR]]4057; CHECK-NEXT:    ret i32 [[COND]]4058;4059entry:4060  %and = and i32 %y, %x4061  %cmp = icmp eq i32 %and, -14062  %or = or i32 %y, %x4063  %xor = xor i32 %y, %x4064  %cond = select i1 %cmp, i32 %or, i32 %xor4065  ret i32 %cond4066}4067 4068; TODO: X&Y==-1 could imply all_common_bit to TrueValue4069define i32 @src_and_eq_neg1_xor_or(i32 %x, i32 %y) {4070; CHECK-LABEL: define i32 @src_and_eq_neg1_xor_or(4071; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4072; CHECK-NEXT:  [[ENTRY:.*:]]4073; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]4074; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], -14075; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]4076; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 0, i32 [[OR]]4077; CHECK-NEXT:    ret i32 [[COND]]4078;4079entry:4080  %and = and i32 %y, %x4081  %cmp = icmp eq i32 %and, -14082  %xor = xor i32 %y, %x4083  %or = or i32 %y, %x4084  %cond = select i1 %cmp, i32 %xor, i32 %or4085  ret i32 %cond4086}4087 4088define i32 @src_and_eq_C_or_xororC(i32 %x, i32 %y, i32 %c) {4089; CHECK-LABEL: define i32 @src_and_eq_C_or_xororC(4090; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[C:%.*]]) {4091; CHECK-NEXT:  [[ENTRY:.*:]]4092; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]4093; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], [[C]]4094; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]4095; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]4096; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[XOR]], [[C]]4097; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[OR1]]4098; CHECK-NEXT:    ret i32 [[COND]]4099;4100entry:4101  %and = and i32 %y, %x4102  %cmp = icmp eq i32 %and, %c4103  %or = or i32 %y, %x4104  %xor = xor i32 %y, %x4105  %or1 = or i32 %xor, %c4106  %cond = select i1 %cmp, i32 %or, i32 %or14107  ret i32 %cond4108}4109 4110define i32 @src_and_eq_C_or_xorxorC(i32 %x, i32 %y, i32 %c) {4111; CHECK-LABEL: define i32 @src_and_eq_C_or_xorxorC(4112; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[C:%.*]]) {4113; CHECK-NEXT:  [[ENTRY:.*:]]4114; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]4115; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], [[C]]4116; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]4117; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]4118; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[XOR]], [[C]]4119; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[XOR1]]4120; CHECK-NEXT:    ret i32 [[COND]]4121;4122entry:4123  %and = and i32 %y, %x4124  %cmp = icmp eq i32 %and, %c4125  %or = or i32 %y, %x4126  %xor = xor i32 %y, %x4127  %xor1 = xor i32 %xor, %c4128  %cond = select i1 %cmp, i32 %or, i32 %xor14129  ret i32 %cond4130}4131 4132define i32 @src_and_eq_C_xor_OrAndNotC(i32 %x, i32 %y, i32 %c) {4133; CHECK-LABEL: define i32 @src_and_eq_C_xor_OrAndNotC(4134; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[C:%.*]]) {4135; CHECK-NEXT:  [[ENTRY:.*:]]4136; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]4137; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], [[C]]4138; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]4139; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]4140; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[C]], -14141; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[OR]], [[NOT]]4142; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[AND1]]4143; CHECK-NEXT:    ret i32 [[COND]]4144;4145entry:4146  %and = and i32 %y, %x4147  %cmp = icmp eq i32 %and, %c4148  %xor = xor i32 %y, %x4149  %or = or i32 %y, %x4150  %not = xor i32 %c, -14151  %and1 = and i32 %or, %not4152  %cond = select i1 %cmp, i32 %xor, i32 %and14153  ret i32 %cond4154}4155 4156define <2 x i32> @src_and_eq_C_xor_OrAndNotC_vec_poison(<2 x i32> %0, <2 x i32> %1, <2 x i32> %2) {4157; CHECK-LABEL: define <2 x i32> @src_and_eq_C_xor_OrAndNotC_vec_poison(4158; CHECK-SAME: <2 x i32> [[TMP0:%.*]], <2 x i32> [[TMP1:%.*]], <2 x i32> [[TMP2:%.*]]) {4159; CHECK-NEXT:  [[ENTRY:.*:]]4160; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[TMP1]], [[TMP0]]4161; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], [[TMP2]]4162; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i32> [[TMP1]], [[TMP0]]4163; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[TMP1]], [[TMP0]]4164; CHECK-NEXT:    [[NOT:%.*]] = xor <2 x i32> [[TMP2]], <i32 -1, i32 poison>4165; CHECK-NEXT:    [[AND1:%.*]] = and <2 x i32> [[OR]], [[NOT]]4166; CHECK-NEXT:    [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[XOR]], <2 x i32> [[AND1]]4167; CHECK-NEXT:    ret <2 x i32> [[COND]]4168;4169entry:4170  %and = and <2 x i32> %1, %04171  %cmp = icmp eq <2 x i32> %and, %24172  %xor = xor <2 x i32> %1, %04173  %or = or <2 x i32> %1, %04174  %not = xor <2 x i32> %2, <i32 -1, i32 poison>4175  %and1 = and <2 x i32> %or, %not4176  %cond = select <2 x i1> %cmp, <2 x i32> %xor, <2 x i32> %and14177  ret <2 x i32> %cond4178}4179 4180define i32 @src_and_eq_C_xor_orxorC(i32 %x, i32 %y, i32 %c) {4181; CHECK-LABEL: define i32 @src_and_eq_C_xor_orxorC(4182; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[C:%.*]]) {4183; CHECK-NEXT:  [[ENTRY:.*:]]4184; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]4185; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], [[C]]4186; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]4187; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]4188; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[OR]], [[C]]4189; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[XOR1]]4190; CHECK-NEXT:    ret i32 [[COND]]4191;4192entry:4193  %and = and i32 %y, %x4194  %cmp = icmp eq i32 %and, %c4195  %xor = xor i32 %y, %x4196  %or = or i32 %y, %x4197  %xor1 = xor i32 %or, %c4198  %cond = select i1 %cmp, i32 %xor, i32 %xor14199  ret i32 %cond4200}4201 4202; https://alive2.llvm.org/ce/z/9RPwfN4203; X|Y==C?X&Y:X^Y, X|Y==C?X^Y:X&Y4204; TODO: X|Y==0 could imply no_common_bit to TrueValue4205define i32 @src_or_eq_0_and_xor(i32 %x, i32 %y) {4206; CHECK-LABEL: define i32 @src_or_eq_0_and_xor(4207; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4208; CHECK-NEXT:  [[ENTRY:.*:]]4209; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]4210; CHECK-NEXT:    ret i32 [[XOR]]4211;4212entry:4213  %or = or i32 %y, %x4214  %cmp = icmp eq i32 %or, 04215  %and = and i32 %y, %x4216  %xor = xor i32 %y, %x4217  %cond = select i1 %cmp, i32 %and, i32 %xor4218  ret i32 %cond4219}4220 4221; TODO: X|Y==0 could imply no_common_bit to TrueValue4222define i32 @src_or_eq_0_xor_and(i32 %x, i32 %y) {4223; CHECK-LABEL: define i32 @src_or_eq_0_xor_and(4224; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4225; CHECK-NEXT:  [[ENTRY:.*:]]4226; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]4227; CHECK-NEXT:    ret i32 [[AND]]4228;4229entry:4230  %or = or i32 %y, %x4231  %cmp = icmp eq i32 %or, 04232  %xor = xor i32 %y, %x4233  %and = and i32 %y, %x4234  %cond = select i1 %cmp, i32 %xor, i32 %and4235  ret i32 %cond4236}4237 4238define i32 @src_or_eq_neg1_and_xor(i32 %x, i32 %y) {4239; CHECK-LABEL: define i32 @src_or_eq_neg1_and_xor(4240; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4241; CHECK-NEXT:  [[ENTRY:.*:]]4242; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]4243; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], -14244; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]4245; CHECK-NEXT:    [[TMP0:%.*]] = xor i32 [[X]], [[Y]]4246; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[TMP0]], -14247; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[NOT]]4248; CHECK-NEXT:    ret i32 [[COND]]4249;4250entry:4251  %or = or i32 %y, %x4252  %cmp = icmp eq i32 %or, -14253  %and = and i32 %y, %x4254  %0 = xor i32 %x, %y4255  %not = xor i32 %0, -14256  %cond = select i1 %cmp, i32 %and, i32 %not4257  ret i32 %cond4258}4259 4260define i32 @src_or_eq_neg1_xor_and(i32 %x, i32 %y) {4261; CHECK-LABEL: define i32 @src_or_eq_neg1_xor_and(4262; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4263; CHECK-NEXT:  [[ENTRY:.*:]]4264; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]4265; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], -14266; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]4267; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]4268; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[AND]], -14269; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[NOT]]4270; CHECK-NEXT:    ret i32 [[COND]]4271;4272entry:4273  %or = or i32 %y, %x4274  %cmp = icmp eq i32 %or, -14275  %xor = xor i32 %y, %x4276  %and = and i32 %y, %x4277  %not = xor i32 %and, -14278  %cond = select i1 %cmp, i32 %xor, i32 %not4279  ret i32 %cond4280}4281 4282define i32 @src_or_eq_C_and_xorC(i32 %x, i32 %y, i32 %c) {4283; CHECK-LABEL: define i32 @src_or_eq_C_and_xorC(4284; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[C:%.*]]) {4285; CHECK-NEXT:  [[ENTRY:.*:]]4286; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]4287; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], [[C]]4288; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]4289; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]4290; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[XOR]], [[C]]4291; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[XOR1]]4292; CHECK-NEXT:    ret i32 [[COND]]4293;4294entry:4295  %or = or i32 %y, %x4296  %cmp = icmp eq i32 %or, %c4297  %and = and i32 %y, %x4298  %xor = xor i32 %y, %x4299  %xor1 = xor i32 %xor, %c4300  %cond = select i1 %cmp, i32 %and, i32 %xor14301  ret i32 %cond4302}4303 4304define i32 @src_or_eq_C_and_andnotxorC(i32 %x, i32 %y, i32 %c) {4305; CHECK-LABEL: define i32 @src_or_eq_C_and_andnotxorC(4306; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[C:%.*]]) {4307; CHECK-NEXT:  [[ENTRY:.*:]]4308; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]4309; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], [[C]]4310; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]4311; CHECK-NEXT:    [[TMP0:%.*]] = xor i32 [[X]], [[Y]]4312; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[TMP0]], -14313; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[C]], [[NOT]]4314; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[AND1]]4315; CHECK-NEXT:    ret i32 [[COND]]4316;4317entry:4318  %or = or i32 %y, %x4319  %cmp = icmp eq i32 %or, %c4320  %and = and i32 %y, %x4321  %0 = xor i32 %x, %y4322  %not = xor i32 %0, -14323  %and1 = and i32 %not, %c4324  %cond = select i1 %cmp, i32 %and, i32 %and14325  ret i32 %cond4326}4327 4328define i32 @src_or_eq_C_xor_xorandC(i32 %x, i32 %y, i32 %c) {4329; CHECK-LABEL: define i32 @src_or_eq_C_xor_xorandC(4330; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[C:%.*]]) {4331; CHECK-NEXT:  [[ENTRY:.*:]]4332; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]4333; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], [[C]]4334; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]4335; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]4336; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[AND]], [[C]]4337; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[XOR1]]4338; CHECK-NEXT:    ret i32 [[COND]]4339;4340entry:4341  %or = or i32 %y, %x4342  %cmp = icmp eq i32 %or, %c4343  %xor = xor i32 %y, %x4344  %and = and i32 %y, %x4345  %xor1 = xor i32 %and, %c4346  %cond = select i1 %cmp, i32 %xor, i32 %xor14347  ret i32 %cond4348}4349 4350define i32 @src_or_eq_C_xor_andnotandC(i32 %x, i32 %y, i32 %c) {4351; CHECK-LABEL: define i32 @src_or_eq_C_xor_andnotandC(4352; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[C:%.*]]) {4353; CHECK-NEXT:  [[ENTRY:.*:]]4354; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]4355; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], [[C]]4356; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]4357; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]4358; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[AND]], -14359; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[C]], [[NOT]]4360; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[AND1]]4361; CHECK-NEXT:    ret i32 [[COND]]4362;4363entry:4364  %or = or i32 %y, %x4365  %cmp = icmp eq i32 %or, %c4366  %xor = xor i32 %y, %x4367  %and = and i32 %y, %x4368  %not = xor i32 %and, -14369  %and1 = and i32 %not, %c4370  %cond = select i1 %cmp, i32 %xor, i32 %and14371  ret i32 %cond4372}4373 4374; https://alive2.llvm.org/ce/z/c6oXi44375; X^Y==C?X&Y:X|Y, X^Y==C?X|Y:X&Y4376define i32 @src_xor_eq_neg1_and(i32 %x, i32 %y) {4377; CHECK-LABEL: define i32 @src_xor_eq_neg1_and(4378; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4379; CHECK-NEXT:  [[ENTRY:.*:]]4380; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]4381; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[XOR]], -14382; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]4383; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]4384; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[OR]], -14385; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[NOT]]4386; CHECK-NEXT:    ret i32 [[COND]]4387;4388entry:4389  %xor = xor i32 %y, %x4390  %cmp = icmp eq i32 %xor, -14391  %and = and i32 %y, %x4392  %or = or i32 %y, %x4393  %not = xor i32 %or, -14394  %cond = select i1 %cmp, i32 %and, i32 %not4395  ret i32 %cond4396}4397 4398; TODO: X^Y==-1 could imply no_common_bit to TrueValue4399define i32 @src_xor_eq_neg1_or(i32 %x, i32 %y) {4400; CHECK-LABEL: define i32 @src_xor_eq_neg1_or(4401; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4402; CHECK-NEXT:  [[ENTRY:.*:]]4403; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]4404; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[XOR]], -14405; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]4406; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 -14407; CHECK-NEXT:    ret i32 [[COND]]4408;4409entry:4410  %xor = xor i32 %y, %x4411  %cmp = icmp eq i32 %xor, -14412  %or = or i32 %y, %x4413  %cond = select i1 %cmp, i32 %or, i32 -14414  ret i32 %cond4415}4416 4417define i32 @src_xor_eq_C_and_xororC(i32 %x, i32 %y, i32 %c) {4418; CHECK-LABEL: define i32 @src_xor_eq_C_and_xororC(4419; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[C:%.*]]) {4420; CHECK-NEXT:  [[ENTRY:.*:]]4421; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]4422; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[XOR]], [[C]]4423; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]4424; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]4425; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[OR]], [[C]]4426; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[XOR1]]4427; CHECK-NEXT:    ret i32 [[COND]]4428;4429entry:4430  %xor = xor i32 %y, %x4431  %cmp = icmp eq i32 %xor, %c4432  %and = and i32 %y, %x4433  %or = or i32 %y, %x4434  %xor1 = xor i32 %or, %c4435  %cond = select i1 %cmp, i32 %and, i32 %xor14436  ret i32 %cond4437}4438 4439define i32 @src_xor_eq_C_and_andornotC(i32 %x, i32 %y, i32 %c) {4440; CHECK-LABEL: define i32 @src_xor_eq_C_and_andornotC(4441; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[C:%.*]]) {4442; CHECK-NEXT:  [[ENTRY:.*:]]4443; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]4444; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[XOR]], [[C]]4445; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]4446; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]4447; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[C]], -14448; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[OR]], [[NOT]]4449; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[AND1]]4450; CHECK-NEXT:    ret i32 [[COND]]4451;4452entry:4453  %xor = xor i32 %y, %x4454  %cmp = icmp eq i32 %xor, %c4455  %and = and i32 %y, %x4456  %or = or i32 %y, %x4457  %not = xor i32 %c, -14458  %and1 = and i32 %or, %not4459  %cond = select i1 %cmp, i32 %and, i32 %and14460  ret i32 %cond4461}4462 4463define i32 @src_xor_eq_C_or_xorandC(i32 %x, i32 %y, i32 %c) {4464; CHECK-LABEL: define i32 @src_xor_eq_C_or_xorandC(4465; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[C:%.*]]) {4466; CHECK-NEXT:  [[ENTRY:.*:]]4467; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]4468; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[XOR]], [[C]]4469; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]4470; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]4471; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[AND]], [[C]]4472; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[XOR1]]4473; CHECK-NEXT:    ret i32 [[COND]]4474;4475entry:4476  %xor = xor i32 %y, %x4477  %cmp = icmp eq i32 %xor, %c4478  %or = or i32 %y, %x4479  %and = and i32 %y, %x4480  %xor1 = xor i32 %and, %c4481  %cond = select i1 %cmp, i32 %or, i32 %xor14482  ret i32 %cond4483}4484 4485define i32 @src_xor_eq_C_or_orandC(i32 %x, i32 %y, i32 %c) {4486; CHECK-LABEL: define i32 @src_xor_eq_C_or_orandC(4487; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[C:%.*]]) {4488; CHECK-NEXT:  [[ENTRY:.*:]]4489; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]4490; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[XOR]], [[C]]4491; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y]], [[X]]4492; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y]], [[X]]4493; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[AND]], [[C]]4494; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[OR1]]4495; CHECK-NEXT:    ret i32 [[COND]]4496;4497entry:4498  %xor = xor i32 %y, %x4499  %cmp = icmp eq i32 %xor, %c4500  %or = or i32 %y, %x4501  %and = and i32 %y, %x4502  %or1 = or i32 %and, %c4503  %cond = select i1 %cmp, i32 %or, i32 %or14504  ret i32 %cond4505}4506 4507; Select icmp and/or/xor4508; NO TRANSFORMED - select condition is compare with not 04509define i32 @src_select_and_min_positive_int(i32 %x, i32 %y) {4510; CHECK-LABEL: define i32 @src_select_and_min_positive_int(4511; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4512; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]4513; CHECK-NEXT:    [[AND0:%.*]] = icmp eq i32 [[AND]], 14514; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]4515; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]4516; CHECK-NEXT:    [[COND:%.*]] = select i1 [[AND0]], i32 [[OR]], i32 [[XOR]]4517; CHECK-NEXT:    ret i32 [[COND]]4518;4519  %and = and i32 %x, %y4520  %and0 = icmp eq i32 %and, 14521  %xor = xor i32 %x, %y4522  %or = or i32 %x, %y4523  %cond = select i1 %and0, i32 %or, i32 %xor4524  ret i32 %cond4525}4526 4527define i32 @src_select_and_max_positive_int(i32 %x, i32 %y) {4528; CHECK-LABEL: define i32 @src_select_and_max_positive_int(4529; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4530; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]4531; CHECK-NEXT:    [[AND0:%.*]] = icmp eq i32 [[AND]], 21474836474532; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]4533; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]4534; CHECK-NEXT:    [[COND:%.*]] = select i1 [[AND0]], i32 [[OR]], i32 [[XOR]]4535; CHECK-NEXT:    ret i32 [[COND]]4536;4537  %and = and i32 %x, %y4538  %and0 = icmp eq i32 %and, 21474836474539  %xor = xor i32 %x, %y4540  %or = or i32 %x, %y4541  %cond = select i1 %and0, i32 %or, i32 %xor4542  ret i32 %cond4543}4544 4545define i32 @src_select_and_min_negative_int(i32 %x, i32 %y) {4546; CHECK-LABEL: define i32 @src_select_and_min_negative_int(4547; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4548; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]4549; CHECK-NEXT:    [[AND0:%.*]] = icmp eq i32 [[AND]], -21474836484550; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]4551; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]4552; CHECK-NEXT:    [[COND:%.*]] = select i1 [[AND0]], i32 [[OR]], i32 [[XOR]]4553; CHECK-NEXT:    ret i32 [[COND]]4554;4555  %and = and i32 %x, %y4556  %and0 = icmp eq i32 %and, -21474836484557  %xor = xor i32 %x, %y4558  %or = or i32 %x, %y4559  %cond = select i1 %and0, i32 %or, i32 %xor4560  ret i32 %cond4561}4562 4563define i32 @src_select_or_min_positive_int(i32 %x, i32 %y) {4564; CHECK-LABEL: define i32 @src_select_or_min_positive_int(4565; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4566; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]4567; CHECK-NEXT:    [[OR0:%.*]] = icmp eq i32 [[OR]], 14568; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]4569; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]4570; CHECK-NEXT:    [[COND:%.*]] = select i1 [[OR0]], i32 [[AND]], i32 [[XOR]]4571; CHECK-NEXT:    ret i32 [[COND]]4572;4573  %or = or i32 %x, %y4574  %or0 = icmp eq i32 %or, 14575  %and = and i32 %x, %y4576  %xor = xor i32 %x, %y4577  %cond = select i1 %or0, i32 %and, i32 %xor4578  ret i32 %cond4579}4580 4581define i32 @src_select_or_max_positive_int(i32 %x, i32 %y) {4582; CHECK-LABEL: define i32 @src_select_or_max_positive_int(4583; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4584; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]4585; CHECK-NEXT:    [[OR0:%.*]] = icmp eq i32 [[OR]], 21474836474586; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]4587; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]4588; CHECK-NEXT:    [[COND:%.*]] = select i1 [[OR0]], i32 [[AND]], i32 [[XOR]]4589; CHECK-NEXT:    ret i32 [[COND]]4590;4591  %or = or i32 %x, %y4592  %or0 = icmp eq i32 %or, 21474836474593  %and = and i32 %x, %y4594  %xor = xor i32 %x, %y4595  %cond = select i1 %or0, i32 %and, i32 %xor4596  ret i32 %cond4597}4598 4599define i32 @src_select_or_min_negative_int(i32 %x, i32 %y) {4600; CHECK-LABEL: define i32 @src_select_or_min_negative_int(4601; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4602; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]4603; CHECK-NEXT:    [[OR0:%.*]] = icmp eq i32 [[OR]], -21474836484604; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]4605; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]4606; CHECK-NEXT:    [[COND:%.*]] = select i1 [[OR0]], i32 [[AND]], i32 [[XOR]]4607; CHECK-NEXT:    ret i32 [[COND]]4608;4609  %or = or i32 %x, %y4610  %or0 = icmp eq i32 %or, -21474836484611  %and = and i32 %x, %y4612  %xor = xor i32 %x, %y4613  %cond = select i1 %or0, i32 %and, i32 %xor4614  ret i32 %cond4615}4616 4617define i32 @src_select_or_max_negative_int(i32 %x, i32 %y) {4618; CHECK-LABEL: define i32 @src_select_or_max_negative_int(4619; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4620; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]4621; CHECK-NEXT:    [[OR0:%.*]] = icmp eq i32 [[OR]], -14622; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]4623; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]4624; CHECK-NEXT:    [[COND:%.*]] = select i1 [[OR0]], i32 [[AND]], i32 [[XOR]]4625; CHECK-NEXT:    ret i32 [[COND]]4626;4627  %or = or i32 %x, %y4628  %or0 = icmp eq i32 %or, -14629  %and = and i32 %x, %y4630  %xor = xor i32 %x, %y4631  %cond = select i1 %or0, i32 %and, i32 %xor4632  ret i32 %cond4633}4634 4635define i32 @src_select_xor_min_positive_int(i32 %x, i32 %y) {4636; CHECK-LABEL: define i32 @src_select_xor_min_positive_int(4637; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4638; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]4639; CHECK-NEXT:    [[XOR0:%.*]] = icmp eq i32 [[XOR]], 14640; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]4641; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]4642; CHECK-NEXT:    [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[OR]]4643; CHECK-NEXT:    ret i32 [[COND]]4644;4645  %xor = xor i32 %x, %y4646  %xor0 = icmp eq i32 %xor, 14647  %and = and i32 %x, %y4648  %or = or i32 %x, %y4649  %cond = select i1 %xor0, i32 %and, i32 %or4650  ret i32 %cond4651}4652 4653define i32 @src_select_xor_max_positive_int(i32 %x, i32 %y) {4654; CHECK-LABEL: define i32 @src_select_xor_max_positive_int(4655; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4656; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]4657; CHECK-NEXT:    [[XOR0:%.*]] = icmp eq i32 [[XOR]], 21474836474658; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]4659; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]4660; CHECK-NEXT:    [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[OR]]4661; CHECK-NEXT:    ret i32 [[COND]]4662;4663  %xor = xor i32 %x, %y4664  %xor0 = icmp eq i32 %xor, 21474836474665  %and = and i32 %x, %y4666  %or = or i32 %x, %y4667  %cond = select i1 %xor0, i32 %and, i32 %or4668  ret i32 %cond4669}4670 4671define i32 @src_select_xor_min_negative_int(i32 %x, i32 %y) {4672; CHECK-LABEL: define i32 @src_select_xor_min_negative_int(4673; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4674; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]4675; CHECK-NEXT:    [[XOR0:%.*]] = icmp eq i32 [[XOR]], -21474836484676; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]4677; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]4678; CHECK-NEXT:    [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[OR]]4679; CHECK-NEXT:    ret i32 [[COND]]4680;4681  %xor = xor i32 %x, %y4682  %xor0 = icmp eq i32 %xor, -21474836484683  %and = and i32 %x, %y4684  %or = or i32 %x, %y4685  %cond = select i1 %xor0, i32 %and, i32 %or4686  ret i32 %cond4687}4688 4689define i32 @src_select_xor_max_negative_int(i32 %x, i32 %y) {4690; CHECK-LABEL: define i32 @src_select_xor_max_negative_int(4691; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4692; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]4693; CHECK-NEXT:    [[XOR0:%.*]] = icmp eq i32 [[XOR]], -14694; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]4695; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]4696; CHECK-NEXT:    [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[OR]]4697; CHECK-NEXT:    ret i32 [[COND]]4698;4699  %xor = xor i32 %x, %y4700  %xor0 = icmp eq i32 %xor, -14701  %and = and i32 %x, %y4702  %or = or i32 %x, %y4703  %cond = select i1 %xor0, i32 %and, i32 %or4704  ret i32 %cond4705}4706 4707; Select icmp and/or/xor4708; https://alive2.llvm.org/ce/z/BVgrJ-4709; NO TRANSFORMED - not supported4710define i32 @src_no_trans_select_and_eq0_and_or(i32 %x, i32 %y) {4711; CHECK-LABEL: define i32 @src_no_trans_select_and_eq0_and_or(4712; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4713; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]4714; CHECK-NEXT:    [[AND0:%.*]] = icmp eq i32 [[AND]], 04715; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]4716; CHECK-NEXT:    [[COND:%.*]] = select i1 [[AND0]], i32 0, i32 [[OR]]4717; CHECK-NEXT:    ret i32 [[COND]]4718;4719  %and = and i32 %x, %y4720  %and0 = icmp eq i32 %and, 04721  %or = or i32 %x, %y4722  %cond = select i1 %and0, i32 %and, i32 %or4723  ret i32 %cond4724}4725 4726define i32 @src_no_trans_select_and_eq0_and_xor(i32 %x, i32 %y) {4727; CHECK-LABEL: define i32 @src_no_trans_select_and_eq0_and_xor(4728; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4729; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]4730; CHECK-NEXT:    [[AND0:%.*]] = icmp eq i32 [[AND]], 04731; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]4732; CHECK-NEXT:    [[COND:%.*]] = select i1 [[AND0]], i32 0, i32 [[XOR]]4733; CHECK-NEXT:    ret i32 [[COND]]4734;4735  %and = and i32 %x, %y4736  %and0 = icmp eq i32 %and, 04737  %xor = xor i32 %x, %y4738  %cond = select i1 %and0, i32 %and, i32 %xor4739  ret i32 %cond4740}4741 4742define i32 @src_no_trans_select_and_eq0_or_and(i32 %x, i32 %y) {4743; CHECK-LABEL: define i32 @src_no_trans_select_and_eq0_or_and(4744; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4745; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]4746; CHECK-NEXT:    [[AND0:%.*]] = icmp eq i32 [[AND]], 04747; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]4748; CHECK-NEXT:    [[COND:%.*]] = select i1 [[AND0]], i32 [[OR]], i32 [[AND]]4749; CHECK-NEXT:    ret i32 [[COND]]4750;4751  %and = and i32 %x, %y4752  %and0 = icmp eq i32 %and, 04753  %or = or i32 %x, %y4754  %cond = select i1 %and0, i32 %or, i32 %and4755  ret i32 %cond4756}4757 4758define i32 @src_no_trans_select_and_eq0_xor_and(i32 %x, i32 %y) {4759; CHECK-LABEL: define i32 @src_no_trans_select_and_eq0_xor_and(4760; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4761; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]4762; CHECK-NEXT:    [[AND0:%.*]] = icmp eq i32 [[AND]], 04763; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]4764; CHECK-NEXT:    [[COND:%.*]] = select i1 [[AND0]], i32 [[XOR]], i32 [[AND]]4765; CHECK-NEXT:    ret i32 [[COND]]4766;4767  %and = and i32 %x, %y4768  %and0 = icmp eq i32 %and, 04769  %xor = xor i32 %x, %y4770  %cond = select i1 %and0, i32 %xor, i32 %and4771  ret i32 %cond4772}4773 4774define i32 @src_no_trans_select_or_eq0_or_and(i32 %x, i32 %y) {4775; CHECK-LABEL: define i32 @src_no_trans_select_or_eq0_or_and(4776; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4777; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]4778; CHECK-NEXT:    ret i32 [[AND]]4779;4780  %or = or i32 %x, %y4781  %or0 = icmp eq i32 %or, 04782  %and = and i32 %x, %y4783  %cond = select i1 %or0, i32 %or, i32 %and4784  ret i32 %cond4785}4786 4787define i32 @src_no_trans_select_or_eq0_or_xor(i32 %x, i32 %y) {4788; CHECK-LABEL: define i32 @src_no_trans_select_or_eq0_or_xor(4789; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4790; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]4791; CHECK-NEXT:    ret i32 [[XOR]]4792;4793  %or = or i32 %x, %y4794  %or0 = icmp eq i32 %or, 04795  %xor = xor i32 %x, %y4796  %cond = select i1 %or0, i32 %or, i32 %xor4797  ret i32 %cond4798}4799 4800define i32 @src_no_trans_select_or_eq0_and_or(i32 %x, i32 %y) {4801; CHECK-LABEL: define i32 @src_no_trans_select_or_eq0_and_or(4802; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4803; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]4804; CHECK-NEXT:    ret i32 [[OR]]4805;4806  %or = or i32 %x, %y4807  %or0 = icmp eq i32 %or, 04808  %and = and i32 %x, %y4809  %cond = select i1 %or0, i32 %and, i32 %or4810  ret i32 %cond4811}4812 4813define i32 @src_no_trans_select_or_eq0_xor_or(i32 %x, i32 %y) {4814; CHECK-LABEL: define i32 @src_no_trans_select_or_eq0_xor_or(4815; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4816; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]4817; CHECK-NEXT:    ret i32 [[OR]]4818;4819  %or = or i32 %x, %y4820  %or0 = icmp eq i32 %or, 04821  %xor = xor i32 %x, %y4822  %cond = select i1 %or0, i32 %xor, i32 %or4823  ret i32 %cond4824}4825 4826define i32 @src_no_trans_select_and_ne0_xor_or(i32 %x, i32 %y) {4827; CHECK-LABEL: define i32 @src_no_trans_select_and_ne0_xor_or(4828; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4829; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]4830; CHECK-NEXT:    ret i32 [[XOR]]4831;4832  %or = or i32 %x, %y4833  %or0 = icmp ne i32 %or, 04834  %xor = xor i32 %x, %y4835  %cond = select i1 %or0, i32 %xor, i32 %or4836  ret i32 %cond4837}4838 4839define i32 @src_no_trans_select_xor_eq0_xor_and(i32 %x, i32 %y) {4840; CHECK-LABEL: define i32 @src_no_trans_select_xor_eq0_xor_and(4841; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4842; CHECK-NEXT:    [[XOR0:%.*]] = icmp eq i32 [[X]], [[Y]]4843; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]4844; CHECK-NEXT:    [[COND:%.*]] = select i1 [[XOR0]], i32 0, i32 [[AND]]4845; CHECK-NEXT:    ret i32 [[COND]]4846;4847  %xor = xor i32 %x, %y4848  %xor0 = icmp eq i32 %xor, 04849  %and = and i32 %x, %y4850  %cond = select i1 %xor0, i32 %xor, i32 %and4851  ret i32 %cond4852}4853 4854define i32 @src_no_trans_select_xor_eq0_xor_or(i32 %x, i32 %y) {4855; CHECK-LABEL: define i32 @src_no_trans_select_xor_eq0_xor_or(4856; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4857; CHECK-NEXT:    [[XOR0:%.*]] = icmp eq i32 [[X]], [[Y]]4858; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]4859; CHECK-NEXT:    [[COND:%.*]] = select i1 [[XOR0]], i32 0, i32 [[OR]]4860; CHECK-NEXT:    ret i32 [[COND]]4861;4862  %xor = xor i32 %x, %y4863  %xor0 = icmp eq i32 %xor, 04864  %or = or i32 %x, %y4865  %cond = select i1 %xor0, i32 %xor, i32 %or4866  ret i32 %cond4867}4868 4869define i32 @src_no_trans_select_xor_eq0_and_xor(i32 %x, i32 %y) {4870; CHECK-LABEL: define i32 @src_no_trans_select_xor_eq0_and_xor(4871; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4872; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]4873; CHECK-NEXT:    [[XOR0:%.*]] = icmp eq i32 [[X]], [[Y]]4874; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[Y]]4875; CHECK-NEXT:    [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[XOR]]4876; CHECK-NEXT:    ret i32 [[COND]]4877;4878  %xor = xor i32 %x, %y4879  %xor0 = icmp eq i32 %xor, 04880  %and = and i32 %x, %y4881  %cond = select i1 %xor0, i32 %and, i32 %xor4882  ret i32 %cond4883}4884 4885; https://alive2.llvm.org/ce/z/SBe8ei4886define i32 @src_no_trans_select_xor_eq0_or_xor(i32 %x, i32 %y) {4887; CHECK-LABEL: define i32 @src_no_trans_select_xor_eq0_or_xor(4888; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4889; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]4890; CHECK-NEXT:    [[XOR0:%.*]] = icmp eq i32 [[X]], [[Y]]4891; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X]], [[Y]]4892; CHECK-NEXT:    [[COND:%.*]] = select i1 [[XOR0]], i32 [[OR]], i32 [[XOR]]4893; CHECK-NEXT:    ret i32 [[COND]]4894;4895  %xor = xor i32 %x, %y4896  %xor0 = icmp eq i32 %xor, 04897  %or = or i32 %x, %y4898  %cond = select i1 %xor0, i32 %or, i32 %xor4899  ret i32 %cond4900}4901 4902; (X == C) ? X : Y -> (X == C) ? C : Y4903; Fixed #775534904define i32 @src_select_xxory_eq0_xorxy_y(i32 %x, i32 %y) {4905; CHECK-LABEL: define i32 @src_select_xxory_eq0_xorxy_y(4906; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {4907; CHECK-NEXT:    [[XOR0:%.*]] = icmp eq i32 [[X]], [[Y]]4908; CHECK-NEXT:    [[COND:%.*]] = select i1 [[XOR0]], i32 0, i32 [[Y]]4909; CHECK-NEXT:    ret i32 [[COND]]4910;4911  %xor = xor i32 %x, %y4912  %xor0 = icmp eq i32 %xor, 04913  %cond = select i1 %xor0, i32 %xor, i32 %y4914  ret i32 %cond4915}4916 4917define i32 @sequence_select_with_same_cond_false(i1 %c1, i1 %c2){4918; CHECK-LABEL: define i32 @sequence_select_with_same_cond_false(4919; CHECK-SAME: i1 [[C1:%.*]], i1 [[C2:%.*]]) {4920; CHECK-NEXT:    [[S2:%.*]] = select i1 [[C2]], i32 666, i32 454921; CHECK-NEXT:    [[S3:%.*]] = select i1 [[C1]], i32 789, i32 [[S2]]4922; CHECK-NEXT:    ret i32 [[S3]]4923;4924  %s1 = select i1 %c1, i32 23, i32 454925  %s2 = select i1 %c2, i32 666, i32 %s14926  %s3 = select i1 %c1, i32 789, i32 %s24927  ret i32 %s34928}4929 4930define i32 @sequence_select_with_same_cond_true(i1 %c1, i1 %c2){4931; CHECK-LABEL: define i32 @sequence_select_with_same_cond_true(4932; CHECK-SAME: i1 [[C1:%.*]], i1 [[C2:%.*]]) {4933; CHECK-NEXT:    [[S2:%.*]] = select i1 [[C2]], i32 45, i32 6664934; CHECK-NEXT:    [[S3:%.*]] = select i1 [[C1]], i32 [[S2]], i32 7894935; CHECK-NEXT:    ret i32 [[S3]]4936;4937  %s1 = select i1 %c1, i32 45, i32 234938  %s2 = select i1 %c2, i32 %s1, i32 6664939  %s3 = select i1 %c1, i32 %s2, i32 7894940  ret i32 %s34941}4942 4943define double @sequence_select_with_same_cond_double(double %a, i1 %c1, i1 %c2, double %r1, double %r2){4944; CHECK-LABEL: define double @sequence_select_with_same_cond_double(4945; CHECK-SAME: double [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]], double [[R1:%.*]], double [[R2:%.*]]) {4946; CHECK-NEXT:    [[S1:%.*]] = select i1 [[C1]], double 1.000000e+00, double 0.000000e+004947; CHECK-NEXT:    [[S2:%.*]] = select i1 [[C2]], double [[S1]], double 2.000000e+004948; CHECK-NEXT:    [[S3:%.*]] = select i1 [[C1]], double [[S2]], double 3.000000e+004949; CHECK-NEXT:    ret double [[S3]]4950;4951  %s1 = select i1 %c1, double 1.0, double 0.04952  %s2 = select i1 %c2, double %s1, double 2.04953  %s3 = select i1 %c1, double %s2, double 3.04954  ret double %s34955}4956 4957declare void @use32(i32)4958 4959define i32 @sequence_select_with_same_cond_extra_use(i1 %c1, i1 %c2){4960; CHECK-LABEL: define i32 @sequence_select_with_same_cond_extra_use(4961; CHECK-SAME: i1 [[C1:%.*]], i1 [[C2:%.*]]) {4962; CHECK-NEXT:    [[S1:%.*]] = select i1 [[C1]], i32 23, i32 454963; CHECK-NEXT:    call void @use32(i32 [[S1]])4964; CHECK-NEXT:    [[S2:%.*]] = select i1 [[C2]], i32 666, i32 [[S1]]4965; CHECK-NEXT:    [[S3:%.*]] = select i1 [[C1]], i32 789, i32 [[S2]]4966; CHECK-NEXT:    ret i32 [[S3]]4967;4968  %s1 = select i1 %c1, i32 23, i32 454969  call void @use32(i32 %s1)4970  %s2 = select i1 %c2, i32 666, i32 %s14971  %s3 = select i1 %c1, i32 789, i32 %s24972  ret i32 %s34973}4974 4975define i8 @test_replace_freeze_multiuse(i1 %x, i8 %y) {4976; CHECK-LABEL: define i8 @test_replace_freeze_multiuse(4977; CHECK-SAME: i1 [[X:%.*]], i8 [[Y:%.*]]) {4978; CHECK-NEXT:    [[EXT:%.*]] = zext i1 [[X]] to i84979; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i8 [[EXT]], [[Y]]4980; CHECK-NEXT:    [[SHL_FR:%.*]] = freeze i8 [[SHL]]4981; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[X]], i8 0, i8 [[SHL_FR]]4982; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[SHL_FR]], [[SEL]]4983; CHECK-NEXT:    ret i8 [[ADD]]4984;4985  %ext = zext i1 %x to i84986  %shl = shl nuw i8 %ext, %y4987  %shl.fr = freeze i8 %shl4988  %sel = select i1 %x, i8 0, i8 %shl.fr4989  %add = add i8 %shl.fr, %sel4990  ret i8 %add4991}4992 4993define i8 @test_replace_freeze_oneuse(i1 %x, i8 %y) {4994; CHECK-LABEL: define i8 @test_replace_freeze_oneuse(4995; CHECK-SAME: i1 [[X:%.*]], i8 [[Y:%.*]]) {4996; CHECK-NEXT:    [[EXT:%.*]] = zext i1 [[X]] to i84997; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i8 [[EXT]], [[Y]]4998; CHECK-NEXT:    [[SHL_FR:%.*]] = freeze i8 [[SHL]]4999; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[X]], i8 0, i8 [[SHL_FR]]5000; CHECK-NEXT:    ret i8 [[SEL]]5001;5002  %ext = zext i1 %x to i85003  %shl = shl nuw i8 %ext, %y5004  %shl.fr = freeze i8 %shl5005  %sel = select i1 %x, i8 0, i8 %shl.fr5006  ret i8 %sel5007}5008 5009define i8 @select_knownbits_simplify(i8 noundef %x)  {5010; CHECK-LABEL: define i8 @select_knownbits_simplify(5011; CHECK-SAME: i8 noundef [[X:%.*]]) {5012; CHECK-NEXT:    [[X_LO:%.*]] = and i8 [[X]], 15013; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X_LO]], 05014; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], -25015; CHECK-NEXT:    [[RES:%.*]] = select i1 [[CMP]], i8 [[AND]], i8 05016; CHECK-NEXT:    ret i8 [[RES]]5017;5018  %x.lo = and i8 %x, 15019  %cmp = icmp eq i8 %x.lo, 05020  %and = and i8 %x, -25021  %res = select i1 %cmp, i8 %and, i8 05022  ret i8 %res5023}5024 5025define i8 @select_knownbits_simplify_nested(i8 noundef %x)  {5026; CHECK-LABEL: define i8 @select_knownbits_simplify_nested(5027; CHECK-SAME: i8 noundef [[X:%.*]]) {5028; CHECK-NEXT:    [[X_LO:%.*]] = and i8 [[X]], 15029; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X_LO]], 05030; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], -25031; CHECK-NEXT:    [[MUL:%.*]] = mul i8 [[AND]], [[AND]]5032; CHECK-NEXT:    [[RES:%.*]] = select i1 [[CMP]], i8 [[MUL]], i8 05033; CHECK-NEXT:    ret i8 [[RES]]5034;5035  %x.lo = and i8 %x, 15036  %cmp = icmp eq i8 %x.lo, 05037  %and = and i8 %x, -25038  %mul = mul i8 %and, %and5039  %res = select i1 %cmp, i8 %mul, i8 05040  ret i8 %res5041}5042 5043define i8 @select_knownbits_simplify_missing_noundef(i8 %x)  {5044; CHECK-LABEL: define i8 @select_knownbits_simplify_missing_noundef(5045; CHECK-SAME: i8 [[X:%.*]]) {5046; CHECK-NEXT:    [[X_LO:%.*]] = and i8 [[X]], 15047; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X_LO]], 05048; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], -25049; CHECK-NEXT:    [[RES:%.*]] = select i1 [[CMP]], i8 [[AND]], i8 05050; CHECK-NEXT:    ret i8 [[RES]]5051;5052  %x.lo = and i8 %x, 15053  %cmp = icmp eq i8 %x.lo, 05054  %and = and i8 %x, -25055  %res = select i1 %cmp, i8 %and, i8 05056  ret i8 %res5057}5058 5059@g_ext = external global i85060 5061; Make sure we don't replace %ptr with @g_ext, which may cause the load to trigger UB.5062define i32 @pr99436(ptr align 4 dereferenceable(4) %ptr) {5063; CHECK-LABEL: define i32 @pr99436(5064; CHECK-SAME: ptr align 4 dereferenceable(4) [[PTR:%.*]]) {5065; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[PTR]], @g_ext5066; CHECK-NEXT:    [[VAL:%.*]] = load i32, ptr [[PTR]], align 45067; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[VAL]], i32 05068; CHECK-NEXT:    ret i32 [[RET]]5069;5070  %cmp = icmp eq ptr %ptr, @g_ext5071  %val = load i32, ptr %ptr, align 45072  %ret = select i1 %cmp, i32 %val, i32 05073  ret i32 %ret5074}5075 5076define i8 @sel_trunc_simplify(i1 %c, i8 %x, i16 %y) {5077; CHECK-LABEL: define i8 @sel_trunc_simplify(5078; CHECK-SAME: i1 [[C:%.*]], i8 [[X:%.*]], i16 [[Y:%.*]]) {5079; CHECK-NEXT:    [[TMP1:%.*]] = trunc i16 [[Y]] to i85080; CHECK-NEXT:    [[TRUNC:%.*]] = select i1 [[C]], i8 [[X]], i8 [[TMP1]]5081; CHECK-NEXT:    ret i8 [[TRUNC]]5082;5083  %x.ext = zext i8 %x to i165084  %sel = select i1 %c, i16 %x.ext, i16 %y5085  %trunc = trunc i16 %sel to i85086  ret i8 %trunc5087}5088 5089define i32 @sel_umin_simplify(i1 %c, i32 %x, i16 %y) {5090; CHECK-LABEL: define i32 @sel_umin_simplify(5091; CHECK-SAME: i1 [[C:%.*]], i32 [[X:%.*]], i16 [[Y:%.*]]) {5092; CHECK-NEXT:    [[Y_EXT:%.*]] = zext i16 [[Y]] to i325093; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y_EXT]])5094; CHECK-NEXT:    [[RES:%.*]] = select i1 [[C]], i32 [[TMP1]], i32 05095; CHECK-NEXT:    ret i32 [[RES]]5096;5097  %sel = select i1 %c, i32 %x, i32 05098  %y.ext = zext i16 %y to i325099  %res = call i32 @llvm.umin.i32(i32 %sel, i32 %y.ext)5100  ret i32 %res5101}5102 5103define i32 @sel_extractvalue_simplify(i1 %c, { i32, i32 } %agg1, i32 %x, i32 %y) {5104; CHECK-LABEL: define i32 @sel_extractvalue_simplify(5105; CHECK-SAME: i1 [[C:%.*]], { i32, i32 } [[AGG1:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) {5106; CHECK-NEXT:    [[TMP1:%.*]] = extractvalue { i32, i32 } [[AGG1]], 15107; CHECK-NEXT:    [[RES:%.*]] = select i1 [[C]], i32 [[TMP1]], i32 [[Y]]5108; CHECK-NEXT:    ret i32 [[RES]]5109;5110  %agg2.0 = insertvalue { i32, i32 } poison, i32 %x, 05111  %agg2.1 = insertvalue { i32, i32 } %agg2.0, i32 %y, 15112  %sel = select i1 %c, { i32, i32 } %agg1, { i32, i32 } %agg2.15113  %res = extractvalue { i32, i32 } %sel, 15114  ret i32 %res5115}5116 5117define i1 @replace_select_cond_true(i1 %cond, i32 %v1, i32 %v2, i32 %v3) {5118; CHECK-LABEL: define i1 @replace_select_cond_true(5119; CHECK-SAME: i1 [[COND:%.*]], i32 [[V1:%.*]], i32 [[V2:%.*]], i32 [[V3:%.*]]) {5120; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[V1]], [[V2]]5121; CHECK-NEXT:    [[AND:%.*]] = select i1 [[COND]], i1 [[CMP]], i1 false5122; CHECK-NEXT:    ret i1 [[AND]]5123;5124  %sel = select i1 %cond, i32 %v1, i32 %v35125  %cmp = icmp eq i32 %sel, %v25126  %and = select i1 %cond, i1 %cmp, i1 false5127  ret i1 %and5128}5129 5130define i1 @replace_select_cond_false(i1 %cond, i32 %v1, i32 %v2, i32 %v3) {5131; CHECK-LABEL: define i1 @replace_select_cond_false(5132; CHECK-SAME: i1 [[COND:%.*]], i32 [[V1:%.*]], i32 [[V2:%.*]], i32 [[V3:%.*]]) {5133; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[V3]], [[V2]]5134; CHECK-NEXT:    [[OR:%.*]] = select i1 [[COND]], i1 true, i1 [[CMP]]5135; CHECK-NEXT:    ret i1 [[OR]]5136;5137  %sel = select i1 %cond, i32 %v1, i32 %v35138  %cmp = icmp eq i32 %sel, %v25139  %or = select i1 %cond, i1 true, i1 %cmp5140  ret i1 %or5141}5142 5143define i32 @replace_and_cond(i1 %cond1, i1 %cond2) {5144; CHECK-LABEL: define i32 @replace_and_cond(5145; CHECK-SAME: i1 [[COND1:%.*]], i1 [[COND2:%.*]]) {5146; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND2]], i32 3, i32 25147; CHECK-NEXT:    [[MUX:%.*]] = select i1 [[COND1]], i32 [[SEL]], i32 15148; CHECK-NEXT:    ret i32 [[MUX]]5149;5150  %and = and i1 %cond1, %cond25151  %sel = select i1 %and, i32 3, i32 25152  %mux = select i1 %cond1, i32 %sel, i32 15153  ret i32 %mux5154}5155 5156define <2 x i32> @replace_and_cond_vec(<2 x i1> %cond1, <2 x i1> %cond2) {5157; CHECK-LABEL: define <2 x i32> @replace_and_cond_vec(5158; CHECK-SAME: <2 x i1> [[COND1:%.*]], <2 x i1> [[COND2:%.*]]) {5159; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[COND2]], <2 x i32> splat (i32 3), <2 x i32> splat (i32 2)5160; CHECK-NEXT:    [[MUX:%.*]] = select <2 x i1> [[COND1]], <2 x i32> [[SEL]], <2 x i32> splat (i32 1)5161; CHECK-NEXT:    ret <2 x i32> [[MUX]]5162;5163  %and = and <2 x i1> %cond1, %cond25164  %sel = select <2 x i1> %and, <2 x i32> splat(i32 3), <2 x i32> splat(i32 2)5165  %mux = select <2 x i1> %cond1, <2 x i32> %sel, <2 x i32> splat(i32 1)5166  ret <2 x i32> %mux5167}5168 5169; TODO: We can still replace the use of %and with %cond25170define i32 @replace_and_cond_multiuse1(i1 %cond1, i1 %cond2) {5171; CHECK-LABEL: define i32 @replace_and_cond_multiuse1(5172; CHECK-SAME: i1 [[COND1:%.*]], i1 [[COND2:%.*]]) {5173; CHECK-NEXT:    [[AND:%.*]] = and i1 [[COND1]], [[COND2]]5174; CHECK-NEXT:    call void @use(i1 [[AND]])5175; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[AND]], i32 3, i32 25176; CHECK-NEXT:    [[MUX:%.*]] = select i1 [[COND1]], i32 [[SEL]], i32 15177; CHECK-NEXT:    ret i32 [[MUX]]5178;5179  %and = and i1 %cond1, %cond25180  call void @use(i1 %and)5181  %sel = select i1 %and, i32 3, i32 25182  %mux = select i1 %cond1, i32 %sel, i32 15183  ret i32 %mux5184}5185 5186define i32 @replace_and_cond_multiuse2(i1 %cond1, i1 %cond2) {5187; CHECK-LABEL: define i32 @replace_and_cond_multiuse2(5188; CHECK-SAME: i1 [[COND1:%.*]], i1 [[COND2:%.*]]) {5189; CHECK-NEXT:    [[AND:%.*]] = and i1 [[COND1]], [[COND2]]5190; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[AND]], i32 3, i32 25191; CHECK-NEXT:    call void @use32(i32 [[SEL]])5192; CHECK-NEXT:    [[MUX:%.*]] = select i1 [[COND1]], i32 [[SEL]], i32 15193; CHECK-NEXT:    ret i32 [[MUX]]5194;5195  %and = and i1 %cond1, %cond25196  %sel = select i1 %and, i32 3, i32 25197  call void @use32(i32 %sel)5198  %mux = select i1 %cond1, i32 %sel, i32 15199  ret i32 %mux5200}5201 5202define i32 @src_simplify_2x_at_once_and(i32 %x, i32 %y) {5203; CHECK-LABEL: define i32 @src_simplify_2x_at_once_and(5204; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {5205; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]5206; CHECK-NEXT:    ret i32 [[XOR]]5207;5208  %and = and i32 %x, %y5209  %and0 = icmp eq i32 %and, -15210  %sub = sub i32 %x, %y5211  %xor = xor i32 %x, %y5212  %cond = select i1 %and0, i32 %sub, i32 %xor5213  ret i32 %cond5214}5215 5216define void @select_freeze_poison_parameter(ptr noundef %addr.src, ptr %addr.tgt, i1 %cond) {5217; CHECK-LABEL: define void @select_freeze_poison_parameter(5218; CHECK-SAME: ptr noundef [[ADDR_SRC:%.*]], ptr [[ADDR_TGT:%.*]], i1 [[COND:%.*]]) {5219; CHECK-NEXT:    store ptr [[ADDR_SRC]], ptr [[ADDR_TGT]], align 85220; CHECK-NEXT:    ret void5221;5222  %freeze = freeze ptr poison5223  %select.addr = select i1 %cond, ptr %addr.src, ptr %freeze5224  store ptr %select.addr, ptr %addr.tgt5225  ret void5226}5227 5228define i8 @select_freeze_poison_different_parameters(i8 noundef %x, i8 noundef %y, i1 %cond1, i1 %cond2) {5229; CHECK-LABEL: define i8 @select_freeze_poison_different_parameters(5230; CHECK-SAME: i8 noundef [[X:%.*]], i8 noundef [[Y:%.*]], i1 [[COND1:%.*]], i1 [[COND2:%.*]]) {5231; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[COND1]], i8 [[X]], i8 05232; CHECK-NEXT:    [[SEL2:%.*]] = select i1 [[COND2]], i8 [[Y]], i8 05233; CHECK-NEXT:    [[CONJ:%.*]] = and i8 [[SEL1]], [[SEL2]]5234; CHECK-NEXT:    ret i8 [[CONJ]]5235;5236  %freeze = freeze i8 poison5237  %sel1 = select i1 %cond1, i8 %x, i8 %freeze5238  %sel2 = select i1 %cond2, i8 %y, i8 %freeze5239  %conj = and i8 %sel1, %sel25240  ret i8 %conj5241}5242 5243define i8 @select_or_freeze_poison_parameter(i8 noundef %x, i1 %cond1) {5244; CHECK-LABEL: define i8 @select_or_freeze_poison_parameter(5245; CHECK-SAME: i8 noundef [[X:%.*]], i1 [[COND1:%.*]]) {5246; CHECK-NEXT:    ret i8 -15247;5248  %freeze = freeze i8 poison5249  %sel1 = select i1 %cond1, i8 -1, i8 %freeze5250  %or1 = or i8 %x, %freeze5251  %conj = and i8 %sel1, %or15252  ret i8 %conj5253}5254 5255define i8 @selects_freeze_poison_parameter(i8 noundef %x, i1 %cond1, i1 %cond2) {5256; CHECK-LABEL: define i8 @selects_freeze_poison_parameter(5257; CHECK-SAME: i8 noundef [[X:%.*]], i1 [[COND1:%.*]], i1 [[COND2:%.*]]) {5258; CHECK-NEXT:    ret i8 [[X]]5259;5260  %freeze = freeze i8 poison5261  %sel1 = select i1 %cond1, i8 %x, i8 %freeze5262  %sel2 = select i1 %cond2, i8 %x, i8 %freeze5263  %conj = and i8 %sel1, %sel25264  ret i8 %conj5265}5266 5267@glb = global ptr null5268 5269define void @select_freeze_poison_global(ptr %addr.tgt, i1 %cond) {5270; CHECK-LABEL: define void @select_freeze_poison_global(5271; CHECK-SAME: ptr [[ADDR_TGT:%.*]], i1 [[COND:%.*]]) {5272; CHECK-NEXT:    store ptr @glb, ptr [[ADDR_TGT]], align 85273; CHECK-NEXT:    ret void5274;5275  %freeze = freeze ptr poison5276  %select.addr = select i1 %cond, ptr @glb, ptr %freeze5277  store ptr %select.addr, ptr %addr.tgt5278  ret void5279}5280 5281define void @select_freeze_poison_constant(ptr %addr.tgt, i1 %cond) {5282; CHECK-LABEL: define void @select_freeze_poison_constant(5283; CHECK-SAME: ptr [[ADDR_TGT:%.*]], i1 [[COND:%.*]]) {5284; CHECK-NEXT:    store i32 72, ptr [[ADDR_TGT]], align 45285; CHECK-NEXT:    ret void5286;5287  %freeze = freeze i32 poison5288  %select.addr = select i1 %cond, i32 72, i32 %freeze5289  store i32 %select.addr, ptr %addr.tgt5290  ret void5291}5292 5293define <2 x i8> @select_freeze_poison_mask_vector(i1 %cond, <2 x i8> noundef %y) {5294; CHECK-LABEL: define <2 x i8> @select_freeze_poison_mask_vector(5295; CHECK-SAME: i1 [[COND:%.*]], <2 x i8> noundef [[Y:%.*]]) {5296; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], <2 x i8> [[Y]], <2 x i8> zeroinitializer5297; CHECK-NEXT:    ret <2 x i8> [[SEL]]5298;5299  %freeze = freeze <2 x i8> <i8 0, i8 poison>5300  %sel = select i1 %cond, <2 x i8> %y, <2 x i8> %freeze5301  ret <2 x i8> %sel5302}5303 5304define <2 x i8> @selects_freeze_poison_mask_vector(<2 x i8> noundef %x, i1 %cond1, i1 %cond2) {5305; CHECK-LABEL: define <2 x i8> @selects_freeze_poison_mask_vector(5306; CHECK-SAME: <2 x i8> noundef [[X:%.*]], i1 [[COND1:%.*]], i1 [[COND2:%.*]]) {5307; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[COND1]], i1 [[COND2]], i1 false5308; CHECK-NEXT:    [[CONJ:%.*]] = select i1 [[TMP1]], <2 x i8> [[X]], <2 x i8> zeroinitializer5309; CHECK-NEXT:    ret <2 x i8> [[CONJ]]5310;5311  %freeze = freeze <2 x i8> <i8 0, i8 poison>5312  %sel1 = select i1 %cond1, <2 x i8> %x, <2 x i8> %freeze5313  %sel2 = select i1 %cond2, <2 x i8> %x, <2 x i8> %freeze5314  %conj = and <2 x i8> %sel1, %sel25315  ret <2 x i8> %conj5316}5317 5318define <2 x i8> @select_freeze_poison_splat_vector(i1 %cond, <2 x i8> noundef %y) {5319; CHECK-LABEL: define <2 x i8> @select_freeze_poison_splat_vector(5320; CHECK-SAME: i1 [[COND:%.*]], <2 x i8> noundef [[Y:%.*]]) {5321; CHECK-NEXT:    ret <2 x i8> [[Y]]5322;5323  %freeze = freeze <2 x i8> <i8 poison, i8 poison>5324  %sel = select i1 %cond, <2 x i8> %y, <2 x i8> %freeze5325  ret <2 x i8> %sel5326}5327 5328define <2 x i8> @selects_freeze_poison_splat_vector(<2 x i8> noundef %x, i1 %cond1, i1 %cond2) {5329; CHECK-LABEL: define <2 x i8> @selects_freeze_poison_splat_vector(5330; CHECK-SAME: <2 x i8> noundef [[X:%.*]], i1 [[COND1:%.*]], i1 [[COND2:%.*]]) {5331; CHECK-NEXT:    ret <2 x i8> [[X]]5332;5333  %freeze = freeze <2 x i8> <i8 poison, i8 poison>5334  %sel1 = select i1 %cond1, <2 x i8> %x, <2 x i8> %freeze5335  %sel2 = select i1 %cond2, <2 x i8> %x, <2 x i8> %freeze5336  %conj = and <2 x i8> %sel1, %sel25337  ret <2 x i8> %conj5338}5339 5340define <2 x i8> @select_freeze_constant_vector(i1 %cond, <2 x i8> noundef %y) {5341; CHECK-LABEL: define <2 x i8> @select_freeze_constant_vector(5342; CHECK-SAME: i1 [[COND:%.*]], <2 x i8> noundef [[Y:%.*]]) {5343; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], <2 x i8> [[Y]], <2 x i8> zeroinitializer5344; CHECK-NEXT:    ret <2 x i8> [[SEL]]5345;5346  %freeze = freeze <2 x i8> <i8 0, i8 0>5347  %sel = select i1 %cond, <2 x i8> %y, <2 x i8> %freeze5348  ret <2 x i8> %sel5349}5350 5351define <2 x i8> @select_freeze_constant_expression_vector_add(i1 %cond, <2 x i8> noundef %y) {5352; CHECK-LABEL: define <2 x i8> @select_freeze_constant_expression_vector_add(5353; CHECK-SAME: i1 [[COND:%.*]], <2 x i8> noundef [[Y:%.*]]) {5354; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], <2 x i8> [[Y]], <2 x i8> splat (i8 3)5355; CHECK-NEXT:    ret <2 x i8> [[SEL]]5356;5357  %freeze = freeze <2 x i8> <i8 poison, i8 add (i8 1, i8 2)>5358  %sel = select i1 %cond, <2 x i8> %y, <2 x i8> %freeze5359  ret <2 x i8> %sel5360}5361 5362%struct.1 = type {i32, i32}5363@glb.struct.1 = global %struct.1 {i32 1, i32 2}5364 5365define <2 x ptr> @select_freeze_constant_expression_vector_gep(i1 %cond, <2 x ptr> noundef %y) {5366; CHECK-LABEL: define <2 x ptr> @select_freeze_constant_expression_vector_gep(5367; CHECK-SAME: i1 [[COND:%.*]], <2 x ptr> noundef [[Y:%.*]]) {5368; CHECK-NEXT:    [[FREEZE:%.*]] = freeze <2 x ptr> <ptr poison, ptr getelementptr inbounds nuw (i8, ptr @glb.struct.1, i64 800)>5369; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], <2 x ptr> [[Y]], <2 x ptr> [[FREEZE]]5370; CHECK-NEXT:    ret <2 x ptr> [[SEL]]5371;5372  %freeze = freeze <2 x ptr> <ptr poison, ptr getelementptr inbounds (%struct.1, ptr @glb.struct.1, i64 100)>5373  %sel = select i1 %cond, <2 x ptr> %y, <2 x ptr> %freeze5374  ret <2 x ptr> %sel5375}5376 5377define void @no_fold_masked_min_loop(ptr nocapture readonly %vals, ptr nocapture readonly %masks, ptr nocapture %out, i64 %n) {5378; CHECK-LABEL: define void @no_fold_masked_min_loop(5379; CHECK-SAME: ptr readonly captures(none) [[VALS:%.*]], ptr readonly captures(none) [[MASKS:%.*]], ptr captures(none) [[OUT:%.*]], i64 [[N:%.*]]) {5380; CHECK-NEXT:  [[ENTRY:.*]]:5381; CHECK-NEXT:    br label %[[LOOP:.*]]5382; CHECK:       [[LOOP]]:5383; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[NEXT_INDEX:%.*]], %[[LOOP]] ]5384; CHECK-NEXT:    [[ACC:%.*]] = phi i8 [ -1, %[[ENTRY]] ], [ [[RES:%.*]], %[[LOOP]] ]5385; CHECK-NEXT:    [[VAL_PTR:%.*]] = getelementptr inbounds i8, ptr [[VALS]], i64 [[INDEX]]5386; CHECK-NEXT:    [[MASK_PTR:%.*]] = getelementptr inbounds i8, ptr [[MASKS]], i64 [[INDEX]]5387; CHECK-NEXT:    [[VAL:%.*]] = load i8, ptr [[VAL_PTR]], align 15388; CHECK-NEXT:    [[MASK:%.*]] = load i8, ptr [[MASK_PTR]], align 15389; CHECK-NEXT:    [[COND:%.*]] = icmp eq i8 [[MASK]], 05390; CHECK-NEXT:    [[MASKED_VAL:%.*]] = select i1 [[COND]], i8 [[VAL]], i8 -15391; CHECK-NEXT:    [[RES]] = call i8 @llvm.umin.i8(i8 [[ACC]], i8 [[MASKED_VAL]])5392; CHECK-NEXT:    [[NEXT_INDEX]] = add i64 [[INDEX]], 15393; CHECK-NEXT:    [[DONE:%.*]] = icmp eq i64 [[NEXT_INDEX]], [[N]]5394; CHECK-NEXT:    br i1 [[DONE]], label %[[EXIT:.*]], label %[[LOOP]]5395; CHECK:       [[EXIT]]:5396; CHECK-NEXT:    store i8 [[RES]], ptr [[OUT]], align 15397; CHECK-NEXT:    ret void5398;5399entry:5400  br label %loop5401 5402loop:5403  %index = phi i64 [0, %entry], [%next_index, %loop]5404  %acc = phi i8 [255, %entry], [%res, %loop]5405 5406  %val_ptr = getelementptr inbounds i8, ptr %vals, i64 %index5407  %mask_ptr = getelementptr inbounds i8, ptr %masks, i64 %index5408 5409  %val = load i8, ptr %val_ptr, align 15410  %mask = load i8, ptr %mask_ptr, align 15411 5412  %cond = icmp eq i8 %mask, 05413  %masked_val = select i1 %cond, i8 %val, i8 -15414  %res = call i8 @llvm.umin.i8(i8 %acc, i8 %masked_val)5415 5416  %next_index = add i64 %index, 15417  %done = icmp eq i64 %next_index, %n5418  br i1 %done, label %exit, label %loop5419 5420exit:5421  store i8 %res, ptr %out, align 15422  ret void5423}5424