summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp12
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()) {
OpenPOWER on IntegriCloud