2019-03-14 Jakub Jelinek <jakub@redhat.com>
+ PR ipa/89684
+ * multiple_target.c (create_dispatcher_calls): Change
+ references_to_redirect from vector of ipa_ref * to vector of ipa_ref.
+ In the node->iterate_referring loop, push *ref rather than ref, call
+ ref->remove_reference () and always pass 0 to iterate_referring.
+
PR rtl-optimization/89679
* expmed.c (expand_mult_const): Don't add a REG_EQUAL note if it
would contain a paradoxical SUBREG.
inode->resolve_alias (cgraph_node::get (resolver_decl));
auto_vec<cgraph_edge *> edges_to_redirect;
- auto_vec<ipa_ref *> references_to_redirect;
+ /* We need to capture the references by value rather than just pointers to them
+ and remove them right away, as removing them later would invalidate what
+ some other reference pointers point to. */
+ auto_vec<ipa_ref> references_to_redirect;
- for (unsigned i = 0; node->iterate_referring (i, ref); i++)
- references_to_redirect.safe_push (ref);
+ while (node->iterate_referring (0, ref))
+ {
+ references_to_redirect.safe_push (*ref);
+ ref->remove_reference ();
+ }
/* 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)
}
symtab_node *source = ref->referring;
- ref->remove_reference ();
source->create_reference (inode, IPA_REF_ADDR);
}
else if (ref->use == IPA_REF_ALIAS)
{
symtab_node *source = ref->referring;
- ref->remove_reference ();
source->create_reference (inode, IPA_REF_ALIAS);
source->add_to_same_comdat_group (inode);
}
--- /dev/null
+/* PR ipa/89684 */
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+
+void bar (int, void (*) (void));
+
+__attribute__((target_clones ("default", "avx")))
+void foo (void)
+{
+ bar (0, foo);
+ bar (0, foo);
+}
+
+__attribute__((target_clones ("default", "avx", "avx2")))
+void baz (void)
+{
+ bar (0, foo);
+ bar (0, foo);
+ bar (0, foo);
+ bar (0, foo);
+ bar (0, foo);
+ bar (0, foo);
+}