1434 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare void @use(<2 x i1>)5declare void @use2(i1)6declare void @use.i32(i32)7 8define i32 @select_xor_icmp(i32 %x, i32 %y, i32 %z) {9; CHECK-LABEL: @select_xor_icmp(10; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 011; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]12; CHECK-NEXT: ret i32 [[C]]13;14 %A = icmp eq i32 %x, 015 %B = xor i32 %x, %z16 %C = select i1 %A, i32 %B, i32 %y17 ret i32 %C18}19 20define i32 @select_xor_icmp2(i32 %x, i32 %y, i32 %z) {21; CHECK-LABEL: @select_xor_icmp2(22; CHECK-NEXT: [[A_NOT:%.*]] = icmp eq i32 [[X:%.*]], 023; CHECK-NEXT: [[C:%.*]] = select i1 [[A_NOT]], i32 [[Z:%.*]], i32 [[Y:%.*]]24; CHECK-NEXT: ret i32 [[C]]25;26 %A = icmp ne i32 %x, 027 %B = xor i32 %x, %z28 %C = select i1 %A, i32 %y, i32 %B29 ret i32 %C30}31 32define i32 @select_xor_icmp_meta(i32 %x, i32 %y, i32 %z) {33; CHECK-LABEL: @select_xor_icmp_meta(34; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 035; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]], !prof [[PROF0:![0-9]+]]36; CHECK-NEXT: ret i32 [[C]]37;38 %A = icmp eq i32 %x, 039 %B = xor i32 %x, %z40 %C = select i1 %A, i32 %B, i32 %y, !prof !041 ret i32 %C42}43 44define i32 @select_mul_icmp(i32 %x, i32 %y, i32 %z) {45; CHECK-LABEL: @select_mul_icmp(46; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 147; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]48; CHECK-NEXT: ret i32 [[C]]49;50 %A = icmp eq i32 %x, 151 %B = mul i32 %x, %z52 %C = select i1 %A, i32 %B, i32 %y53 ret i32 %C54}55 56define i32 @select_add_icmp(i32 %x, i32 %y, i32 %z) {57; CHECK-LABEL: @select_add_icmp(58; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 059; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]60; CHECK-NEXT: ret i32 [[C]]61;62 %A = icmp eq i32 %x, 063 %B = add i32 %x, %z64 %C = select i1 %A, i32 %B, i32 %y65 ret i32 %C66}67 68define i32 @select_or_icmp(i32 %x, i32 %y, i32 %z) {69; CHECK-LABEL: @select_or_icmp(70; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 071; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]72; CHECK-NEXT: ret i32 [[C]]73;74 %A = icmp eq i32 %x, 075 %B = or i32 %x, %z76 %C = select i1 %A, i32 %B, i32 %y77 ret i32 %C78}79 80define i32 @select_and_icmp(i32 %x, i32 %y, i32 %z) {81; CHECK-LABEL: @select_and_icmp(82; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], -183; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]84; CHECK-NEXT: ret i32 [[C]]85;86 %A = icmp eq i32 %x, -187 %B = and i32 %x, %z88 %C = select i1 %A, i32 %B, i32 %y89 ret i32 %C90}91 92define <2 x i8> @select_xor_icmp_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {93; CHECK-LABEL: @select_xor_icmp_vec(94; CHECK-NEXT: [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], zeroinitializer95; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[Z:%.*]], <2 x i8> [[Y:%.*]]96; CHECK-NEXT: ret <2 x i8> [[C]]97;98 %A = icmp eq <2 x i8> %x, <i8 0, i8 0>99 %B = xor <2 x i8> %x, %z100 %C = select <2 x i1> %A, <2 x i8> %B, <2 x i8> %y101 ret <2 x i8> %C102}103 104define <2 x i8> @select_xor_icmp_vec_use(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {105; CHECK-LABEL: @select_xor_icmp_vec_use(106; CHECK-NEXT: [[A:%.*]] = icmp ne <2 x i8> [[X:%.*]], zeroinitializer107; CHECK-NEXT: call void @use(<2 x i1> [[A]])108; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[Y:%.*]], <2 x i8> [[Z:%.*]]109; CHECK-NEXT: ret <2 x i8> [[C]]110;111 %A = icmp ne <2 x i8> %x, <i8 0, i8 0>112 call void @use(<2 x i1> %A)113 %B = xor <2 x i8> %x, %z114 %C = select <2 x i1> %A, <2 x i8> %y, <2 x i8> %B115 ret <2 x i8> %C116}117 118define i32 @select_xor_inv_icmp(i32 %x, i32 %y, i32 %z) {119; CHECK-LABEL: @select_xor_inv_icmp(120; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0121; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]122; CHECK-NEXT: ret i32 [[C]]123;124 %A = icmp eq i32 %x, 0125 %B = xor i32 %z, %x126 %C = select i1 %A, i32 %B, i32 %y127 ret i32 %C128}129 130define i32 @select_xor_inv_icmp2(i32 %x, i32 %y, i32 %z) {131; CHECK-LABEL: @select_xor_inv_icmp2(132; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0133; CHECK-NEXT: call void @use2(i1 [[A]])134; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]135; CHECK-NEXT: ret i32 [[C]]136;137 %A = icmp ne i32 %x, 0138 call void @use2(i1 %A) ; thwart predicate canonicalization139 %B = xor i32 %x, %z140 %C = select i1 %A, i32 %y, i32 %B141 ret i32 %C142}143 144define float @select_fadd_fcmp(float %x, float %y, float %z) {145; CHECK-LABEL: @select_fadd_fcmp(146; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00147; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]148; CHECK-NEXT: ret float [[C]]149;150 %A = fcmp oeq float %x, -0.0151 %B = fadd nsz float %x, %z152 %C = select i1 %A, float %B, float %y153 ret float %C154}155 156; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.157 158define float @select_fadd_fcmp_poszero(float %x, float %y, float %z) {159; CHECK-LABEL: @select_fadd_fcmp_poszero(160; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00161; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]162; CHECK-NEXT: ret float [[C]]163;164 %A = fcmp oeq float %x, 0.0165 %B = fadd nsz float %z, %x166 %C = select i1 %A, float %B, float %y167 ret float %C168}169 170define float @select_fadd_fcmp_2(float %x, float %y, float %v) {171; CHECK-LABEL: @select_fadd_fcmp_2(172; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00173; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00174; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]]175; CHECK-NEXT: ret float [[C]]176;177 %A = fcmp une float %x, -0.0178 %z = fadd float %v, 0.0 ; cannot produce -0.0179 %B = fadd float %z, %x180 %C = select i1 %A, float %y, float %B181 ret float %C182}183 184; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.185 186define float @select_fadd_fcmp_2_poszero(float %x, float %y, float %v) {187; CHECK-LABEL: @select_fadd_fcmp_2_poszero(188; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00189; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00190; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]]191; CHECK-NEXT: ret float [[C]]192;193 %A = fcmp une float %x, 0.0194 %z = fadd float %v, 0.0 ; cannot produce -0.0195 %B = fadd float %z, %x196 %C = select i1 %A, float %y, float %B197 ret float %C198}199 200define float @select_fadd_fcmp_3(float %x, float %y) {201; CHECK-LABEL: @select_fadd_fcmp_3(202; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00203; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float 6.000000e+00204; CHECK-NEXT: ret float [[C]]205;206 %A = fcmp une float %x, -0.0207 %B = fadd float 6.0, %x208 %C = select i1 %A, float %y, float %B209 ret float %C210}211 212; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.213 214define float @select_fadd_fcmp_3_poszero(float %x, float %y) {215; CHECK-LABEL: @select_fadd_fcmp_3_poszero(216; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00217; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float 6.000000e+00218; CHECK-NEXT: ret float [[C]]219;220 %A = fcmp une float %x, 0.0221 %B = fadd float 6.0, %x222 %C = select i1 %A, float %y, float %B223 ret float %C224}225 226define float @select_fadd_fcmp_4(float %x, float %y, float %z) {227; CHECK-LABEL: @select_fadd_fcmp_4(228; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00229; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z:%.*]]230; CHECK-NEXT: ret float [[C]]231;232 %A = fcmp une float %x, -0.0233 %B = fadd nsz float %z, %x234 %C = select i1 %A, float %y, float %B235 ret float %C236}237 238; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.239 240define float @select_fadd_fcmp_4_poszero(float %x, float %y, float %z) {241; CHECK-LABEL: @select_fadd_fcmp_4_poszero(242; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00243; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z:%.*]]244; CHECK-NEXT: ret float [[C]]245;246 %A = fcmp une float %x, 0.0247 %B = fadd nsz float %z, %x248 %C = select i1 %A, float %y, float %B249 ret float %C250}251 252define float @select_fadd_fcmp_5(float %x, float %y, float %v) {253; CHECK-LABEL: @select_fadd_fcmp_5(254; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00255; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00256; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z]], float [[Y:%.*]]257; CHECK-NEXT: ret float [[C]]258;259 %A = fcmp oeq float %x, -0.0260 %z = fadd float %v, 0.0 ; cannot produce -0.0261 %B = fadd float %z, %x262 %C = select i1 %A, float %B, float %y263 ret float %C264}265 266; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.267 268define float @select_fadd_fcmp_5_poszero(float %x, float %y, float %v) {269; CHECK-LABEL: @select_fadd_fcmp_5_poszero(270; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00271; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00272; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z]], float [[Y:%.*]]273; CHECK-NEXT: ret float [[C]]274;275 %A = fcmp oeq float %x, 0.0276 %z = fadd float %v, 0.0 ; cannot produce -0.0277 %B = fadd float %z, %x278 %C = select i1 %A, float %B, float %y279 ret float %C280}281 282define float @select_fadd_fcmp_6(float %x, float %y, float %z) {283; CHECK-LABEL: @select_fadd_fcmp_6(284; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00285; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float 6.000000e+00, float [[Y:%.*]]286; CHECK-NEXT: ret float [[C]]287;288 %A = fcmp oeq float %x, -0.0289 %B = fadd float %x, 6.0290 %C = select i1 %A, float %B, float %y291 ret float %C292}293 294; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.295 296define float @select_fadd_fcmp_6_poszero(float %x, float %y, float %z) {297; CHECK-LABEL: @select_fadd_fcmp_6_poszero(298; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00299; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float 6.000000e+00, float [[Y:%.*]]300; CHECK-NEXT: ret float [[C]]301;302 %A = fcmp oeq float %x, 0.0303 %B = fadd float %x, 6.0304 %C = select i1 %A, float %B, float %y305 ret float %C306}307 308define float @select_fmul_fcmp(float %x, float %y, float %z) {309; CHECK-LABEL: @select_fmul_fcmp(310; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00311; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]312; CHECK-NEXT: ret float [[C]]313;314 %A = fcmp oeq float %x, 1.0315 %B = fmul nsz float %x, %z316 %C = select i1 %A, float %B, float %y317 ret float %C318}319 320define float @select_fsub_fcmp(float %x, float %y, float %z) {321; CHECK-LABEL: @select_fsub_fcmp(322; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00323; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]324; CHECK-NEXT: ret float [[C]]325;326 %A = fcmp oeq float %x, 0.0327 %B = fsub nsz float %z, %x328 %C = select i1 %A, float %B, float %y329 ret float %C330}331 332; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.333 334define float @select_fsub_fcmp_negzero(float %x, float %y, float %z) {335; CHECK-LABEL: @select_fsub_fcmp_negzero(336; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00337; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]338; CHECK-NEXT: ret float [[C]]339;340 %A = fcmp oeq float %x, -0.0341 %B = fsub nsz float %z, %x342 %C = select i1 %A, float %B, float %y343 ret float %C344}345 346define float @select_fdiv_fcmp(float %x, float %y, float %z) {347; CHECK-LABEL: @select_fdiv_fcmp(348; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00349; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]350; CHECK-NEXT: ret float [[C]]351;352 %A = fcmp oeq float %x, 1.0353 %B = fdiv nsz float %z, %x354 %C = select i1 %A, float %B, float %y355 ret float %C356}357 358define i32 @select_sub_icmp(i32 %x, i32 %y, i32 %z) {359; CHECK-LABEL: @select_sub_icmp(360; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0361; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]362; CHECK-NEXT: ret i32 [[C]]363;364 %A = icmp eq i32 %x, 0365 %B = sub i32 %z, %x366 %C = select i1 %A, i32 %B, i32 %y367 ret i32 %C368}369 370define i32 @select_sub_icmp_2(i32 %x, i32 %y, i32 %z) {371; CHECK-LABEL: @select_sub_icmp_2(372; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0373; CHECK-NEXT: call void @use2(i1 [[A]])374; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]375; CHECK-NEXT: ret i32 [[C]]376;377 %A = icmp eq i32 %x, 0378 call void @use2(i1 %A)379 %B = sub i32 %z, %x380 %C = select i1 %A, i32 %B, i32 %y381 ret i32 %C382}383 384define i32 @select_sub_icmp_3(i32 %x, i32 %y, i32 %z) {385; CHECK-LABEL: @select_sub_icmp_3(386; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0387; CHECK-NEXT: call void @use2(i1 [[A]])388; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]389; CHECK-NEXT: ret i32 [[C]]390;391 %A = icmp ne i32 %x, 0392 call void @use2(i1 %A)393 %B = sub i32 %z, %x394 %C = select i1 %A, i32 %y, i32 %B395 ret i32 %C396}397 398define <2 x i8> @select_sub_icmp_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {399; CHECK-LABEL: @select_sub_icmp_vec(400; CHECK-NEXT: [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], zeroinitializer401; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[Z:%.*]], <2 x i8> [[Y:%.*]]402; CHECK-NEXT: ret <2 x i8> [[C]]403;404 %A = icmp eq <2 x i8> %x, <i8 0, i8 0>405 %B = sub <2 x i8> %z, %x406 %C = select <2 x i1> %A, <2 x i8> %B, <2 x i8> %y407 ret <2 x i8> %C408}409 410define i32 @select_shl_icmp(i32 %x, i32 %y, i32 %z) {411; CHECK-LABEL: @select_shl_icmp(412; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0413; CHECK-NEXT: call void @use2(i1 [[A]])414; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]415; CHECK-NEXT: ret i32 [[C]]416;417 %A = icmp ne i32 %x, 0418 call void @use2(i1 %A) ; thwart predicate canonicalization419 %B = shl i32 %z, %x420 %C = select i1 %A, i32 %y, i32 %B421 ret i32 %C422}423 424define i32 @select_lshr_icmp(i32 %x, i32 %y, i32 %z) {425; CHECK-LABEL: @select_lshr_icmp(426; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0427; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]428; CHECK-NEXT: ret i32 [[C]]429;430 %A = icmp eq i32 %x, 0431 %B = lshr i32 %z, %x432 %C = select i1 %A, i32 %B, i32 %y433 ret i32 %C434}435 436define i32 @select_ashr_icmp(i32 %x, i32 %y, i32 %z) {437; CHECK-LABEL: @select_ashr_icmp(438; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0439; CHECK-NEXT: call void @use2(i1 [[A]])440; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]441; CHECK-NEXT: ret i32 [[C]]442;443 %A = icmp ne i32 %x, 0444 call void @use2(i1 %A) ; thwart predicate canonicalization445 %B = ashr i32 %z, %x446 %C = select i1 %A, i32 %y, i32 %B447 ret i32 %C448}449 450define i32 @select_udiv_icmp(i32 %x, i32 %y, i32 %z) {451; CHECK-LABEL: @select_udiv_icmp(452; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1453; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]454; CHECK-NEXT: ret i32 [[C]]455;456 %A = icmp eq i32 %x, 1457 %B = udiv i32 %z, %x458 %C = select i1 %A, i32 %B, i32 %y459 ret i32 %C460}461 462define i32 @select_sdiv_icmp(i32 %x, i32 %y, i32 %z) {463; CHECK-LABEL: @select_sdiv_icmp(464; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 1465; CHECK-NEXT: call void @use2(i1 [[A]])466; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]467; CHECK-NEXT: ret i32 [[C]]468;469 %A = icmp ne i32 %x, 1470 call void @use2(i1 %A) ; thwart predicate canonicalization471 %B = sdiv i32 %z, %x472 %C = select i1 %A, i32 %y, i32 %B473 ret i32 %C474}475 476; Negative tests477define i32 @select_xor_icmp_bad_1(i32 %x, i32 %y, i32 %z, i32 %k) {478; CHECK-LABEL: @select_xor_icmp_bad_1(479; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], [[K:%.*]]480; CHECK-NEXT: [[B:%.*]] = xor i32 [[X]], [[Z:%.*]]481; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]482; CHECK-NEXT: ret i32 [[C]]483;484 %A = icmp eq i32 %x, %k485 %B = xor i32 %x, %z486 %C = select i1 %A, i32 %B, i32 %y487 ret i32 %C488}489 490define i32 @select_xor_icmp_bad_2(i32 %x, i32 %y, i32 %z, i32 %k) {491; CHECK-LABEL: @select_xor_icmp_bad_2(492; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0493; CHECK-NEXT: [[B:%.*]] = xor i32 [[K:%.*]], [[Z:%.*]]494; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]495; CHECK-NEXT: ret i32 [[C]]496;497 %A = icmp eq i32 %x, 0498 %B = xor i32 %k, %z499 %C = select i1 %A, i32 %B, i32 %y500 ret i32 %C501}502 503define i32 @select_xor_icmp_bad_3(i32 %x, i32 %y, i32 %z) {504; CHECK-LABEL: @select_xor_icmp_bad_3(505; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 3506; CHECK-NEXT: [[B:%.*]] = xor i32 [[Z:%.*]], 3507; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]508; CHECK-NEXT: ret i32 [[C]]509;510 %A = icmp eq i32 %x, 3511 %B = xor i32 %x, %z512 %C = select i1 %A, i32 %B, i32 %y513 ret i32 %C514}515 516define i32 @select_xor_fcmp_bad_4(i32 %x, i32 %y, i32 %z, float %k) {517; CHECK-LABEL: @select_xor_fcmp_bad_4(518; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[K:%.*]], 0.000000e+00519; CHECK-NEXT: [[B:%.*]] = xor i32 [[X:%.*]], [[Z:%.*]]520; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]521; CHECK-NEXT: ret i32 [[C]]522;523 %A = fcmp oeq float %k, 0.0524 %B = xor i32 %x, %z525 %C = select i1 %A, i32 %B, i32 %y526 ret i32 %C527}528 529define i32 @select_xor_icmp_bad_5(i32 %x, i32 %y, i32 %z) {530; CHECK-LABEL: @select_xor_icmp_bad_5(531; CHECK-NEXT: [[A_NOT:%.*]] = icmp eq i32 [[X:%.*]], 0532; CHECK-NEXT: [[B:%.*]] = xor i32 [[X]], [[Z:%.*]]533; CHECK-NEXT: [[C:%.*]] = select i1 [[A_NOT]], i32 [[Y:%.*]], i32 [[B]]534; CHECK-NEXT: ret i32 [[C]]535;536 %A = icmp ne i32 %x, 0537 %B = xor i32 %x, %z538 %C = select i1 %A, i32 %B, i32 %y539 ret i32 %C540}541 542define i32 @select_xor_icmp_bad_6(i32 %x, i32 %y, i32 %z) {543; CHECK-LABEL: @select_xor_icmp_bad_6(544; CHECK-NEXT: [[A_NOT:%.*]] = icmp eq i32 [[X:%.*]], 1545; CHECK-NEXT: [[B:%.*]] = xor i32 [[Z:%.*]], 1546; CHECK-NEXT: [[C:%.*]] = select i1 [[A_NOT]], i32 [[B]], i32 [[Y:%.*]]547; CHECK-NEXT: ret i32 [[C]]548;549 %A = icmp ne i32 %x, 1550 %B = xor i32 %x, %z551 %C = select i1 %A, i32 %y, i32 %B552 ret i32 %C553}554 555; Value equivalence substitution is valid.556 557define <2 x i8> @select_xor_icmp_vec_equivalence(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {558; CHECK-LABEL: @select_xor_icmp_vec_equivalence(559; CHECK-NEXT: [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 5, i8 3>560; CHECK-NEXT: [[B:%.*]] = xor <2 x i8> [[Z:%.*]], <i8 5, i8 3>561; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[B]], <2 x i8> [[Y:%.*]]562; CHECK-NEXT: ret <2 x i8> [[C]]563;564 %A = icmp eq <2 x i8> %x, <i8 5, i8 3>565 %B = xor <2 x i8> %x, %z566 %C = select <2 x i1> %A, <2 x i8> %B, <2 x i8> %y567 ret <2 x i8> %C568}569 570; Value equivalence substitution is invalid due to lane-crossing shufflevector.571 572define <2 x i32> @vec_select_no_equivalence(<2 x i32> %x) {573; CHECK-LABEL: @vec_select_no_equivalence(574; CHECK-NEXT: [[X10:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> <i32 1, i32 0>575; CHECK-NEXT: [[COND:%.*]] = icmp eq <2 x i32> [[X]], zeroinitializer576; CHECK-NEXT: [[S:%.*]] = select <2 x i1> [[COND]], <2 x i32> [[X10]], <2 x i32> [[X]]577; CHECK-NEXT: ret <2 x i32> [[S]]578;579 %x10 = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> <i32 1, i32 0>580 %cond = icmp eq <2 x i32> %x, zeroinitializer581 %s = select <2 x i1> %cond, <2 x i32> %x10, <2 x i32> %x582 ret <2 x i32> %s583}584 585; Folding this would only be legal if we sanitized undef to 0.586define <2 x i8> @select_xor_icmp_vec_undef(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {587; CHECK-LABEL: @select_xor_icmp_vec_undef(588; CHECK-NEXT: [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 0, i8 undef>589; CHECK-NEXT: [[B:%.*]] = xor <2 x i8> [[X]], [[Z:%.*]]590; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[B]], <2 x i8> [[Y:%.*]]591; CHECK-NEXT: ret <2 x i8> [[C]]592;593 %A = icmp eq <2 x i8> %x, <i8 0, i8 undef>594 %B = xor <2 x i8> %x, %z595 %C = select <2 x i1> %A, <2 x i8> %B, <2 x i8> %y596 ret <2 x i8> %C597}598 599define i32 @select_mul_icmp_bad(i32 %x, i32 %y, i32 %z, i32 %k) {600; CHECK-LABEL: @select_mul_icmp_bad(601; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 3602; CHECK-NEXT: [[B:%.*]] = mul i32 [[Z:%.*]], 3603; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]604; CHECK-NEXT: ret i32 [[C]]605;606 %A = icmp eq i32 %x, 3607 %B = mul i32 %x, %z608 %C = select i1 %A, i32 %B, i32 %y609 ret i32 %C610}611 612define i32 @select_add_icmp_bad(i32 %x, i32 %y, i32 %z) {613; CHECK-LABEL: @select_add_icmp_bad(614; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1615; CHECK-NEXT: [[B:%.*]] = add i32 [[Z:%.*]], 1616; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]617; CHECK-NEXT: ret i32 [[C]]618;619 %A = icmp eq i32 %x, 1620 %B = add i32 %x, %z621 %C = select i1 %A, i32 %B, i32 %y622 ret i32 %C623}624 625define i32 @select_and_icmp_zero(i32 %x, i32 %y, i32 %z) {626; CHECK-LABEL: @select_and_icmp_zero(627; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0628; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 0, i32 [[Y:%.*]]629; CHECK-NEXT: ret i32 [[C]]630;631 %A = icmp eq i32 %x, 0632 %B = and i32 %x, %z633 %C = select i1 %A, i32 %B, i32 %y634 ret i32 %C635}636 637define i32 @select_or_icmp_bad(i32 %x, i32 %y, i32 %z) {638; CHECK-LABEL: @select_or_icmp_bad(639; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 3640; CHECK-NEXT: [[B:%.*]] = or i32 [[Z:%.*]], 3641; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]642; CHECK-NEXT: ret i32 [[C]]643;644 %A = icmp eq i32 %x, 3645 %B = or i32 %x, %z646 %C = select i1 %A, i32 %B, i32 %y647 ret i32 %C648}649 650define i32 @select_lshr_icmp_const(i32 %x) {651; CHECK-LABEL: @select_lshr_icmp_const(652; CHECK-NEXT: [[B:%.*]] = lshr i32 [[X:%.*]], 5653; CHECK-NEXT: ret i32 [[B]]654;655 %A = icmp ugt i32 %x, 31656 %B = lshr i32 %x, 5657 %C = select i1 %A, i32 %B, i32 0658 ret i32 %C659}660 661define i32 @select_lshr_icmp_const_reordered(i32 %x) {662; CHECK-LABEL: @select_lshr_icmp_const_reordered(663; CHECK-NEXT: [[B:%.*]] = lshr i32 [[X:%.*]], 5664; CHECK-NEXT: ret i32 [[B]]665;666 %A = icmp ult i32 %x, 32667 %B = lshr i32 %x, 5668 %C = select i1 %A, i32 0, i32 %B669 ret i32 %C670}671 672define i32 @select_exact_lshr_icmp_const(i32 %x) {673; CHECK-LABEL: @select_exact_lshr_icmp_const(674; CHECK-NEXT: [[B:%.*]] = lshr i32 [[X:%.*]], 5675; CHECK-NEXT: ret i32 [[B]]676;677 %A = icmp ugt i32 %x, 31678 %B = lshr exact i32 %x, 5679 %C = select i1 %A, i32 %B, i32 0680 ret i32 %C681}682 683define i32 @select_lshr_icmp_const_large_exact_range(i32 %x) {684; CHECK-LABEL: @select_lshr_icmp_const_large_exact_range(685; CHECK-NEXT: [[A:%.*]] = icmp ugt i32 [[X:%.*]], 63686; CHECK-NEXT: [[B:%.*]] = lshr i32 [[X]], 5687; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 0688; CHECK-NEXT: ret i32 [[C]]689;690 %A = icmp ugt i32 %x, 63691 %B = lshr i32 %x, 5692 %C = select i1 %A, i32 %B, i32 0693 ret i32 %C694}695 696define i32 @select_lshr_icmp_const_different_values(i32 %x, i32 %y) {697; CHECK-LABEL: @select_lshr_icmp_const_different_values(698; CHECK-NEXT: [[A:%.*]] = icmp ugt i32 [[X:%.*]], 31699; CHECK-NEXT: [[B:%.*]] = lshr i32 [[Y:%.*]], 5700; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 0701; CHECK-NEXT: ret i32 [[C]]702;703 %A = icmp ugt i32 %x, 31704 %B = lshr i32 %y, 5705 %C = select i1 %A, i32 %B, i32 0706 ret i32 %C707}708 709define float @select_fadd_fcmp_equiv(float %x, float %y, float %z) {710; CHECK-LABEL: @select_fadd_fcmp_equiv(711; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], -1.000000e+00712; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], -1.000000e+00713; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]714; CHECK-NEXT: ret float [[C]]715;716 %A = fcmp oeq float %x, -1.0717 %B = fadd nsz float %x, %z718 %C = select i1 %A, float %B, float %y719 ret float %C720}721 722define float @select_fadd_fcmp_equiv2(float %x, float %y, float %z) {723; CHECK-LABEL: @select_fadd_fcmp_equiv2(724; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], -1.000000e+00725; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], -1.000000e+00726; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]727; CHECK-NEXT: ret float [[C]]728;729 %A = fcmp une float %x, -1.0730 %B = fadd nsz float %x, %z731 %C = select i1 %A, float %y, float %B732 ret float %C733}734 735; Invalid comparison type736define float @select_fadd_fcmp_bad_2(float %x, float %y, float %z) {737; CHECK-LABEL: @select_fadd_fcmp_bad_2(738; CHECK-NEXT: [[A:%.*]] = fcmp ueq float [[X:%.*]], -1.000000e+00739; CHECK-NEXT: [[B:%.*]] = fadd float [[X]], [[Z:%.*]]740; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]741; CHECK-NEXT: ret float [[C]]742;743 %A = fcmp ueq float %x, -1.0744 %B = fadd float %x, %z745 %C = select i1 %A, float %B, float %y746 ret float %C747}748 749; Invalid comparison type750define float @select_fadd_fcmp_bad_3(float %x, float %y, float %z, float %k) {751; CHECK-LABEL: @select_fadd_fcmp_bad_3(752; CHECK-NEXT: [[A:%.*]] = fcmp one float [[X:%.*]], [[K:%.*]]753; CHECK-NEXT: [[B:%.*]] = fadd float [[X]], [[Z:%.*]]754; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]755; CHECK-NEXT: ret float [[C]]756;757 %A = fcmp one float %x, %k758 %B = fadd float %x, %z759 %C = select i1 %A, float %y, float %B760 ret float %C761}762 763; Invalid order of operands of select764define float @select_fadd_fcmp_bad_4(float %x, float %y, float %z) {765; CHECK-LABEL: @select_fadd_fcmp_bad_4(766; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00767; CHECK-NEXT: [[B:%.*]] = fadd float [[X]], [[Z:%.*]]768; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]769; CHECK-NEXT: ret float [[C]]770;771 %A = fcmp une float %x, -0.0772 %B = fadd float %x, %z773 %C = select i1 %A, float %B, float %y774 ret float %C775}776 777; Invalid comparison type778define float @select_fadd_fcmp_bad_5(float %x, float %y, float %z) {779; CHECK-LABEL: @select_fadd_fcmp_bad_5(780; CHECK-NEXT: [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00781; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]]782; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]783; CHECK-NEXT: ret float [[C]]784;785 %A = fcmp one float %x, -0.0786 %B = fadd nsz float %z, %x787 %C = select i1 %A, float %y, float %B788 ret float %C789}790 791; Invalid order of operands of select792define float @select_fadd_fcmp_bad_6(float %x, float %y, float %z) {793; CHECK-LABEL: @select_fadd_fcmp_bad_6(794; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00795; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]]796; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]797; CHECK-NEXT: ret float [[C]]798;799 %A = fcmp oeq float %x, -0.0800 %B = fadd nsz float %z, %x801 %C = select i1 %A, float %y, float %B802 ret float %C803}804 805; Do not transform if we have signed zeros and if Z is possibly negative zero806define float @select_fadd_fcmp_bad_7(float %x, float %y, float %z) {807; CHECK-LABEL: @select_fadd_fcmp_bad_7(808; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00809; CHECK-NEXT: [[B:%.*]] = fadd float [[X]], [[Z:%.*]]810; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]811; CHECK-NEXT: ret float [[C]]812;813 %A = fcmp oeq float %x, -0.0814 %B = fadd float %x, %z815 %C = select i1 %A, float %B, float %y816 ret float %C817}818 819; Invalid comparison type820define float @select_fadd_fcmp_bad_8(float %x, float %y, float %v) {821; CHECK-LABEL: @select_fadd_fcmp_bad_8(822; CHECK-NEXT: [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00823; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], -1.000000e+00824; CHECK-NEXT: [[B:%.*]] = fadd float [[Z]], [[X]]825; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]826; CHECK-NEXT: ret float [[C]]827;828 %A = fcmp one float %x, -0.0829 %z = fadd float %v, -1.0830 %B = fadd float %z, %x831 %C = select i1 %A, float %y, float %B832 ret float %C833}834 835; Invalid comparison type836define float @select_fadd_fcmp_bad_9(float %x, float %y, float %z) {837; CHECK-LABEL: @select_fadd_fcmp_bad_9(838; CHECK-NEXT: [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00839; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]]840; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]841; CHECK-NEXT: ret float [[C]]842;843 %A = fcmp one float %x, -0.0844 %B = fadd nsz float %z, %x845 %C = select i1 %A, float %y, float %B846 ret float %C847}848 849; Invalid comparison type850define float @select_fadd_fcmp_bad_10(float %x, float %y, float %v) {851; CHECK-LABEL: @select_fadd_fcmp_bad_10(852; CHECK-NEXT: [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00853; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00854; CHECK-NEXT: [[B:%.*]] = fadd float [[Z]], [[X]]855; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]856; CHECK-NEXT: ret float [[C]]857;858 %A = fcmp one float %x, -0.0859 %z = fadd float %v, 0.0 ; cannot produce -0.0860 %B = fadd float %z, %x861 %C = select i1 %A, float %y, float %B862 ret float %C863}864 865; Do not transform if Z is possibly negative zero866define float @select_fadd_fcmp_bad_11(float %x, float %y, float %v) {867; CHECK-LABEL: @select_fadd_fcmp_bad_11(868; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00869; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], -1.000000e+00870; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]]871; CHECK-NEXT: ret float [[C]]872;873 %A = fcmp une float %x, -0.0874 %z = fadd float %v, -1.0875 %B = fadd nsz float %z, %x876 %C = select i1 %A, float %y, float %B877 ret float %C878}879 880; Do not transform if we have signed zeros and if Z is possibly negative zero881define float @select_fadd_fcmp_bad_12(float %x, float %y, float %z) {882; CHECK-LABEL: @select_fadd_fcmp_bad_12(883; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00884; CHECK-NEXT: [[B:%.*]] = fadd float [[Z:%.*]], [[X]]885; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]886; CHECK-NEXT: ret float [[C]]887;888 %A = fcmp une float %x, -0.0889 %B = fadd float %z, %x890 %C = select i1 %A, float %y, float %B891 ret float %C892}893 894; Invalid order of operands of select895define float @select_fadd_fcmp_bad_13(float %x, float %y, float %z) {896; CHECK-LABEL: @select_fadd_fcmp_bad_13(897; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00898; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[X]], [[Z:%.*]]899; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]900; CHECK-NEXT: ret float [[C]]901;902 %A = fcmp oeq float %x, -0.0903 %B = fadd nsz float %x, %z904 %C = select i1 %A, float %y, float %B905 ret float %C906}907 908define float @select_fmul_fcmp_equiv(float %x, float %y, float %z) {909; CHECK-LABEL: @select_fmul_fcmp_equiv(910; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 3.000000e+00911; CHECK-NEXT: [[B:%.*]] = fmul nsz float [[Z:%.*]], 3.000000e+00912; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]913; CHECK-NEXT: ret float [[C]]914;915 %A = fcmp oeq float %x, 3.0916 %B = fmul nsz float %x, %z917 %C = select i1 %A, float %B, float %y918 ret float %C919}920 921define float @select_fmul_fcmp_equiv2(float %x, float %y, float %z) {922; CHECK-LABEL: @select_fmul_fcmp_equiv2(923; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00924; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B:%.*]], float [[Y:%.*]]925; CHECK-NEXT: ret float [[C]]926;927 %A = fcmp oeq float %x, 1.0928 %B = fmul float %x, %z929 %C = select i1 %A, float %B, float %y930 ret float %C931}932 933define float @select_fmul_icmp_bad(float %x, float %y, float %z, i32 %k) {934; CHECK-LABEL: @select_fmul_icmp_bad(935; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[K:%.*]], 0936; CHECK-NEXT: [[B:%.*]] = fmul float [[X:%.*]], [[Z:%.*]]937; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]938; CHECK-NEXT: ret float [[C]]939;940 %A = icmp eq i32 %k, 0941 %B = fmul float %x, %z942 %C = select i1 %A, float %B, float %y943 ret float %C944}945 946define float @select_fmul_icmp_bad_2(float %x, float %y, float %z, i32 %k) {947; CHECK-LABEL: @select_fmul_icmp_bad_2(948; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[K:%.*]], 0949; CHECK-NEXT: [[B:%.*]] = fmul nsz float [[X:%.*]], [[Z:%.*]]950; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]951; CHECK-NEXT: ret float [[C]]952;953 %A = icmp eq i32 %k, 0954 %B = fmul nsz float %x, %z955 %C = select i1 %A, float %B, float %y956 ret float %C957}958 959define float @select_fdiv_fcmp_equiv(float %x, float %y, float %z) {960; CHECK-LABEL: @select_fdiv_fcmp_equiv(961; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00962; CHECK-NEXT: [[B:%.*]] = fdiv float 1.000000e+00, [[Z:%.*]]963; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]964; CHECK-NEXT: ret float [[C]]965;966 %A = fcmp oeq float %x, 1.0967 %B = fdiv float %x, %z968 %C = select i1 %A, float %B, float %y969 ret float %C970}971 972define float @select_fdiv_fcmp_equiv2(float %x, float %y, float %z) {973; CHECK-LABEL: @select_fdiv_fcmp_equiv2(974; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 3.000000e+00975; CHECK-NEXT: [[B:%.*]] = fdiv nsz float 3.000000e+00, [[Z:%.*]]976; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]977; CHECK-NEXT: ret float [[C]]978;979 %A = fcmp oeq float %x, 3.0980 %B = fdiv nsz float %x, %z981 %C = select i1 %A, float %B, float %y982 ret float %C983}984 985; The transform is not valid when x = -0.0 and z = -0.0986; (optimized code would return -0.0, but this returns +0.0).987 988define float @select_fsub_fcmp_bad(float %x, float %y, float %z) {989; CHECK-LABEL: @select_fsub_fcmp_bad(990; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00991; CHECK-NEXT: [[B:%.*]] = fsub float [[Z:%.*]], [[X]]992; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]993; CHECK-NEXT: ret float [[C]]994;995 %A = fcmp oeq float %x, 0.0996 %B = fsub float %z, %x997 %C = select i1 %A, float %B, float %y998 ret float %C999}1000 1001define float @select_fsub_fcmp_equiv(float %x, float %y, float %z) {1002; CHECK-LABEL: @select_fsub_fcmp_equiv(1003; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+001004; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], -1.000000e+001005; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]1006; CHECK-NEXT: ret float [[C]]1007;1008 %A = fcmp oeq float %x, 1.01009 %B = fsub nsz float %z, %x1010 %C = select i1 %A, float %B, float %y1011 ret float %C1012}1013 1014define i32 @select_sub_icmp_bad(i32 %x, i32 %y, i32 %z) {1015; CHECK-LABEL: @select_sub_icmp_bad(1016; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 01017; CHECK-NEXT: [[B:%.*]] = sub i32 0, [[Z:%.*]]1018; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]1019; CHECK-NEXT: ret i32 [[C]]1020;1021 %A = icmp eq i32 %x, 01022 %B = sub i32 %x, %z1023 %C = select i1 %A, i32 %B, i32 %y1024 ret i32 %C1025}1026 1027define i32 @select_sub_icmp_bad_2(i32 %x, i32 %y, i32 %z) {1028; CHECK-LABEL: @select_sub_icmp_bad_2(1029; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 11030; CHECK-NEXT: [[B:%.*]] = add i32 [[Z:%.*]], -11031; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]1032; CHECK-NEXT: ret i32 [[C]]1033;1034 %A = icmp eq i32 %x, 11035 %B = sub i32 %z, %x1036 %C = select i1 %A, i32 %B, i32 %y1037 ret i32 %C1038}1039 1040define i32 @select_sub_icmp_bad_3(i32 %x, i32 %y, i32 %z) {1041; CHECK-LABEL: @select_sub_icmp_bad_3(1042; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 01043; CHECK-NEXT: call void @use2(i1 [[A]])1044; CHECK-NEXT: [[B:%.*]] = sub i32 [[Z:%.*]], [[X]]1045; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]1046; CHECK-NEXT: ret i32 [[C]]1047;1048 %A = icmp ne i32 %x, 01049 call void @use2(i1 %A)1050 %B = sub i32 %z, %x1051 %C = select i1 %A, i32 %B, i32 %y1052 ret i32 %C1053}1054 1055define i32 @select_sub_icmp_4(i32 %x, i32 %y, i32 %z) {1056; CHECK-LABEL: @select_sub_icmp_4(1057; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 01058; CHECK-NEXT: call void @use2(i1 [[A]])1059; CHECK-NEXT: [[B:%.*]] = sub i32 [[Z:%.*]], [[X]]1060; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]1061; CHECK-NEXT: ret i32 [[C]]1062;1063 %A = icmp ne i32 %x, 01064 call void @use2(i1 %A)1065 %B = sub i32 %z, %x1066 %C = select i1 %A, i32 %B, i32 %y1067 ret i32 %C1068}1069 1070define i32 @select_sub_icmp_bad_4(i32 %x, i32 %y, i32 %z, i32 %k) {1071; CHECK-LABEL: @select_sub_icmp_bad_4(1072; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 01073; CHECK-NEXT: [[B:%.*]] = sub i32 [[Z:%.*]], [[K:%.*]]1074; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]1075; CHECK-NEXT: ret i32 [[C]]1076;1077 %A = icmp eq i32 %x, 01078 %B = sub i32 %z, %k1079 %C = select i1 %A, i32 %B, i32 %y1080 ret i32 %C1081}1082 1083define i32 @select_sub_icmp_bad_5(i32 %x, i32 %y, i32 %z, i32 %k) {1084; CHECK-LABEL: @select_sub_icmp_bad_5(1085; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], [[K:%.*]]1086; CHECK-NEXT: [[B:%.*]] = sub i32 [[Z:%.*]], [[X]]1087; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]1088; CHECK-NEXT: ret i32 [[C]]1089;1090 %A = icmp eq i32 %x, %k1091 %B = sub i32 %z, %x1092 %C = select i1 %A, i32 %B, i32 %y1093 ret i32 %C1094}1095 1096define i32 @select_shl_icmp_bad(i32 %x, i32 %y, i32 %z) {1097; CHECK-LABEL: @select_shl_icmp_bad(1098; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 11099; CHECK-NEXT: [[B:%.*]] = shl i32 [[Z:%.*]], 11100; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]1101; CHECK-NEXT: ret i32 [[C]]1102;1103 %A = icmp eq i32 %x, 11104 %B = shl i32 %z, %x1105 %C = select i1 %A, i32 %B, i32 %y1106 ret i32 %C1107}1108 1109define i32 @select_lshr_icmp_bad(i32 %x, i32 %y, i32 %z) {1110; CHECK-LABEL: @select_lshr_icmp_bad(1111; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 11112; CHECK-NEXT: [[B:%.*]] = lshr i32 [[Z:%.*]], 11113; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]1114; CHECK-NEXT: ret i32 [[C]]1115;1116 %A = icmp eq i32 %x, 11117 %B = lshr i32 %z, %x1118 %C = select i1 %A, i32 %B, i32 %y1119 ret i32 %C1120}1121 1122define i32 @select_ashr_icmp_bad(i32 %x, i32 %y, i32 %z) {1123; CHECK-LABEL: @select_ashr_icmp_bad(1124; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 11125; CHECK-NEXT: [[B:%.*]] = ashr i32 [[Z:%.*]], 11126; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]1127; CHECK-NEXT: ret i32 [[C]]1128;1129 %A = icmp eq i32 %x, 11130 %B = ashr i32 %z, %x1131 %C = select i1 %A, i32 %B, i32 %y1132 ret i32 %C1133}1134 1135define i32 @select_udiv_icmp_bad(i32 %x, i32 %y, i32 %z) {1136; CHECK-LABEL: @select_udiv_icmp_bad(1137; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 31138; CHECK-NEXT: [[B:%.*]] = udiv i32 [[Z:%.*]], [[X]]1139; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]1140; CHECK-NEXT: ret i32 [[C]]1141;1142 %A = icmp eq i32 %x, 31143 %B = udiv i32 %z, %x1144 %C = select i1 %A, i32 %B, i32 %y1145 ret i32 %C1146}1147 1148define i32 @select_sdiv_icmp_bad(i32 %x, i32 %y, i32 %z) {1149; CHECK-LABEL: @select_sdiv_icmp_bad(1150; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 31151; CHECK-NEXT: [[B:%.*]] = sdiv i32 [[Z:%.*]], [[X]]1152; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]1153; CHECK-NEXT: ret i32 [[C]]1154;1155 %A = icmp eq i32 %x, 31156 %B = sdiv i32 %z, %x1157 %C = select i1 %A, i32 %B, i32 %y1158 ret i32 %C1159}1160 1161; Can replace %x with 0, because sub is only used in the select.1162define i32 @select_replace_one_use(i32 %x, i32 %y) {1163; CHECK-LABEL: @select_replace_one_use(1164; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 01165; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[Y:%.*]]1166; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[SUB]], i32 [[Y]]1167; CHECK-NEXT: ret i32 [[S]]1168;1169 %c = icmp eq i32 %x, 01170 %sub = sub i32 %x, %y1171 %s = select i1 %c, i32 %sub, i32 %y1172 ret i32 %s1173}1174 1175; Can not replace %x with 0, because %sub has other uses as well.1176define i32 @select_replace_multi_use(i32 %x, i32 %y) {1177; CHECK-LABEL: @select_replace_multi_use(1178; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 01179; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X]], [[Y:%.*]]1180; CHECK-NEXT: call void @use_i32(i32 [[SUB]])1181; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[SUB]], i32 [[Y]]1182; CHECK-NEXT: ret i32 [[S]]1183;1184 %c = icmp eq i32 %x, 01185 %sub = sub i32 %x, %y1186 call void @use_i32(i32 %sub)1187 %s = select i1 %c, i32 %sub, i32 %y1188 ret i32 %s1189}1190 1191; Case where the replacement allows the instruction to fold away.1192define i32 @select_replace_fold(i32 %x, i32 %y, i32 %z) {1193; CHECK-LABEL: @select_replace_fold(1194; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 01195; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[Z:%.*]], i32 [[Y:%.*]]1196; CHECK-NEXT: ret i32 [[S]]1197;1198 %c = icmp eq i32 %x, 01199 %fshr = call i32 @llvm.fshr.i32(i32 %y, i32 %z, i32 %x)1200 %s = select i1 %c, i32 %fshr, i32 %y1201 ret i32 %s1202}1203 1204 1205; Case where the use of %x is in a nested instruction.1206define i32 @select_replace_nested(i32 %x, i32 %y, i32 %z) {1207; CHECK-LABEL: @select_replace_nested(1208; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 01209; CHECK-NEXT: [[ADD:%.*]] = select i1 [[C]], i32 [[Z:%.*]], i32 01210; CHECK-NEXT: [[S:%.*]] = add i32 [[Y:%.*]], [[ADD]]1211; CHECK-NEXT: ret i32 [[S]]1212;1213 %c = icmp eq i32 %x, 01214 %sub = sub i32 %y, %x1215 %add = add i32 %sub, %z1216 %s = select i1 %c, i32 %add, i32 %y1217 ret i32 %s1218}1219 1220define i32 @select_replace_nested_extra_use(i32 %x, i32 %y, i32 %z) {1221; CHECK-LABEL: @select_replace_nested_extra_use(1222; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 01223; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[Y:%.*]], [[X]]1224; CHECK-NEXT: call void @use.i32(i32 [[SUB]])1225; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SUB]], [[Z:%.*]]1226; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[ADD]], i32 [[Y]]1227; CHECK-NEXT: ret i32 [[S]]1228;1229 %c = icmp eq i32 %x, 01230 %sub = sub i32 %y, %x1231 call void @use.i32(i32 %sub)1232 %add = add i32 %sub, %z1233 %s = select i1 %c, i32 %add, i32 %y1234 ret i32 %s1235}1236 1237define i32 @select_replace_nested_no_simplify(i32 %x, i32 %y, i32 %z) {1238; CHECK-LABEL: @select_replace_nested_no_simplify(1239; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 11240; CHECK-NEXT: [[SUB:%.*]] = add i32 [[Y:%.*]], -11241; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SUB]], [[Z:%.*]]1242; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[ADD]], i32 [[Y]]1243; CHECK-NEXT: ret i32 [[S]]1244;1245 %c = icmp eq i32 %x, 11246 %sub = sub i32 %y, %x1247 %add = add i32 %sub, %z1248 %s = select i1 %c, i32 %add, i32 %y1249 ret i32 %s1250}1251 1252; FIXME: We only perform replacements two levels up right now.1253define i32 @select_replace_deeply_nested(i32 %x, i32 %y, i32 %z) {1254; CHECK-LABEL: @select_replace_deeply_nested(1255; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 01256; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[Y:%.*]], [[X]]1257; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SUB]], [[Z:%.*]]1258; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[ADD]], 11259; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[SHL]], i32 [[Y]]1260; CHECK-NEXT: ret i32 [[S]]1261;1262 %c = icmp eq i32 %x, 01263 %sub = sub i32 %y, %x1264 %add = add i32 %sub, %z1265 %shl = shl i32 %add, 11266 %s = select i1 %c, i32 %shl, i32 %y1267 ret i32 %s1268}1269 1270; Do not replace with constant expressions. The profitability in this case is1271; unclear, and such replacements have historically lead to infinite combine1272; loops.1273define i32 @select_replace_constexpr(i32 %x, i32 %y, i32 %z) {1274; CHECK-LABEL: @select_replace_constexpr(1275; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], ptrtoint (ptr @g to i32)1276; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X]], [[Y:%.*]]1277; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[ADD]], i32 [[Z:%.*]]1278; CHECK-NEXT: ret i32 [[S]]1279;1280 %c = icmp eq i32 %x, ptrtoint (ptr @g to i32)1281 %add = add i32 %x, %y1282 %s = select i1 %c, i32 %add, i32 %z1283 ret i32 %s1284}1285 1286; Don't replace with a potentially undef constant, as undef could evaluate1287; to different values for both uses.1288define <2 x i32> @select_replace_undef(<2 x i32> %x, <2 x i32> %y) {1289; CHECK-LABEL: @select_replace_undef(1290; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 0, i32 undef>1291; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i32> [[X]], [[Y:%.*]]1292; CHECK-NEXT: [[S:%.*]] = select <2 x i1> [[C]], <2 x i32> [[SUB]], <2 x i32> [[Y]]1293; CHECK-NEXT: ret <2 x i32> [[S]]1294;1295 %c = icmp eq <2 x i32> %x, <i32 0, i32 undef>1296 %sub = sub <2 x i32> %x, %y1297 %s = select <2 x i1> %c, <2 x i32> %sub, <2 x i32> %y1298 ret <2 x i32> %s1299}1300 1301; We can replace the call arguments, as the call is speculatable.1302define i32 @select_replace_call_speculatable(i32 %x, i32 %y) {1303; CHECK-LABEL: @select_replace_call_speculatable(1304; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 01305; CHECK-NEXT: [[CALL:%.*]] = call i32 @call_speculatable(i32 0, i32 0)1306; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[CALL]], i32 [[Y:%.*]]1307; CHECK-NEXT: ret i32 [[S]]1308;1309 %c = icmp eq i32 %x, 01310 %call = call i32 @call_speculatable(i32 %x, i32 %x)1311 %s = select i1 %c, i32 %call, i32 %y1312 ret i32 %s1313}1314 1315define i32 @select_replace_call_speculatable_intrinsic(i32 %x, i32 %y) {1316; CHECK-LABEL: @select_replace_call_speculatable_intrinsic(1317; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 01318; CHECK-NEXT: [[CALL:%.*]] = call i32 @llvm.smax.i32(i32 [[Y:%.*]], i32 0)1319; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[CALL]], i32 [[Y]]1320; CHECK-NEXT: ret i32 [[S]]1321;1322 %c = icmp eq i32 %x, 01323 %call = call i32 @llvm.smax.i32(i32 %x, i32 %y)1324 %s = select i1 %c, i32 %call, i32 %y1325 ret i32 %s1326}1327 1328; We can't replace the call arguments, as the call is not speculatable. We1329; may end up changing side-effects or causing undefined behavior.1330define i32 @select_replace_call_non_speculatable(i32 %x, i32 %y) {1331; CHECK-LABEL: @select_replace_call_non_speculatable(1332; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 01333; CHECK-NEXT: [[CALL:%.*]] = call i32 @call_non_speculatable(i32 [[X]], i32 [[X]])1334; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[CALL]], i32 [[Y:%.*]]1335; CHECK-NEXT: ret i32 [[S]]1336;1337 %c = icmp eq i32 %x, 01338 %call = call i32 @call_non_speculatable(i32 %x, i32 %x)1339 %s = select i1 %c, i32 %call, i32 %y1340 ret i32 %s1341}1342 1343; We can replace %x by 2 here, because division by two cannot cause UB.1344; FIXME: As we check speculation prior to replacement, we don't catch this.1345define i32 @select_replace_sdiv_speculatable(i32 %x, i32 %y) {1346; CHECK-LABEL: @select_replace_sdiv_speculatable(1347; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 21348; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[Y:%.*]], [[X]]1349; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[DIV]], i32 [[Y]]1350; CHECK-NEXT: ret i32 [[S]]1351;1352 %c = icmp eq i32 %x, 21353 %div = sdiv i32 %y, %x1354 %s = select i1 %c, i32 %div, i32 %y1355 ret i32 %s1356}1357 1358; We cannot replace %x by -1, because division by -1 can cause UB.1359define i32 @select_replace_sdiv_non_speculatable(i32 %x, i32 %y) {1360; CHECK-LABEL: @select_replace_sdiv_non_speculatable(1361; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], -11362; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[Y:%.*]], [[X]]1363; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[DIV]], i32 [[Y]]1364; CHECK-NEXT: ret i32 [[S]]1365;1366 %c = icmp eq i32 %x, -11367 %div = sdiv i32 %y, %x1368 %s = select i1 %c, i32 %div, i32 %y1369 ret i32 %s1370}1371 1372; We can replace %x by 2 here, because division by two cannot cause UB.1373; FIXME: As we check speculation prior to replacement, we don't catch this.1374define i32 @select_replace_udiv_speculatable(i32 %x, i32 %y) {1375; CHECK-LABEL: @select_replace_udiv_speculatable(1376; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 21377; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[Y:%.*]], [[X]]1378; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[DIV]], i32 [[Y]]1379; CHECK-NEXT: ret i32 [[S]]1380;1381 %c = icmp eq i32 %x, 21382 %div = udiv i32 %y, %x1383 %s = select i1 %c, i32 %div, i32 %y1384 ret i32 %s1385}1386 1387; We can't replace %x by 0 here, because that would cause UB. However,1388; replacing the udiv result by poison is fine.1389define i32 @select_replace_udiv_non_speculatable(i32 %x, i32 %y) {1390; CHECK-LABEL: @select_replace_udiv_non_speculatable(1391; CHECK-NEXT: ret i32 [[Y:%.*]]1392;1393 %c = icmp eq i32 %x, 01394 %div = udiv i32 %y, %x1395 %s = select i1 %c, i32 %div, i32 %y1396 ret i32 %s1397}1398 1399; We can't replace %i in the phi node here, because it refers to %i from1400; the previous loop iteration, not the current one.1401define void @select_replace_phi(i32 %x) {1402; CHECK-LABEL: @select_replace_phi(1403; CHECK-NEXT: entry:1404; CHECK-NEXT: br label [[LOOP:%.*]]1405; CHECK: loop:1406; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]1407; CHECK-NEXT: [[I_PREV:%.*]] = phi i32 [ -1, [[ENTRY]] ], [ [[I]], [[LOOP]] ]1408; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 11409; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[I]], 01410; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[I_PREV]], i32 21411; CHECK-NEXT: call void @use_i32(i32 [[S]])1412; CHECK-NEXT: br label [[LOOP]]1413;1414entry:1415 br label %loop1416 1417loop:1418 %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]1419 %i.prev = phi i32 [ -1, %entry], [ %i, %loop ]1420 %i.next = add i32 %i, 11421 %c = icmp eq i32 %i, 01422 %s = select i1 %c, i32 %i.prev, i32 21423 call void @use_i32(i32 %s)1424 br label %loop1425}1426 1427@g = global i32 01428declare i32 @llvm.fshr.i32(i32, i32, i32)1429declare i32 @call_speculatable(i32, i32) speculatable1430declare i32 @call_non_speculatable(i32, i32)1431declare void @use_i32(i32)1432 1433!0 = !{!"branch_weights", i32 2, i32 10}1434