From patchwork Mon Oct 23 11:16:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 116681 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp4522419qgn; Mon, 23 Oct 2017 04:16:43 -0700 (PDT) X-Received: by 10.99.97.132 with SMTP id v126mr5443496pgb.179.1508757403343; Mon, 23 Oct 2017 04:16:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1508757403; cv=none; d=google.com; s=arc-20160816; b=MHvBZBK+1sibGbm6GAXYB10S96EXEuDM53Qjzg0XpsjggsMD4gR5NHyxrvTXOsEb7Q nkvlolDhk5xn6imCHeu+dmYbajCk00tHzmV67j1oagujpt+DNd7l+zB7p2eiClz6HbNh oaUZBUNKQm9toJeAhORQg46FAp3/r0VNU8PyAr8Uw82cMueELiUuKK2Jjf9+kzcgSimT tZBzNKCBPkJDDMqy1N8+/OVsqA7j+7nFT0nkwGlHeZkeT/grI6yUua8s1QRfV3SqUlgg 5/4eKDJunEVSn2VpHbGD4Y12QXBsNrBH/TFkr/bblOy0jhsNGu+A6REgschQfcGHxjQF /SEw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:user-agent:message-id:in-reply-to:date:references :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=o2s+DMqV2k/4GgAE5tJXbUZAQOLUFHZ/hwa1gJn5xdk=; b=MPP8BI9HF+anmoE+2DLB/6xFUKXjio9bz83EdSxVUoJLAOMm6rv3KxGzuY8qZi+YOW FLZZqK6XDxNOTvp62dCdzIi2ne2DtavsjP54lcgqmtxSu/HjNOCuwNvXjk/a0sFCoMH2 Gwa/MIri0YgnPyilMCMvl/+8M2XMs8JS4suxImBArIOQiM5Qhu8c44eI+GivM2D+pWwt vhZGTRgDB1nnlrqwF9SD8HZvudWzEKOZlp8TtKXq/TKs682kgWiptkg053pDncxb1djx vaLn9Wa6yBSKu/OrgT/dNiryboMzeQb8PkrWFx+HXxymp7APG7/cGLohJxSj0rhSXDY6 8O/Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=UlBZLhEg; spf=pass (google.com: domain of gcc-patches-return-464727-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-464727-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 o65si5197705pfj.447.2017.10.23.04.16.43 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 23 Oct 2017 04:16:43 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-464727-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=UlBZLhEg; spf=pass (google.com: domain of gcc-patches-return-464727-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-464727-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:references:date:in-reply-to:message-id:mime-version :content-type; q=dns; s=default; b=EUyv2XGXghEfvQJXs0+r5XJn/kevd To6TqB01k5Si+QexGHkK/xzsgDaF/buw5Ar0ta5hAQlpx8Ziy7IGrlIkI6TxDPZ4 e6AWW+bcz6gZbh+XWQagyQTmLe9Tq14krhy9d3+7sywXZsD6/wT/ITvPHZMthmtI +KEEKyfKHlcQfE= 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:references:date:in-reply-to:message-id:mime-version :content-type; s=default; bh=eS+VfSlfNbozp3c3ccaSeQVGKXU=; b=UlB ZLhEgpbs9wzvyUiku6rRfA/jZ2aZHgumOdw/k4LMOSZ0NPtYHk+DmQtispSo2X+B Ff+xKyhZWdKrhBnIj9jbbmhLnGuFmyGZji3WBI2ryW1MpoLxo0Fdr8II1BL78MoJ nKr6tAwRDPjtlRd8fCxA85I8ojHmSxMNoxaR+Gm0= Received: (qmail 130387 invoked by alias); 23 Oct 2017 11:16:27 -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 130365 invoked by uid 89); 23 Oct 2017 11:16:25 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-9.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS, URIBL_ABUSE_SURBL autolearn=ham version=3.3.2 spammy=arms X-HELO: mail-wr0-f193.google.com Received: from mail-wr0-f193.google.com (HELO mail-wr0-f193.google.com) (209.85.128.193) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 23 Oct 2017 11:16:21 +0000 Received: by mail-wr0-f193.google.com with SMTP id j15so4804539wre.8 for ; Mon, 23 Oct 2017 04:16:21 -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:references:date :in-reply-to:message-id:user-agent:mime-version; bh=o2s+DMqV2k/4GgAE5tJXbUZAQOLUFHZ/hwa1gJn5xdk=; b=JsTtFG6moJXduo0x6rFxuk2AfDMIOeJ5UYZog8lO9sov2q5PJNuhC7YpFTJn49G5Ph aNdSI/dHz+P7Aa8hfu6C8aAoBh9B3LyvYeuUrAAyMkh5B85vFbUS0u1x8z6pEPXMCEQ+ TYdwngido1TYV5G1biJnJ08gJX4MWIUxFnxviX12S06UIDegrn7taZ9gY9ftOuSF6H2R 8n/htSwT/Oxiqyoe2S4ny9txrQMNDotjpLdV5GMQVobnPZ9wC+K8BCx+vo1kTQYSEhAv 7rJtR/VCjtro/vwuVZQ/VPHRW6NQxAPlsjdU/PlPv8hXSPTCWCkD33RYwfaTqjjCZH+x vOjw== X-Gm-Message-State: AMCzsaWKtZmR2J/Ph/JYR7cZLxzMzr8EAt0SmjzXcG3SkgaghglO8D1+ v7tJvN8ItZfVpi8SyQOk5njlS0T8hKA= X-Google-Smtp-Source: ABhQp+TaJhdUl98zTpxkuUW9HxqTntMsTaCf2ANg8cBrRFbHA3vZwpltzs02WRO2O44UR+VBC/ha7Q== X-Received: by 10.223.136.246 with SMTP id g51mr10286251wrg.226.1508757378899; Mon, 23 Oct 2017 04:16:18 -0700 (PDT) Received: from localhost ([2.26.27.199]) by smtp.gmail.com with ESMTPSA id y129sm3952418wmg.42.2017.10.23.04.16.17 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 23 Oct 2017 04:16:18 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Subject: [01/nn] Add gen_(const_)vec_duplicate helpers References: <87wp3mxgir.fsf@linaro.org> Date: Mon, 23 Oct 2017 12:16:16 +0100 In-Reply-To: <87wp3mxgir.fsf@linaro.org> (Richard Sandiford's message of "Mon, 23 Oct 2017 12:14:36 +0100") Message-ID: <87sheaxgfz.fsf@linaro.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) MIME-Version: 1.0 This patch adds helper functions for generating constant and non-constant vector duplicates. These routines help with SVE because it is then easier to use: (const:M (vec_duplicate:M X)) for a broadcast of X, even if the number of elements in M isn't known at compile time. It also makes it easier for general rtx code to treat constant and non-constant duplicates in the same way. In the target code, the patch uses gen_vec_duplicate instead of gen_rtx_VEC_DUPLICATE if handling constants correctly is potentially useful. It might be that some or all of the call sites only handle non-constants in practice, in which case the change is a harmless no-op (and a saving of a few characters). Otherwise, the target changes use gen_const_vec_duplicate instead of gen_rtx_CONST_VECTOR if the constant is obviously a duplicate. They also include some changes to use CONSTxx_RTX for easy global constants. 2017-10-23 Richard Sandiford Alan Hayward David Sherwood gcc/ * emit-rtl.h (gen_const_vec_duplicate): Declare. (gen_vec_duplicate): Likewise. * emit-rtl.c (gen_const_vec_duplicate_1): New function, split out from... (gen_const_vector): ...here. (gen_const_vec_duplicate, gen_vec_duplicate): New functions. (gen_rtx_CONST_VECTOR): Use gen_const_vec_duplicate for constants whose elements are all equal. * optabs.c (expand_vector_broadcast): Use gen_const_vec_duplicate. * simplify-rtx.c (simplify_const_unary_operation): Likewise. (simplify_relational_operation): Likewise. * config/aarch64/aarch64.c (aarch64_simd_gen_const_vector_dup): Likewise. (aarch64_simd_dup_constant): Use gen_vec_duplicate. (aarch64_expand_vector_init): Likewise. * config/arm/arm.c (neon_vdup_constant): Likewise. (neon_expand_vector_init): Likewise. (arm_expand_vec_perm): Use gen_const_vec_duplicate. (arm_block_set_unaligned_vect): Likewise. (arm_block_set_aligned_vect): Likewise. * config/arm/neon.md (neon_copysignf): Likewise. * config/i386/i386.c (ix86_expand_vec_perm): Likewise. (expand_vec_perm_even_odd_pack): Likewise. (ix86_vector_duplicate_value): Use gen_vec_duplicate. * config/i386/sse.md (one_cmpl2): Use CONSTM1_RTX. * config/ia64/ia64.c (ia64_expand_vecint_compare): Use gen_const_vec_duplicate. * config/ia64/vect.md (addv2sf3, subv2sf3): Use CONST1_RTX. * config/mips/mips.c (mips_gen_const_int_vector): Use gen_const_vec_duplicate. (mips_expand_vector_init): Use CONST0_RTX. * config/powerpcspe/altivec.md (abs2, nabs2): Likewise. (define_split): Use gen_const_vec_duplicate. * config/rs6000/altivec.md (abs2, nabs2): Use CONST0_RTX. (define_split): Use gen_const_vec_duplicate. * config/s390/vx-builtins.md (vec_genmask): Likewise. (vec_ctd_s64, vec_ctd_u64, vec_ctsl, vec_ctul): Likewise. * config/spu/spu.c (spu_const): Likewise. Index: gcc/emit-rtl.h =================================================================== --- gcc/emit-rtl.h 2017-10-23 11:40:11.561479591 +0100 +++ gcc/emit-rtl.h 2017-10-23 11:41:32.369050264 +0100 @@ -438,6 +438,9 @@ get_max_uid (void) return crtl->emit.x_cur_insn_uid; } +extern rtx gen_const_vec_duplicate (machine_mode, rtx); +extern rtx gen_vec_duplicate (machine_mode, rtx); + extern void set_decl_incoming_rtl (tree, rtx, bool); /* Return a memory reference like MEMREF, but with its mode changed Index: gcc/emit-rtl.c =================================================================== --- gcc/emit-rtl.c 2017-10-23 11:41:25.541909864 +0100 +++ gcc/emit-rtl.c 2017-10-23 11:41:32.369050264 +0100 @@ -5756,32 +5756,60 @@ init_emit (void) #endif } -/* Generate a vector constant for mode MODE and constant value CONSTANT. */ +/* Like gen_const_vec_duplicate, but ignore const_tiny_rtx. */ static rtx -gen_const_vector (machine_mode mode, int constant) +gen_const_vec_duplicate_1 (machine_mode mode, rtx el) { - rtx tem; - rtvec v; - int units, i; - machine_mode inner; + int nunits = GET_MODE_NUNITS (mode); + rtvec v = rtvec_alloc (nunits); + for (int i = 0; i < nunits; ++i) + RTVEC_ELT (v, i) = el; + return gen_rtx_raw_CONST_VECTOR (mode, v); +} - units = GET_MODE_NUNITS (mode); - inner = GET_MODE_INNER (mode); +/* Generate a vector constant of mode MODE in which every element has + value ELT. */ - gcc_assert (!DECIMAL_FLOAT_MODE_P (inner)); +rtx +gen_const_vec_duplicate (machine_mode mode, rtx elt) +{ + scalar_mode inner_mode = GET_MODE_INNER (mode); + if (elt == CONST0_RTX (inner_mode)) + return CONST0_RTX (mode); + else if (elt == CONST1_RTX (inner_mode)) + return CONST1_RTX (mode); + else if (elt == CONSTM1_RTX (inner_mode)) + return CONSTM1_RTX (mode); + + return gen_const_vec_duplicate_1 (mode, elt); +} - v = rtvec_alloc (units); +/* Return a vector rtx of mode MODE in which every element has value X. + The result will be a constant if X is constant. */ - /* We need to call this function after we set the scalar const_tiny_rtx - entries. */ - gcc_assert (const_tiny_rtx[constant][(int) inner]); +rtx +gen_vec_duplicate (machine_mode mode, rtx x) +{ + if (CONSTANT_P (x)) + return gen_const_vec_duplicate (mode, x); + return gen_rtx_VEC_DUPLICATE (mode, x); +} - for (i = 0; i < units; ++i) - RTVEC_ELT (v, i) = const_tiny_rtx[constant][(int) inner]; +/* Generate a new vector constant for mode MODE and constant value + CONSTANT. */ - tem = gen_rtx_raw_CONST_VECTOR (mode, v); - return tem; +static rtx +gen_const_vector (machine_mode mode, int constant) +{ + machine_mode inner = GET_MODE_INNER (mode); + + gcc_assert (!DECIMAL_FLOAT_MODE_P (inner)); + + rtx el = const_tiny_rtx[constant][(int) inner]; + gcc_assert (el); + + return gen_const_vec_duplicate_1 (mode, el); } /* Generate a vector like gen_rtx_raw_CONST_VEC, but use the zero vector when @@ -5789,28 +5817,12 @@ gen_const_vector (machine_mode mode, int rtx gen_rtx_CONST_VECTOR (machine_mode mode, rtvec v) { - machine_mode inner = GET_MODE_INNER (mode); - int nunits = GET_MODE_NUNITS (mode); - rtx x; - int i; - - /* Check to see if all of the elements have the same value. */ - x = RTVEC_ELT (v, nunits - 1); - for (i = nunits - 2; i >= 0; i--) - if (RTVEC_ELT (v, i) != x) - break; + gcc_assert (GET_MODE_NUNITS (mode) == GET_NUM_ELEM (v)); /* If the values are all the same, check to see if we can use one of the standard constant vectors. */ - if (i == -1) - { - if (x == CONST0_RTX (inner)) - return CONST0_RTX (mode); - else if (x == CONST1_RTX (inner)) - return CONST1_RTX (mode); - else if (x == CONSTM1_RTX (inner)) - return CONSTM1_RTX (mode); - } + if (rtvec_all_equal_p (v)) + return gen_const_vec_duplicate (mode, RTVEC_ELT (v, 0)); return gen_rtx_raw_CONST_VECTOR (mode, v); } Index: gcc/optabs.c =================================================================== --- gcc/optabs.c 2017-10-23 11:41:23.502006982 +0100 +++ gcc/optabs.c 2017-10-23 11:41:32.369050264 +0100 @@ -377,13 +377,8 @@ expand_vector_broadcast (machine_mode vm gcc_checking_assert (VECTOR_MODE_P (vmode)); - n = GET_MODE_NUNITS (vmode); - vec = rtvec_alloc (n); - for (i = 0; i < n; ++i) - RTVEC_ELT (vec, i) = op; - if (CONSTANT_P (op)) - return gen_rtx_CONST_VECTOR (vmode, vec); + return gen_const_vec_duplicate (vmode, op); /* ??? If the target doesn't have a vec_init, then we have no easy way of performing this operation. Most of this sort of generic support @@ -393,6 +388,10 @@ expand_vector_broadcast (machine_mode vm if (icode == CODE_FOR_nothing) return NULL; + n = GET_MODE_NUNITS (vmode); + vec = rtvec_alloc (n); + for (i = 0; i < n; ++i) + RTVEC_ELT (vec, i) = op; ret = gen_reg_rtx (vmode); emit_insn (GEN_FCN (icode) (ret, gen_rtx_PARALLEL (vmode, vec))); Index: gcc/simplify-rtx.c =================================================================== --- gcc/simplify-rtx.c 2017-10-23 11:41:25.549647760 +0100 +++ gcc/simplify-rtx.c 2017-10-23 11:41:32.370050264 +0100 @@ -1704,28 +1704,23 @@ simplify_const_unary_operation (enum rtx gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER (GET_MODE (op))); } - if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op) - || GET_CODE (op) == CONST_VECTOR) + if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op)) + return gen_const_vec_duplicate (mode, op); + if (GET_CODE (op) == CONST_VECTOR) { int elt_size = GET_MODE_UNIT_SIZE (mode); unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size); rtvec v = rtvec_alloc (n_elts); unsigned int i; - if (GET_CODE (op) != CONST_VECTOR) - for (i = 0; i < n_elts; i++) - RTVEC_ELT (v, i) = op; - else - { - machine_mode inmode = GET_MODE (op); - int in_elt_size = GET_MODE_UNIT_SIZE (inmode); - unsigned in_n_elts = (GET_MODE_SIZE (inmode) / in_elt_size); - - gcc_assert (in_n_elts < n_elts); - gcc_assert ((n_elts % in_n_elts) == 0); - for (i = 0; i < n_elts; i++) - RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op, i % in_n_elts); - } + machine_mode inmode = GET_MODE (op); + int in_elt_size = GET_MODE_UNIT_SIZE (inmode); + unsigned in_n_elts = (GET_MODE_SIZE (inmode) / in_elt_size); + + gcc_assert (in_n_elts < n_elts); + gcc_assert ((n_elts % in_n_elts) == 0); + for (i = 0; i < n_elts; i++) + RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op, i % in_n_elts); return gen_rtx_CONST_VECTOR (mode, v); } } @@ -4632,20 +4627,13 @@ simplify_relational_operation (enum rtx_ return CONST0_RTX (mode); #ifdef VECTOR_STORE_FLAG_VALUE { - int i, units; - rtvec v; - rtx val = VECTOR_STORE_FLAG_VALUE (mode); if (val == NULL_RTX) return NULL_RTX; if (val == const1_rtx) return CONST1_RTX (mode); - units = GET_MODE_NUNITS (mode); - v = rtvec_alloc (units); - for (i = 0; i < units; i++) - RTVEC_ELT (v, i) = val; - return gen_rtx_raw_CONST_VECTOR (mode, v); + return gen_const_vec_duplicate (mode, val); } #else return NULL_RTX; Index: gcc/config/aarch64/aarch64.c =================================================================== --- gcc/config/aarch64/aarch64.c 2017-10-23 11:41:23.125751780 +0100 +++ gcc/config/aarch64/aarch64.c 2017-10-23 11:41:32.352050263 +0100 @@ -11726,16 +11726,8 @@ aarch64_mov_operand_p (rtx x, machine_mo rtx aarch64_simd_gen_const_vector_dup (machine_mode mode, HOST_WIDE_INT val) { - int nunits = GET_MODE_NUNITS (mode); - rtvec v = rtvec_alloc (nunits); - int i; - - rtx cache = GEN_INT (val); - - for (i=0; i < nunits; i++) - RTVEC_ELT (v, i) = cache; - - return gen_rtx_CONST_VECTOR (mode, v); + rtx c = gen_int_mode (val, GET_MODE_INNER (mode)); + return gen_const_vec_duplicate (mode, c); } /* Check OP is a legal scalar immediate for the MOVI instruction. */ @@ -11947,7 +11939,7 @@ aarch64_simd_dup_constant (rtx vals) single ARM register. This will be cheaper than a vector load. */ x = copy_to_mode_reg (inner_mode, x); - return gen_rtx_VEC_DUPLICATE (mode, x); + return gen_vec_duplicate (mode, x); } @@ -12046,7 +12038,7 @@ aarch64_expand_vector_init (rtx target, if (all_same) { rtx x = copy_to_mode_reg (inner_mode, v0); - aarch64_emit_move (target, gen_rtx_VEC_DUPLICATE (mode, x)); + aarch64_emit_move (target, gen_vec_duplicate (mode, x)); return; } @@ -12087,7 +12079,7 @@ aarch64_expand_vector_init (rtx target, /* Create a duplicate of the most common element. */ rtx x = copy_to_mode_reg (inner_mode, XVECEXP (vals, 0, maxelement)); - aarch64_emit_move (target, gen_rtx_VEC_DUPLICATE (mode, x)); + aarch64_emit_move (target, gen_vec_duplicate (mode, x)); /* Insert the rest. */ for (int i = 0; i < n_elts; i++) Index: gcc/config/arm/arm.c =================================================================== --- gcc/config/arm/arm.c 2017-10-23 11:41:22.965190434 +0100 +++ gcc/config/arm/arm.c 2017-10-23 11:41:32.355050263 +0100 @@ -12151,7 +12151,7 @@ neon_vdup_constant (rtx vals) load. */ x = copy_to_mode_reg (inner_mode, x); - return gen_rtx_VEC_DUPLICATE (mode, x); + return gen_vec_duplicate (mode, x); } /* Generate code to load VALS, which is a PARALLEL containing only @@ -12246,7 +12246,7 @@ neon_expand_vector_init (rtx target, rtx if (all_same && GET_MODE_SIZE (inner_mode) <= 4) { x = copy_to_mode_reg (inner_mode, XVECEXP (vals, 0, 0)); - emit_insn (gen_rtx_SET (target, gen_rtx_VEC_DUPLICATE (mode, x))); + emit_insn (gen_rtx_SET (target, gen_vec_duplicate (mode, x))); return; } @@ -28731,9 +28731,9 @@ arm_expand_vec_perm_1 (rtx target, rtx o arm_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel) { machine_mode vmode = GET_MODE (target); - unsigned int i, nelt = GET_MODE_NUNITS (vmode); + unsigned int nelt = GET_MODE_NUNITS (vmode); bool one_vector_p = rtx_equal_p (op0, op1); - rtx rmask[MAX_VECT_LEN], mask; + rtx mask; /* TODO: ARM's VTBL indexing is little-endian. In order to handle GCC's numbering of elements for big-endian, we must reverse the order. */ @@ -28742,9 +28742,7 @@ arm_expand_vec_perm (rtx target, rtx op0 /* The VTBL instruction does not use a modulo index, so we must take care of that ourselves. */ mask = GEN_INT (one_vector_p ? nelt - 1 : 2 * nelt - 1); - for (i = 0; i < nelt; ++i) - rmask[i] = mask; - mask = gen_rtx_CONST_VECTOR (vmode, gen_rtvec_v (nelt, rmask)); + mask = gen_const_vec_duplicate (vmode, mask); sel = expand_simple_binop (vmode, AND, sel, mask, NULL, 0, OPTAB_LIB_WIDEN); arm_expand_vec_perm_1 (target, op0, op1, sel); @@ -29798,10 +29796,9 @@ arm_block_set_unaligned_vect (rtx dstbas unsigned HOST_WIDE_INT value, unsigned HOST_WIDE_INT align) { - unsigned int i, j, nelt_v16, nelt_v8, nelt_mode; + unsigned int i, nelt_v16, nelt_v8, nelt_mode; rtx dst, mem; - rtx val_elt, val_vec, reg; - rtx rval[MAX_VECT_LEN]; + rtx val_vec, reg; rtx (*gen_func) (rtx, rtx); machine_mode mode; unsigned HOST_WIDE_INT v = value; @@ -29829,12 +29826,9 @@ arm_block_set_unaligned_vect (rtx dstbas mem = adjust_automodify_address (dstbase, mode, dst, offset); v = sext_hwi (v, BITS_PER_WORD); - val_elt = GEN_INT (v); - for (j = 0; j < nelt_mode; j++) - rval[j] = val_elt; reg = gen_reg_rtx (mode); - val_vec = gen_rtx_CONST_VECTOR (mode, gen_rtvec_v (nelt_mode, rval)); + val_vec = gen_const_vec_duplicate (mode, GEN_INT (v)); /* Emit instruction loading the constant value. */ emit_move_insn (reg, val_vec); @@ -29898,10 +29892,9 @@ arm_block_set_aligned_vect (rtx dstbase, unsigned HOST_WIDE_INT value, unsigned HOST_WIDE_INT align) { - unsigned int i, j, nelt_v8, nelt_v16, nelt_mode; + unsigned int i, nelt_v8, nelt_v16, nelt_mode; rtx dst, addr, mem; - rtx val_elt, val_vec, reg; - rtx rval[MAX_VECT_LEN]; + rtx val_vec, reg; machine_mode mode; unsigned HOST_WIDE_INT v = value; unsigned int offset = 0; @@ -29923,12 +29916,9 @@ arm_block_set_aligned_vect (rtx dstbase, dst = copy_addr_to_reg (XEXP (dstbase, 0)); v = sext_hwi (v, BITS_PER_WORD); - val_elt = GEN_INT (v); - for (j = 0; j < nelt_mode; j++) - rval[j] = val_elt; reg = gen_reg_rtx (mode); - val_vec = gen_rtx_CONST_VECTOR (mode, gen_rtvec_v (nelt_mode, rval)); + val_vec = gen_const_vec_duplicate (mode, GEN_INT (v)); /* Emit instruction loading the constant value. */ emit_move_insn (reg, val_vec); Index: gcc/config/arm/neon.md =================================================================== --- gcc/config/arm/neon.md 2017-10-23 11:41:22.968092145 +0100 +++ gcc/config/arm/neon.md 2017-10-23 11:41:32.356050263 +0100 @@ -3052,15 +3052,10 @@ (define_expand "neon_copysignf" "{ rtx v_bitmask_cast; rtx v_bitmask = gen_reg_rtx (mode); - int i, n_elt = GET_MODE_NUNITS (mode); - rtvec v = rtvec_alloc (n_elt); - - /* Create bitmask for vector select. */ - for (i = 0; i < n_elt; ++i) - RTVEC_ELT (v, i) = GEN_INT (0x80000000); + rtx c = GEN_INT (0x80000000); emit_move_insn (v_bitmask, - gen_rtx_CONST_VECTOR (mode, v)); + gen_const_vec_duplicate (mode, c)); emit_move_insn (operands[0], operands[2]); v_bitmask_cast = simplify_gen_subreg (mode, v_bitmask, mode, 0); Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c 2017-10-23 11:41:22.913926872 +0100 +++ gcc/config/i386/i386.c 2017-10-23 11:41:32.360050263 +0100 @@ -24117,9 +24117,7 @@ ix86_expand_vec_perm (rtx operands[]) t2 = gen_reg_rtx (V32QImode); t3 = gen_reg_rtx (V32QImode); vt2 = GEN_INT (-128); - for (i = 0; i < 32; i++) - vec[i] = vt2; - vt = gen_rtx_CONST_VECTOR (V32QImode, gen_rtvec_v (32, vec)); + vt = gen_const_vec_duplicate (V32QImode, vt2); vt = force_reg (V32QImode, vt); for (i = 0; i < 32; i++) vec[i] = i < 16 ? vt2 : const0_rtx; @@ -24227,9 +24225,7 @@ ix86_expand_vec_perm (rtx operands[]) vt = GEN_INT (w - 1); } - for (i = 0; i < w; i++) - vec[i] = vt; - vt = gen_rtx_CONST_VECTOR (maskmode, gen_rtvec_v (w, vec)); + vt = gen_const_vec_duplicate (maskmode, vt); mask = expand_simple_binop (maskmode, AND, mask, vt, NULL_RTX, 0, OPTAB_DIRECT); @@ -24319,9 +24315,7 @@ ix86_expand_vec_perm (rtx operands[]) e = w = 4; } - for (i = 0; i < w; i++) - vec[i] = vt; - vt = gen_rtx_CONST_VECTOR (maskmode, gen_rtvec_v (w, vec)); + vt = gen_const_vec_duplicate (maskmode, vt); vt = force_reg (maskmode, vt); mask = expand_simple_binop (maskmode, AND, mask, vt, NULL_RTX, 0, OPTAB_DIRECT); @@ -40814,7 +40808,7 @@ ix86_vector_duplicate_value (machine_mod rtx dup; /* First attempt to recognize VAL as-is. */ - dup = gen_rtx_VEC_DUPLICATE (mode, val); + dup = gen_vec_duplicate (mode, val); insn = emit_insn (gen_rtx_SET (target, dup)); if (recog_memoized (insn) < 0) { @@ -46120,7 +46114,7 @@ expand_vec_perm_vpshufb2_vpermq_even_odd static bool expand_vec_perm_even_odd_pack (struct expand_vec_perm_d *d) { - rtx op, dop0, dop1, t, rperm[16]; + rtx op, dop0, dop1, t; unsigned i, odd, c, s, nelt = d->nelt; bool end_perm = false; machine_mode half_mode; @@ -46197,9 +46191,7 @@ expand_vec_perm_even_odd_pack (struct ex dop1 = gen_reg_rtx (half_mode); if (odd == 0) { - for (i = 0; i < nelt / 2; i++) - rperm[i] = GEN_INT (c); - t = gen_rtx_CONST_VECTOR (half_mode, gen_rtvec_v (nelt / 2, rperm)); + t = gen_const_vec_duplicate (half_mode, GEN_INT (c)); t = force_reg (half_mode, t); emit_insn (gen_and (dop0, t, gen_lowpart (half_mode, d->op0))); emit_insn (gen_and (dop1, t, gen_lowpart (half_mode, d->op1))); Index: gcc/config/i386/sse.md =================================================================== --- gcc/config/i386/sse.md 2017-10-23 11:41:22.905221739 +0100 +++ gcc/config/i386/sse.md 2017-10-23 11:41:32.362050263 +0100 @@ -11529,13 +11529,7 @@ (define_expand "one_cmpl2" (match_dup 2)))] "TARGET_SSE" { - int i, n = GET_MODE_NUNITS (mode); - rtvec v = rtvec_alloc (n); - - for (i = 0; i < n; ++i) - RTVEC_ELT (v, i) = constm1_rtx; - - operands[2] = force_reg (mode, gen_rtx_CONST_VECTOR (mode, v)); + operands[2] = force_reg (mode, CONSTM1_RTX (mode)); }) (define_expand "_andnot3" Index: gcc/config/ia64/ia64.c =================================================================== --- gcc/config/ia64/ia64.c 2017-10-23 11:40:11.561479591 +0100 +++ gcc/config/ia64/ia64.c 2017-10-23 11:41:32.363050263 +0100 @@ -1938,7 +1938,7 @@ ia64_expand_vecint_compare (enum rtx_cod /* Subtract (-(INT MAX) - 1) from both operands to make them signed. */ mask = gen_int_mode (0x80000000, SImode); - mask = gen_rtx_CONST_VECTOR (V2SImode, gen_rtvec (2, mask, mask)); + mask = gen_const_vec_duplicate (V2SImode, mask); mask = force_reg (mode, mask); t1 = gen_reg_rtx (mode); emit_insn (gen_subv2si3 (t1, op0, mask)); Index: gcc/config/ia64/vect.md =================================================================== --- gcc/config/ia64/vect.md 2017-10-23 11:40:11.561479591 +0100 +++ gcc/config/ia64/vect.md 2017-10-23 11:41:32.363050263 +0100 @@ -1138,8 +1138,7 @@ (define_expand "addv2sf3" (match_operand:V2SF 2 "fr_register_operand" "")))] "" { - rtvec v = gen_rtvec (2, CONST1_RTX (SFmode), CONST1_RTX (SFmode)); - operands[3] = force_reg (V2SFmode, gen_rtx_CONST_VECTOR (V2SFmode, v)); + operands[3] = force_reg (V2SFmode, CONST1_RTX (V2SFmode)); }) (define_expand "subv2sf3" @@ -1150,8 +1149,7 @@ (define_expand "subv2sf3" (neg:V2SF (match_operand:V2SF 2 "fr_register_operand" ""))))] "" { - rtvec v = gen_rtvec (2, CONST1_RTX (SFmode), CONST1_RTX (SFmode)); - operands[3] = force_reg (V2SFmode, gen_rtx_CONST_VECTOR (V2SFmode, v)); + operands[3] = force_reg (V2SFmode, CONST1_RTX (V2SFmode)); }) (define_insn "mulv2sf3" Index: gcc/config/mips/mips.c =================================================================== --- gcc/config/mips/mips.c 2017-10-23 11:41:22.797858429 +0100 +++ gcc/config/mips/mips.c 2017-10-23 11:41:32.365050264 +0100 @@ -21681,14 +21681,8 @@ mips_expand_vi_broadcast (machine_mode v rtx mips_gen_const_int_vector (machine_mode mode, HOST_WIDE_INT val) { - int nunits = GET_MODE_NUNITS (mode); - rtvec v = rtvec_alloc (nunits); - int i; - - for (i = 0; i < nunits; i++) - RTVEC_ELT (v, i) = gen_int_mode (val, GET_MODE_INNER (mode)); - - return gen_rtx_CONST_VECTOR (mode, v); + rtx c = gen_int_mode (val, GET_MODE_INNER (mode)); + return gen_const_vec_duplicate (mode, c); } /* Return a vector of repeated 4-element sets generated from @@ -21843,12 +21837,7 @@ mips_expand_vector_init (rtx target, rtx } else { - rtvec vec = shallow_copy_rtvec (XVEC (vals, 0)); - - for (i = 0; i < nelt; ++i) - RTVEC_ELT (vec, i) = CONST0_RTX (imode); - - emit_move_insn (target, gen_rtx_CONST_VECTOR (vmode, vec)); + emit_move_insn (target, CONST0_RTX (vmode)); for (i = 0; i < nelt; ++i) { Index: gcc/config/powerpcspe/altivec.md =================================================================== --- gcc/config/powerpcspe/altivec.md 2017-10-23 11:40:11.561479591 +0100 +++ gcc/config/powerpcspe/altivec.md 2017-10-23 11:41:32.366050264 +0100 @@ -352,12 +352,10 @@ (define_split HOST_WIDE_INT val = const_vector_elt_as_int (op1, elt); rtx rtx_val = GEN_INT (val); int shift = vspltis_shifted (op1); - int nunits = GET_MODE_NUNITS (mode); - int i; gcc_assert (shift != 0); operands[2] = gen_reg_rtx (mode); - operands[3] = gen_rtx_CONST_VECTOR (mode, rtvec_alloc (nunits)); + operands[3] = gen_const_vec_duplicate (mode, rtx_val); operands[4] = gen_reg_rtx (mode); if (shift < 0) @@ -370,10 +368,6 @@ (define_split operands[5] = CONST0_RTX (mode); operands[6] = GEN_INT (shift); } - - /* Populate the constant vectors. */ - for (i = 0; i < nunits; i++) - XVECEXP (operands[3], 0, i) = rtx_val; }) (define_insn "get_vrsave_internal" @@ -2752,15 +2746,8 @@ (define_expand "abs2" (smax:VI2 (match_dup 1) (match_dup 4)))] "" { - int i, n_elt = GET_MODE_NUNITS (mode); - rtvec v = rtvec_alloc (n_elt); - - /* Create an all 0 constant. */ - for (i = 0; i < n_elt; ++i) - RTVEC_ELT (v, i) = const0_rtx; - operands[2] = gen_reg_rtx (mode); - operands[3] = gen_rtx_CONST_VECTOR (mode, v); + operands[3] = CONST0_RTX (mode); operands[4] = gen_reg_rtx (mode); }) @@ -2777,17 +2764,8 @@ (define_expand "nabs2" (smin:VI2 (match_dup 1) (match_dup 4)))] "" { - int i; - int n_elt = GET_MODE_NUNITS (mode); - - rtvec v = rtvec_alloc (n_elt); - - /* Create an all 0 constant. */ - for (i = 0; i < n_elt; ++i) - RTVEC_ELT (v, i) = const0_rtx; - operands[2] = gen_reg_rtx (mode); - operands[3] = gen_rtx_CONST_VECTOR (mode, v); + operands[3] = CONST0_RTX (mode); operands[4] = gen_reg_rtx (mode); }) Index: gcc/config/rs6000/altivec.md =================================================================== --- gcc/config/rs6000/altivec.md 2017-10-23 11:40:11.561479591 +0100 +++ gcc/config/rs6000/altivec.md 2017-10-23 11:41:32.366050264 +0100 @@ -363,12 +363,10 @@ (define_split HOST_WIDE_INT val = const_vector_elt_as_int (op1, elt); rtx rtx_val = GEN_INT (val); int shift = vspltis_shifted (op1); - int nunits = GET_MODE_NUNITS (mode); - int i; gcc_assert (shift != 0); operands[2] = gen_reg_rtx (mode); - operands[3] = gen_rtx_CONST_VECTOR (mode, rtvec_alloc (nunits)); + operands[3] = gen_const_vec_duplicate (mode, rtx_val); operands[4] = gen_reg_rtx (mode); if (shift < 0) @@ -381,10 +379,6 @@ (define_split operands[5] = CONST0_RTX (mode); operands[6] = GEN_INT (shift); } - - /* Populate the constant vectors. */ - for (i = 0; i < nunits; i++) - XVECEXP (operands[3], 0, i) = rtx_val; }) (define_insn "get_vrsave_internal" @@ -3237,15 +3231,8 @@ (define_expand "abs2" (smax:VI2 (match_dup 1) (match_dup 4)))] "" { - int i, n_elt = GET_MODE_NUNITS (mode); - rtvec v = rtvec_alloc (n_elt); - - /* Create an all 0 constant. */ - for (i = 0; i < n_elt; ++i) - RTVEC_ELT (v, i) = const0_rtx; - operands[2] = gen_reg_rtx (mode); - operands[3] = gen_rtx_CONST_VECTOR (mode, v); + operands[3] = CONST0_RTX (mode); operands[4] = gen_reg_rtx (mode); }) @@ -3262,17 +3249,8 @@ (define_expand "nabs2" (smin:VI2 (match_dup 1) (match_dup 4)))] "" { - int i; - int n_elt = GET_MODE_NUNITS (mode); - - rtvec v = rtvec_alloc (n_elt); - - /* Create an all 0 constant. */ - for (i = 0; i < n_elt; ++i) - RTVEC_ELT (v, i) = const0_rtx; - operands[2] = gen_reg_rtx (mode); - operands[3] = gen_rtx_CONST_VECTOR (mode, v); + operands[3] = CONST0_RTX (mode); operands[4] = gen_reg_rtx (mode); }) Index: gcc/config/s390/vx-builtins.md =================================================================== --- gcc/config/s390/vx-builtins.md 2017-10-23 11:40:11.561479591 +0100 +++ gcc/config/s390/vx-builtins.md 2017-10-23 11:41:32.367050264 +0100 @@ -91,12 +91,10 @@ (define_expand "vec_genmask" (match_operand:QI 2 "const_int_operand" "C")] "TARGET_VX" { - int nunits = GET_MODE_NUNITS (mode); int bitlen = GET_MODE_UNIT_BITSIZE (mode); /* To bit little endian style. */ int end = bitlen - 1 - INTVAL (operands[1]); int start = bitlen - 1 - INTVAL (operands[2]); - rtx const_vec[16]; int i; unsigned HOST_WIDE_INT mask; bool swapped_p = false; @@ -116,13 +114,11 @@ (define_expand "vec_genmask" if (swapped_p) mask = ~mask; - for (i = 0; i < nunits; i++) - const_vec[i] = GEN_INT (trunc_int_for_mode (mask, - GET_MODE_INNER (mode))); + rtx mask_rtx = gen_int_mode (mask, GET_MODE_INNER (mode)); emit_insn (gen_rtx_SET (operands[0], - gen_rtx_CONST_VECTOR (mode, - gen_rtvec_v (nunits, const_vec)))); + gen_const_vec_duplicate (mode, + mask_rtx))); DONE; }) @@ -1623,7 +1619,7 @@ (define_expand "vec_ctd_s64" real_2expN (&f, -INTVAL (operands[2]), DFmode); c = const_double_from_real_value (f, DFmode); - operands[3] = gen_rtx_CONST_VECTOR (V2DFmode, gen_rtvec (2, c, c)); + operands[3] = gen_const_vec_duplicate (V2DFmode, c); operands[3] = force_reg (V2DFmode, operands[3]); }) @@ -1654,7 +1650,7 @@ (define_expand "vec_ctd_u64" real_2expN (&f, -INTVAL (operands[2]), DFmode); c = const_double_from_real_value (f, DFmode); - operands[3] = gen_rtx_CONST_VECTOR (V2DFmode, gen_rtvec (2, c, c)); + operands[3] = gen_const_vec_duplicate (V2DFmode, c); operands[3] = force_reg (V2DFmode, operands[3]); }) @@ -1686,7 +1682,7 @@ (define_expand "vec_ctsl" real_2expN (&f, INTVAL (operands[2]), DFmode); c = const_double_from_real_value (f, DFmode); - operands[3] = gen_rtx_CONST_VECTOR (V2DFmode, gen_rtvec (2, c, c)); + operands[3] = gen_const_vec_duplicate (V2DFmode, c); operands[3] = force_reg (V2DFmode, operands[3]); operands[4] = gen_reg_rtx (V2DFmode); }) @@ -1719,7 +1715,7 @@ (define_expand "vec_ctul" real_2expN (&f, INTVAL (operands[2]), DFmode); c = const_double_from_real_value (f, DFmode); - operands[3] = gen_rtx_CONST_VECTOR (V2DFmode, gen_rtvec (2, c, c)); + operands[3] = gen_const_vec_duplicate (V2DFmode, c); operands[3] = force_reg (V2DFmode, operands[3]); operands[4] = gen_reg_rtx (V2DFmode); }) Index: gcc/config/spu/spu.c =================================================================== --- gcc/config/spu/spu.c 2017-10-23 11:41:23.057077951 +0100 +++ gcc/config/spu/spu.c 2017-10-23 11:41:32.368050264 +0100 @@ -1903,8 +1903,6 @@ spu_return_addr (int count, rtx frame AT spu_const (machine_mode mode, HOST_WIDE_INT val) { rtx inner; - rtvec v; - int units, i; gcc_assert (GET_MODE_CLASS (mode) == MODE_INT || GET_MODE_CLASS (mode) == MODE_FLOAT @@ -1923,14 +1921,7 @@ spu_const (machine_mode mode, HOST_WIDE_ else inner = hwint_to_const_double (GET_MODE_INNER (mode), val); - units = GET_MODE_NUNITS (mode); - - v = rtvec_alloc (units); - - for (i = 0; i < units; ++i) - RTVEC_ELT (v, i) = inner; - - return gen_rtx_CONST_VECTOR (mode, v); + return gen_const_vec_duplicate (mode, inner); } /* Create a MODE vector constant from 4 ints. */