@@ -1988,10 +1988,22 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementInst, Value)
1988
1988
// ShuffleVectorInst Class
1989
1989
// ===----------------------------------------------------------------------===//
1990
1990
1991
+ constexpr int UndefMaskElem = -1;
1992
+
1991
1993
// / This instruction constructs a fixed permutation of two
1992
1994
// / input vectors.
1993
1995
// /
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.
1994
2003
class ShuffleVectorInst : public Instruction {
2004
+ SmallVector<int , 4 > ShuffleMask;
2005
+ Constant *ShuffleMaskForBitcode;
2006
+
1995
2007
protected:
1996
2008
// Note: Instruction needs to be a friend here to call cloneImpl.
1997
2009
friend class Instruction ;
@@ -2004,20 +2016,24 @@ class ShuffleVectorInst : public Instruction {
2004
2016
Instruction *InsertBefor = nullptr );
2005
2017
ShuffleVectorInst (Value *V1, Value *V2, Value *Mask,
2006
2018
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);
2007
2024
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 ); }
2012
2026
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
2014
2028
// / of the instruction.
2015
2029
void commute ();
2016
2030
2017
2031
// / Return true if a shufflevector instruction can be
2018
2032
// / formed with the specified operands.
2019
2033
static bool isValidOperands (const Value *V1, const Value *V2,
2020
2034
const Value *Mask);
2035
+ static bool isValidOperands (const Value *V1, const Value *V2,
2036
+ ArrayRef<int > Mask);
2021
2037
2022
2038
// / Overload to return most specific vector type.
2023
2039
// /
@@ -2028,44 +2044,41 @@ class ShuffleVectorInst : public Instruction {
2028
2044
// / Transparently provide more efficient getOperand methods.
2029
2045
DECLARE_TRANSPARENT_OPERAND_ACCESSORS (Value);
2030
2046
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
-
2039
2047
// / 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]; }
2044
2050
2045
2051
// / 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 .
2047
2053
static void getShuffleMask (const Constant *Mask,
2048
2054
SmallVectorImpl<int > &Result);
2049
2055
2050
2056
// / 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 .
2052
2058
void getShuffleMask (SmallVectorImpl<int > &Result) const {
2053
- return getShuffleMask ( getMask (), Result );
2059
+ Result. assign (ShuffleMask. begin (), ShuffleMask. end () );
2054
2060
}
2055
2061
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; }
2061
2074
2062
2075
// / Return true if this shuffle returns a vector with a different number of
2063
2076
// / elements than its source vectors.
2064
2077
// / Examples: shufflevector <4 x n> A, <4 x n> B, <1,2,3>
2065
2078
// / shufflevector <4 x n> A, <4 x n> B, <1,2,3,4,5>
2066
2079
bool changesLength () const {
2067
2080
unsigned NumSourceElts = Op<0 >()->getType ()->getVectorNumElements ();
2068
- unsigned NumMaskElts = getMask ()-> getType ()-> getVectorNumElements ();
2081
+ unsigned NumMaskElts = ShuffleMask. size ();
2069
2082
return NumSourceElts != NumMaskElts;
2070
2083
}
2071
2084
@@ -2074,7 +2087,7 @@ class ShuffleVectorInst : public Instruction {
2074
2087
// / Example: shufflevector <2 x n> A, <2 x n> B, <1,2,3>
2075
2088
bool increasesLength () const {
2076
2089
unsigned NumSourceElts = Op<0 >()->getType ()->getVectorNumElements ();
2077
- unsigned NumMaskElts = getMask ()-> getType ()-> getVectorNumElements ();
2090
+ unsigned NumMaskElts = ShuffleMask. size ();
2078
2091
return NumSourceElts < NumMaskElts;
2079
2092
}
2080
2093
@@ -2095,7 +2108,7 @@ class ShuffleVectorInst : public Instruction {
2095
2108
// / Example: shufflevector <4 x n> A, <4 x n> B, <3,0,undef,3>
2096
2109
// / TODO: Optionally allow length-changing shuffles.
2097
2110
bool isSingleSource () const {
2098
- return !changesLength () && isSingleSourceMask (getMask () );
2111
+ return !changesLength () && isSingleSourceMask (ShuffleMask );
2099
2112
}
2100
2113
2101
2114
// / Return true if this shuffle mask chooses elements from exactly one source
@@ -2116,7 +2129,7 @@ class ShuffleVectorInst : public Instruction {
2116
2129
// / from its input vectors.
2117
2130
// / Example: shufflevector <4 x n> A, <4 x n> B, <4,undef,6,undef>
2118
2131
bool isIdentity () const {
2119
- return !changesLength () && isIdentityMask (getShuffleMask () );
2132
+ return !changesLength () && isIdentityMask (ShuffleMask );
2120
2133
}
2121
2134
2122
2135
// / Return true if this shuffle lengthens exactly one source vector with
@@ -2157,7 +2170,7 @@ class ShuffleVectorInst : public Instruction {
2157
2170
// / In that case, the shuffle is better classified as an identity shuffle.
2158
2171
// / TODO: Optionally allow length-changing shuffles.
2159
2172
bool isSelect () const {
2160
- return !changesLength () && isSelectMask (getMask () );
2173
+ return !changesLength () && isSelectMask (ShuffleMask );
2161
2174
}
2162
2175
2163
2176
// / Return true if this shuffle mask swaps the order of elements from exactly
@@ -2177,7 +2190,7 @@ class ShuffleVectorInst : public Instruction {
2177
2190
// / Example: shufflevector <4 x n> A, <4 x n> B, <3,undef,1,undef>
2178
2191
// / TODO: Optionally allow length-changing shuffles.
2179
2192
bool isReverse () const {
2180
- return !changesLength () && isReverseMask (getMask () );
2193
+ return !changesLength () && isReverseMask (ShuffleMask );
2181
2194
}
2182
2195
2183
2196
// / Return true if this shuffle mask chooses all elements with the same value
@@ -2199,7 +2212,7 @@ class ShuffleVectorInst : public Instruction {
2199
2212
// / TODO: Optionally allow length-changing shuffles.
2200
2213
// / TODO: Optionally allow splats from other elements.
2201
2214
bool isZeroEltSplat () const {
2202
- return !changesLength () && isZeroEltSplatMask (getMask () );
2215
+ return !changesLength () && isZeroEltSplatMask (ShuffleMask );
2203
2216
}
2204
2217
2205
2218
// / Return true if this shuffle mask is a transpose mask.
@@ -2248,7 +2261,7 @@ class ShuffleVectorInst : public Instruction {
2248
2261
// / exact specification.
2249
2262
// / Example: shufflevector <4 x n> A, <4 x n> B, <0,4,2,6>
2250
2263
bool isTranspose () const {
2251
- return !changesLength () && isTransposeMask (getMask () );
2264
+ return !changesLength () && isTransposeMask (ShuffleMask );
2252
2265
}
2253
2266
2254
2267
// / Return true if this shuffle mask is an extract subvector mask.
@@ -2267,7 +2280,7 @@ class ShuffleVectorInst : public Instruction {
2267
2280
// / Return true if this shuffle mask is an extract subvector mask.
2268
2281
bool isExtractSubvectorMask (int &Index) const {
2269
2282
int NumSrcElts = Op<0 >()->getType ()->getVectorNumElements ();
2270
- return isExtractSubvectorMask (getMask () , NumSrcElts, Index);
2283
+ return isExtractSubvectorMask (ShuffleMask , NumSrcElts, Index);
2271
2284
}
2272
2285
2273
2286
// / Change values in a shuffle permute mask assuming the two vector operands
@@ -2293,9 +2306,8 @@ class ShuffleVectorInst : public Instruction {
2293
2306
};
2294
2307
2295
2308
template <>
2296
- struct OperandTraits <ShuffleVectorInst> :
2297
- public FixedNumOperandTraits<ShuffleVectorInst, 3 > {
2298
- };
2309
+ struct OperandTraits <ShuffleVectorInst>
2310
+ : public FixedNumOperandTraits<ShuffleVectorInst, 2 > {};
2299
2311
2300
2312
DEFINE_TRANSPARENT_OPERAND_ACCESSORS (ShuffleVectorInst, Value)
2301
2313
0 commit comments