On Sun, Oct 8, 2017 at 1:22 PM, Marc Glisse <marc.gli...@inria.fr> wrote: > Hello, > > this moves (and extends a bit) one more transformation from fold-const.c to > match.pd. The single_use restriction is necessary for consistency with the > existing X+CST1 CMP CST2 transformation (if we do only one of the 2 > transformations, gcc.dg/tree-ssa/vrp54.c regresses because DOM fails to > simplify 2 conditions based on different variables). The relaxation of the > condition to simplify (T) X == (T) Y is an easier way to avoid regressing > gcc.dg/tree-ssa/foldaddr-1.c than adding plenty of convert? in the patterns, > although that may still prove necessary at some point. I left a few odd > float cases in fold-const.c for later.
+/* X + Y < Y is the same as X < 0 when there is no overflow. */ +(for op (lt le ge gt) + rop (gt ge le lt) + (simplify + (op (plus:c@2 @0 @1) @1) + (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)) + && (CONSTANT_CLASS_P (@0) || single_use (@2))) + (op @0 { build_zero_cst (TREE_TYPE (@0)); }))) + (simplify + (op @1 (plus:c@2 @0 @1)) + (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)) + && (CONSTANT_CLASS_P (@0) || single_use (@2))) + (rop @0 { build_zero_cst (TREE_TYPE (@0)); })))) any reason (op:c (plus... on the first of the two patterns wouldn't have catched the second? :c on comparison swaps the comparison code. +/* For equality, this is also true with wrapping overflow. */ +(for op (eq ne) + (simplify + (op:c (plus:c@2 @0 @1) @1) + (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)) + || TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))) + && (CONSTANT_CLASS_P (@0) || single_use (@2))) + (op @0 { build_zero_cst (TREE_TYPE (@0)); }))) + (simplify + (op:c (convert?@3 (pointer_plus@2 @0 @1)) (convert? @0)) + (if (CONSTANT_CLASS_P (@1) || (single_use (@2) && single_use (@3))) + (op @1 { build_zero_cst (TREE_TYPE (@1)); })))) for consistency can you add the convert?s to the integer variant as well? I'm not sure you'll see the convers like you write them (with matching @0). Eventually on GENERIC when we still have pointer conversions around? You are allowing arbitrary conversions here - is that desired? Isn't a tree_nop_conversion_p missing? > We could add a strict overflow warning to the transformations, there are > already examples in match.pd, but experience shows that it mostly confuses > users (if we do add it, we should at least restrict it to GENERIC or remove > it from -Wall). My plan, unless reviewers complain, is to list the 2 xfailed > testcases in PR80511. Works for me. > It is inconvenient that :s is ignored when the output is a single > instruction, there are now quite a few transformations that call single_use > manually but would be ok with a :S that is only ignored if the output is a > constant (or SSA_NAME?). On the other hand, not having a shotcut makes it > more likely we'll tailor the heuristic to each transformation. I know -- the situation isn't very satisfying but unless the places we call into match-and-simplify apply some sort of a cost-model it's going to be like it is. Note that each single_use () check possibly pessimizes value-numbering which uses this for expression simplification. Richard. > Bootstrap+testsuite on powerpc64le-unknown-linux-gnu. > > 2017-10-09 Marc Glisse <marc.gli...@inria.fr> > > gcc/ > * fold-const.c (fold_binary_loc) [X +- Y CMP X]: Move ... > * match.pd: ... here. > ((T) X == (T) Y): Relax condition. > > gcc/testsuite/ > * gcc.dg/Wstrict-overflow-7.c: Xfail. > * gcc.dg/pragma-diag-3.c: Likewise. > > -- > Marc Glisse