On Wed, 13 Nov 2024, Soumya AR wrote: > > > > On 12 Nov 2024, at 6:19 PM, Richard Biener <rguent...@suse.de> wrote: > > > > External email: Use caution opening links or attachments > > > > > > On Mon, 11 Nov 2024, Soumya AR wrote: > > > >> Hi Richard, > >> > >>> On 7 Nov 2024, at 6:10 PM, Richard Biener <rguent...@suse.de> wrote: > >>> > >>> External email: Use caution opening links or attachments > >>> > >>> > >>> On Tue, 5 Nov 2024, Soumya AR wrote: > >>> > >>>> > >>>> > >>>>> On 29 Oct 2024, at 7:16 PM, Richard Biener <rguent...@suse.de> wrote: > >>>>> > >>>>> External email: Use caution opening links or attachments > >>>>> > >>>>> > >>>>> On Mon, 28 Oct 2024, Soumya AR wrote: > >>>>> > >>>>>> This patch transforms the following POW calls to equivalent LDEXP > >>>>>> calls, as > >>>>>> discussed in PR57492: > >>>>>> > >>>>>> powi (2.0, i) -> ldexp (1.0, i) > >>>>>> > >>>>>> a * powi (2.0, i) -> ldexp (a, i) > >>>>>> > >>>>>> 2.0 * powi (2.0, i) -> ldexp (1.0, i + 1) > >>>>>> > >>>>>> pow (powof2, i) -> ldexp (1.0, i * log2 (powof2)) > >>>>>> > >>>>>> powof2 * pow (2, i) -> ldexp (1.0, i + log2 (powof2)) > >>>>> > >>>>> For the multiplication cases why not handle powof2 * ldexp (1., i) > >>>>> to ldexp (1., i + log2 (powof2)) and a * ldexp (1., i) -> ldexp (a, i) > >>>>> instead? exp2 * ldexp (1., i) is another candidate. > >>>>> > >>>>> So please split out the multiplication parts. > >>>>> > >>>>> + /* Simplify pow (powof2, i) to ldexp (1, i * log2 (powof2)). */ > >>>>> > >>>>> the below pattern handles POWI, not POW. > >>>>> > >>>>> + (simplify > >>>>> + (POWI REAL_CST@0 @1) > >>>>> + (with { HOST_WIDE_INT tmp = 0; > >>>>> + tree integer_arg1 = NULL_TREE; } > >>>>> + (if (integer_valued_real_p (@0) > >>>>> + && real_isinteger (&TREE_REAL_CST (@0), &tmp) > >>>>> + && integer_pow2p (integer_arg1 = build_int_cst > >>>>> (integer_type_node, > >>>>> tmp))) > >>>>> > >>>>> && tmp > 0 > >>>>> && pow2p_hwi (tmp) > >>>>> > >>>>> + (LDEXP { build_one_cst (type); } > >>>>> + (mult @1 { build_int_cst (integer_type_node, > >>>>> + tree_log2 (integer_arg1)); }))))) > >>>>> > >>>>> build_int_cst (integer_type_node, exact_log2 (tmp)) > >>>>> > >>>>> + /* Simplify powi (2.0, i) to ldexp (1, i). */ > >>>>> + (simplify > >>>>> + (POWI REAL_CST@0 @1) > >>>>> + (if (real_equal (TREE_REAL_CST_PTR (@0), &dconst2)) > >>>>> + (LDEXP { build_one_cst (type); } @1))) > >>>>> + > >>>>> > >>>>> You'll have a duplicate pattern here, instead merge them. 2.0 > >>>>> is power-of-two so I wonder why the pattern is needed. > >>>> > >>>> Thanks for the feedback! > >>>> > >>>> I've merged the extra case that was specifically checking for 2.0. > >>>> > >>>> Like you suggested, I also added two ldexp specific transforms: > >>>> > >>>> • powof2 * ldexp (x, i) -> ldexp (x, i + log2 (powof2)) > >>>> • a * ldexp(1., i) -> ldexp (a, i) > >>>> > >>>> Regarding your suggestion to also fold exp2, a conversion like > >>>> exp2 (x) -> ldexp (1., x) or exp2 (x) * ldexp (y, i) -> ldexp (y, i + x) > >>>> is a > >>>> bit tricky because we'd have to cast it to an integer before passing it > >>>> to > >>>> ldexp. > >>>> > >>>> real_to_integer only works for constants, which isn't helpful here as > >>>> exp2 (CST) > >>>> becomes a power of 2 anyway and matches with the above patterns. > >>>> > >>>> We'll have to explicitly convert it for non constants and I'm not sure > >>>> if that > >>>> is worth it for this patch. > >>>> > >>>> Let me know what you think. > >>> > >>> + (simplify > >>> + (mult:c REAL_CST@0 (POWI REAL_CST@1 @2)) > >>> + (with { HOST_WIDE_INT tmp = 0; > >>> + tree integer_arg1 = NULL_TREE; } > >>> + (if (integer_valued_real_p (@0) > >>> + && real_equal (TREE_REAL_CST_PTR (@1), &dconst2) > >>> + && real_isinteger (&TREE_REAL_CST (@0), &tmp) > >>> + && integer_pow2p (integer_arg1 = build_int_cst (integer_type_node, > >>> tmp))) > >>> > >>> as said you can use tmp > 0 && pow2p_hwi (tmp) instead of > >>> integer_pow2p and build_int_cst. This applies to all patterns. > >> > >> Thanks for the feedback! Updated the patch with this modification. > >> > >>> + (if (integer_valued_real_p (@0) > >>> + && real_isinteger (&TREE_REAL_CST (@0), &tmp) > >>> > >>> also is a redundant check, real_isinteger gives you the answer already. > >>> > >>> + (mult @1 {build_int_cst (integer_type_node, > >>> + tree_log2 (integer_arg1)); }))))) > >>> > >>> and use exact_log2 (tmp) instead of tree_log2 (integer_arg1). > >> > >> Fixed. > >> > >>> > >>> + /* Simplify a * powi (2.0, i) to ldexp (a, i). */ > >>> + (simplify > >>> + (mult:c @0 (POWI REAL_CST@1 @2)) > >>> + (if (real_equal (TREE_REAL_CST_PTR (@1), &dconst2)) > >>> + (LDEXP @0 @2))) > >>> ... > >>> + /* Simplify powi (2.0, i) to ldexp (1, i). */ > >>> + (simplify > >>> + (POWI REAL_CST@0 @1) > >>> + (if (real_equal (TREE_REAL_CST_PTR (@0), &dconst2)) > >>> + (LDEXP { build_one_cst (type); } @1))) > >>> > >>> you can expect the first to never hit as we should replace > >>> a * powi (2.0, i) with a * ldexp (1, i) first. So you can > >>> drop the first pattern. > >> > >> Makes sense, apologies for the oversight. Fixed this. > > > > + /* Simplify powi (2.0, i) to ldexp (1, i). */ > > + (simplify > > + (POWI REAL_CST@0 @1) > > + (if (real_equal (TREE_REAL_CST_PTR (@0), &dconst2)) > > + (LDEXP { build_one_cst (type); } @1))) > > > > why do you need this? The powi (powof2, i) to ldexp (1, i * log2 > > (powof2)) pattern should handle this already? > > > > + /* Simplify powof2 * powi (2, i) to ldexp (1, i + log2 (powof2)). */ > > + (simplify > > + (mult:c REAL_CST@0 (POWI REAL_CST@1 @2)) > > + (with { HOST_WIDE_INT tmp = 0; } > > + (if (real_isinteger (&TREE_REAL_CST (@0), &tmp) > > + && tmp > 0 && pow2p_hwi (tmp)) > > + (LDEXP { build_one_cst (type); } > > + (plus {build_int_cst (integer_type_node, exact_log2 (tmp)); } > > @2))))) > > + > > + /* Simplify powi (powof2, i) to ldexp (1, i * log2 (powof2)). */ > > + (simplify > > + (POWI REAL_CST@0 @1) > > + (with { HOST_WIDE_INT tmp = 0; } > > + (if (real_isinteger (&TREE_REAL_CST (@0), &tmp) > > + && tmp > 0 && pow2p_hwi (tmp)) > > + (LDEXP { build_one_cst (type); } > > + (mult @1 {build_int_cst (integer_type_node, > > + exact_log2 (tmp)); }))))) > > > > with the second pattern you shouldn't see powof2 * powi (2, i) > > since powi (2, i) will be simplified to ldexp already, so the > > powof2 * powi (2, i) simplification should not be necessary. > > > > Otherwise looks good now. > > Removed both redundant cases as suggested.
OK. Thanks, Richard. > Best, > Soumya > > > > > Richard. > > > >> Best, > >> Soumya > >> > >>> Richard. > >>> > >>> > >>>> Best, > >>>> Soumya > >>>> > >>>> > >>>> > >>>>> Richard. > >>>>> > >>>>>> > >>>>>> This is especially helpful for SVE architectures as LDEXP calls can be > >>>>>> implemented using the FSCALE instruction, as seen in the following > >>>>>> patch: > >>>>>> https://gcc.gnu.org/pipermail/gcc-patches/2024-September/664160.html > >>>>>> > >>>>>> SPEC2017 was run with this patch, while there are no noticeable > >>>>>> improvements, > >>>>>> there are no non-noise regressions either. > >>>>>> > >>>>>> The patch was bootstrapped and regtested on aarch64-linux-gnu, no > >>>>>> regression. > >>>>>> OK for mainline? > >>>>>> > >>>>>> Signed-off-by: Soumya AR <soum...@nvidia.com> > >>>>>> > >>>>>> gcc/ChangeLog: > >>>>>> PR target/57492 > >>>>>> * match.pd: Added patterns to fold certain calls to pow to ldexp. > >>>>>> > >>>>>> gcc/testsuite/ChangeLog: > >>>>>> PR target/57492 > >>>>>> * gcc.dg/tree-ssa/pow-to-ldexp.c: New test. > >>>>>> > >>>>>> > >>>>> > >>>>> -- > >>>>> Richard Biener <rguent...@suse.de> > >>>>> SUSE Software Solutions Germany GmbH, > >>>>> Frankenstrasse 146, 90461 Nuernberg, Germany; > >>>>> GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG > >>>>> Nuernberg) > >>>> > >>>> > >>>> > >>> > >>> -- > >>> Richard Biener <rguent...@suse.de> > >>> SUSE Software Solutions Germany GmbH, > >>> Frankenstrasse 146, 90461 Nuernberg, Germany; > >>> GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg) > >> > >> > >> > > > > -- > > Richard Biener <rguent...@suse.de> > > SUSE Software Solutions Germany GmbH, > > Frankenstrasse 146, 90461 Nuernberg, Germany; > > GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg) > > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)