summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/X86/X86ISelLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/X86/X86ISelLowering.cpp')
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp28
1 files changed, 23 insertions, 5 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 494c965b7d7..a306885e05e 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -7738,6 +7738,17 @@ static SDValue lowerVectorShuffleAsZeroOrAnyExtend(
return SDValue();
}
+/// \brief Try to get a scalar value for a specific element of a vector.
+///
+/// Looks through BUILD_VECTOR and SCALAR_TO_VECTOR nodes to find a scalar.
+static SDValue getScalarValueForVectorElement(SDValue V, int Idx) {
+ if (V.getOpcode() == ISD::BUILD_VECTOR ||
+ (Idx == 0 && V.getOpcode() == ISD::SCALAR_TO_VECTOR))
+ return V.getOperand(Idx);
+
+ return SDValue();
+}
+
/// \brief Try to lower insertion of a single element into a zero vector.
///
/// This is a common pattern that we have especially efficient patterns to lower
@@ -7773,13 +7784,10 @@ static SDValue lowerVectorShuffleAsElementInsertion(
// all the smarts here sunk into that routine. However, the current
// lowering of BUILD_VECTOR makes that nearly impossible until the old
// vector shuffle lowering is dead.
- if (!((V2.getOpcode() == ISD::SCALAR_TO_VECTOR &&
- Mask[V2Index] == (int)Mask.size()) ||
- V2.getOpcode() == ISD::BUILD_VECTOR))
+ SDValue V2S = getScalarValueForVectorElement(V2, Mask[V2Index] - Mask.size());
+ if (!V2S)
return SDValue();
- SDValue V2S = V2.getOperand(Mask[V2Index] - Mask.size());
-
// First, we need to zext the scalar if it is smaller than an i32.
MVT ExtVT = VT;
MVT EltVT = VT.getVectorElementType();
@@ -7910,6 +7918,16 @@ static SDValue lowerV2F64VectorShuffle(SDValue Op, SDValue V1, SDValue V2,
MVT::v2f64, DL, V1, V2, Mask, Subtarget, DAG))
return Insertion;
+ // Try to use one of the special instruction patterns to handle two common
+ // blend patterns if a zero-blend above didn't work.
+ if (isShuffleEquivalent(Mask, 0, 3) || isShuffleEquivalent(Mask, 1, 3))
+ if (SDValue V1S = getScalarValueForVectorElement(V1, Mask[0]))
+ // We can either use a special instruction to load over the low double or
+ // to move just the low double.
+ return DAG.getNode(ISD::isNON_EXTLoad(V1S.getNode()) ? X86ISD::MOVLPD
+ : X86ISD::MOVSD,
+ DL, MVT::v2f64, V2, V1S);
+
if (Subtarget->hasSSE41())
if (SDValue Blend = lowerVectorShuffleAsBlend(DL, MVT::v2f64, V1, V2, Mask,
Subtarget, DAG))
OpenPOWER on IntegriCloud