aboutsummaryrefslogtreecommitdiff
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.cpp72
1 files changed, 35 insertions, 37 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 450927aaf5cc..f8b6b7eb3aff 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -6916,25 +6916,16 @@ static bool getTargetShuffleMask(SDNode *N, MVT VT, bool AllowSentinelZero,
DecodeZeroMoveLowMask(NumElems, Mask);
IsUnary = true;
break;
- case X86ISD::VBROADCAST: {
- SDValue N0 = N->getOperand(0);
- // See if we're broadcasting from index 0 of an EXTRACT_SUBVECTOR. If so,
- // add the pre-extracted value to the Ops vector.
- if (N0.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
- N0.getOperand(0).getValueType() == VT &&
- N0.getConstantOperandVal(1) == 0)
- Ops.push_back(N0.getOperand(0));
-
- // We only decode broadcasts of same-sized vectors, unless the broadcast
- // came from an extract from the original width. If we found one, we
- // pushed it the Ops vector above.
- if (N0.getValueType() == VT || !Ops.empty()) {
+ case X86ISD::VBROADCAST:
+ // We only decode broadcasts of same-sized vectors, peeking through to
+ // extracted subvectors is likely to cause hasOneUse issues with
+ // SimplifyDemandedBits etc.
+ if (N->getOperand(0).getValueType() == VT) {
DecodeVectorBroadcast(NumElems, Mask);
IsUnary = true;
break;
}
return false;
- }
case X86ISD::VPERMILPV: {
assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
IsUnary = true;
@@ -44523,6 +44514,8 @@ static SDValue combineFaddFsub(SDNode *N, SelectionDAG &DAG,
isHorizontalBinOp(LHS, RHS, DAG, Subtarget, IsFadd))
return DAG.getNode(HorizOpcode, SDLoc(N), VT, LHS, RHS);
+ // NOTE: isHorizontalBinOp may have changed LHS/RHS variables.
+
return SDValue();
}
@@ -47604,6 +47597,30 @@ static SDValue matchPMADDWD_2(SelectionDAG &DAG, SDValue N0, SDValue N1,
PMADDBuilder);
}
+static SDValue combineAddOrSubToHADDorHSUB(SDNode *N, SelectionDAG &DAG,
+ const X86Subtarget &Subtarget) {
+ EVT VT = N->getValueType(0);
+ SDValue Op0 = N->getOperand(0);
+ SDValue Op1 = N->getOperand(1);
+ bool IsAdd = N->getOpcode() == ISD::ADD;
+ assert((IsAdd || N->getOpcode() == ISD::SUB) && "Wrong opcode");
+
+ if ((VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v16i16 ||
+ VT == MVT::v8i32) &&
+ Subtarget.hasSSSE3() &&
+ isHorizontalBinOp(Op0, Op1, DAG, Subtarget, IsAdd)) {
+ auto HOpBuilder = [IsAdd](SelectionDAG &DAG, const SDLoc &DL,
+ ArrayRef<SDValue> Ops) {
+ return DAG.getNode(IsAdd ? X86ISD::HADD : X86ISD::HSUB,
+ DL, Ops[0].getValueType(), Ops);
+ };
+ return SplitOpsAndApply(DAG, Subtarget, SDLoc(N), VT, {Op0, Op1},
+ HOpBuilder);
+ }
+
+ return SDValue();
+}
+
static SDValue combineAdd(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const X86Subtarget &Subtarget) {
@@ -47617,17 +47634,8 @@ static SDValue combineAdd(SDNode *N, SelectionDAG &DAG,
return MAdd;
// Try to synthesize horizontal adds from adds of shuffles.
- if ((VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v16i16 ||
- VT == MVT::v8i32) &&
- Subtarget.hasSSSE3() &&
- isHorizontalBinOp(Op0, Op1, DAG, Subtarget, true)) {
- auto HADDBuilder = [](SelectionDAG &DAG, const SDLoc &DL,
- ArrayRef<SDValue> Ops) {
- return DAG.getNode(X86ISD::HADD, DL, Ops[0].getValueType(), Ops);
- };
- return SplitOpsAndApply(DAG, Subtarget, SDLoc(N), VT, {Op0, Op1},
- HADDBuilder);
- }
+ if (SDValue V = combineAddOrSubToHADDorHSUB(N, DAG, Subtarget))
+ return V;
// If vectors of i1 are legal, turn (add (zext (vXi1 X)), Y) into
// (sub Y, (sext (vXi1 X))).
@@ -47800,18 +47808,8 @@ static SDValue combineSub(SDNode *N, SelectionDAG &DAG,
}
// Try to synthesize horizontal subs from subs of shuffles.
- EVT VT = N->getValueType(0);
- if ((VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v16i16 ||
- VT == MVT::v8i32) &&
- Subtarget.hasSSSE3() &&
- isHorizontalBinOp(Op0, Op1, DAG, Subtarget, false)) {
- auto HSUBBuilder = [](SelectionDAG &DAG, const SDLoc &DL,
- ArrayRef<SDValue> Ops) {
- return DAG.getNode(X86ISD::HSUB, DL, Ops[0].getValueType(), Ops);
- };
- return SplitOpsAndApply(DAG, Subtarget, SDLoc(N), VT, {Op0, Op1},
- HSUBBuilder);
- }
+ if (SDValue V = combineAddOrSubToHADDorHSUB(N, DAG, Subtarget))
+ return V;
// Try to create PSUBUS if SUB's argument is max/min
if (SDValue V = combineSubToSubus(N, DAG, Subtarget))