From patchwork Wed Jan 3 09:02:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 123284 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp9931599qgn; Wed, 3 Jan 2018 01:02:25 -0800 (PST) X-Google-Smtp-Source: ACJfBospkxPrkOFa9rTqnxhK2gMurqe6uuNczNsY1NKjiwwBuupzB2jgk0/a3Sd37OimkP8cyLfZ X-Received: by 10.84.225.21 with SMTP id t21mr774357plj.68.1514970145029; Wed, 03 Jan 2018 01:02:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1514970145; cv=none; d=google.com; s=arc-20160816; b=gTY8dp766xPREBCWAI8Y0Tjqfo65ffIR6ZVR0ve+Ginhy1yzLb/DeJUR932hyhnYGY fm5UPHYD7VHXMSk6utSXM0aV65n51pIKalN4f0rn5Qb1ngbZVr4/WHXITkJaI8QoWB8i kmEj546RbNAE9gAvt7i42lFcu2qiXwDA+7WKkmxxA+lRqCUKArLWpWS+eoFgtIB9YnJn uOCbk2H2/REqIzNi3fXeoDI9PN4sMOXNmFMEBUxIerWZVm2+7v7uVamYrqCGLmXCAdRv IojA6qOKOxHN/VDdWcMAMe4hiVUfaLOztRTkcY5zA9VwvAUyROiN9LUAk3RAaMsn+GkH hQGA== 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=gL72ayV9ozoM0/iQWSXMlKwQ6L9Zm3pMUhLG1H3Ul8M=; b=l+mKe5wOPc5Zf6aCI2vZY+idlEJoWAXWrOAVLO3PiN4LuVlBGYA3MPjEv03kB+kP+j xlxYa7u4dLgH51p9A86D59N32S2zko4nxz3Uj4zQOta+Ra2MSkLhcLw7n4LVLYBlgaSU QIFDTne0hVlW/1hJ4mtH1ap9vgUoCioCGmUpCBLv6tr0lqiPm2vCn5xGmYPUNF4JO5rc 4CkTC2KQYB6eA0NDZTvr/GadpfmFM7lP6shkRKHJQZYbjRUWoAHWnBpJr5aFB5z4lnLY 70y8xfMVQhVARaRul0JHnIgLcdR5KvhDrwpkiels0K3FXGAQhGCQNzsKl2vkGjGcW6ls v+/w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=wyX4EXVa; spf=pass (google.com: domain of gcc-patches-return-470030-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-470030-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 r8si397911pgf.137.2018.01.03.01.02.24 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 03 Jan 2018 01:02:25 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-470030-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=wyX4EXVa; spf=pass (google.com: domain of gcc-patches-return-470030-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-470030-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=K91vRBEW0Z+gvUh5Q9xNq+0AAGY3/E9e4EldZOA+QtpkoMv5563yB mwnpgMXw9v0akQihaf1FtA1SJHqWQlDzdC5nw85H/rqnchTg8+VPyHw9oFvHz4PA ShRdoFLmm09J1qDbFTCbmjI0kG+Z0OZcQQtTbo+YW48Sm+Qs83fiog= 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=ylxhFsRTMMZ2BUL5bEgAxQhjxWc=; b=wyX4EXVaZiqFWETXdWzL BVstgHwyQ/q4FUQWq/60/AgnKuCcpD9652gMEP1pjOEO5vsO66i9+iCnzrUk/OJt Lf+ChPBDOLZI8RWdD6qX3DtUcXE/S58qfUC3JYO2dA5o1052osFSLxTAg5LuwZQR ecErbTpMM2fPFU0TbBTITlQ= Received: (qmail 39834 invoked by alias); 3 Jan 2018 09:02:12 -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 39825 invoked by uid 89); 3 Jan 2018 09:02:11 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-wm0-f50.google.com Received: from mail-wm0-f50.google.com (HELO mail-wm0-f50.google.com) (74.125.82.50) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 03 Jan 2018 09:02:05 +0000 Received: by mail-wm0-f50.google.com with SMTP id b141so1409274wme.1 for ; Wed, 03 Jan 2018 01:02:05 -0800 (PST) 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=gL72ayV9ozoM0/iQWSXMlKwQ6L9Zm3pMUhLG1H3Ul8M=; b=mTnb97O2ilnR+f9sO6LOoauTui2XXdPWhv5QoMYGmLxG8Jy3cKSXWXBiqYwhWK9smq EbdfLX8PPwr3a+SOgDaPPPjlOfEjoewDtQ4W/7wSw6aeJqsBqqy9yrKLnPQL31CLJKH5 amtr+EdghwA0x6msnAMcv0g8lwatJm3pGzyapnjt8QCA+mlET+l45aTXdAgXfL09bbpo g1hgLJAX3PsTnuSQIijjlR99zUeP8w0WsgNJxY7tMN9rznRY0+mDMT4RHseOXzdoUg1P ciC+wZNi7Evp2d0xerb4KfzNuWRJyIiUp/36V+jvaYDsebohqsBsxkwu6r23gBs5cLAd tx8A== X-Gm-Message-State: AKGB3mL+Xxazkcd/FPHWMMTFDmgS9Dz0JrobD0QelxyIR4X0cYTanduh fl/v7psGrWh+vMx2lB26PAAD3peSlpk= X-Received: by 10.28.138.142 with SMTP id m136mr882602wmd.40.1514970123204; Wed, 03 Jan 2018 01:02:03 -0800 (PST) Received: from localhost (188.29.165.215.threembb.co.uk. [188.29.165.215]) by smtp.gmail.com with ESMTPSA id j96sm275556wrj.93.2018.01.03.01.02.01 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 03 Jan 2018 01:02:02 -0800 (PST) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Subject: [committed] [100.2/nnn] poly_int: vector_builder element count Date: Wed, 03 Jan 2018 09:02:00 +0000 Message-ID: <87o9mbmi2f.fsf@linaro.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) MIME-Version: 1.0 This patch changes the number of elements in a vector being built by a vector_builder from unsigned int to poly_uint64. The case in which it isn't a constant is the one that motivated adding the vector encoding in the first place. Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu. Also tested by comparing the before and after assembly output for at least one target per CPU directory. Committed as pre-approved by Jeff here: https://gcc.gnu.org/ml/gcc-patches/2017-11/msg01409.html . Thanks, Richard 2018-01-03 Richard Sandiford gcc/ * vector-builder.h (vector_builder::m_full_nelts): Change from unsigned int to poly_uint64. (vector_builder::full_nelts): Update prototype accordingly. (vector_builder::new_vector): Likewise. (vector_builder::encoded_full_vector_p): Handle polynomial full_nelts. (vector_builder::operator ==): Likewise. (vector_builder::finalize): Likewise. * int-vector-builder.h (int_vector_builder::int_vector_builder): Take the number of elements as a poly_uint64 rather than an unsigned int. * vec-perm-indices.h (vec_perm_indices::m_nelts_per_input): Change from unsigned int to poly_uint64. (vec_perm_indices::vec_perm_indices): Update prototype accordingly. (vec_perm_indices::new_vector): Likewise. (vec_perm_indices::length): Likewise. (vec_perm_indices::nelts_per_input): Likewise. (vec_perm_indices::input_nelts): Likewise. * vec-perm-indices.c (vec_perm_indices::new_vector): Take the number of elements per input as a poly_uint64 rather than an unsigned int. Use the original encoding for variable-length vectors, rather than clamping each individual element. For the second and subsequent elements in each pattern, clamp the step and base before clamping their sum. (vec_perm_indices::series_p): Handle polynomial element counts. (vec_perm_indices::all_in_range_p): Likewise. (vec_perm_indices_to_tree): Likewise. (vec_perm_indices_to_rtx): Likewise. * tree-vect-stmts.c (vect_gen_perm_mask_any): Likewise. * tree-vector-builder.c (tree_vector_builder::new_unary_operation) (tree_vector_builder::new_binary_operation): Handle polynomial element counts. Return false if we need to know the number of elements at compile time. * fold-const.c (fold_vec_perm): Punt if the number of elements isn't known at compile time. Index: gcc/vector-builder.h =================================================================== --- gcc/vector-builder.h 2018-01-03 08:46:30.347663443 +0000 +++ gcc/vector-builder.h 2018-01-03 08:54:24.909508898 +0000 @@ -90,7 +90,7 @@ #define GCC_VECTOR_BUILDER_H public: vector_builder (); - unsigned int full_nelts () const { return m_full_nelts; } + poly_uint64 full_nelts () const { return m_full_nelts; } unsigned int npatterns () const { return m_npatterns; } unsigned int nelts_per_pattern () const { return m_nelts_per_pattern; } unsigned int encoded_nelts () const; @@ -103,7 +103,7 @@ #define GCC_VECTOR_BUILDER_H void finalize (); protected: - void new_vector (unsigned int, unsigned int, unsigned int); + void new_vector (poly_uint64, unsigned int, unsigned int); void reshape (unsigned int, unsigned int); bool repeating_sequence_p (unsigned int, unsigned int, unsigned int); bool stepped_sequence_p (unsigned int, unsigned int, unsigned int); @@ -115,7 +115,7 @@ #define GCC_VECTOR_BUILDER_H Derived *derived () { return static_cast (this); } const Derived *derived () const; - unsigned int m_full_nelts; + poly_uint64 m_full_nelts; unsigned int m_npatterns; unsigned int m_nelts_per_pattern; }; @@ -152,7 +152,7 @@ vector_builder::encoded_nelt inline bool vector_builder::encoded_full_vector_p () const { - return m_npatterns * m_nelts_per_pattern == m_full_nelts; + return known_eq (m_npatterns * m_nelts_per_pattern, m_full_nelts); } /* Start building a vector that has FULL_NELTS elements. Initially @@ -160,7 +160,7 @@ vector_builder::encoded_full template void -vector_builder::new_vector (unsigned int full_nelts, +vector_builder::new_vector (poly_uint64 full_nelts, unsigned int npatterns, unsigned int nelts_per_pattern) { @@ -178,7 +178,7 @@ vector_builder::new_vector ( bool vector_builder::operator == (const Derived &other) const { - if (m_full_nelts != other.m_full_nelts + if (maybe_ne (m_full_nelts, other.m_full_nelts) || m_npatterns != other.m_npatterns || m_nelts_per_pattern != other.m_nelts_per_pattern) return false; @@ -356,14 +356,16 @@ vector_builder::finalize () { /* The encoding requires the same number of elements to come from each pattern. */ - gcc_assert (m_full_nelts % m_npatterns == 0); + gcc_assert (multiple_p (m_full_nelts, m_npatterns)); /* Allow the caller to build more elements than necessary. For example, it's often convenient to build a stepped vector from the natural encoding of three elements even if the vector itself only has two. */ - if (m_full_nelts <= encoded_nelts ()) + unsigned HOST_WIDE_INT const_full_nelts; + if (m_full_nelts.is_constant (&const_full_nelts) + && const_full_nelts <= encoded_nelts ()) { - m_npatterns = m_full_nelts; + m_npatterns = const_full_nelts; m_nelts_per_pattern = 1; } @@ -435,9 +437,10 @@ vector_builder::finalize () would be for 2-bit elements. We'll have treated them as duplicates in the loop above. */ if (m_nelts_per_pattern == 1 - && this->length () >= m_full_nelts + && m_full_nelts.is_constant (&const_full_nelts) + && this->length () >= const_full_nelts && (m_npatterns & 3) == 0 - && stepped_sequence_p (m_npatterns / 4, m_full_nelts, + && stepped_sequence_p (m_npatterns / 4, const_full_nelts, m_npatterns / 4)) { reshape (m_npatterns / 4, 3); Index: gcc/int-vector-builder.h =================================================================== --- gcc/int-vector-builder.h 2018-01-03 08:46:30.345663760 +0000 +++ gcc/int-vector-builder.h 2018-01-03 08:54:24.908508964 +0000 @@ -33,7 +33,7 @@ #define GCC_INT_VECTOR_BUILDER_H 1 public: int_vector_builder () {} - int_vector_builder (unsigned int, unsigned int, unsigned int); + int_vector_builder (poly_uint64, unsigned int, unsigned int); using parent::new_vector; @@ -53,7 +53,7 @@ #define GCC_INT_VECTOR_BUILDER_H 1 template inline -int_vector_builder::int_vector_builder (unsigned int full_nelts, +int_vector_builder::int_vector_builder (poly_uint64 full_nelts, unsigned int npatterns, unsigned int nelts_per_pattern) { Index: gcc/vec-perm-indices.h =================================================================== --- gcc/vec-perm-indices.h 2018-01-03 08:46:30.347663443 +0000 +++ gcc/vec-perm-indices.h 2018-01-03 08:54:24.909508898 +0000 @@ -53,9 +53,9 @@ typedef int_vector_builder v public: vec_perm_indices (); - vec_perm_indices (const vec_perm_builder &, unsigned int, unsigned int); + vec_perm_indices (const vec_perm_builder &, unsigned int, poly_uint64); - void new_vector (const vec_perm_builder &, unsigned int, unsigned int); + void new_vector (const vec_perm_builder &, unsigned int, poly_uint64); void new_expanded_vector (const vec_perm_indices &, unsigned int); void rotate_inputs (int delta); @@ -64,16 +64,16 @@ typedef int_vector_builder v /* Return the number of output elements. This is called length () so that we present a more vec-like interface. */ - unsigned int length () const { return m_encoding.full_nelts (); } + poly_uint64 length () const { return m_encoding.full_nelts (); } /* Return the number of input vectors being permuted. */ unsigned int ninputs () const { return m_ninputs; } /* Return the number of elements in each input vector. */ - unsigned int nelts_per_input () const { return m_nelts_per_input; } + poly_uint64 nelts_per_input () const { return m_nelts_per_input; } /* Return the total number of input elements. */ - unsigned int input_nelts () const { return m_ninputs * m_nelts_per_input; } + poly_uint64 input_nelts () const { return m_ninputs * m_nelts_per_input; } element_type clamp (element_type) const; element_type operator[] (unsigned int i) const; @@ -86,7 +86,7 @@ typedef int_vector_builder v vec_perm_builder m_encoding; unsigned int m_ninputs; - unsigned int m_nelts_per_input; + poly_uint64 m_nelts_per_input; }; bool tree_to_vec_perm_builder (vec_perm_builder *, tree); @@ -107,7 +107,7 @@ vec_perm_indices::vec_perm_indices () inline vec_perm_indices::vec_perm_indices (const vec_perm_builder &elements, unsigned int ninputs, - unsigned int nelts_per_input) + poly_uint64 nelts_per_input) { new_vector (elements, ninputs, nelts_per_input); } Index: gcc/vec-perm-indices.c =================================================================== --- gcc/vec-perm-indices.c 2018-01-03 08:46:30.347663443 +0000 +++ gcc/vec-perm-indices.c 2018-01-03 08:54:24.909508898 +0000 @@ -38,16 +38,42 @@ Software Foundation; either version 3, o void vec_perm_indices::new_vector (const vec_perm_builder &elements, unsigned int ninputs, - unsigned int nelts_per_input) + poly_uint64 nelts_per_input) { m_ninputs = ninputs; m_nelts_per_input = nelts_per_input; - /* Expand the encoding and clamp each element. E.g. { 0, 2, 4, ... } - might wrap halfway if there is only one vector input. */ - unsigned int full_nelts = elements.full_nelts (); - m_encoding.new_vector (full_nelts, full_nelts, 1); - for (unsigned int i = 0; i < full_nelts; ++i) + /* If the vector has a constant number of elements, expand the + encoding and clamp each element. E.g. { 0, 2, 4, ... } might + wrap halfway if there is only one vector input, and we want + the wrapped form to be the canonical one. + + If the vector has a variable number of elements, just copy + the encoding. In that case the unwrapped form is canonical + and there is no way of representing the wrapped form. */ + poly_uint64 full_nelts = elements.full_nelts (); + unsigned HOST_WIDE_INT copy_nelts; + if (full_nelts.is_constant (©_nelts)) + m_encoding.new_vector (full_nelts, copy_nelts, 1); + else + { + copy_nelts = elements.encoded_nelts (); + m_encoding.new_vector (full_nelts, elements.npatterns (), + elements.nelts_per_pattern ()); + } + unsigned int npatterns = m_encoding.npatterns (); + for (unsigned int i = 0; i < npatterns; ++i) m_encoding.quick_push (clamp (elements.elt (i))); + /* Use the fact that: + + (a + b) % c == ((a % c) + (b % c)) % c + + to simplify the clamping of variable-length vectors. */ + for (unsigned int i = npatterns; i < copy_nelts; ++i) + { + element_type step = clamp (elements.elt (i) + - elements.elt (i - npatterns)); + m_encoding.quick_push (clamp (m_encoding[i - npatterns] + step)); + } m_encoding.finalize (); } @@ -98,7 +124,7 @@ vec_perm_indices::series_p (unsigned int if (maybe_ne (clamp (m_encoding.elt (out_base)), clamp (in_base))) return false; - unsigned int full_nelts = m_encoding.full_nelts (); + element_type full_nelts = m_encoding.full_nelts (); unsigned int npatterns = m_encoding.npatterns (); /* Calculate which multiple of OUT_STEP elements we need to get @@ -112,7 +138,7 @@ vec_perm_indices::series_p (unsigned int for (;;) { /* Succeed if we've checked all the elements in the vector. */ - if (out_base >= full_nelts) + if (known_ge (out_base, full_nelts)) return true; if (out_base >= npatterns) @@ -156,7 +182,8 @@ vec_perm_indices::all_in_range_p (elemen /* The number of elements in each pattern beyond the first two that we checked above. */ - unsigned int step_nelts = (m_encoding.full_nelts () / npatterns) - 2; + poly_int64 step_nelts = exact_div (m_encoding.full_nelts (), + npatterns) - 2; for (unsigned int i = 0; i < npatterns; ++i) { /* BASE1 has been checked but BASE2 hasn't. */ @@ -210,7 +237,7 @@ tree_to_vec_perm_builder (vec_perm_build tree vec_perm_indices_to_tree (tree type, const vec_perm_indices &indices) { - gcc_assert (TYPE_VECTOR_SUBPARTS (type) == indices.length ()); + gcc_assert (known_eq (TYPE_VECTOR_SUBPARTS (type), indices.length ())); tree_vector_builder sel (type, indices.encoding ().npatterns (), indices.encoding ().nelts_per_pattern ()); unsigned int encoded_nelts = sel.encoded_nelts (); @@ -226,7 +253,7 @@ vec_perm_indices_to_tree (tree type, con vec_perm_indices_to_rtx (machine_mode mode, const vec_perm_indices &indices) { gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_INT - && GET_MODE_NUNITS (mode) == indices.length ()); + && known_eq (GET_MODE_NUNITS (mode), indices.length ())); rtx_vector_builder sel (mode, indices.encoding ().npatterns (), indices.encoding ().nelts_per_pattern ()); unsigned int encoded_nelts = sel.encoded_nelts (); Index: gcc/tree-vect-stmts.c =================================================================== --- gcc/tree-vect-stmts.c 2018-01-03 07:16:23.065729718 +0000 +++ gcc/tree-vect-stmts.c 2018-01-03 08:54:24.909508898 +0000 @@ -6588,8 +6588,8 @@ vect_gen_perm_mask_any (tree vectype, co { tree mask_type; - unsigned int nunits = sel.length (); - gcc_assert (nunits == TYPE_VECTOR_SUBPARTS (vectype)); + poly_uint64 nunits = sel.length (); + gcc_assert (known_eq (nunits, TYPE_VECTOR_SUBPARTS (vectype))); mask_type = build_vector_type (ssizetype, nunits); return vec_perm_indices_to_tree (mask_type, sel); Index: gcc/tree-vector-builder.c =================================================================== --- gcc/tree-vector-builder.c 2018-01-02 16:55:01.415292836 +0000 +++ gcc/tree-vector-builder.c 2018-01-03 08:54:24.909508898 +0000 @@ -36,13 +36,15 @@ Software Foundation; either version 3, o tree_vector_builder::new_unary_operation (tree type, tree t, bool allow_stepped_p) { - unsigned int full_nelts = TYPE_VECTOR_SUBPARTS (type); - gcc_assert (full_nelts == TYPE_VECTOR_SUBPARTS (TREE_TYPE (t))); + poly_uint64 full_nelts = TYPE_VECTOR_SUBPARTS (type); + gcc_assert (known_eq (full_nelts, TYPE_VECTOR_SUBPARTS (TREE_TYPE (t)))); unsigned int npatterns = VECTOR_CST_NPATTERNS (t); unsigned int nelts_per_pattern = VECTOR_CST_NELTS_PER_PATTERN (t); if (!allow_stepped_p && nelts_per_pattern > 2) { - npatterns = full_nelts; + if (!full_nelts.is_constant ()) + return false; + npatterns = full_nelts.to_constant (); nelts_per_pattern = 1; } new_vector (type, npatterns, nelts_per_pattern); @@ -61,9 +63,9 @@ tree_vector_builder::new_unary_operation tree_vector_builder::new_binary_operation (tree type, tree t1, tree t2, bool allow_stepped_p) { - unsigned int full_nelts = TYPE_VECTOR_SUBPARTS (type); - gcc_assert (full_nelts == TYPE_VECTOR_SUBPARTS (TREE_TYPE (t1)) - && full_nelts == TYPE_VECTOR_SUBPARTS (TREE_TYPE (t2))); + poly_uint64 full_nelts = TYPE_VECTOR_SUBPARTS (type); + gcc_assert (known_eq (full_nelts, TYPE_VECTOR_SUBPARTS (TREE_TYPE (t1))) + && known_eq (full_nelts, TYPE_VECTOR_SUBPARTS (TREE_TYPE (t2)))); /* Conceptually we split the patterns in T1 and T2 until we have an equal number for both. Each split pattern requires the same number of elements per pattern as the original. E.g. splitting: @@ -89,7 +91,9 @@ tree_vector_builder::new_binary_operatio VECTOR_CST_NELTS_PER_PATTERN (t2)); if (!allow_stepped_p && nelts_per_pattern > 2) { - npatterns = full_nelts; + if (!full_nelts.is_constant ()) + return false; + npatterns = full_nelts.to_constant (); nelts_per_pattern = 1; } new_vector (type, npatterns, nelts_per_pattern); Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c 2018-01-03 08:46:30.345663760 +0000 +++ gcc/fold-const.c 2018-01-03 08:54:24.907509030 +0000 @@ -8927,9 +8927,11 @@ vec_cst_ctor_to_array (tree arg, unsigne fold_vec_perm (tree type, tree arg0, tree arg1, const vec_perm_indices &sel) { unsigned int i; + unsigned HOST_WIDE_INT nelts; bool need_ctor = false; - unsigned int nelts = sel.length (); + if (!sel.length ().is_constant (&nelts)) + return NULL_TREE; gcc_assert (TYPE_VECTOR_SUBPARTS (type) == nelts && TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)) == nelts && TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1)) == nelts);