diff mbox

tail merge ICE

Message ID 358455dd-7f46-02d8-fc37-05c5ddd7d900@codesourcery.com
State New
Headers show

Commit Message

Nathan Sidwell May 4, 2016, 5:25 p.m. UTC
This patch fixes an ICE Thomas observed in tree-ssa-tail-merge.c:

On 05/03/16 06:34, Thomas Schwinge wrote:

> I'm also seeing the following regression for C and C++,
> libgomp.oacc-c-c++-common/loop-auto-1.c with -O2:
>
>     source-gcc/libgomp/testsuite/libgomp.oacc-c-c++-common/loop-auto-1.c: In function 'vector_1._omp_fn.0':
>     source-gcc/libgomp/testsuite/libgomp.oacc-c-c++-common/loop-auto-1.c:104:9: internal compiler error: Segmentation fault
>      #pragma acc parallel num_workers (32) vector_length(32) copy(ary[0:size]) firstprivate (size)
>              ^
>
>     #4  0x0000000000f73d46 in internal_error (gmsgid=gmsgid@entry=0x105be63 "%s")
>         at [...]/source-gcc/gcc/diagnostic.c:1270
>     #5  0x00000000009fccb0 in crash_signal (signo=<optimized out>)
>         at [...]/source-gcc/gcc/toplev.c:333
>     #6  <signal handler called>
>     #7  0x0000000000beaf2e in same_succ_flush_bb (bb=<optimized out>, bb=<optimized out>)
>         at [...]/source-gcc/gcc/hash-table.h:919
>     #8  0x0000000000bec499 in same_succ_flush_bbs (bbs=<optimized out>)
>         at [...]/source-gcc/gcc/tree-ssa-tail-merge.c:823

What's happening is we're trying to delete an object from a hash table, and 
asserting that we did indeed find the object.  The hash's equality function 
compares gimple sequences and ends up calling gimple_call_same_target_p.  That 
returns false if the call is IFN_UNIQUE, and so the deletion fails to find 
anything.  IFN_UNIQUE function calls should not compare equal, but they should 
compare eq (in the lispy sense).

The local fix is to augment the hash compare function with a check for pointer 
equality.  That way deleting items from the table works and comparing different 
sequences functions as before.

The more general fix is to augment gimple_call_same_target_p so that unique fns 
are eq but not equal.  A cursory look at the other users of that function did 
not indicate this currently causes a problem, but IMHO it is odd for a value to 
not compare the same as itself -- though IEEE NaNs do that :)

I placed the pointer equality comparison in gimple_call_same_target_p after the 
check for unique_fn_p, as I suspect that it is the rare case for that to be 
called with the same gimple call object for both parameters.  Although pointer 
equality would be applicable to all cases, in most instances it's going to be false.

Of course, the gimple_call_same_target_p change fixes the problem on its own, 
but the local change to same_succ::equal seems beneficial on its own merits.

ok?

nathan

Comments

Richard Biener May 6, 2016, 10:31 a.m. UTC | #1
On Wed, May 4, 2016 at 7:25 PM, Nathan Sidwell <nathan@codesourcery.com> wrote:
> This patch fixes an ICE Thomas observed in tree-ssa-tail-merge.c:
>
> On 05/03/16 06:34, Thomas Schwinge wrote:
>
>> I'm also seeing the following regression for C and C++,
>> libgomp.oacc-c-c++-common/loop-auto-1.c with -O2:
>>
>>     source-gcc/libgomp/testsuite/libgomp.oacc-c-c++-common/loop-auto-1.c:
>> In function 'vector_1._omp_fn.0':
>>
>> source-gcc/libgomp/testsuite/libgomp.oacc-c-c++-common/loop-auto-1.c:104:9:
>> internal compiler error: Segmentation fault
>>      #pragma acc parallel num_workers (32) vector_length(32)
>> copy(ary[0:size]) firstprivate (size)
>>              ^
>>
>>     #4  0x0000000000f73d46 in internal_error
>> (gmsgid=gmsgid@entry=0x105be63 "%s")
>>         at [...]/source-gcc/gcc/diagnostic.c:1270
>>     #5  0x00000000009fccb0 in crash_signal (signo=<optimized out>)
>>         at [...]/source-gcc/gcc/toplev.c:333
>>     #6  <signal handler called>
>>     #7  0x0000000000beaf2e in same_succ_flush_bb (bb=<optimized out>,
>> bb=<optimized out>)
>>         at [...]/source-gcc/gcc/hash-table.h:919
>>     #8  0x0000000000bec499 in same_succ_flush_bbs (bbs=<optimized out>)
>>         at [...]/source-gcc/gcc/tree-ssa-tail-merge.c:823
>
>
> What's happening is we're trying to delete an object from a hash table, and
> asserting that we did indeed find the object.  The hash's equality function
> compares gimple sequences and ends up calling gimple_call_same_target_p.
> That returns false if the call is IFN_UNIQUE, and so the deletion fails to
> find anything.  IFN_UNIQUE function calls should not compare equal, but they
> should compare eq (in the lispy sense).
>
> The local fix is to augment the hash compare function with a check for
> pointer equality.  That way deleting items from the table works and
> comparing different sequences functions as before.
>
> The more general fix is to augment gimple_call_same_target_p so that unique
> fns are eq but not equal.  A cursory look at the other users of that
> function did not indicate this currently causes a problem, but IMHO it is
> odd for a value to not compare the same as itself -- though IEEE NaNs do
> that :)
>
> I placed the pointer equality comparison in gimple_call_same_target_p after
> the check for unique_fn_p, as I suspect that it is the rare case for that to
> be called with the same gimple call object for both parameters.  Although
> pointer equality would be applicable to all cases, in most instances it's
> going to be false.
>
> Of course, the gimple_call_same_target_p change fixes the problem on its
> own, but the local change to same_succ::equal seems beneficial on its own
> merits.
>
> ok?

Ok.

Richard.

> nathan
> --
> Nathan Sidwell
diff mbox

Patch

2016-05-04  Nathan Sidwell  <nathan@codesourcery.com>

	* gimple.c (gimple_call_same_target_p): Unique functions are eq.
	* tree-ssa-tail-merge.c (same_succ::equal): Check pointer eq
	equality first.

Index: gimple.c
===================================================================
--- gimple.c	(revision 235871)
+++ gimple.c	(working copy)
@@ -1355,7 +1355,8 @@  gimple_call_same_target_p (const gimple
   if (gimple_call_internal_p (c1))
     return (gimple_call_internal_p (c2)
 	    && gimple_call_internal_fn (c1) == gimple_call_internal_fn (c2)
-	    && !gimple_call_internal_unique_p (as_a <const gcall *> (c1)));
+	    && (!gimple_call_internal_unique_p (as_a <const gcall *> (c1))
+		|| c1 == c2));
   else
     return (gimple_call_fn (c1) == gimple_call_fn (c2)
 	    || (gimple_call_fndecl (c1)
Index: tree-ssa-tail-merge.c
===================================================================
--- tree-ssa-tail-merge.c	(revision 235871)
+++ tree-ssa-tail-merge.c	(working copy)
@@ -538,6 +538,9 @@  same_succ::equal (const same_succ *e1, c
   gimple *s1, *s2;
   basic_block bb1, bb2;
 
+  if (e1 == e2)
+    return 1;
+
   if (e1->hashval != e2->hashval)
     return 0;