summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2018-11-02 00:39:57 +0000
committerThomas Lively <tlively@google.com>2018-11-02 00:39:57 +0000
commitb2382c8bf797129c33fdcc2819dde82fbd3b2b1e (patch)
tree8d386248fb63e03e54ecfc02981b33dac334b74e /llvm/lib
parent9914c3a2bae84bb92e5269165c4d098140549b46 (diff)
downloadbcm5719-llvm-b2382c8bf797129c33fdcc2819dde82fbd3b2b1e.tar.gz
bcm5719-llvm-b2382c8bf797129c33fdcc2819dde82fbd3b2b1e.zip
[WebAssembly] General vector shift lowering
Summary: Adds support for lowering non-splat shifts. Reviewers: aheejin, dschuff Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits Differential Revision: https://reviews.llvm.org/D53625 llvm-svn: 345916
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp39
1 files changed, 27 insertions, 12 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index d182bd9f369..578d23570f8 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -146,10 +146,15 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
}
}
- // Custom lowering to avoid having to emit a wrap for 2xi64 constant shifts
- if (Subtarget->hasSIMD128() && EnableUnimplementedWasmSIMDInstrs)
- for (auto Op : {ISD::SHL, ISD::SRA, ISD::SRL})
- setOperationAction(Op, MVT::v2i64, Custom);
+ // Custom lowering since wasm shifts must have a scalar shift amount
+ if (Subtarget->hasSIMD128()) {
+ for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32})
+ for (auto Op : {ISD::SHL, ISD::SRA, ISD::SRL})
+ setOperationAction(Op, T, Custom);
+ if (EnableUnimplementedWasmSIMDInstrs)
+ for (auto Op : {ISD::SHL, ISD::SRA, ISD::SRL})
+ setOperationAction(Op, MVT::v2i64, Custom);
+ }
// There is no select instruction for vectors
if (Subtarget->hasSIMD128()) {
@@ -1082,13 +1087,23 @@ WebAssemblyTargetLowering::LowerAccessVectorElement(SDValue Op,
SDValue WebAssemblyTargetLowering::LowerShift(SDValue Op,
SelectionDAG &DAG) const {
SDLoc DL(Op);
- auto *ShiftVec = dyn_cast<BuildVectorSDNode>(Op.getOperand(1).getNode());
- APInt SplatValue, SplatUndef;
- unsigned SplatBitSize;
- bool HasAnyUndefs;
- if (!ShiftVec || !ShiftVec->isConstantSplat(SplatValue, SplatUndef,
- SplatBitSize, HasAnyUndefs))
+
+ // Only manually lower vector shifts
+ assert(Op.getSimpleValueType().isVector());
+
+ // Unroll non-splat vector shifts
+ BuildVectorSDNode *ShiftVec;
+ SDValue SplatVal;
+ if (!(ShiftVec = dyn_cast<BuildVectorSDNode>(Op.getOperand(1).getNode())) ||
+ !(SplatVal = ShiftVec->getSplatValue()))
+ return DAG.UnrollVectorOp(Op.getNode());
+
+ // All splats except i64x2 const splats are handled by patterns
+ ConstantSDNode *SplatConst = dyn_cast<ConstantSDNode>(SplatVal);
+ if (!SplatConst || Op.getSimpleValueType() != MVT::v2i64)
return Op;
+
+ // i64x2 const splats are custom lowered to avoid unnecessary wraps
unsigned Opcode;
switch (Op.getOpcode()) {
case ISD::SHL:
@@ -1102,10 +1117,10 @@ SDValue WebAssemblyTargetLowering::LowerShift(SDValue Op,
break;
default:
llvm_unreachable("unexpected opcode");
- return Op;
}
+ APInt Shift = SplatConst->getAPIntValue().zextOrTrunc(32);
return DAG.getNode(Opcode, DL, Op.getValueType(), Op.getOperand(0),
- DAG.getConstant(SplatValue.trunc(32), DL, MVT::i32));
+ DAG.getConstant(Shift, DL, MVT::i32));
}
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud