From patchwork Fri Dec 6 16:41:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 1205202 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-515355-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="mm11oLhU"; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="BZMOlrOZ"; 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 47Tyzh3b5fz9sR7 for ; Sat, 7 Dec 2019 03:42:06 +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:cc:subject:message-id:reply-to:mime-version :content-type:content-transfer-encoding; q=dns; s=default; b=ZyH RSS+HTxKHMj9jCKN7+cyaxR8aQ7xWjjWEUN5Gbe7qu3c5tPFzJ9oLmo2PyV4iP6E E91biUfem68JEoMvqWPo37CF7SfaFy7D5a1n3nG4W/qc8fsXEPVe4rnxfF3p9d1E C1xWhwYHFrAlOZA6xvtmCJZ9dNW57M1m40MmwBoY= 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:content-transfer-encoding; s=default; bh=Cb1Gu6oFt xJhuigMn7CYWaz3bAI=; b=mm11oLhUIyvh3wofkTmUMxjaTJcz+PTiCdm1sq+/x IfUrn7/MBNVattg1W/CKiEAs+DxDHeKep7xK/jJK5v9PRcVB9ToExsSurg29I1Pc 7UIq8ch2txOIn2xOKy6sAKW2u34zJfd2ULBBEBIt//B0T1GlrfGAd9c+eUD9tjfQ PU= Received: (qmail 102058 invoked by alias); 6 Dec 2019 16:41:59 -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 102050 invoked by uid 89); 6 Dec 2019 16:41:58 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-7.8 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, SPF_PASS autolearn=ham version=3.3.1 spammy= X-HELO: us-smtp-1.mimecast.com Received: from us-smtp-delivery-1.mimecast.com (HELO us-smtp-1.mimecast.com) (205.139.110.120) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 06 Dec 2019 16:41:56 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1575650515; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=oePdhND09w1WwWapEwOXKvxY84QezAwcF7RqZ3WNfy4=; b=BZMOlrOZyuOEiXjhRI36kzCjiyD41RN3pXeL/xh8tdYFIHNY4pV/Vp+QExn2IQYvZjQoiM g3HctcBMbGH16uix0as9rjyAvjENvT+TzmuHLm3xUN6Dh6+wHDDTksd/Z+tM2V0L5AtHZy QI04XOPfch2OVuS8r8pPynubqsOl0Xw= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-236-H_sjUL-nPJ6AFPuqzYZfAw-1; Fri, 06 Dec 2019 11:41:53 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C8FA51005512; Fri, 6 Dec 2019 16:41:52 +0000 (UTC) Received: from tucnak.zalov.cz (ovpn-117-59.ams2.redhat.com [10.36.117.59]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 613C95D6C3; Fri, 6 Dec 2019 16:41:52 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id xB6GfokB025395; Fri, 6 Dec 2019 17:41:50 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id xB6GfmLP025394; Fri, 6 Dec 2019 17:41:48 +0100 Date: Fri, 6 Dec 2019 17:41:48 +0100 From: Jakub Jelinek To: Richard Biener Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] Canonicalize fancy ways of expressing blend operation into COND_EXPR (PR tree-optimization/92834) Message-ID: <20191206164148.GF10088@tucnak> Reply-To: Jakub Jelinek MIME-Version: 1.0 User-Agent: Mutt/1.11.3 (2019-02-01) X-Mimecast-Spam-Score: 0 Content-Disposition: inline X-IsSubscribed: yes Hi! The following patch canonicalizes fancy ways of writing cond ? A : B into COND_EXPR, which is what we expect people writing and thus are able to optimize it better. If in some case we wouldn't optimize it better, the right way would be improve the COND_EXPR handling, as that is what people are using in the wild most of the time. E.g. on the testcase in the patch on x86_64-linux with -O2, the difference is that test used to be 519 bytes long and now is 223, with -O2 -march=skylake used to be the same 519 bytes long and now is 275 bytes (in that case it uses the SSE4.1+ min/max). Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2019-12-06 Jakub Jelinek PR tree-optimization/92834 * match.pd (A - ((A - B) & -(C cmp D)) -> (C cmp D) ? B : A, A + ((B - A) & -(C cmp D)) -> (C cmp D) ? B : A): New simplifications. * gcc.dg/tree-ssa/pr92834.c: New test. Jakub --- gcc/match.pd.jj 2019-12-06 14:07:26.877749065 +0100 +++ gcc/match.pd 2019-12-06 15:06:08.042953309 +0100 @@ -2697,6 +2697,31 @@ (define_operator_list COND_TERNARY (cmp (minmax @0 INTEGER_CST@1) INTEGER_CST@2) (comb (cmp @0 @2) (cmp @1 @2)))) +/* Undo fancy way of writing max/min or other ?: expressions, + like a - ((a - b) & -(a < b)), in this case into (a < b) ? b : a. + People normally use ?: and that is what we actually try to optimize. */ +(for cmp (simple_comparison) + (simplify + (minus @0 (bit_and:c (minus @0 @1) + (convert? (negate@4 (convert? (cmp@5 @2 @3)))))) + (if (INTEGRAL_TYPE_P (type) + && INTEGRAL_TYPE_P (TREE_TYPE (@4)) + && TREE_CODE (TREE_TYPE (@4)) != BOOLEAN_TYPE + && INTEGRAL_TYPE_P (TREE_TYPE (@5)) + && (TYPE_PRECISION (TREE_TYPE (@4)) >= TYPE_PRECISION (type) + || !TYPE_UNSIGNED (TREE_TYPE (@4)))) + (cond (cmp @2 @3) @1 @0))) + (simplify + (plus:c @0 (bit_and:c (minus @1 @0) + (convert? (negate@4 (convert? (cmp@5 @2 @3)))))) + (if (INTEGRAL_TYPE_P (type) + && INTEGRAL_TYPE_P (TREE_TYPE (@4)) + && TREE_CODE (TREE_TYPE (@4)) != BOOLEAN_TYPE + && INTEGRAL_TYPE_P (TREE_TYPE (@5)) + && (TYPE_PRECISION (TREE_TYPE (@4)) >= TYPE_PRECISION (type) + || !TYPE_UNSIGNED (TREE_TYPE (@4)))) + (cond (cmp @2 @3) @1 @0)))) + /* Simplifications of shift and rotates. */ (for rotate (lrotate rrotate) --- gcc/testsuite/gcc.dg/tree-ssa/pr92834.c.jj 2019-12-06 15:24:56.817353747 +0100 +++ gcc/testsuite/gcc.dg/tree-ssa/pr92834.c 2019-12-06 15:24:08.921100518 +0100 @@ -0,0 +1,122 @@ +/* PR tree-optimization/92834 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times "MIN_EXPR <" 8 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "MAX_EXPR <" 8 "optimized" } } */ + +static inline unsigned +umax1 (unsigned a, unsigned b) +{ + return a - ((a - b) & -(a < b)); +} + +static inline unsigned +umin1 (unsigned a, unsigned b) +{ + return a - ((a - b) & -(a > b)); +} + +static inline int +smax1 (int a, int b) +{ + return a - ((a - b) & -(a < b)); +} + +static inline int +smin1 (int a, int b) +{ + return a - ((a - b) & -(a > b)); +} + +static inline unsigned long long +umax2 (unsigned long long a, unsigned long long b) +{ + return a - ((a - b) & -(a <= b)); +} + +static inline unsigned long long +umin2 (unsigned long long a, unsigned long long b) +{ + return a - ((a - b) & -(a >= b)); +} + +static inline long long +smax2 (long long a, long long b) +{ + return a - ((a - b) & -(a <= b)); +} + +static inline long long +smin2 (long long a, long long b) +{ + return a - ((a - b) & -(a >= b)); +} + +static inline unsigned +umax3 (unsigned a, unsigned b) +{ + return a + ((b - a) & -(a < b)); +} + +static inline unsigned +umin3 (unsigned a, unsigned b) +{ + return a + ((b - a) & -(a > b)); +} + +static inline int +smax3 (int a, int b) +{ + return a + ((b - a) & -(a < b)); +} + +static inline int +smin3 (int a, int b) +{ + return a + ((b - a) & -(a > b)); +} + +static inline unsigned long long +umax4 (unsigned long long a, unsigned long long b) +{ + return a + ((b - a) & -(a <= b)); +} + +static inline unsigned long long +umin4 (unsigned long long a, unsigned long long b) +{ + return a + ((b - a) & -(a >= b)); +} + +static inline long long +smax4 (long long a, long long b) +{ + return a + ((b - a) & -(a <= b)); +} + +static inline long long +smin4 (long long a, long long b) +{ + return a + ((b - a) & -(a >= b)); +} + +void +test (unsigned *x, int *y, unsigned long long *z, long long *w) +{ + x[2] = umax1 (x[0], x[1]); + x[5] = umin1 (x[2], x[3]); + y[2] = smax1 (y[0], y[1]); + y[5] = smin1 (y[2], y[3]); + z[2] = umax2 (z[0], z[1]); + z[5] = umin2 (z[2], z[3]); + w[2] = smax2 (w[0], w[1]); + w[5] = smin2 (w[2], w[3]); + x[8] = umax3 (x[6], x[7]); + x[11] = umin3 (x[9], x[10]); + y[8] = smax3 (y[6], y[7]); + y[11] = smin3 (y[9], y[10]); + z[8] = umax4 (z[6], z[7]); + z[11] = umin4 (z[9], z[10]); + w[8] = smax4 (w[6], w[7]); + w[11] = smin4 (w[9], w[10]); +}