From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 72318 invoked by alias); 29 May 2015 10:39:18 -0000 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 Received: (qmail 72309 invoked by uid 89); 29 May 2015 10:39:17 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=AWL,BAYES_00,KAM_ASCII_DIVIDERS,KAM_LAZY_DOMAIN_SECURITY,T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: mx2.suse.de Received: from cantor2.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, 29 May 2015 10:39:16 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 6149DAD1F for ; Fri, 29 May 2015 10:39:13 +0000 (UTC) Date: Fri, 29 May 2015 11:05:00 -0000 From: Richard Biener To: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix PR66314 Message-ID: User-Agent: Alpine 2.11 (LSU 23 2013-08-11) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-SW-Source: 2015-05/txt/msg02740.txt.bz2 This fixes jump threading which fails to update the loop ownership of duplicated blocks (and was probably just lucky that loops were fixed up usually). The blocks of the jump thread path always belong to the loop of the final threading destination. Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2015-05-29 Richard Biener PR tree-optimization/66314 * tree-ssa-threadupdate.c (create_block_for_threading): Add parameter that says which loop the new block belongs to. (ssa_create_duplicates): Blocks duplicated for the threaded path belong to the loop of the thread destination. * gcc.dg/asan/pr66314.c: New testcase. Index: gcc/tree-ssa-threadupdate.c =================================================================== *** gcc/tree-ssa-threadupdate.c (revision 223818) --- gcc/tree-ssa-threadupdate.c (working copy) *************** remove_ctrl_stmt_and_useless_edges (basi *** 312,324 **** } /* Create a duplicate of BB. Record the duplicate block in an array ! indexed by COUNT stored in RD. */ static void create_block_for_threading (basic_block bb, struct redirection_data *rd, unsigned int count, ! bitmap *duplicate_blocks) { edge_iterator ei; edge e; --- 312,326 ---- } /* Create a duplicate of BB. Record the duplicate block in an array ! indexed by COUNT stored in RD. LOOP is the loop the block should ! belong to, if not NULL, in which case it will belong to the same ! loop as BB. */ static void create_block_for_threading (basic_block bb, struct redirection_data *rd, unsigned int count, ! bitmap *duplicate_blocks, loop_p loop) { edge_iterator ei; edge e; *************** create_block_for_threading (basic_block *** 326,331 **** --- 328,338 ---- /* We can use the generic block duplication code and simply remove the stuff we do not need. */ rd->dup_blocks[count] = duplicate_block (bb, NULL, NULL); + if (loop && rd->dup_blocks[count]->loop_father != loop) + { + remove_bb_from_loops (rd->dup_blocks[count]); + add_bb_to_loop (rd->dup_blocks[count], loop); + } FOR_EACH_EDGE (e, ei, rd->dup_blocks[count]->succs) e->aux = NULL; *************** ssa_create_duplicates (struct redirectio *** 1303,1308 **** --- 1310,1319 ---- ssa_local_info_t *local_info) { struct redirection_data *rd = *slot; + vec *path = rd->path; + + /* Check to which loop the threading destination belongs to. */ + loop_p dest_loop = (*path).last ()->e->dest->loop_father; /* The second duplicated block in a jump threading path is specific to the path. So it gets stored in RD rather than in LOCAL_DATA. *************** ssa_create_duplicates (struct redirectio *** 1313,1326 **** Note the search starts with the third edge on the path. The first edge is the incoming edge, the second edge always has its source duplicated. Thus we start our search with the third edge. */ - vec *path = rd->path; for (unsigned int i = 2; i < path->length (); i++) { if ((*path)[i]->type == EDGE_COPY_SRC_BLOCK || (*path)[i]->type == EDGE_COPY_SRC_JOINER_BLOCK) { create_block_for_threading ((*path)[i]->e->src, rd, 1, ! &local_info->duplicate_blocks); break; } } --- 1324,1336 ---- Note the search starts with the third edge on the path. The first edge is the incoming edge, the second edge always has its source duplicated. Thus we start our search with the third edge. */ for (unsigned int i = 2; i < path->length (); i++) { if ((*path)[i]->type == EDGE_COPY_SRC_BLOCK || (*path)[i]->type == EDGE_COPY_SRC_JOINER_BLOCK) { create_block_for_threading ((*path)[i]->e->src, rd, 1, ! &local_info->duplicate_blocks, dest_loop); break; } } *************** ssa_create_duplicates (struct redirectio *** 1330,1336 **** if (local_info->template_block == NULL) { create_block_for_threading ((*path)[1]->e->src, rd, 0, ! &local_info->duplicate_blocks); local_info->template_block = rd->dup_blocks[0]; /* We do not create any outgoing edges for the template. We will --- 1340,1346 ---- if (local_info->template_block == NULL) { create_block_for_threading ((*path)[1]->e->src, rd, 0, ! &local_info->duplicate_blocks, dest_loop); local_info->template_block = rd->dup_blocks[0]; /* We do not create any outgoing edges for the template. We will *************** ssa_create_duplicates (struct redirectio *** 1340,1346 **** else { create_block_for_threading (local_info->template_block, rd, 0, ! &local_info->duplicate_blocks); /* Go ahead and wire up outgoing edges and update PHIs for the duplicate block. */ --- 1350,1356 ---- else { create_block_for_threading (local_info->template_block, rd, 0, ! &local_info->duplicate_blocks, dest_loop); /* Go ahead and wire up outgoing edges and update PHIs for the duplicate block. */ *************** thread_single_edge (edge e) *** 1677,1683 **** npath->safe_push (x); rd.path = npath; ! create_block_for_threading (bb, &rd, 0, NULL); remove_ctrl_stmt_and_useless_edges (rd.dup_blocks[0], NULL); create_edge_and_update_destination_phis (&rd, rd.dup_blocks[0], 0); --- 1687,1693 ---- npath->safe_push (x); rd.path = npath; ! create_block_for_threading (bb, &rd, 0, NULL, NULL); remove_ctrl_stmt_and_useless_edges (rd.dup_blocks[0], NULL); create_edge_and_update_destination_phis (&rd, rd.dup_blocks[0], 0); Index: gcc/testsuite/gcc.dg/asan/pr66314.c =================================================================== *** gcc/testsuite/gcc.dg/asan/pr66314.c (revision 0) --- gcc/testsuite/gcc.dg/asan/pr66314.c (working copy) *************** *** 0 **** --- 1,33 ---- + /* { dg-do compile } */ + /* { dg-options "-fprofile-arcs -fno-sanitize=address -fsanitize=kernel-address" } */ + + char *a; + int d; + + static int + fn1 (int b, int c) + { + while (a) + if (*a) + return -126; + if (b) + return -12; + if (c == -12) + return c; + } + + void + fn2 (int b, int c) + { + for (;;) + { + d = fn1 (b, c); + switch (d) + { + case -126: + continue; + default: + return; + } + } + }