From patchwork Wed Sep 7 13:07:00 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 113761 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 65198B6F7F for ; Wed, 7 Sep 2011 23:07:23 +1000 (EST) Received: (qmail 30501 invoked by alias); 7 Sep 2011 13:07:20 -0000 Received: (qmail 30491 invoked by uid 22791); 7 Sep 2011 13:07:19 -0000 X-SWARE-Spam-Status: No, hits=-3.5 required=5.0 tests=AWL, BAYES_00, 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; Wed, 07 Sep 2011 13:07:02 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.221.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id A606D8E857 for ; Wed, 7 Sep 2011 15:07:00 +0200 (CEST) Date: Wed, 7 Sep 2011 15:07:00 +0200 (CEST) From: Richard Guenther To: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix PR50319, if-conversion behaving weirdly Message-ID: User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 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 This fixes if-conversion to properly track inversion in its (topmost) predicate. Spurious gimplification made this code never work (it doesn't work at least on the 4.6 branch either). Bootstrap and regtest ongoing on x86_64-unknown-linux-gnu. Richard. 2011-09-07 Richard Guenther PR tree-optimization/50319 * tree-if-conv.c (set_bb_predicate): Assert we only set canonical predicates. (add_to_predicate_list): Simplify. Allow TRUTH_NOT_EXPR around canonical predicates. (predicate_bbs): Do not re-gimplify already canonical predicates. Properly unshare them though. (find_phi_replacement_condition): Simplify. Index: gcc/tree-if-conv.c =================================================================== --- gcc/tree-if-conv.c (revision 178633) +++ gcc/tree-if-conv.c (working copy) @@ -137,6 +137,9 @@ bb_predicate (basic_block bb) static inline void set_bb_predicate (basic_block bb, tree cond) { + gcc_assert ((TREE_CODE (cond) == TRUTH_NOT_EXPR + && is_gimple_condexpr (TREE_OPERAND (cond, 0))) + || is_gimple_condexpr (cond)); ((bb_predicate_p) bb->aux)->predicate = cond; } @@ -328,7 +331,7 @@ fold_or_predicates (location_t loc, tree static inline void add_to_predicate_list (basic_block bb, tree nc) { - tree bc; + tree bc, *tp; if (is_true_predicate (nc)) return; @@ -339,19 +342,25 @@ add_to_predicate_list (basic_block bb, t { bc = bb_predicate (bb); bc = fold_or_predicates (EXPR_LOCATION (bc), nc, bc); + if (is_true_predicate (bc)) + { + reset_bb_predicate (bb); + return; + } } - if (!is_gimple_condexpr (bc)) + /* Allow a TRUTH_NOT_EXPR around the main predicate. */ + if (TREE_CODE (bc) == TRUTH_NOT_EXPR) + tp = &TREE_OPERAND (bc, 0); + else + tp = &bc; + if (!is_gimple_condexpr (*tp)) { gimple_seq stmts; - bc = force_gimple_operand (bc, &stmts, true, NULL_TREE); + *tp = force_gimple_operand_1 (*tp, &stmts, is_gimple_condexpr, NULL_TREE); add_bb_predicate_gimplified_stmts (bb, stmts); } - - if (is_true_predicate (bc)) - reset_bb_predicate (bb); - else - set_bb_predicate (bb, bc); + set_bb_predicate (bb, bc); } /* Add the condition COND to the previous condition PREV_COND, and add @@ -944,14 +953,6 @@ predicate_bbs (loop_p loop) } cond = bb_predicate (bb); - if (cond - && bb != loop->header) - { - gimple_seq stmts; - - cond = force_gimple_operand (cond, &stmts, true, NULL_TREE); - add_bb_predicate_gimplified_stmts (bb, stmts); - } for (itr = gsi_start_bb (bb); !gsi_end_p (itr); gsi_next (&itr)) { @@ -980,14 +981,17 @@ predicate_bbs (loop_p loop) &true_edge, &false_edge); /* If C is true, then TRUE_EDGE is taken. */ - add_to_dst_predicate_list (loop, true_edge, cond, unshare_expr (c)); + add_to_dst_predicate_list (loop, true_edge, + unshare_expr (cond), + unshare_expr (c)); /* If C is false, then FALSE_EDGE is taken. */ c2 = invert_truthvalue_loc (loc, unshare_expr (c)); tem = canonicalize_cond_expr_cond (c2); if (tem) c2 = tem; - add_to_dst_predicate_list (loop, false_edge, cond, c2); + add_to_dst_predicate_list (loop, false_edge, + unshare_expr (cond), c2); cond = NULL_TREE; break; @@ -1237,7 +1241,7 @@ find_phi_replacement_condition (struct l *cond = bb_predicate (second_edge->src); if (TREE_CODE (*cond) == TRUTH_NOT_EXPR) - *cond = invert_truthvalue (*cond); + *cond = TREE_OPERAND (*cond, 0); else /* Select non loop header bb. */ first_edge = second_edge; @@ -1245,18 +1249,10 @@ find_phi_replacement_condition (struct l else *cond = bb_predicate (first_edge->src); - /* Gimplify the condition: the vectorizer prefers to have gimple - values as conditions. Various targets use different means to - communicate conditions in vector compare operations. Using a - gimple value allows the compiler to emit vector compare and - select RTL without exposing compare's result. */ - *cond = force_gimple_operand_gsi (gsi, unshare_expr (*cond), - false, NULL_TREE, - true, GSI_SAME_STMT); - if (!is_gimple_reg (*cond) && !is_gimple_condexpr (*cond)) - *cond = ifc_temp_var (TREE_TYPE (*cond), unshare_expr (*cond), gsi); - - gcc_assert (*cond); + /* Gimplify the condition to a valid cond-expr conditonal operand. */ + *cond = force_gimple_operand_gsi_1 (gsi, unshare_expr (*cond), + is_gimple_condexpr, NULL_TREE, + true, GSI_SAME_STMT); return first_edge->src; }