From patchwork Fri Nov 27 11:10:47 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 549387 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id DE03E140281 for ; Fri, 27 Nov 2015 22:11:00 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=Uo3mqdWk; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:in-reply-to:message-id:references :mime-version:content-type; q=dns; s=default; b=g5gVGcASwUJINvVu ALIT8cVg1Wq5jICm4vj2dKGYeAkVs8D4A+w2RpmGDo6INaW/dl4ULr/cH6HDehJa 7TKB107hQLbhOrd7Lr0chPVSGeq15bhydvY0VL5zFTqdl1o0CL93nO9Mu9E4iEsb 9nbCM5hQi4Ua1Y1mkfcEPHt1PpY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:in-reply-to:message-id:references :mime-version:content-type; s=default; bh=pO8BI1CPFaWHNzNZFAX6Y9 JciRY=; b=Uo3mqdWkA5e36E36SChKwz2xsAxGWafAZ1JetkLl2wvohWmTR0F3RC 44uu1ulyVCTN/KPmWemoo5sgEwk6kmOYB4BUGYfbQlNu1KoM9gr7G8IHV48GYcSf OZky1B30cmOskC8oUNfzlhNDj+vZ8z+rzlRsK7mz1Oxy/g9j+wLHM= Received: (qmail 34672 invoked by alias); 27 Nov 2015 11:10:53 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 34653 invoked by uid 89); 27 Nov 2015 11:10:52 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.0 required=5.0 tests=AWL, BAYES_00, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_LOW, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx2.suse.de Received: from mx2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Fri, 27 Nov 2015 11:10:51 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 590A2AC08; Fri, 27 Nov 2015 11:09:08 +0000 (UTC) Date: Fri, 27 Nov 2015 12:10:47 +0100 (CET) From: Richard Biener To: gcc-patches@gcc.gnu.org cc: Jan Hubicka Subject: Re: [PATCH] Fix PR68470, ICE in IPA split In-Reply-To: Message-ID: References: User-Agent: Alpine 2.11 (LSU 23 2013-08-11) MIME-Version: 1.0 On Fri, 27 Nov 2015, Richard Biener wrote: > > This fixes the case where we split the returning part of a function > and keep the non-returning part as main. We were keeping the return > block with stmts not relevant to main in the return path of the > split which obviously doesn't work as it may use SSA names no longer > defined (but split out). > > The following patch detects the situation and pretends the exit > block was found as EXIT_BLOCK_FOR_FN in this case. > > Bootstrap and regtest ongoing on x86_64-unknown-linux-gnu. > > Honza, does this look ok? Ok, fails for example FAIL: gcc.dg/vect/pr51581-1.c execution test where we split a region at a point the main part falls thru to (an odd place to split...). Happens when we split at a loop header but the pre-header remains in the main part. Adjusted patch as follows. Richard. 2015-11-27 Richard Biener PR ipa/68470 * ipa-split.c (split_function): Handle main part not returning. * g++.dg/torture/pr68470.C: New testcase. Index: gcc/ipa-split.c =================================================================== --- gcc/ipa-split.c (revision 230998) +++ gcc/ipa-split.c (working copy) @@ -1205,7 +1205,6 @@ split_function (basic_block return_bb, s edge e; edge_iterator ei; tree retval = NULL, real_retval = NULL, retbnd = NULL; - bool split_part_return_p = false; bool with_bounds = chkp_function_instrumented_p (current_function_decl); gimple *last_stmt = NULL; unsigned int i; @@ -1246,12 +1245,28 @@ split_function (basic_block return_bb, s args_to_pass.safe_push (arg); } - /* See if the split function will return. */ + /* See if the split function or the main part will return. */ + bool main_part_return_p = false; + bool split_part_return_p = false; FOR_EACH_EDGE (e, ei, return_bb->preds) - if (bitmap_bit_p (split_point->split_bbs, e->src->index)) - break; - if (e) - split_part_return_p = true; + { + if (bitmap_bit_p (split_point->split_bbs, e->src->index)) + split_part_return_p = true; + else + main_part_return_p = true; + } + /* The main part also returns if we we split on a fallthru edge + and the split part returns. */ + if (split_part_return_p) + FOR_EACH_EDGE (e, ei, split_point->entry_bb->preds) + { + if (! bitmap_bit_p (split_point->split_bbs, e->src->index) + && single_succ_p (e->src)) + { + main_part_return_p = true; + break; + } + } /* Add return block to what will become the split function. We do not return; no return block is needed. */ @@ -1295,6 +1310,11 @@ split_function (basic_block return_bb, s else bitmap_set_bit (split_point->split_bbs, return_bb->index); + /* If the main part doesn't return pretend the return block wasn't + found for all of the following. */ + if (! main_part_return_p) + return_bb = EXIT_BLOCK_PTR_FOR_FN (cfun); + /* If RETURN_BB has virtual operand PHIs, they must be removed and the virtual operand marked for renaming as we change the CFG in a way that tree-inline is not able to compensate for. Index: gcc/testsuite/g++.dg/torture/pr68470.C =================================================================== --- gcc/testsuite/g++.dg/torture/pr68470.C (revision 0) +++ gcc/testsuite/g++.dg/torture/pr68470.C (working copy) @@ -0,0 +1,36 @@ +/* { dg-do compile } */ + +void deallocate(void *); +void *a; + +struct C { + virtual void m_fn1(); +}; + +struct D { + C *m_fn2() { + if (a) + __builtin_abort(); + } +}; +D getd(); + +struct vec_int { + int _M_start; + ~vec_int() { + if (_M_start) + deallocate(&_M_start); + } +}; +vec_int *b; + +struct I { + virtual void m_fn3(); +}; + +void I::m_fn3() { + if (a) + getd().m_fn2()->m_fn1(); + b->~vec_int(); +} +