947 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4;; ((X & 27) ? 27 : 0)5 6define i41 @test5(i41 %X) {7; CHECK-LABEL: @test5(8; CHECK-NEXT: [[Y:%.*]] = and i41 [[X:%.*]], 329; CHECK-NEXT: ret i41 [[Y]]10;11 %Y = and i41 %X, 3212 %t = icmp ne i41 %Y, 013 %V = select i1 %t, i41 32, i41 014 ret i41 %V15}16 17;; ((X & 27) ? 27 : 0)18 19define i1023 @test6(i1023 %X) {20; CHECK-LABEL: @test6(21; CHECK-NEXT: [[Y:%.*]] = and i1023 [[X:%.*]], 6422; CHECK-NEXT: ret i1023 [[Y]]23;24 %Y = and i1023 %X, 6425 %t = icmp ne i1023 %Y, 026 %V = select i1 %t, i1023 64, i1023 027 ret i1023 %V28}29 30define i32 @test35(i32 %x) {31; CHECK-LABEL: @test35(32; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -133; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 60, i32 10034; CHECK-NEXT: ret i32 [[COND]]35;36 %cmp = icmp sge i32 %x, 037 %cond = select i1 %cmp, i32 60, i32 10038 ret i32 %cond39}40 41define <2 x i32> @test35vec(<2 x i32> %x) {42; CHECK-LABEL: @test35vec(43; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[X:%.*]], splat (i32 -1)44; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> splat (i32 60), <2 x i32> splat (i32 100)45; CHECK-NEXT: ret <2 x i32> [[COND]]46;47 %cmp = icmp sge <2 x i32> %x, <i32 0, i32 0>48 %cond = select <2 x i1> %cmp, <2 x i32> <i32 60, i32 60>, <2 x i32> <i32 100, i32 100>49 ret <2 x i32> %cond50}51 52; Make sure we can still perform this optimization with a truncate present53define i32 @test35_with_trunc(i64 %x) {54; CHECK-LABEL: @test35_with_trunc(55; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[X:%.*]], 214748364856; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP1]], 057; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 60, i32 10058; CHECK-NEXT: ret i32 [[COND]]59;60 %x1 = trunc i64 %x to i3261 %cmp = icmp sge i32 %x1, 062 %cond = select i1 %cmp, i32 60, i32 10063 ret i32 %cond64}65 66define i32 @test36(i32 %x) {67; CHECK-LABEL: @test36(68; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 069; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 60, i32 10070; CHECK-NEXT: ret i32 [[COND]]71;72 %cmp = icmp slt i32 %x, 073 %cond = select i1 %cmp, i32 60, i32 10074 ret i32 %cond75}76 77define <2 x i32> @test36vec(<2 x i32> %x) {78; CHECK-LABEL: @test36vec(79; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer80; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> splat (i32 60), <2 x i32> splat (i32 100)81; CHECK-NEXT: ret <2 x i32> [[COND]]82;83 %cmp = icmp slt <2 x i32> %x, <i32 0, i32 0>84 %cond = select <2 x i1> %cmp, <2 x i32> <i32 60, i32 60>, <2 x i32> <i32 100, i32 100>85 ret <2 x i32> %cond86}87 88define i32 @test37(i32 %x) {89; CHECK-LABEL: @test37(90; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -191; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 1, i32 -192; CHECK-NEXT: ret i32 [[COND]]93;94 %cmp = icmp sgt i32 %x, -195 %cond = select i1 %cmp, i32 1, i32 -196 ret i32 %cond97}98 99define <2 x i32> @test37vec(<2 x i32> %x) {100; CHECK-LABEL: @test37vec(101; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[X:%.*]], splat (i32 -1)102; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> splat (i32 1), <2 x i32> splat (i32 -1)103; CHECK-NEXT: ret <2 x i32> [[COND]]104;105 %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>106 %cond = select <2 x i1> %cmp, <2 x i32> <i32 1, i32 1>, <2 x i32> <i32 -1, i32 -1>107 ret <2 x i32> %cond108}109 110define i32 @test65(i64 %x) {111; CHECK-LABEL: @test65(112; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[X:%.*]], 16113; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i64 [[TMP1]], 0114; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[DOTNOT]], i32 42, i32 40115; CHECK-NEXT: ret i32 [[TMP2]]116;117 %1 = and i64 %x, 16118 %2 = icmp ne i64 %1, 0119 %3 = select i1 %2, i32 40, i32 42120 ret i32 %3121}122 123define <2 x i32> @test65vec(<2 x i64> %x) {124; CHECK-LABEL: @test65vec(125; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i64> [[X:%.*]], splat (i64 16)126; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq <2 x i64> [[TMP1]], zeroinitializer127; CHECK-NEXT: [[TMP2:%.*]] = select <2 x i1> [[DOTNOT]], <2 x i32> splat (i32 42), <2 x i32> splat (i32 40)128; CHECK-NEXT: ret <2 x i32> [[TMP2]]129;130 %1 = and <2 x i64> %x, <i64 16, i64 16>131 %2 = icmp ne <2 x i64> %1, zeroinitializer132 %3 = select <2 x i1> %2, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42>133 ret <2 x i32> %3134}135 136define i32 @test66(i64 %x) {137; CHECK-LABEL: @test66(138; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[X:%.*]], 4294967296139; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i64 [[TMP1]], 0140; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[DOTNOT]], i32 42, i32 40141; CHECK-NEXT: ret i32 [[TMP2]]142;143 %1 = and i64 %x, 4294967296144 %2 = icmp ne i64 %1, 0145 %3 = select i1 %2, i32 40, i32 42146 ret i32 %3147}148 149define <2 x i32> @test66vec(<2 x i64> %x) {150; CHECK-LABEL: @test66vec(151; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i64> [[X:%.*]], splat (i64 4294967296)152; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq <2 x i64> [[TMP1]], zeroinitializer153; CHECK-NEXT: [[TMP2:%.*]] = select <2 x i1> [[DOTNOT]], <2 x i32> splat (i32 42), <2 x i32> splat (i32 40)154; CHECK-NEXT: ret <2 x i32> [[TMP2]]155;156 %1 = and <2 x i64> %x, <i64 4294967296, i64 4294967296>157 %2 = icmp ne <2 x i64> %1, zeroinitializer158 %3 = select <2 x i1> %2, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42>159 ret <2 x i32> %3160}161 162; Make sure we don't try to optimize a scalar 'and' with a vector select.163define <2 x i32> @test66vec_scalar_and(i64 %x) {164; CHECK-LABEL: @test66vec_scalar_and(165; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[X:%.*]], 4294967296166; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i64 [[TMP1]], 0167; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[DOTNOT]], <2 x i32> splat (i32 42), <2 x i32> splat (i32 40)168; CHECK-NEXT: ret <2 x i32> [[TMP2]]169;170 %1 = and i64 %x, 4294967296171 %2 = icmp ne i64 %1, 0172 %3 = select i1 %2, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42>173 ret <2 x i32> %3174}175 176define i32 @test67(i16 %x) {177; CHECK-LABEL: @test67(178; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[X:%.*]], 4179; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i16 [[TMP1]], 0180; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[DOTNOT]], i32 42, i32 40181; CHECK-NEXT: ret i32 [[TMP2]]182;183 %1 = and i16 %x, 4184 %2 = icmp ne i16 %1, 0185 %3 = select i1 %2, i32 40, i32 42186 ret i32 %3187}188 189define <2 x i32> @test67vec(<2 x i16> %x) {190; CHECK-LABEL: @test67vec(191; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i16> [[X:%.*]], splat (i16 4)192; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq <2 x i16> [[TMP1]], zeroinitializer193; CHECK-NEXT: [[TMP2:%.*]] = select <2 x i1> [[DOTNOT]], <2 x i32> splat (i32 42), <2 x i32> splat (i32 40)194; CHECK-NEXT: ret <2 x i32> [[TMP2]]195;196 %1 = and <2 x i16> %x, <i16 4, i16 4>197 %2 = icmp ne <2 x i16> %1, zeroinitializer198 %3 = select <2 x i1> %2, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42>199 ret <2 x i32> %3200}201 202define i32 @test71(i32 %x) {203; CHECK-LABEL: @test71(204; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 128205; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 0206; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[DOTNOT]], i32 42, i32 40207; CHECK-NEXT: ret i32 [[TMP2]]208;209 %1 = and i32 %x, 128210 %2 = icmp ne i32 %1, 0211 %3 = select i1 %2, i32 40, i32 42212 ret i32 %3213}214 215define <2 x i32> @test71vec(<2 x i32> %x) {216; CHECK-LABEL: @test71vec(217; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 128)218; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer219; CHECK-NEXT: [[TMP2:%.*]] = select <2 x i1> [[DOTNOT]], <2 x i32> splat (i32 42), <2 x i32> splat (i32 40)220; CHECK-NEXT: ret <2 x i32> [[TMP2]]221;222 %1 = and <2 x i32> %x, <i32 128, i32 128>223 %2 = icmp ne <2 x i32> %1, <i32 0, i32 0>224 %3 = select <2 x i1> %2, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42>225 ret <2 x i32> %3226}227 228define i32 @test72(i32 %x) {229; CHECK-LABEL: @test72(230; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 128231; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0232; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 40, i32 42233; CHECK-NEXT: ret i32 [[TMP3]]234;235 %1 = and i32 %x, 128236 %2 = icmp eq i32 %1, 0237 %3 = select i1 %2, i32 40, i32 42238 ret i32 %3239}240 241define <2 x i32> @test72vec(<2 x i32> %x) {242; CHECK-LABEL: @test72vec(243; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 128)244; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer245; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> splat (i32 40), <2 x i32> splat (i32 42)246; CHECK-NEXT: ret <2 x i32> [[TMP3]]247;248 %1 = and <2 x i32> %x, <i32 128, i32 128>249 %2 = icmp eq <2 x i32> %1, <i32 0, i32 0>250 %3 = select <2 x i1> %2, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42>251 ret <2 x i32> %3252}253 254define i32 @test73(i32 %x) {255; CHECK-LABEL: @test73(256; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 128257; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0258; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 40, i32 42259; CHECK-NEXT: ret i32 [[TMP3]]260;261 %1 = trunc i32 %x to i8262 %2 = icmp sgt i8 %1, -1263 %3 = select i1 %2, i32 40, i32 42264 ret i32 %3265}266 267define <2 x i32> @test73vec(<2 x i32> %x) {268; CHECK-LABEL: @test73vec(269; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 128)270; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer271; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> splat (i32 40), <2 x i32> splat (i32 42)272; CHECK-NEXT: ret <2 x i32> [[TMP3]]273;274 %1 = trunc <2 x i32> %x to <2 x i8>275 %2 = icmp sgt <2 x i8> %1, <i8 -1, i8 -1>276 %3 = select <2 x i1> %2, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42>277 ret <2 x i32> %3278}279 280define i32 @test74(i32 %x) {281; CHECK-LABEL: @test74(282; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], -1283; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 40, i32 42284; CHECK-NEXT: ret i32 [[TMP2]]285;286 %1 = icmp sgt i32 %x, -1287 %2 = select i1 %1, i32 40, i32 42288 ret i32 %2289}290 291define <2 x i32> @test74vec(<2 x i32> %x) {292; CHECK-LABEL: @test74vec(293; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <2 x i32> [[X:%.*]], splat (i32 -1)294; CHECK-NEXT: [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> splat (i32 40), <2 x i32> splat (i32 42)295; CHECK-NEXT: ret <2 x i32> [[TMP2]]296;297 %1 = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>298 %2 = select <2 x i1> %1, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42>299 ret <2 x i32> %2300}301 302define i64 @test75(i32 %X) {303; CHECK-LABEL: @test75(304; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0305; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i64 0, i64 8306; CHECK-NEXT: ret i64 [[TMP2]]307;308 %1 = icmp slt i32 %X, 0309 %2 = select i1 %1, i64 0, i64 8310 ret i64 %2311}312 313;; Code sequence for (X & 16) ? 16 : 0314define i32 @test15a(i32 %X) {315; CHECK-LABEL: @test15a(316; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 16317; CHECK-NEXT: ret i32 [[T1]]318;319 %t1 = and i32 %X, 16320 %t2 = icmp eq i32 %t1, 0321 %t3 = select i1 %t2, i32 0, i32 16322 ret i32 %t3323}324 325;; Code sequence for (X & 32) ? 0 : 24326define i32 @test15b(i32 %X) {327; CHECK-LABEL: @test15b(328; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 32329; CHECK-NEXT: [[T3:%.*]] = xor i32 [[T1]], 32330; CHECK-NEXT: ret i32 [[T3]]331;332 %t1 = and i32 %X, 32333 %t2 = icmp eq i32 %t1, 0334 %t3 = select i1 %t2, i32 32, i32 0335 ret i32 %t3336}337 338;; Alternate code sequence for (X & 16) ? 16 : 0339define i32 @test15c(i32 %X) {340; CHECK-LABEL: @test15c(341; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 16342; CHECK-NEXT: ret i32 [[T1]]343;344 %t1 = and i32 %X, 16345 %t2 = icmp eq i32 %t1, 16346 %t3 = select i1 %t2, i32 16, i32 0347 ret i32 %t3348}349 350;; Alternate code sequence for (X & 16) ? 16 : 0351define i32 @test15d(i32 %X) {352; CHECK-LABEL: @test15d(353; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 16354; CHECK-NEXT: ret i32 [[T1]]355;356 %t1 = and i32 %X, 16357 %t2 = icmp ne i32 %t1, 0358 %t3 = select i1 %t2, i32 16, i32 0359 ret i32 %t3360}361 362;; (a & 128) ? 256 : 0363define i32 @test15e(i32 %X) {364; CHECK-LABEL: @test15e(365; CHECK-NEXT: [[T1:%.*]] = shl i32 [[X:%.*]], 1366; CHECK-NEXT: [[T3:%.*]] = and i32 [[T1]], 256367; CHECK-NEXT: ret i32 [[T3]]368;369 %t1 = and i32 %X, 128370 %t2 = icmp ne i32 %t1, 0371 %t3 = select i1 %t2, i32 256, i32 0372 ret i32 %t3373}374 375;; (a & 128) ? 256 : 0376define i32 @test15e_extra_use(i32 %X) {377; CHECK-LABEL: @test15e_extra_use(378; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 128379; CHECK-NEXT: [[T2:%.*]] = icmp ne i32 [[T1]], 0380; CHECK-NEXT: [[T3:%.*]] = shl nuw nsw i32 [[T1]], 1381; CHECK-NEXT: call void @use1(i1 [[T2]])382; CHECK-NEXT: ret i32 [[T3]]383;384 %t1 = and i32 %X, 128385 %t2 = icmp ne i32 %t1, 0386 %t3 = select i1 %t2, i32 256, i32 0387 call void @use1(i1 %t2)388 ret i32 %t3389}390 391;; (a & 128) ? 256 : 0392define i32 @test15e_zext(i8 %X) {393; CHECK-LABEL: @test15e_zext(394; CHECK-NEXT: [[T2_NOT:%.*]] = icmp sgt i8 [[X:%.*]], -1395; CHECK-NEXT: [[T3:%.*]] = select i1 [[T2_NOT]], i32 0, i32 256396; CHECK-NEXT: ret i32 [[T3]]397;398 %t1 = and i8 %X, 128399 %t2 = icmp ne i8 %t1, 0400 %t3 = select i1 %t2, i32 256, i32 0401 ret i32 %t3402}403 404;; (a & 128) ? 256 : 0405define i32 @test15e_zext_extra_use(i8 %X) {406; CHECK-LABEL: @test15e_zext_extra_use(407; CHECK-NEXT: [[T2:%.*]] = icmp slt i8 [[X:%.*]], 0408; CHECK-NEXT: [[T3:%.*]] = select i1 [[T2]], i32 256, i32 0409; CHECK-NEXT: call void @use1(i1 [[T2]])410; CHECK-NEXT: ret i32 [[T3]]411;412 %t1 = and i8 %X, 128413 %t2 = icmp ne i8 %t1, 0414 %t3 = select i1 %t2, i32 256, i32 0415 call void @use1(i1 %t2)416 ret i32 %t3417}418 419;; (a & 128) ? 0 : 256420define i32 @test15f(i32 %X) {421; CHECK-LABEL: @test15f(422; CHECK-NEXT: [[T1:%.*]] = shl i32 [[X:%.*]], 1423; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[T1]], 256424; CHECK-NEXT: [[T3:%.*]] = xor i32 [[TMP1]], 256425; CHECK-NEXT: ret i32 [[T3]]426;427 %t1 = and i32 %X, 128428 %t2 = icmp ne i32 %t1, 0429 %t3 = select i1 %t2, i32 0, i32 256430 ret i32 %t3431}432 433;; (a & 128) ? 0 : 256434define i32 @test15f_extra_use(i32 %X) {435; CHECK-LABEL: @test15f_extra_use(436; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 128437; CHECK-NEXT: [[T2:%.*]] = icmp ne i32 [[T1]], 0438; CHECK-NEXT: [[T3:%.*]] = select i1 [[T2]], i32 0, i32 256439; CHECK-NEXT: call void @use1(i1 [[T2]])440; CHECK-NEXT: ret i32 [[T3]]441;442 %t1 = and i32 %X, 128443 %t2 = icmp ne i32 %t1, 0444 %t3 = select i1 %t2, i32 0, i32 256445 call void @use1(i1 %t2)446 ret i32 %t3447}448 449;; (a & 128) ? 0 : 256450define i16 @test15f_trunc(i32 %X) {451; CHECK-LABEL: @test15f_trunc(452; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 128453; CHECK-NEXT: [[T2_NOT:%.*]] = icmp eq i32 [[T1]], 0454; CHECK-NEXT: [[T3:%.*]] = select i1 [[T2_NOT]], i16 256, i16 0455; CHECK-NEXT: ret i16 [[T3]]456;457 %t1 = and i32 %X, 128458 %t2 = icmp ne i32 %t1, 0459 %t3 = select i1 %t2, i16 0, i16 256460 ret i16 %t3461}462 463;; (a & 8) ? -1 : -9464define i32 @test15g(i32 %X) {465; CHECK-LABEL: @test15g(466; CHECK-NEXT: [[T3:%.*]] = or i32 [[X:%.*]], -9467; CHECK-NEXT: ret i32 [[T3]]468;469 %t1 = and i32 %X, 8470 %t2 = icmp ne i32 %t1, 0471 %t3 = select i1 %t2, i32 -1, i32 -9472 ret i32 %t3473}474 475;; (a & 8) ? -9 : -1476define i32 @test15h(i32 %X) {477; CHECK-LABEL: @test15h(478; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 8479; CHECK-NEXT: [[T3:%.*]] = xor i32 [[T1]], -1480; CHECK-NEXT: ret i32 [[T3]]481;482 %t1 = and i32 %X, 8483 %t2 = icmp ne i32 %t1, 0484 %t3 = select i1 %t2, i32 -9, i32 -1485 ret i32 %t3486}487 488;; (a & 2) ? 577 : 1089489define i32 @test15i(i32 %X) {490; CHECK-LABEL: @test15i(491; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 2492; CHECK-NEXT: [[T2_NOT:%.*]] = icmp eq i32 [[T1]], 0493; CHECK-NEXT: [[T3:%.*]] = select i1 [[T2_NOT]], i32 1089, i32 577494; CHECK-NEXT: ret i32 [[T3]]495;496 %t1 = and i32 %X, 2497 %t2 = icmp ne i32 %t1, 0498 %t3 = select i1 %t2, i32 577, i32 1089499 ret i32 %t3500}501 502;; (a & 2) ? 1089 : 577503define i32 @test15j(i32 %X) {504; CHECK-LABEL: @test15j(505; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 2506; CHECK-NEXT: [[T2_NOT:%.*]] = icmp eq i32 [[T1]], 0507; CHECK-NEXT: [[T3:%.*]] = select i1 [[T2_NOT]], i32 577, i32 1089508; CHECK-NEXT: ret i32 [[T3]]509;510 %t1 = and i32 %X, 2511 %t2 = icmp ne i32 %t1, 0512 %t3 = select i1 %t2, i32 1089, i32 577513 ret i32 %t3514}515 516declare void @use1(i1)517 518; (X & 8) == 0 ? -3 : -11 --> (X & 8) ^ -3519; Extra cmp use ensures that cmp predicate canonicalization is thwarted.520 521define i32 @clear_to_set(i32 %x) {522; CHECK-LABEL: @clear_to_set(523; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 8524; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0525; CHECK-NEXT: [[T3:%.*]] = xor i32 [[T1]], -3526; CHECK-NEXT: call void @use1(i1 [[T2]])527; CHECK-NEXT: ret i32 [[T3]]528;529 %t1 = and i32 %x, 8530 %t2 = icmp eq i32 %t1, 0531 %t3 = select i1 %t2, i32 -3, i32 -11532 call void @use1(i1 %t2)533 ret i32 %t3534}535 536; (X & 8) == 0 ? -11 : -3 --> (X & 8) | -11537; Extra cmp use ensures that cmp predicate canonicalization is thwarted.538 539define i32 @clear_to_clear(i32 %x) {540; CHECK-LABEL: @clear_to_clear(541; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 8542; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0543; CHECK-NEXT: [[T3:%.*]] = or disjoint i32 [[T1]], -11544; CHECK-NEXT: call void @use1(i1 [[T2]])545; CHECK-NEXT: ret i32 [[T3]]546;547 %t1 = and i32 %x, 8548 %t2 = icmp eq i32 %t1, 0549 %t3 = select i1 %t2, i32 -11, i32 -3550 call void @use1(i1 %t2)551 ret i32 %t3552}553 554; (X & 8) != 0 ? -3 : -11 --> (X & 8) | -11555; Extra cmp use ensures that cmp predicate canonicalization is thwarted.556 557define i32 @set_to_set(i32 %x) {558; CHECK-LABEL: @set_to_set(559; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 8560; CHECK-NEXT: [[T2:%.*]] = icmp ne i32 [[T1]], 0561; CHECK-NEXT: [[T3:%.*]] = or disjoint i32 [[T1]], -11562; CHECK-NEXT: call void @use1(i1 [[T2]])563; CHECK-NEXT: ret i32 [[T3]]564;565 %t1 = and i32 %x, 8566 %t2 = icmp ne i32 %t1, 0567 %t3 = select i1 %t2, i32 -3, i32 -11568 call void @use1(i1 %t2)569 ret i32 %t3570}571 572; (X & 8) != 0 ? -3 : -11 --> (X & 8) ^ -3573; Extra cmp use ensures that cmp predicate canonicalization is thwarted.574 575define i32 @set_to_clear(i32 %x) {576; CHECK-LABEL: @set_to_clear(577; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 8578; CHECK-NEXT: [[T2:%.*]] = icmp ne i32 [[T1]], 0579; CHECK-NEXT: [[T3:%.*]] = xor i32 [[T1]], -3580; CHECK-NEXT: call void @use1(i1 [[T2]])581; CHECK-NEXT: ret i32 [[T3]]582;583 %t1 = and i32 %x, 8584 %t2 = icmp ne i32 %t1, 0585 %t3 = select i1 %t2, i32 -11, i32 -3586 call void @use1(i1 %t2)587 ret i32 %t3588}589 590; (X & 128) == 0 ? 131 : 3 --> (X & 128) ^ 131591 592define i8 @clear_to_set_decomposebittest(i8 %x) {593; CHECK-LABEL: @clear_to_set_decomposebittest(594; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -128595; CHECK-NEXT: [[T3:%.*]] = xor i8 [[TMP1]], -125596; CHECK-NEXT: ret i8 [[T3]]597;598 %t2 = icmp sgt i8 %x, -1599 %t3 = select i1 %t2, i8 131, i8 3600 ret i8 %t3601}602 603; (X & 128) == 0 ? 3 : 131 --> (X & 128) | 3604 605define i8 @clear_to_clear_decomposebittest(i8 %x) {606; CHECK-LABEL: @clear_to_clear_decomposebittest(607; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -128608; CHECK-NEXT: [[T3:%.*]] = or disjoint i8 [[TMP1]], 3609; CHECK-NEXT: ret i8 [[T3]]610;611 %t2 = icmp sgt i8 %x, -1612 %t3 = select i1 %t2, i8 3, i8 131613 ret i8 %t3614}615 616; (X & 128) != 0 ? 131 : 3 --> (X & 128) | 3617 618define i8 @set_to_set_decomposebittest(i8 %x) {619; CHECK-LABEL: @set_to_set_decomposebittest(620; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -128621; CHECK-NEXT: [[T3:%.*]] = or disjoint i8 [[TMP1]], 3622; CHECK-NEXT: ret i8 [[T3]]623;624 %t2 = icmp slt i8 %x, 0625 %t3 = select i1 %t2, i8 131, i8 3626 ret i8 %t3627}628 629; (X & 128) != 0 ? 3 : 131 --> (X & 128) ^ 131630 631define i8 @set_to_clear_decomposebittest(i8 %x) {632; CHECK-LABEL: @set_to_clear_decomposebittest(633; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -128634; CHECK-NEXT: [[T3:%.*]] = xor i8 [[TMP1]], -125635; CHECK-NEXT: ret i8 [[T3]]636;637 %t2 = icmp slt i8 %x, 0638 %t3 = select i1 %t2, i8 3, i8 131639 ret i8 %t3640}641 642; (X & 128) == 0 ? 131 : 3 --> (X & 128) ^ 131643; Extra cmp use to verify that we are not creating extra instructions.644 645define i8 @clear_to_set_decomposebittest_extra_use(i8 %x) {646; CHECK-LABEL: @clear_to_set_decomposebittest_extra_use(647; CHECK-NEXT: [[T2:%.*]] = icmp sgt i8 [[X:%.*]], -1648; CHECK-NEXT: [[T3:%.*]] = select i1 [[T2]], i8 -125, i8 3649; CHECK-NEXT: call void @use1(i1 [[T2]])650; CHECK-NEXT: ret i8 [[T3]]651;652 %t2 = icmp sgt i8 %x, -1653 %t3 = select i1 %t2, i8 131, i8 3654 call void @use1(i1 %t2)655 ret i8 %t3656}657 658; (X & 128) == 0 ? 3 : 131 --> (X & 128) | 3659; Extra cmp use to verify that we are not creating extra instructions.660 661define i8 @clear_to_clear_decomposebittest_extra_use(i8 %x) {662; CHECK-LABEL: @clear_to_clear_decomposebittest_extra_use(663; CHECK-NEXT: [[T2:%.*]] = icmp sgt i8 [[X:%.*]], -1664; CHECK-NEXT: [[T3:%.*]] = select i1 [[T2]], i8 3, i8 -125665; CHECK-NEXT: call void @use1(i1 [[T2]])666; CHECK-NEXT: ret i8 [[T3]]667;668 %t2 = icmp sgt i8 %x, -1669 %t3 = select i1 %t2, i8 3, i8 131670 call void @use1(i1 %t2)671 ret i8 %t3672}673 674; (X & 128) != 0 ? 131 : 3 --> (X & 128) | 3675; Extra cmp use to verify that we are not creating extra instructions.676 677define i8 @set_to_set_decomposebittest_extra_use(i8 %x) {678; CHECK-LABEL: @set_to_set_decomposebittest_extra_use(679; CHECK-NEXT: [[T2:%.*]] = icmp slt i8 [[X:%.*]], 0680; CHECK-NEXT: [[T3:%.*]] = select i1 [[T2]], i8 -125, i8 3681; CHECK-NEXT: call void @use1(i1 [[T2]])682; CHECK-NEXT: ret i8 [[T3]]683;684 %t2 = icmp slt i8 %x, 0685 %t3 = select i1 %t2, i8 131, i8 3686 call void @use1(i1 %t2)687 ret i8 %t3688}689 690; (X & 128) != 0 ? 3 : 131 --> (X & 128) ^ 131691; Extra cmp use to verify that we are not creating extra instructions.692 693define i8 @set_to_clear_decomposebittest_extra_use(i8 %x) {694; CHECK-LABEL: @set_to_clear_decomposebittest_extra_use(695; CHECK-NEXT: [[T2:%.*]] = icmp slt i8 [[X:%.*]], 0696; CHECK-NEXT: [[T3:%.*]] = select i1 [[T2]], i8 3, i8 -125697; CHECK-NEXT: call void @use1(i1 [[T2]])698; CHECK-NEXT: ret i8 [[T3]]699;700 %t2 = icmp slt i8 %x, 0701 %t3 = select i1 %t2, i8 3, i8 131702 call void @use1(i1 %t2)703 ret i8 %t3704}705 706define i32 @select_bittest_to_add(i32 %x) {707; CHECK-LABEL: @select_bittest_to_add(708; CHECK-NEXT: entry:709; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1710; CHECK-NEXT: [[RET:%.*]] = add nuw nsw i32 [[AND]], 3711; CHECK-NEXT: ret i32 [[RET]]712;713entry:714 %and = and i32 %x, 1715 %cmp = icmp eq i32 %and, 0716 %ret = select i1 %cmp, i32 3, i32 4717 ret i32 %ret718}719 720define i32 @select_bittest_to_sub(i32 %x) {721; CHECK-LABEL: @select_bittest_to_sub(722; CHECK-NEXT: entry:723; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1724; CHECK-NEXT: [[RET:%.*]] = sub nuw nsw i32 4, [[AND]]725; CHECK-NEXT: ret i32 [[RET]]726;727entry:728 %and = and i32 %x, 1729 %cmp = icmp eq i32 %and, 0730 %ret = select i1 %cmp, i32 4, i32 3731 ret i32 %ret732}733 734define i32 @select_bittest_to_shl(i32 %x) {735; CHECK-LABEL: @select_bittest_to_shl(736; CHECK-NEXT: entry:737; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1738; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0739; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 2, i32 4740; CHECK-NEXT: ret i32 [[RET]]741;742entry:743 %and = and i32 %x, 1744 %cmp = icmp eq i32 %and, 0745 %ret = select i1 %cmp, i32 2, i32 4746 ret i32 %ret747}748 749define i32 @select_bittest_to_lshr(i32 %x) {750; CHECK-LABEL: @select_bittest_to_lshr(751; CHECK-NEXT: entry:752; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1753; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0754; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 4, i32 2755; CHECK-NEXT: ret i32 [[RET]]756;757entry:758 %and = and i32 %x, 1759 %cmp = icmp eq i32 %and, 0760 %ret = select i1 %cmp, i32 4, i32 2761 ret i32 %ret762}763 764define i32 @select_bittest_to_ashr(i32 %x) {765; CHECK-LABEL: @select_bittest_to_ashr(766; CHECK-NEXT: entry:767; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 2768; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0769; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 -4, i32 -1770; CHECK-NEXT: ret i32 [[RET]]771;772entry:773 %and = and i32 %x, 2774 %cmp = icmp eq i32 %and, 0775 %ret = select i1 %cmp, i32 -4, i32 -1776 ret i32 %ret777}778 779define i32 @select_bittest_to_shl_negative_test(i32 %x) {780; CHECK-LABEL: @select_bittest_to_shl_negative_test(781; CHECK-NEXT: [[MASK:%.*]] = and i32 [[X:%.*]], 1782; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[MASK]], 0783; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND]], i32 4, i32 6784; CHECK-NEXT: ret i32 [[RES]]785;786 %mask = and i32 %x, 1787 %cond = icmp eq i32 %mask, 0788 %y = select i1 %cond, i32 2, i32 4789 %res = add nuw nsw i32 %y, 2790 ret i32 %res791}792 793define i8 @select_bittest_to_xor(i8 %x) {794; CHECK-LABEL: @select_bittest_to_xor(795; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1796; CHECK-NEXT: call void @use1(i1 [[CMP]])797; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], 127798; CHECK-NEXT: [[MASKSEL1:%.*]] = select i1 [[CMP]], i8 -128, i8 0799; CHECK-NEXT: [[MASKSEL:%.*]] = or disjoint i8 [[AND]], [[MASKSEL1]]800; CHECK-NEXT: ret i8 [[MASKSEL]]801;802 %cmp = icmp sgt i8 %x, -1803 call void @use1(i1 %cmp)804 %and = and i8 %x, 127805 %or = or i8 %x, -128806 %masksel = select i1 %cmp, i8 %or, i8 %and807 ret i8 %masksel808}809 810define i8 @select_trunc_bittest_to_sub(i8 %x) {811; CHECK-LABEL: @select_trunc_bittest_to_sub(812; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 1813; CHECK-NEXT: [[RET:%.*]] = sub nuw nsw i8 4, [[TMP1]]814; CHECK-NEXT: ret i8 [[RET]]815;816 %trunc = trunc i8 %x to i1817 %ret = select i1 %trunc, i8 3, i8 4818 ret i8 %ret819}820 821define i8 @select_trunc_nuw_bittest_to_sub(i8 %x) {822; CHECK-LABEL: @select_trunc_nuw_bittest_to_sub(823; CHECK-NEXT: [[RET:%.*]] = sub i8 4, [[X:%.*]]824; CHECK-NEXT: ret i8 [[RET]]825;826 %trunc = trunc nuw i8 %x to i1827 %ret = select i1 %trunc, i8 3, i8 4828 ret i8 %ret829}830 831define i8 @select_trunc_nsw_bittest_to_sub(i8 %x) {832; CHECK-LABEL: @select_trunc_nsw_bittest_to_sub(833; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 1834; CHECK-NEXT: [[RET:%.*]] = sub nuw nsw i8 4, [[TMP1]]835; CHECK-NEXT: ret i8 [[RET]]836;837 %trunc = trunc nsw i8 %x to i1838 %ret = select i1 %trunc, i8 3, i8 4839 ret i8 %ret840}841 842define i8 @select_trunc_nuw_bittest_to_sub_extra_use(i8 %x) {843; CHECK-LABEL: @select_trunc_nuw_bittest_to_sub_extra_use(844; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i8 [[X:%.*]] to i1845; CHECK-NEXT: call void @use1(i1 [[TRUNC]])846; CHECK-NEXT: [[RET:%.*]] = sub i8 4, [[X]]847; CHECK-NEXT: ret i8 [[RET]]848;849 %trunc = trunc nuw i8 %x to i1850 call void @use1(i1 %trunc)851 %ret = select i1 %trunc, i8 3, i8 4852 ret i8 %ret853}854 855define i8 @neg_select_trunc_bittest_to_sub_extra_use(i8 %x) {856; CHECK-LABEL: @neg_select_trunc_bittest_to_sub_extra_use(857; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[X:%.*]] to i1858; CHECK-NEXT: call void @use1(i1 [[TRUNC]])859; CHECK-NEXT: [[RET:%.*]] = select i1 [[TRUNC]], i8 3, i8 4860; CHECK-NEXT: ret i8 [[RET]]861;862 %trunc = trunc i8 %x to i1863 call void @use1(i1 %trunc)864 %ret = select i1 %trunc, i8 3, i8 4865 ret i8 %ret866}867 868define i8 @select_trunc_nuw_bittest_to_shl_not(i8 %x) {869; CHECK-LABEL: @select_trunc_nuw_bittest_to_shl_not(870; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 2871; CHECK-NEXT: [[RET:%.*]] = xor i8 [[TMP1]], 4872; CHECK-NEXT: ret i8 [[RET]]873;874 %trunc = trunc nuw i8 %x to i1875 %ret = select i1 %trunc, i8 0, i8 4876 ret i8 %ret877}878 879define i8 @select_trunc_bittest_to_shl(i8 %x) {880; CHECK-LABEL: @select_trunc_bittest_to_shl(881; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 2882; CHECK-NEXT: [[RET:%.*]] = and i8 [[TMP1]], 4883; CHECK-NEXT: ret i8 [[RET]]884;885 %trunc = trunc i8 %x to i1886 %ret = select i1 %trunc, i8 4, i8 0887 ret i8 %ret888}889 890define i8 @neg_select_trunc_bittest_to_shl_extra_use(i8 %x) {891; CHECK-LABEL: @neg_select_trunc_bittest_to_shl_extra_use(892; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[X:%.*]] to i1893; CHECK-NEXT: call void @use1(i1 [[TRUNC]])894; CHECK-NEXT: [[RET:%.*]] = select i1 [[TRUNC]], i8 4, i8 0895; CHECK-NEXT: ret i8 [[RET]]896;897 %trunc = trunc i8 %x to i1898 call void @use1(i1 %trunc)899 %ret = select i1 %trunc, i8 4, i8 0900 ret i8 %ret901}902 903define i16 @select_trunc_nuw_bittest_or(i8 %x) {904; CHECK-LABEL: @select_trunc_nuw_bittest_or(905; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[X:%.*]] to i16906; CHECK-NEXT: [[SELECT:%.*]] = shl nuw nsw i16 [[TMP1]], 4907; CHECK-NEXT: [[RES:%.*]] = or disjoint i16 [[SELECT]], 4908; CHECK-NEXT: ret i16 [[RES]]909;910 %trunc = trunc nuw i8 %x to i1911 %select = select i1 %trunc, i16 16, i16 0912 %res = or i16 4, %select913 ret i16 %res914}915 916define i16 @select_icmp_bittest_range(i16 range (i16 0, 512) %a) {917; CHECK-LABEL: @select_icmp_bittest_range(918; CHECK-NEXT: [[RES:%.*]] = and i16 [[A:%.*]], 256919; CHECK-NEXT: ret i16 [[RES]]920;921 %cmp = icmp ult i16 %a, 256922 %res = select i1 %cmp, i16 0, i16 256923 ret i16 %res924}925 926define i16 @select_icmp_bittest_range_negative_test(i16 range (i16 0, 513) %a) {927; CHECK-LABEL: @select_icmp_bittest_range_negative_test(928; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ult i16 [[A:%.*]], 256929; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i16 0, i16 256930; CHECK-NEXT: ret i16 [[RES]]931;932 %cmp = icmp ult i16 %a, 256933 %res = select i1 %cmp, i16 0, i16 256934 ret i16 %res935}936 937define i16 @select_icmp_bittest_range_negative_test2(i16 range (i16 0, 512) %a) {938; CHECK-LABEL: @select_icmp_bittest_range_negative_test2(939; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ult i16 [[A:%.*]], 255940; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i16 0, i16 255941; CHECK-NEXT: ret i16 [[RES]]942;943 %cmp = icmp ult i16 %a, 255944 %res = select i1 %cmp, i16 0, i16 255945 ret i16 %res946}947