summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2019-06-25 12:49:35 +0000
committerSanjay Patel <spatel@rotateright.com>2019-06-25 12:49:35 +0000
commite4ef62291b46c261e6205e76f869902dcef8e0c0 (patch)
tree4dc8d3cc3891d71ffc5bd70d2d2a51cc84116118 /llvm/lib/CodeGen
parent42f44b387e4d741a2fc909cacc98b6f3d08c8718 (diff)
downloadbcm5719-llvm-e4ef62291b46c261e6205e76f869902dcef8e0c0.tar.gz
bcm5719-llvm-e4ef62291b46c261e6205e76f869902dcef8e0c0.zip
[SDAG] improve expansion of ctpop+setcc
This should not cause any visible change in output, but it's more efficient because we were producing non-canonical 'sub x, 1' and 'setcc ugt x, 0'. As mentioned in the TODO, we should also be handling the inverse predicate. llvm-svn: 364302
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp25
1 files changed, 14 insertions, 11 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index b20c3a937fe..5fd9b469dfa 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -2700,17 +2700,20 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
return DAG.getSetCC(dl, VT, And, DAG.getConstant(0, dl, CTVT), CC);
}
- // (ctpop x) == 1 -> x && (x & x-1) == 0 iff ctpop is illegal.
- if (Cond == ISD::SETEQ && C1 == 1 &&
- !isOperationLegalOrCustom(ISD::CTPOP, CTVT)) {
- SDValue Sub =
- DAG.getNode(ISD::SUB, dl, CTVT, CTOp, DAG.getConstant(1, dl, CTVT));
- SDValue And = DAG.getNode(ISD::AND, dl, CTVT, CTOp, Sub);
- SDValue LHS = DAG.getSetCC(dl, VT, CTOp, DAG.getConstant(0, dl, CTVT),
- ISD::SETUGT);
- SDValue RHS =
- DAG.getSetCC(dl, VT, And, DAG.getConstant(0, dl, CTVT), ISD::SETEQ);
- return DAG.getNode(ISD::AND, dl, VT, LHS, RHS);
+ // If ctpop is not supported, expand a power-of-2 comparison based on it.
+ if (C1 == 1 && !isOperationLegalOrCustom(ISD::CTPOP, CTVT)) {
+ // (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)
}
}
OpenPOWER on IntegriCloud