From e6a1187dd867cc0feea4041b22a9bb29aaa3ae48 Mon Sep 17 00:00:00 2001 From: Justin Bogner Date: Wed, 9 Dec 2020 10:33:59 -0800 Subject: [PATCH] Limit the recursion depth of SelectionDAG::isSplatValue() This method previously always recursively checked both the left-hand side and right-hand side of binary operations for splatted (broadcast) vector values to determine if the parent DAG node is a splat. Like several other SelectionDAG methods, limit the recursion depth to MaxRecursionDepth (6). This prevents stack overflow. See also https://issuetracker.google.com/173785481 Patch by Nicolas Capens. Thanks! Differential Revision: https://reviews.llvm.org/D92421 --- llvm/include/llvm/CodeGen/SelectionDAG.h | 3 ++- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 13 ++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h index d73155a..4ec870b 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -1829,7 +1829,8 @@ public: /// for \p DemandedElts. /// /// NOTE: The function will return true for a demanded splat of UNDEF values. - bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts); + bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, + unsigned Depth = 0); /// Test whether \p V has a splatted value. bool isSplatValue(SDValue V, bool AllowUndefs = false); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 4661b0d..83e8637 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2355,13 +2355,16 @@ bool SelectionDAG::MaskedValueIsAllOnes(SDValue V, const APInt &Mask, /// sense to specify which elements are demanded or undefined, therefore /// they are simply ignored. bool SelectionDAG::isSplatValue(SDValue V, const APInt &DemandedElts, - APInt &UndefElts) { + APInt &UndefElts, unsigned Depth) { EVT VT = V.getValueType(); assert(VT.isVector() && "Vector type expected"); if (!VT.isScalableVector() && !DemandedElts) return false; // No demanded elts, better to assume we don't know anything. + if (Depth >= MaxRecursionDepth) + return false; // Limit search depth. + // Deal with some common cases here that work for both fixed and scalable // vector types. switch (V.getOpcode()) { @@ -2376,8 +2379,8 @@ bool SelectionDAG::isSplatValue(SDValue V, const APInt &DemandedElts, APInt UndefLHS, UndefRHS; SDValue LHS = V.getOperand(0); SDValue RHS = V.getOperand(1); - if (isSplatValue(LHS, DemandedElts, UndefLHS) && - isSplatValue(RHS, DemandedElts, UndefRHS)) { + if (isSplatValue(LHS, DemandedElts, UndefLHS, Depth + 1) && + isSplatValue(RHS, DemandedElts, UndefRHS, Depth + 1)) { UndefElts = UndefLHS | UndefRHS; return true; } @@ -2386,7 +2389,7 @@ bool SelectionDAG::isSplatValue(SDValue V, const APInt &DemandedElts, case ISD::TRUNCATE: case ISD::SIGN_EXTEND: case ISD::ZERO_EXTEND: - return isSplatValue(V.getOperand(0), DemandedElts, UndefElts); + return isSplatValue(V.getOperand(0), DemandedElts, UndefElts, Depth + 1); } // We don't support other cases than those above for scalable vectors at @@ -2441,7 +2444,7 @@ bool SelectionDAG::isSplatValue(SDValue V, const APInt &DemandedElts, unsigned NumSrcElts = Src.getValueType().getVectorNumElements(); APInt UndefSrcElts; APInt DemandedSrcElts = DemandedElts.zextOrSelf(NumSrcElts).shl(Idx); - if (isSplatValue(Src, DemandedSrcElts, UndefSrcElts)) { + if (isSplatValue(Src, DemandedSrcElts, UndefSrcElts, Depth + 1)) { UndefElts = UndefSrcElts.extractBits(NumElts, Idx); return true; } -- 2.7.4