diff options
author | Jakub Jelinek <jakub@gcc.gnu.org> | 2019-12-02 09:51:49 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2019-12-02 09:51:49 +0100 |
commit | a213ab38560f0b95ec318b2a4795e66cc0518848 (patch) | |
tree | 39451dd44a61601d97dcf6462ceede232af61ca9 /gcc/match.pd | |
parent | 9b14fc3326e087975653b1af8ac54114041cde51 (diff) | |
download | gcc-a213ab38560f0b95ec318b2a4795e66cc0518848.zip gcc-a213ab38560f0b95ec318b2a4795e66cc0518848.tar.gz gcc-a213ab38560f0b95ec318b2a4795e66cc0518848.tar.bz2 |
re PR tree-optimization/92712 (Performance regression with assumed values)
PR tree-optimization/92712
* match.pd ((A * B) +- A -> (B +- 1) * A,
A +- (A * B) -> (1 +- B) * A): Allow optimizing signed integers
even when we don't know anything about range of A, but do know
something about range of B and the simplification won't introduce
new UB.
* gcc.dg/tree-ssa/pr92712-1.c: New test.
* gcc.dg/tree-ssa/pr92712-2.c: New test.
* gcc.dg/tree-ssa/pr92712-3.c: New test.
* gfortran.dg/loop_versioning_1.f90: Adjust expected number of
likely to be innermost dimension messages.
* gfortran.dg/loop_versioning_10.f90: Likewise.
* gfortran.dg/loop_versioning_6.f90: Likewise.
From-SVN: r278894
Diffstat (limited to 'gcc/match.pd')
-rw-r--r-- | gcc/match.pd | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/gcc/match.pd b/gcc/match.pd index eabd01f..14f6a9d 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -2480,18 +2480,42 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (plusminus @0 (mult:c@3 @0 @2)) (if ((!ANY_INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_WRAPS (type) + /* For @0 + @0*@2 this transformation would introduce UB + (where there was none before) for @0 in [-1,0] and @2 max. + For @0 - @0*@2 this transformation would introduce UB + for @0 0 and @2 in [min,min+1] or @0 -1 and @2 min+1. */ || (INTEGRAL_TYPE_P (type) - && tree_expr_nonzero_p (@0) - && expr_not_equal_to (@0, wi::minus_one (TYPE_PRECISION (type))))) + && ((tree_expr_nonzero_p (@0) + && expr_not_equal_to (@0, + wi::minus_one (TYPE_PRECISION (type)))) + || (plusminus == PLUS_EXPR + ? expr_not_equal_to (@2, + wi::max_value (TYPE_PRECISION (type), SIGNED)) + /* Let's ignore the @0 -1 and @2 min case. */ + : (expr_not_equal_to (@2, + wi::min_value (TYPE_PRECISION (type), SIGNED)) + && expr_not_equal_to (@2, + wi::min_value (TYPE_PRECISION (type), SIGNED) + + 1)))))) && single_use (@3)) (mult (plusminus { build_one_cst (type); } @2) @0))) (simplify (plusminus (mult:c@3 @0 @2) @0) (if ((!ANY_INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_WRAPS (type) + /* For @0*@2 + @0 this transformation would introduce UB + (where there was none before) for @0 in [-1,0] and @2 max. + For @0*@2 - @0 this transformation would introduce UB + for @0 0 and @2 min. */ || (INTEGRAL_TYPE_P (type) - && tree_expr_nonzero_p (@0) - && expr_not_equal_to (@0, wi::minus_one (TYPE_PRECISION (type))))) + && ((tree_expr_nonzero_p (@0) + && (plusminus == MINUS_EXPR + || expr_not_equal_to (@0, + wi::minus_one (TYPE_PRECISION (type))))) + || expr_not_equal_to (@2, + (plusminus == PLUS_EXPR + ? wi::max_value (TYPE_PRECISION (type), SIGNED) + : wi::min_value (TYPE_PRECISION (type), SIGNED)))))) && single_use (@3)) (mult (plusminus @2 { build_one_cst (type); }) @0)))))) |