public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fold ((T)(A + CST1)) + CST2 -> (T)(A) + (T)CST1 + CST2 for unsigned T and undefined overflow A + CST1 (PR middle-end/91866)
@ 2019-09-24 10:43 Jakub Jelinek
  2019-09-24 11:13 ` Richard Biener
  0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2019-09-24 10:43 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

Hi!

As mentioned in the PR, the following patch decreases number of +/-
operation when one is inside sign extension, done with undefined overflow,
and the outer is using wrapping arithmetics.

The :s as well as the outer + are there in order to make sure it is actually
beneficial, that we decrease the number of +/-, either from two to one or
from two to zero, depending on whether they cancel each other.
The price for the reduction is that we loose information about the undefined
behavior for certain @0 values.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2019-09-24  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/91866
	* match.pd (((T)(A)) + CST -> (T)(A + CST)): Formatting fix.
	(((T)(A + CST1)) + CST2 -> (T)(A) + (T)CST1 + CST2): New optimization.

	* gcc.dg/tree-ssa/pr91866.c: New test.

--- gcc/match.pd.jj	2019-09-21 23:53:52.108385196 +0200
+++ gcc/match.pd	2019-09-24 10:18:58.804114496 +0200
@@ -2265,8 +2265,9 @@ (define_operator_list COND_TERNARY
 			  max_ovf = wi::OVF_OVERFLOW;
         tree inner_type = TREE_TYPE (@0);
 
-        wide_int w1 = wide_int::from (wi::to_wide (@1), TYPE_PRECISION (inner_type),
-	    TYPE_SIGN (inner_type));
+	wide_int w1
+	  = wide_int::from (wi::to_wide (@1), TYPE_PRECISION (inner_type),
+			    TYPE_SIGN (inner_type));
 
         wide_int wmin0, wmax0;
         if (get_range_info (@0, &wmin0, &wmax0) == VR_RANGE)
@@ -2280,6 +2281,20 @@ (define_operator_list COND_TERNARY
      )))
 #endif
 
+/* ((T)(A + CST1)) + CST2 -> (T)(A) + (T)CST1 + CST2  */
+#if GIMPLE
+  (for op (plus minus)
+   (simplify
+    (plus (convert:s (op:s @0 INTEGER_CST@1)) INTEGER_CST@2)
+     (if (TREE_CODE (TREE_TYPE (@0)) == INTEGER_TYPE
+	  && TREE_CODE (type) == INTEGER_TYPE
+	  && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (@0))
+	  && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))
+	  && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@0))
+	  && TYPE_OVERFLOW_WRAPS (type))
+       (plus (convert @0) (op @2 (convert @1))))))
+#endif
+
   /* ~A + A -> -1 */
   (simplify
    (plus:c (bit_not @0) @0)
--- gcc/testsuite/gcc.dg/tree-ssa/pr91866.c.jj	2019-09-24 10:35:34.035784152 +0200
+++ gcc/testsuite/gcc.dg/tree-ssa/pr91866.c	2019-09-24 10:36:59.858463024 +0200
@@ -0,0 +1,12 @@
+/* PR middle-end/91866 */
+/* { dg-do compile { target { ilp32 || lp64 } } } */
+/* { dg-options "-O2 -fdump-tree-optimized" } * /
+/* { dg-final { scan-tree-dump-times " \\+ 11;" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " \[+-] \[0-9-]\[0-9]*;" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\\(long long unsigned int\\) x_" 5 "optimized" } } */
+
+unsigned long long f1 (int x) { return (x + 1) - 1ULL; }
+unsigned long long f2 (int x) { return (x - 5) + 5ULL; }
+unsigned long long f3 (int x) { return (x - 15) + 26ULL; }
+unsigned long long f4 (int x) { return (x + 6) + 5ULL; }
+unsigned long long f5 (int x) { return (x - (-1 - __INT_MAX__)) + 10ULL - __INT_MAX__; }

	Jakub

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Fold ((T)(A + CST1)) + CST2 -> (T)(A) + (T)CST1 + CST2 for unsigned T and undefined overflow A + CST1 (PR middle-end/91866)
  2019-09-24 10:43 [PATCH] Fold ((T)(A + CST1)) + CST2 -> (T)(A) + (T)CST1 + CST2 for unsigned T and undefined overflow A + CST1 (PR middle-end/91866) Jakub Jelinek
@ 2019-09-24 11:13 ` Richard Biener
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2019-09-24 11:13 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 3347 bytes --]

On Tue, 24 Sep 2019, Jakub Jelinek wrote:

> Hi!
> 
> As mentioned in the PR, the following patch decreases number of +/-
> operation when one is inside sign extension, done with undefined overflow,
> and the outer is using wrapping arithmetics.
> 
> The :s as well as the outer + are there in order to make sure it is actually
> beneficial, that we decrease the number of +/-, either from two to one or
> from two to zero, depending on whether they cancel each other.
> The price for the reduction is that we loose information about the undefined
> behavior for certain @0 values.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Thanks,
Richard.

> 2019-09-24  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR middle-end/91866
> 	* match.pd (((T)(A)) + CST -> (T)(A + CST)): Formatting fix.
> 	(((T)(A + CST1)) + CST2 -> (T)(A) + (T)CST1 + CST2): New optimization.
> 
> 	* gcc.dg/tree-ssa/pr91866.c: New test.
> 
> --- gcc/match.pd.jj	2019-09-21 23:53:52.108385196 +0200
> +++ gcc/match.pd	2019-09-24 10:18:58.804114496 +0200
> @@ -2265,8 +2265,9 @@ (define_operator_list COND_TERNARY
>  			  max_ovf = wi::OVF_OVERFLOW;
>          tree inner_type = TREE_TYPE (@0);
>  
> -        wide_int w1 = wide_int::from (wi::to_wide (@1), TYPE_PRECISION (inner_type),
> -	    TYPE_SIGN (inner_type));
> +	wide_int w1
> +	  = wide_int::from (wi::to_wide (@1), TYPE_PRECISION (inner_type),
> +			    TYPE_SIGN (inner_type));
>  
>          wide_int wmin0, wmax0;
>          if (get_range_info (@0, &wmin0, &wmax0) == VR_RANGE)
> @@ -2280,6 +2281,20 @@ (define_operator_list COND_TERNARY
>       )))
>  #endif
>  
> +/* ((T)(A + CST1)) + CST2 -> (T)(A) + (T)CST1 + CST2  */
> +#if GIMPLE
> +  (for op (plus minus)
> +   (simplify
> +    (plus (convert:s (op:s @0 INTEGER_CST@1)) INTEGER_CST@2)
> +     (if (TREE_CODE (TREE_TYPE (@0)) == INTEGER_TYPE
> +	  && TREE_CODE (type) == INTEGER_TYPE
> +	  && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (@0))
> +	  && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))
> +	  && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@0))
> +	  && TYPE_OVERFLOW_WRAPS (type))
> +       (plus (convert @0) (op @2 (convert @1))))))
> +#endif
> +
>    /* ~A + A -> -1 */
>    (simplify
>     (plus:c (bit_not @0) @0)
> --- gcc/testsuite/gcc.dg/tree-ssa/pr91866.c.jj	2019-09-24 10:35:34.035784152 +0200
> +++ gcc/testsuite/gcc.dg/tree-ssa/pr91866.c	2019-09-24 10:36:59.858463024 +0200
> @@ -0,0 +1,12 @@
> +/* PR middle-end/91866 */
> +/* { dg-do compile { target { ilp32 || lp64 } } } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } * /
> +/* { dg-final { scan-tree-dump-times " \\+ 11;" 3 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times " \[+-] \[0-9-]\[0-9]*;" 3 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "\\(long long unsigned int\\) x_" 5 "optimized" } } */
> +
> +unsigned long long f1 (int x) { return (x + 1) - 1ULL; }
> +unsigned long long f2 (int x) { return (x - 5) + 5ULL; }
> +unsigned long long f3 (int x) { return (x - 15) + 26ULL; }
> +unsigned long long f4 (int x) { return (x + 6) + 5ULL; }
> +unsigned long long f5 (int x) { return (x - (-1 - __INT_MAX__)) + 10ULL - __INT_MAX__; }
> 
> 	Jakub
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 247165 (AG MÌnchen)

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-09-24 11:13 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-24 10:43 [PATCH] Fold ((T)(A + CST1)) + CST2 -> (T)(A) + (T)CST1 + CST2 for unsigned T and undefined overflow A + CST1 (PR middle-end/91866) Jakub Jelinek
2019-09-24 11:13 ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).