[1/2] using overflow_free_p to simplify pattern
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gcc_check--master-arm |
success
|
Testing passed
|
Commit Message
Hi,
In r14-3582, an "overflow_free_p" interface is added.
The pattern of "(t * 2) / 2" in match.pd can be simplified
by using this interface.
Bootstrap & regtest pass on ppc64{,le} and x86_64.
Is this ok for trunk?
BR,
Jeff (Jiufu)
gcc/ChangeLog:
* match.pd ((t * 2) / 2): Update to use overflow_free_p.
---
gcc/match.pd | 37 +++++++------------------------------
1 file changed, 7 insertions(+), 30 deletions(-)
Comments
On Tue, 19 Sep 2023, Jiufu Guo wrote:
> Hi,
>
> In r14-3582, an "overflow_free_p" interface is added.
> The pattern of "(t * 2) / 2" in match.pd can be simplified
> by using this interface.
>
> Bootstrap & regtest pass on ppc64{,le} and x86_64.
> Is this ok for trunk?
>
> BR,
> Jeff (Jiufu)
>
> gcc/ChangeLog:
>
> * match.pd ((t * 2) / 2): Update to use overflow_free_p.
>
> ---
> gcc/match.pd | 37 +++++++------------------------------
> 1 file changed, 7 insertions(+), 30 deletions(-)
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 87edf0e75c3..8bba7056000 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -926,36 +926,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> (if (TYPE_OVERFLOW_UNDEFINED (type))
> @0
> #if GIMPLE
> - (with
> - {
> - bool overflowed = true;
> - value_range vr0, vr1;
> - if (INTEGRAL_TYPE_P (type)
> - && get_range_query (cfun)->range_of_expr (vr0, @0)
> - && get_range_query (cfun)->range_of_expr (vr1, @1)
> - && !vr0.varying_p () && !vr0.undefined_p ()
> - && !vr1.varying_p () && !vr1.undefined_p ())
> - {
> - wide_int wmin0 = vr0.lower_bound ();
> - wide_int wmax0 = vr0.upper_bound ();
> - wide_int wmin1 = vr1.lower_bound ();
> - wide_int wmax1 = vr1.upper_bound ();
> - /* If the multiplication can't overflow/wrap around, then
> - it can be optimized too. */
> - wi::overflow_type min_ovf, max_ovf;
> - wi::mul (wmin0, wmin1, TYPE_SIGN (type), &min_ovf);
> - wi::mul (wmax0, wmax1, TYPE_SIGN (type), &max_ovf);
> - if (min_ovf == wi::OVF_NONE && max_ovf == wi::OVF_NONE)
> - {
> - wi::mul (wmin0, wmax1, TYPE_SIGN (type), &min_ovf);
> - wi::mul (wmax0, wmin1, TYPE_SIGN (type), &max_ovf);
> - if (min_ovf == wi::OVF_NONE && max_ovf == wi::OVF_NONE)
> - overflowed = false;
> - }
> - }
> - }
> - (if (!overflowed)
> - @0))
> + (with {value_range vr0, vr1;}
> + (if (INTEGRAL_TYPE_P (type)
> + && get_range_query (cfun)->range_of_expr (vr0, @0)
> + && get_range_query (cfun)->range_of_expr (vr1, @1)
> + && !vr0.varying_p () && !vr1.varying_p ()
From your other uses checking !varying_p doesn't seem necessary?
OK with omitting.
Richard.
> + && range_op_handler (MULT_EXPR).overflow_free_p (vr0, vr1))
> + @0))
> #endif
> ))))
>
>
Hi,
Richard Biener <rguenther@suse.de> writes:
> On Tue, 19 Sep 2023, Jiufu Guo wrote:
>
>> Hi,
>>
>> In r14-3582, an "overflow_free_p" interface is added.
>> The pattern of "(t * 2) / 2" in match.pd can be simplified
>> by using this interface.
>>
>> Bootstrap & regtest pass on ppc64{,le} and x86_64.
>> Is this ok for trunk?
>>
>> BR,
>> Jeff (Jiufu)
>>
>> gcc/ChangeLog:
>>
>> * match.pd ((t * 2) / 2): Update to use overflow_free_p.
>>
>> ---
>> gcc/match.pd | 37 +++++++------------------------------
>> 1 file changed, 7 insertions(+), 30 deletions(-)
>>
>> diff --git a/gcc/match.pd b/gcc/match.pd
>> index 87edf0e75c3..8bba7056000 100644
>> --- a/gcc/match.pd
>> +++ b/gcc/match.pd
>> @@ -926,36 +926,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>> (if (TYPE_OVERFLOW_UNDEFINED (type))
>> @0
>> #if GIMPLE
>> - (with
>> - {
>> - bool overflowed = true;
>> - value_range vr0, vr1;
>> - if (INTEGRAL_TYPE_P (type)
>> - && get_range_query (cfun)->range_of_expr (vr0, @0)
>> - && get_range_query (cfun)->range_of_expr (vr1, @1)
>> - && !vr0.varying_p () && !vr0.undefined_p ()
>> - && !vr1.varying_p () && !vr1.undefined_p ())
>> - {
>> - wide_int wmin0 = vr0.lower_bound ();
>> - wide_int wmax0 = vr0.upper_bound ();
>> - wide_int wmin1 = vr1.lower_bound ();
>> - wide_int wmax1 = vr1.upper_bound ();
>> - /* If the multiplication can't overflow/wrap around, then
>> - it can be optimized too. */
>> - wi::overflow_type min_ovf, max_ovf;
>> - wi::mul (wmin0, wmin1, TYPE_SIGN (type), &min_ovf);
>> - wi::mul (wmax0, wmax1, TYPE_SIGN (type), &max_ovf);
>> - if (min_ovf == wi::OVF_NONE && max_ovf == wi::OVF_NONE)
>> - {
>> - wi::mul (wmin0, wmax1, TYPE_SIGN (type), &min_ovf);
>> - wi::mul (wmax0, wmin1, TYPE_SIGN (type), &max_ovf);
>> - if (min_ovf == wi::OVF_NONE && max_ovf == wi::OVF_NONE)
>> - overflowed = false;
>> - }
>> - }
>> - }
>> - (if (!overflowed)
>> - @0))
>> + (with {value_range vr0, vr1;}
>> + (if (INTEGRAL_TYPE_P (type)
>> + && get_range_query (cfun)->range_of_expr (vr0, @0)
>> + && get_range_query (cfun)->range_of_expr (vr1, @1)
>> + && !vr0.varying_p () && !vr1.varying_p ()
>
> From your other uses checking !varying_p doesn't seem necessary?
Thanks for pointing out this!!
Yes, !varying_p is not needed, overflow_free_p could cover it.
Committed via r14-4191.
BR,
Jeff (Jiufu Guo)
>
> OK with omitting.
>
> Richard.
>
>> + && range_op_handler (MULT_EXPR).overflow_free_p (vr0, vr1))
>> + @0))
>> #endif
>> ))))
>>
>>
@@ -926,36 +926,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(if (TYPE_OVERFLOW_UNDEFINED (type))
@0
#if GIMPLE
- (with
- {
- bool overflowed = true;
- value_range vr0, vr1;
- if (INTEGRAL_TYPE_P (type)
- && get_range_query (cfun)->range_of_expr (vr0, @0)
- && get_range_query (cfun)->range_of_expr (vr1, @1)
- && !vr0.varying_p () && !vr0.undefined_p ()
- && !vr1.varying_p () && !vr1.undefined_p ())
- {
- wide_int wmin0 = vr0.lower_bound ();
- wide_int wmax0 = vr0.upper_bound ();
- wide_int wmin1 = vr1.lower_bound ();
- wide_int wmax1 = vr1.upper_bound ();
- /* If the multiplication can't overflow/wrap around, then
- it can be optimized too. */
- wi::overflow_type min_ovf, max_ovf;
- wi::mul (wmin0, wmin1, TYPE_SIGN (type), &min_ovf);
- wi::mul (wmax0, wmax1, TYPE_SIGN (type), &max_ovf);
- if (min_ovf == wi::OVF_NONE && max_ovf == wi::OVF_NONE)
- {
- wi::mul (wmin0, wmax1, TYPE_SIGN (type), &min_ovf);
- wi::mul (wmax0, wmin1, TYPE_SIGN (type), &max_ovf);
- if (min_ovf == wi::OVF_NONE && max_ovf == wi::OVF_NONE)
- overflowed = false;
- }
- }
- }
- (if (!overflowed)
- @0))
+ (with {value_range vr0, vr1;}
+ (if (INTEGRAL_TYPE_P (type)
+ && get_range_query (cfun)->range_of_expr (vr0, @0)
+ && get_range_query (cfun)->range_of_expr (vr1, @1)
+ && !vr0.varying_p () && !vr1.varying_p ()
+ && range_op_handler (MULT_EXPR).overflow_free_p (vr0, vr1))
+ @0))
#endif
))))