public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] ipa-prop: Fix multiple-target speculation resolution
@ 2020-10-01 17:39 Martin Jambor
  2020-10-07  8:31 ` Martin Liška
  0 siblings, 1 reply; 2+ messages in thread
From: Martin Jambor @ 2020-10-01 17:39 UTC (permalink / raw)
  To: GCC Patches; +Cc: Jan Hubicka, Martin Liska

Hi,

as the FIXME which this patch removes states, the current code does
not work when a call with multiple speculative targets gets resolved
through parameter tracking during inlining - it feeds the inliner an
edge it has already dealt with.  The patch makes the code which should
prevent it aware of the possibility that that speculation can have
more than one target now.

Bootstrapped and tested and LTO bootstrapped on x86_64-linux.  I did not
try profiled LTO bootstrap because it fails even without the patch (even
without Ada, just C, C++ and Fortran, at least commit 92f0d3d03a7 does).
OK for trunk?

Thanks,

Martin


gcc/ChangeLog:

2020-09-30  Martin Jambor  <mjambor@suse.cz>

	PR ipa/96394
	* ipa-prop.c (update_indirect_edges_after_inlining): Do not add
	resolved speculation edges to vector of new direct edges even in
	presence of multiple speculative direct edges for a single call.

gcc/testsuite/ChangeLog:

2020-09-30  Martin Jambor  <mjambor@suse.cz>

	PR ipa/96394
	* gcc.dg/tree-prof/pr96394.c: New test.
---
 gcc/ipa-prop.c                           | 10 ++--
 gcc/testsuite/gcc.dg/tree-prof/pr96394.c | 64 ++++++++++++++++++++++++
 2 files changed, 70 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-prof/pr96394.c

diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index b28c78eeab4..2ef7a48c5d2 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -3787,11 +3787,13 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
 
       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;
@@ -3814,7 +3816,7 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
 
       /* 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);
diff --git a/gcc/testsuite/gcc.dg/tree-prof/pr96394.c b/gcc/testsuite/gcc.dg/tree-prof/pr96394.c
new file mode 100644
index 00000000000..4280182a7c3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-prof/pr96394.c
@@ -0,0 +1,64 @@
+/* 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
+    },
+};
-- 
2.28.0


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] ipa-prop: Fix multiple-target speculation resolution
  2020-10-01 17:39 [PATCH] ipa-prop: Fix multiple-target speculation resolution Martin Jambor
@ 2020-10-07  8:31 ` Martin Liška
  0 siblings, 0 replies; 2+ messages in thread
From: Martin Liška @ 2020-10-07  8:31 UTC (permalink / raw)
  To: Martin Jambor, GCC Patches; +Cc: Jan Hubicka

On 10/1/20 7:39 PM, Martin Jambor wrote:
> OK for trunk?

Approved.

Martin

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-10-07  8:31 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-01 17:39 [PATCH] ipa-prop: Fix multiple-target speculation resolution Martin Jambor
2020-10-07  8:31 ` Martin Liška

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).