Hi! As mentioned in the PR, the following patch decreases number of +/- operation when one is inside sign extension, done with undefined overflow, and the outer is using wrapping arithmetics.
The :s as well as the outer + are there in order to make sure it is actually beneficial, that we decrease the number of +/-, either from two to one or from two to zero, depending on whether they cancel each other. The price for the reduction is that we loose information about the undefined behavior for certain @0 values. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2019-09-24 Jakub Jelinek <ja...@redhat.com> PR middle-end/91866 * match.pd (((T)(A)) + CST -> (T)(A + CST)): Formatting fix. (((T)(A + CST1)) + CST2 -> (T)(A) + (T)CST1 + CST2): New optimization. * gcc.dg/tree-ssa/pr91866.c: New test. --- gcc/match.pd.jj 2019-09-21 23:53:52.108385196 +0200 +++ gcc/match.pd 2019-09-24 10:18:58.804114496 +0200 @@ -2265,8 +2265,9 @@ (define_operator_list COND_TERNARY 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 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) @@ -2280,6 +2281,20 @@ (define_operator_list COND_TERNARY ))) #endif +/* ((T)(A + CST1)) + CST2 -> (T)(A) + (T)CST1 + CST2 */ +#if GIMPLE + (for op (plus minus) + (simplify + (plus (convert:s (op:s @0 INTEGER_CST@1)) INTEGER_CST@2) + (if (TREE_CODE (TREE_TYPE (@0)) == INTEGER_TYPE + && TREE_CODE (type) == INTEGER_TYPE + && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (@0)) + && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)) + && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@0)) + && TYPE_OVERFLOW_WRAPS (type)) + (plus (convert @0) (op @2 (convert @1)))))) +#endif + /* ~A + A -> -1 */ (simplify (plus:c (bit_not @0) @0) --- gcc/testsuite/gcc.dg/tree-ssa/pr91866.c.jj 2019-09-24 10:35:34.035784152 +0200 +++ gcc/testsuite/gcc.dg/tree-ssa/pr91866.c 2019-09-24 10:36:59.858463024 +0200 @@ -0,0 +1,12 @@ +/* PR middle-end/91866 */ +/* { dg-do compile { target { ilp32 || lp64 } } } */ +/* { dg-options "-O2 -fdump-tree-optimized" } * / +/* { dg-final { scan-tree-dump-times " \\+ 11;" 3 "optimized" } } */ +/* { dg-final { scan-tree-dump-times " \[+-] \[0-9-]\[0-9]*;" 3 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\\(long long unsigned int\\) x_" 5 "optimized" } } */ + +unsigned long long f1 (int x) { return (x + 1) - 1ULL; } +unsigned long long f2 (int x) { return (x - 5) + 5ULL; } +unsigned long long f3 (int x) { return (x - 15) + 26ULL; } +unsigned long long f4 (int x) { return (x + 6) + 5ULL; } +unsigned long long f5 (int x) { return (x - (-1 - __INT_MAX__)) + 10ULL - __INT_MAX__; } Jakub