From ec0b66c318ea42ec229fd3a9ef4ad92bf81d41cf Mon Sep 17 00:00:00 2001 From: Sander de Smalen Date: Thu, 28 May 2020 09:27:00 +0100 Subject: [PATCH] [CodeGen] Specify meaning of ISD opcodes for scalable vectors This patch contains changes to the description of EXTRACT_SUBVECTOR, INSERT_SUBVECTOR, INSERT_VECTOR_ELT, EXTRACT_VECTOR_ELT and CONCAT_VECTORS to specify their behaviour for scalable vectors. For EXTRACT_SUBVECTOR it specifies that the IDX is scaled by the same runtime scaling as the extracted (or inserted) vector. This definition is the most natural extension to EXTRACT_SUBVECTOR for scalable vectors, as most use-cases that work on fixed-width types will have the same meaning for scalable types. For legalization for example, it is common to split the vector operation to operate on the LO and HI halfs of a vector. For a fixed width vector <16 x i8> this would be expressed with: v16i8 %res = EXTRACT_SUBVECTOR v32i8 %v, i32 16 For a scalable vector, this would similarly be expressed as: nxv16i8 %res = EXTRACT_SUBVECTOR nxv32i8 %V, i32 16 By extending the meaning of IDX for scalable vectors, most existing optimisations on EXTRACT/INSERT_SUBVECTOR work for scalable vectors without any changes. This definition also allows extracting a fixed-width subvector from a scalable vector, which is useful to e.g. extract the low N lanes of a scalable vector. This patch is not NFC because it sets the meaning of these nodes for scalable vectors, which future patches will build upon. Reviewers: efriedma, ctetreau, rogfer01, craig.topper Reviewed By: efriedma Tags: #llvm Differential Revision: https://reviews.llvm.org/D79806 --- llvm/include/llvm/CodeGen/ISDOpcodes.h | 67 +++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 22 deletions(-) diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h index f081a53263e..cf3afd8aeab 100644 --- a/llvm/include/llvm/CodeGen/ISDOpcodes.h +++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h @@ -446,44 +446,67 @@ enum NodeType { /// Returns platform specific canonical encoding of a floating point number. FCANONICALIZE, - /// BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a vector with the - /// specified, possibly variable, elements. The number of elements is - /// required to be a power of two. The types of the operands must all be - /// the same and must match the vector element type, except that integer - /// types are allowed to be larger than the element type, in which case - /// the operands are implicitly truncated. + /// BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector + /// with the specified, possibly variable, elements. The number of elements + /// is required to be a power of two. The types of the operands must all be + /// the same and must match the vector element type, except that integer types + /// are allowed to be larger than the element type, in which case the operands + /// are implicitly truncated. BUILD_VECTOR, /// INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element - /// at IDX replaced with VAL. If the type of VAL is larger than the vector + /// at IDX replaced with VAL. If the type of VAL is larger than the vector /// element type then VAL is truncated before replacement. + /// + /// If VECTOR is a scalable vector, then IDX may be larger than the minimum + /// vector width. IDX is not first scaled by the runtime scaling factor of + /// VECTOR. INSERT_VECTOR_ELT, /// EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR - /// identified by the (potentially variable) element number IDX. If the - /// return type is an integer type larger than the element type of the - /// vector, the result is extended to the width of the return type. In - /// that case, the high bits are undefined. + /// identified by the (potentially variable) element number IDX. If the return + /// type is an integer type larger than the element type of the vector, the + /// result is extended to the width of the return type. In that case, the high + /// bits are undefined. + /// + /// If VECTOR is a scalable vector, then IDX may be larger than the minimum + /// vector width. IDX is not first scaled by the runtime scaling factor of + /// VECTOR. EXTRACT_VECTOR_ELT, /// CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of /// vector type with the same length and element type, this produces a /// concatenated vector result value, with length equal to the sum of the - /// lengths of the input vectors. + /// lengths of the input vectors. If VECTOR0 is a fixed-width vector, then + /// VECTOR1..VECTORN must all be fixed-width vectors. Similarly, if VECTOR0 + /// is a scalable vector, then VECTOR1..VECTORN must all be scalable vectors. CONCAT_VECTORS, - /// INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector - /// with VECTOR2 inserted into VECTOR1 at the constant element number - /// IDX, which must be a multiple of the VECTOR2 vector length. The - /// elements of VECTOR1 starting at IDX are overwritten with VECTOR2. - /// Elements IDX through vector_length(VECTOR2) must be valid VECTOR1 - /// indices. + /// INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 + /// inserted into VECTOR1. IDX represents the starting element number at which + /// VECTOR2 will be inserted. IDX must be a constant multiple of T's known + /// minimum vector length. Let the type of VECTOR2 be T, then if T is a + /// scalable vector, IDX is first scaled by the runtime scaling factor of T. + /// The elements of VECTOR1 starting at IDX are overwritten with VECTOR2. + /// Elements IDX through (IDX + num_elements(T) - 1) must be valid VECTOR1 + /// indices. If this condition cannot be determined statically but is false at + /// runtime, then the result vector is undefined. + /// + /// This operation supports inserting a fixed-width vector into a scalable + /// vector, but not the other way around. INSERT_SUBVECTOR, - /// EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR (an - /// vector value) starting with the constant element number IDX, which - /// must be a multiple of the result vector length. Elements IDX through - /// vector_length(VECTOR) must be valid VECTOR indices. + /// EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR. + /// Let the result type be T, then IDX represents the starting element number + /// from which a subvector of type T is extracted. IDX must be a constant + /// multiple of T's known minimum vector length. If T is a scalable vector, + /// IDX is first scaled by the runtime scaling factor of T. Elements IDX + /// through (IDX + num_elements(T) - 1) must be valid VECTOR indices. If this + /// condition cannot be determined statically but is false at runtime, then + /// the result vector is undefined. + /// + /// This operation supports extracting a fixed-width vector from a scalable + /// vector, but not the other way around. EXTRACT_SUBVECTOR, /// VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as -- 2.11.0