This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] tail merge ICE
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: Thomas Schwinge <thomas at codesourcery dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>, Jakub Jelinek <jakub at redhat dot com>, Richard Guenther <richard dot guenther at gmail dot com>
- Date: Wed, 4 May 2016 13:25:19 -0400
- Subject: [PATCH] tail merge ICE
- Authentication-results: sourceware.org; auth=none
- References: <56A2A908 dot 2070001 at acm dot org> <56A2A62F dot 3030103 at acm dot org> <b0e06bc4-1414-6858-5ca9-a0782fa70094 at acm dot org> <87lh3rwhtv dot fsf at kepler dot schwinge dot homeip dot net>
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
--
Nathan Sidwell
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;