@@ -1701,18 +1701,14 @@ SDValue WebAssemblyTargetLowering::LowerBUILD_VECTOR(SDValue Op,
17011701 std::function<bool (size_t , const SDValue &)> IsLaneConstructed;
17021702 SDValue Result;
17031703 // Prefer swizzles over vector consts over splats
1704- if (NumSwizzleLanes >= NumSplatLanes &&
1705- (!Subtarget->hasUnimplementedSIMD128 () ||
1706- NumSwizzleLanes >= NumConstantLanes)) {
1704+ if (NumSwizzleLanes >= NumSplatLanes && NumSwizzleLanes >= NumConstantLanes) {
17071705 Result = DAG.getNode (WebAssemblyISD::SWIZZLE, DL, VecT, SwizzleSrc,
17081706 SwizzleIndices);
17091707 auto Swizzled = std::make_pair (SwizzleSrc, SwizzleIndices);
17101708 IsLaneConstructed = [&, Swizzled](size_t I, const SDValue &Lane) {
17111709 return Swizzled == GetSwizzleSrcs (I, Lane);
17121710 };
1713- } else if (NumConstantLanes >= NumSplatLanes &&
1714- Subtarget->hasUnimplementedSIMD128 ()) {
1715- // If we support v128.const, emit it directly
1711+ } else if (NumConstantLanes >= NumSplatLanes) {
17161712 SmallVector<SDValue, 16 > ConstLanes;
17171713 for (const SDValue &Lane : Op->op_values ()) {
17181714 if (IsConstant (Lane)) {
@@ -1727,55 +1723,6 @@ SDValue WebAssemblyTargetLowering::LowerBUILD_VECTOR(SDValue Op,
17271723 IsLaneConstructed = [&IsConstant](size_t _, const SDValue &Lane) {
17281724 return IsConstant (Lane);
17291725 };
1730- } else if (NumConstantLanes >= NumSplatLanes && VecT.isInteger ()) {
1731- // Otherwise, if this is an integer vector, pack the lane values together so
1732- // we can construct the 128-bit constant from a pair of i64s using a splat
1733- // followed by at most one i64x2.replace_lane. Also keep track of the lanes
1734- // that actually matter so we can avoid the replace_lane in more cases.
1735- std::array<uint64_t , 2 > I64s{{0 , 0 }};
1736- std::array<uint64_t , 2 > ConstLaneMasks{{0 , 0 }};
1737- size_t LaneBits = 128 / Lanes;
1738- size_t HalfLanes = Lanes / 2 ;
1739- for (size_t I = 0 ; I < Lanes; ++I) {
1740- const SDValue &Lane = Op.getOperand (I);
1741- if (IsConstant (Lane)) {
1742- // How much we need to shift Val to position it in an i64
1743- auto Shift = LaneBits * (I % HalfLanes);
1744- auto Mask = maskTrailingOnes<uint64_t >(LaneBits);
1745- auto Val = cast<ConstantSDNode>(Lane.getNode ())->getZExtValue () & Mask;
1746- I64s[I / HalfLanes] |= Val << Shift;
1747- ConstLaneMasks[I / HalfLanes] |= Mask << Shift;
1748- }
1749- }
1750- // Check whether all constant lanes in the second half of the vector are
1751- // equivalent in the first half or vice versa to determine whether splatting
1752- // either side will be sufficient to materialize the constant. As a special
1753- // case, if the first and second halves have no constant lanes in common, we
1754- // can just combine them.
1755- bool FirstHalfSufficient = (I64s[0 ] & ConstLaneMasks[1 ]) == I64s[1 ];
1756- bool SecondHalfSufficient = (I64s[1 ] & ConstLaneMasks[0 ]) == I64s[0 ];
1757- bool CombinedSufficient = (ConstLaneMasks[0 ] & ConstLaneMasks[1 ]) == 0 ;
1758-
1759- uint64_t Splatted;
1760- if (SecondHalfSufficient) {
1761- Splatted = I64s[1 ];
1762- } else if (CombinedSufficient) {
1763- Splatted = I64s[0 ] | I64s[1 ];
1764- } else {
1765- Splatted = I64s[0 ];
1766- }
1767-
1768- Result = DAG.getSplatBuildVector (MVT::v2i64, DL,
1769- DAG.getConstant (Splatted, DL, MVT::i64 ));
1770- if (!FirstHalfSufficient && !SecondHalfSufficient && !CombinedSufficient) {
1771- Result = DAG.getNode (ISD::INSERT_VECTOR_ELT, DL, MVT::v2i64, Result,
1772- DAG.getConstant (I64s[1 ], DL, MVT::i64 ),
1773- DAG.getConstant (1 , DL, MVT::i32 ));
1774- }
1775- Result = DAG.getBitcast (VecT, Result);
1776- IsLaneConstructed = [&IsConstant](size_t _, const SDValue &Lane) {
1777- return IsConstant (Lane);
1778- };
17791726 } else {
17801727 // Use a splat, but possibly a load_splat
17811728 LoadSDNode *SplattedLoad;
0 commit comments