From aefaf167588b38768b15c57f0f0bfccfb87a399f Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Tue, 12 Oct 2021 08:46:08 -0700 Subject: [PATCH] [TableGen] Fix both sides of '&&' are same The operand of the second any_of in EnforceSmallerThan should be B not S like the FP code in the if below. Unfortunately, fixing that causes an infinite loop in the build of RISCV. So I've added a workaround for that as well. Fixes PR44768. Reviewed By: RKSimon Differential Revision: https://reviews.llvm.org/D111502 --- llvm/utils/TableGen/CodeGenDAGPatterns.cpp | 19 +++++++++++++++---- llvm/utils/TableGen/CodeGenDAGPatterns.h | 7 +++++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp index ebb4a31..2d0694d 100644 --- a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp @@ -451,13 +451,16 @@ static Iter max_if(Iter B, Iter E, Pred P, Less L) { } /// Make sure that for each type in Small, there exists a larger type in Big. -bool TypeInfer::EnforceSmallerThan(TypeSetByHwMode &Small, - TypeSetByHwMode &Big) { +bool TypeInfer::EnforceSmallerThan(TypeSetByHwMode &Small, TypeSetByHwMode &Big, + bool SmallIsVT) { ValidateOnExit _1(Small, *this), _2(Big, *this); if (TP.hasError()) return false; bool Changed = false; + assert((!SmallIsVT || !Small.empty()) && + "Small should not be empty for SDTCisVTSmallerThanOp"); + if (Small.empty()) Changed |= EnforceAny(Small); if (Big.empty()) @@ -476,7 +479,9 @@ bool TypeInfer::EnforceSmallerThan(TypeSetByHwMode &Small, TypeSetByHwMode::SetType &S = Small.get(M); TypeSetByHwMode::SetType &B = Big.get(M); - if (any_of(S, isIntegerOrPtr) && any_of(S, isIntegerOrPtr)) { + assert((!SmallIsVT || !S.empty()) && "Expected non-empty type"); + + if (any_of(S, isIntegerOrPtr) && any_of(B, isIntegerOrPtr)) { auto NotInt = [](MVT VT) { return !isIntegerOrPtr(VT); }; Changed |= berase_if(S, NotInt); Changed |= berase_if(B, NotInt); @@ -484,6 +489,11 @@ bool TypeInfer::EnforceSmallerThan(TypeSetByHwMode &Small, auto NotFP = [](MVT VT) { return !isFloatingPoint(VT); }; Changed |= berase_if(S, NotFP); Changed |= berase_if(B, NotFP); + } else if (SmallIsVT && B.empty()) { + // B is empty and since S is a specific VT, it will never be empty. Don't + // report this as a change, just clear S and continue. This prevents an + // infinite loop. + S.clear(); } else if (S.empty() || B.empty()) { Changed = !S.empty() || !B.empty(); S.clear(); @@ -1637,7 +1647,8 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N, getOperandNum(x.SDTCisVTSmallerThanOp_Info.OtherOperandNum, N, NodeInfo, OResNo); - return TI.EnforceSmallerThan(TypeListTmp, OtherNode->getExtType(OResNo)); + return TI.EnforceSmallerThan(TypeListTmp, OtherNode->getExtType(OResNo), + /*SmallIsVT*/ true); } case SDTCisOpSmallerThanOp: { unsigned BResNo = 0; diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.h b/llvm/utils/TableGen/CodeGenDAGPatterns.h index a69f1e2..39d8123 100644 --- a/llvm/utils/TableGen/CodeGenDAGPatterns.h +++ b/llvm/utils/TableGen/CodeGenDAGPatterns.h @@ -298,8 +298,11 @@ struct TypeInfer { /// unchanged. bool EnforceAny(TypeSetByHwMode &Out); /// Make sure that for each type in \p Small, there exists a larger type - /// in \p Big. - bool EnforceSmallerThan(TypeSetByHwMode &Small, TypeSetByHwMode &Big); + /// in \p Big. \p SmallIsVT indicates that this is being called for + /// SDTCisVTSmallerThanOp. In that case the TypeSetByHwMode is re-created for + /// each call and needs special consideration in how we detect changes. + bool EnforceSmallerThan(TypeSetByHwMode &Small, TypeSetByHwMode &Big, + bool SmallIsVT = false); /// 1. Ensure that for each type T in \p Vec, T is a vector type, and that /// for each type U in \p Elem, U is a scalar type. /// 2. Ensure that for each (scalar) type U in \p Elem, there exists a -- 2.7.4