diff options
author | Robin Dapp <rdapp@linux.ibm.com> | 2019-08-26 10:24:44 +0000 |
---|---|---|
committer | Robin Dapp <rdapp@gcc.gnu.org> | 2019-08-26 10:24:44 +0000 |
commit | df7d46d925c7baca7bf9961aee900876d8aef225 (patch) | |
tree | 052e129ae6ca3d130003a8d22424156f81b471c3 /gcc/match.pd | |
parent | e944354ec05891474b0d204c6c239c04ee7b527b (diff) |
[PATCH 2/2] Add simplify rule for wrapped addition.
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
Diffstat (limited to 'gcc/match.pd')
-rw-r--r-- | gcc/match.pd | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/gcc/match.pd b/gcc/match.pd index 93dcef9d66d..13e41a933f7 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -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) |