From patchwork Mon Nov 19 20:46:29 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 200154 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]) by ozlabs.org (Postfix) with SMTP id D71E92C0080 for ; Tue, 20 Nov 2012 07:46:49 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1353962810; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Date:From:To:Cc:Subject:Message-ID:Reply-To: MIME-Version:Content-Type:Content-Disposition:User-Agent: Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:Sender:Delivered-To; bh=1q2S+1UuGi0Nc9vzBgtF 3cCE718=; b=Zff+BGUzs2VaMXI5bQWGLwbaZ0P/9NFq+iJK+6Cqfry5PrneiFn0 Bl1euA13EIcsnVnXX3i3Z7i4lAlnejQvWHOz7ePZSQL8AqSh7AxA4viYxMyUFHvy Bhw5++WiLR4FtwMUGdNH+6vf9DgNBlnxb2dWnrgsMXkhO06Cje9j6nU= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:Received:Date:From:To:Cc:Subject:Message-ID:Reply-To:MIME-Version:Content-Type:Content-Disposition:User-Agent:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=ptU00Zpaajb+0c03O7MuPmmn+t/woMKF3s7H8RREfbVKgX+0xmldETjxfao1uW IpT65Tny5uWWWDsWfVCz54uzcLTUKrPXhw+eP82ZnMu9zUqhkzMtPdMi3ulgtAzG hxqnSvR0kSQrhH4m2aDcKMYuVjHnVPQpgfeW3v/RyKlow=; Received: (qmail 11601 invoked by alias); 19 Nov 2012 20:46:41 -0000 Received: (qmail 11541 invoked by uid 22791); 19 Nov 2012 20:46:40 -0000 X-SWARE-Spam-Status: No, hits=-6.6 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_W, RP_MATCHES_RCVD, SPF_HELO_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 19 Nov 2012 20:46:33 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id qAJKkWLm011459 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 19 Nov 2012 15:46:32 -0500 Received: from zalov.redhat.com (vpn1-6-134.ams2.redhat.com [10.36.6.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id qAJKkUwb014290 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 19 Nov 2012 15:46:32 -0500 Received: from zalov.cz (localhost [127.0.0.1]) by zalov.redhat.com (8.14.5/8.14.5) with ESMTP id qAJKkUS3021023; Mon, 19 Nov 2012 21:46:30 +0100 Received: (from jakub@localhost) by zalov.cz (8.14.5/8.14.5/Submit) id qAJKkTke021022; Mon, 19 Nov 2012 21:46:29 +0100 Date: Mon, 19 Nov 2012 21:46:29 +0100 From: Jakub Jelinek To: Richard Henderson Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix up cross-jumping with __builtin_trap or __builtin_unreachable (PR middle-end/55094) Message-ID: <20121119204629.GO2315@tucnak.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes 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 Hi! As the following testcase (with disabled LRA) shows, cross-jumping sometimes leads into dwarf2cfi ICEs, because traps or even arbitrary insns followed by __builtin_unreachable () with different args size depth can be cross-jumped together. Fixed by emitting REG_ARGS_SIZE notes on traps, and for __builtin_unreachable where we have nothing to attach it to just giving up cross-jumping if there is no REG_ARGS_SIZE note and !ACCUMULATE_OUTGOING_ARGS. Additionally it fixes a -fcompare-debug insn, because with __builtin_unreachable the block might not end up with any jump/call/trap insn, but e.g. debug insns. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk and after a while for 4.7 too? 2012-11-19 Jakub Jelinek PR middle-end/55094 * builtins.c (expand_builtin_trap): Add REG_ARGS_SIZE note on the trap insn for !ACCUMULATE_OUTGOING_ARGS. * cfgcleanup.c (outgoing_edges_match): Don't look at debug insns on the first old_insns_match_p call. For !ACCUMULATE_OUTGOING_ARGS fail if the last real insn doesn't have REG_ARGS_SIZE note. * gcc.dg/pr55094.c: New test. Jakub --- gcc/builtins.c.jj 2012-11-19 14:41:14.000000000 +0100 +++ gcc/builtins.c 2012-11-19 18:21:30.324047247 +0100 @@ -4666,7 +4666,14 @@ expand_builtin_trap (void) { #ifdef HAVE_trap if (HAVE_trap) - emit_insn (gen_trap ()); + { + rtx insn = emit_insn (gen_trap ()); + /* For trap insns when not accumulating outgoing args force + REG_ARGS_SIZE note to prevent crossjumping of calls with + different args sizes. */ + if (!ACCUMULATE_OUTGOING_ARGS) + add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta)); + } else #endif emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0); --- gcc/cfgcleanup.c.jj 2012-11-19 14:41:24.000000000 +0100 +++ gcc/cfgcleanup.c 2012-11-19 18:21:30.324047247 +0100 @@ -1702,9 +1702,15 @@ outgoing_edges_match (int mode, basic_bl } } + rtx last1 = BB_END (bb1); + rtx last2 = BB_END (bb2); + if (DEBUG_INSN_P (last1)) + last1 = prev_nondebug_insn (last1); + if (DEBUG_INSN_P (last2)) + last2 = prev_nondebug_insn (last2); /* First ensure that the instructions match. There may be many outgoing edges so this test is generally cheaper. */ - if (old_insns_match_p (mode, BB_END (bb1), BB_END (bb2)) != dir_both) + if (old_insns_match_p (mode, last1, last2) != dir_both) return false; /* Search the outgoing edges, ensure that the counts do match, find possible @@ -1713,10 +1719,14 @@ outgoing_edges_match (int mode, basic_bl if (EDGE_COUNT (bb1->succs) != EDGE_COUNT (bb2->succs)) return false; + bool nonfakeedges = false; FOR_EACH_EDGE (e1, ei, bb1->succs) { e2 = EDGE_SUCC (bb2, ei.index); + if ((e1->flags & EDGE_FAKE) == 0) + nonfakeedges = true; + if (e1->flags & EDGE_EH) nehedges1++; @@ -1734,6 +1744,18 @@ outgoing_edges_match (int mode, basic_bl || (fallthru1 != 0) != (fallthru2 != 0)) return false; + /* If !ACCUMULATE_OUTGOING_ARGS, bb1 (and bb2) have no successors + and the last real insn doesn't have REG_ARGS_SIZE note, don't + attempt to optimize, as the two basic blocks might have different + REG_ARGS_SIZE depths. For noreturn calls and unconditional + traps there should be REG_ARG_SIZE notes, they could be missing + for __builtin_unreachable () uses though. */ + if (!nonfakeedges + && !ACCUMULATE_OUTGOING_ARGS + && (!INSN_P (last1) + || !find_reg_note (last1, REG_ARGS_SIZE, NULL))) + return false; + /* fallthru edges must be forwarded to the same destination. */ if (fallthru1) { --- gcc/testsuite/gcc.dg/pr55094.c.jj 2012-11-19 18:21:56.120897505 +0100 +++ gcc/testsuite/gcc.dg/pr55094.c 2012-11-19 18:20:52.000000000 +0100 @@ -0,0 +1,45 @@ +/* PR middle-end/55094 */ +/* { dg-do compile } */ +/* { dg-options "-fcompare-debug -Os" } */ +/* { dg-additional-options "-fomit-frame-pointer -fno-asynchronous-unwind-tables -mpreferred-stack-boundary=2" { target { { i?86-*-* x86_64-*-* } && ia32 } } } */ + +extern int fn (long); +int v; + +int +foo (int x, long *y) +{ + if (x) + { + fn (y[0]); + __builtin_trap (); + } + __builtin_trap (); +} + +int +bar (int x, long *y) +{ + if (x) + { + fn (y[0]); + v = 1; + __builtin_unreachable (); + } + v = 1; + __builtin_unreachable (); +} + +int +baz (int x, long *y) +{ + if (x) + { + fn (y[0]); + v = 1; + __builtin_unreachable (); + } + v = 1; + int w = 1; + __builtin_unreachable (); +}