brintos

brintos / llvm-project-archived public Read only

0
0
Text · 43.9 KiB · 39117f5 Raw
1308 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3; RUN: opt < %s -passes=instcombine -use-constant-fp-for-fixed-length-splat -S | FileCheck %s4 5declare float @llvm.ldexp.f32.i32(float, i32)6declare <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float>, <2 x i32>)7declare void @use(float)8 9define float @fneg_fneg(float %a) {10;11; CHECK-LABEL: @fneg_fneg(12; CHECK-NEXT:    ret float [[A:%.*]]13;14  %f = fneg float %a15  %r = fneg float %f16  ret float %r17}18 19; -(X * C) --> X * (-C)20 21define float @fmul_fsub(float %x) {22; CHECK-LABEL: @fmul_fsub(23; CHECK-NEXT:    [[R:%.*]] = fmul float [[X:%.*]], -4.200000e+0124; CHECK-NEXT:    ret float [[R]]25;26  %m = fmul float %x, 42.027  %r = fsub float -0.0, %m28  ret float %r29}30 31define float @fmul_fneg(float %x) {32; CHECK-LABEL: @fmul_fneg(33; CHECK-NEXT:    [[R:%.*]] = fmul float [[X:%.*]], -4.200000e+0134; CHECK-NEXT:    ret float [[R]]35;36  %m = fmul float %x, 42.037  %r = fneg float %m38  ret float %r39}40 41; Fast math is not required, but it should be propagated.42 43define float @fmul_fsub_fmf(float %x) {44; CHECK-LABEL: @fmul_fsub_fmf(45; CHECK-NEXT:    [[R:%.*]] = fmul nsz float [[X:%.*]], -4.200000e+0146; CHECK-NEXT:    ret float [[R]]47;48  %m = fmul float %x, 42.049  %r = fsub reassoc nsz float -0.0, %m50  ret float %r51}52 53define float @fmul_fneg_fmf(float %x) {54; CHECK-LABEL: @fmul_fneg_fmf(55; CHECK-NEXT:    [[R:%.*]] = fmul nsz float [[X:%.*]], -4.200000e+0156; CHECK-NEXT:    ret float [[R]]57;58  %m = fmul float %x, 42.059  %r = fneg reassoc nsz float %m60  ret float %r61}62 63; Extra use prevents the fold. We don't want to replace the fneg with an fmul.64 65define float @fmul_fsub_extra_use(float %x) {66; CHECK-LABEL: @fmul_fsub_extra_use(67; CHECK-NEXT:    [[M:%.*]] = fmul float [[X:%.*]], 4.200000e+0168; CHECK-NEXT:    [[R:%.*]] = fneg float [[M]]69; CHECK-NEXT:    call void @use(float [[M]])70; CHECK-NEXT:    ret float [[R]]71;72  %m = fmul float %x, 42.073  %r = fsub float -0.0, %m74  call void @use(float %m)75  ret float %r76}77 78define float @fmul_fneg_extra_use(float %x) {79; CHECK-LABEL: @fmul_fneg_extra_use(80; CHECK-NEXT:    [[M:%.*]] = fmul float [[X:%.*]], 4.200000e+0181; CHECK-NEXT:    [[R:%.*]] = fneg float [[M]]82; CHECK-NEXT:    call void @use(float [[M]])83; CHECK-NEXT:    ret float [[R]]84;85  %m = fmul float %x, 42.086  %r = fneg float %m87  call void @use(float %m)88  ret float %r89}90 91; Try a vector. Use special constants (NaN, INF, poison) because they don't change anything.92 93define <4 x double> @fmul_fsub_vec(<4 x double> %x) {94; CHECK-LABEL: @fmul_fsub_vec(95; CHECK-NEXT:    [[R:%.*]] = fmul <4 x double> [[X:%.*]], <double -4.200000e+01, double 0xFFF8000000000000, double 0xFFF0000000000000, double poison>96; CHECK-NEXT:    ret <4 x double> [[R]]97;98  %m = fmul <4 x double> %x, <double 42.0, double 0x7FF8000000000000, double 0x7FF0000000000000, double poison>99  %r = fsub <4 x double> <double -0.0, double -0.0, double -0.0, double -0.0>, %m100  ret <4 x double> %r101}102 103define <4 x double> @fmul_fneg_vec(<4 x double> %x) {104; CHECK-LABEL: @fmul_fneg_vec(105; CHECK-NEXT:    [[R:%.*]] = fmul <4 x double> [[X:%.*]], <double -4.200000e+01, double 0xFFF8000000000000, double 0xFFF0000000000000, double poison>106; CHECK-NEXT:    ret <4 x double> [[R]]107;108  %m = fmul <4 x double> %x, <double 42.0, double 0x7FF8000000000000, double 0x7FF0000000000000, double poison>109  %r = fneg <4 x double> %m110  ret <4 x double> %r111}112 113; -(X / C) --> X / (-C)114 115define float @fdiv_op1_constant_fsub(float %x) {116; CHECK-LABEL: @fdiv_op1_constant_fsub(117; CHECK-NEXT:    [[R:%.*]] = fdiv float [[X:%.*]], 4.200000e+01118; CHECK-NEXT:    ret float [[R]]119;120  %d = fdiv float %x, -42.0121  %r = fsub float -0.0, %d122  ret float %r123}124 125define float @fdiv_op1_constant_fneg(float %x) {126; CHECK-LABEL: @fdiv_op1_constant_fneg(127; CHECK-NEXT:    [[R:%.*]] = fdiv float [[X:%.*]], 4.200000e+01128; CHECK-NEXT:    ret float [[R]]129;130  %d = fdiv float %x, -42.0131  %r = fneg float %d132  ret float %r133}134 135; Fast math is not required, but it should be propagated.136 137define float @fdiv_op1_constant_fsub_fmf(float %x) {138; CHECK-LABEL: @fdiv_op1_constant_fsub_fmf(139; CHECK-NEXT:    [[R:%.*]] = fdiv nnan float [[X:%.*]], 4.200000e+01140; CHECK-NEXT:    ret float [[R]]141;142  %d = fdiv float %x, -42.0143  %r = fsub nnan float -0.0, %d144  ret float %r145}146 147define float @fdiv_op1_constant_fneg_fmf(float %x) {148; CHECK-LABEL: @fdiv_op1_constant_fneg_fmf(149; CHECK-NEXT:    [[R:%.*]] = fdiv nnan float [[X:%.*]], 4.200000e+01150; CHECK-NEXT:    ret float [[R]]151;152  %d = fdiv float %x, -42.0153  %r = fneg nnan float %d154  ret float %r155}156 157; Extra use prevents the fold. We don't want to replace the fneg with an fdiv.158 159define float @fdiv_op1_constant_fsub_extra_use(float %x) {160; CHECK-LABEL: @fdiv_op1_constant_fsub_extra_use(161; CHECK-NEXT:    [[D:%.*]] = fdiv float [[X:%.*]], 4.200000e+01162; CHECK-NEXT:    [[R:%.*]] = fneg float [[D]]163; CHECK-NEXT:    call void @use(float [[D]])164; CHECK-NEXT:    ret float [[R]]165;166  %d = fdiv float %x, 42.0167  %r = fsub float -0.0, %d168  call void @use(float %d)169  ret float %r170}171 172define float @fdiv_op1_constant_fneg_extra_use(float %x) {173; CHECK-LABEL: @fdiv_op1_constant_fneg_extra_use(174; CHECK-NEXT:    [[D:%.*]] = fdiv float [[X:%.*]], 4.200000e+01175; CHECK-NEXT:    [[R:%.*]] = fneg float [[D]]176; CHECK-NEXT:    call void @use(float [[D]])177; CHECK-NEXT:    ret float [[R]]178;179  %d = fdiv float %x, 42.0180  %r = fneg float %d181  call void @use(float %d)182  ret float %r183}184 185; Try a vector. Use special constants (NaN, INF, poison) because they don't change anything.186 187define <4 x double> @fdiv_op1_constant_fsub_vec(<4 x double> %x) {188; CHECK-LABEL: @fdiv_op1_constant_fsub_vec(189; CHECK-NEXT:    [[R:%.*]] = fdiv <4 x double> [[X:%.*]], <double 4.200000e+01, double 0x7FF800000ABCD000, double 0x7FF0000000000000, double poison>190; CHECK-NEXT:    ret <4 x double> [[R]]191;192  %d = fdiv <4 x double> %x, <double -42.0, double 0xFFF800000ABCD000, double 0xFFF0000000000000, double poison>193  %r = fsub <4 x double> <double -0.0, double -0.0, double -0.0, double -0.0>, %d194  ret <4 x double> %r195}196 197define <4 x double> @fdiv_op1_constant_fneg_vec(<4 x double> %x) {198; CHECK-LABEL: @fdiv_op1_constant_fneg_vec(199; CHECK-NEXT:    [[R:%.*]] = fdiv <4 x double> [[X:%.*]], <double 4.200000e+01, double 0x7FF800000ABCD000, double 0x7FF0000000000000, double poison>200; CHECK-NEXT:    ret <4 x double> [[R]]201;202  %d = fdiv <4 x double> %x, <double -42.0, double 0xFFF800000ABCD000, double 0xFFF0000000000000, double poison>203  %r = fneg <4 x double> %d204  ret <4 x double> %r205}206 207; -(C / X) --> (-C) / X208 209define float @fdiv_op0_constant_fsub(float %x) {210; CHECK-LABEL: @fdiv_op0_constant_fsub(211; CHECK-NEXT:    [[R:%.*]] = fdiv float -4.200000e+01, [[X:%.*]]212; CHECK-NEXT:    ret float [[R]]213;214  %d = fdiv float 42.0, %x215  %r = fsub float -0.0, %d216  ret float %r217}218 219define float @fdiv_op0_constant_fneg(float %x) {220; CHECK-LABEL: @fdiv_op0_constant_fneg(221; CHECK-NEXT:    [[R:%.*]] = fdiv float -4.200000e+01, [[X:%.*]]222; CHECK-NEXT:    ret float [[R]]223;224  %d = fdiv float 42.0, %x225  %r = fneg float %d226  ret float %r227}228 229; Fast math is not required, but it should be propagated.230 231define float @fdiv_op0_constant_fneg_fast_fast(float %x) {232; CHECK-LABEL: @fdiv_op0_constant_fneg_fast_fast(233; CHECK-NEXT:    [[R:%.*]] = fdiv fast float -4.200000e+01, [[X:%.*]]234; CHECK-NEXT:    ret float [[R]]235;236  %d = fdiv fast float 42.0, %x237  %r = fneg fast float %d238  ret float %r239}240 241define float @fdiv_op0_constant_fneg_fast(float %x) {242; CHECK-LABEL: @fdiv_op0_constant_fneg_fast(243; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc nnan arcp contract afn float -4.200000e+01, [[X:%.*]]244; CHECK-NEXT:    ret float [[R]]245;246  %d = fdiv float 42.0, %x247  %r = fneg fast float %d248  ret float %r249}250 251define float @fdiv_op0_constant_fneg_nsz_nsz(float %x) {252; CHECK-LABEL: @fdiv_op0_constant_fneg_nsz_nsz(253; CHECK-NEXT:    [[R:%.*]] = fdiv nsz float -4.200000e+01, [[X:%.*]]254; CHECK-NEXT:    ret float [[R]]255;256  %d = fdiv nsz float 42.0, %x257  %r = fneg nsz float %d258  ret float %r259}260 261define float @fdiv_op0_constant_fneg_nsz(float %x) {262; CHECK-LABEL: @fdiv_op0_constant_fneg_nsz(263; CHECK-NEXT:    [[R:%.*]] = fdiv float -4.200000e+01, [[X:%.*]]264; CHECK-NEXT:    ret float [[R]]265;266  %d = fdiv float 42.0, %x267  %r = fneg nsz float %d268  ret float %r269}270 271define float @fdiv_op0_constant_fneg_ninf_ninf(float %x) {272; CHECK-LABEL: @fdiv_op0_constant_fneg_ninf_ninf(273; CHECK-NEXT:    [[R:%.*]] = fdiv ninf float -4.200000e+01, [[X:%.*]]274; CHECK-NEXT:    ret float [[R]]275;276  %d = fdiv ninf float 42.0, %x277  %r = fneg ninf float %d278  ret float %r279}280 281define float @fdiv_op0_constant_fneg_ninf(float %x) {282; CHECK-LABEL: @fdiv_op0_constant_fneg_ninf(283; CHECK-NEXT:    [[R:%.*]] = fdiv float -4.200000e+01, [[X:%.*]]284; CHECK-NEXT:    ret float [[R]]285;286  %d = fdiv float 42.0, %x287  %r = fneg ninf float %d288  ret float %r289}290 291define float @fdiv_op0_constant_fneg_nnan_nnan(float %x) {292; CHECK-LABEL: @fdiv_op0_constant_fneg_nnan_nnan(293; CHECK-NEXT:    [[R:%.*]] = fdiv nnan float -4.200000e+01, [[X:%.*]]294; CHECK-NEXT:    ret float [[R]]295;296  %d = fdiv nnan float 42.0, %x297  %r = fneg nnan float %d298  ret float %r299}300 301define float @fdiv_op0_constant_fneg_nnan(float %x) {302; CHECK-LABEL: @fdiv_op0_constant_fneg_nnan(303; CHECK-NEXT:    [[R:%.*]] = fdiv nnan float -4.200000e+01, [[X:%.*]]304; CHECK-NEXT:    ret float [[R]]305;306  %d = fdiv float 42.0, %x307  %r = fneg nnan float %d308  ret float %r309}310 311; Extra use prevents the fold. We don't want to replace the fneg with an fdiv.312 313define float @fdiv_op0_constant_fsub_extra_use(float %x) {314; CHECK-LABEL: @fdiv_op0_constant_fsub_extra_use(315; CHECK-NEXT:    [[D:%.*]] = fdiv float -4.200000e+01, [[X:%.*]]316; CHECK-NEXT:    [[R:%.*]] = fneg float [[D]]317; CHECK-NEXT:    call void @use(float [[D]])318; CHECK-NEXT:    ret float [[R]]319;320  %d = fdiv float -42.0, %x321  %r = fsub float -0.0, %d322  call void @use(float %d)323  ret float %r324}325 326define float @fdiv_op0_constant_fneg_extra_use(float %x) {327; CHECK-LABEL: @fdiv_op0_constant_fneg_extra_use(328; CHECK-NEXT:    [[D:%.*]] = fdiv float -4.200000e+01, [[X:%.*]]329; CHECK-NEXT:    [[R:%.*]] = fneg float [[D]]330; CHECK-NEXT:    call void @use(float [[D]])331; CHECK-NEXT:    ret float [[R]]332;333  %d = fdiv float -42.0, %x334  %r = fneg float %d335  call void @use(float %d)336  ret float %r337}338 339; Try a vector. Use special constants (NaN, INF, poison) because they don't change anything.340 341define <4 x double> @fdiv_op0_constant_fsub_vec(<4 x double> %x) {342; CHECK-LABEL: @fdiv_op0_constant_fsub_vec(343; CHECK-NEXT:    [[R:%.*]] = fdiv <4 x double> <double 4.200000e+01, double 0xFFF8000000000000, double 0x7FF0000000000000, double poison>, [[X:%.*]]344; CHECK-NEXT:    ret <4 x double> [[R]]345;346  %d = fdiv <4 x double> <double -42.0, double 0x7FF8000000000000, double 0xFFF0000000000000, double poison>, %x347  %r = fsub <4 x double> <double -0.0, double -0.0, double -0.0, double -0.0>, %d348  ret <4 x double> %r349}350 351define <4 x double> @fdiv_op0_constant_fneg_vec(<4 x double> %x) {352; CHECK-LABEL: @fdiv_op0_constant_fneg_vec(353; CHECK-NEXT:    [[R:%.*]] = fdiv <4 x double> <double 4.200000e+01, double 0xFFF8000000000000, double 0x7FF0000000000000, double poison>, [[X:%.*]]354; CHECK-NEXT:    ret <4 x double> [[R]]355;356  %d = fdiv <4 x double> <double -42.0, double 0x7FF8000000000000, double 0xFFF0000000000000, double poison>, %x357  %r = fneg <4 x double> %d358  ret <4 x double> %r359}360 361; Sink FP negation through a select:362; c ? -x : -y --> -(c ? x : y)363 364define <2 x double> @fneg_fneg_sel(<2 x double> %x, <2 x double> %y, i1 %cond) {365; CHECK-LABEL: @fneg_fneg_sel(366; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[COND:%.*]], <2 x double> [[X:%.*]], <2 x double> [[Y:%.*]]367; CHECK-NEXT:    [[SEL:%.*]] = fneg <2 x double> [[SEL_V]]368; CHECK-NEXT:    ret <2 x double> [[SEL]]369;370  %n1 = fneg <2 x double> %x371  %n2 = fneg <2 x double> %y372  %sel = select i1 %cond, <2 x double> %n1, <2 x double> %n2373  ret <2 x double> %sel374}375 376; An extra use is allowed.377 378define float @fneg_fneg_sel_extra_use1(float %x, float %y, i1 %cond) {379; CHECK-LABEL: @fneg_fneg_sel_extra_use1(380; CHECK-NEXT:    [[N1:%.*]] = fneg float [[X:%.*]]381; CHECK-NEXT:    call void @use(float [[N1]])382; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[COND:%.*]], float [[X]], float [[Y:%.*]]383; CHECK-NEXT:    [[SEL:%.*]] = fneg float [[SEL_V]]384; CHECK-NEXT:    ret float [[SEL]]385;386  %n1 = fneg float %x387  call void @use(float %n1)388  %n2 = fneg float %y389  %sel = select i1 %cond, float %n1, float %n2390  ret float %sel391}392 393define float @fneg_fneg_sel_extra_use2(float %x, float %y, i1 %cond) {394; CHECK-LABEL: @fneg_fneg_sel_extra_use2(395; CHECK-NEXT:    [[N2:%.*]] = fneg float [[Y:%.*]]396; CHECK-NEXT:    call void @use(float [[N2]])397; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[COND:%.*]], float [[X:%.*]], float [[Y]]398; CHECK-NEXT:    [[SEL:%.*]] = fneg float [[SEL_V]]399; CHECK-NEXT:    ret float [[SEL]]400;401  %n1 = fneg float %x402  %n2 = fneg float %y403  call void @use(float %n2)404  %sel = select i1 %cond, float %n1, float %n2405  ret float %sel406}407 408; Legacy form of fneg should work too.409 410define float @fsub_fsub_sel_extra_use1(float %x, float %y, i1 %cond) {411; CHECK-LABEL: @fsub_fsub_sel_extra_use1(412; CHECK-NEXT:    [[N1:%.*]] = fneg float [[X:%.*]]413; CHECK-NEXT:    call void @use(float [[N1]])414; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[COND:%.*]], float [[X]], float [[Y:%.*]]415; CHECK-NEXT:    [[SEL:%.*]] = fneg float [[SEL_V]]416; CHECK-NEXT:    ret float [[SEL]]417;418  %n1 = fsub float -0.0, %x419  call void @use(float %n1)420  %n2 = fsub float -0.0, %y421  %sel = select i1 %cond, float %n1, float %n2422  ret float %sel423}424 425; Negative test: but 2 extra uses would require an extra instruction.426 427define float @fneg_fneg_sel_extra_use3(float %x, float %y, i1 %cond) {428; CHECK-LABEL: @fneg_fneg_sel_extra_use3(429; CHECK-NEXT:    [[N1:%.*]] = fneg float [[X:%.*]]430; CHECK-NEXT:    call void @use(float [[N1]])431; CHECK-NEXT:    [[N2:%.*]] = fneg float [[Y:%.*]]432; CHECK-NEXT:    call void @use(float [[N2]])433; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], float [[N1]], float [[N2]]434; CHECK-NEXT:    ret float [[SEL]]435;436  %n1 = fneg float %x437  call void @use(float %n1)438  %n2 = fneg float %y439  call void @use(float %n2)440  %sel = select i1 %cond, float %n1, float %n2441  ret float %sel442}443 444define double @fneg_fneg_sel_fmf1(double %x, double %y, i1 %cond) {445; CHECK-LABEL: @fneg_fneg_sel_fmf1(446; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[COND:%.*]], double [[X:%.*]], double [[Y:%.*]]447; CHECK-NEXT:    [[SEL:%.*]] = fneg double [[SEL_V]]448; CHECK-NEXT:    ret double [[SEL]]449;450  %n1 = fneg nnan double %x451  %n2 = fneg ninf double %y452  %sel = select i1 %cond, double %n1, double %n2453  ret double %sel454}455 456define double @fneg_fneg_sel_fmf2(double %x, double %y, i1 %cond) {457; CHECK-LABEL: @fneg_fneg_sel_fmf2(458; CHECK-NEXT:    [[SEL_V:%.*]] = select ninf i1 [[COND:%.*]], double [[X:%.*]], double [[Y:%.*]]459; CHECK-NEXT:    [[SEL:%.*]] = fneg ninf double [[SEL_V]]460; CHECK-NEXT:    ret double [[SEL]]461;462  %n1 = fneg nnan ninf double %x463  %n2 = fneg ninf double %y464  %sel = select i1 %cond, double %n1, double %n2465  ret double %sel466}467 468define double @fneg_fneg_sel_fmf3(double %x, double %y, i1 %cond) {469; CHECK-LABEL: @fneg_fneg_sel_fmf3(470; CHECK-NEXT:    [[SEL_V:%.*]] = select ninf i1 [[COND:%.*]], double [[X:%.*]], double [[Y:%.*]]471; CHECK-NEXT:    [[SEL:%.*]] = fneg ninf double [[SEL_V]]472; CHECK-NEXT:    ret double [[SEL]]473;474  %n1 = fneg nnan ninf double %x475  %n2 = fneg ninf double %y476  %sel = select ninf i1 %cond, double %n1, double %n2477  ret double %sel478}479 480define double @fneg_fneg_sel_fmf4(double %x, double %y, i1 %cond) {481; CHECK-LABEL: @fneg_fneg_sel_fmf4(482; CHECK-NEXT:    [[SEL_V:%.*]] = select nnan ninf nsz i1 [[COND:%.*]], double [[X:%.*]], double [[Y:%.*]]483; CHECK-NEXT:    [[SEL:%.*]] = fneg nnan ninf nsz double [[SEL_V]]484; CHECK-NEXT:    ret double [[SEL]]485;486  %n1 = fneg nnan double %x487  %n2 = fneg ninf double %y488  %sel = select nsz nnan ninf i1 %cond, double %n1, double %n2489  ret double %sel490}491 492; Negative test493 494define float @fneg_fadd_constant(float %x) {495; CHECK-LABEL: @fneg_fadd_constant(496; CHECK-NEXT:    [[A:%.*]] = fadd float [[X:%.*]], 4.200000e+01497; CHECK-NEXT:    [[R:%.*]] = fneg float [[A]]498; CHECK-NEXT:    ret float [[R]]499;500  %a = fadd float %x, 42.0501  %r = fneg float %a502  ret float %r503}504 505; Negative test506 507define float @fake_nsz_fadd_constant(float %x) {508; CHECK-LABEL: @fake_nsz_fadd_constant(509; CHECK-NEXT:    [[A:%.*]] = fadd float [[X:%.*]], 4.200000e+01510; CHECK-NEXT:    [[R:%.*]] = fneg float [[A]]511; CHECK-NEXT:    ret float [[R]]512;513  %a = fadd float %x, 42.0514  %r = fsub float -0.0, %a515  ret float %r516}517 518; -(X + C) --> -C - X519 520define float @fneg_nsz_fadd_constant(float %x) {521; CHECK-LABEL: @fneg_nsz_fadd_constant(522; CHECK-NEXT:    [[R:%.*]] = fsub nsz float -4.200000e+01, [[X:%.*]]523; CHECK-NEXT:    ret float [[R]]524;525  %a = fadd float %x, 42.0526  %r = fneg nsz float %a527  ret float %r528}529 530; -(X + C) --> -C - X531 532define float @fake_fneg_nsz_fadd_constant(float %x) {533; CHECK-LABEL: @fake_fneg_nsz_fadd_constant(534; CHECK-NEXT:    [[R:%.*]] = fsub fast float -4.200000e+01, [[X:%.*]]535; CHECK-NEXT:    ret float [[R]]536;537  %a = fadd float %x, 42.0538  %r = fsub fast float -0.0, %a539  ret float %r540}541 542; Negative test543 544define float @fneg_nsz_fadd_constant_extra_use(float %x) {545; CHECK-LABEL: @fneg_nsz_fadd_constant_extra_use(546; CHECK-NEXT:    [[A:%.*]] = fadd float [[X:%.*]], 4.200000e+01547; CHECK-NEXT:    call void @use(float [[A]])548; CHECK-NEXT:    [[R:%.*]] = fneg nsz float [[A]]549; CHECK-NEXT:    ret float [[R]]550;551  %a = fadd float %x, 42.0552  call void @use(float %a)553  %r = fneg nsz float %a554  ret float %r555}556 557; Negative test558 559define float @fake_fneg_nsz_fadd_constant_extra_use(float %x) {560; CHECK-LABEL: @fake_fneg_nsz_fadd_constant_extra_use(561; CHECK-NEXT:    [[A:%.*]] = fadd float [[X:%.*]], 4.200000e+01562; CHECK-NEXT:    call void @use(float [[A]])563; CHECK-NEXT:    [[R:%.*]] = fneg fast float [[A]]564; CHECK-NEXT:    ret float [[R]]565;566  %a = fadd float %x, 42.0567  call void @use(float %a)568  %r = fsub fast float -0.0, %a569  ret float %r570}571 572; -(X + C) --> -C - X573 574define <2 x float> @fneg_nsz_fadd_constant_vec(<2 x float> %x) {575; CHECK-LABEL: @fneg_nsz_fadd_constant_vec(576; CHECK-NEXT:    [[R:%.*]] = fsub reassoc nnan nsz <2 x float> <float -4.200000e+01, float -4.300000e+01>, [[X:%.*]]577; CHECK-NEXT:    ret <2 x float> [[R]]578;579  %a = fadd <2 x float> %x, <float 42.0, float 43.0>580  %r = fneg nsz nnan reassoc <2 x float> %a581  ret <2 x float> %r582}583 584; -(X + C) --> -C - X585 586define <2 x float> @fake_fneg_nsz_fadd_constant_vec(<2 x float> %x) {587; CHECK-LABEL: @fake_fneg_nsz_fadd_constant_vec(588; CHECK-NEXT:    [[R:%.*]] = fsub nsz <2 x float> <float -4.200000e+01, float poison>, [[X:%.*]]589; CHECK-NEXT:    ret <2 x float> [[R]]590;591  %a = fadd <2 x float> %x, <float 42.0, float poison>592  %r = fsub nsz <2 x float> <float poison, float -0.0>, %a593  ret <2 x float> %r594}595 596@g = external global i16, align 1597 598define float @fneg_nsz_fadd_constant_expr(float %x) {599; CHECK-LABEL: @fneg_nsz_fadd_constant_expr(600; CHECK-NEXT:    [[A:%.*]] = fadd float [[X:%.*]], bitcast (i32 ptrtoint (ptr @g to i32) to float)601; CHECK-NEXT:    [[R:%.*]] = fneg nsz float [[A]]602; CHECK-NEXT:    ret float [[R]]603;604  %a = fadd float %x, bitcast (i32 ptrtoint (ptr @g to i32) to float)605  %r = fneg nsz float %a606  ret float %r607}608 609define float @fake_fneg_nsz_fadd_constant_expr(float %x) {610; CHECK-LABEL: @fake_fneg_nsz_fadd_constant_expr(611; CHECK-NEXT:    [[A:%.*]] = fadd float [[X:%.*]], bitcast (i32 ptrtoint (ptr @g to i32) to float)612; CHECK-NEXT:    [[R:%.*]] = fneg nsz float [[A]]613; CHECK-NEXT:    ret float [[R]]614;615  %a = fadd float %x, bitcast (i32 ptrtoint (ptr @g to i32) to float)616  %r = fsub nsz float -0.0, %a617  ret float %r618}619 620define float @select_fneg_true(float %x, float %y, i1 %b) {621; CHECK-LABEL: @select_fneg_true(622; CHECK-NEXT:    [[Y_NEG:%.*]] = fneg float [[Y:%.*]]623; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], float [[X:%.*]], float [[Y_NEG]]624; CHECK-NEXT:    ret float [[R]]625;626  %nx = fneg float %x627  %s = select i1 %b, float %nx, float %y628  %r = fneg float %s629  ret float %r630}631 632define <2 x float> @select_fneg_false(<2 x float> %x, <2 x float> %y, <2 x i1> %b) {633; CHECK-LABEL: @select_fneg_false(634; CHECK-NEXT:    [[X_NEG:%.*]] = fneg nnan nsz <2 x float> [[X:%.*]]635; CHECK-NEXT:    [[R:%.*]] = select nnan ninf <2 x i1> [[B:%.*]], <2 x float> [[X_NEG]], <2 x float> [[Y:%.*]]636; CHECK-NEXT:    ret <2 x float> [[R]]637;638  %ny = fneg nnan <2 x float> %y639  %s = select ninf <2 x i1> %b, <2 x float> %x, <2 x float> %ny640  %r = fneg nsz nnan <2 x float> %s641  ret <2 x float> %r642}643 644define float @select_fneg_false_no_nsz(float %x, float %y, i1 %b) {645; CHECK-LABEL: @select_fneg_false_no_nsz(646; CHECK-NEXT:    [[X_NEG:%.*]] = fneg nnan ninf nsz float [[X:%.*]]647; CHECK-NEXT:    [[R:%.*]] = select nnan ninf i1 [[B:%.*]], float [[X_NEG]], float [[Y:%.*]]648; CHECK-NEXT:    ret float [[R]]649;650  %ny = fneg float %y651  %s = select i1 %b, float %x, float %ny652  %r = fneg ninf nnan nsz float %s653  ret float %r654}655 656; The removal of nsz in this pattern is not needed if the select condition can't be poison.657 658define float @select_fneg_false_nsz_ok(float %x, float %y, i1 noundef %b) {659; CHECK-LABEL: @select_fneg_false_nsz_ok(660; CHECK-NEXT:    [[X_NEG:%.*]] = fneg nnan ninf nsz float [[X:%.*]]661; CHECK-NEXT:    [[R:%.*]] = select nnan ninf nsz i1 [[B:%.*]], float [[X_NEG]], float [[Y:%.*]]662; CHECK-NEXT:    ret float [[R]]663;664  %ny = fneg float %y665  %s = select i1 %b, float %x, float %ny666  %r = fneg nsz ninf nnan float %s667  ret float %r668}669 670define float @select_fneg_false_nsz(float %x, float %y, i1 %b) {671; CHECK-LABEL: @select_fneg_false_nsz(672; CHECK-NEXT:    [[X_NEG:%.*]] = fneg nnan ninf nsz float [[X:%.*]]673; CHECK-NEXT:    [[R:%.*]] = select nnan ninf nsz i1 [[B:%.*]], float [[X_NEG]], float [[Y:%.*]]674; CHECK-NEXT:    ret float [[R]]675;676  %ny = fneg float %y677  %s = select nsz i1 %b, float %x, float %ny678  %r = fneg ninf nnan nsz float %s679  ret float %r680}681 682; Special-case for propagating nsz: it's ok when selecting between an operand and its negation.683 684define float @select_common_op_fneg_true(float %x, i1 %b) {685; CHECK-LABEL: @select_common_op_fneg_true(686; CHECK-NEXT:    [[X_NEG:%.*]] = fneg nnan ninf nsz float [[X:%.*]]687; CHECK-NEXT:    [[R:%.*]] = select nnan ninf nsz i1 [[B:%.*]], float [[X_NEG]], float [[X]]688; CHECK-NEXT:    ret float [[R]]689;690  %nx = fneg float %x691  %s = select i1 %b, float %x, float %nx692  %r = fneg nsz ninf nnan float %s693  ret float %r694}695 696define float @select_common_op_fneg_false(float %x, i1 %b) {697; CHECK-LABEL: @select_common_op_fneg_false(698; CHECK-NEXT:    [[X_NEG:%.*]] = fneg nnan ninf nsz float [[X:%.*]]699; CHECK-NEXT:    [[R:%.*]] = select nnan ninf nsz i1 [[B:%.*]], float [[X_NEG]], float [[X]]700; CHECK-NEXT:    ret float [[R]]701;702  %nx = fneg float %x703  %s = select i1 %b, float %x, float %nx704  %r = fneg nsz ninf nnan float %s705  ret float %r706}707 708; The transform above allows follow-on folds to convert to fabs.709 710define float @fabs(float %a) {711; CHECK-LABEL: @fabs(712; CHECK-NEXT:    [[FNEG1:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]])713; CHECK-NEXT:    ret float [[FNEG1]]714;715  %fneg = fneg float %a716  %cmp = fcmp ogt float %a, %fneg717  %sel = select i1 %cmp, float %fneg, float %a718  %fneg1 = fneg nnan ninf nsz float %sel719  ret float %fneg1720}721 722define float @fnabs(float %a) {723; CHECK-LABEL: @fnabs(724; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]])725; CHECK-NEXT:    [[FNEG1:%.*]] = fneg fast float [[TMP1]]726; CHECK-NEXT:    ret float [[FNEG1]]727;728  %fneg = fneg float %a729  %cmp = fcmp olt float %a, %fneg730  %sel = select i1 %cmp, float %fneg, float %a731  %fneg1 = fneg fast float %sel732  ret float %fneg1733}734 735define float @fnabs_1(float %a) {736; CHECK-LABEL: @fnabs_1(737; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]])738; CHECK-NEXT:    [[FNEG1:%.*]] = fneg fast float [[TMP1]]739; CHECK-NEXT:    ret float [[FNEG1]]740;741  %fneg = fneg float %a742  %cmp = fcmp ogt float %a, %fneg743  %sel = select i1 %cmp, float %a, float %fneg744  %fneg1 = fneg fast float %sel745  ret float %fneg1746}747 748; This is not fabs because that could produce a different signbit for a NAN input.749; PR59279750 751define float @fnabs_2_nsz(float %a) {752; CHECK-LABEL: @fnabs_2_nsz(753; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[A:%.*]], 0.000000e+00754; CHECK-NEXT:    [[A_NEG:%.*]] = fneg float [[A]]755; CHECK-NEXT:    [[FNEG1:%.*]] = select nsz i1 [[CMP]], float [[A]], float [[A_NEG]]756; CHECK-NEXT:    ret float [[FNEG1]]757;758  %fneg = fneg float %a759  %cmp = fcmp olt float %a, %fneg760  %sel = select nsz i1 %cmp, float %fneg, float %a761  %fneg1 = fneg float %sel762  ret float %fneg1763}764 765define float @fnabs_2_nsz_nnan(float %a) {766; CHECK-LABEL: @fnabs_2_nsz_nnan(767; CHECK-NEXT:    [[SEL:%.*]] = call nnan nsz float @llvm.fabs.f32(float [[A:%.*]])768; CHECK-NEXT:    [[FNEG1:%.*]] = fneg float [[SEL]]769; CHECK-NEXT:    ret float [[FNEG1]]770;771  %fneg = fneg float %a772  %cmp = fcmp olt float %a, %fneg773  %sel = select nsz nnan i1 %cmp, float %fneg, float %a774  %fneg1 = fneg float %sel775  ret float %fneg1776}777 778define float @select_fneg_both(float %x, float %y, i1 %b) {779; CHECK-LABEL: @select_fneg_both(780; CHECK-NEXT:    [[S_V:%.*]] = select i1 [[B:%.*]], float [[X:%.*]], float [[Y:%.*]]781; CHECK-NEXT:    ret float [[S_V]]782;783  %nx = fneg float %x784  %ny = fneg float %y785  %s = select i1 %b, float %nx, float %ny786  %r = fneg float %s787  ret float %r788}789 790define float @select_fneg_use1(float %x, float %y, i1 %b) {791; CHECK-LABEL: @select_fneg_use1(792; CHECK-NEXT:    [[NX:%.*]] = fneg ninf float [[X:%.*]]793; CHECK-NEXT:    call void @use(float [[NX]])794; CHECK-NEXT:    [[Y_NEG:%.*]] = fneg float [[Y:%.*]]795; CHECK-NEXT:    [[R:%.*]] = select fast i1 [[B:%.*]], float [[X]], float [[Y_NEG]]796; CHECK-NEXT:    ret float [[R]]797;798  %nx = fneg ninf float %x799  call void @use(float %nx)800  %s = select fast i1 %b, float %nx, float %y801  %r = fneg float %s802  ret float %r803}804 805define float @select_fneg_use2(float %x, float %y, i1 %b) {806; CHECK-LABEL: @select_fneg_use2(807; CHECK-NEXT:    call void @use(float [[Y:%.*]])808; CHECK-NEXT:    [[Y_NEG:%.*]] = fneg fast float [[Y]]809; CHECK-NEXT:    [[R:%.*]] = select reassoc nnan ninf arcp contract afn i1 [[B:%.*]], float [[X:%.*]], float [[Y_NEG]]810; CHECK-NEXT:    ret float [[R]]811;812  call void @use(float %y)813  %nx = fneg nsz float %x814  %s = select ninf i1 %b, float %nx, float %y815  %r = fneg fast float %s816  ret float %r817}818 819; Negative test820 821define float @select_fneg_use3(float %x, float %y, i1 %b) {822; CHECK-LABEL: @select_fneg_use3(823; CHECK-NEXT:    [[NX:%.*]] = fneg float [[X:%.*]]824; CHECK-NEXT:    [[S:%.*]] = select i1 [[B:%.*]], float [[NX]], float [[Y:%.*]]825; CHECK-NEXT:    call void @use(float [[S]])826; CHECK-NEXT:    [[R:%.*]] = fneg float [[S]]827; CHECK-NEXT:    ret float [[R]]828;829  %nx = fneg float %x830  %s = select i1 %b, float %nx, float %y831  call void @use(float %s)832  %r = fneg float %s833  ret float %r834}835 836define float @fneg_ldexp(float %x, i32 %n) {837; CHECK-LABEL: @fneg_ldexp(838; CHECK-NEXT:    [[TMP1:%.*]] = fneg float [[X:%.*]]839; CHECK-NEXT:    [[NEG:%.*]] = call float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]])840; CHECK-NEXT:    ret float [[NEG]]841;842  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n)843  %neg = fneg float %ldexp844  ret float %neg845}846 847define float @fsub_fneg_ldexp(float %x, i32 %n) {848; CHECK-LABEL: @fsub_fneg_ldexp(849; CHECK-NEXT:    [[TMP1:%.*]] = fneg float [[X:%.*]]850; CHECK-NEXT:    [[NEG:%.*]] = call float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]])851; CHECK-NEXT:    ret float [[NEG]]852;853  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n)854  %neg = fsub float -0.0, %ldexp855  ret float %neg856}857 858define float @fsub_fneg_ldexp_nsz(float %x, i32 %n) {859; CHECK-LABEL: @fsub_fneg_ldexp_nsz(860; CHECK-NEXT:    [[TMP1:%.*]] = fneg nsz float [[X:%.*]]861; CHECK-NEXT:    [[NEG:%.*]] = call nsz float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]])862; CHECK-NEXT:    ret float [[NEG]]863;864  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n)865  %neg = fsub nsz float -0.0, %ldexp866  ret float %neg867}868 869define float @fsub_fneg_ldexp_p0_nsz(float %x, i32 %n) {870; CHECK-LABEL: @fsub_fneg_ldexp_p0_nsz(871; CHECK-NEXT:    [[TMP1:%.*]] = fneg nsz float [[X:%.*]]872; CHECK-NEXT:    [[NEG:%.*]] = call nsz float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]])873; CHECK-NEXT:    ret float [[NEG]]874;875  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n)876  %neg = fsub nsz float 0.0, %ldexp877  ret float %neg878}879 880define float @fsub_fneg_ldexp_p0(float %x, i32 %n) {881; CHECK-LABEL: @fsub_fneg_ldexp_p0(882; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]])883; CHECK-NEXT:    [[NEG:%.*]] = fsub float 0.000000e+00, [[LDEXP]]884; CHECK-NEXT:    ret float [[NEG]]885;886  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n)887  %neg = fsub float 0.0, %ldexp888  ret float %neg889}890 891define <2 x float> @fneg_ldexp_vector(<2 x float> %x, <2 x i32> %n) {892; CHECK-LABEL: @fneg_ldexp_vector(893; CHECK-NEXT:    [[TMP1:%.*]] = fneg <2 x float> [[X:%.*]]894; CHECK-NEXT:    [[NEG:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[TMP1]], <2 x i32> [[N:%.*]])895; CHECK-NEXT:    ret <2 x float> [[NEG]]896;897  %ldexp = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> %n)898  %neg = fneg <2 x float> %ldexp899  ret <2 x float> %neg900}901 902define float @fneg_ldexp_multiuse(float %x, i32 %n, ptr %ptr) {903; CHECK-LABEL: @fneg_ldexp_multiuse(904; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]])905; CHECK-NEXT:    store float [[LDEXP]], ptr [[PTR:%.*]], align 4906; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[LDEXP]]907; CHECK-NEXT:    ret float [[NEG]]908;909  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n)910  store float %ldexp, ptr %ptr911  %neg = fneg float %ldexp912  ret float %neg913}914 915define float @fneg_ldexp_fmf_ldexp(float %x, i32 %n) {916; CHECK-LABEL: @fneg_ldexp_fmf_ldexp(917; CHECK-NEXT:    [[TMP1:%.*]] = fneg nnan float [[X:%.*]]918; CHECK-NEXT:    [[NEG:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]])919; CHECK-NEXT:    ret float [[NEG]]920;921  %ldexp = call nnan float @llvm.ldexp.f32.i32(float %x, i32 %n)922  %neg = fneg float %ldexp923  ret float %neg924}925 926define float @fneg_ldexp_fmf_neg(float %x, i32 %n) {927; CHECK-LABEL: @fneg_ldexp_fmf_neg(928; CHECK-NEXT:    [[TMP1:%.*]] = fneg nnan float [[X:%.*]]929; CHECK-NEXT:    [[NEG:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]])930; CHECK-NEXT:    ret float [[NEG]]931;932  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n)933  %neg = fneg nnan float %ldexp934  ret float %neg935}936 937define float @fneg_ldexp_fmf(float %x, i32 %n) {938; CHECK-LABEL: @fneg_ldexp_fmf(939; CHECK-NEXT:    [[TMP1:%.*]] = fneg nnan ninf float [[X:%.*]]940; CHECK-NEXT:    [[NEG:%.*]] = call nnan ninf float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]])941; CHECK-NEXT:    ret float [[NEG]]942;943  %ldexp = call ninf float @llvm.ldexp.f32.i32(float %x, i32 %n)944  %neg = fneg nnan float %ldexp945  ret float %neg946}947 948define float @fneg_ldexp_contract0(float %x, i32 %n) {949; CHECK-LABEL: @fneg_ldexp_contract0(950; CHECK-NEXT:    [[TMP1:%.*]] = fneg contract float [[X:%.*]]951; CHECK-NEXT:    [[NEG:%.*]] = call contract float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]])952; CHECK-NEXT:    ret float [[NEG]]953;954  %ldexp = call contract float @llvm.ldexp.f32.i32(float %x, i32 %n)955  %neg = fneg float %ldexp956  ret float %neg957}958 959define float @fneg_ldexp_contract1(float %x, i32 %n) {960; CHECK-LABEL: @fneg_ldexp_contract1(961; CHECK-NEXT:    [[TMP1:%.*]] = fneg contract float [[X:%.*]]962; CHECK-NEXT:    [[NEG:%.*]] = call contract float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]])963; CHECK-NEXT:    ret float [[NEG]]964;965  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n)966  %neg = fneg contract float %ldexp967  ret float %neg968}969 970define float @fneg_ldexp_contract(float %x, i32 %n) {971; CHECK-LABEL: @fneg_ldexp_contract(972; CHECK-NEXT:    [[TMP1:%.*]] = fneg contract float [[X:%.*]]973; CHECK-NEXT:    [[NEG:%.*]] = call contract float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]])974; CHECK-NEXT:    ret float [[NEG]]975;976  %ldexp = call contract float @llvm.ldexp.f32.i32(float %x, i32 %n)977  %neg = fneg contract float %ldexp978  ret float %neg979}980 981define float @fneg_ldexp_metadata(float %x, i32 %n) {982; CHECK-LABEL: @fneg_ldexp_metadata(983; CHECK-NEXT:    [[TMP1:%.*]] = fneg float [[X:%.*]]984; CHECK-NEXT:    [[NEG:%.*]] = call float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]]), !arst [[META0:![0-9]+]]985; CHECK-NEXT:    ret float [[NEG]]986;987  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n), !arst !0988  %neg = fneg float %ldexp989  ret float %neg990}991 992define float @test_fneg_select_constants(i1 %cond) {993; CHECK-LABEL: @test_fneg_select_constants(994; CHECK-NEXT:    [[NEG:%.*]] = select i1 [[COND:%.*]], float -0.000000e+00, float 0.000000e+00995; CHECK-NEXT:    ret float [[NEG]]996;997  %sel1 = select i1 %cond, float 0.0, float -0.0998  %neg = fneg float %sel1999  ret float %neg1000}1001 1002define <2 x float> @test_fneg_vec(<2 x i1> %cond) {1003; CHECK-LABEL: @test_fneg_vec(1004; CHECK-NEXT:    [[NEG:%.*]] = select <2 x i1> [[COND:%.*]], <2 x float> <float -0.000000e+00, float 0.000000e+00>, <2 x float> <float 0.000000e+00, float -0.000000e+00>1005; CHECK-NEXT:    ret <2 x float> [[NEG]]1006;1007  %sel1 = select <2 x i1> %cond, <2 x float> <float 0.0, float -0.0>, <2 x float> <float -0.0, float 0.0>1008  %neg = fneg <2 x float> %sel11009  ret <2 x float> %neg1010}1011 1012define float @test_fneg_select_var_constant(i1 %cond, float %x) {1013; CHECK-LABEL: @test_fneg_select_var_constant(1014; CHECK-NEXT:    [[X_NEG:%.*]] = fneg float [[X:%.*]]1015; CHECK-NEXT:    [[NEG:%.*]] = select i1 [[COND:%.*]], float [[X_NEG]], float 0.000000e+001016; CHECK-NEXT:    ret float [[NEG]]1017;1018  %sel1 = select i1 %cond, float %x, float -0.01019  %neg = fneg float %sel11020  ret float %neg1021}1022 1023; nsz can be preserved.1024 1025define float @test_fneg_select_var_constant_fmf1(i1 %cond, float %x) {1026; CHECK-LABEL: @test_fneg_select_var_constant_fmf1(1027; CHECK-NEXT:    [[X_NEG:%.*]] = fneg float [[X:%.*]]1028; CHECK-NEXT:    [[NEG:%.*]] = select nnan ninf nsz i1 [[COND:%.*]], float [[X_NEG]], float -1.000000e+001029; CHECK-NEXT:    ret float [[NEG]]1030;1031  %sel1 = select nnan ninf nsz i1 %cond, float %x, float 1.01032  %neg = fneg float %sel11033  ret float %neg1034}1035 1036define float @test_fneg_select_var_constant_fmf2(i1 %cond, float %x) {1037; CHECK-LABEL: @test_fneg_select_var_constant_fmf2(1038; CHECK-NEXT:    [[X_NEG:%.*]] = fneg nnan ninf nsz float [[X:%.*]]1039; CHECK-NEXT:    [[NEG:%.*]] = select nnan ninf nsz i1 [[COND:%.*]], float [[X_NEG]], float -1.000000e+001040; CHECK-NEXT:    ret float [[NEG]]1041;1042  %sel1 = select i1 %cond, float %x, float 1.01043  %neg = fneg nnan ninf nsz float %sel11044  ret float %neg1045}1046 1047define float @test_fneg_select_constant_var(i1 %cond, float %x) {1048; CHECK-LABEL: @test_fneg_select_constant_var(1049; CHECK-NEXT:    [[X_NEG:%.*]] = fneg float [[X:%.*]]1050; CHECK-NEXT:    [[NEG:%.*]] = select i1 [[COND:%.*]], float -0.000000e+00, float [[X_NEG]]1051; CHECK-NEXT:    ret float [[NEG]]1052;1053  %sel1 = select i1 %cond, float 0.0, float %x1054  %neg = fneg float %sel11055  ret float %neg1056}1057 1058; Make sure nabs is generated.1059 1060define float @test_fneg_select_abs(i1 %cond, float %x) {1061; CHECK-LABEL: @test_fneg_select_abs(1062; CHECK-NEXT:    [[ABSX:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])1063; CHECK-NEXT:    [[ABSX_NEG:%.*]] = fneg float [[ABSX]]1064; CHECK-NEXT:    [[NEG:%.*]] = select i1 [[COND:%.*]], float -0.000000e+00, float [[ABSX_NEG]]1065; CHECK-NEXT:    ret float [[NEG]]1066;1067  %absx = call float @llvm.fabs.f32(float %x)1068  %sel1 = select i1 %cond, float 0.0, float %absx1069  %neg = fneg float %sel11070  ret float %neg1071}1072 1073define float @test_fneg_fabs_select(i1 %cond, float %x) {1074; CHECK-LABEL: @test_fneg_fabs_select(1075; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])1076; CHECK-NEXT:    [[DOTNEG:%.*]] = fneg float [[TMP1]]1077; CHECK-NEXT:    [[NEG:%.*]] = select i1 [[COND:%.*]], float -0.000000e+00, float [[DOTNEG]]1078; CHECK-NEXT:    ret float [[NEG]]1079;1080  %sel1 = select i1 %cond, float 0.0, float %x1081  %abs = call float @llvm.fabs.f32(float %sel1)1082  %neg = fneg float %abs1083  ret float %neg1084}1085 1086define float @test_fneg_select_constant_var_multiuse(i1 %cond, float %x) {1087; CHECK-LABEL: @test_fneg_select_constant_var_multiuse(1088; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[COND:%.*]], float 0.000000e+00, float [[X:%.*]]1089; CHECK-NEXT:    call void @use(float [[SEL1]])1090; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[SEL1]]1091; CHECK-NEXT:    ret float [[NEG]]1092;1093  %sel1 = select i1 %cond, float 0.0, float %x1094  call void @use(float %sel1)1095  %neg = fneg float %sel11096  ret float %neg1097}1098 1099; Don't break fmax idioms.1100 1101define float @test_fneg_select_maxnum(float %x) {1102; CHECK-LABEL: @test_fneg_select_maxnum(1103; CHECK-NEXT:    [[SEL1:%.*]] = call nsz float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)1104; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[SEL1]]1105; CHECK-NEXT:    ret float [[NEG]]1106;1107  %cmp1 = fcmp ogt float %x, 1.01108  %sel1 = select nnan nsz i1 %cmp1, float %x, float 1.01109  %neg = fneg float %sel11110  ret float %neg1111}1112 1113; Check that there's no infinite loop.1114define <vscale x 2 x double> @test_fneg_select_svec(<vscale x 2 x i1> %cond, <vscale x 2 x double> %b) {1115; CHECK-LABEL: @test_fneg_select_svec(1116; CHECK-NEXT:    [[TMP2:%.*]] = fneg fast <vscale x 2 x double> [[TMP1:%.*]]1117; CHECK-NEXT:    [[TMP3:%.*]] = select fast <vscale x 2 x i1> [[COND:%.*]], <vscale x 2 x double> splat (double -0.000000e+00), <vscale x 2 x double> [[TMP2]]1118; CHECK-NEXT:    ret <vscale x 2 x double> [[TMP3]]1119;1120  %1 = select <vscale x 2 x i1> %cond, <vscale x 2 x double> zeroinitializer, <vscale x 2 x double> %b1121  %2 = fneg fast <vscale x 2 x double> %11122  ret <vscale x 2 x double> %21123}1124 1125define <vscale x 2 x double> @test_fneg_select_svec_2(<vscale x 2 x i1> %cond, <vscale x 2 x double> %a) {1126; CHECK-LABEL: @test_fneg_select_svec_2(1127; CHECK-NEXT:    [[A_NEG:%.*]] = fneg fast <vscale x 2 x double> [[A:%.*]]1128; CHECK-NEXT:    [[TMP1:%.*]] = select fast <vscale x 2 x i1> [[COND:%.*]], <vscale x 2 x double> [[A_NEG]], <vscale x 2 x double> splat (double -0.000000e+00)1129; CHECK-NEXT:    ret <vscale x 2 x double> [[TMP1]]1130;1131  %1 = select <vscale x 2 x i1> %cond, <vscale x 2 x double> %a, <vscale x 2 x double> zeroinitializer1132  %2 = fneg fast <vscale x 2 x double> %11133  ret <vscale x 2 x double> %21134}1135 1136define <vscale x 2 x double> @test_fneg_select_svec_3(<vscale x 2 x i1> %cond, <vscale x 2 x double> %b) {1137; CHECK-LABEL: @test_fneg_select_svec_3(1138; CHECK-NEXT:    ret <vscale x 2 x double> splat (double -0.000000e+00)1139;1140  %1 = select <vscale x 2 x i1> %cond, <vscale x 2 x double> zeroinitializer, <vscale x 2 x double> zeroinitializer1141  %2 = fneg fast <vscale x 2 x double> %11142  ret <vscale x 2 x double> %21143}1144 1145define float @test_fneg_ninf_mul_with_anyzero(float %a) {1146; CHECK-LABEL: @test_fneg_ninf_mul_with_anyzero(1147; CHECK-NEXT:    [[F:%.*]] = fmul float [[A:%.*]], -0.000000e+001148; CHECK-NEXT:    ret float [[F]]1149;1150  %mul = fmul float %a, 0.01151  %f = fneg ninf float %mul1152  ret float %f1153}1154 1155define float @test_fsub_ninf_mul_with_anyzero(float %a) {1156; CHECK-LABEL: @test_fsub_ninf_mul_with_anyzero(1157; CHECK-NEXT:    [[F2:%.*]] = fmul nsz float [[A:%.*]], -0.000000e+001158; CHECK-NEXT:    ret float [[F2]]1159;1160  %f1 = fmul nsz float %a, 0.0000001161  %f2 = fsub ninf float -0.000000, %f11162  ret float %f21163}1164 1165define float @test_fneg_nnan_mul_with_anyzero(float %a) {1166; CHECK-LABEL: @test_fneg_nnan_mul_with_anyzero(1167; CHECK-NEXT:    [[TMP1:%.*]] = fneg nnan float [[A:%.*]]1168; CHECK-NEXT:    [[F2:%.*]] = call nnan float @llvm.copysign.f32(float 0.000000e+00, float [[TMP1]])1169; CHECK-NEXT:    ret float [[F2]]1170;1171  %f1 = fmul ninf float %a, 0.0000001172  %f2 = fneg nnan float %f11173  ret float %f21174}1175 1176define float @test_fneg_nsz_mul_with_anyzero(float %a) {1177; CHECK-LABEL: @test_fneg_nsz_mul_with_anyzero(1178; CHECK-NEXT:    [[F2:%.*]] = fmul nsz float [[A:%.*]], -0.000000e+001179; CHECK-NEXT:    ret float [[F2]]1180;1181  %f1 = fmul ninf float %a, 0.0000001182  %f2 = fneg nsz float %f11183  ret float %f21184}1185 1186define float @test_fneg_ninf_mul_nnan_with_const(float %a) {1187; CHECK-LABEL: @test_fneg_ninf_mul_nnan_with_const(1188; CHECK-NEXT:    [[TMP1:%.*]] = fneg float [[A:%.*]]1189; CHECK-NEXT:    [[F2:%.*]] = call float @llvm.copysign.f32(float 0.000000e+00, float [[TMP1]])1190; CHECK-NEXT:    ret float [[F2]]1191;1192  %f1 = fmul nnan float %a, 0.0000001193  %f2 = fneg ninf float %f11194  ret float %f21195}1196 1197define float @test_fneg_ninf_mul_nsz_with_const(float %a) {1198; CHECK-LABEL: @test_fneg_ninf_mul_nsz_with_const(1199; CHECK-NEXT:    [[F2:%.*]] = fmul nsz float [[A:%.*]], -0.000000e+001200; CHECK-NEXT:    ret float [[F2]]1201;1202  %f1 = fmul nsz float %a, 0.0000001203  %f2 = fneg ninf float %f11204  ret float %f21205}1206 1207define <2 x float> @test_fneg_mul_combine_nnan_ninf_with_vec_const(<2 x float> %a) {1208; CHECK-LABEL: @test_fneg_mul_combine_nnan_ninf_with_vec_const(1209; CHECK-NEXT:    [[F2:%.*]] = fmul nnan <2 x float> [[A:%.*]], <float -0.000000e+00, float 0.000000e+00>1210; CHECK-NEXT:    ret <2 x float> [[F2]]1211;1212  %f1 = fmul nnan <2 x float> %a, <float 0.000000, float -0.000000>1213  %f2 = fneg ninf <2 x float> %f11214  ret <2 x float> %f21215}1216 1217define <2 x float> @test_fneg_mul_combine_nsz_ninf_with_vec_const(<2 x float> %a) {1218; CHECK-LABEL: @test_fneg_mul_combine_nsz_ninf_with_vec_const(1219; CHECK-NEXT:    [[F2:%.*]] = fmul nsz <2 x float> [[A:%.*]], <float -0.000000e+00, float 0.000000e+00>1220; CHECK-NEXT:    ret <2 x float> [[F2]]1221;1222  %f1 = fmul nsz <2 x float> %a, <float 0.000000, float -0.000000>1223  %f2 = fneg ninf <2 x float> %f11224  ret <2 x float> %f21225}1226 1227define <2 x float> @test_fneg_ninf_nnan_mul_with_vec_const(<2 x float> %a) {1228; CHECK-LABEL: @test_fneg_ninf_nnan_mul_with_vec_const(1229; CHECK-NEXT:    [[F2:%.*]] = fmul nnan <2 x float> [[A:%.*]], <float -0.000000e+00, float 0.000000e+00>1230; CHECK-NEXT:    ret <2 x float> [[F2]]1231;1232  %f1 = fmul <2 x float> %a, <float 0.000000, float -0.000000>1233  %f2 = fneg nnan ninf <2 x float> %f11234  ret <2 x float> %f21235}1236 1237define <2 x float> @test_fneg_mul_combine_nnan_ninf_with_vec_const2(<2 x float> %a) {1238; CHECK-LABEL: @test_fneg_mul_combine_nnan_ninf_with_vec_const2(1239; CHECK-NEXT:    [[F2:%.*]] = fmul nnan ninf <2 x float> [[A:%.*]], <float -0.000000e+00, float 0.000000e+00>1240; CHECK-NEXT:    ret <2 x float> [[F2]]1241;1242  %f1 = fmul ninf <2 x float> %a, <float 0.000000, float -0.000000>1243  %f2 = fneg nnan ninf <2 x float> %f11244  ret <2 x float> %f21245}1246 1247define <2 x float> @test_fneg_mul_combine_reassoc_ninf_with_vec_const1(<2 x float> %a) {1248; CHECK-LABEL: @test_fneg_mul_combine_reassoc_ninf_with_vec_const1(1249; CHECK-NEXT:    [[F2:%.*]] = fmul <2 x float> [[A:%.*]], <float -0.000000e+00, float 0.000000e+00>1250; CHECK-NEXT:    ret <2 x float> [[F2]]1251;1252  %f1 = fmul reassoc <2 x float> %a, <float 0.000000, float -0.000000>1253  %f2 = fneg ninf <2 x float> %f11254  ret <2 x float> %f21255}1256 1257define <2 x float> @test_fneg_mul_combine_reassoc_ninf_with_vec_const2(<2 x float> %a) {1258; CHECK-LABEL: @test_fneg_mul_combine_reassoc_ninf_with_vec_const2(1259; CHECK-NEXT:    [[F2:%.*]] = fmul ninf <2 x float> [[A:%.*]], <float -0.000000e+00, float 0.000000e+00>1260; CHECK-NEXT:    ret <2 x float> [[F2]]1261;1262  %f1 = fmul ninf <2 x float> %a, <float 0.000000, float -0.000000>1263  %f2 = fneg reassoc ninf <2 x float> %f11264  ret <2 x float> %f21265}1266 1267define <2 x float> @test_fneg_mul_combine_reassoc_ninf_with_vec_const3(<2 x float> %a) {1268; CHECK-LABEL: @test_fneg_mul_combine_reassoc_ninf_with_vec_const3(1269; CHECK-NEXT:    [[F2:%.*]] = fmul reassoc <2 x float> [[A:%.*]], <float -0.000000e+00, float 0.000000e+00>1270; CHECK-NEXT:    ret <2 x float> [[F2]]1271;1272  %f1 = fmul reassoc <2 x float> %a, <float 0.000000, float -0.000000>1273  %f2 = fneg reassoc ninf <2 x float> %f11274  ret <2 x float> %f21275}1276 1277define <2 x float> @test_fneg_mul_combine_contract_ninf_with_vec_const1(<2 x float> %a) {1278; CHECK-LABEL: @test_fneg_mul_combine_contract_ninf_with_vec_const1(1279; CHECK-NEXT:    [[F2:%.*]] = fmul <2 x float> [[A:%.*]], <float -0.000000e+00, float 0.000000e+00>1280; CHECK-NEXT:    ret <2 x float> [[F2]]1281;1282  %f1 = fmul contract <2 x float> %a, <float 0.000000, float -0.000000>1283  %f2 = fneg ninf <2 x float> %f11284  ret <2 x float> %f21285}1286 1287define <2 x float> @test_fneg_mul_combine_contract_ninf_with_vec_const2(<2 x float> %a) {1288; CHECK-LABEL: @test_fneg_mul_combine_contract_ninf_with_vec_const2(1289; CHECK-NEXT:    [[F2:%.*]] = fmul ninf <2 x float> [[A:%.*]], <float -0.000000e+00, float 0.000000e+00>1290; CHECK-NEXT:    ret <2 x float> [[F2]]1291;1292  %f1 = fmul ninf <2 x float> %a, <float 0.000000, float -0.000000>1293  %f2 = fneg contract ninf <2 x float> %f11294  ret <2 x float> %f21295}1296 1297define <2 x float> @test_fneg_mul_combine_contract_ninf_with_vec_const3(<2 x float> %a) {1298; CHECK-LABEL: @test_fneg_mul_combine_contract_ninf_with_vec_const3(1299; CHECK-NEXT:    [[F2:%.*]] = fmul contract <2 x float> [[A:%.*]], <float -0.000000e+00, float 0.000000e+00>1300; CHECK-NEXT:    ret <2 x float> [[F2]]1301;1302  %f1 = fmul contract <2 x float> %a, <float 0.000000, float -0.000000>1303  %f2 = fneg contract ninf <2 x float> %f11304  ret <2 x float> %f21305}1306 1307!0 = !{}1308