From patchwork Thu Nov 24 15:11:59 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 127535 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 6490D1007D7 for ; Fri, 25 Nov 2011 02:12:17 +1100 (EST) Received: (qmail 581 invoked by alias); 24 Nov 2011 15:12:16 -0000 Received: (qmail 564 invoked by uid 22791); 24 Nov 2011 15:12:15 -0000 X-SWARE-Spam-Status: No, hits=-7.2 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, 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; Thu, 24 Nov 2011 15:12:01 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id pAOFC0rI018107 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 24 Nov 2011 10:12:01 -0500 Received: from tyan-ft48-01.lab.bos.redhat.com (tyan-ft48-01.lab.bos.redhat.com [10.16.42.4]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id pAOFC0es025073 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 24 Nov 2011 10:12:00 -0500 Received: from tyan-ft48-01.lab.bos.redhat.com (tyan-ft48-01.lab.bos.redhat.com [127.0.0.1]) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4) with ESMTP id pAOFBx8C026912 for ; Thu, 24 Nov 2011 16:11:59 +0100 Received: (from jakub@localhost) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4/Submit) id pAOFBxmw026911 for gcc-patches@gcc.gnu.org; Thu, 24 Nov 2011 16:11:59 +0100 Date: Thu, 24 Nov 2011 16:11:59 +0100 From: Jakub Jelinek To: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix extract_range_from_assert for signed 1-bit precision types (PR tree-optimization/51247) Message-ID: <20111124151159.GJ27242@tyan-ft48-01.lab.bos.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! Since Richard's build_int_cst changes to make it effectively build_int_cst_type when extract_range_from_assert wants to subtract or add 1 to min or max of a signed 1-bit precision type, build_int_cst (..., 1) returns actually -1 constant and that overflows on the fold_build2, leading to ICEs later on. This patch in that case adds resp. subtracts -1 instead of subtracting resp. adding 1. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2011-11-24 Jakub Jelinek PR tree-optimization/51247 * tree-vrp.c (extract_range_from_assert): For signed 1-bit precision types instead of adding 1 subtract -1 and instead of subtracting 1 add -1 to avoid overflows. * gcc.c-torture/compile/pr51247.c: New test. Jakub --- gcc/tree-vrp.c.jj 2011-10-17 22:27:42.000000000 +0200 +++ gcc/tree-vrp.c 2011-11-24 11:23:23.032335859 +0100 @@ -1693,8 +1693,13 @@ extract_range_from_assert (value_range_t /* For LT_EXPR, we create the range [MIN, MAX - 1]. */ if (cond_code == LT_EXPR) { - tree one = build_int_cst (TREE_TYPE (max), 1); - max = fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, one); + if (TYPE_PRECISION (TREE_TYPE (max)) == 1 + && !TYPE_UNSIGNED (TREE_TYPE (max))) + max = fold_build2 (PLUS_EXPR, TREE_TYPE (max), max, + build_int_cst (TREE_TYPE (max), -1)); + else + max = fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, + build_int_cst (TREE_TYPE (max), 1)); if (EXPR_P (max)) TREE_NO_WARNING (max) = 1; } @@ -1728,8 +1733,13 @@ extract_range_from_assert (value_range_t /* For GT_EXPR, we create the range [MIN + 1, MAX]. */ if (cond_code == GT_EXPR) { - tree one = build_int_cst (TREE_TYPE (min), 1); - min = fold_build2 (PLUS_EXPR, TREE_TYPE (min), min, one); + if (TYPE_PRECISION (TREE_TYPE (min)) == 1 + && !TYPE_UNSIGNED (TREE_TYPE (min))) + min = fold_build2 (MINUS_EXPR, TREE_TYPE (min), min, + build_int_cst (TREE_TYPE (min), -1)); + else + min = fold_build2 (PLUS_EXPR, TREE_TYPE (min), min, + build_int_cst (TREE_TYPE (min), 1)); if (EXPR_P (min)) TREE_NO_WARNING (min) = 1; } @@ -1915,9 +1925,19 @@ extract_range_from_assert (value_range_t min = positive_overflow_infinity (TREE_TYPE (var_vr->min)); } else if (!POINTER_TYPE_P (TREE_TYPE (var_vr->min))) - min = fold_build2 (PLUS_EXPR, TREE_TYPE (var_vr->min), - anti_max, - build_int_cst (TREE_TYPE (var_vr->min), 1)); + { + if (TYPE_PRECISION (TREE_TYPE (var_vr->min)) == 1 + && !TYPE_UNSIGNED (TREE_TYPE (var_vr->min))) + min = fold_build2 (MINUS_EXPR, TREE_TYPE (var_vr->min), + anti_max, + build_int_cst (TREE_TYPE (var_vr->min), + -1)); + else + min = fold_build2 (PLUS_EXPR, TREE_TYPE (var_vr->min), + anti_max, + build_int_cst (TREE_TYPE (var_vr->min), + 1)); + } else min = fold_build_pointer_plus_hwi (anti_max, 1); max = real_max; @@ -1942,9 +1962,19 @@ extract_range_from_assert (value_range_t max = negative_overflow_infinity (TREE_TYPE (var_vr->min)); } else if (!POINTER_TYPE_P (TREE_TYPE (var_vr->min))) - max = fold_build2 (MINUS_EXPR, TREE_TYPE (var_vr->min), - anti_min, - build_int_cst (TREE_TYPE (var_vr->min), 1)); + { + if (TYPE_PRECISION (TREE_TYPE (var_vr->min)) == 1 + && !TYPE_UNSIGNED (TREE_TYPE (var_vr->min))) + max = fold_build2 (PLUS_EXPR, TREE_TYPE (var_vr->min), + anti_min, + build_int_cst (TREE_TYPE (var_vr->min), + -1)); + else + max = fold_build2 (MINUS_EXPR, TREE_TYPE (var_vr->min), + anti_min, + build_int_cst (TREE_TYPE (var_vr->min), + 1)); + } else max = fold_build_pointer_plus_hwi (anti_min, -1); min = real_min; --- gcc/testsuite/gcc.c-torture/compile/pr51247.c.jj 2011-11-24 11:28:18.293592580 +0100 +++ gcc/testsuite/gcc.c-torture/compile/pr51247.c 2011-11-24 11:27:53.000000000 +0100 @@ -0,0 +1,16 @@ +/* PR tree-optimization/51247 */ + +struct S { int s : 1; }; +int a; + +void +foo (int x, int y) +{ + struct S s; + s.s = !!y; + while (1) + { + unsigned l = 94967295; + a = x || (s.s &= l); + } +}