diff options
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index d69e50d9007..a1ce77455e9 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -269,15 +269,24 @@ bool ISD::allOperandsUndef(const SDNode *N) { } bool ISD::matchUnaryPredicate(SDValue Op, - std::function<bool(ConstantSDNode *)> Match) { + std::function<bool(ConstantSDNode *)> Match, + bool AllowUndefs) { + // FIXME: Add support for scalar UNDEF cases? if (auto *Cst = dyn_cast<ConstantSDNode>(Op)) return Match(Cst); + // FIXME: Add support for vector UNDEF cases? if (ISD::BUILD_VECTOR != Op.getOpcode()) return false; EVT SVT = Op.getValueType().getScalarType(); for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i) { + if (AllowUndefs && Op.getOperand(i).isUndef()) { + if (!Match(nullptr)) + return false; + continue; + } + auto *Cst = dyn_cast<ConstantSDNode>(Op.getOperand(i)); if (!Cst || Cst->getValueType(0) != SVT || !Match(Cst)) return false; @@ -6967,11 +6976,11 @@ SDValue SelectionDAG::simplifyShift(SDValue X, SDValue Y) { return X; // shift X, C >= bitwidth(X) --> undef - // All vector elements must be too big to avoid partial undefs. + // All vector elements must be too big (or undef) to avoid partial undefs. auto isShiftTooBig = [X](ConstantSDNode *Val) { - return Val->getAPIntValue().uge(X.getScalarValueSizeInBits()); + return !Val || Val->getAPIntValue().uge(X.getScalarValueSizeInBits()); }; - if (ISD::matchUnaryPredicate(Y, isShiftTooBig)) + if (ISD::matchUnaryPredicate(Y, isShiftTooBig, true)) return getUNDEF(X.getValueType()); return SDValue(); |