From patchwork Fri Dec 4 21:45:19 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Glisse X-Patchwork-Id: 552892 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 1395B1402A3 for ; Sat, 5 Dec 2015 08:45:44 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=s43CnJK5; 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:reply-to:to:subject:in-reply-to:message-id:references :mime-version:content-type; q=dns; s=default; b=yYcOpCbHD/+wH1mm 6o9YavF88F4qEjUDZQMT44aAy+/92KO1PzqpUSo7l64wbKm7F+lEFRB964TrRCmn Nkr7BVQRyNUnRQ6/zpmTm35iU2Vava8sPJmpitqpWPl3sZ07Q9MJhEjp+mq4Pgen TqflU4WTlgRB8/pnkXy3+zCJPYk= 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:reply-to:to:subject:in-reply-to:message-id:references :mime-version:content-type; s=default; bh=u85eaibUr6OmgX8IDwc2nu 99EUM=; b=s43CnJK5oWF0JkEWMo+rxL1an8sMj8OVBVHXsqbO1N0rtrywwo1GAT Vvim0xYxznyXERGViwvPV4IcADvtN5H9GyS4k+kICCr3SlQb4/rqhQteORVK+Yke 7oVWmx+C9LLO1pcSrnyATpO08K++0HFd6Xk4FRPMvywVvpXt3mp1o= Received: (qmail 77437 invoked by alias); 4 Dec 2015 21:45:36 -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 77421 invoked by uid 89); 4 Dec 2015 21:45:35 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.4 required=5.0 tests=AWL, BAYES_00, KAM_ASCII_DIVIDERS, KAM_LAZY_DOMAIN_SECURITY, T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: mail2-relais-roc.national.inria.fr Received: from mail2-relais-roc.national.inria.fr (HELO mail2-relais-roc.national.inria.fr) (192.134.164.83) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Fri, 04 Dec 2015 21:45:32 +0000 Received: from 81-64-192-195.rev.numericable.fr (HELO laptop-mg.local) ([81.64.192.195]) by mail2-relais-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 04 Dec 2015 22:45:28 +0100 Date: Fri, 4 Dec 2015 22:45:19 +0100 (CET) From: Marc Glisse Reply-To: gcc-patches@gcc.gnu.org To: gcc-patches@gcc.gnu.org Subject: Re: [PATCH] Convert manual unsigned +/- overflow checking into {ADD, SUB}_OVERFLOW (PR target/67089) In-Reply-To: Message-ID: References: <20151124205352.GS5675@tucnak.redhat.com> <20151125083627.GU5675@tucnak.redhat.com> <20151125090425.GW5675@tucnak.redhat.com> User-Agent: Alpine 2.02 (DEB 1266 2009-07-14) MIME-Version: 1.0 On Wed, 25 Nov 2015, Marc Glisse wrote: >> So, I'd really prefer doing x-y>x to y>x only for single use. > > Ok Let me post this patch (needs testing on x86, I only tested on ppc which does not implement the new optabs) so I can more easily find it again at next stage 1. It produces imag()==0 or imag()!=0 because I think that's what Jakub's patch does. Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 231300) +++ gcc/match.pd (working copy) @@ -2396,20 +2396,62 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && types_match (type, TREE_TYPE (@0))) (non_lvalue @0))) /* Do not handle bool_var == 0 becomes !bool_var or bool_var != 1 becomes !bool_var here because that only is good in assignment context as long as we require a tcc_comparison in GIMPLE_CONDs where we'd replace if (x == 0) with tem = ~x; if (tem != 0) which is clearly less optimal and which we'll transform again in forwprop. */ +/* To detect overflow in unsigned A - B, A < B is simpler than A - B > A. + However, the detection logic for SUB_OVERFLOW in tree-ssa-math-opts.c + expects the long form, so we restrict the transformation for now. */ +(for cmp (gt le) + (simplify + (cmp (minus@2 @0 @1) @0) + (if (single_use (@2) + && TYPE_UNSIGNED (TREE_TYPE (@0)) + && TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))) + (cmp @1 @0)))) +(for cmp (lt ge) + (simplify + (cmp @0 (minus@2 @0 @1)) + (if (single_use (@2) + && TYPE_UNSIGNED (TREE_TYPE (@0)) + && TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))) + (cmp @0 @1)))) +/* Testing for overflow is unnecessary if we already know the result. */ +(for cmp (lt ge) + out (ne eq) + (simplify + (cmp @0 (realpart (IFN_SUB_OVERFLOW@2 @0 @1))) + (if (TYPE_UNSIGNED (TREE_TYPE (@0))) + (out (imagpart @2) { build_zero_cst (TREE_TYPE (@0)); })))) +(for cmp (gt le) + out (ne eq) + (simplify + (cmp (realpart (IFN_SUB_OVERFLOW@2 @0 @1)) @0) + (if (TYPE_UNSIGNED (TREE_TYPE (@0))) + (out (imagpart @2) { build_zero_cst (TREE_TYPE (@0)); })))) +(for cmp (lt ge) + out (ne eq) + (simplify + (cmp (realpart (IFN_ADD_OVERFLOW@2 @0 @1)) @0) + (if (TYPE_UNSIGNED (TREE_TYPE (@0))) + (out (imagpart @2) { build_zero_cst (TREE_TYPE (@0)); })))) +(for cmp (gt le) + out (ne eq) + (simplify + (cmp @0 (realpart (IFN_ADD_OVERFLOW@2 @0 @1))) + (if (TYPE_UNSIGNED (TREE_TYPE (@0))) + (out (imagpart @2) { build_zero_cst (TREE_TYPE (@0)); })))) /* Simplification of math builtins. These rules must all be optimizations as well as IL simplifications. If there is a possibility that the new form could be a pessimization, the rule should go in the canonicalization section that follows this one. Rules can generally go in this section if they satisfy one of the following: - the rule describes an identity Index: gcc/testsuite/gcc.dg/tree-ssa/minus-ovf.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/minus-ovf.c (revision 0) +++ gcc/testsuite/gcc.dg/tree-ssa/minus-ovf.c (working copy) @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +int f(unsigned a, unsigned b) { + unsigned remove = a - b; + return remove > a; +} + +int g(unsigned a, unsigned b) { + unsigned remove = a - b; + return remove <= a; +} + +int h(unsigned a, unsigned b) { + unsigned remove = a - b; + return a < remove; +} + +int i(unsigned a, unsigned b) { + unsigned remove = a - b; + return a >= remove; +} + +/* { dg-final { scan-tree-dump-not "remove" "optimized" } } */ Index: gcc/testsuite/gcc.dg/tree-ssa/overflow-1.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/overflow-1.c (revision 0) +++ gcc/testsuite/gcc.dg/tree-ssa/overflow-1.c (working copy) @@ -0,0 +1,48 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized-raw" } */ + +int carry; +int f(unsigned a, unsigned b) { + unsigned r; + carry = __builtin_sub_overflow(a, b, &r); + return r > a; +} +int g(unsigned a, unsigned b) { + unsigned r; + carry = __builtin_sub_overflow(a, b, &r); + return a < r; +} +int h(unsigned a, unsigned b) { + unsigned r; + carry = __builtin_sub_overflow(a, b, &r); + return r <= a; +} +int i(unsigned a, unsigned b) { + unsigned r; + carry = __builtin_sub_overflow(a, b, &r); + return a >= r; +} +int j(unsigned a, unsigned b) { + unsigned r; + carry = __builtin_add_overflow(a, b, &r); + return r < a; +} +int k(unsigned a, unsigned b) { + unsigned r; + carry = __builtin_add_overflow(a, b, &r); + return a > r; +} +int l(unsigned a, unsigned b) { + unsigned r; + carry = __builtin_add_overflow(a, b, &r); + return r >= a; +} +int m(unsigned a, unsigned b) { + unsigned r; + carry = __builtin_add_overflow(a, b, &r); + return a <= r; +} + +/* { dg-final { scan-tree-dump-not "(le|lt|ge|gt)_expr" "optimized" } } */ +/* { dg-final { scan-tree-dump-times "ADD_OVERFLOW" 4 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "SUB_OVERFLOW" 4 "optimized" } } */