[PATCH] D83615: [WebAssembly] Custom combine splat build_vectors into swizzles
Thomas Lively via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 10 19:49:21 PDT 2020
tlively created this revision.
tlively added reviewers: aheejin, dschuff.
Herald added subscribers: llvm-commits, sunfish, hiraditya, jgravelle-google, sbc100.
Herald added a project: LLVM.
Some splat build_vectors can be lowered to swizzles, but only if all
of their lanes but one are undefined. This patch adds a custom combine
to turn these build_vectors into swizzles before their undefined lanes
are combined away by the combine introduced in D83606 <https://reviews.llvm.org/D83606>.
Depends on D83606 <https://reviews.llvm.org/D83606>.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D83615
Files:
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
llvm/test/CodeGen/WebAssembly/simd-build-vector.ll
Index: llvm/test/CodeGen/WebAssembly/simd-build-vector.ll
===================================================================
--- llvm/test/CodeGen/WebAssembly/simd-build-vector.ll
+++ llvm/test/CodeGen/WebAssembly/simd-build-vector.ll
@@ -93,14 +93,10 @@
ret <8 x i16> %v7
}
-;; TODO: This should be a swizzle, but will need a custom combine to
-;; preempt the combine that removes undef lanes from splat
-;; build_vectors, since swizzle lowering depends on those lanes being
-;; undef.
-
; CHECK-LABEL: swizzle_one_i8x16:
; CHECK-NEXT: .functype swizzle_one_i8x16 (v128, v128) -> (v128)
-; CHECK-NOT: v8x16.swizzle
+; CHECK-NEXT: v8x16.swizzle $push[[L0:[0-9]+]]=, $0, $1
+; CHECK-NEXT: return $pop[[L0]]
define <16 x i8> @swizzle_one_i8x16(<16 x i8> %src, <16 x i8> %mask) {
%m0 = extractelement <16 x i8> %mask, i32 0
%s0 = extractelement <16 x i8> %src, i8 %m0
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1736,6 +1736,48 @@
return DAG.getBitcast(DstType, NewShuffle);
}
+static SDValue combineSwizzleSplat(BuildVectorSDNode *N, SelectionDAG &DAG,
+ const BitVector &UndefElts) {
+ // This splat can only be lowered to a swizzle if all lanes but one are undef.
+ //
+ // We are looking for the following pattern:
+ // (insert undef,
+ // (extract Vec1,
+ // (sext (extract Vec2, Index))
+ // ),
+ // Index
+ // )
+ //
+ // To combine to: (swizzle vec1, vec2)
+ if (N->getValueType(0) != MVT::v16i8)
+ return SDValue();
+ if (UndefElts.count() != 15)
+ return SDValue();
+ unsigned Index1 = UndefElts.find_first_unset();
+ auto Extract1 = N->getOperand(Index1);
+ if (Extract1.getOpcode() != ISD::EXTRACT_VECTOR_ELT)
+ return SDValue();
+ auto Vec1 = Extract1.getOperand(0);
+ if (Vec1.getValueType() != MVT::v16i8)
+ return SDValue();
+ auto SExt = Extract1.getOperand(1);
+ if (SExt.getOpcode() != ISD::SIGN_EXTEND)
+ return SDValue();
+ auto Extract2 = SExt.getOperand(0);
+ if (Extract2.getOpcode() != ISD::EXTRACT_VECTOR_ELT)
+ return SDValue();
+ auto Vec2 = Extract2.getOperand(0);
+ if (Vec2.getValueType() != MVT::v16i8)
+ return SDValue();
+ if (Extract2.getOperand(1).getOpcode() != ISD::Constant)
+ return SDValue();
+ unsigned Index2 = Extract2.getConstantOperandVal(1);
+ if (Index1 != Index2)
+ return SDValue();
+
+ return DAG.getNode(WebAssemblyISD::SWIZZLE, SDLoc(N), MVT::v16i8, Vec1, Vec2);
+}
+
static SDValue
performBUILD_VECTORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI) {
auto &DAG = DCI.DAG;
@@ -1744,9 +1786,16 @@
// Remove undef lanes from splats. They don't allow us to make any extra
// optimizations and they can inhibit splat scalarization combines.
BitVector UndefElts;
- if (SDValue SplatVal = Build->getSplatValue(&UndefElts))
- if (UndefElts.any())
+ if (SDValue SplatVal = Build->getSplatValue(&UndefElts)) {
+ if (UndefElts.any()) {
+ // If this BUILD_VECTOR can be implemented as a swizzle, perform that
+ // transformation now because once we remove the undef lanes we will not
+ // be able to recover the swizzle.
+ if (auto Swizzle = combineSwizzleSplat(Build, DAG, UndefElts))
+ return Swizzle;
return DAG.getSplatBuildVector(N->getValueType(0), SDLoc(N), SplatVal);
+ }
+ }
return SDValue();
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D83615.277210.patch
Type: text/x-patch
Size: 3583 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200711/e26c5302/attachment.bin>
More information about the llvm-commits
mailing list