diff options
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 27 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 16 |
2 files changed, 29 insertions, 14 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 24f019d55c9..0f428b72d52 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -7236,21 +7236,24 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) { EVT VT0 = N0.getValueType(); SDLoc DL(N); - // fold (select C, X, X) -> X - if (N1 == N2) - return N1; - - // fold (select, C, X, undef) -> X - if (N2.isUndef()) - return N1; + // select undef, N1, N2 --> N1 (if it's a constant), otherwise N2 + if (N0.isUndef()) + return isa<ConstantSDNode>(N1) ? N1 : N2; + // select, ?, undef, N2 --> N2 if (N1.isUndef()) return N2; + // select, ?, N1, undef --> N1 + if (N2.isUndef()) + 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 true, X, Y) -> X + // fold (select false, X, Y) -> Y + if (auto *N0C = dyn_cast<const ConstantSDNode>(N0)) + return N0C->isNullValue() ? N2 : N1; + + // select ?, N1, N1 --> N1 + if (N1 == N2) + return N1; // fold (select X, X, Y) -> (or X, Y) // fold (select X, 1, Y) -> (or C, Y) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 70958c557f9..45c435a317d 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -5078,12 +5078,24 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT, break; } case ISD::SELECT: + // select undef, N2, N3 --> N2 (if it's a constant), otherwise N3 + if (N1.isUndef()) + return isa<ConstantSDNode>(N2) ? N2 : N3; + // select, ?, undef, N3 --> N3 + if (N2.isUndef()) + return N3; + // select, ?, N2, undef --> N2 + if (N3.isUndef()) + return N2; + // select true, N2, N3 --> N2 // select false, N2, N3 --> N3 if (auto *N1C = dyn_cast<ConstantSDNode>(N1)) - return N1C->getZExtValue() ? N2 : N3; + return N1C->isNullValue() ? N3 : N2; - if (N2 == N3) return N2; // select ?, N2, N2 --> N2 + // select ?, N2, N2 --> N2 + if (N2 == N3) + return N2; break; case ISD::VECTOR_SHUFFLE: llvm_unreachable("should use getVectorShuffle constructor!"); |

