On Mon, Jul 14, 2014 at 3:05 PM, Richard Biener <richard.guent...@gmail.com> wrote: > On Mon, Jul 14, 2014 at 12:07 PM, Prathamesh Kulkarni > <bilbotheelffri...@gmail.com> wrote: >> I was wondering if it was a good idea to implement >> predicate on expressions ? >> >> Sth like: >> (match_and_simplify >> (op (op2:predicate @0)) >> transform) >> >> instead of: >> (match_and_simplify >> (op (op2@1 @0)) >> if (predicate (@1)) >> transform) >> >> When predicate is simple as just being a macro/function, >> we could use this style and when the predicate is more complex >> resort to using if-expr (or write the predicate as macro in >> gimple-match-head.c >> and use the macro in pattern instead ...) >> >> Example: >> we could rewrite the pattern >> (match_and_simplify >> (plus:c @0 (negate @1)) >> if (!TYPE_SATURATING (type)) >> (minus @0 @1)) >> >> to >> >> (match_and_simplify >> (plus:c:NOT_TYPE_SATURATING_P @0 (negate @1)) >> (minus @0 @1)) >> >> with NOT_TYPE_SATURATING_P predicate defined >> appropriately in gimple-match-head.c >> >> However I am not entirely sure if adding predicates on expressions >> would be very useful.... > > Well. I think there are two aspects to this. First is pattern > readability where I think that the if-expr form is more readable. > Second is the ability to do less work in the code generated > from the decision tree. > > For example most of the patterns from associate_plusminus > still miss the !TYPE_SATURATING && !FLOAT_TYPE_P && > !FIXED_POINT_TYPE_P if-expr. That is, we'd have > > /* (A +- B) - A -> +-B. */ > (match_and_simplify > (minus (plus @0 @1) @0) > if (!TYPE_SATURATING (type) > && !FLOAT_TYPE_P (type) && !FIXED_POINT_TYPE_P (type)) > @1) > (match_and_simplify > (minus (minus @0 @1) @0) > if (!TYPE_SATURATING (type) > && !FLOAT_TYPE_P (type) && !FIXED_POINT_TYPE_P (type)) > (negate @1)) > /* (A +- B) -+ B -> A. */ > (match_and_simplify > (minus (plus @0 @1) @1) > if (!TYPE_SATURATING (type) > && !FLOAT_TYPE_P (type) && !FIXED_POINT_TYPE_P (type)) > @0) > (match_and_simplify > (plus:c (minus @0 @1) @1) > if (!TYPE_SATURATING (type) > && !FLOAT_TYPE_P (type) && !FIXED_POINT_TYPE_P (type)) > @0) > > with code-generation checking the if-expr after matching. And > with using expression predicates we'd be able to check the > predicate when matching the outermost 'minus' and "CSE" > the predicate check for the first three patterns. Runtime-wise > it depends on whether there is a point to back-track to.
Actually now that I look at the current state of the testsuite on the branch and notice FAIL: gcc.c-torture/execute/20081112-1.c execution, -O1 which points at (match_and_simplify (plus (plus @0 INTEGER_CST_P@1) INTEGER_CST_P@2) (plus @0 (plus @1 @2)) which we may not apply to (a - 1) + INT_MIN as -1 + INT_MIN overflows and a + (-1 + INT_MIN) then introduces undefined signed integer overflow. tree-ssa-forwprop.c checks TREE_OVERFLOW on the result of (plus @1 @2) and disables the simplification properly. We can do the same with re-writing the pattern to (match_and_simplify (plus (plus @0 INTEGER_CST_P@1) INTEGER_CST_P@2) /* If the constant operation overflows we cannot do the transform as we would introduce undefined overflow, for example with (a - 1) + INT_MIN. */ if (!TREE_OVERFLOW (@1 = int_const_binop (PLUS_EXPR, @1, @2))) (plus @0 @1)) also using something I'd like to more formally allow (re-using sth computed in the if-expr in the replacement). But of course writing it this way is ugly and the following would be nicer? (match_and_simplify (plus (plus @0 INTEGER_CST_P@1) INTEGER_CST_P@2) (plus @0 (plus:!TREE_OVERFLOW @1 @2))) ? That would be predicates on replacement expressions ... (also negated predicates). Now it doesn't look all-that-pretty :/ Another possibility is to always fail if TREE_OVERFLOW constants leak into the replacement IL. (but I'd like to avoid those behind-the-backs things at the moment) Richard.