brintos

brintos / llvm-project-archived public Read only

0
0
Text · 36.8 KiB · 54b0bf8 Raw
1068 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.fabs.f32(float) nounwind readnone6declare float @llvm.pow.f32(float, float) nounwind readnone7declare <2 x half> @llvm.pow.v2f16(<2 x half>, <2 x half>) nounwind readnone8declare float @llvm.exp.f32(float) nounwind readnone9declare <2 x half> @llvm.exp.v2f16(<2 x half>) nounwind readnone10declare float @llvm.exp2.f32(float) nounwind readnone11declare <2 x half> @llvm.exp2.v2f16(<2 x half>) nounwind readnone12declare float @llvm.powi.f32.i32(float, i32) nounwind readnone13declare <2 x half> @llvm.powi.v2f16.i32(<2 x half>, i32) nounwind readnone14 15define float @exact_inverse(float %x) {16; CHECK-LABEL: @exact_inverse(17; CHECK-NEXT:    [[DIV:%.*]] = fmul float [[X:%.*]], 1.250000e-0118; CHECK-NEXT:    ret float [[DIV]]19;20  %div = fdiv float %x, 8.021  ret float %div22}23 24; Min normal float = 1.17549435E-3825 26define float @exact_inverse2(float %x) {27; CHECK-LABEL: @exact_inverse2(28; CHECK-NEXT:    [[DIV:%.*]] = fmul float [[X:%.*]], 0x47D000000000000029; CHECK-NEXT:    ret float [[DIV]]30;31  %div = fdiv float %x, 0x381000000000000032  ret float %div33}34 35; Max exponent = 1.70141183E+38; don't transform to multiply with denormal.36 37define float @exact_inverse_but_denorm(float %x) {38; CHECK-LABEL: @exact_inverse_but_denorm(39; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[X:%.*]], 0x47E000000000000040; CHECK-NEXT:    ret float [[DIV]]41;42  %div = fdiv float %x, 0x47E000000000000043  ret float %div44}45 46; Denormal = float 1.40129846E-45; inverse can't be represented.47 48define float @not_exact_inverse2(float %x) {49; CHECK-LABEL: @not_exact_inverse2(50; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[X:%.*]], 0x36A000000000000051; CHECK-NEXT:    ret float [[DIV]]52;53  %div = fdiv float %x, 0x36A000000000000054  ret float %div55}56 57; Fast math allows us to replace this fdiv.58 59define float @not_exact_but_allow_recip(float %x) {60; CHECK-LABEL: @not_exact_but_allow_recip(61; CHECK-NEXT:    [[DIV:%.*]] = fmul arcp float [[X:%.*]], 0x3FD555556000000062; CHECK-NEXT:    ret float [[DIV]]63;64  %div = fdiv arcp float %x, 3.065  ret float %div66}67 68; Fast math allows us to replace this fdiv, but we don't to avoid a denormal.69; TODO: What if the function attributes tell us that denormals are flushed?70 71define float @not_exact_but_allow_recip_but_denorm(float %x) {72; CHECK-LABEL: @not_exact_but_allow_recip_but_denorm(73; CHECK-NEXT:    [[DIV:%.*]] = fdiv arcp float [[X:%.*]], 0x47E000010000000074; CHECK-NEXT:    ret float [[DIV]]75;76  %div = fdiv arcp float %x, 0x47E000010000000077  ret float %div78}79 80define <2 x float> @exact_inverse_splat(<2 x float> %x) {81; CHECK-LABEL: @exact_inverse_splat(82; CHECK-NEXT:    [[DIV:%.*]] = fmul <2 x float> [[X:%.*]], splat (float 2.500000e-01)83; CHECK-NEXT:    ret <2 x float> [[DIV]]84;85  %div = fdiv <2 x float> %x, <float 4.0, float 4.0>86  ret <2 x float> %div87}88 89define <vscale x 2 x float> @exact_inverse_scalable_splat(<vscale x 2 x float> %x) {90; CHECK-LABEL: @exact_inverse_scalable_splat(91; CHECK-NEXT:    [[DIV:%.*]] = fmul <vscale x 2 x float> [[X:%.*]], splat (float 2.500000e-01)92; CHECK-NEXT:    ret <vscale x 2 x float> [[DIV]]93;94  %div = fdiv <vscale x 2 x float> %x, splat (float 4.0)95  ret <vscale x 2 x float> %div96}97 98; Fast math allows us to replace this fdiv.99 100define <2 x float> @not_exact_but_allow_recip_splat(<2 x float> %x) {101; CHECK-LABEL: @not_exact_but_allow_recip_splat(102; CHECK-NEXT:    [[DIV:%.*]] = fmul arcp <2 x float> [[X:%.*]], splat (float 0x3FD5555560000000)103; CHECK-NEXT:    ret <2 x float> [[DIV]]104;105  %div = fdiv arcp <2 x float> %x, <float 3.0, float 3.0>106  ret <2 x float> %div107}108 109define <2 x float> @exact_inverse_vec(<2 x float> %x) {110; CHECK-LABEL: @exact_inverse_vec(111; CHECK-NEXT:    [[DIV:%.*]] = fmul <2 x float> [[X:%.*]], <float 2.500000e-01, float 1.250000e-01>112; CHECK-NEXT:    ret <2 x float> [[DIV]]113;114  %div = fdiv <2 x float> %x, <float 4.0, float 8.0>115  ret <2 x float> %div116}117 118define <2 x float> @not_exact_inverse_splat(<2 x float> %x) {119; CHECK-LABEL: @not_exact_inverse_splat(120; CHECK-NEXT:    [[DIV:%.*]] = fdiv <2 x float> [[X:%.*]], splat (float 3.000000e+00)121; CHECK-NEXT:    ret <2 x float> [[DIV]]122;123  %div = fdiv <2 x float> %x, <float 3.0, float 3.0>124  ret <2 x float> %div125}126 127define <2 x float> @not_exact_inverse_vec(<2 x float> %x) {128; CHECK-LABEL: @not_exact_inverse_vec(129; CHECK-NEXT:    [[DIV:%.*]] = fdiv <2 x float> [[X:%.*]], <float 4.000000e+00, float 3.000000e+00>130; CHECK-NEXT:    ret <2 x float> [[DIV]]131;132  %div = fdiv <2 x float> %x, <float 4.0, float 3.0>133  ret <2 x float> %div134}135 136define <2 x float> @not_exact_inverse_vec_arcp(<2 x float> %x) {137; CHECK-LABEL: @not_exact_inverse_vec_arcp(138; CHECK-NEXT:    [[DIV:%.*]] = fmul arcp <2 x float> [[X:%.*]], <float 2.500000e-01, float 0x3FD5555560000000>139; CHECK-NEXT:    ret <2 x float> [[DIV]]140;141  %div = fdiv arcp <2 x float> %x, <float 4.0, float 3.0>142  ret <2 x float> %div143}144 145define <2 x float> @not_exact_inverse_vec_arcp_with_poison_elt(<2 x float> %x) {146; CHECK-LABEL: @not_exact_inverse_vec_arcp_with_poison_elt(147; CHECK-NEXT:    [[DIV:%.*]] = fdiv arcp <2 x float> [[X:%.*]], <float poison, float 3.000000e+00>148; CHECK-NEXT:    ret <2 x float> [[DIV]]149;150  %div = fdiv arcp <2 x float> %x, <float poison, float 3.0>151  ret <2 x float> %div152}153 154; (X / Y) / Z --> X / (Y * Z)155 156define float @div_with_div_numerator(float %x, float %y, float %z) {157; CHECK-LABEL: @div_with_div_numerator(158; CHECK-NEXT:    [[TMP1:%.*]] = fmul reassoc arcp float [[Y:%.*]], [[Z:%.*]]159; CHECK-NEXT:    [[DIV2:%.*]] = fdiv reassoc arcp float [[X:%.*]], [[TMP1]]160; CHECK-NEXT:    ret float [[DIV2]]161;162  %div1 = fdiv ninf float %x, %y163  %div2 = fdiv arcp reassoc float %div1, %z164  ret float %div2165}166 167; Z / (X / Y) --> (Z * Y) / X168 169define <2 x float> @div_with_div_denominator(<2 x float> %x, <2 x float> %y, <2 x float> %z) {170; CHECK-LABEL: @div_with_div_denominator(171; CHECK-NEXT:    [[TMP1:%.*]] = fmul reassoc arcp <2 x float> [[Y:%.*]], [[Z:%.*]]172; CHECK-NEXT:    [[DIV2:%.*]] = fdiv reassoc arcp <2 x float> [[TMP1]], [[X:%.*]]173; CHECK-NEXT:    ret <2 x float> [[DIV2]]174;175  %div1 = fdiv nnan <2 x float> %x, %y176  %div2 = fdiv arcp reassoc <2 x float> %z, %div1177  ret <2 x float> %div2178}179 180; Don't create an extra multiply if we can't eliminate the first div.181 182declare void @use_f32(float)183 184define float @div_with_div_numerator_extra_use(float %x, float %y, float %z) {185; CHECK-LABEL: @div_with_div_numerator_extra_use(186; CHECK-NEXT:    [[DIV1:%.*]] = fdiv float [[X:%.*]], [[Y:%.*]]187; CHECK-NEXT:    [[DIV2:%.*]] = fdiv fast float [[DIV1]], [[Z:%.*]]188; CHECK-NEXT:    call void @use_f32(float [[DIV1]])189; CHECK-NEXT:    ret float [[DIV2]]190;191  %div1 = fdiv float %x, %y192  %div2 = fdiv fast float %div1, %z193  call void @use_f32(float %div1)194  ret float %div2195}196 197define float @div_with_div_denominator_extra_use(float %x, float %y, float %z) {198; CHECK-LABEL: @div_with_div_denominator_extra_use(199; CHECK-NEXT:    [[DIV1:%.*]] = fdiv float [[X:%.*]], [[Y:%.*]]200; CHECK-NEXT:    [[DIV2:%.*]] = fdiv fast float [[Z:%.*]], [[DIV1]]201; CHECK-NEXT:    call void @use_f32(float [[DIV1]])202; CHECK-NEXT:    ret float [[DIV2]]203;204  %div1 = fdiv float %x, %y205  %div2 = fdiv fast float %z, %div1206  call void @use_f32(float %div1)207  ret float %div2208}209 210; Z / (1.0 / Y) ==> Y * Z211 212define float @div_with_div_denominator_with_one_as_numerator_extra_use(float %x, float %y, float %z) {213; CHECK-LABEL: @div_with_div_denominator_with_one_as_numerator_extra_use(214; CHECK-NEXT:    [[DIV1:%.*]] = fdiv float 1.000000e+00, [[Y:%.*]]215; CHECK-NEXT:    [[DIV2:%.*]] = fmul reassoc arcp float [[Y]], [[Z:%.*]]216; CHECK-NEXT:    call void @use_f32(float [[DIV1]])217; CHECK-NEXT:    ret float [[DIV2]]218;219  %div1 = fdiv float 1.0, %y220  %div2 = fdiv reassoc arcp float %z, %div1221  call void @use_f32(float %div1)222  ret float %div2223}224 225define float @fneg_fneg(float %x, float %y) {226; CHECK-LABEL: @fneg_fneg(227; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[X:%.*]], [[Y:%.*]]228; CHECK-NEXT:    ret float [[DIV]]229;230  %x.fneg = fsub float -0.0, %x231  %y.fneg = fsub float -0.0, %y232  %div = fdiv float %x.fneg, %y.fneg233  ret float %div234}235 236define float @unary_fneg_unary_fneg(float %x, float %y) {237; CHECK-LABEL: @unary_fneg_unary_fneg(238; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[X:%.*]], [[Y:%.*]]239; CHECK-NEXT:    ret float [[DIV]]240;241  %x.fneg = fneg float %x242  %y.fneg = fneg float %y243  %div = fdiv float %x.fneg, %y.fneg244  ret float %div245}246 247define float @unary_fneg_fneg(float %x, float %y) {248; CHECK-LABEL: @unary_fneg_fneg(249; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[X:%.*]], [[Y:%.*]]250; CHECK-NEXT:    ret float [[DIV]]251;252  %x.fneg = fneg float %x253  %y.fneg = fsub float -0.0, %y254  %div = fdiv float %x.fneg, %y.fneg255  ret float %div256}257 258define float @fneg_unary_fneg(float %x, float %y) {259; CHECK-LABEL: @fneg_unary_fneg(260; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[X:%.*]], [[Y:%.*]]261; CHECK-NEXT:    ret float [[DIV]]262;263  %x.fneg = fsub float -0.0, %x264  %y.fneg = fneg float %y265  %div = fdiv float %x.fneg, %y.fneg266  ret float %div267}268 269; The test above shows that no FMF are needed, but show that we are not dropping FMF.270 271define float @fneg_fneg_fast(float %x, float %y) {272; CHECK-LABEL: @fneg_fneg_fast(273; CHECK-NEXT:    [[DIV:%.*]] = fdiv fast float [[X:%.*]], [[Y:%.*]]274; CHECK-NEXT:    ret float [[DIV]]275;276  %x.fneg = fsub float -0.0, %x277  %y.fneg = fsub float -0.0, %y278  %div = fdiv fast float %x.fneg, %y.fneg279  ret float %div280}281 282define float @unary_fneg_unary_fneg_fast(float %x, float %y) {283; CHECK-LABEL: @unary_fneg_unary_fneg_fast(284; CHECK-NEXT:    [[DIV:%.*]] = fdiv fast float [[X:%.*]], [[Y:%.*]]285; CHECK-NEXT:    ret float [[DIV]]286;287  %x.fneg = fneg float %x288  %y.fneg = fneg float %y289  %div = fdiv fast float %x.fneg, %y.fneg290  ret float %div291}292 293define <2 x float> @fneg_fneg_vec(<2 x float> %x, <2 x float> %y) {294; CHECK-LABEL: @fneg_fneg_vec(295; CHECK-NEXT:    [[DIV:%.*]] = fdiv <2 x float> [[X:%.*]], [[Y:%.*]]296; CHECK-NEXT:    ret <2 x float> [[DIV]]297;298  %xneg = fsub <2 x float> <float -0.0, float -0.0>, %x299  %yneg = fsub <2 x float> <float -0.0, float -0.0>, %y300  %div = fdiv <2 x float> %xneg, %yneg301  ret <2 x float> %div302}303 304define <2 x float> @unary_fneg_unary_fneg_vec(<2 x float> %x, <2 x float> %y) {305; CHECK-LABEL: @unary_fneg_unary_fneg_vec(306; CHECK-NEXT:    [[DIV:%.*]] = fdiv <2 x float> [[X:%.*]], [[Y:%.*]]307; CHECK-NEXT:    ret <2 x float> [[DIV]]308;309  %xneg = fneg <2 x float> %x310  %yneg = fneg <2 x float> %y311  %div = fdiv <2 x float> %xneg, %yneg312  ret <2 x float> %div313}314 315define <2 x float> @fneg_unary_fneg_vec(<2 x float> %x, <2 x float> %y) {316; CHECK-LABEL: @fneg_unary_fneg_vec(317; CHECK-NEXT:    [[DIV:%.*]] = fdiv <2 x float> [[X:%.*]], [[Y:%.*]]318; CHECK-NEXT:    ret <2 x float> [[DIV]]319;320  %xneg = fsub <2 x float> <float -0.0, float -0.0>, %x321  %yneg = fneg <2 x float> %y322  %div = fdiv <2 x float> %xneg, %yneg323  ret <2 x float> %div324}325 326define <2 x float> @unary_fneg_fneg_vec(<2 x float> %x, <2 x float> %y) {327; CHECK-LABEL: @unary_fneg_fneg_vec(328; CHECK-NEXT:    [[DIV:%.*]] = fdiv <2 x float> [[X:%.*]], [[Y:%.*]]329; CHECK-NEXT:    ret <2 x float> [[DIV]]330;331  %xneg = fneg <2 x float> %x332  %yneg = fsub <2 x float> <float -0.0, float -0.0>, %y333  %div = fdiv <2 x float> %xneg, %yneg334  ret <2 x float> %div335}336 337define <2 x float> @fneg_fneg_vec_poison_elts(<2 x float> %x, <2 x float> %y) {338; CHECK-LABEL: @fneg_fneg_vec_poison_elts(339; CHECK-NEXT:    [[DIV:%.*]] = fdiv <2 x float> [[X:%.*]], [[Y:%.*]]340; CHECK-NEXT:    ret <2 x float> [[DIV]]341;342  %xneg = fsub <2 x float> <float poison, float -0.0>, %x343  %yneg = fsub <2 x float> <float -0.0, float poison>, %y344  %div = fdiv <2 x float> %xneg, %yneg345  ret <2 x float> %div346}347 348define float @fneg_dividend_constant_divisor(float %x) {349; CHECK-LABEL: @fneg_dividend_constant_divisor(350; CHECK-NEXT:    [[DIV:%.*]] = fdiv nsz float [[X:%.*]], -3.000000e+00351; CHECK-NEXT:    ret float [[DIV]]352;353  %neg = fsub float -0.0, %x354  %div = fdiv nsz float %neg, 3.0355  ret  float %div356}357 358define float @unary_fneg_dividend_constant_divisor(float %x) {359; CHECK-LABEL: @unary_fneg_dividend_constant_divisor(360; CHECK-NEXT:    [[DIV:%.*]] = fdiv nsz float [[X:%.*]], -3.000000e+00361; CHECK-NEXT:    ret float [[DIV]]362;363  %neg = fneg float %x364  %div = fdiv nsz float %neg, 3.0365  ret  float %div366}367 368define float @fneg_divisor_constant_dividend(float %x) {369; CHECK-LABEL: @fneg_divisor_constant_dividend(370; CHECK-NEXT:    [[DIV:%.*]] = fdiv nnan float 3.000000e+00, [[X:%.*]]371; CHECK-NEXT:    ret float [[DIV]]372;373  %neg = fsub float -0.0, %x374  %div = fdiv nnan float -3.0, %neg375  ret float %div376}377 378define float @unary_fneg_divisor_constant_dividend(float %x) {379; CHECK-LABEL: @unary_fneg_divisor_constant_dividend(380; CHECK-NEXT:    [[DIV:%.*]] = fdiv nnan float 3.000000e+00, [[X:%.*]]381; CHECK-NEXT:    ret float [[DIV]]382;383  %neg = fneg float %x384  %div = fdiv nnan float -3.0, %neg385  ret float %div386}387 388define <2 x float> @fneg_dividend_constant_divisor_vec(<2 x float> %x) {389; CHECK-LABEL: @fneg_dividend_constant_divisor_vec(390; CHECK-NEXT:    [[DIV:%.*]] = fdiv ninf <2 x float> [[X:%.*]], <float -3.000000e+00, float 8.000000e+00>391; CHECK-NEXT:    ret <2 x float> [[DIV]]392;393  %neg = fsub <2 x float> <float -0.0, float -0.0>, %x394  %div = fdiv ninf <2 x float> %neg, <float 3.0, float -8.0>395  ret <2 x float> %div396}397 398define <2 x float> @unary_fneg_dividend_constant_divisor_vec(<2 x float> %x) {399; CHECK-LABEL: @unary_fneg_dividend_constant_divisor_vec(400; CHECK-NEXT:    [[DIV:%.*]] = fdiv ninf <2 x float> [[X:%.*]], <float -3.000000e+00, float 8.000000e+00>401; CHECK-NEXT:    ret <2 x float> [[DIV]]402;403  %neg = fneg <2 x float> %x404  %div = fdiv ninf <2 x float> %neg, <float 3.0, float -8.0>405  ret <2 x float> %div406}407 408define <2 x float> @fneg_dividend_constant_divisor_vec_poison_elt(<2 x float> %x) {409; CHECK-LABEL: @fneg_dividend_constant_divisor_vec_poison_elt(410; CHECK-NEXT:    [[DIV:%.*]] = fdiv ninf <2 x float> [[X:%.*]], <float -3.000000e+00, float 8.000000e+00>411; CHECK-NEXT:    ret <2 x float> [[DIV]]412;413  %neg = fsub <2 x float> <float poison, float -0.0>, %x414  %div = fdiv ninf <2 x float> %neg, <float 3.0, float -8.0>415  ret <2 x float> %div416}417 418define <2 x float> @fneg_divisor_constant_dividend_vec(<2 x float> %x) {419; CHECK-LABEL: @fneg_divisor_constant_dividend_vec(420; CHECK-NEXT:    [[DIV:%.*]] = fdiv afn <2 x float> <float 3.000000e+00, float -5.000000e+00>, [[X:%.*]]421; CHECK-NEXT:    ret <2 x float> [[DIV]]422;423  %neg = fsub <2 x float> <float -0.0, float -0.0>, %x424  %div = fdiv afn <2 x float> <float -3.0, float 5.0>, %neg425  ret <2 x float> %div426}427 428define <2 x float> @unary_fneg_divisor_constant_dividend_vec(<2 x float> %x) {429; CHECK-LABEL: @unary_fneg_divisor_constant_dividend_vec(430; CHECK-NEXT:    [[DIV:%.*]] = fdiv afn <2 x float> <float 3.000000e+00, float -5.000000e+00>, [[X:%.*]]431; CHECK-NEXT:    ret <2 x float> [[DIV]]432;433  %neg = fneg <2 x float> %x434  %div = fdiv afn <2 x float> <float -3.0, float 5.0>, %neg435  ret <2 x float> %div436}437 438 439; X / (X * Y) --> 1.0 / Y440 441define float @div_factor(float %x, float %y) {442; CHECK-LABEL: @div_factor(443; CHECK-NEXT:    [[D:%.*]] = fdiv reassoc nnan float 1.000000e+00, [[Y:%.*]]444; CHECK-NEXT:    ret float [[D]]445;446  %m = fmul float %x, %y447  %d = fdiv nnan reassoc float %x, %m448  ret float %d;449}450 451; We can't do the transform without 'nnan' because if x is NAN and y is a number, this should return NAN.452 453define float @div_factor_too_strict(float %x, float %y) {454; CHECK-LABEL: @div_factor_too_strict(455; CHECK-NEXT:    [[M:%.*]] = fmul float [[X:%.*]], [[Y:%.*]]456; CHECK-NEXT:    [[D:%.*]] = fdiv reassoc float [[X]], [[M]]457; CHECK-NEXT:    ret float [[D]]458;459  %m = fmul float %x, %y460  %d = fdiv reassoc float %x, %m461  ret float %d462}463 464; Commute, verify vector types, and show that we are not dropping extra FMF.465; X / (Y * X) --> 1.0 / Y466 467define <2 x float> @div_factor_commute(<2 x float> %x, <2 x float> %y) {468; CHECK-LABEL: @div_factor_commute(469; CHECK-NEXT:    [[D:%.*]] = fdiv reassoc nnan ninf nsz <2 x float> splat (float 1.000000e+00), [[Y:%.*]]470; CHECK-NEXT:    ret <2 x float> [[D]]471;472  %m = fmul <2 x float> %y, %x473  %d = fdiv nnan ninf nsz reassoc <2 x float> %x, %m474  ret <2 x float> %d475}476 477; C1/(X*C2) => (C1/C2) / X478 479define <2 x float> @div_constant_dividend1(<2 x float> %x) {480; CHECK-LABEL: @div_constant_dividend1(481; CHECK-NEXT:    [[T2:%.*]] = fdiv reassoc arcp <2 x float> <float 5.000000e+00, float 1.000000e+00>, [[X:%.*]]482; CHECK-NEXT:    ret <2 x float> [[T2]]483;484  %t1 = fmul <2 x float> %x, <float 3.0e0, float 7.0e0>485  %t2 = fdiv arcp reassoc <2 x float> <float 15.0e0, float 7.0e0>, %t1486  ret <2 x float> %t2487}488 489define <2 x float> @div_constant_dividend1_arcp_only(<2 x float> %x) {490; CHECK-LABEL: @div_constant_dividend1_arcp_only(491; CHECK-NEXT:    [[T1:%.*]] = fmul <2 x float> [[X:%.*]], <float 3.000000e+00, float 7.000000e+00>492; CHECK-NEXT:    [[T2:%.*]] = fdiv arcp <2 x float> <float 1.500000e+01, float 7.000000e+00>, [[T1]]493; CHECK-NEXT:    ret <2 x float> [[T2]]494;495  %t1 = fmul <2 x float> %x, <float 3.0e0, float 7.0e0>496  %t2 = fdiv arcp <2 x float> <float 15.0e0, float 7.0e0>, %t1497  ret <2 x float> %t2498}499 500; C1/(X/C2) => (C1*C2) / X501 502define <2 x float> @div_constant_dividend2(<2 x float> %x) {503; CHECK-LABEL: @div_constant_dividend2(504; CHECK-NEXT:    [[T2:%.*]] = fdiv reassoc arcp <2 x float> <float 4.500000e+01, float 4.900000e+01>, [[X:%.*]]505; CHECK-NEXT:    ret <2 x float> [[T2]]506;507  %t1 = fdiv <2 x float> %x, <float 3.0e0, float -7.0e0>508  %t2 = fdiv arcp reassoc <2 x float> <float 15.0e0, float -7.0e0>, %t1509  ret <2 x float> %t2510}511 512define <2 x float> @div_constant_dividend2_reassoc_only(<2 x float> %x) {513; CHECK-LABEL: @div_constant_dividend2_reassoc_only(514; CHECK-NEXT:    [[T1:%.*]] = fdiv <2 x float> [[X:%.*]], <float 3.000000e+00, float -7.000000e+00>515; CHECK-NEXT:    [[T2:%.*]] = fdiv reassoc <2 x float> <float 1.500000e+01, float -7.000000e+00>, [[T1]]516; CHECK-NEXT:    ret <2 x float> [[T2]]517;518  %t1 = fdiv <2 x float> %x, <float 3.0e0, float -7.0e0>519  %t2 = fdiv reassoc <2 x float> <float 15.0e0, float -7.0e0>, %t1520  ret <2 x float> %t2521}522 523; C1/(C2/X) => (C1/C2) * X524; This tests the combination of 2 folds: (C1 * X) / C2 --> (C1 / C2) * X525 526define <2 x float> @div_constant_dividend3(<2 x float> %x) {527; CHECK-LABEL: @div_constant_dividend3(528; CHECK-NEXT:    [[TMP1:%.*]] = fmul reassoc arcp <2 x float> [[X:%.*]], <float 1.500000e+01, float -7.000000e+00>529; CHECK-NEXT:    [[T2:%.*]] = fmul reassoc arcp <2 x float> [[TMP1]], <float 0x3FD5555560000000, float 0x3FC24924A0000000>530; CHECK-NEXT:    ret <2 x float> [[T2]]531;532  %t1 = fdiv <2 x float> <float 3.0e0, float 7.0e0>, %x533  %t2 = fdiv arcp reassoc <2 x float> <float 15.0e0, float -7.0e0>, %t1534  ret <2 x float> %t2535}536 537define double @fdiv_fneg1(double %x, double %y) {538; CHECK-LABEL: @fdiv_fneg1(539; CHECK-NEXT:    [[NEG:%.*]] = fneg double [[X:%.*]]540; CHECK-NEXT:    [[DIV:%.*]] = fdiv double [[NEG]], [[Y:%.*]]541; CHECK-NEXT:    ret double [[DIV]]542;543  %neg = fsub double -0.0, %x544  %div = fdiv double %neg, %y545  ret double %div546}547 548define double @fdiv_unary_fneg1(double %x, double %y) {549; CHECK-LABEL: @fdiv_unary_fneg1(550; CHECK-NEXT:    [[NEG:%.*]] = fneg double [[X:%.*]]551; CHECK-NEXT:    [[DIV:%.*]] = fdiv double [[NEG]], [[Y:%.*]]552; CHECK-NEXT:    ret double [[DIV]]553;554  %neg = fneg double %x555  %div = fdiv double %neg, %y556  ret double %div557}558 559define <2 x float> @fdiv_fneg2(<2 x float> %x, <2 x float> %y) {560; CHECK-LABEL: @fdiv_fneg2(561; CHECK-NEXT:    [[NEG:%.*]] = fneg <2 x float> [[X:%.*]]562; CHECK-NEXT:    [[DIV:%.*]] = fdiv <2 x float> [[Y:%.*]], [[NEG]]563; CHECK-NEXT:    ret <2 x float> [[DIV]]564;565  %neg = fsub <2 x float> <float -0.0, float -0.0>, %x566  %div = fdiv <2 x float> %y, %neg567  ret <2 x float> %div568}569 570define <2 x float> @fdiv_unary_fneg2(<2 x float> %x, <2 x float> %y) {571; CHECK-LABEL: @fdiv_unary_fneg2(572; CHECK-NEXT:    [[NEG:%.*]] = fneg <2 x float> [[X:%.*]]573; CHECK-NEXT:    [[DIV:%.*]] = fdiv <2 x float> [[Y:%.*]], [[NEG]]574; CHECK-NEXT:    ret <2 x float> [[DIV]]575;576  %neg = fneg <2 x float> %x577  %div = fdiv <2 x float> %y, %neg578  ret <2 x float> %div579}580 581define float @fdiv_fneg1_extra_use(float %x, float %y) {582; CHECK-LABEL: @fdiv_fneg1_extra_use(583; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]584; CHECK-NEXT:    call void @use_f32(float [[NEG]])585; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[NEG]], [[Y:%.*]]586; CHECK-NEXT:    ret float [[DIV]]587;588  %neg = fsub float -0.0, %x589  call void @use_f32(float %neg)590  %div = fdiv float %neg, %y591  ret float %div592}593 594define float @fabs_same_op(float %x) {595; CHECK-LABEL: @fabs_same_op(596; CHECK-NEXT:    [[R:%.*]] = fdiv float [[X:%.*]], [[X]]597; CHECK-NEXT:    ret float [[R]]598;599  %a = call float @llvm.fabs.f32(float %x)600  %r = fdiv float %a, %a601  ret float %r602}603 604define float @fabs_same_op_extra_use(float %x) {605; CHECK-LABEL: @fabs_same_op_extra_use(606; CHECK-NEXT:    [[A:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])607; CHECK-NEXT:    call void @use_f32(float [[A]])608; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc ninf float [[X]], [[X]]609; CHECK-NEXT:    ret float [[R]]610;611  %a = call float @llvm.fabs.f32(float %x)612  call void @use_f32(float %a)613  %r = fdiv ninf reassoc float %a, %a614  ret float %r615}616 617define float @fabs_fabs(float %x, float %y) {618; CHECK-LABEL: @fabs_fabs(619; CHECK-NEXT:    [[TMP1:%.*]] = fdiv float [[X:%.*]], [[Y:%.*]]620; CHECK-NEXT:    [[R:%.*]] = call float @llvm.fabs.f32(float [[TMP1]])621; CHECK-NEXT:    ret float [[R]]622;623  %x.fabs = call float @llvm.fabs.f32(float %x)624  %y.fabs = call float @llvm.fabs.f32(float %y)625  %r = fdiv float %x.fabs, %y.fabs626  ret float %r627}628 629define float @fabs_fabs_extra_use1(float %x, float %y) {630; CHECK-LABEL: @fabs_fabs_extra_use1(631; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])632; CHECK-NEXT:    call void @use_f32(float [[X_FABS]])633; CHECK-NEXT:    [[TMP1:%.*]] = fdiv ninf float [[X]], [[Y:%.*]]634; CHECK-NEXT:    [[R:%.*]] = call ninf float @llvm.fabs.f32(float [[TMP1]])635; CHECK-NEXT:    ret float [[R]]636;637  %x.fabs = call float @llvm.fabs.f32(float %x)638  call void @use_f32(float %x.fabs)639  %y.fabs = call float @llvm.fabs.f32(float %y)640  %r = fdiv ninf float %x.fabs, %y.fabs641  ret float %r642}643 644define float @fabs_fabs_extra_use2(float %x, float %y) {645; CHECK-LABEL: @fabs_fabs_extra_use2(646; CHECK-NEXT:    [[Y_FABS:%.*]] = call fast float @llvm.fabs.f32(float [[Y:%.*]])647; CHECK-NEXT:    call void @use_f32(float [[Y_FABS]])648; CHECK-NEXT:    [[TMP1:%.*]] = fdiv reassoc ninf float [[X:%.*]], [[Y]]649; CHECK-NEXT:    [[R:%.*]] = call reassoc ninf float @llvm.fabs.f32(float [[TMP1]])650; CHECK-NEXT:    ret float [[R]]651;652  %x.fabs = call fast float @llvm.fabs.f32(float %x)653  %y.fabs = call fast float @llvm.fabs.f32(float %y)654  call void @use_f32(float %y.fabs)655  %r = fdiv reassoc ninf float %x.fabs, %y.fabs656  ret float %r657}658 659; negative test - don't create an extra instruction660 661define float @fabs_fabs_extra_use3(float %x, float %y) {662; CHECK-LABEL: @fabs_fabs_extra_use3(663; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])664; CHECK-NEXT:    call void @use_f32(float [[X_FABS]])665; CHECK-NEXT:    [[Y_FABS:%.*]] = call float @llvm.fabs.f32(float [[Y:%.*]])666; CHECK-NEXT:    call void @use_f32(float [[Y_FABS]])667; CHECK-NEXT:    [[R:%.*]] = fdiv float [[X_FABS]], [[Y_FABS]]668; CHECK-NEXT:    ret float [[R]]669;670  %x.fabs = call float @llvm.fabs.f32(float %x)671  call void @use_f32(float %x.fabs)672  %y.fabs = call float @llvm.fabs.f32(float %y)673  call void @use_f32(float %y.fabs)674  %r = fdiv float %x.fabs, %y.fabs675  ret float %r676}677 678define float @pow_divisor(float %x, float %y, float %z) {679; CHECK-LABEL: @pow_divisor(680; CHECK-NEXT:    [[TMP1:%.*]] = fneg reassoc arcp float [[Y:%.*]]681; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc arcp float @llvm.pow.f32(float [[X:%.*]], float [[TMP1]])682; CHECK-NEXT:    [[R:%.*]] = fmul reassoc arcp float [[Z:%.*]], [[TMP2]]683; CHECK-NEXT:    ret float [[R]]684;685  %p = call float @llvm.pow.f32(float %x, float %y)686  %r = fdiv reassoc arcp float %z, %p687  ret float %r688}689 690; Negative test - don't create an extra pow691 692define float @pow_divisor_extra_use(float %x, float %y, float %z) {693; CHECK-LABEL: @pow_divisor_extra_use(694; CHECK-NEXT:    [[P:%.*]] = call float @llvm.pow.f32(float [[X:%.*]], float [[Y:%.*]])695; CHECK-NEXT:    call void @use_f32(float [[P]])696; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc arcp float [[Z:%.*]], [[P]]697; CHECK-NEXT:    ret float [[R]]698;699  %p = call float @llvm.pow.f32(float %x, float %y)700  call void @use_f32(float %p)701  %r = fdiv reassoc arcp float %z, %p702  ret float %r703}704 705; Negative test - must have reassoc+arcp706 707define float @pow_divisor_not_enough_fmf(float %x, float %y, float %z) {708; CHECK-LABEL: @pow_divisor_not_enough_fmf(709; CHECK-NEXT:    [[P:%.*]] = call fast float @llvm.pow.f32(float [[X:%.*]], float [[Y:%.*]])710; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc float [[Z:%.*]], [[P]]711; CHECK-NEXT:    ret float [[R]]712;713  %p = call fast float @llvm.pow.f32(float %x, float %y)714  %r = fdiv reassoc float %z, %p715  ret float %r716}717 718; Negative test - must have reassoc+arcp719 720define float @pow_divisor_not_enough_fmf2(float %x, float %y, float %z) {721; CHECK-LABEL: @pow_divisor_not_enough_fmf2(722; CHECK-NEXT:    [[P:%.*]] = call fast float @llvm.pow.f32(float [[X:%.*]], float [[Y:%.*]])723; CHECK-NEXT:    [[R:%.*]] = fdiv arcp float [[Z:%.*]], [[P]]724; CHECK-NEXT:    ret float [[R]]725;726  %p = call fast float @llvm.pow.f32(float %x, float %y)727  %r = fdiv arcp float %z, %p728  ret float %r729}730 731; Special-case - reciprocal does not require extra fmul732 733define <2 x half> @pow_recip(<2 x half> %x, <2 x half> %y) {734; CHECK-LABEL: @pow_recip(735; CHECK-NEXT:    [[TMP1:%.*]] = fneg reassoc ninf arcp <2 x half> [[Y:%.*]]736; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc ninf arcp <2 x half> @llvm.pow.v2f16(<2 x half> [[X:%.*]], <2 x half> [[TMP1]])737; CHECK-NEXT:    ret <2 x half> [[TMP2]]738;739  %p = call <2 x half> @llvm.pow.v2f16(<2 x half> %x, <2 x half> %y)740  %r = fdiv reassoc arcp ninf <2 x half> <half 1.0, half 1.0>, %p741  ret <2 x half> %r742}743 744define float @exp_divisor(float %y, float %z) {745; CHECK-LABEL: @exp_divisor(746; CHECK-NEXT:    [[TMP1:%.*]] = fneg reassoc arcp float [[Y:%.*]]747; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc arcp float @llvm.exp.f32(float [[TMP1]])748; CHECK-NEXT:    [[R:%.*]] = fmul reassoc arcp float [[Z:%.*]], [[TMP2]]749; CHECK-NEXT:    ret float [[R]]750;751  %p = call float @llvm.exp.f32(float %y)752  %r = fdiv reassoc arcp float %z, %p753  ret float %r754}755 756; Negative test - don't create an extra exp757 758define float @exp_divisor_extra_use(float %y, float %z) {759; CHECK-LABEL: @exp_divisor_extra_use(760; CHECK-NEXT:    [[P:%.*]] = call float @llvm.exp.f32(float [[Y:%.*]])761; CHECK-NEXT:    call void @use_f32(float [[P]])762; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc arcp float [[Z:%.*]], [[P]]763; CHECK-NEXT:    ret float [[R]]764;765  %p = call float @llvm.exp.f32(float %y)766  call void @use_f32(float %p)767  %r = fdiv reassoc arcp float %z, %p768  ret float %r769}770 771; Negative test - must have reassoc+arcp772 773define float @exp_divisor_not_enough_fmf(float %y, float %z) {774; CHECK-LABEL: @exp_divisor_not_enough_fmf(775; CHECK-NEXT:    [[P:%.*]] = call fast float @llvm.exp.f32(float [[Y:%.*]])776; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc float [[Z:%.*]], [[P]]777; CHECK-NEXT:    ret float [[R]]778;779  %p = call fast float @llvm.exp.f32(float %y)780  %r = fdiv reassoc float %z, %p781  ret float %r782}783 784; Negative test - must have reassoc+arcp785 786define float @exp_divisor_not_enough_fmf2(float %y, float %z) {787; CHECK-LABEL: @exp_divisor_not_enough_fmf2(788; CHECK-NEXT:    [[P:%.*]] = call fast float @llvm.exp.f32(float [[Y:%.*]])789; CHECK-NEXT:    [[R:%.*]] = fdiv arcp float [[Z:%.*]], [[P]]790; CHECK-NEXT:    ret float [[R]]791;792  %p = call fast float @llvm.exp.f32(float %y)793  %r = fdiv arcp float %z, %p794  ret float %r795}796 797; Special-case - reciprocal does not require extra fmul798 799define <2 x half> @exp_recip(<2 x half> %x, <2 x half> %y) {800; CHECK-LABEL: @exp_recip(801; CHECK-NEXT:    [[TMP1:%.*]] = fneg reassoc ninf arcp <2 x half> [[Y:%.*]]802; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc ninf arcp <2 x half> @llvm.exp.v2f16(<2 x half> [[TMP1]])803; CHECK-NEXT:    ret <2 x half> [[TMP2]]804;805  %p = call <2 x half> @llvm.exp.v2f16(<2 x half> %y)806  %r = fdiv reassoc arcp ninf <2 x half> <half 1.0, half 1.0>, %p807  ret <2 x half> %r808}809 810define float @exp2_divisor(float %y, float %z) {811; CHECK-LABEL: @exp2_divisor(812; CHECK-NEXT:    [[TMP1:%.*]] = fneg reassoc arcp float [[Y:%.*]]813; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc arcp float @llvm.exp2.f32(float [[TMP1]])814; CHECK-NEXT:    [[R:%.*]] = fmul reassoc arcp float [[Z:%.*]], [[TMP2]]815; CHECK-NEXT:    ret float [[R]]816;817  %p = call float @llvm.exp2.f32(float %y)818  %r = fdiv reassoc arcp float %z, %p819  ret float %r820}821 822; Negative test - don't create an extra exp823 824define float @exp2_divisor_extra_use(float %y, float %z) {825; CHECK-LABEL: @exp2_divisor_extra_use(826; CHECK-NEXT:    [[P:%.*]] = call float @llvm.exp2.f32(float [[Y:%.*]])827; CHECK-NEXT:    call void @use_f32(float [[P]])828; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc arcp float [[Z:%.*]], [[P]]829; CHECK-NEXT:    ret float [[R]]830;831  %p = call float @llvm.exp2.f32(float %y)832  call void @use_f32(float %p)833  %r = fdiv reassoc arcp float %z, %p834  ret float %r835}836 837; Negative test - must have reassoc+arcp838 839define float @exp2_divisor_not_enough_fmf(float %y, float %z) {840; CHECK-LABEL: @exp2_divisor_not_enough_fmf(841; CHECK-NEXT:    [[P:%.*]] = call fast float @llvm.exp2.f32(float [[Y:%.*]])842; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc float [[Z:%.*]], [[P]]843; CHECK-NEXT:    ret float [[R]]844;845  %p = call fast float @llvm.exp2.f32(float %y)846  %r = fdiv reassoc float %z, %p847  ret float %r848}849 850; Negative test - must have reassoc+arcp851 852define float @exp2_divisor_not_enough_fmf2(float %y, float %z) {853; CHECK-LABEL: @exp2_divisor_not_enough_fmf2(854; CHECK-NEXT:    [[P:%.*]] = call fast float @llvm.exp2.f32(float [[Y:%.*]])855; CHECK-NEXT:    [[R:%.*]] = fdiv arcp float [[Z:%.*]], [[P]]856; CHECK-NEXT:    ret float [[R]]857;858  %p = call fast float @llvm.exp2.f32(float %y)859  %r = fdiv arcp float %z, %p860  ret float %r861}862 863; Special-case - reciprocal does not require extra fmul864 865define <2 x half> @exp2_recip(<2 x half> %x, <2 x half> %y) {866; CHECK-LABEL: @exp2_recip(867; CHECK-NEXT:    [[TMP1:%.*]] = fneg reassoc ninf arcp <2 x half> [[Y:%.*]]868; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc ninf arcp <2 x half> @llvm.exp2.v2f16(<2 x half> [[TMP1]])869; CHECK-NEXT:    ret <2 x half> [[TMP2]]870;871  %p = call <2 x half> @llvm.exp2.v2f16(<2 x half> %y)872  %r = fdiv reassoc arcp ninf <2 x half> <half 1.0, half 1.0>, %p873  ret <2 x half> %r874}875 876define float @powi_divisor(float %x, i32 %y, float %z) {877; CHECK-LABEL: @powi_divisor(878; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[Y:%.*]]879; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc ninf arcp float @llvm.powi.f32.i32(float [[X:%.*]], i32 [[TMP1]])880; CHECK-NEXT:    [[R:%.*]] = fmul reassoc ninf arcp float [[Z:%.*]], [[TMP2]]881; CHECK-NEXT:    ret float [[R]]882;883  %p = call float @llvm.powi.f32.i32(float %x, i32 %y)884  %r = fdiv reassoc arcp ninf float %z, %p885  ret float %r886}887 888; Negative test - don't create an extra pow889 890define float @powi_divisor_extra_use(float %x, i32 %y, float %z) {891; CHECK-LABEL: @powi_divisor_extra_use(892; CHECK-NEXT:    [[P:%.*]] = call float @llvm.powi.f32.i32(float [[X:%.*]], i32 [[Y:%.*]])893; CHECK-NEXT:    call void @use_f32(float [[P]])894; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc ninf arcp float [[Z:%.*]], [[P]]895; CHECK-NEXT:    ret float [[R]]896;897  %p = call float @llvm.powi.f32.i32(float %x, i32 %y)898  call void @use_f32(float %p)899  %r = fdiv reassoc arcp ninf float %z, %p900  ret float %r901}902 903; Negative test - must have reassoc+arcp+ninf904 905define float @powi_divisor_not_enough_fmf(float %x, i32 %y, float %z) {906; CHECK-LABEL: @powi_divisor_not_enough_fmf(907; CHECK-NEXT:    [[P:%.*]] = call fast float @llvm.powi.f32.i32(float [[X:%.*]], i32 [[Y:%.*]])908; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc ninf float [[Z:%.*]], [[P]]909; CHECK-NEXT:    ret float [[R]]910;911  %p = call fast float @llvm.powi.f32.i32(float %x, i32 %y)912  %r = fdiv reassoc ninf float %z, %p913  ret float %r914}915 916; Negative test - must have reassoc+arcp+ninf917 918define float @powi_divisor_not_enough_fmf2(float %x, i32 %y, float %z) {919; CHECK-LABEL: @powi_divisor_not_enough_fmf2(920; CHECK-NEXT:    [[P:%.*]] = call fast float @llvm.powi.f32.i32(float [[X:%.*]], i32 [[Y:%.*]])921; CHECK-NEXT:    [[R:%.*]] = fdiv ninf arcp float [[Z:%.*]], [[P]]922; CHECK-NEXT:    ret float [[R]]923;924  %p = call fast float @llvm.powi.f32.i32(float %x, i32 %y)925  %r = fdiv arcp ninf float %z, %p926  ret float %r927}928 929; Special-case - reciprocal does not require extra fmul930 931define <2 x half> @powi_recip(<2 x half> %x, i32 %y) {932; CHECK-LABEL: @powi_recip(933; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[Y:%.*]]934; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc nnan ninf arcp <2 x half> @llvm.powi.v2f16.i32(<2 x half> [[X:%.*]], i32 [[TMP1]])935; CHECK-NEXT:    ret <2 x half> [[TMP2]]936;937  %p = call <2 x half> @llvm.powi.v2f16.i32(<2 x half> %x, i32 %y)938  %r = fdiv reassoc arcp nnan ninf <2 x half> <half 1.0, half 1.0>, %p939  ret <2 x half> %r940}941 942define float @fdiv_zero_f32(float %x) {943; CHECK-LABEL: @fdiv_zero_f32(944; CHECK-NEXT:    [[FDIV:%.*]] = fdiv float [[X:%.*]], 0.000000e+00945; CHECK-NEXT:    ret float [[FDIV]]946;947  %fdiv = fdiv float %x, 0.0948  ret float %fdiv949}950 951; https://alive2.llvm.org/ce/z/gLBFKB952define float @fdiv_nnan_zero_f32(float %x) {953; CHECK-LABEL: @fdiv_nnan_zero_f32(954; CHECK-NEXT:    [[FDIV:%.*]] = call nnan float @llvm.copysign.f32(float 0x7FF0000000000000, float [[X:%.*]])955; CHECK-NEXT:    ret float [[FDIV]]956;957  %fdiv = fdiv nnan float %x, 0.0958  ret float %fdiv959}960 961define <2 x float> @fdiv_nnan_zero_v2f32(<2 x float> %x) {962; CHECK-LABEL: @fdiv_nnan_zero_v2f32(963; CHECK-NEXT:    [[FDIV:%.*]] = call nnan <2 x float> @llvm.copysign.v2f32(<2 x float> splat (float 0x7FF0000000000000), <2 x float> [[X:%.*]])964; CHECK-NEXT:    ret <2 x float> [[FDIV]]965;966  %fdiv = fdiv nnan <2 x float> %x, zeroinitializer967  ret <2 x float> %fdiv968}969 970define float @fdiv_nnan_zero_f32_fmf(float %x) {971; CHECK-LABEL: @fdiv_nnan_zero_f32_fmf(972; CHECK-NEXT:    [[FDIV:%.*]] = call nnan nsz float @llvm.copysign.f32(float 0x7FF0000000000000, float [[X:%.*]])973; CHECK-NEXT:    ret float [[FDIV]]974;975  %fdiv = fdiv nnan nsz float %x, 0.0976  ret float %fdiv977}978 979define <2 x float> @fdiv_nnan_zero_v2f32_fmf(<2 x float> %x) {980; CHECK-LABEL: @fdiv_nnan_zero_v2f32_fmf(981; CHECK-NEXT:    [[FDIV:%.*]] = call nnan nsz <2 x float> @llvm.copysign.v2f32(<2 x float> splat (float 0x7FF0000000000000), <2 x float> [[X:%.*]])982; CHECK-NEXT:    ret <2 x float> [[FDIV]]983;984  %fdiv = fdiv nnan nsz <2 x float> %x, zeroinitializer985  ret <2 x float> %fdiv986}987 988define float @fdiv_nnan_neg_zero_f32(float %x) {989; CHECK-LABEL: @fdiv_nnan_neg_zero_f32(990; CHECK-NEXT:    [[FDIV:%.*]] = fdiv nnan float [[X:%.*]], -0.000000e+00991; CHECK-NEXT:    ret float [[FDIV]]992;993  %fdiv = fdiv nnan float %x, -0.0994  ret float %fdiv995}996 997define double @test_positive_zero_nsz(double %X) {998; CHECK-LABEL: @test_positive_zero_nsz(999; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz double @llvm.copysign.f64(double 0x7FF0000000000000, double [[X:%.*]])1000; CHECK-NEXT:    ret double [[TMP1]]1001;1002  %1 = fdiv nnan nsz double %X, 0.01003  ret double %11004}1005 1006define double @test_negative_zero_nsz(double %X) {1007; CHECK-LABEL: @test_negative_zero_nsz(1008; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz double @llvm.copysign.f64(double 0x7FF0000000000000, double [[X:%.*]])1009; CHECK-NEXT:    ret double [[TMP1]]1010;1011  %1 = fdiv nnan nsz double %X, -0.01012  ret double %11013}1014 1015define double @test_positive_zero(double %X) {1016; CHECK-LABEL: @test_positive_zero(1017; CHECK-NEXT:    [[TMP1:%.*]] = call nnan double @llvm.copysign.f64(double 0x7FF0000000000000, double [[X:%.*]])1018; CHECK-NEXT:    ret double [[TMP1]]1019;1020  %1 = fdiv nnan double %X, 0.01021  ret double %11022}1023 1024define double @test_negative_zero(double %X) {1025; CHECK-LABEL: @test_negative_zero(1026; CHECK-NEXT:    [[TMP1:%.*]] = fdiv nnan double [[X:%.*]], -0.000000e+001027; CHECK-NEXT:    ret double [[TMP1]]1028;1029  %1 = fdiv nnan double %X, -0.01030  ret double %11031}1032 1033define <2 x double> @test_positive_zero_vector_nsz(<2 x double> %X) {1034; CHECK-LABEL: @test_positive_zero_vector_nsz(1035; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz <2 x double> @llvm.copysign.v2f64(<2 x double> splat (double 0x7FF0000000000000), <2 x double> [[X:%.*]])1036; CHECK-NEXT:    ret <2 x double> [[TMP1]]1037;1038  %1 = fdiv nnan nsz <2 x double> %X, <double 0.0, double 0.0>1039  ret <2 x double> %11040}1041 1042define <2 x double> @test_negative_zero_vector_nsz(<2 x double> %X) {1043; CHECK-LABEL: @test_negative_zero_vector_nsz(1044; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz <2 x double> @llvm.copysign.v2f64(<2 x double> splat (double 0x7FF0000000000000), <2 x double> [[X:%.*]])1045; CHECK-NEXT:    ret <2 x double> [[TMP1]]1046;1047  %1 = fdiv nnan nsz <2 x double> %X, <double -0.0, double 0.0>1048  ret <2 x double> %11049}1050 1051define <2 x double> @test_positive_zero_vector(<2 x double> %X) {1052; CHECK-LABEL: @test_positive_zero_vector(1053; CHECK-NEXT:    [[TMP1:%.*]] = call nnan <2 x double> @llvm.copysign.v2f64(<2 x double> splat (double 0x7FF0000000000000), <2 x double> [[X:%.*]])1054; CHECK-NEXT:    ret <2 x double> [[TMP1]]1055;1056  %1 = fdiv nnan <2 x double> %X, <double 0.0, double 0.0>1057  ret <2 x double> %11058}1059 1060define <2 x double> @test_negative_zero_vector(<2 x double> %X) {1061; CHECK-LABEL: @test_negative_zero_vector(1062; CHECK-NEXT:    [[TMP1:%.*]] = fdiv nnan <2 x double> [[X:%.*]], <double -0.000000e+00, double 0.000000e+00>1063; CHECK-NEXT:    ret <2 x double> [[TMP1]]1064;1065  %1 = fdiv nnan <2 x double> %X, <double -0.0, double 0.0>1066  ret <2 x double> %11067}1068