From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12089 invoked by alias); 18 Feb 2013 10:39:10 -0000 Received: (qmail 12067 invoked by uid 22791); 18 Feb 2013 10:39:10 -0000 X-SWARE-Spam-Status: No, hits=-5.5 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 18 Feb 2013 10:39:04 +0000 Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 701A8A3A78 for ; Mon, 18 Feb 2013 11:39:03 +0100 (CET) Date: Mon, 18 Feb 2013 10:39:00 -0000 From: Richard Biener To: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix PR56350 Message-ID: User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2013-02/txt/msg00843.txt.bz2 The issue in PR56350 is two-fold. First, fix_loop_structure mishandles latch edge computation (ugh). Second, RTL if-conversion, when merging a latch block into sth else ends up generating stale latch block references. The following two patches cure that, adding some basic latch block checking. Bootstrap & regtest running on x86_64-unknown-linux-gnu. Richard. 2013-02-18 Richard Biener PR middle-end/56349 * cfgloop.c (flow_loops_find): Reset latch before recomputing it. (verify_loop_structure): Verify that a recorded latch is in fact a latch. Index: gcc/cfgloop.c =================================================================== *** gcc/cfgloop.c (revision 196115) --- gcc/cfgloop.c (working copy) *************** flow_loops_find (struct loops *loops) *** 466,471 **** --- 466,473 ---- "loop %d with header %d\n", loop->num, header->index); } + /* Reset latch, we recompute it below. */ + loop->latch = NULL; larray.safe_push (loop); } *************** verify_loop_structure (void) *** 1413,1418 **** --- 1415,1433 ---- error ("loop %d%'s header does not have exactly 2 entries", i); err = 1; } + if (loop->latch) + { + if (!find_edge (loop->latch, loop->header)) + { + error ("loop %d%'s latch does not have an edge to its header", i); + err = 1; + } + if (!dominated_by_p (CDI_DOMINATORS, loop->latch, loop->header)) + { + error ("loop %d%'s latch is not dominated by its header", i); + err = 1; + } + } if (loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES)) { if (!single_succ_p (loop->latch)) 2013-02-18 Richard Biener PR middle-end/56350 * cfghooks.c (merge_blocks): If we merge a latch into another block adjust references to it. * gcc.dg/torture/pr56350.c: New testcase. Index: gcc/cfghooks.c =================================================================== *** gcc/cfghooks.c (revision 196115) --- gcc/cfghooks.c (working copy) *************** merge_blocks (basic_block a, basic_block *** 761,767 **** { e->src = a; if (current_loops != NULL) ! rescan_loop_exit (e, true, false); } a->succs = b->succs; a->flags |= b->flags; --- 761,772 ---- { e->src = a; if (current_loops != NULL) ! { ! /* If b was a latch, a now is. */ ! if (e->dest->loop_father->latch == b) ! e->dest->loop_father->latch = a; ! rescan_loop_exit (e, true, false); ! } } a->succs = b->succs; a->flags |= b->flags; Index: gcc/testsuite/gcc.dg/torture/pr56350.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr56350.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr56350.c (working copy) *************** *** 0 **** --- 1,41 ---- + /* { dg-do compile } */ + + int a, b; + short c; + + void f(void) + { + int a = 0; + int *k = 0; + + for(; a < 2; a++); + + if(!!(b |= a < 3) - 1) + { + if(0) + for (;; a++) + { + for (; c; *k = 0); + lbl1: + ; + } + + for(; *k; k++) + { + c = b ? : a; + + if (c) + lbl2: + b = 0; + } + goto lbl1; + } + + for(;; b++) + { + if(b) + goto lbl2; + + k = &b; + } + }