On Fri, Apr 22, 2016 at 5:29 AM, Marc Glisse <marc.gli...@inria.fr> wrote: > Hello, > > this optimizes a common pattern for unsigned overflow detection, when one of > the arguments turns out to be a constant. There are more ways this could > look like, (a + 42 <= 41) in particular, but that'll be for another patch.
This case is also covered by fold_comparison which should be re-written to match.pd patterns (and removed from fold-const.c). fold_binary also as a few interesting/similar equality compare cases like X +- Y CMP X to Y CMP 0 which look related. Also your case is in fold_binary for the case of undefined overflow: /* Transform comparisons of the form X +- C CMP X. */ if ((TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR) && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0) && ((TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST && !HONOR_SNANS (arg0)) || (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1))))) { ... +/* When one argument is a constant, overflow detection can be simplified. + Currently restricted to single use so as not to interfere too much with + ADD_OVERFLOW detection in tree-ssa-math-opts.c. */ +(for cmp (lt le ge gt) + out (gt gt le le) + (simplify + (cmp (plus@2 @0 integer_nonzerop@1) @0) + (if (TYPE_UNSIGNED (TREE_TYPE (@0)) + && TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)) + && TYPE_MAX_VALUE (TREE_TYPE (@0)) + && single_use (@2)) + (out @0 (minus { TYPE_MAX_VALUE (TREE_TYPE (@0)); } @1))))) +(for cmp (gt ge le lt) + out (gt gt le le) + (simplify + (cmp @0 (plus@2 @0 integer_nonzerop@1)) + (if (TYPE_UNSIGNED (TREE_TYPE (@0)) + && TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)) + && TYPE_MAX_VALUE (TREE_TYPE (@0)) + && single_use (@2)) + (out @0 (minus { TYPE_MAX_VALUE (TREE_TYPE (@0)); } @1))))) please add a comment with the actual transform - A + CST CMP A -> A CMP' CST' As we are relying on twos-complement wrapping you shouldn't need TYPE_MAX_VALUE here but you can use wi::max_value (precision, sign). I'm not sure we have sensible TYPE_MAX_VALUE for vector or complex types - the accessor uses NUMERICAL_TYPE_CKECK and TYPE_OVERFLOW_WRAPS checks for ANY_INTEGRAL_TYPE. Thus I wonder if we should restrict this to INTEGRAL_TYPE_P (making the wi::max_value route valid). Thanks, Richard. > Bootstrap+regtest on powerpc64le-unknown-linux-gnu. > 2016-04-22 Marc Glisse <marc.gli...@inria.fr> > > gcc/ > * match.pd (X + CST CMP X): New transformation. > > gcc/testsuite/ > * gcc.dg/tree-ssa/overflow-1.c: New testcase. > > -- > Marc Glisse