From patchwork Thu May 24 08:37:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 136719 Delivered-To: patch@linaro.org Received: by 2002:a2e:9706:0:0:0:0:0 with SMTP id r6-v6csp1910305lji; Thu, 24 May 2018 01:38:02 -0700 (PDT) X-Google-Smtp-Source: AB8JxZowArsgecyk20zMixw0vPSvXwe2xxrdFsHfPU86Mfz2JVDgSlMKCJtKp6N+4nzhbXz5dCSe X-Received: by 2002:a63:4c8:: with SMTP id 191-v6mr424175pge.129.1527151082007; Thu, 24 May 2018 01:38:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527151082; cv=none; d=google.com; s=arc-20160816; b=a73IeMUG52ihKK18e/ptCQy0Uc3ySO2N6my8qdCMbc4G4oc4nvBn0+DQ6nxrox8x+2 MXy2kyeSW7J+Ek1s3oAituw11rltAx4u+rzBcKfHwkpeCRr/jUkygHGtO5gTakdo8Dec xxSsVB6jUBSda3Rdjq0skGTJf2QadhKkWVc8ORHD3dQATz+oXcW92XT4ueu94fN0a/gb iyzeTAk6ach2VLoXciE6fKjLuHX1tpjnltFB2q0PHxH01D9lPnu0I0FuEGx5BHlHykFt pZLqjjhb5Oa4sz89lyS9OGwvACJUcmIghf66sbPMvP0rBt4NDk7alB9mrJkaFZ84KO/d lzhw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:user-agent:message-id:date:subject:mail-followup-to:to :from:delivered-to:sender:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=+9rokP0JUGOnthYRe2JKIKvTGX3yLI55MIRhHdxSwQw=; b=LZ+m8QJ05HtYpd2DFPNv8Ztl6XlYSNPj7HzDWhZqfMSafG+eMOPTt7cUG62/h3GAJf vNuugmvxvx7n7Nx2nfvh2HtD5OEoCRmmuiKFVU5KY8vLgLaJ9IN+14ds5C4xXF+SIX8X NEeG3DXpreIQXdZaVBzdA7CRfcthQVqlOaj+c+gR6Xdheq8b4S/IufhvQIXWzx7jpAzJ ERs7Yj/hcMRxEeZRhDyD6LX3Zd46IP1uU3pPVdjS7Sg8T+TtqRL82ItzG/e0fsa1JAx1 HY86L3yADuaq45ANI+d8S7id3QpLZhKykjq6ljusrRREbwB98zzBWXQ2qnCDNvur/J52 +wUQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=hzxVO0XW; spf=pass (google.com: domain of gcc-patches-return-478352-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-478352-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id b84-v6si22643071pfb.189.2018.05.24.01.38.01 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 24 May 2018 01:38:01 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-478352-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=hzxVO0XW; spf=pass (google.com: domain of gcc-patches-return-478352-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-478352-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type; q=dns; s= default; b=RzM9D/9iOeMQlsBphWn3lEilWfwFjpZUj9IymH0lB6x3eXRxYwLHp UQuLzOLHSLWiafBwh2iv64WVASWOqox2KwNPNM7wW4r2oNB4Cu0QxI5Xfoobkhfp F6SEkIecy9GWtoBuPG14QRO+uXjSxL3Wu32UAowSNDdfPR4Z0AJZqE= 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:from :to:subject:date:message-id:mime-version:content-type; s= default; bh=c//E1915z2Ud15S9gl50anPwCHg=; b=hzxVO0XW439yGXE9H/Xy zKsdunwW5UgsvV1jzfhD0F2uRxVZJG8pkUkEW862mRCLUb2DFikE1WqgUDN1wqeI W1bmjtP7rnJi+KPHvjO9W9b3n9W6BLrc7gVY1gwLUyi8zOtOt0FQ/+EKeo7AYwjh ILOiBzpApPjg4QXoQCSyC1o= Received: (qmail 26254 invoked by alias); 24 May 2018 08:37:49 -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 26133 invoked by uid 89); 24 May 2018 08:37:32 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-15.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=1737, rtx_equal_p, fns, def_internal_fn X-HELO: mail-wm0-f45.google.com Received: from mail-wm0-f45.google.com (HELO mail-wm0-f45.google.com) (74.125.82.45) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 24 May 2018 08:37:24 +0000 Received: by mail-wm0-f45.google.com with SMTP id j4-v6so2743932wme.1 for ; Thu, 24 May 2018 01:37:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:mail-followup-to:subject:date:message-id :user-agent:mime-version; bh=+9rokP0JUGOnthYRe2JKIKvTGX3yLI55MIRhHdxSwQw=; b=CHkpLHDgAclr7SNdSdhyHCTaYoTGhnThnIZghFth42BVAnz2AYVZ7FnTMeVFlHQGeC tksuspB9FQ0Au4HjUyezcuf5G/lc5PjNQZ0VZhlWlTcrjSCpkgnU6lQ7csA7ZHaOyF/0 wTu9ny51wWWwoBBLcIAZApDqW/asirUyFScryRjlHFlJz4C5lKB9tQ0G0WnkAnDMejwE mBKDkD5G8jcYSTPi4xDkMObFoauZcZnVGIT/lWoD68eCKSLtQhJ8iZRQ6QAu01VsMqhG +cINsUAJGDh18g4ZA+9ewh+0lcLzd16KWDLxmqyHS0umtQ6pODUhJB6+V71niTIwyee3 KciA== X-Gm-Message-State: ALKqPwfw709Vq98fCLH1zfZyvSoIWRr55iop/rjGXBB8QftFKtsiSSLW 5X4b1wBKT1fQG/o65cXYFRsPzfzDGJs= X-Received: by 2002:a1c:1047:: with SMTP id 68-v6mr6483412wmq.132.1527151042003; Thu, 24 May 2018 01:37:22 -0700 (PDT) Received: from localhost (201.69.7.51.dyn.plus.net. [51.7.69.201]) by smtp.gmail.com with ESMTPSA id u35-v6sm31324953wrc.29.2018.05.24.01.37.21 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 24 May 2018 01:37:21 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Subject: Add an "else" argument to IFN_COND_* functions Date: Thu, 24 May 2018 09:37:20 +0100 Message-ID: <878t89e9fj.fsf@linaro.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) MIME-Version: 1.0 As suggested by Richard B, this patch changes the IFN_COND_* functions so that they take the else value of the ?: operation as a final argument, rather than always using argument 1. All current callers will still use the equivalent of argument 1, so this patch makes the SVE code assert that for now. Later patches add the general case. This relies on the earlier "Try harder to preserve operand ties in maybe_legitimize_operands" https://gcc.gnu.org/ml/gcc-patches/2018-05/msg01199.html Tested on aarch64-linux-gnu (with and without SVE), aarch64_be-elf and x86_64-linux-gnu. OK for the non-AArch64 bits? Thanks, Richard 2018-05-24 Richard Sandiford gcc/ * doc/md.texi: Update the documentation of the cond_* optabs to mention the new final operand. Fix GET_MODE_NUNITS call. Describe the scalar case too. * internal-fn.def (IFN_EXTRACT_LAST): Change type to fold_left. * internal-fn.c (expand_cond_unary_optab_fn): Expect 3 operands instead of 2. (expand_cond_binary_optab_fn): Expect 4 operands instead of 3. (get_conditional_internal_fn): Update comment. * tree-vect-loop.c (vectorizable_reduction): Pass the original accumulator value as a final argument to conditional functions. * config/aarch64/aarch64-sve.md (cond_): Turn into a define_expand and add an "else" operand. Assert for now that the else operand is equal to operand 2. Use SVE_INT_BINARY and SVE_COND_FP_BINARY instead of SVE_COND_INT_OP and SVE_COND_FP_OP. (*cond_): New patterns. * config/aarch64/iterators.md (UNSPEC_COND_SMAX, UNSPEC_COND_UMAX) (UNSPEC_COND_SMIN, UNSPEC_COND_UMIN, UNSPEC_COND_AND, UNSPEC_COND_ORR) (UNSPEC_COND_EOR): Delete. (optab): Remove associated mappings. (SVE_INT_BINARY): New code iterator. (sve_int_op): Remove int attribute and add "minus" to the code attribute. (SVE_COND_INT_OP): Delete. (SVE_COND_FP_OP): Rename to... (SVE_COND_FP_BINARY): ...this. Index: gcc/doc/md.texi =================================================================== --- gcc/doc/md.texi 2018-05-24 09:31:46.687834412 +0100 +++ gcc/doc/md.texi 2018-05-24 09:32:10.522816506 +0100 @@ -6349,13 +6349,21 @@ operand 0, otherwise (operand 2 + operan @itemx @samp{cond_smax@var{mode}} @itemx @samp{cond_umin@var{mode}} @itemx @samp{cond_umax@var{mode}} -Perform an elementwise operation on vector operands 2 and 3, -under the control of the vector mask in operand 1, and store the result -in operand 0. This is equivalent to: +When operand 1 is true, perform an operation on operands 2 and 3 and +store the result in operand 0, otherwise store operand 4 in operand 0. +The operation works elementwise if the operands are vectors. + +The scalar case is equivalent to: + +@smallexample +op0 = op1 ? op2 @var{op} op3 : op4; +@end smallexample + +while the vector case is equivalent to: @smallexample -for (i = 0; i < GET_MODE_NUNITS (@var{n}); i++) - op0[i] = op1[i] ? op2[i] @var{op} op3[i] : op2[i]; +for (i = 0; i < GET_MODE_NUNITS (@var{m}); i++) + op0[i] = op1[i] ? op2[i] @var{op} op3[i] : op4[i]; @end smallexample where, for example, @var{op} is @code{+} for @samp{cond_add@var{mode}}. @@ -6364,8 +6372,9 @@ When defined for floating-point modes, t are not interpreted if @var{op1[i]} is false, just like they would not be in a normal C @samp{?:} condition. -Operands 0, 2 and 3 all have mode @var{m}, while operand 1 has the mode -returned by @code{TARGET_VECTORIZE_GET_MASK_MODE}. +Operands 0, 2, 3 and 4 all have mode @var{m}. Operand 1 is a scalar +integer if @var{m} is scalar, otherwise it has the mode returned by +@code{TARGET_VECTORIZE_GET_MASK_MODE}. @cindex @code{neg@var{mode}cc} instruction pattern @item @samp{neg@var{mode}cc} Index: gcc/internal-fn.def =================================================================== --- gcc/internal-fn.def 2018-05-24 09:31:46.687834412 +0100 +++ gcc/internal-fn.def 2018-05-24 09:32:10.522816506 +0100 @@ -173,7 +173,7 @@ DEF_INTERNAL_OPTAB_FN (REDUC_XOR, ECF_CO /* Extract the last active element from a vector. */ DEF_INTERNAL_OPTAB_FN (EXTRACT_LAST, ECF_CONST | ECF_NOTHROW, - extract_last, cond_unary) + extract_last, fold_left) /* Same, but return the first argument if no elements are active. */ DEF_INTERNAL_OPTAB_FN (FOLD_EXTRACT_LAST, ECF_CONST | ECF_NOTHROW, Index: gcc/internal-fn.c =================================================================== --- gcc/internal-fn.c 2018-05-24 09:31:46.687834412 +0100 +++ gcc/internal-fn.c 2018-05-24 09:32:10.522816506 +0100 @@ -2988,10 +2988,10 @@ #define expand_ternary_optab_fn(FN, STMT expand_direct_optab_fn (FN, STMT, OPTAB, 3) #define expand_cond_unary_optab_fn(FN, STMT, OPTAB) \ - expand_direct_optab_fn (FN, STMT, OPTAB, 2) + expand_direct_optab_fn (FN, STMT, OPTAB, 3) #define expand_cond_binary_optab_fn(FN, STMT, OPTAB) \ - expand_direct_optab_fn (FN, STMT, OPTAB, 3) + expand_direct_optab_fn (FN, STMT, OPTAB, 4) #define expand_fold_extract_optab_fn(FN, STMT, OPTAB) \ expand_direct_optab_fn (FN, STMT, OPTAB, 3) @@ -3219,12 +3219,19 @@ #define DEF_INTERNAL_FN(CODE, FLAGS, FNS 0 }; -/* Return a function that performs the conditional form of CODE, i.e.: +/* Return a function that only performs CODE when a certain condition is met + and that uses a given fallback value otherwise. For example, if CODE is + a binary operation associated with conditional function FN: + + LHS = FN (COND, A, B, ELSE) + + is equivalent to the C expression: + + LHS = COND ? A CODE B : ELSE; - LHS = RHS1 ? RHS2 CODE RHS3 : RHS2 + operating elementwise if the operands are vectors. - (operating elementwise if the operands are vectors). Return IFN_LAST - if no such function exists. */ + Return IFN_LAST if no such function exists. */ internal_fn get_conditional_internal_fn (tree_code code) Index: gcc/tree-vect-loop.c =================================================================== --- gcc/tree-vect-loop.c 2018-05-24 09:31:46.687834412 +0100 +++ gcc/tree-vect-loop.c 2018-05-24 09:32:10.523816456 +0100 @@ -7222,8 +7222,9 @@ vectorizable_reduction (gimple *stmt, gi } tree mask = vect_get_loop_mask (gsi, masks, vec_num * ncopies, vectype_in, i * ncopies + j); - gcall *call = gimple_build_call_internal (cond_fn, 3, mask, - vop[0], vop[1]); + gcall *call = gimple_build_call_internal (cond_fn, 4, mask, + vop[0], vop[1], + vop[0]); new_temp = make_ssa_name (vec_dest, call); gimple_call_set_lhs (call, new_temp); gimple_call_set_nothrow (call, true); Index: gcc/config/aarch64/aarch64-sve.md =================================================================== --- gcc/config/aarch64/aarch64-sve.md 2018-05-24 09:32:03.433159783 +0100 +++ gcc/config/aarch64/aarch64-sve.md 2018-05-24 09:32:10.521816556 +0100 @@ -1787,14 +1787,31 @@ (define_insn "*3" "\t%0., %1/m, %0., %3." ) +;; Predicated integer operations with select. +(define_expand "cond_" + [(set (match_operand:SVE_I 0 "register_operand") + (unspec:SVE_I + [(match_operand: 1 "register_operand") + (SVE_INT_BINARY:SVE_I + (match_operand:SVE_I 2 "register_operand") + (match_operand:SVE_I 3 "register_operand")) + (match_operand:SVE_I 4 "register_operand")] + UNSPEC_SEL))] + "TARGET_SVE" +{ + gcc_assert (rtx_equal_p (operands[2], operands[4])); +}) + ;; Predicated integer operations. -(define_insn "cond_" +(define_insn "*cond_" [(set (match_operand:SVE_I 0 "register_operand" "=w") (unspec:SVE_I [(match_operand: 1 "register_operand" "Upl") - (match_operand:SVE_I 2 "register_operand" "0") - (match_operand:SVE_I 3 "register_operand" "w")] - SVE_COND_INT_OP))] + (SVE_INT_BINARY:SVE_I + (match_operand:SVE_I 2 "register_operand" "0") + (match_operand:SVE_I 3 "register_operand" "w")) + (match_dup 2)] + UNSPEC_SEL))] "TARGET_SVE" "\t%0., %1/m, %0., %3." ) @@ -2566,14 +2583,35 @@ (define_expand "vec_pack_fix_trunc_v } ) +;; Predicated floating-point operations with select. +(define_expand "cond_" + [(set (match_operand:SVE_F 0 "register_operand") + (unspec:SVE_F + [(match_operand: 1 "register_operand") + (unspec:SVE_F + [(match_dup 1) + (match_operand:SVE_F 2 "register_operand") + (match_operand:SVE_F 3 "register_operand")] + SVE_COND_FP_BINARY) + (match_operand:SVE_F 4 "register_operand")] + UNSPEC_SEL))] + "TARGET_SVE" +{ + gcc_assert (rtx_equal_p (operands[2], operands[4])); +}) + ;; Predicated floating-point operations. -(define_insn "cond_" +(define_insn "*cond_" [(set (match_operand:SVE_F 0 "register_operand" "=w") (unspec:SVE_F [(match_operand: 1 "register_operand" "Upl") - (match_operand:SVE_F 2 "register_operand" "0") - (match_operand:SVE_F 3 "register_operand" "w")] - SVE_COND_FP_OP))] + (unspec:SVE_F + [(match_dup 1) + (match_operand:SVE_F 2 "register_operand" "0") + (match_operand:SVE_F 3 "register_operand" "w")] + SVE_COND_FP_BINARY) + (match_dup 2)] + UNSPEC_SEL))] "TARGET_SVE" "\t%0., %1/m, %0., %3." ) Index: gcc/config/aarch64/iterators.md =================================================================== --- gcc/config/aarch64/iterators.md 2018-05-24 09:32:03.433159783 +0100 +++ gcc/config/aarch64/iterators.md 2018-05-24 09:32:10.521816556 +0100 @@ -464,13 +464,6 @@ (define_c_enum "unspec" UNSPEC_UMUL_HIGHPART ; Used in aarch64-sve.md. UNSPEC_COND_ADD ; Used in aarch64-sve.md. UNSPEC_COND_SUB ; Used in aarch64-sve.md. - UNSPEC_COND_SMAX ; Used in aarch64-sve.md. - UNSPEC_COND_UMAX ; Used in aarch64-sve.md. - UNSPEC_COND_SMIN ; Used in aarch64-sve.md. - UNSPEC_COND_UMIN ; Used in aarch64-sve.md. - UNSPEC_COND_AND ; Used in aarch64-sve.md. - UNSPEC_COND_ORR ; Used in aarch64-sve.md. - UNSPEC_COND_EOR ; Used in aarch64-sve.md. UNSPEC_COND_LT ; Used in aarch64-sve.md. UNSPEC_COND_LE ; Used in aarch64-sve.md. UNSPEC_COND_EQ ; Used in aarch64-sve.md. @@ -1207,6 +1200,9 @@ (define_code_iterator SVE_INT_UNARY [neg ;; SVE floating-point unary operations. (define_code_iterator SVE_FP_UNARY [neg abs sqrt]) +(define_code_iterator SVE_INT_BINARY [plus minus smax umax smin umin + and ior xor]) + (define_code_iterator SVE_INT_BINARY_SD [div udiv]) ;; SVE integer comparisons. @@ -1381,6 +1377,7 @@ (define_mode_attr lconst_atomic [(QI "K" ;; The integer SVE instruction that implements an rtx code. (define_code_attr sve_int_op [(plus "add") + (minus "sub") (div "sdiv") (udiv "udiv") (neg "neg") @@ -1538,14 +1535,7 @@ (define_int_iterator UNPACK_UNSIGNED [UN (define_int_iterator MUL_HIGHPART [UNSPEC_SMUL_HIGHPART UNSPEC_UMUL_HIGHPART]) -(define_int_iterator SVE_COND_INT_OP [UNSPEC_COND_ADD UNSPEC_COND_SUB - UNSPEC_COND_SMAX UNSPEC_COND_UMAX - UNSPEC_COND_SMIN UNSPEC_COND_UMIN - UNSPEC_COND_AND - UNSPEC_COND_ORR - UNSPEC_COND_EOR]) - -(define_int_iterator SVE_COND_FP_OP [UNSPEC_COND_ADD UNSPEC_COND_SUB]) +(define_int_iterator SVE_COND_FP_BINARY [UNSPEC_COND_ADD UNSPEC_COND_SUB]) (define_int_iterator SVE_COND_FP_CMP [UNSPEC_COND_LT UNSPEC_COND_LE UNSPEC_COND_EQ UNSPEC_COND_NE @@ -1575,14 +1565,7 @@ (define_int_attr optab [(UNSPEC_ANDF "an (UNSPEC_IORV "ior") (UNSPEC_XORV "xor") (UNSPEC_COND_ADD "add") - (UNSPEC_COND_SUB "sub") - (UNSPEC_COND_SMAX "smax") - (UNSPEC_COND_UMAX "umax") - (UNSPEC_COND_SMIN "smin") - (UNSPEC_COND_UMIN "umin") - (UNSPEC_COND_AND "and") - (UNSPEC_COND_ORR "ior") - (UNSPEC_COND_EOR "xor")]) + (UNSPEC_COND_SUB "sub")]) (define_int_attr maxmin_uns [(UNSPEC_UMAXV "umax") (UNSPEC_UMINV "umin") @@ -1793,15 +1776,5 @@ (define_int_attr cmp_op [(UNSPEC_COND_LT (UNSPEC_COND_GE "ge") (UNSPEC_COND_GT "gt")]) -(define_int_attr sve_int_op [(UNSPEC_COND_ADD "add") - (UNSPEC_COND_SUB "sub") - (UNSPEC_COND_SMAX "smax") - (UNSPEC_COND_UMAX "umax") - (UNSPEC_COND_SMIN "smin") - (UNSPEC_COND_UMIN "umin") - (UNSPEC_COND_AND "and") - (UNSPEC_COND_ORR "orr") - (UNSPEC_COND_EOR "eor")]) - (define_int_attr sve_fp_op [(UNSPEC_COND_ADD "fadd") (UNSPEC_COND_SUB "fsub")])