This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
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];
+ }
+}