On Tue, May 13, 2014 at 2:36 PM, Richard Biener <richard.guent...@gmail.com> wrote: > On Sun, May 11, 2014 at 5:00 PM, Prathamesh Kulkarni > <bilbotheelffri...@gmail.com> wrote: >> On Sun, May 11, 2014 at 8:10 PM, Andreas Schwab <sch...@linux-m68k.org> >> wrote: >>> Prathamesh Kulkarni <bilbotheelffri...@gmail.com> writes: >>> >>>> a) I am not able to follow why 3 slashes are required here >>>> in x_.\\\(D\\\) ? Why does x_.\(D\) not work ? >>> >>> Two of the three backslashes are eaten by the tcl parser. But actually >>> only two backslashes are needed, since the parens are not special to tcl >>> (but are special to the regexp engine, so you want a single backslash >>> surviving the tcl parser). >>> >>>> b) The expression after folding would be of the form: >>>> t2_<digit> = x_<digit>(D) - y_<digit>(D) >>>> I have used the operator "." in the pattern to match digit. >>>> While that works in the above case, I think a better >>>> idea would be to match using [0-9]. >>>> I tried the following but it does not work: >>>> t_[0-9] = x_[0-9]\\\(D\\\) - y_[0-9]\\\(D\\\) >>>> Neither does \\\[ and \\\] work. >>> >>> Brackets are special in tcl (including inside double quotes), so they >>> need to be quoted. But you want the brackets to appear unquoted to the >>> regexp engine, so a single backslash will do the Right Thing. >>> >>> See tcl(n) for the tcl parsing rules. >>> >> Thanks. Now I get it, the double backslash \\ is an escape sequence >> for \, and special characters like (, [ >> retain their meaning in quotes, so to match input text: (D), the >> pattern has to be written as: "\\(D\\)". >> I believe "\(D\)" would only match D in the input ? >> I have modified the test-case. Is this version correct ? > > I usually verify that by running the testcase in isolation on a GCC version > that should FAIL it and on one that should PASS it (tcl quoting is also > try-and-error for me most of the time...). > > Thus I do > > gcc/> make check-gcc RUNTESTFLAGS="tree-ssa.exp=match-2.c" > <test should FAIL> > <patch source tree> > gcc/> make cc1 > ... compiles cc1 ... > gcc/> make check-gcc RUNTESTFLAGS="tree-ssa.exp=match-2.c" > <test should PASS> > > A more complete matching for an SSA name would be (allowing > for SSA name versions > 9) _\\d\+ with \\(D\\) appended if > suitable (that's usually known from the testcase). \\d\+ should match > at least one decimal digit. I thought that SSA name version wouldn't exceed 9 for that test-case, so I decided for matching only one digit. I will change it to match one or more digits.
* I have written test-cases for patterns in match.pd (attached patch), which result in PASS. Could you review them for me ? I couldn't write for following ones: 1] Patterns involving COMPLEX_EXPR, REALPART_EXPR, IMAGPART_EXPR (match_and_simplify (complex (realpart @0) (imagpart @0)) @0) (match_and_simplify (realpart (complex @0 @1)) @0) (match_and_simplify (imagpart (complex @0 @1)) @1) Sorry to be daft, but I couldn't understand what these patterns meant (I know complex numbers). Could you give an example that matches one of these patterns ? Thanks. 2] Test-case for FMA_EXPR. I am not sure how to generate FMA_EXPR from C code. (match_and_simplify (fma INTEGER_CST_P@0 INTEGER_CST_P@1 @3) (plus (mult @0 @1) @3)) 3] Test-case for COND_EXPR (match_and_simplify (cond (bit_not @0) @1 @2) (cond @0 @2 @1)) I believe cond corresponds to C's ternary operator ? However c-expression of the form: t2 = (x ? y : z) gets translated to gimple as an if-else statement, with "x" being condition, "y" being then-statement, and "z" being else-statement. So I guess we need to handle this case specially in genmatch ? Or am I mistaken ? * I added few patterns from TODO list in match.pd. I am not sure how to write pattern for the following transform: (T) (P + A) - (T) P -> (T) A * ICE for transform sqrt (x * x) -> x The following pattern results in ICE (gimple-match-head.c:546) (match_and_simplify (built_in_sqrt (mult @0 @0)) @0) I triggered the pattern with this test-case: double foo(double x) { double t1, t2; t1 = x * x; t2 = sqrt (t1); return t2; } This happens because the following assert fails in bool gimple_match_and_simplify (gimple_stmt_iterator *gsi, tree (*valueize)(tree)): line 546: gcc_assert (gimple_seq_singleton_p (tail)); I guess that happens because for the above pattern maybe_push_res_to_seq() returns ops[0], and tail remains NULL. if (TREE_CODE_LENGTH ((tree_code) rcode) == 0 && is_gimple_val (ops[0])) return ops[0]; Unfortunately, I couldn't find a fix. I have a couple of questions regarding gimple-match-head.c a) Why do we return if the above condition is true ? I mean why don't we want gimple_build_assign_with_ops to be called if that's true ? Removing that condition in maybe_push_res_to_seq or calling gimple_build_assign_with_ops (rcode, lhs, ops[0], NULL_TREE, NULL_TREE, NULL_TREE); from gimple_match_and_simplify (if maybe_push_res_to_seq returns ops[0]), resulted in verify_ssa failed: missing definition. b) In static bool gimple_match_and_simplify (gimple stmt, code_helper *rcode, tree *ops, gimple_seq *seq, tree (*valueize)(tree)) why do we return false by default (line 491), if number of args is greater than 1 ? Thanks and Regards, Prathamesh > > Richard. > >> Thanks and Regards, >> Prathamesh >> >> >>> Andreas. >>> >>> -- >>> Andreas Schwab, sch...@linux-m68k.org >>> GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 >>> "And now for something completely different."
Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 210330) +++ gcc/match.pd (working copy) @@ -98,6 +98,26 @@ to (minus @1 @0) (T)(P + A) - (T)P -> (T)A */ +/* ~A + A -> -1 */ +(match_and_simplify + (plus (bit_not @0) @0) + if (INTEGRAL_TYPE_P (TREE_TYPE (@0))) + { build_int_cst (TREE_TYPE (@0), -1); }) + +/* ~A + 1 -> -A */ +(match_and_simplify + (plus (bit_not @0) integer_onep) + if (INTEGRAL_TYPE_P (TREE_TYPE (@0))) + (negate @0)) + +/* A - (A +- B) -> -+ B */ +(match_and_simplify + (minus @0 (plus @0 @1)) + (negate @0)) + +(match_and_simplify + (minus @0 (minus @0 @1)) + @1) /* Patterns required to avoid SCCVN testsuite regressions. */ Index: gcc/testsuite/gcc.dg/tree-ssa/match-2.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/match-2.c (revision 0) +++ gcc/testsuite/gcc.dg/tree-ssa/match-2.c (working copy) @@ -0,0 +1,133 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-forwprop" } */ + +/* x + (-y) -> x - y */ +int f1(int x, int y) +{ + int t1, t2; + t1 = -y; + t2 = x + t1; + return t2; +} + +/* x - (-y) -> y + x */ +int f2(int x, int y) +{ + int t1, t2; + t1 = -y; + t2 = x - t1; + return t2; +} + +/* (-x) + y -> y - x */ +int f3(int x, int y) +{ + int t1, t2; + t1 = -x; + t2 = t1 + y; + return t2; +} + +/* (x + y) - x -> y */ +int f4(int x, int y) +{ + int t1, t2; + t1 = x + y; + t2 = t1 - x; + return t2; +} + +/* (x - y) - x -> -y */ +int f5(int x, int y) +{ + int t1, t2; + t1 = x - y; + t2 = t1 - x; + return t2; +} + +/* (x + y) - y -> x */ +int f6(int x, int y) +{ + int t1, t2; + t1 = x + y; + t2 = t1 - y; + return t2; +} + +/* (x - y) + y -> x */ +int f7(int x, int y) +{ + int t1, t2; + t1 = x - y; + t2 = t1 + y; + return t2; +} + +/* (x + cst1) + cst2 -> x + (cst1 + cst2) */ +int f8(int x) +{ + int t1, t2; + t1 = x + 3; + t2 = t1 + 4; + return t2; +} + +/* (cst1 - x) + cst2 -> (cst1 + cst2) - x */ +int f9(int x) +{ + int t1, t2; + t1 = 3 - x; + t2 = t1 + 4; + return t2; +} + +/* (x >> 31) & 1 -> x >> 31 */ +int f10(int x) +{ + int t1, t2; + t1 = x >> 31; + t2 = t1 & 1; + return t2; +} + +/* -(~x) -> x + 1 */ +int f11(int x) +{ + int t1, t2; + t1 = ~x; + t2 = -t1; + return t2; +} + +/* x + ~x -> -1 */ +int f12(int x) +{ + int t1, t2; + t1 = ~x; + t2 = t1 + x; + return t2; +} + +/* ~x + 1 -> -x */ +int f13(int x) +{ + int t1, t2; + t1 = ~x; + t2 = t1 + 1; + return t2; +} + +/* { dg-final { scan-tree-dump-times "t2_\[0-9\] = x_\[0-9\]\\(D\\) - y_\[0-9\]\\(D\\)" 1 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times "t2_\[0-9\] = y_\[0-9\]\\(D\\) \\+ x_\[0-9\]\\(D\\)" 1 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times "t2_\[0-9\] = y_\[0-9\]\\(D\\) - x_\[0-9\]\\(D\\)" 1 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times "t2_\[0-9\] = y_\[0-9\]\\(D\\);" 1 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times "t2_\[0-9\] = -y_\[0-9\]\\(D\\);" 1 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times "t2_\[0-9\] = x_\[0-9\]\\(D\\);" 2 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times "t2_\[0-9\] = x_\[0-9\]\\(D\\) \\+ 7;" 1 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times "t2_\[0-9\] = 7 - x_\[0-9\]\\(D\\);" 1 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times "t2_\[0-9\] = t1_\[0-9\];" 1 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times "t2_\[0-9\] = x_\[0-9\]\\(D\\) \\+ 1;" 1 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times "t2_\[0-9\] = -1;" 1 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times "t2_\[0-9\] = -x_\[0-9\]\\(D\\);" 1 forwprop1 } } */ +/* { dg-final { cleanup-tree-dump "forwprop2" } } */