summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorSimon Pilgrim <llvm-dev@redking.me.uk>2018-02-23 19:58:44 +0000
committerSimon Pilgrim <llvm-dev@redking.me.uk>2018-02-23 19:58:44 +0000
commit425965be0fd7ca9a85d9f305255353d98d4816ab (patch)
treef3d4f70e9f431322f1b364c7cff9e5d875a4f234 /llvm/lib
parent2a639a4c11c54a2b8bd66e6d78846966c9f75d49 (diff)
downloadbcm5719-llvm-425965be0fd7ca9a85d9f305255353d98d4816ab.tar.gz
bcm5719-llvm-425965be0fd7ca9a85d9f305255353d98d4816ab.zip
[X86][SSE] Generalize x > C-1 ? x+-C : 0 --> subus x, C combine for non-uniform constants
llvm-svn: 325944
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp46
1 files changed, 24 insertions, 22 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 5dd5a92674f..d6e36d5122a 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -31886,34 +31886,36 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
SUBUSBuilder);
if (auto *OpRHSBV = dyn_cast<BuildVectorSDNode>(OpRHS))
- if (auto *OpRHSConst = OpRHSBV->getConstantSplatNode()) {
- if (auto *CondRHSBV = dyn_cast<BuildVectorSDNode>(CondRHS))
- if (auto *CondRHSConst = CondRHSBV->getConstantSplatNode())
- // If the RHS is a constant we have to reverse the const
- // canonicalization.
- // x > C-1 ? x+-C : 0 --> subus x, C
- if (CC == ISD::SETUGT && Other->getOpcode() == ISD::ADD &&
- CondRHSConst->getAPIntValue() ==
- (-OpRHSConst->getAPIntValue() - 1))
- return SplitBinaryOpsAndApply(
- DAG, Subtarget, DL, VT, OpLHS,
- DAG.getConstant(-OpRHSConst->getAPIntValue(), DL, VT),
- SUBUSBuilder);
+ if (auto *CondRHSBV = dyn_cast<BuildVectorSDNode>(CondRHS)) {
+ // If the RHS is a constant we have to reverse the const
+ // canonicalization.
+ // x > C-1 ? x+-C : 0 --> subus x, C
+ auto MatchSUBUS = [](ConstantSDNode *Op, ConstantSDNode *Cond) {
+ return Cond->getAPIntValue() == (-Op->getAPIntValue() - 1);
+ };
+ if (CC == ISD::SETUGT && Other->getOpcode() == ISD::ADD &&
+ ISD::matchBinaryPredicate(OpRHS, CondRHS, MatchSUBUS))
+ return SplitBinaryOpsAndApply(
+ DAG, Subtarget, DL, VT, OpLHS,
+ DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT),
+ OpRHS),
+ SUBUSBuilder);
// Another special case: If C was a sign bit, the sub has been
// canonicalized into a xor.
// FIXME: Would it be better to use computeKnownBits to determine
// whether it's safe to decanonicalize the xor?
// x s< 0 ? x^C : 0 --> subus x, C
- if (CC == ISD::SETLT && Other->getOpcode() == ISD::XOR &&
- ISD::isBuildVectorAllZeros(CondRHS.getNode()) &&
- OpRHSConst->getAPIntValue().isSignMask())
- // Note that we have to rebuild the RHS constant here to ensure we
- // don't rely on particular values of undef lanes.
- return SplitBinaryOpsAndApply(
- DAG, Subtarget, DL, VT, OpLHS,
- DAG.getConstant(OpRHSConst->getAPIntValue(), DL, VT),
- SUBUSBuilder);
+ if (auto *OpRHSConst = OpRHSBV->getConstantSplatNode())
+ if (CC == ISD::SETLT && Other.getOpcode() == ISD::XOR &&
+ ISD::isBuildVectorAllZeros(CondRHS.getNode()) &&
+ OpRHSConst->getAPIntValue().isSignMask())
+ // Note that we have to rebuild the RHS constant here to ensure we
+ // don't rely on particular values of undef lanes.
+ return SplitBinaryOpsAndApply(
+ DAG, Subtarget, DL, VT, OpLHS,
+ DAG.getConstant(OpRHSConst->getAPIntValue(), DL, VT),
+ SUBUSBuilder);
}
}
}
OpenPOWER on IntegriCloud