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 <rd...@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 <rd...@linux.ibm.com> * trans-intrinsic.c (gfc_conv_intrinsic_findloc): Initialize to prevent "maybe used uninitialized". -- gcc/ChangeLog: 2019-08-21 Robin Dapp <rd...@linux.ibm.com> * match.pd: Add (T)(A) + CST -> (T)(A + CST). gcc/testsuite/ChangeLog: 2019-08-21 Robin Dapp <rd...@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]; + } +}