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

Reply via email to