diff options
author | Sanjay Patel <spatel@rotateright.com> | 2016-10-07 20:47:51 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2016-10-07 20:47:51 +0000 |
commit | ecaf343fe7dfd4cd5e87ea199941be19b6254e33 (patch) | |
tree | 1c559cd9961d2ab405d337215d39a2eb28765e71 /llvm/lib/CodeGen | |
parent | 6982bb8f25c3df47fc105b877dcb1796ac6a2912 (diff) | |
download | bcm5719-llvm-ecaf343fe7dfd4cd5e87ea199941be19b6254e33.tar.gz bcm5719-llvm-ecaf343fe7dfd4cd5e87ea199941be19b6254e33.zip |
[DAG] move fold (select C, 0, 1 -> xor C, 1) to a helper function; NFC
We're missing at least 3 other similar folds based on what we have in InstCombine.
llvm-svn: 283596
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 47 |
1 files changed, 31 insertions, 16 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index cbcd6ca9d74..3f62f0af9e1 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -334,6 +334,7 @@ namespace { SDValue visitShiftByConstant(SDNode *N, ConstantSDNode *Amt); + SDValue foldSelectOfConstants(SDNode *N); bool SimplifySelectOps(SDNode *SELECT, SDValue LHS, SDValue RHS); SDValue SimplifyBinOpWithSameOpcodeHands(SDNode *N); SDValue SimplifySelect(const SDLoc &DL, SDValue N0, SDValue N1, SDValue N2); @@ -5105,24 +5106,14 @@ static SDValue combineMinNumMaxNum(const SDLoc &DL, EVT VT, SDValue LHS, } } -SDValue DAGCombiner::visitSELECT(SDNode *N) { +// TODO: We should handle other cases of selecting between {-1,0,1} here. +SDValue DAGCombiner::foldSelectOfConstants(SDNode *N) { SDValue N0 = N->getOperand(0); SDValue N1 = N->getOperand(1); SDValue N2 = N->getOperand(2); EVT VT = N->getValueType(0); EVT VT0 = N0.getValueType(); - // fold (select C, X, X) -> X - if (N1 == N2) - return N1; - if (const ConstantSDNode *N0C = dyn_cast<const ConstantSDNode>(N0)) { - // fold (select true, X, Y) -> X - // fold (select false, X, Y) -> Y - return !N0C->isNullValue() ? N1 : N2; - } - // fold (select C, 1, X) -> (or C, X) - if (VT == MVT::i1 && isOneConstant(N1)) - return DAG.getNode(ISD::OR, SDLoc(N), VT, N0, N2); // fold (select C, 0, 1) -> (xor C, 1) // We can't do this reliably if integer based booleans have different contents // to floating point based booleans. This is because we can't tell whether we @@ -5142,17 +5133,41 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) { SDValue XORNode; if (VT == VT0) { SDLoc DL(N); - return DAG.getNode(ISD::XOR, DL, VT0, - N0, DAG.getConstant(1, DL, VT0)); + return DAG.getNode(ISD::XOR, DL, VT0, N0, DAG.getConstant(1, DL, VT0)); } SDLoc DL0(N0); - XORNode = DAG.getNode(ISD::XOR, DL0, VT0, - N0, DAG.getConstant(1, DL0, VT0)); + XORNode = DAG.getNode(ISD::XOR, DL0, VT0, N0, DAG.getConstant(1, DL0, VT0)); AddToWorklist(XORNode.getNode()); if (VT.bitsGT(VT0)) return DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N), VT, XORNode); return DAG.getNode(ISD::TRUNCATE, SDLoc(N), VT, XORNode); } + + return SDValue(); +} + +SDValue DAGCombiner::visitSELECT(SDNode *N) { + SDValue N0 = N->getOperand(0); + SDValue N1 = N->getOperand(1); + SDValue N2 = N->getOperand(2); + EVT VT = N->getValueType(0); + EVT VT0 = N0.getValueType(); + + // fold (select C, X, X) -> X + if (N1 == N2) + return N1; + if (const ConstantSDNode *N0C = dyn_cast<const ConstantSDNode>(N0)) { + // fold (select true, X, Y) -> X + // fold (select false, X, Y) -> Y + return !N0C->isNullValue() ? N1 : N2; + } + // fold (select C, 1, X) -> (or C, X) + if (VT == MVT::i1 && isOneConstant(N1)) + return DAG.getNode(ISD::OR, SDLoc(N), VT, N0, N2); + + if (SDValue V = foldSelectOfConstants(N)) + return V; + // fold (select C, 0, X) -> (and (not C), X) if (VT == VT0 && VT == MVT::i1 && isNullConstant(N1)) { SDValue NOTNode = DAG.getNOT(SDLoc(N0), N0, VT); |