[PATCH 2/2] Add simplify rule for wrapped addition.
authorRobin Dapp <rdapp@linux.ibm.com>
Mon, 26 Aug 2019 10:24:44 +0000 (10:24 +0000)
committerRobin Dapp <rdapp@gcc.gnu.org>
Mon, 26 Aug 2019 10:24:44 +0000 (10:24 +0000)
Add the transform (T)(A) + CST -> (T)(A + CST).  This enables vrp to
simplify sequences like

_2 = a_7 - 1;
_3 = (long unsigned int) _2;
_5 = _3 + 1

that ivopts creates.

--

gcc/ChangeLog:

2019-08-26  Robin Dapp  <rdapp@linux.ibm.com>

        * match.pd: Add (T)(A) + CST -> (T)(A + CST).

gcc/testsuite/ChangeLog:

2019-08-26  Robin Dapp  <rdapp@linux.ibm.com>

        * gcc.dg/tree-ssa/copy-headers-5.c: Do not run vrp pass.
        * gcc.dg/tree-ssa/copy-headers-7.c: Do not run vrp pass.
        * gcc.dg/tree-ssa/loop-15.c: Remove XFAIL.
        * gcc.dg/tree-ssa/pr23744.c: Change search pattern.
        * gcc.dg/wrapped-binop-simplify.c: New test.

From-SVN: r274925

gcc/ChangeLog
gcc/match.pd
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/copy-headers-5.c
gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c
gcc/testsuite/gcc.dg/tree-ssa/loop-15.c
gcc/testsuite/gcc.dg/tree-ssa/pr23744.c
gcc/testsuite/gcc.dg/wrapped-binop-simplify.c [new file with mode: 0644]

index f5acb32756baf47ac9f37f3e50eb22fca6973aad..abccd69b1e4dfc5eb3f7698675c194920fbe8bb2 100644 (file)
@@ -1,3 +1,7 @@
+2019-08-26  Robin Dapp  <rdapp@linux.ibm.com>
+
+       * match.pd: Add (T)(A) + CST -> (T)(A + CST).
+
 2019-08-26  Robin Dapp  <rdapp@linux.ibm.com>
 
        * gimple-loop-versioning.cc (loop_versioning::record_address_fragment):
index 93dcef9d66db17a1f9afb4f7282a6a113abea96d..13e41a933f7430405a47705562fc090cca2368b5 100644 (file)
@@ -2022,6 +2022,37 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
     (if (cst && !TREE_OVERFLOW (cst))
      (plus { cst; } @0))))
 
+/* ((T)(A)) + CST -> (T)(A + CST)  */
+#if GIMPLE
+  (simplify
+   (plus (convert SSA_NAME@0) INTEGER_CST@1)
+    (if (TREE_CODE (TREE_TYPE (@0)) == INTEGER_TYPE
+         && TREE_CODE (type) == INTEGER_TYPE
+         && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (@0))
+         && int_fits_type_p (@1, TREE_TYPE (@0)))
+     /* Perform binary operation inside the cast if the constant fits
+        and (A + CST)'s range does not overflow.  */
+     (with
+      {
+       wi::overflow_type min_ovf = wi::OVF_OVERFLOW,
+                         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 wmin0, wmax0;
+        if (get_range_info (@0, &wmin0, &wmax0) == VR_RANGE)
+          {
+            wi::add (wmin0, w1, TYPE_SIGN (inner_type), &min_ovf);
+            wi::add (wmax0, w1, TYPE_SIGN (inner_type), &max_ovf);
+          }
+      }
+     (if (min_ovf == wi::OVF_NONE && max_ovf == wi::OVF_NONE)
+      (convert (plus @0 { wide_int_to_tree (TREE_TYPE (@0), w1); } )))
+     )))
+#endif
+
   /* ~A + A -> -1 */
   (simplify
    (plus:c (bit_not @0) @0)
index dd4d9b7b631b3b5c48a0f380b79f8c9697892ed1..c7bf9cc0e2f82251359d83553ec13dc95deb2b42 100644 (file)
@@ -1,3 +1,11 @@
+2019-08-26  Robin Dapp  <rdapp@linux.ibm.com>
+
+       * gcc.dg/tree-ssa/copy-headers-5.c: Do not run vrp pass.
+       * gcc.dg/tree-ssa/copy-headers-7.c: Do not run vrp pass.
+       * gcc.dg/tree-ssa/loop-15.c: Remove XFAIL.
+       * gcc.dg/tree-ssa/pr23744.c: Change search pattern.
+       * gcc.dg/wrapped-binop-simplify.c: New test.
+
 2019-08-26  Kito Cheng  <kito.cheng@sifive.com>
 
        * gcc.target/riscv/li.c: New test.
index 3d9940558cbe94b020c9af70c8986647883074d0..42e0ed965950bf291dc08e34769c58fbedc914dd 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-ch2-details" } */
+/* { dg-options "-O2 -fno-tree-vrp -fdump-tree-ch2-details" } */
 
 int is_sorted(int *a, int n)
 {
index a0a6e6a9b570f158dbd1b8bc18bb8ebc3663aaea..3c9b3807041dd565597279e51200ae318d092ef7 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-ch2-details --param logical-op-non-short-circuit=0" } */
+/* { dg-options "-O2 -fno-tree-vrp -fdump-tree-ch2-details --param logical-op-non-short-circuit=0" } */
 
 int is_sorted(int *a, int n, int m, int k)
 {
index b437518487d73bac9e4999107e5e64315b74c128..dce6ad57a04938a955141cfe1814b861b07866ca 100644 (file)
@@ -19,7 +19,7 @@ int bla(void)
 }
 
 /* Since the loop is removed, there should be no addition.  */
-/* { dg-final { scan-tree-dump-times " \\+ " 0 "optimized" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times " \\+ " 0 "optimized" } } */
 /* { dg-final { scan-tree-dump-times " \\* " 1 "optimized" } } */
 
 /* The if from the loop header copying remains in the code.  */
index 3385aa1e42483cf5089b55b2f6c608ba0bfa863c..ba3fda352ca33d7ce8da58bb8f17f7d4c2debd24 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fno-tree-ccp -fdisable-tree-evrp -fdump-tree-vrp1" } */
+/* { dg-options "-O2 -fno-tree-ccp -fdisable-tree-evrp -fdump-tree-vrp1-details" } */
 
 void h (void);
 
@@ -17,4 +17,4 @@ int g (int i, int j)
     return 1;
 }
 
-/* { dg-final { scan-tree-dump-times "Folding predicate.*to 1" 1 "vrp1" } } */
+/* { dg-final { scan-tree-dump-times "gimple_simplified" 1 "vrp1" } } */
diff --git a/gcc/testsuite/gcc.dg/wrapped-binop-simplify.c b/gcc/testsuite/gcc.dg/wrapped-binop-simplify.c
new file mode 100644 (file)
index 0000000..44d85c0
--- /dev/null
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp2-details" } */
+/* { dg-final { scan-tree-dump-times "gimple_simplified to" 4 "vrp2" } } */
+
+void v1 (unsigned long *in, unsigned long *out, unsigned int n)
+{
+  int i;
+
+  for (i = 0; i < n; i++)
+  {
+    out[i] = in[i];
+  }
+}
+
+void v2 (unsigned long *in, unsigned long *out, int n)
+{
+  int i;
+
+  for (i = 0; i < n; i++)
+  {
+    out[i] = in[i];
+  }
+}
+
+void v3 (unsigned long *in, unsigned long *out, unsigned int n)
+{
+  unsigned int i;
+
+  for (i = 0; i < n; i++)
+  {
+    out[i] = in[i];
+  }
+}
+
+void v4 (unsigned long *in, unsigned long *out, int n)
+{
+  unsigned int i;
+
+  for (i = 0; i < n; i++)
+  {
+    out[i] = in[i];
+  }
+}