diff options
Diffstat (limited to 'llvm/lib/Target/X86')
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 39 |
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. } |