diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2019-06-25 14:46:52 +0000 |
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2019-06-25 14:46:52 +0000 |
| commit | 685c5cbc654fe6edca15811d1fc2c6b5832027de (patch) | |
| tree | 7da9aca9805145b078fbf5eb1a0b3a5acaa3431c /llvm/lib/CodeGen | |
| parent | f0a665afca70c924e7d582242c01f1835d601a65 (diff) | |
| download | bcm5719-llvm-685c5cbc654fe6edca15811d1fc2c6b5832027de.tar.gz bcm5719-llvm-685c5cbc654fe6edca15811d1fc2c6b5832027de.zip | |
[SDAG] expand ctpop != 1
Change the generic ctpop expansion to more efficiently handle a
check for not-a-power-of-two value:
(ctpop x) != 1 --> (x == 0) || ((x & x-1) != 0)
This is the inverted predicate sibling pattern that was added with:
D63004
This should have been done before I changed IR canonicalization to
favor this form with:
rL364246
...so if this requires revert/changing, the earlier commit may also
need to modified.
llvm-svn: 364319
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index d83bd108b67..74ab96afe5a 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -2715,19 +2715,19 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1, } // If ctpop is not supported, expand a power-of-2 comparison based on it. - if (C1 == 1 && !isOperationLegalOrCustom(ISD::CTPOP, CTVT)) { + if (C1 == 1 && !isOperationLegalOrCustom(ISD::CTPOP, CTVT) && + (Cond == ISD::SETEQ || Cond == ISD::SETNE)) { // (ctpop x) == 1 --> (x != 0) && ((x & x-1) == 0) - if (Cond == ISD::SETEQ) { - SDValue Zero = DAG.getConstant(0, dl, CTVT); - SDValue NegOne = DAG.getAllOnesConstant(dl, CTVT); - SDValue Add = DAG.getNode(ISD::ADD, dl, CTVT, CTOp, NegOne); - SDValue And = DAG.getNode(ISD::AND, dl, CTVT, CTOp, Add); - SDValue LHS = DAG.getSetCC(dl, VT, CTOp, Zero, ISD::SETNE); - SDValue RHS = DAG.getSetCC(dl, VT, And, Zero, ISD::SETEQ); - return DAG.getNode(ISD::AND, dl, VT, LHS, RHS); - } - // TODO: // (ctpop x) != 1 --> (x == 0) || ((x & x-1) != 0) + SDValue Zero = DAG.getConstant(0, dl, CTVT); + SDValue NegOne = DAG.getAllOnesConstant(dl, CTVT); + ISD::CondCode InvCond = ISD::getSetCCInverse(Cond, true); + SDValue Add = DAG.getNode(ISD::ADD, dl, CTVT, CTOp, NegOne); + SDValue And = DAG.getNode(ISD::AND, dl, CTVT, CTOp, Add); + SDValue LHS = DAG.getSetCC(dl, VT, CTOp, Zero, InvCond); + SDValue RHS = DAG.getSetCC(dl, VT, And, Zero, Cond); + unsigned LogicOpcode = Cond == ISD::SETEQ ? ISD::AND : ISD::OR; + return DAG.getNode(LogicOpcode, dl, VT, LHS, RHS); } } |

