diff mbox series

[1/2] using overflow_free_p to simplify pattern

Message ID 20230919052353.3208707-1-guojiufu@linux.ibm.com
State New
Headers show
Series [1/2] using overflow_free_p to simplify pattern | expand

Commit Message

Jiufu Guo Sept. 19, 2023, 5:23 a.m. UTC
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

Richard Biener Sept. 19, 2023, 12:50 p.m. UTC | #1
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
>     ))))
>  
>
Jiufu Guo Sept. 21, 2023, 5:22 a.m. UTC | #2
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
>>     ))))
>>  
>>
diff mbox series

Patch

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 ()
+	  && range_op_handler (MULT_EXPR).overflow_free_p (vr0, vr1))
+      @0))
 #endif
    ))))