[Bug c/89684] [8/9 Regression] ICE in gsi_for_stmt, at gimple-iterator.c:613

2019-03-12 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89684

--- Comment #3 from Jakub Jelinek  ---
Tried:
--- gcc/multiple_target.c.jj2019-01-18 09:13:59.081781785 +0100
+++ gcc/multiple_target.c   2019-03-12 22:38:53.197662850 +0100
@@ -105,8 +105,24 @@ create_dispatcher_calls (struct cgraph_n
   auto_vec edges_to_redirect;
   auto_vec references_to_redirect;

+  /* If there are any references where ref->referring == node, we need to
+ be more careful, as ref->remove_reference () will copy the last reference
+ over to the removed one and pop the last one.  So, make sure that
+ the self references are added from the last to first one in the
references
+ vector, then their removal will not affect any earlier references.  */
+  bool self_referring_p = false;
   for (unsigned i = 0; node->iterate_referring (i, ref); i++)
-references_to_redirect.safe_push (ref);
+if (ref->referring == node)
+  self_referring_p = true;
+else
+  references_to_redirect.safe_push (ref);
+  if (self_referring_p)
+{
+  for (unsigned i = node->num_references () - 1;
+  node->iterate_reference (i, ref); i--)
+   if (ref->referred == node)
+ references_to_redirect.safe_push (ref);
+}

   /* We need to remember NEXT_CALLER as it could be modified in the loop.  */
   for (cgraph_edge *e = node->callers; e ; e = e->next_caller)
but it actually isn't sufficient, the problem is any time there is more than
one reference from the same referring to node, because if we don't process them
from last to first, then
  struct ipa_ref *ref = this;

  if (ref != last)
{
  *ref = *last;
  ref->referred_ref_list ()->referring[referred_index] = ref;
}
  list2->references->pop ();
in remove_reference can clobber the other reference we still have in the list.
I'll try tomorrow to capture the references by value instead of pointers to
them and remove them immediately, though guess even that can affect
iterate_referring.

[Bug c/89684] [8/9 Regression] ICE in gsi_for_stmt, at gimple-iterator.c:613

2019-03-12 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89684

--- Comment #2 from Jakub Jelinek  ---
The problem is that references_to_redirect contains ipa_ref_t and those
ipa_ref_t nodes live in the referring node->ref_list.references vector.
If there is more than one reference with ref->referring == node, then we need
to ensure we process them from the one which appears last in
node->ref_list.references vector.

[Bug c/89684] [8/9 Regression] ICE in gsi_for_stmt, at gimple-iterator.c:613

2019-03-12 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89684

Jakub Jelinek  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2019-03-12
 CC||jakub at gcc dot gnu.org
   Target Milestone|--- |8.4
 Ever confirmed|0   |1

--- Comment #1 from Jakub Jelinek  ---
Cleaned up testcase:

void bar (int, void (*) (void));

__attribute__((target_clones ("default", "avx")))
void foo (void)
{
  bar (0, foo);
  bar (0, foo);
}

Started with r258596.