From patchwork Mon Apr 17 16:20:28 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Law X-Patchwork-Id: 751400 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 3w6D5R1MvQz9s0g for ; Tue, 18 Apr 2017 02:20:41 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="rsnp3XIH"; 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:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=CCQPuLJ5OjO1zRyx247HR7KpI06NqiERSLWd3djr80GTx5IN4D MML3IaUPy8bKAMuTedauymONUACGc80Dl6it16el+jf5/keiT0aEBhPB6hkht+B9 xD4YgpyVGx/8Z5eje2Oh6srmKCzFZrNNV1t8xRLLHMXtqzK6dA0ng1fNg= 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:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=eX+V6DPCZI5qUKb3Evuf8wlLHxA=; b=rsnp3XIHYARD9jSUnCyZ YPh9EzbEHQt4Dazzq1V8GUUPbPC9KSRqF1B/L4eJHZM1dNCJUD0qrOlhvCA/i6fH LsxXIIqxcB7/+HwbwQ8EKITxqhYB4nOYonPrN7bLKMKxdidy1LthmgLCX9rHwa36 nyXKgUcM8AHhA5FfeEK3wTY= Received: (qmail 70375 invoked by alias); 17 Apr 2017 16:20:31 -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 70349 invoked by uid 89); 17 Apr 2017 16:20:30 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=boom X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 17 Apr 2017 16:20:29 +0000 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E77A54E8AB for ; Mon, 17 Apr 2017 16:20:28 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com E77A54E8AB Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=law@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com E77A54E8AB Received: from localhost.localdomain (ovpn-116-25.phx2.redhat.com [10.3.116.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id B96FD783B5 for ; Mon, 17 Apr 2017 16:20:28 +0000 (UTC) To: gcc-patches From: Jeff Law Subject: [RFA][PATCH][P2][PR middle-end/80422] Fix crossjumping ICE Message-ID: <23d4bf7e-c5c6-e07f-5287-f0c9b1f4bc1b@redhat.com> Date: Mon, 17 Apr 2017 10:20:28 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.0 MIME-Version: 1.0 X-IsSubscribed: yes A forwarder block becomes unreachable during cfg_cleanup. Later we're cross jumping an indirect (via more forwarders) successor of the now unreachable forwarder and walk up the CFG looking for hunks of equivalent insns and walk back into the unreachable forwarder block. We then want to look at the predecessors and boom we ICE. --- If we look at try_crossjump_to_edge we see the check to verify that SRC1 and SRC2 both have predecessors: /* Likewise with dead code (possibly newly created by the other optimizations of cfg_cleanup). */ if (EDGE_COUNT (src1->preds) == 0 || EDGE_COUNT (src2->preds) == 0) return false; Clearly someone was aware that we could have unreachable blocks when this code runs. Then later we find call flow_find_cross_jump which walks up the insn chain, potentially leaving SRC1/SRC2 (by design). When that happens we reset SRC1/SRC2: /* ... and part the second. */ nmatch = flow_find_cross_jump (src1, src2, &newpos1, &newpos2, &dir); osrc1 = src1; osrc2 = src2; if (newpos1 != NULL_RTX) src1 = BLOCK_FOR_INSN (newpos1); if (newpos2 != NULL_RTX) src2 = BLOCK_FOR_INSN (newpos2); [ ... ] A short time later we do this: /* Avoid splitting if possible. We must always split when SRC2 has EH predecessor edges, or we may end up with basic blocks with both normal and EH predecessor edges. */ if (newpos2 == BB_HEAD (src2) && !(EDGE_PRED (src2, 0)->flags & EDGE_EH)) redirect_to = src2; If SRC2 is unreachable, then EDGE_PRED will read outside the vec's boundary triggering the fault. The fix is pretty simple. Check that SRC1/SRC2 have preds after the call to flow_find_cross_jump. Bootstrapped and regression tested on x86_64-linux-gnu. OK for the trunk? Jeff PR middle-end/80422 * cfgcleanup.c (try_crossjump_to_edge): Verify SRC1 and SRC2 have predecessors after walking up the insn chain. PR middle-end/80422 * gcc.c-torture/compile/pr80422.c: New test. diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index d55b0ce..f68a964 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -2017,6 +2017,11 @@ try_crossjump_to_edge (int mode, edge e1, edge e2, if (newpos2 != NULL_RTX) src2 = BLOCK_FOR_INSN (newpos2); + /* Check that SRC1 and SRC2 have preds again. They may have changed + above due to the call to flow_find_cross_jump. */ + if (EDGE_COUNT (src1->preds) == 0 || EDGE_COUNT (src2->preds) == 0) + return false; + if (dir == dir_backward) { #define SWAP(T, X, Y) do { T tmp = (X); (X) = (Y); (Y) = tmp; } while (0) diff --git a/gcc/testsuite/gcc.c-torture/compile/pr80422.c b/gcc/testsuite/gcc.c-torture/compile/pr80422.c new file mode 100644 index 0000000..2cece67 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr80422.c @@ -0,0 +1,26 @@ + +int a, c, f; +short b, d, e; + +int fn1 (int h) +{ + return a > 2 || h > a ? h : h << a; +} + +void fn2 () +{ + int j, k; + while (1) + { + k = c && b; + f &= e > (fn1 (k) && j); + if (!d) + break; + } +} + +int main () +{ + fn2 (); + return 0; +}