summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@intel.com>2019-08-19 05:45:39 +0000
committerCraig Topper <craig.topper@intel.com>2019-08-19 05:45:39 +0000
commitebb7ddc6330b28b8c7e53d4c68d3684c127a41c1 (patch)
tree9db03b3417059390173ab5a7fd07a94a53a8d146 /llvm/lib
parentdee9546b8f8386223769e96becc2e24ddcc39de7 (diff)
downloadbcm5719-llvm-ebb7ddc6330b28b8c7e53d4c68d3684c127a41c1.tar.gz
bcm5719-llvm-ebb7ddc6330b28b8c7e53d4c68d3684c127a41c1.zip
[X86] Teach lower1BitShuffle to match right shifts with upper zero elements on types that don't natively support KSHIFT.
We can support these by widening to a supported type, then shifting all the way to the left and then back to the right to ensure that we shift in zeroes. llvm-svn: 369232
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp39
1 files changed, 20 insertions, 19 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index ae3aed0055a..f0a4cf2aef8 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -16640,25 +16640,26 @@ static SDValue lower1BitShuffle(const SDLoc &DL, ArrayRef<int> Mask,
unsigned Opcode;
int ShiftAmt = match1BitShuffleAsKSHIFT(Opcode, Mask, Offset, Zeroable);
if (ShiftAmt >= 0) {
- // FIXME: We can't easily widen an illegal right shift if we need to shift
- // in zeroes.
- if (Opcode == X86ISD::KSHIFTR &&
- (NumElts >= 16 || (Subtarget.hasDQI() && NumElts == 8)))
- return DAG.getNode(Opcode, DL, VT, V,
- DAG.getConstant(ShiftAmt, DL, MVT::i8));
- if (Opcode == X86ISD::KSHIFTL) {
- // If this is a shift left we can widen the VT to a suported kshiftl.
- MVT WideVT = VT;
- if ((!Subtarget.hasDQI() && NumElts == 8) || NumElts < 8)
- WideVT = Subtarget.hasDQI() ? MVT::v8i1 : MVT::v16i1;
- SDValue Res = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, WideVT,
- DAG.getUNDEF(WideVT), V,
- DAG.getIntPtrConstant(0, DL));
- Res = DAG.getNode(Opcode, DL, WideVT, Res,
- DAG.getConstant(ShiftAmt, DL, MVT::i8));
- return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, Res,
- DAG.getIntPtrConstant(0, DL));
- }
+ MVT WideVT = VT;
+ if ((!Subtarget.hasDQI() && NumElts == 8) || NumElts < 8)
+ WideVT = Subtarget.hasDQI() ? MVT::v8i1 : MVT::v16i1;
+ SDValue Res = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, WideVT,
+ DAG.getUNDEF(WideVT), V,
+ DAG.getIntPtrConstant(0, DL));
+ // Widened right shifts need two shifts to ensure we shift in zeroes.
+ if (Opcode == X86ISD::KSHIFTR && WideVT != VT) {
+ int WideElts = WideVT.getVectorNumElements();
+ // Shift left to put the original vector in the MSBs of the new size.
+ Res = DAG.getNode(X86ISD::KSHIFTL, DL, WideVT, Res,
+ DAG.getConstant(WideElts - NumElts, DL, MVT::i8));
+ // Increase the shift amount to account for the left shift.
+ ShiftAmt += WideElts - NumElts;
+ }
+
+ Res = DAG.getNode(Opcode, DL, WideVT, Res,
+ DAG.getConstant(ShiftAmt, DL, MVT::i8));
+ return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, Res,
+ DAG.getIntPtrConstant(0, DL));
}
Offset += NumElts; // Increment for next iteration.
}
OpenPOWER on IntegriCloud