@@ -1988,10 +1988,22 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementInst, Value)
19881988// ShuffleVectorInst Class
19891989// ===----------------------------------------------------------------------===//
19901990
1991+ constexpr int UndefMaskElem = -1;
1992+
19911993// / This instruction constructs a fixed permutation of two
19921994// / input vectors.
19931995// /
1996+ // / For each element of the result vector, the shuffle mask selects an element
1997+ // / from one of the input vectors to copy to the result. Non-negative elements
1998+ // / in the mask represent an index into the concatenated pair of input vectors.
1999+ // / UndefMaskElem (-1) specifies that the result element is undefined.
2000+ // /
2001+ // / For scalable vectors, all the elements of the mask must be 0 or -1. This
2002+ // / requirement may be relaxed in the future.
19942003class ShuffleVectorInst : public Instruction {
2004+ SmallVector<int , 4 > ShuffleMask;
2005+ Constant *ShuffleMaskForBitcode;
2006+
19952007protected:
19962008 // Note: Instruction needs to be a friend here to call cloneImpl.
19972009 friend class Instruction ;
@@ -2004,20 +2016,24 @@ class ShuffleVectorInst : public Instruction {
20042016 Instruction *InsertBefor = nullptr );
20052017 ShuffleVectorInst (Value *V1, Value *V2, Value *Mask,
20062018 const Twine &NameStr, BasicBlock *InsertAtEnd);
2019+ ShuffleVectorInst (Value *V1, Value *V2, ArrayRef<int > Mask,
2020+ const Twine &NameStr = " " ,
2021+ Instruction *InsertBefor = nullptr );
2022+ ShuffleVectorInst (Value *V1, Value *V2, ArrayRef<int > Mask,
2023+ const Twine &NameStr, BasicBlock *InsertAtEnd);
20072024
2008- // allocate space for exactly three operands
2009- void *operator new (size_t s) {
2010- return User::operator new (s, 3 );
2011- }
2025+ void *operator new (size_t s) { return User::operator new (s, 2 ); }
20122026
2013- // / Swap the first 2 operands and adjust the mask to preserve the semantics
2027+ // / Swap the operands and adjust the mask to preserve the semantics
20142028 // / of the instruction.
20152029 void commute ();
20162030
20172031 // / Return true if a shufflevector instruction can be
20182032 // / formed with the specified operands.
20192033 static bool isValidOperands (const Value *V1, const Value *V2,
20202034 const Value *Mask);
2035+ static bool isValidOperands (const Value *V1, const Value *V2,
2036+ ArrayRef<int > Mask);
20212037
20222038 // / Overload to return most specific vector type.
20232039 // /
@@ -2028,44 +2044,41 @@ class ShuffleVectorInst : public Instruction {
20282044 // / Transparently provide more efficient getOperand methods.
20292045 DECLARE_TRANSPARENT_OPERAND_ACCESSORS (Value);
20302046
2031- Constant *getMask () const {
2032- return cast<Constant>(getOperand (2 ));
2033- }
2034-
2035- // / Return the shuffle mask value for the specified element of the mask.
2036- // / Return -1 if the element is undef.
2037- static int getMaskValue (const Constant *Mask, unsigned Elt);
2038-
20392047 // / Return the shuffle mask value of this instruction for the given element
2040- // / index. Return -1 if the element is undef.
2041- int getMaskValue (unsigned Elt) const {
2042- return getMaskValue (getMask (), Elt);
2043- }
2048+ // / index. Return UndefMaskElem if the element is undef.
2049+ int getMaskValue (unsigned Elt) const { return ShuffleMask[Elt]; }
20442050
20452051 // / Convert the input shuffle mask operand to a vector of integers. Undefined
2046- // / elements of the mask are returned as -1 .
2052+ // / elements of the mask are returned as UndefMaskElem .
20472053 static void getShuffleMask (const Constant *Mask,
20482054 SmallVectorImpl<int > &Result);
20492055
20502056 // / Return the mask for this instruction as a vector of integers. Undefined
2051- // / elements of the mask are returned as -1 .
2057+ // / elements of the mask are returned as UndefMaskElem .
20522058 void getShuffleMask (SmallVectorImpl<int > &Result) const {
2053- return getShuffleMask ( getMask (), Result );
2059+ Result. assign (ShuffleMask. begin (), ShuffleMask. end () );
20542060 }
20552061
2056- SmallVector<int , 16 > getShuffleMask () const {
2057- SmallVector<int , 16 > Mask;
2058- getShuffleMask (Mask);
2059- return Mask;
2060- }
2062+ // / Return the mask for this instruction, for use in bitcode.
2063+ // /
2064+ // / TODO: This is temporary until we decide a new bitcode encoding for
2065+ // / shufflevector.
2066+ Constant *getShuffleMaskForBitcode () const { return ShuffleMaskForBitcode; }
2067+
2068+ static Constant *convertShuffleMaskForBitcode (ArrayRef<int > Mask,
2069+ Type *ResultTy);
2070+
2071+ void setShuffleMask (ArrayRef<int > Mask);
2072+
2073+ ArrayRef<int > getShuffleMask () const { return ShuffleMask; }
20612074
20622075 // / Return true if this shuffle returns a vector with a different number of
20632076 // / elements than its source vectors.
20642077 // / Examples: shufflevector <4 x n> A, <4 x n> B, <1,2,3>
20652078 // / shufflevector <4 x n> A, <4 x n> B, <1,2,3,4,5>
20662079 bool changesLength () const {
20672080 unsigned NumSourceElts = Op<0 >()->getType ()->getVectorNumElements ();
2068- unsigned NumMaskElts = getMask ()-> getType ()-> getVectorNumElements ();
2081+ unsigned NumMaskElts = ShuffleMask. size ();
20692082 return NumSourceElts != NumMaskElts;
20702083 }
20712084
@@ -2074,7 +2087,7 @@ class ShuffleVectorInst : public Instruction {
20742087 // / Example: shufflevector <2 x n> A, <2 x n> B, <1,2,3>
20752088 bool increasesLength () const {
20762089 unsigned NumSourceElts = Op<0 >()->getType ()->getVectorNumElements ();
2077- unsigned NumMaskElts = getMask ()-> getType ()-> getVectorNumElements ();
2090+ unsigned NumMaskElts = ShuffleMask. size ();
20782091 return NumSourceElts < NumMaskElts;
20792092 }
20802093
@@ -2095,7 +2108,7 @@ class ShuffleVectorInst : public Instruction {
20952108 // / Example: shufflevector <4 x n> A, <4 x n> B, <3,0,undef,3>
20962109 // / TODO: Optionally allow length-changing shuffles.
20972110 bool isSingleSource () const {
2098- return !changesLength () && isSingleSourceMask (getMask () );
2111+ return !changesLength () && isSingleSourceMask (ShuffleMask );
20992112 }
21002113
21012114 // / Return true if this shuffle mask chooses elements from exactly one source
@@ -2116,7 +2129,7 @@ class ShuffleVectorInst : public Instruction {
21162129 // / from its input vectors.
21172130 // / Example: shufflevector <4 x n> A, <4 x n> B, <4,undef,6,undef>
21182131 bool isIdentity () const {
2119- return !changesLength () && isIdentityMask (getShuffleMask () );
2132+ return !changesLength () && isIdentityMask (ShuffleMask );
21202133 }
21212134
21222135 // / Return true if this shuffle lengthens exactly one source vector with
@@ -2157,7 +2170,7 @@ class ShuffleVectorInst : public Instruction {
21572170 // / In that case, the shuffle is better classified as an identity shuffle.
21582171 // / TODO: Optionally allow length-changing shuffles.
21592172 bool isSelect () const {
2160- return !changesLength () && isSelectMask (getMask () );
2173+ return !changesLength () && isSelectMask (ShuffleMask );
21612174 }
21622175
21632176 // / Return true if this shuffle mask swaps the order of elements from exactly
@@ -2177,7 +2190,7 @@ class ShuffleVectorInst : public Instruction {
21772190 // / Example: shufflevector <4 x n> A, <4 x n> B, <3,undef,1,undef>
21782191 // / TODO: Optionally allow length-changing shuffles.
21792192 bool isReverse () const {
2180- return !changesLength () && isReverseMask (getMask () );
2193+ return !changesLength () && isReverseMask (ShuffleMask );
21812194 }
21822195
21832196 // / Return true if this shuffle mask chooses all elements with the same value
@@ -2199,7 +2212,7 @@ class ShuffleVectorInst : public Instruction {
21992212 // / TODO: Optionally allow length-changing shuffles.
22002213 // / TODO: Optionally allow splats from other elements.
22012214 bool isZeroEltSplat () const {
2202- return !changesLength () && isZeroEltSplatMask (getMask () );
2215+ return !changesLength () && isZeroEltSplatMask (ShuffleMask );
22032216 }
22042217
22052218 // / Return true if this shuffle mask is a transpose mask.
@@ -2248,7 +2261,7 @@ class ShuffleVectorInst : public Instruction {
22482261 // / exact specification.
22492262 // / Example: shufflevector <4 x n> A, <4 x n> B, <0,4,2,6>
22502263 bool isTranspose () const {
2251- return !changesLength () && isTransposeMask (getMask () );
2264+ return !changesLength () && isTransposeMask (ShuffleMask );
22522265 }
22532266
22542267 // / Return true if this shuffle mask is an extract subvector mask.
@@ -2267,7 +2280,7 @@ class ShuffleVectorInst : public Instruction {
22672280 // / Return true if this shuffle mask is an extract subvector mask.
22682281 bool isExtractSubvectorMask (int &Index) const {
22692282 int NumSrcElts = Op<0 >()->getType ()->getVectorNumElements ();
2270- return isExtractSubvectorMask (getMask () , NumSrcElts, Index);
2283+ return isExtractSubvectorMask (ShuffleMask , NumSrcElts, Index);
22712284 }
22722285
22732286 // / Change values in a shuffle permute mask assuming the two vector operands
@@ -2293,9 +2306,8 @@ class ShuffleVectorInst : public Instruction {
22932306};
22942307
22952308template <>
2296- struct OperandTraits <ShuffleVectorInst> :
2297- public FixedNumOperandTraits<ShuffleVectorInst, 3 > {
2298- };
2309+ struct OperandTraits <ShuffleVectorInst>
2310+ : public FixedNumOperandTraits<ShuffleVectorInst, 2 > {};
22992311
23002312DEFINE_TRANSPARENT_OPERAND_ACCESSORS (ShuffleVectorInst, Value)
23012313
0 commit comments