From patchwork Mon May 18 19:48:36 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 473590 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id A9CC614029C for ; Tue, 19 May 2015 05:48:53 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=xBlv1Ll/; dkim-atps=neutral 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:cc:subject:message-id:reply-to:mime-version :content-type; q=dns; s=default; b=h9fVJgKv4BXpn/6MNqY13yhtyQu+S fZvHBPCymiZaF66pRJAFJwGJldjLBz+xm17KmUiWRj23DnnwT9mUkilhGTKNvi8u 3bmjYMUk7az1IxOKYUtdnmCDUbPUjrQZFxfbWw2Bei93KdwQlV4N7PqXrBLVQV88 bPGn+7L6yxcSvo= 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:cc:subject:message-id:reply-to:mime-version :content-type; s=default; bh=Horfj6tQZ6re+uVzUBjxx6kmhu0=; b=xBl v1Ll/WrPbzEiB6rr/K8J5hYAmzmI6uaBsa+nithtFQXKQeybPNZ49a8y0oW87Efy Y9p7R0klGKnwVKceNBDOM2eecv6hvFGyEOyxK5Aaprn8C0PRrn5qRXyxeBTZLbf8 bJO2KQHFch7sBQLIrc0wqSOxZzmYwhw2gn3CbruA= Received: (qmail 84089 invoked by alias); 18 May 2015 19:48:46 -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 84068 invoked by uid 89); 18 May 2015 19:48:45 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.4 required=5.0 tests=AWL, BAYES_00, KAM_LAZY_DOMAIN_SECURITY, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Mon, 18 May 2015 19:48:44 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t4IJmgax015870 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 18 May 2015 15:48:42 -0400 Received: from tucnak.zalov.cz (ovpn-116-89.ams2.redhat.com [10.36.116.89]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t4IJmeHu016797 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 18 May 2015 15:48:41 -0400 Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.14.9/8.14.9) with ESMTP id t4IJmc9s023110; Mon, 18 May 2015 21:48:38 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.14.9/8.14.9/Submit) id t4IJmaGj023109; Mon, 18 May 2015 21:48:36 +0200 Date: Mon, 18 May 2015 21:48:36 +0200 From: Jakub Jelinek To: Richard Biener , Jeff Law Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix match.pd narrowing opt (PR tree-optimization/66187) Message-ID: <20150518194836.GW1751@tucnak.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes Hi! As the testcases show, for signed types we really should use SIGNED rather than UNSIGNED as tree_int_cst_min_precision argument, that function doesn't really do the desired thing with UNSIGNED for negative values and with -fwrapv we just want the narrowing cast to not lose anything from the number. Additionally, as for TYPE_OVERFLOW_WRAPS case we perform the +/-/& in unsigned type, we have to avoid all negative masks, because those surely have the higher bits set. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? For plus and unsigned type, we could improve it even further, as in that case we could just check if the bit immediately above precision is clear in the mask, higher bits than that are uninteresting, because the addition will have always zeros there. Perhaps as a follow-up? I mean say uchar foo (uchar a, uchar b) { return (x + y) & 0x72fe; } can be done as uchar addition & 0xfe, but not e.g. & 0x71fe. 2015-05-18 Jakub Jelinek PR tree-optimization/66187 * match.pd ((bit_and (plus/minus (convert @0) (convert @1)) mask)): Pass TYPE_SIGN to tree_int_cst_min_precision. If !TYPE_OVERFLOW_WRAPS, ensure @4 is non-negative. * gcc.c-torture/execute/pr66187.c: New test. * gcc.dg/pr66187-1.c: New test. * gcc.dg/pr66187-2.c: New test. Jakub --- gcc/match.pd.jj 2015-05-18 09:46:39.000000000 +0200 +++ gcc/match.pd 2015-05-18 10:20:24.944475737 +0200 @@ -1115,8 +1115,10 @@ (define_operator_list CBRT BUILT_IN_CBRT /* The inner conversion must be a widening conversion. */ && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE (@0)) && types_match (@0, @1) - && (tree_int_cst_min_precision (@4, UNSIGNED) + && (tree_int_cst_min_precision (@4, TYPE_SIGN (TREE_TYPE (@0))) <= TYPE_PRECISION (TREE_TYPE (@0))) + && (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)) + || tree_int_cst_sgn (@4) >= 0) && single_use (@5)) (if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))) (with { tree ntype = TREE_TYPE (@0); } --- gcc/testsuite/gcc.c-torture/execute/pr66187.c.jj 2015-05-18 10:53:43.953654893 +0200 +++ gcc/testsuite/gcc.c-torture/execute/pr66187.c 2015-05-18 10:53:28.000000000 +0200 @@ -0,0 +1,16 @@ +/* PR tree-optimization/66187 */ + +int a = 1, e = -1; +short b, f; + +int +main () +{ + f = e; + int g = b < 0 ? 0 : f + b; + if ((g & -4) < 0) + a = 0; + if (a) + __builtin_abort (); + return 0; +} --- gcc/testsuite/gcc.dg/pr66187-1.c.jj 2015-05-18 10:54:30.677906029 +0200 +++ gcc/testsuite/gcc.dg/pr66187-1.c 2015-05-18 12:30:17.000000000 +0200 @@ -0,0 +1,97 @@ +/* PR tree-optimization/66187 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-wrapv" } */ + +__attribute__((noinline, noclone)) int +f0 (unsigned char x, unsigned char y) +{ + return (x + y) & 0x2ff; +} + +__attribute__((noinline, noclone)) int +f1 (unsigned char x, unsigned char y) +{ + return (x - y) & 0x2ff; +} + +__attribute__((noinline, noclone)) int +f2 (signed char x, signed char y) +{ + return (x + y) & -4; +} + +__attribute__((noinline, noclone)) int +f3 (signed char x, signed char y) +{ + return (x + y) & 0xf8; +} + +__attribute__((noinline, noclone)) int +f4 (signed char x, signed char y) +{ + return (x + y) & 0x78; +} + +__attribute__((noinline, noclone)) int +f5 (unsigned char x, unsigned char y) +{ + int a = x; + int b = y; + int c = a + b; + return c & 0x2ff; +} + +__attribute__((noinline, noclone)) int +f6 (unsigned char x, unsigned char y) +{ + int a = x; + int b = y; + int c = a - b; + return c & 0x2ff; +} + +__attribute__((noinline, noclone)) int +f7 (signed char x, signed char y) +{ + int a = x; + int b = y; + int c = a + b; + return c & -4; +} + +__attribute__((noinline, noclone)) int +f8 (signed char x, signed char y) +{ + int a = x; + int b = y; + int c = a + b; + return c & 0xf8; +} + +__attribute__((noinline, noclone)) int +f9 (signed char x, signed char y) +{ + int a = x; + int b = y; + int c = a + b; + return c & 0x78; +} + +int +main () +{ + if (__SCHAR_MAX__ != 127 || sizeof (int) != 4) + return 0; + if (f0 (0xff, 0xff) != 0xfe + || f1 (0, 1) != 0x2ff + || f2 (-2, 1) != -4 + || f3 (-2, 1) != 0xf8 + || f4 (-2, 1) != 0x78 + || f5 (0xff, 0xff) != 0xfe + || f6 (0, 1) != 0x2ff + || f7 (-2, 1) != -4 + || f8 (-2, 1) != 0xf8 + || f9 (-2, 1) != 0x78) + __builtin_abort (); + return 0; +} --- gcc/testsuite/gcc.dg/pr66187-2.c.jj 2015-05-18 12:31:39.398176973 +0200 +++ gcc/testsuite/gcc.dg/pr66187-2.c 2015-05-18 12:31:46.319067151 +0200 @@ -0,0 +1,97 @@ +/* PR tree-optimization/66187 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fwrapv" } */ + +__attribute__((noinline, noclone)) int +f0 (unsigned char x, unsigned char y) +{ + return (x + y) & 0x2ff; +} + +__attribute__((noinline, noclone)) int +f1 (unsigned char x, unsigned char y) +{ + return (x - y) & 0x2ff; +} + +__attribute__((noinline, noclone)) int +f2 (signed char x, signed char y) +{ + return (x + y) & -4; +} + +__attribute__((noinline, noclone)) int +f3 (signed char x, signed char y) +{ + return (x + y) & 0xf8; +} + +__attribute__((noinline, noclone)) int +f4 (signed char x, signed char y) +{ + return (x + y) & 0x78; +} + +__attribute__((noinline, noclone)) int +f5 (unsigned char x, unsigned char y) +{ + int a = x; + int b = y; + int c = a + b; + return c & 0x2ff; +} + +__attribute__((noinline, noclone)) int +f6 (unsigned char x, unsigned char y) +{ + int a = x; + int b = y; + int c = a - b; + return c & 0x2ff; +} + +__attribute__((noinline, noclone)) int +f7 (signed char x, signed char y) +{ + int a = x; + int b = y; + int c = a + b; + return c & -4; +} + +__attribute__((noinline, noclone)) int +f8 (signed char x, signed char y) +{ + int a = x; + int b = y; + int c = a + b; + return c & 0xf8; +} + +__attribute__((noinline, noclone)) int +f9 (signed char x, signed char y) +{ + int a = x; + int b = y; + int c = a + b; + return c & 0x78; +} + +int +main () +{ + if (__SCHAR_MAX__ != 127 || sizeof (int) != 4) + return 0; + if (f0 (0xff, 0xff) != 0xfe + || f1 (0, 1) != 0x2ff + || f2 (-2, 1) != -4 + || f3 (-2, 1) != 0xf8 + || f4 (-2, 1) != 0x78 + || f5 (0xff, 0xff) != 0xfe + || f6 (0, 1) != 0x2ff + || f7 (-2, 1) != -4 + || f8 (-2, 1) != 0xf8 + || f9 (-2, 1) != 0x78) + __builtin_abort (); + return 0; +}