diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 7d1fd037869..99cc2da97af 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -23133,6 +23133,8 @@ static SDValue LowerScalarImmediateShift(SDValue Op, SelectionDAG &DAG, static SDValue IsSplatValue(MVT VT, SDValue V, const SDLoc &dl, SelectionDAG &DAG, const X86Subtarget &Subtarget, unsigned Opcode) { + V = peekThroughEXTRACT_SUBVECTORs(V); + // Check if this is a splat build_vector node. if (BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(V)) { SDValue SplatAmt = BV->getSplatValue(); @@ -23792,6 +23794,16 @@ static SDValue LowerRotate(SDValue Op, const X86Subtarget &Subtarget, } } + // Rotate by splat - expand back to shifts. + // TODO - legalizers should be able to handle this. + if (IsSplatValue(VT, Amt, DL, DAG, Subtarget, Opcode)) { + SDValue AmtR = DAG.getConstant(EltSizeInBits, DL, VT); + AmtR = DAG.getNode(ISD::SUB, DL, VT, AmtR, Amt); + SDValue SHL = DAG.getNode(ISD::SHL, DL, VT, R, Amt); + SDValue SRL = DAG.getNode(ISD::SRL, DL, VT, R, AmtR); + return DAG.getNode(ISD::OR, DL, VT, SHL, SRL); + } + // AVX2 - best to fallback to variable shifts. // TODO - legalizers should be able to handle this. if (Subtarget.hasAVX2()) { |