Re: [PATCH, PR62167] Fix tail-merge pass for dead type-unsafe code

2014-11-19 Thread Richard Biener
On Tue, 18 Nov 2014, Tom de Vries wrote:

 Richard,
 
 this (trunk) patch fixes PR62167.
 
 The patch fixes a problem that triggers with the test-case on the 4.8 branch,
 when tail-merge makes a dead type-unsafe load alive.
 
 I'm not able to reproduce this bug on 4.9 and trunk with the same test-case.
 On those branches, the tail-merge already does not happen.
 
 The reason for the difference is as follows: With 4.8 the two phi arguments of
 the phi in the tail block are value-numbered identically:
 ...
 SCC consists of: p_14
 Value numbering p_14 stmt = p_14 = MEM[(struct head *)_13].first;
 Setting value number of p_14 to p_14 (changed)
 
 SCC consists of: p_15
 Value numbering p_15 stmt = p_15 = _13-next;
 Setting value number of p_15 to p_14 (changed)
 ...
 
 With 4.9 (and trunk), that's not the case:
 ...
 SCC consists of: p_14
 Value numbering p_14 stmt = p_14 = MEM[(struct head *)heads][k.1_9].first;
 Setting value number of p_14 to p_14 (changed)
 
 SCC consists of: p_15
 Value numbering p_15 stmt = p_15 = _13-next;
 Setting value number of p_15 to p_15 (changed)
 ...
 
 I'm not sure the bug triggers on trunk and 4.9, but I see no reason why it
 could not trigger, so I'd prefer to apply the patch to 4.9 and trunk as well.
 
 The patch introduces an xfail for pr51879-12.c. I can follow up with a patch
 to improve upon that, but I think that's better limited to trunk only.

Yeah.

 Bootstrapped and reg-tested on x86_64/trunk.
 
 OK for trunk/stage3, 4.8, 4.9?

Ok.  Note that this goes well with disabling the (re-)use of 
value-numbering in tail-merging (which causes me quite some headaches...).
On trunk it shouldn't be necessary as much as it was earlier as we now
fully propagate constants and copies during FRE/PRE elimination.

Thanks,
Richard.


Re: [PATCH, PR62167] Fix tail-merge pass for dead type-unsafe code

2014-11-19 Thread Richard Biener
On Tue, 18 Nov 2014, Jeff Law wrote:

 On 11/18/14 09:57, Tom de Vries wrote:
  Richard,
  
  this (trunk) patch fixes PR62167.
  
  The patch fixes a problem that triggers with the test-case on the 4.8
  branch, when tail-merge makes a dead type-unsafe load alive.
  
  I'm not able to reproduce this bug on 4.9 and trunk with the same
  test-case. On those branches, the tail-merge already does not happen.
  
  The reason for the difference is as follows: With 4.8 the two phi
  arguments of the phi in the tail block are value-numbered identically:
  ...
  SCC consists of: p_14
  Value numbering p_14 stmt = p_14 = MEM[(struct head *)_13].first;
  Setting value number of p_14 to p_14 (changed)
  
  SCC consists of: p_15
  Value numbering p_15 stmt = p_15 = _13-next;
  Setting value number of p_15 to p_14 (changed)
  ...
  
  With 4.9 (and trunk), that's not the case:
  ...
  SCC consists of: p_14
  Value numbering p_14 stmt = p_14 = MEM[(struct head *)heads][k.1_9].first;
  Setting value number of p_14 to p_14 (changed)
  
  SCC consists of: p_15
  Value numbering p_15 stmt = p_15 = _13-next;
  Setting value number of p_15 to p_15 (changed)
  ...
  
  I'm not sure the bug triggers on trunk and 4.9, but I see no reason why
  it could not trigger, so I'd prefer to apply the patch to 4.9 and trunk
  as well.
  
  The patch introduces an xfail for pr51879-12.c. I can follow up with a
  patch to improve upon that, but I think that's better limited to trunk
  only.
  
  Bootstrapped and reg-tested on x86_64/trunk.
 So instead of simply disabling for anything with virtual operands, shouldn't
 instead we be comparing the virtual operands and alias information?  Seems to
 me that if we did that properly, this would just work.  Right?

But that would simply use operand_equal_p () 

Richard.


[PATCH, PR62167] Fix tail-merge pass for dead type-unsafe code

2014-11-18 Thread Tom de Vries

Richard,

this (trunk) patch fixes PR62167.

The patch fixes a problem that triggers with the test-case on the 4.8 branch, 
when tail-merge makes a dead type-unsafe load alive.


I'm not able to reproduce this bug on 4.9 and trunk with the same test-case. On 
those branches, the tail-merge already does not happen.


The reason for the difference is as follows: With 4.8 the two phi arguments of 
the phi in the tail block are value-numbered identically:

...
SCC consists of: p_14
Value numbering p_14 stmt = p_14 = MEM[(struct head *)_13].first;
Setting value number of p_14 to p_14 (changed)

SCC consists of: p_15
Value numbering p_15 stmt = p_15 = _13-next;
Setting value number of p_15 to p_14 (changed)
...

With 4.9 (and trunk), that's not the case:
...
SCC consists of: p_14
Value numbering p_14 stmt = p_14 = MEM[(struct head *)heads][k.1_9].first;
Setting value number of p_14 to p_14 (changed)

SCC consists of: p_15
Value numbering p_15 stmt = p_15 = _13-next;
Setting value number of p_15 to p_15 (changed)
...

I'm not sure the bug triggers on trunk and 4.9, but I see no reason why it could 
not trigger, so I'd prefer to apply the patch to 4.9 and trunk as well.


The patch introduces an xfail for pr51879-12.c. I can follow up with a patch to 
improve upon that, but I think that's better limited to trunk only.


Bootstrapped and reg-tested on x86_64/trunk.

OK for trunk/stage3, 4.8, 4.9?

Thanks,
- Tom
2014-11-17  Tom de Vries  t...@codesourcery.com

	PR tree-optimization/62167
	* tree-ssa-tail-merge.c (stmt_local_def): Handle statements with vuse
	conservatively.
	(gimple_equal_p): Don't use vn_valueize to compare for lhs equality of
	assigns.

	* gcc.dg/pr51879-12.c: Add xfails.
	* gcc.dg/pr62167-run.c: New test.
	* gcc.dg/pr62167.c: New test.
---
 gcc/testsuite/gcc.dg/pr51879-12.c  |  4 +--
 gcc/testsuite/gcc.dg/pr62167-run.c | 47 +++
 gcc/testsuite/gcc.dg/pr62167.c | 50 ++
 gcc/tree-ssa-tail-merge.c  |  6 +++--
 4 files changed, 103 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr62167-run.c
 create mode 100644 gcc/testsuite/gcc.dg/pr62167.c

diff --git a/gcc/testsuite/gcc.dg/pr51879-12.c b/gcc/testsuite/gcc.dg/pr51879-12.c
index 8126505..85e2687 100644
--- a/gcc/testsuite/gcc.dg/pr51879-12.c
+++ b/gcc/testsuite/gcc.dg/pr51879-12.c
@@ -24,6 +24,6 @@ foo (int y)
   baz (a);
 }
 
-/* { dg-final { scan-tree-dump-times bar \\( 1 pre} } */
-/* { dg-final { scan-tree-dump-times bar2 \\( 1 pre} } */
+/* { dg-final { scan-tree-dump-times bar \\( 1 pre { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times bar2 \\( 1 pre { xfail *-*-* } } } */
 /* { dg-final { cleanup-tree-dump pre } } */
diff --git a/gcc/testsuite/gcc.dg/pr62167-run.c b/gcc/testsuite/gcc.dg/pr62167-run.c
new file mode 100644
index 000..37214a3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr62167-run.c
@@ -0,0 +1,47 @@
+/* { dg-do run } */
+/* { dg-options -O2 -ftree-tail-merge } */
+
+struct node
+{
+  struct node *next;
+  struct node *prev;
+};
+
+struct node node;
+
+struct head
+{
+  struct node *first;
+};
+
+struct head heads[5];
+
+int k = 2;
+
+struct head *head = heads[2];
+
+int
+main ()
+{
+  struct node *p;
+
+  node.next = (void*)0;
+
+  node.prev = (void *)head;
+
+  head-first = node;
+
+  struct node *n = head-first;
+
+  struct head *h = heads[k];
+
+  heads[2].first = n-next;
+
+  if ((void*)n-prev == (void *)h)
+p = h-first;
+  else
+/* Dead tbaa-unsafe load from ((struct node *)heads[2])-next.  */
+p = n-prev-next;
+
+  return !(p == (void*)0);
+}
diff --git a/gcc/testsuite/gcc.dg/pr62167.c b/gcc/testsuite/gcc.dg/pr62167.c
new file mode 100644
index 000..f8c31a0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr62167.c
@@ -0,0 +1,50 @@
+/* { dg-do compile } */
+/* { dg-options -O2 -ftree-tail-merge -fdump-tree-pre } */
+
+struct node
+{
+  struct node *next;
+  struct node *prev;
+};
+
+struct node node;
+
+struct head
+{
+  struct node *first;
+};
+
+struct head heads[5];
+
+int k = 2;
+
+struct head *head = heads[2];
+
+int
+main ()
+{
+  struct node *p;
+
+  node.next = (void*)0;
+
+  node.prev = (void *)head;
+
+  head-first = node;
+
+  struct node *n = head-first;
+
+  struct head *h = heads[k];
+
+  heads[2].first = n-next;
+
+  if ((void*)n-prev == (void *)h)
+p = h-first;
+  else
+/* Dead tbaa-unsafe load from ((struct node *)heads[2])-next.  */
+p = n-prev-next;
+
+  return !(p == (void*)0);
+}
+
+/* { dg-final { scan-tree-dump-not Removing basic block pre} } */
+/* { dg-final { cleanup-tree-dump pre } } */
diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
index 303bd5e..1651985 100644
--- a/gcc/tree-ssa-tail-merge.c
+++ b/gcc/tree-ssa-tail-merge.c
@@ -326,7 +326,8 @@ stmt_local_def (gimple stmt)
 
   if (gimple_vdef (stmt) != NULL_TREE
   || gimple_has_side_effects (stmt)
-  || gimple_could_trap_p_1 (stmt, false, false))
+  || gimple_could_trap_p_1 

Re: [PATCH, PR62167] Fix tail-merge pass for dead type-unsafe code

2014-11-18 Thread Jeff Law

On 11/18/14 09:57, Tom de Vries wrote:

Richard,

this (trunk) patch fixes PR62167.

The patch fixes a problem that triggers with the test-case on the 4.8
branch, when tail-merge makes a dead type-unsafe load alive.

I'm not able to reproduce this bug on 4.9 and trunk with the same
test-case. On those branches, the tail-merge already does not happen.

The reason for the difference is as follows: With 4.8 the two phi
arguments of the phi in the tail block are value-numbered identically:
...
SCC consists of: p_14
Value numbering p_14 stmt = p_14 = MEM[(struct head *)_13].first;
Setting value number of p_14 to p_14 (changed)

SCC consists of: p_15
Value numbering p_15 stmt = p_15 = _13-next;
Setting value number of p_15 to p_14 (changed)
...

With 4.9 (and trunk), that's not the case:
...
SCC consists of: p_14
Value numbering p_14 stmt = p_14 = MEM[(struct head *)heads][k.1_9].first;
Setting value number of p_14 to p_14 (changed)

SCC consists of: p_15
Value numbering p_15 stmt = p_15 = _13-next;
Setting value number of p_15 to p_15 (changed)
...

I'm not sure the bug triggers on trunk and 4.9, but I see no reason why
it could not trigger, so I'd prefer to apply the patch to 4.9 and trunk
as well.

The patch introduces an xfail for pr51879-12.c. I can follow up with a
patch to improve upon that, but I think that's better limited to trunk
only.

Bootstrapped and reg-tested on x86_64/trunk.
So instead of simply disabling for anything with virtual operands, 
shouldn't instead we be comparing the virtual operands and alias 
information?  Seems to me that if we did that properly, this would just 
work.  Right?



jeff