From patchwork Sat Nov 11 22:03:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Glisse X-Patchwork-Id: 837091 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-466587-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="DTFDyLEd"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yZ9rq5PS5z9s7F for ; Sun, 12 Nov 2017 09:03:23 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=t9o1/UYjUz34tTb1qgxIE1PTAJWQ91fn0NlGHj5TPIlnQdVef6MBO gTjJtE9Rx0/1ddswvoF5mdrSZATtzOzT6oeW5HPu397N+g52FQHJgLdQq3T3SAt/ zDMChK2hV1onyZnmhb8+uEnTSqlIde+tNVVIp/UfvFOw2AnDw6bwnc= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=ZfJfkVZdf+MFg5Cq3XcbyEUG/2Y=; b=DTFDyLEdUgNI7zwm4vxe VDK251xdJn3tF04Heu6ws/uki2/Ik8yQ9mVdBp0Q/TaBrAnXlpR4fF92TtLcgH0j 0N9D1UuBkOiyaQkeabu45sxqLeWNSeYOoirKjsSA6KQFPFlcfQQsPmXJ1ld4kJ1g /Mx6sMst4QL/aKmGT4TLFvs= Received: (qmail 5004 invoked by alias); 11 Nov 2017 22:03:16 -0000 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 Received: (qmail 4988 invoked by uid 89); 11 Nov 2017 22:03:15 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-9.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=H*c:HHHHH X-HELO: mail3-relais-sop.national.inria.fr Received: from mail3-relais-sop.national.inria.fr (HELO mail3-relais-sop.national.inria.fr) (192.134.164.104) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 11 Nov 2017 22:03:13 +0000 Received: from ip-195.net-89-2-234.rev.numericable.fr (HELO stedding) ([89.2.234.195]) by mail3-relais-sop.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 11 Nov 2017 23:03:11 +0100 Date: Sat, 11 Nov 2017 23:03:06 +0100 (CET) From: Marc Glisse To: gcc-patches@gcc.gnu.org Subject: VRP: x+1 and -x cannot be INT_MIN Message-ID: User-Agent: Alpine 2.02 (DEB 1266 2009-07-14) MIME-Version: 1.0 Hello, with undefined overflow, just because we know nothing about one of the arguments of an addition doesn't mean we can't say something about the result. We could constrain more the cases where we replace VR_VARYING with a full VR_RANGE, but I didn't want to duplicate too much logic. The 20040409 testcases were introduced to test an RTL transformation, so I don't feel too bad adding -fwrapv to work around the undefined overflows they exhibit. Bootstrap+regtest on powerpc64le-unknown-linux-gnu. 2017-11-13 Marc Glisse gcc/ * tree-vrp.c (extract_range_from_binary_expr_1) [PLUS_EXPR, MINUS_EXPR]: Use a full range for VR_VARYING. gcc/testsuite/ PR testsuite/82951 * gcc.c-torture/execute/20040409-1.c: Use -fwrapv. * gcc.c-torture/execute/20040409-2.c: Likewise. * gcc.c-torture/execute/20040409-3.c: Likewise. * gcc.dg/tree-ssa/vrp118.c: New file. Index: gcc/testsuite/gcc.c-torture/execute/20040409-1.c =================================================================== --- gcc/testsuite/gcc.c-torture/execute/20040409-1.c (revision 254629) +++ gcc/testsuite/gcc.c-torture/execute/20040409-1.c (working copy) @@ -1,10 +1,12 @@ +/* { dg-options "-fwrapv" } */ + #include extern void abort (); int test1(int x) { return x ^ INT_MIN; } unsigned int test1u(unsigned int x) Index: gcc/testsuite/gcc.c-torture/execute/20040409-2.c =================================================================== --- gcc/testsuite/gcc.c-torture/execute/20040409-2.c (revision 254629) +++ gcc/testsuite/gcc.c-torture/execute/20040409-2.c (working copy) @@ -1,10 +1,12 @@ +/* { dg-options "-fwrapv" } */ + #include extern void abort (); int test1(int x) { return (x ^ INT_MIN) ^ 0x1234; } unsigned int test1u(unsigned int x) Index: gcc/testsuite/gcc.c-torture/execute/20040409-3.c =================================================================== --- gcc/testsuite/gcc.c-torture/execute/20040409-3.c (revision 254629) +++ gcc/testsuite/gcc.c-torture/execute/20040409-3.c (working copy) @@ -1,10 +1,12 @@ +/* { dg-options "-fwrapv" } */ + #include extern void abort (); int test1(int x) { return ~(x ^ INT_MIN); } unsigned int test1u(unsigned int x) Index: gcc/testsuite/gcc.dg/tree-ssa/vrp118.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/vrp118.c (nonexistent) +++ gcc/testsuite/gcc.dg/tree-ssa/vrp118.c (working copy) @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +void eliminate_me(); +void f(int x,int y){ + if (y < 4) + __builtin_unreachable(); + x += y; + if (x == -__INT_MAX__) + eliminate_me (); +} + +/* { dg-final { scan-tree-dump-not "eliminate_me" "optimized" } } */ Index: gcc/tree-vrp.c =================================================================== --- gcc/tree-vrp.c (revision 254629) +++ gcc/tree-vrp.c (working copy) @@ -2086,20 +2086,38 @@ extract_range_from_binary_expr_1 (value_ else set_value_range_to_varying (vr); return; } /* For integer ranges, apply the operation to each end of the range and see what we end up with. */ if (code == PLUS_EXPR || code == MINUS_EXPR) { + /* If one argument is varying, we can sometimes still deduce a + range for the output: any + [3, +INF] is in [MIN+3, +INF]. */ + if (TYPE_OVERFLOW_UNDEFINED (expr_type)) + { + if(vr0.type == VR_VARYING && vr1.type == VR_RANGE) + { + vr0.type = type = VR_RANGE; + vr0.min = vrp_val_min (expr_type); + vr0.max = vrp_val_max (expr_type); + } + if(vr1.type == VR_VARYING && vr0.type == VR_RANGE) + { + vr1.type = VR_RANGE; + vr1.min = vrp_val_min (expr_type); + vr1.max = vrp_val_max (expr_type); + } + } + const bool minus_p = (code == MINUS_EXPR); tree min_op0 = vr0.min; tree min_op1 = minus_p ? vr1.max : vr1.min; tree max_op0 = vr0.max; tree max_op1 = minus_p ? vr1.min : vr1.max; tree sym_min_op0 = NULL_TREE; tree sym_min_op1 = NULL_TREE; tree sym_max_op0 = NULL_TREE; tree sym_max_op1 = NULL_TREE; bool neg_min_op0, neg_min_op1, neg_max_op0, neg_max_op1;