diff options
| author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2018-02-23 19:58:44 +0000 |
|---|---|---|
| committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2018-02-23 19:58:44 +0000 |
| commit | 425965be0fd7ca9a85d9f305255353d98d4816ab (patch) | |
| tree | f3d4f70e9f431322f1b364c7cff9e5d875a4f234 /llvm/lib | |
| parent | 2a639a4c11c54a2b8bd66e6d78846966c9f75d49 (diff) | |
| download | bcm5719-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.cpp | 46 |
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); } } } |

