From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18430 invoked by alias); 13 Feb 2015 17:02:10 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 18375 invoked by uid 48); 13 Feb 2015 17:02:06 -0000 From: "jamborm at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug ipa/65028] [5 Regression] 450.soplex in SPEC CPU 2006 is miscompiled Date: Fri, 13 Feb 2015 17:02:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: ipa X-Bugzilla-Version: 5.0 X-Bugzilla-Keywords: wrong-code X-Bugzilla-Severity: normal X-Bugzilla-Who: jamborm at gcc dot gnu.org X-Bugzilla-Status: ASSIGNED X-Bugzilla-Priority: P1 X-Bugzilla-Assigned-To: jamborm at gcc dot gnu.org X-Bugzilla-Target-Milestone: 5.0 X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2015-02/txt/msg01517.txt.bz2 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65028 --- Comment #4 from Martin Jambor --- 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 PR ipa/65028 * ipa-inline-transform.c (mark_all_inlined_calls_cdtor): New function. (inline_call): Use it. 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 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)