diff mbox

Fix soplex miscompilation

Message ID 20150213200839.GB20469@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka Feb. 13, 2015, 8:08 p.m. UTC
Hi,
the following patch by Martin Jambor fixes soplex miscompilation. I went ahead
regtested it on x86_64-linux and comitted.

Honza

--- Comment #4 from Martin Jambor <jamborm at gcc dot gnu.org> ---
OK, so here are my findings.  Switching off IPA-CP helps because the
pass then does not propagate polymorphic context from
_ZN8MySoPlexC2EN6soplex6SoPlex4TypeENS1_14RepresentationE/5887 to
_ZN6soplex9SPxSolverC2ENS_6SoPlex4TypeENS1_14RepresentationE/51162
(both are constructors) for the 0th parameter.  This propagation
clears the dynamic flag and speculation from the context on the edge
and the result is stored to a lattice describing the callee.

Later on, inlining comes along and calls ipa_context_from_jfunc which
picks up this value from the lattice and uses it as a base for a jump
function on the edge being inlined.  In this process, it also checks
for dynamic type changes in constructors and destructors but
apparently it relies on edge flag in_polymorphic_cdtor being correct.

And that is the problem, apparently it is not.  When we are inlining
into a function that has itself already been inlined into the
constructor, the flag is false, although we are basing jump function
calculations on lattices corresponding to the constructor.

Therefore I'd suggest the following fix.  (Alternatively we could
easily do this propagation in update_jump_functions_after_inlining,
without introducing another recursion.)


2015-02-13  Martin Jambor  <mjambor@suse.cz>

    PR ipa/65028
    * ipa-inline-transform.c (mark_all_inlined_calls_cdtor): New function.
    (inline_call): Use it.

    specify whether profile of original function should be updated.  If any new
@@ -332,6 +347,8 @@ inline_call (struct cgraph_edge *e, bool update_original,

   old_size = inline_summaries->get (to)->size;
   inline_merge_summary (e);
+  if (e->in_polymorphic_cdtor)
+    mark_all_inlined_calls_cdtor (e->callee);
   if (opt_for_fn (e->caller->decl, optimize))
     new_edges_found = ipa_propagate_indirect_call_infos (curr, new_edges);
   if (update_overall_summary)
diff mbox

Patch

diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
index 235219d..61229ac 100644
--- a/gcc/ipa-inline-transform.c
+++ b/gcc/ipa-inline-transform.c
@@ -261,6 +261,21 @@  clone_inlined_nodes (struct cgraph_edge *e, bool
duplicate,
     }
 }

+/* Mark all call graph edges coming out of NODE and all nodes that have been
+   inlined to it as in_polymorphic_cdtor.  */
+
+static void
+mark_all_inlined_calls_cdtor (cgraph_node *node)
+{
+  for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
+    {
+      cs->in_polymorphic_cdtor = true;
+      if (!cs->inline_failed)
+    mark_all_inlined_calls_cdtor (cs->callee);
+    }
+  for (cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
+    cs->in_polymorphic_cdtor = true;
+}

 /* Mark edge E as inlined and update callgraph accordingly.  UPDATE_ORIGINAL