@@ -1883,6 +1883,76 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementInst, Value)
1883
1883
1884
1884
constexpr int PoisonMaskElem = -1;
1885
1885
1886
+ // / Attributes of a shufflevector mask.
1887
+ struct ShuffleMaskAttrs {
1888
+ // / If the shuffle chooses elements from exactly one source vector without
1889
+ // / changing the length of that vector.
1890
+ // / Example: shufflevector <4 x n> A, <4 x n> B, <3,0,undef,3>
1891
+ // / TODO: Optionally allow length-changing shuffles.
1892
+ bool SingleSource : 1 ;
1893
+
1894
+ // / If the shuffle chooses elements from exactly one source vector without
1895
+ // / lane crossings and does not change the number of elements from its input
1896
+ // / vectors.
1897
+ // / Example: shufflevector <4 x n> A, <4 x n> B, <4,undef,6,undef>
1898
+ bool Identity : 1 ;
1899
+
1900
+ // / If the shuffle lengthens exactly one source vector with undefs in the
1901
+ // / high elements.
1902
+ bool IdentityWithPadding : 1 ;
1903
+
1904
+ // / If the shuffle extracts the first N elements of exactly one source
1905
+ // / vector.
1906
+ bool IdentityWithExtract : 1 ;
1907
+
1908
+ // / If the shuffle concatenates the two source vectors. This is false if either
1909
+ // / input is undefined. In that case, the shuffle is better classified as an
1910
+ // / identity with padding operation.
1911
+ bool Concat : 1 ;
1912
+
1913
+ // / If the shuffle swaps the order of elements from exactly one source vector.
1914
+ // / Example: shufflevector <4 x n> A, <4 x n> B, <3,undef,1,undef>
1915
+ // / TODO: Optionally allow length-changing shuffles.
1916
+ bool Reverse : 1 ;
1917
+
1918
+ // / If all elements of the shuffle are the same value as the first element of
1919
+ // / exactly one source vector without changing the length of that vector.
1920
+ // / Example: shufflevector <4 x n> A, <4 x n> B, <undef,0,undef,0>
1921
+ // / TODO: Optionally allow length-changing shuffles.
1922
+ // / TODO: Optionally allow splats from other elements.
1923
+ bool ZeroEltSplat : 1 ;
1924
+
1925
+ // / Return true if this shuffle chooses elements from its source vectors
1926
+ // / without lane crossings and all operands have the same number of elements.
1927
+ // / In other words, this shuffle is equivalent to a vector select with a
1928
+ // / constant condition operand.
1929
+ // / Example: shufflevector <4 x n> A, <4 x n> B, <undef,1,6,3>
1930
+ // / This returns false if the mask does not choose from both input vectors.
1931
+ // / In that case, the shuffle is better classified as an identity shuffle.
1932
+ // / TODO: Optionally allow length-changing shuffles.
1933
+ bool Select : 1 ;
1934
+
1935
+ // / If the shuffle transposes the elements of its inputs without changing the
1936
+ // / length of the vectors. This operation may also be known as a merge or
1937
+ // / interleave. See the description for isTransposeMask() for the exact
1938
+ // / specification.
1939
+ // / Example: shufflevector <4 x n> A, <4 x n> B, <0,4,2,6>
1940
+ bool Transpose : 1 ;
1941
+
1942
+ // / If the shuffle splices two inputs without changing the length of the
1943
+ // / vectors. This operation concatenates the two inputs together and then
1944
+ // / extracts an original width vector starting from the splice index.
1945
+ // / Example: shufflevector <4 x n> A, <4 x n> B, <1,2,3,4>
1946
+ bool Splice : 1 ;
1947
+
1948
+ // / The starting index of the splice.
1949
+ // / Example: 1, from the previous example
1950
+ int SpliceIndex;
1951
+ };
1952
+
1953
+ static_assert (sizeof (ShuffleMaskAttrs) <= sizeof(uint64_t ),
1954
+ "ShuffleMaskAttrs is too large!");
1955
+
1886
1956
// / This instruction constructs a fixed permutation of two
1887
1957
// / input vectors.
1888
1958
// /
@@ -1898,6 +1968,7 @@ class ShuffleVectorInst : public Instruction {
1898
1968
1899
1969
SmallVector<int , 4 > ShuffleMask;
1900
1970
Constant *ShuffleMaskForBitcode;
1971
+ ShuffleMaskAttrs MaskAttrs;
1901
1972
1902
1973
protected:
1903
1974
// Note: Instruction needs to be a friend here to call cloneImpl.
@@ -1924,6 +1995,12 @@ class ShuffleVectorInst : public Instruction {
1924
1995
// / of the instruction.
1925
1996
void commute ();
1926
1997
1998
+ // Analyze mask of fixed vector. NumOpElts is number of known elements in
1999
+ // operand1/operand2. Scalable is set if any operands are scalable vectors.
2000
+ // HasUndefOp is set if there are any undef operands.
2001
+ static ShuffleMaskAttrs analyzeMask (ArrayRef<int > Mask, int NumOpElts,
2002
+ bool Scalable, bool HasUndefOp);
2003
+
1927
2004
// / Return true if a shufflevector instruction can be
1928
2005
// / formed with the specified operands.
1929
2006
static bool isValidOperands (const Value *V1, const Value *V2,
@@ -2004,13 +2081,8 @@ class ShuffleVectorInst : public Instruction {
2004
2081
return isSingleSourceMask (MaskAsInts, NumSrcElts);
2005
2082
}
2006
2083
2007
- // / Return true if this shuffle chooses elements from exactly one source
2008
- // / vector without changing the length of that vector.
2009
- // / Example: shufflevector <4 x n> A, <4 x n> B, <3,0,undef,3>
2010
- // / TODO: Optionally allow length-changing shuffles.
2011
2084
bool isSingleSource () const {
2012
- return !changesLength () &&
2013
- isSingleSourceMask (ShuffleMask, ShuffleMask.size ());
2085
+ return MaskAttrs.SingleSource ;
2014
2086
}
2015
2087
2016
2088
// / Return true if this shuffle mask chooses elements from exactly one source
@@ -2032,31 +2104,21 @@ class ShuffleVectorInst : public Instruction {
2032
2104
return isIdentityMask (MaskAsInts, NumSrcElts);
2033
2105
}
2034
2106
2035
- // / Return true if this shuffle chooses elements from exactly one source
2036
- // / vector without lane crossings and does not change the number of elements
2037
- // / from its input vectors.
2038
- // / Example: shufflevector <4 x n> A, <4 x n> B, <4,undef,6,undef>
2039
2107
bool isIdentity () const {
2040
- // Not possible to express a shuffle mask for a scalable vector for this
2041
- // case.
2042
- if (isa<ScalableVectorType>(getType ()))
2043
- return false ;
2044
-
2045
- return !changesLength () && isIdentityMask (ShuffleMask, ShuffleMask.size ());
2108
+ return MaskAttrs.Identity ;
2046
2109
}
2047
2110
2048
- // / Return true if this shuffle lengthens exactly one source vector with
2049
- // / undefs in the high elements.
2050
- bool isIdentityWithPadding () const ;
2111
+ bool isIdentityWithPadding () const {
2112
+ return MaskAttrs. IdentityWithPadding ;
2113
+ }
2051
2114
2052
- // / Return true if this shuffle extracts the first N elements of exactly one
2053
- // / source vector.
2054
- bool isIdentityWithExtract () const ;
2115
+ bool isIdentityWithExtract () const {
2116
+ return MaskAttrs. IdentityWithExtract ;
2117
+ }
2055
2118
2056
- // / Return true if this shuffle concatenates its 2 source vectors. This
2057
- // / returns false if either input is undefined. In that case, the shuffle is
2058
- // / is better classified as an identity with padding operation.
2059
- bool isConcat () const ;
2119
+ bool isConcat () const {
2120
+ return MaskAttrs.Concat ;
2121
+ }
2060
2122
2061
2123
// / Return true if this shuffle mask chooses elements from its source vectors
2062
2124
// / without lane crossings. A shuffle using this mask would be
@@ -2074,16 +2136,8 @@ class ShuffleVectorInst : public Instruction {
2074
2136
return isSelectMask (MaskAsInts, NumSrcElts);
2075
2137
}
2076
2138
2077
- // / Return true if this shuffle chooses elements from its source vectors
2078
- // / without lane crossings and all operands have the same number of elements.
2079
- // / In other words, this shuffle is equivalent to a vector select with a
2080
- // / constant condition operand.
2081
- // / Example: shufflevector <4 x n> A, <4 x n> B, <undef,1,6,3>
2082
- // / This returns false if the mask does not choose from both input vectors.
2083
- // / In that case, the shuffle is better classified as an identity shuffle.
2084
- // / TODO: Optionally allow length-changing shuffles.
2085
2139
bool isSelect () const {
2086
- return ! changesLength () && isSelectMask (ShuffleMask, ShuffleMask. size ()) ;
2140
+ return MaskAttrs. Select ;
2087
2141
}
2088
2142
2089
2143
// / Return true if this shuffle mask swaps the order of elements from exactly
@@ -2099,12 +2153,8 @@ class ShuffleVectorInst : public Instruction {
2099
2153
return isReverseMask (MaskAsInts, NumSrcElts);
2100
2154
}
2101
2155
2102
- // / Return true if this shuffle swaps the order of elements from exactly
2103
- // / one source vector.
2104
- // / Example: shufflevector <4 x n> A, <4 x n> B, <3,undef,1,undef>
2105
- // / TODO: Optionally allow length-changing shuffles.
2106
2156
bool isReverse () const {
2107
- return ! changesLength () && isReverseMask (ShuffleMask, ShuffleMask. size ()) ;
2157
+ return MaskAttrs. Reverse ;
2108
2158
}
2109
2159
2110
2160
// / Return true if this shuffle mask chooses all elements with the same value
@@ -2120,15 +2170,8 @@ class ShuffleVectorInst : public Instruction {
2120
2170
return isZeroEltSplatMask (MaskAsInts, NumSrcElts);
2121
2171
}
2122
2172
2123
- // / Return true if all elements of this shuffle are the same value as the
2124
- // / first element of exactly one source vector without changing the length
2125
- // / of that vector.
2126
- // / Example: shufflevector <4 x n> A, <4 x n> B, <undef,0,undef,0>
2127
- // / TODO: Optionally allow length-changing shuffles.
2128
- // / TODO: Optionally allow splats from other elements.
2129
2173
bool isZeroEltSplat () const {
2130
- return !changesLength () &&
2131
- isZeroEltSplatMask (ShuffleMask, ShuffleMask.size ());
2174
+ return MaskAttrs.ZeroEltSplat ;
2132
2175
}
2133
2176
2134
2177
// / Return true if this shuffle mask is a transpose mask.
@@ -2171,13 +2214,8 @@ class ShuffleVectorInst : public Instruction {
2171
2214
return isTransposeMask (MaskAsInts, NumSrcElts);
2172
2215
}
2173
2216
2174
- // / Return true if this shuffle transposes the elements of its inputs without
2175
- // / changing the length of the vectors. This operation may also be known as a
2176
- // / merge or interleave. See the description for isTransposeMask() for the
2177
- // / exact specification.
2178
- // / Example: shufflevector <4 x n> A, <4 x n> B, <0,4,2,6>
2179
2217
bool isTranspose () const {
2180
- return ! changesLength () && isTransposeMask (ShuffleMask, ShuffleMask. size ()) ;
2218
+ return MaskAttrs. Transpose ;
2181
2219
}
2182
2220
2183
2221
// / Return true if this shuffle mask is a splice mask, concatenating the two
@@ -2194,13 +2232,9 @@ class ShuffleVectorInst : public Instruction {
2194
2232
return isSpliceMask (MaskAsInts, NumSrcElts, Index);
2195
2233
}
2196
2234
2197
- // / Return true if this shuffle splices two inputs without changing the length
2198
- // / of the vectors. This operation concatenates the two inputs together and
2199
- // / then extracts an original width vector starting from the splice index.
2200
- // / Example: shufflevector <4 x n> A, <4 x n> B, <1,2,3,4>
2201
2235
bool isSplice (int &Index) const {
2202
- return ! changesLength () &&
2203
- isSpliceMask (ShuffleMask, ShuffleMask. size (), Index) ;
2236
+ Index = MaskAttrs. SpliceIndex ;
2237
+ return MaskAttrs. Splice ;
2204
2238
}
2205
2239
2206
2240
// / Return true if this shuffle mask is an extract subvector mask.
0 commit comments