param_index = ici->param_index;
jfunc = ipa_get_ith_jump_func (top, param_index);
- cgraph_node *spec_target = NULL;
- /* FIXME: This may need updating for multiple calls. */
+ auto_vec<cgraph_node *, 4> spec_targets;
if (ie->speculative)
- spec_target = ie->first_speculative_call_target ()->callee;
+ for (cgraph_edge *direct = ie->first_speculative_call_target ();
+ direct;
+ direct = direct->next_speculative_call_target ())
+ spec_targets.safe_push (direct->callee);
if (!opt_for_fn (node->decl, flag_indirect_inlining))
new_direct_edge = NULL;
/* If speculation was removed, then we need to do nothing. */
if (new_direct_edge && new_direct_edge != ie
- && new_direct_edge->callee == spec_target)
+ && spec_targets.contains (new_direct_edge->callee))
{
new_direct_edge->indirect_inlining_edge = 1;
top = IPA_EDGE_REF (cs);
--- /dev/null
+/* PR ipa/96394 */
+/* { dg-options "-O2" } */
+
+typedef struct _entry {
+ int has_next;
+ int next_ix;
+ int count;
+} entry;
+
+extern entry table[];
+
+void *
+__attribute__((noipa))
+PyErr_Format(entry * e){ return 0; }
+
+void ae(entry *);
+int h(entry *);
+int ap(entry *);
+int ag(entry *);
+
+int ag(entry *j) {
+ if (j->has_next)
+ h(&table[j->next_ix]);
+ return 0;
+}
+static int ai(entry *j, int k(entry *), int l, int m) {
+ int am = 1;
+ int ab;
+
+ /* k is either 'h' or 'ap': 50%/50% */
+ ab = k(j);
+
+ /* loop never gets executed on real data */
+ for (; j->count >= 2; am += 2)
+ if (l) {
+ entry *i = &table[am + m];
+ PyErr_Format(i);
+ }
+ return ab;
+}
+void
+__attribute__((noipa))
+bug() {
+ h(table);
+ h(table);
+}
+int h(entry *j) { return ai(j, ap, 4, 5); }
+int ap(entry *j) { return ai(j, ag, 14, 4); }
+
+int main(void)
+{
+ bug();
+}
+
+entry table[2] = {
+ { .has_next = 1
+ , .next_ix = 1
+ , .count = 0
+ },
+ { .has_next = 0
+ , .next_ix = 0
+ , .count = 0
+ },
+};