From patchwork Fri Jul 29 08:46:54 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 107358 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 69A08B6F68 for ; Fri, 29 Jul 2011 18:47:16 +1000 (EST) Received: (qmail 11445 invoked by alias); 29 Jul 2011 08:47:13 -0000 Received: (qmail 11436 invoked by uid 22791); 29 Jul 2011 08:47:11 -0000 X-SWARE-Spam-Status: No, hits=-3.9 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; Fri, 29 Jul 2011 08:46:56 +0000 Received: from relay2.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 DE0C98891E for ; Fri, 29 Jul 2011 10:46:54 +0200 (CEST) Date: Fri, 29 Jul 2011 10:46:54 +0200 (CEST) From: Richard Guenther To: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix VRP handling of undefined state 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 I noticed that for binary expressions VRP contains the same bugs that CCP once did (it treats UNDEFINED * 0 as UNDEFINED). Then I noticed we never hit this bug because we never end up with any range being UNDEFINED - which is bad, because this way we miss value-ranges for all conditionally initialized variables. Thus, the following patch fixes this and conservatively handles the binary expression case (which is only of academic interest anyway - the important part is to handle UNDEFINED in PHIs). Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2011-07-29 Richard Guenther * tree-vrp.c (get_value_range): Only set parameter default definitions to varying, leave others at undefined. (extract_range_from_binary_expr): Fix undefined handling. (vrp_visit_phi_node): Handle merged undefined state. * gcc.dg/uninit-suppress.c: Also disable VRP. * gcc.dg/uninit-suppress_2.c: Likewise. Index: gcc/testsuite/gcc.dg/uninit-suppress.c =================================================================== *** gcc/testsuite/gcc.dg/uninit-suppress.c (revision 176869) --- gcc/testsuite/gcc.dg/uninit-suppress.c (working copy) *************** *** 1,5 **** /* { dg-do compile } */ ! /* { dg-options "-fno-tree-ccp -O2 -Wuninitialized -Wno-maybe-uninitialized" } */ void blah(); int gflag; --- 1,5 ---- /* { dg-do compile } */ ! /* { dg-options "-fno-tree-ccp -fno-tree-vrp -O2 -Wuninitialized -Wno-maybe-uninitialized" } */ void blah(); int gflag; Index: gcc/testsuite/gcc.dg/uninit-suppress_2.c =================================================================== *** gcc/testsuite/gcc.dg/uninit-suppress_2.c (revision 176869) --- gcc/testsuite/gcc.dg/uninit-suppress_2.c (working copy) *************** *** 1,5 **** /* { dg-do compile } */ ! /* { dg-options "-fno-tree-ccp -O2 -Wuninitialized -Werror=uninitialized -Wno-error=maybe-uninitialized" } */ void blah(); int gflag; --- 1,5 ---- /* { dg-do compile } */ ! /* { dg-options "-fno-tree-ccp -fno-tree-vrp -O2 -Wuninitialized -Werror=uninitialized -Wno-error=maybe-uninitialized" } */ void blah(); int gflag; Index: gcc/tree-vrp.c =================================================================== --- gcc/tree-vrp.c (revision 176869) +++ gcc/tree-vrp.c (working copy) @@ -692,16 +692,16 @@ get_value_range (const_tree var) /* Defer allocating the equivalence set. */ vr->equiv = NULL; - /* If VAR is a default definition, the variable can take any value - in VAR's type. */ + /* If VAR is a default definition of a parameter, the variable can + take any value in VAR's type. */ sym = SSA_NAME_VAR (var); - if (SSA_NAME_IS_DEFAULT_DEF (var)) + if (SSA_NAME_IS_DEFAULT_DEF (var) + && TREE_CODE (sym) == PARM_DECL) { /* Try to use the "nonnull" attribute to create ~[0, 0] anti-ranges for pointers. Note that this is only valid with default definitions of PARM_DECLs. */ - if (TREE_CODE (sym) == PARM_DECL - && POINTER_TYPE_P (TREE_TYPE (sym)) + if (POINTER_TYPE_P (TREE_TYPE (sym)) && nonnull_arg_p (sym)) set_value_range_to_nonnull (vr, TREE_TYPE (sym)); else @@ -2225,12 +2225,20 @@ extract_range_from_binary_expr (value_ra else set_value_range_to_varying (&vr1); - /* If either range is UNDEFINED, so is the result. */ - if (vr0.type == VR_UNDEFINED || vr1.type == VR_UNDEFINED) + /* If both ranges are UNDEFINED, so is the result. */ + if (vr0.type == VR_UNDEFINED && vr1.type == VR_UNDEFINED) { set_value_range_to_undefined (vr); return; } + /* If one of the ranges is UNDEFINED drop it to VARYING for the following + code. At some point we may want to special-case operations that + have UNDEFINED result for all or some value-ranges of the not UNDEFINED + operand. */ + else if (vr0.type == VR_UNDEFINED) + set_value_range_to_varying (&vr0); + else if (vr1.type == VR_UNDEFINED) + set_value_range_to_varying (&vr1); /* The type of the resulting value range defaults to VR0.TYPE. */ type = vr0.type; @@ -6642,6 +6650,8 @@ vrp_visit_phi_node (gimple phi) if (vr_result.type == VR_VARYING) goto varying; + else if (vr_result.type == VR_UNDEFINED) + goto update_range; old_edges = vr_phi_edge_counts[SSA_NAME_VERSION (lhs)]; vr_phi_edge_counts[SSA_NAME_VERSION (lhs)] = edges; @@ -6713,6 +6723,7 @@ vrp_visit_phi_node (gimple phi) /* If the new range is different than the previous value, keep iterating. */ +update_range: if (update_value_range (lhs, &vr_result)) { if (dump_file && (dump_flags & TDF_DETAILS))