This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 2/3] Add simplify rules for wrapped binary operations.


I'm going to commit the attached two patches.  Removed the redundant
changes in test cases and added constructor initialization of
fold_all_stmts.

Regards
 Robin

--

gcc/ChangeLog:

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

	* gimple-loop-versioning.cc (loop_versioning::record_address_fragment):
	Add nop_convert case.
	* tree-ssa-propagate.c
(substitute_and_fold_dom_walker::before_dom_children):
	Fold all statements if requested.
	* tree-ssa-propagate.h (class substitute_and_fold_engine):
	Allow to fold all statements.
	* tree-vrp.c (class vrp_folder):
	Let substitute_and_fold_engine fold all statements.

gcc/fortran/ChangeLog:

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

	* trans-intrinsic.c (gfc_conv_intrinsic_findloc): Initialize
	to prevent "maybe used uninitialized".

--

gcc/ChangeLog:

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

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

gcc/testsuite/ChangeLog:

2019-08-21  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.
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index a6e33833680..99ec5f34319 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -5428,8 +5428,9 @@ gfc_conv_intrinsic_findloc (gfc_se *se, gfc_expr *expr)
   tree type;
   tree tmp;
   tree found;
-  tree forward_branch;
-  tree back_branch;
+  /* Initialize here to avoid 'maybe used uninitialized'.  */
+  tree forward_branch = NULL_TREE;
+  tree back_branch = NULL_TREE;
   gfc_loopinfo loop;
   gfc_ss *arrayss;
   gfc_ss *maskss;
diff --git a/gcc/gimple-loop-versioning.cc b/gcc/gimple-loop-versioning.cc
index 8fa19488490..35344b7b448 100644
--- a/gcc/gimple-loop-versioning.cc
+++ b/gcc/gimple-loop-versioning.cc
@@ -1266,6 +1266,12 @@ loop_versioning::record_address_fragment (gimple *stmt,
 		  continue;
 		}
 	    }
+	  if (CONVERT_EXPR_CODE_P (code))
+	    {
+	      tree op1 = gimple_assign_rhs1 (assign);
+	      address->terms[i].expr = strip_casts (op1);
+	      continue;
+	    }
 	}
       i += 1;
     }
diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c
index 0862f83e9a1..7172ef8b4e6 100644
--- a/gcc/tree-ssa-propagate.c
+++ b/gcc/tree-ssa-propagate.c
@@ -814,7 +814,6 @@ ssa_propagation_engine::ssa_propagate (void)
   ssa_prop_fini ();
 }
 
-
 /* Return true if STMT is of the form 'mem_ref = RHS', where 'mem_ref'
    is a non-volatile pointer dereference, a structure reference or a
    reference to a single _DECL.  Ignore volatile memory references
@@ -1071,6 +1070,14 @@ substitute_and_fold_dom_walker::before_dom_children (basic_block bb)
 	  stmt = gsi_stmt (i);
 	  gimple_set_modified (stmt, true);
 	}
+      /* Also fold if we want to fold all statements.  */
+      else if (substitute_and_fold_engine->fold_all_stmts
+	  && fold_stmt (&i, follow_single_use_edges))
+	{
+	  did_replace = true;
+	  stmt = gsi_stmt (i);
+	  gimple_set_modified (stmt, true);
+	}
 
       /* Some statements may be simplified using propagator
 	 specific information.  Do this before propagating
diff --git a/gcc/tree-ssa-propagate.h b/gcc/tree-ssa-propagate.h
index 81b635e0787..f79c2ffadf3 100644
--- a/gcc/tree-ssa-propagate.h
+++ b/gcc/tree-ssa-propagate.h
@@ -100,6 +100,8 @@ class ssa_propagation_engine
 class substitute_and_fold_engine
 {
  public:
+  substitute_and_fold_engine (bool fold_all_stmts = false)
+    : fold_all_stmts (fold_all_stmts) { }
   virtual ~substitute_and_fold_engine (void) { }
   virtual bool fold_stmt (gimple_stmt_iterator *) { return false; }
   virtual tree get_value (tree) { return NULL_TREE; }
@@ -107,6 +109,10 @@ class substitute_and_fold_engine
   bool substitute_and_fold (basic_block = NULL);
   bool replace_uses_in (gimple *);
   bool replace_phi_args_in (gphi *);
+
+  /* Users like VRP can set this when they want to perform
+     folding for every propagation.  */
+  bool fold_all_stmts;
 };
 
 #endif /* _TREE_SSA_PROPAGATE_H  */
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index e2850682da2..1cba9b4d180 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -6257,6 +6257,7 @@ vrp_prop::visit_phi (gphi *phi)
 class vrp_folder : public substitute_and_fold_engine
 {
  public:
+  vrp_folder () : substitute_and_fold_engine (/* Fold all stmts.  */ true) {  }
   tree get_value (tree) FINAL OVERRIDE;
   bool fold_stmt (gimple_stmt_iterator *) FINAL OVERRIDE;
   bool fold_predicate_in (gimple_stmt_iterator *);
diff --git a/gcc/match.pd b/gcc/match.pd
index 0317bc704f7..22282615f84 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2020,6 +2020,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)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-5.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-5.c
index 3d9940558cb..42e0ed96595 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-5.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-5.c
@@ -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)
 {
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c
index a0a6e6a9b57..3c9b3807041 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c
@@ -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)
 {
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-15.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-15.c
index b437518487d..dce6ad57a04 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loop-15.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-15.c
@@ -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.  */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23744.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23744.c
index 3385aa1e424..ba3fda352ca 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr23744.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr23744.c
@@ -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
index 00000000000..44d85c04bfb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/wrapped-binop-simplify.c
@@ -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];
+  }
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]