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