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" } } */

Reply via email to