diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -646,6 +646,7 @@ bool Sequential = false); const SCEV *getUMinExpr(SmallVectorImpl &Operands, bool Sequential = false); + const SCEV *getSelectExpr(ArrayRef Operands); const SCEV *getUnknown(Value *V); const SCEV *getCouldNotCompute(); @@ -1702,18 +1703,14 @@ const SCEV *createNodeFromSelectLikePHI(PHINode *PN); /// Provide special handling for a select-like instruction (currently this - /// is either a select instruction or a phi node). \p I is the instruction - /// being processed, and it is assumed equivalent to "Cond ? TrueVal : - /// FalseVal". - const SCEV *createNodeForSelectOrPHIInstWithICmpInstCond(Instruction *I, - ICmpInst *Cond, - Value *TrueVal, - Value *FalseVal); - - /// See if we can model this select-like instruction via umin_seq expression. - const SCEV *createNodeForSelectOrPHIViaUMinSeq(Value *I, Value *Cond, - Value *TrueVal, - Value *FalseVal); + /// is either a select instruction or a phi node). \p Ty is the type of the + /// instruction being processed, that is assumed equivalent to + /// "Cond ? TrueVal : FalseVal". + const std::optional + createNonSelectNodeForSelectOrPHIInstWithICmpInstCond(Type *Ty, + ICmpInst *Cond, + Value *TrueVal, + Value *FalseVal); /// Given a value \p V, which is a select-like instruction (currently this is /// either a select instruction or a phi node), which is assumed equivalent to diff --git a/llvm/include/llvm/Analysis/ScalarEvolutionDivision.h b/llvm/include/llvm/Analysis/ScalarEvolutionDivision.h --- a/llvm/include/llvm/Analysis/ScalarEvolutionDivision.h +++ b/llvm/include/llvm/Analysis/ScalarEvolutionDivision.h @@ -43,6 +43,7 @@ void visitSMinExpr(const SCEVSMinExpr *Numerator) {} void visitUMinExpr(const SCEVUMinExpr *Numerator) {} void visitSequentialUMinExpr(const SCEVSequentialUMinExpr *Numerator) {} + void visitSelectExpr(const SCEVSelectExpr *Numerator) {} // FIXME: trivial. void visitUnknown(const SCEVUnknown *Numerator) {} void visitCouldNotCompute(const SCEVCouldNotCompute *Numerator) {} diff --git a/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h b/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h --- a/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ b/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -51,6 +51,7 @@ scUMinExpr, scSMinExpr, scSequentialUMinExpr, + scSelectExpr, scPtrToInt, scUnknown, scCouldNotCompute @@ -553,6 +554,38 @@ } }; +/// This class represents a ternary select expression. +class SCEVSelectExpr : public SCEV { + friend class ScalarEvolution; + + std::array Operands; + + SCEVSelectExpr(const FoldingSetNodeIDRef ID, ArrayRef Ops) + : SCEV(ID, scSelectExpr, computeExpressionSize(Ops)) { + assert(Ops.size() == 3 && "Unexpected operand count!"); + llvm::copy(Ops, Operands.begin()); + } + +public: + const SCEV *getCondition() const { return Operands[0]; } + const SCEV *getTrueValue() const { return Operands[1]; } + const SCEV *getFalseValue() const { return Operands[2]; } + size_t getNumOperands() const { return 3; } + const SCEV *getOperand(unsigned i) const { + assert((i < getNumOperands()) && "Operand index out of range!"); + return Operands[i]; + } + + ArrayRef operands() const { return Operands; } + + Type *getType() const { return getTrueValue()->getType(); } + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static bool classof(const SCEV *S) { + return S->getSCEVType() == scSelectExpr; + } +}; + /// This means that we are dealing with an entirely unknown SCEV /// value, and only represent it as its LLVM Value. This is the /// "bottom" value for the analysis. @@ -631,6 +664,8 @@ case scSequentialUMinExpr: return ((SC *)this) ->visitSequentialUMinExpr((const SCEVSequentialUMinExpr *)S); + case scSelectExpr: + return ((SC *)this)->visitSelectExpr((const SCEVSelectExpr *)S); case scUnknown: return ((SC *)this)->visitUnknown((const SCEVUnknown *)S); case scCouldNotCompute: @@ -687,18 +722,14 @@ case scUMinExpr: case scSequentialUMinExpr: case scAddRecExpr: - for (const auto *Op : cast(S)->operands()) { + case scUDivExpr: + case scSelectExpr: + for (const auto *Op : S->operands()) { push(Op); if (Visitor.isDone()) break; } continue; - case scUDivExpr: { - const SCEVUDivExpr *UDiv = cast(S); - push(UDiv->getLHS()); - push(UDiv->getRHS()); - continue; - } case scCouldNotCompute: llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!"); } @@ -884,6 +915,18 @@ return !Changed ? Expr : SE.getUMinExpr(Operands, /*Sequential=*/true); } + const SCEV *visitSelectExpr(const SCEVSelectExpr *Expr) { + std::array Operands; + bool Changed = false; + for (auto I : zip(Expr->operands(), Operands)) { + const SCEV *Op = std::get<0>(I); + const SCEV *&NewOp = std::get<1>(I); + NewOp = ((SC *)this)->visit(Op); + Changed |= Op != NewOp; + } + return !Changed ? Expr : SE.getSelectExpr(Operands); + } + const SCEV *visitUnknown(const SCEVUnknown *Expr) { return Expr; } const SCEV *visitCouldNotCompute(const SCEVCouldNotCompute *Expr) { diff --git a/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h b/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h --- a/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h +++ b/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h @@ -483,6 +483,8 @@ Value *visitSequentialUMinExpr(const SCEVSequentialUMinExpr *S); + Value *visitSelectExpr(const SCEVSelectExpr *S); + Value *visitUnknown(const SCEVUnknown *S) { return S->getValue(); } void rememberInstruction(Value *I); diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -366,6 +366,17 @@ OS << "(" << *UDiv->getLHS() << " /u " << *UDiv->getRHS() << ")"; return; } + + case scSelectExpr: { + const SCEVSelectExpr *Sel = cast(this); + OS << "(select "; + ListSeparator LS(", "); + for (const SCEV *Op : Sel->operands()) + OS << LS << *Op; + OS << ")"; + return; + } + case scUnknown: { const SCEVUnknown *U = cast(this); Type *AllocTy; @@ -422,6 +433,8 @@ return cast(this)->getType(); case scUDivExpr: return cast(this)->getType(); + case scSelectExpr: + return cast(this)->getType(); case scUnknown: return cast(this)->getType(); case scCouldNotCompute: @@ -451,6 +464,8 @@ return cast(this)->operands(); case scUDivExpr: return cast(this)->operands(); + case scSelectExpr: + return cast(this)->operands(); case scCouldNotCompute: llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!"); } @@ -827,19 +842,24 @@ case scUMaxExpr: case scSMinExpr: case scUMinExpr: - case scSequentialUMinExpr: { - const SCEVNAryExpr *LC = cast(LHS); - const SCEVNAryExpr *RC = cast(RHS); + case scSequentialUMinExpr: + case scSelectExpr: + case scUDivExpr: + case scPtrToInt: + case scTruncate: + case scZeroExtend: + case scSignExtend: { + ArrayRef LOps = LHS->operands(); + ArrayRef ROps = RHS->operands(); - // Lexicographically compare n-ary expressions. - unsigned LNumOps = LC->getNumOperands(), RNumOps = RC->getNumOperands(); + // Lexicographically compare simple n-ary-like expressions. + unsigned LNumOps = LOps.size(), RNumOps = ROps.size(); if (LNumOps != RNumOps) return (int)LNumOps - (int)RNumOps; for (unsigned i = 0; i != LNumOps; ++i) { - auto X = CompareSCEVComplexity(EqCacheSCEV, EqCacheValue, LI, - LC->getOperand(i), RC->getOperand(i), DT, - Depth + 1); + auto X = CompareSCEVComplexity(EqCacheSCEV, EqCacheValue, LI, LOps[i], + ROps[i], DT, Depth + 1); if (X != 0) return X; } @@ -847,38 +867,6 @@ return 0; } - case scUDivExpr: { - const SCEVUDivExpr *LC = cast(LHS); - const SCEVUDivExpr *RC = cast(RHS); - - // Lexicographically compare udiv expressions. - auto X = CompareSCEVComplexity(EqCacheSCEV, EqCacheValue, LI, LC->getLHS(), - RC->getLHS(), DT, Depth + 1); - if (X != 0) - return X; - X = CompareSCEVComplexity(EqCacheSCEV, EqCacheValue, LI, LC->getRHS(), - RC->getRHS(), DT, Depth + 1); - if (X == 0) - EqCacheSCEV.unionSets(LHS, RHS); - return X; - } - - case scPtrToInt: - case scTruncate: - case scZeroExtend: - case scSignExtend: { - const SCEVCastExpr *LC = cast(LHS); - const SCEVCastExpr *RC = cast(RHS); - - // Compare cast expressions by operand. - auto X = - CompareSCEVComplexity(EqCacheSCEV, EqCacheValue, LI, LC->getOperand(), - RC->getOperand(), DT, Depth + 1); - if (X == 0) - EqCacheSCEV.unionSets(LHS, RHS); - return X; - } - case scCouldNotCompute: llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!"); } @@ -4129,6 +4117,8 @@ return visitAnyMinMaxExpr(Expr); } + RetVal visitSelectExpr(const SCEVSelectExpr *Expr) { return Expr; } + RetVal visitUnknown(const SCEVUnknown *Expr) { return Expr; } RetVal visitCouldNotCompute(const SCEVCouldNotCompute *Expr) { return Expr; } @@ -4279,6 +4269,8 @@ } } + // FIXME: for i1-typed sequential min/max's, canonicalize to select. + // Okay, it looks like we really DO need an expr. Check to see if we // already have one, otherwise create a new one. FoldingSetNodeID ID; @@ -4340,6 +4332,50 @@ : getMinMaxExpr(scUMinExpr, Ops); } +const SCEV *ScalarEvolution::getSelectExpr(ArrayRef Ops) { + static constexpr SCEVTypes Kind = scSelectExpr; + + assert(Ops.size() == 3 && "Unexpected operand count to the select!"); + assert(Ops[0]->getType()->isIntegerTy(1) && "First operand must be bool!"); + assert(Ops[1]->getType()->isPointerTy() == Ops[2]->getType()->isPointerTy() && + getEffectiveSCEVType(Ops[1]->getType()) == + getEffectiveSCEVType(Ops[2]->getType()) && + "Types of select's hands do not match!"); + + // Check if we have created the same expression before. + if (const SCEV *S = findExistingSCEVInCache(Kind, Ops)) + return S; + + // FIXME: perform simplifications. + // FIXME: perform `createNonSelectNodeForSelectOrPHIInstWithICmpInstCond()` + // here? + + // If both hands of select are identical, just return one of them. + if (Ops[1] == Ops[2]) + return Ops[1]; + + // Have we succeeded in constant-folding the condition? + if (auto *CondConst = dyn_cast(Ops[0])) + return CondConst->isOne() ? Ops[1] : Ops[2]; + + // Okay, it looks like we really DO need an expr. Check to see if we + // already have one, otherwise create a new one. + FoldingSetNodeID ID; + ID.AddInteger(Kind); + for (const SCEV *Op : Ops) + ID.AddPointer(Op); + void *IP = nullptr; + const SCEV *ExistingSCEV = UniqueSCEVs.FindNodeOrInsertPos(ID, IP); + if (ExistingSCEV) + return ExistingSCEV; + + SCEV *S = new (SCEVAllocator) SCEVSelectExpr(ID.Intern(SCEVAllocator), Ops); + + UniqueSCEVs.InsertNode(S, IP); + registerUser(S, Ops); + return S; +} + const SCEV * ScalarEvolution::getSizeOfScalableVectorExpr(Type *IntTy, ScalableVectorType *ScalableTy) { @@ -5933,6 +5969,7 @@ case scUMinExpr: case scSMinExpr: case scSequentialUMinExpr: + case scSelectExpr: // These expressions are available if their operand(s) is/are. return true; @@ -6103,8 +6140,10 @@ return FC.Found; } -const SCEV *ScalarEvolution::createNodeForSelectOrPHIInstWithICmpInstCond( - Instruction *I, ICmpInst *Cond, Value *TrueVal, Value *FalseVal) { +// FIXME: this should be done in `ScalarEvolution::getSelectExpr()`. +const std::optional +ScalarEvolution::createNonSelectNodeForSelectOrPHIInstWithICmpInstCond( + Type *Ty, ICmpInst *Cond, Value *TrueVal, Value *FalseVal) { // Try to match some simple smax or umax patterns. auto *ICI = Cond; @@ -6124,7 +6163,7 @@ case ICmpInst::ICMP_UGE: // a > b ? a+x : b+x -> max(a, b)+x // a > b ? b+x : a+x -> min(a, b)+x - if (getTypeSizeInBits(LHS->getType()) <= getTypeSizeInBits(I->getType())) { + if (getTypeSizeInBits(LHS->getType()) <= getTypeSizeInBits(Ty)) { bool Signed = ICI->isSigned(); const SCEV *LA = getSCEV(TrueVal); const SCEV *RA = getSCEV(FalseVal); @@ -6146,9 +6185,9 @@ return Op; } if (Signed) - Op = getNoopOrSignExtend(Op, I->getType()); + Op = getNoopOrSignExtend(Op, Ty); else - Op = getNoopOrZeroExtend(Op, I->getType()); + Op = getNoopOrZeroExtend(Op, Ty); return Op; }; LS = CoerceOperand(LS); @@ -6173,9 +6212,9 @@ [[fallthrough]]; case ICmpInst::ICMP_EQ: // x == 0 ? C+y : x+y -> umax(x, C)+y iff C u<= 1 - if (getTypeSizeInBits(LHS->getType()) <= getTypeSizeInBits(I->getType()) && + if (getTypeSizeInBits(LHS->getType()) <= getTypeSizeInBits(Ty) && isa(RHS) && cast(RHS)->isZero()) { - const SCEV *X = getNoopOrZeroExtend(getSCEV(LHS), I->getType()); + const SCEV *X = getNoopOrZeroExtend(getSCEV(LHS), Ty); const SCEV *TrueValExpr = getSCEV(TrueVal); // C+y const SCEV *FalseValExpr = getSCEV(FalseVal); // x+y const SCEV *Y = getMinusSCEV(FalseValExpr, X); // y = (x+y)-x @@ -6192,10 +6231,10 @@ const SCEV *X = getSCEV(LHS); while (auto *ZExt = dyn_cast(X)) X = ZExt->getOperand(); - if (getTypeSizeInBits(X->getType()) <= getTypeSizeInBits(I->getType())) { + if (getTypeSizeInBits(X->getType()) <= getTypeSizeInBits(Ty)) { const SCEV *FalseValExpr = getSCEV(FalseVal); if (SCEVMinMaxExprContains(FalseValExpr, X, scSequentialUMinExpr)) - return getUMinExpr(getNoopOrZeroExtend(X, I->getType()), FalseValExpr, + return getUMinExpr(getNoopOrZeroExtend(X, Ty), FalseValExpr, /*Sequential=*/true); } } @@ -6204,70 +6243,7 @@ break; } - return getUnknown(I); -} - -static std::optional -createNodeForSelectViaUMinSeq(ScalarEvolution *SE, const SCEV *CondExpr, - const SCEV *TrueExpr, const SCEV *FalseExpr) { - assert(CondExpr->getType()->isIntegerTy(1) && - TrueExpr->getType() == FalseExpr->getType() && - TrueExpr->getType()->isIntegerTy(1) && - "Unexpected operands of a select."); - - // i1 cond ? i1 x : i1 C --> C + (i1 cond ? (i1 x - i1 C) : i1 0) - // --> C + (umin_seq cond, x - C) - // - // i1 cond ? i1 C : i1 x --> C + (i1 cond ? i1 0 : (i1 x - i1 C)) - // --> C + (i1 ~cond ? (i1 x - i1 C) : i1 0) - // --> C + (umin_seq ~cond, x - C) - - // FIXME: while we can't legally model the case where both of the hands - // are fully variable, we only require that the *difference* is constant. - if (!isa(TrueExpr) && !isa(FalseExpr)) - return std::nullopt; - - const SCEV *X, *C; - if (isa(TrueExpr)) { - CondExpr = SE->getNotSCEV(CondExpr); - X = FalseExpr; - C = TrueExpr; - } else { - X = TrueExpr; - C = FalseExpr; - } - return SE->getAddExpr(C, SE->getUMinExpr(CondExpr, SE->getMinusSCEV(X, C), - /*Sequential=*/true)); -} - -static std::optional -createNodeForSelectViaUMinSeq(ScalarEvolution *SE, Value *Cond, Value *TrueVal, - Value *FalseVal) { - if (!isa(TrueVal) && !isa(FalseVal)) - return std::nullopt; - - const auto *SECond = SE->getSCEV(Cond); - const auto *SETrue = SE->getSCEV(TrueVal); - const auto *SEFalse = SE->getSCEV(FalseVal); - return createNodeForSelectViaUMinSeq(SE, SECond, SETrue, SEFalse); -} - -const SCEV *ScalarEvolution::createNodeForSelectOrPHIViaUMinSeq( - Value *V, Value *Cond, Value *TrueVal, Value *FalseVal) { - assert(Cond->getType()->isIntegerTy(1) && "Select condition is not an i1?"); - assert(TrueVal->getType() == FalseVal->getType() && - V->getType() == TrueVal->getType() && - "Types of select hands and of the result must match."); - - // For now, only deal with i1-typed `select`s. - if (!V->getType()->isIntegerTy(1)) - return getUnknown(V); - - if (std::optional S = - createNodeForSelectViaUMinSeq(this, Cond, TrueVal, FalseVal)) - return *S; - - return getUnknown(V); + return std::nullopt; } const SCEV *ScalarEvolution::createNodeForSelectOrPHI(Value *V, Value *Cond, @@ -6280,14 +6256,14 @@ if (auto *I = dyn_cast(V)) { if (auto *ICI = dyn_cast(Cond)) { - const SCEV *S = createNodeForSelectOrPHIInstWithICmpInstCond( - I, ICI, TrueVal, FalseVal); - if (!isa(S)) - return S; + if (std::optional S = + createNonSelectNodeForSelectOrPHIInstWithICmpInstCond( + I->getType(), ICI, TrueVal, FalseVal)) + return *S; } } - return createNodeForSelectOrPHIViaUMinSeq(V, Cond, TrueVal, FalseVal); + return getSelectExpr({getSCEV(Cond), getSCEV(TrueVal), getSCEV(FalseVal)}); } /// Expand GEP instructions into add and multiply operations. This allows them @@ -6774,6 +6750,14 @@ return setRange(S, SignHint, ConservativeResult.intersectWith(X, RangeType)); } + case scSelectExpr: { + const SCEVSelectExpr *Sel = cast(S); + ConstantRange T = getRangeRef(Sel->getTrueValue(), SignHint, Depth + 1); + ConstantRange F = getRangeRef(Sel->getFalseValue(), SignHint, Depth + 1); + return setRange( + Sel, SignHint, + ConservativeResult.intersectWith(T.unionWith(F), RangeType)); + } case scUnknown: { const SCEVUnknown *U = cast(S); @@ -7035,7 +7019,7 @@ // == RangeOf({A,+,P}) union RangeOf({B,+,Q}) struct SelectPattern { - Value *Condition = nullptr; + const SCEV *Condition = nullptr; APInt TrueValue; APInt FalseValue; @@ -7066,17 +7050,20 @@ using namespace llvm::PatternMatch; - auto *SU = dyn_cast(S); - const APInt *TrueVal, *FalseVal; - if (!SU || - !match(SU->getValue(), m_Select(m_Value(Condition), m_APInt(TrueVal), - m_APInt(FalseVal)))) { + auto *SelExpr = dyn_cast(S); + const SCEVConstant *TrueConst = nullptr, *FalseConst = nullptr; + if (SelExpr) { + Condition = SelExpr->getCondition(); + TrueConst = dyn_cast(SelExpr->getTrueValue()); + FalseConst = dyn_cast(SelExpr->getFalseValue()); + } + if (!TrueConst || !FalseConst) { Condition = nullptr; return; } - TrueValue = *TrueVal; - FalseValue = *FalseVal; + TrueValue = TrueConst->getAPInt(); + FalseValue = FalseConst->getAPInt(); // Re-apply the cast we peeled off earlier if (CastOp) @@ -9797,6 +9784,17 @@ } return C; } + case scSelectExpr: { + const SCEVSelectExpr *S = cast(V); + std::array CstOps; + for (auto I : zip(S->operands(), CstOps)) { + Constant *&CstOp = std::get<1>(I); + CstOp = BuildConstantFromSCEV(std::get<0>(I)); + if (!CstOp) + return nullptr; + } + return ConstantExpr::getSelect(CstOps[0], CstOps[1], CstOps[2]); + } case scUDivExpr: case scSMaxExpr: case scUMaxExpr: @@ -9883,37 +9881,40 @@ case scSMaxExpr: case scUMinExpr: case scSMinExpr: - case scSequentialUMinExpr: { - const auto *Comm = cast(V); + case scSequentialUMinExpr: + case scSelectExpr: { + ArrayRef Ops = V->operands(); // Avoid performing the look-up in the common case where the specified // expression has no loop-variant portions. - for (unsigned i = 0, e = Comm->getNumOperands(); i != e; ++i) { - const SCEV *OpAtScope = getSCEVAtScope(Comm->getOperand(i), L); - if (OpAtScope != Comm->getOperand(i)) { + for (unsigned i = 0, e = Ops.size(); i != e; ++i) { + const SCEV *OpAtScope = getSCEVAtScope(Ops[i], L); + if (OpAtScope != Ops[i]) { // Okay, at least one of these operands is loop variant but might be // foldable. Build a new instance of the folded commutative expression. SmallVector NewOps; - NewOps.reserve(Comm->getNumOperands()); - append_range(NewOps, Comm->operands().take_front(i)); + NewOps.reserve(Ops.size()); + append_range(NewOps, V->operands().take_front(i)); NewOps.push_back(OpAtScope); for (++i; i != e; ++i) { - OpAtScope = getSCEVAtScope(Comm->getOperand(i), L); + OpAtScope = getSCEVAtScope(Ops[i], L); NewOps.push_back(OpAtScope); } - if (isa(Comm)) - return getAddExpr(NewOps, Comm->getNoWrapFlags()); - if (isa(Comm)) - return getMulExpr(NewOps, Comm->getNoWrapFlags()); - if (isa(Comm)) - return getMinMaxExpr(Comm->getSCEVType(), NewOps); - if (isa(Comm)) - return getSequentialMinMaxExpr(Comm->getSCEVType(), NewOps); - llvm_unreachable("Unknown commutative / sequential min/max SCEV type!"); + if (isa(V)) + return getAddExpr(NewOps, cast(V)->getNoWrapFlags()); + if (isa(V)) + return getMulExpr(NewOps, cast(V)->getNoWrapFlags()); + if (isa(V)) + return getMinMaxExpr(V->getSCEVType(), NewOps); + if (isa(V)) + return getSequentialMinMaxExpr(V->getSCEVType(), NewOps); + if (isa(V)) + return getSelectExpr(NewOps); + llvm_unreachable("Unknown SCEV type!"); } } // If we got here, all operands are loop invariant. - return Comm; + return V; } case scUnknown: { // If this instruction is evolved from a constant-evolving PHI, compute the @@ -13731,9 +13732,11 @@ case scSMaxExpr: case scUMinExpr: case scSMinExpr: - case scSequentialUMinExpr: { + case scSequentialUMinExpr: + case scUDivExpr: + case scSelectExpr: { bool HasVarying = false; - for (const auto *Op : cast(S)->operands()) { + for (const auto *Op : S->operands()) { LoopDisposition D = getLoopDisposition(Op, L); if (D == LoopVariant) return LoopVariant; @@ -13742,17 +13745,6 @@ } return HasVarying ? LoopComputable : LoopInvariant; } - case scUDivExpr: { - const SCEVUDivExpr *UDiv = cast(S); - LoopDisposition LD = getLoopDisposition(UDiv->getLHS(), L); - if (LD == LoopVariant) - return LoopVariant; - LoopDisposition RD = getLoopDisposition(UDiv->getRHS(), L); - if (RD == LoopVariant) - return LoopVariant; - return (LD == LoopInvariant && RD == LoopInvariant) ? - LoopInvariant : LoopComputable; - } case scUnknown: // All non-instruction values are loop invariant. All instructions are loop // invariant if they are not contained in the specified loop. @@ -13822,11 +13814,12 @@ case scSMaxExpr: case scUMinExpr: case scSMinExpr: - case scSequentialUMinExpr: { - const SCEVNAryExpr *NAry = cast(S); + case scSequentialUMinExpr: + case scUDivExpr: + case scSelectExpr: { bool Proper = true; - for (const SCEV *NAryOp : NAry->operands()) { - BlockDisposition D = getBlockDisposition(NAryOp, BB); + for (const SCEV *SOp : S->operands()) { + BlockDisposition D = getBlockDisposition(SOp, BB); if (D == DoesNotDominateBlock) return DoesNotDominateBlock; if (D == DominatesBlock) @@ -13834,18 +13827,6 @@ } return Proper ? ProperlyDominatesBlock : DominatesBlock; } - case scUDivExpr: { - const SCEVUDivExpr *UDiv = cast(S); - const SCEV *LHS = UDiv->getLHS(), *RHS = UDiv->getRHS(); - BlockDisposition LD = getBlockDisposition(LHS, BB); - if (LD == DoesNotDominateBlock) - return DoesNotDominateBlock; - BlockDisposition RD = getBlockDisposition(RHS, BB); - if (RD == DoesNotDominateBlock) - return DoesNotDominateBlock; - return (LD == ProperlyDominatesBlock && RD == ProperlyDominatesBlock) ? - ProperlyDominatesBlock : DominatesBlock; - } case scUnknown: if (Instruction *I = dyn_cast(cast(S)->getValue())) { diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp --- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp +++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp @@ -689,27 +689,22 @@ const Loop *Result = getRelevantLoop(C->getOperand()); return RelevantLoops[C] = Result; } - case scUDivExpr: { - const SCEVUDivExpr *D = cast(S); - const Loop *Result = PickMostRelevantLoop( - getRelevantLoop(D->getLHS()), getRelevantLoop(D->getRHS()), SE.DT); - return RelevantLoops[D] = Result; - } case scAddExpr: case scMulExpr: + case scUDivExpr: case scAddRecExpr: case scUMaxExpr: case scSMaxExpr: case scUMinExpr: case scSMinExpr: - case scSequentialUMinExpr: { - const SCEVNAryExpr *N = cast(S); + case scSequentialUMinExpr: + case scSelectExpr: { const Loop *L = nullptr; if (const SCEVAddRecExpr *AR = dyn_cast(S)) L = AR->getLoop(); - for (const SCEV *Op : N->operands()) + for (const SCEV *Op : S->operands()) L = PickMostRelevantLoop(L, getRelevantLoop(Op), SE.DT); - return RelevantLoops[N] = L; + return RelevantLoops[S] = L; } case scUnknown: { const SCEVUnknown *U = cast(S); @@ -1754,6 +1749,13 @@ return expandMinMaxExpr(S, Intrinsic::umin, "umin", /*IsSequential*/true); } +Value *SCEVExpander::visitSelectExpr(const SCEVSelectExpr *S) { + std::array Vals; + for (auto I : zip(S->operands(), Vals)) + std::get<1>(I) = expand(std::get<0>(I)); + return Builder.CreateSelect(Vals[0], Vals[1], Vals[2]); +} + Value *SCEVExpander::expandCodeForImpl(const SCEV *SH, Type *Ty, Instruction *IP) { setInsertPoint(IP); @@ -2123,7 +2125,7 @@ auto CmpSelCost = [&](unsigned Opcode, unsigned NumRequired, unsigned MinIdx, unsigned MaxIdx) -> InstructionCost { Operations.emplace_back(Opcode, MinIdx, MaxIdx); - Type *OpType = S->getOperand(0)->getType(); + Type *OpType = S->getType(); return NumRequired * TTI.getCmpSelInstrCost( Opcode, OpType, CmpInst::makeCmpResultType(OpType), CmpInst::BAD_ICMP_PREDICATE, CostKind); @@ -2230,6 +2232,9 @@ Cost += MulCost * (PolyDegree - 1); break; } + case scSelectExpr: + Cost += CmpSelCost(Instruction::Select, 1, 0, 2); + break; } for (auto &CostOp : Operations) { @@ -2329,6 +2334,11 @@ WorkItem, TTI, CostKind, Worklist); return Cost > Budget; } + case scSelectExpr: { + Cost += costAndCollectOperands(WorkItem, TTI, CostKind, + Worklist); + return Cost > Budget; + } } llvm_unreachable("Unknown SCEV kind!"); } diff --git a/llvm/test/Analysis/ScalarEvolution/becount-invalidation.ll b/llvm/test/Analysis/ScalarEvolution/becount-invalidation.ll --- a/llvm/test/Analysis/ScalarEvolution/becount-invalidation.ll +++ b/llvm/test/Analysis/ScalarEvolution/becount-invalidation.ll @@ -25,7 +25,7 @@ ; CHECK-NEXT: %iv.next = add i64 %iv, 1 ; CHECK-NEXT: --> {1,+,1}<%loop2.header> U: [1,2) S: [1,2) Exits: <> LoopDispositions: { %loop2.header: Computable, %loop.header: Variant } ; CHECK-NEXT: %ptr2.next = phi ptr [ %ptr1, %if ], [ %arg, %else ] -; CHECK-NEXT: --> %ptr2.next U: full-set S: full-set Exits: <> LoopDispositions: { %loop.header: Variant, %loop2.header: Invariant } +; CHECK-NEXT: --> (select %cmp2, %ptr1, %arg) U: full-set S: full-set Exits: <> LoopDispositions: { %loop.header: Variant, %loop2.header: Invariant } ; CHECK-NEXT: Determining loop execution counts for: @test ; CHECK-NEXT: Loop %loop2.header: Unpredictable backedge-taken count. ; CHECK-NEXT: exit count for loop2.header: ***COULDNOTCOMPUTE*** diff --git a/llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll b/llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll --- a/llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll +++ b/llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll @@ -9,7 +9,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_2ops ; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -39,7 +39,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 true, i1 %cond_p1 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, true, %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_2ops ; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -69,9 +69,9 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m umin_seq %k)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond_p3 = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond = select i1 %cond_p3, i1 %cond_p2, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1 umin_seq %cond_p2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select (select %cond_p0, %cond_p1, false), %cond_p2, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_3ops ; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq %m umin_seq %k) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -103,9 +103,9 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m umin_seq %k)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond_p3 = select i1 %cond_p0, i1 true, i1 %cond_p1 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, true, %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond = select i1 %cond_p3, i1 true, i1 %cond_p2 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1) umin_seq (true + %cond_p2))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select (select %cond_p0, true, %cond_p1), true, %cond_p2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_3ops ; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq %m umin_seq %k) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -137,11 +137,11 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m umin_seq %k)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond_p4 = select i1 %cond_p0, i1 true, i1 %cond_p1 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, true, %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond_p5 = select i1 %cond_p4, i1 true, i1 %cond_p2 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq ((true + %cond_p1) umin (true + %cond_p2)))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select (select %cond_p0, true, %cond_p1), true, %cond_p2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond = select i1 %cond_p5, i1 true, i1 %cond_p3 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq ((true + %cond_p1) umin (true + %cond_p2)) umin_seq (true + %cond_p3))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select (select (select %cond_p0, true, %cond_p1), true, %cond_p2), true, %cond_p3) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_3ops_duplicate ; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq %m umin_seq %k) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -177,9 +177,9 @@ ; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %n, i32 %m) ; CHECK-NEXT: --> (%n umin %m) U: full-set S: full-set Exits: (%n umin %m) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %cond_p3 = select i1 %cond_p0, i1 true, i1 %cond_p1 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, true, %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond = select i1 %cond_p3, i1 true, i1 %cond_p2 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1) umin_seq (true + %cond_p2))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select (select %cond_p0, true, %cond_p1), true, %cond_p2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_3ops_redundant_uminseq_operand ; CHECK-NEXT: Loop %loop: backedge-taken count is ((%n umin %m) umin_seq %k) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -214,9 +214,9 @@ ; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %n, i32 %m) ; CHECK-NEXT: --> (%n umin %m) U: full-set S: full-set Exits: (%n umin %m) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %cond_p3 = select i1 %cond_p0, i1 true, i1 %cond_p1 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, true, %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond = select i1 %cond_p3, i1 true, i1 %cond_p2 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1) umin_seq (true + %cond_p2))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select (select %cond_p0, true, %cond_p1), true, %cond_p2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_3ops_redundant_umin_operand ; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq %k umin_seq %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -253,9 +253,9 @@ ; CHECK-NEXT: %umin2 = call i32 @llvm.umin.i32(i32 %n, i32 %q) ; CHECK-NEXT: --> (%n umin %q) U: full-set S: full-set Exits: (%n umin %q) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %cond_p3 = select i1 %cond_p0, i1 true, i1 %cond_p1 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, true, %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond = select i1 %cond_p3, i1 true, i1 %cond_p2 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1) umin_seq (true + %cond_p2))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select (select %cond_p0, true, %cond_p1), true, %cond_p2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_4ops_redundant_operand_across_umins ; CHECK-NEXT: Loop %loop: backedge-taken count is ((%n umin %m) umin_seq %k umin_seq %q) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -293,9 +293,9 @@ ; CHECK-NEXT: %umin2 = call i32 @llvm.umin.i32(i32 %n, i32 %k) ; CHECK-NEXT: --> (%n umin %k) U: full-set S: full-set Exits: (%n umin %k) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %cond_p3 = select i1 %cond_p0, i1 true, i1 %cond_p1 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, true, %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond = select i1 %cond_p3, i1 true, i1 %cond_p2 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1) umin_seq (true + %cond_p2))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select (select %cond_p0, true, %cond_p1), true, %cond_p2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_3ops_operand_wise_redundant_umin ; CHECK-NEXT: Loop %loop: backedge-taken count is ((%n umin %m) umin_seq %k) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -333,7 +333,7 @@ ; CHECK-NEXT: %umin2 = call i32 @llvm.umin.i32(i32 %umin, i32 %k) ; CHECK-NEXT: --> (%n umin %m umin %k) U: full-set S: full-set Exits: (%n umin %m umin %k) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 true, i1 %cond_p1 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, true, %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_3ops_partially_redundant_umin ; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq (%m umin %k)) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -365,9 +365,9 @@ ; CHECK-NEXT: %first.i.next = add i32 %first.i, 1 ; CHECK-NEXT: --> {1,+,1}<%first.loop> U: full-set S: full-set Exits: (1 + (%e umin_seq %d umin_seq %a)) LoopDispositions: { %first.loop: Computable } ; CHECK-NEXT: %cond_p3 = select i1 %cond_p0, i1 true, i1 %cond_p1 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %first.loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, true, %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %first.loop: Variant } ; CHECK-NEXT: %cond_p4 = select i1 %cond_p3, i1 true, i1 %cond_p2 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1) umin_seq (true + %cond_p2))) U: full-set S: full-set Exits: <> LoopDispositions: { %first.loop: Variant } +; CHECK-NEXT: --> (select (select %cond_p0, true, %cond_p1), true, %cond_p2) U: full-set S: full-set Exits: <> LoopDispositions: { %first.loop: Variant } ; CHECK-NEXT: %i = phi i32 [ 0, %first.loop.exit ], [ %i.next, %loop ] ; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%a umin_seq %b umin_seq ((%e umin_seq %d) umin %c)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 @@ -377,9 +377,9 @@ ; CHECK-NEXT: %umin2 = call i32 @llvm.umin.i32(i32 %umin, i32 %first.i) ; CHECK-NEXT: --> ({0,+,1}<%first.loop> umin %c umin %d) U: full-set S: full-set --> ((%e umin_seq %d umin_seq %a) umin %c umin %d) U: full-set S: full-set Exits: ((%e umin_seq %d umin_seq %a) umin %c umin %d) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %cond_p8 = select i1 %cond_p5, i1 true, i1 %cond_p6 -; CHECK-NEXT: --> (true + ((true + %cond_p5) umin_seq (true + %cond_p6))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p5, true, %cond_p6) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond = select i1 %cond_p8, i1 true, i1 %cond_p7 -; CHECK-NEXT: --> (true + ((true + %cond_p5) umin_seq (true + %cond_p6) umin_seq (true + %cond_p7))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select (select %cond_p5, true, %cond_p6), true, %cond_p7) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_5ops_redundant_opearand_of_inner_uminseq ; CHECK-NEXT: Loop %loop: backedge-taken count is (%a umin_seq %b umin_seq ((%e umin_seq %d) umin %c)) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -432,7 +432,7 @@ ; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %n, i32 42) ; CHECK-NEXT: --> (42 umin %n) U: [0,43) S: [0,43) Exits: (42 umin %n) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %cond = select i1 %cond_p1, i1 true, i1 %cond_p0 -; CHECK-NEXT: --> (true + ((true + %cond_p1) umin (true + %cond_p0))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p1, true, %cond_p0) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_2ops_and_constant ; CHECK-NEXT: Loop %loop: backedge-taken count is (42 umin %n) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 42 @@ -463,7 +463,7 @@ ; CHECK-NEXT: %e.1 = phi i32 [ %inc3, %for.body ], [ %d.0, %for.cond.preheader ] ; CHECK-NEXT: --> {%d.0,+,1}<%for.cond> U: full-set S: full-set Exits: 0 LoopDispositions: { %for.cond: Computable, %while.cond: Variant } ; CHECK-NEXT: %0 = select i1 %tobool1, i1 %tobool2, i1 false -; CHECK-NEXT: --> (%tobool1 umin_seq %tobool2) U: full-set S: full-set Exits: false LoopDispositions: { %for.cond: Variant, %while.cond: Variant } +; CHECK-NEXT: --> (select %tobool1, %tobool2, false) U: full-set S: full-set Exits: false LoopDispositions: { %for.cond: Variant, %while.cond: Variant } ; CHECK-NEXT: %inc = add nsw i32 %d.1, 1 ; CHECK-NEXT: --> {(1 + %d.0),+,1}<%for.cond> U: full-set S: full-set Exits: 1 LoopDispositions: { %for.cond: Computable, %while.cond: Variant } ; CHECK-NEXT: %inc3 = add nsw i32 %e.1, 1 @@ -536,7 +536,7 @@ ; CHECK-NEXT: %i.next = add i64 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %ptr.int = ptrtoint ptr %ptr to i64 ; CHECK-NEXT: --> (ptrtoint ptr %ptr to i64) U: full-set S: full-set ; CHECK-NEXT: %r = add i64 %i, %ptr.int @@ -574,7 +574,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((1 + %n) umin %n)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison1 ; CHECK-NEXT: Loop %loop: backedge-taken count is ((1 + %n) umin %n) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -607,7 +607,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((1 + %n) umin %n)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p1 umin %cond_p0) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison2 ; CHECK-NEXT: Loop %loop: backedge-taken count is ((1 + %n) umin %n) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -640,7 +640,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n + %m) umin %n)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p1 umin %cond_p0) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison3 ; CHECK-NEXT: Loop %loop: backedge-taken count is ((%n + %m) umin %n) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -673,7 +673,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq (%n + %m))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison_wrong_direction ; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq (%n + %m)) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -704,7 +704,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison_noundef ; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -734,7 +734,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%m umin_seq %n)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison_noundef_wrong_direction ; CHECK-NEXT: Loop %loop: backedge-taken count is (%m umin_seq %n) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -768,7 +768,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n + %m) umin (1 + %n + %m))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison_complex1 ; CHECK-NEXT: Loop %loop: backedge-taken count is ((%n + %m) umin (1 + %n + %m)) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -804,7 +804,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n + %m) umin (%n + %m + %l))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison_complex2 ; CHECK-NEXT: Loop %loop: backedge-taken count is ((%n + %m) umin (%n + %m + %l)) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -840,7 +840,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n + %m) umin_seq (%n + %m + %l))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison_complex_wrong_direction ; CHECK-NEXT: Loop %loop: backedge-taken count is ((%n + %m) umin_seq (%n + %m + %l)) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -874,9 +874,9 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (((1 + %n) umin %n) umin_seq %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond2 = select i1 %cond, i1 %cond_p2, i1 false -; CHECK-NEXT: --> ((%cond_p0 umin %cond_p1) umin_seq %cond_p2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select (select %cond_p0, %cond_p1, false), %cond_p2, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_multiple_ops ; CHECK-NEXT: Loop %loop: backedge-taken count is (((1 + %n) umin %n) umin_seq %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -911,9 +911,9 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq ((1 + %n) umin %m))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond2 = select i1 %cond, i1 %cond_p2, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq (%cond_p1 umin %cond_p2)) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select (select %cond_p0, %cond_p1, false), %cond_p2, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_multiple_ops2 ; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq ((1 + %n) umin %m)) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -948,9 +948,9 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%m umin_seq ((1 + %n) umin %n))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond2 = select i1 %cond, i1 %cond_p2, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1 umin_seq %cond_p2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select (select %cond_p0, %cond_p1, false), %cond_p2, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_multiple_ops3 ; CHECK-NEXT: Loop %loop: backedge-taken count is (%m umin_seq ((1 + %n) umin %n)) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -987,7 +987,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,65538) S: [1,65538) Exits: (1 + ((1 + (zext i16 %n to i32)) umin %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_not_zero ; CHECK-NEXT: Loop %loop: backedge-taken count is ((1 + (zext i16 %n to i32)) umin %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 65536 @@ -1023,7 +1023,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,65538) S: [1,65538) Exits: (1 + (%m umin_seq (1 + (zext i16 %n to i32)))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_not_zero_wrong_order ; CHECK-NEXT: Loop %loop: backedge-taken count is (%m umin_seq (1 + (zext i16 %n to i32))) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 65536 @@ -1055,7 +1055,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_not_zero_needs_context ; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -1094,7 +1094,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,65537) S: [1,65537) Exits: (1 + (zext i16 %n to i32)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_known_smaller ; CHECK-NEXT: Loop %loop: backedge-taken count is (zext i16 %n to i32) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 65535 @@ -1133,7 +1133,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,65537) S: [1,65537) Exits: (1 + (zext i16 %n to i32)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_known_smaller_equal ; CHECK-NEXT: Loop %loop: backedge-taken count is (zext i16 %n to i32) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 65535 @@ -1172,7 +1172,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,65537) S: [1,65537) Exits: (1 + ((zext i16 %n to i32) umin_seq (65534 + (zext i16 %m to i32)))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_not_known_smaller_equal ; CHECK-NEXT: Loop %loop: backedge-taken count is ((zext i16 %n to i32) umin_seq (65534 + (zext i16 %m to i32))) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 65535 @@ -1211,7 +1211,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,65537) S: [1,65537) Exits: (1 + (zext i16 %n to i32)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_known_greater ; CHECK-NEXT: Loop %loop: backedge-taken count is (zext i16 %n to i32) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 65535 @@ -1250,7 +1250,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,65537) S: [1,65537) Exits: (1 + (zext i16 %n to i32)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_known_greater_equal ; CHECK-NEXT: Loop %loop: backedge-taken count is (zext i16 %n to i32) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 65535 @@ -1289,7 +1289,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,65537) S: [1,65537) Exits: (1 + ((zext i16 %n to i32) umin (65534 + (zext i16 %m to i32)))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_not_known_greater_equal ; CHECK-NEXT: Loop %loop: backedge-taken count is ((zext i16 %n to i32) umin (65534 + (zext i16 %m to i32))) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 65535 @@ -1322,7 +1322,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,2) S: [1,2) Exits: 1 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: false LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: false LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_zero_arg1 ; CHECK-NEXT: Loop %loop: backedge-taken count is 0 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 0 @@ -1352,7 +1352,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,2) S: [1,2) Exits: 1 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p1 umin %cond_p0) U: full-set S: full-set Exits: false LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: false LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_zero_arg2 ; CHECK-NEXT: Loop %loop: backedge-taken count is 0 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 0 diff --git a/llvm/test/Analysis/ScalarEvolution/exit-count-select.ll b/llvm/test/Analysis/ScalarEvolution/exit-count-select.ll --- a/llvm/test/Analysis/ScalarEvolution/exit-count-select.ll +++ b/llvm/test/Analysis/ScalarEvolution/exit-count-select.ll @@ -11,7 +11,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,4) S: [1,4) Exits: (1 + (2 umin %n)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_i, i1 %cond_i2, i1 false -; CHECK-NEXT: --> (%cond_i2 umin %cond_i) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_i, %cond_i2, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_m_const ; CHECK-NEXT: Loop %loop: backedge-taken count is (2 umin %n) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 2 @@ -43,7 +43,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,4) S: [1,4) Exits: (1 + (2 umin %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_i, i1 %cond_i2, i1 false -; CHECK-NEXT: --> (%cond_i umin_seq %cond_i2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_i, %cond_i2, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_nonzero ; CHECK-NEXT: Loop %loop: backedge-taken count is (2 umin %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 2 @@ -76,7 +76,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,2) S: [1,2) Exits: 1 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_i, i1 %cond_i2, i1 false -; CHECK-NEXT: --> (%cond_i umin_seq %cond_i2) U: full-set S: full-set Exits: false LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_i, %cond_i2, false) U: full-set S: full-set Exits: false LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_zero ; CHECK-NEXT: Loop %loop: backedge-taken count is 0 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 0 @@ -110,7 +110,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_i, i1 %cond_i2, i1 false -; CHECK-NEXT: --> (%cond_i umin_seq %cond_i2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_i, %cond_i2, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_inversed ; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count. ; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count. @@ -140,7 +140,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,4) S: [1,4) Exits: (1 + (2 umin %n)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_i, i1 true, i1 %cond_i2 -; CHECK-NEXT: --> (true + ((true + %cond_i) umin (true + %cond_i2))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_i, true, %cond_i2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_m_const ; CHECK-NEXT: Loop %loop: backedge-taken count is (2 umin %n) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 2 @@ -172,7 +172,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,4) S: [1,4) Exits: (1 + (2 umin %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_i, i1 true, i1 %cond_i2 -; CHECK-NEXT: --> (true + ((true + %cond_i) umin_seq (true + %cond_i2))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_i, true, %cond_i2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_nonzero ; CHECK-NEXT: Loop %loop: backedge-taken count is (2 umin %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 2 @@ -205,7 +205,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,2) S: [1,2) Exits: 1 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_i, i1 true, i1 %cond_i2 -; CHECK-NEXT: --> (true + ((true + %cond_i) umin_seq (true + %cond_i2))) U: full-set S: full-set Exits: true LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_i, true, %cond_i2) U: full-set S: full-set Exits: true LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_zero ; CHECK-NEXT: Loop %loop: backedge-taken count is 0 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 0 @@ -239,7 +239,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_i, i1 true, i1 %cond_i2 -; CHECK-NEXT: --> (true + ((true + %cond_i) umin_seq (true + %cond_i2))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_i, true, %cond_i2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_inversed ; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count. ; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count. diff --git a/llvm/test/Analysis/ScalarEvolution/ext_min_max.ll b/llvm/test/Analysis/ScalarEvolution/ext_min_max.ll --- a/llvm/test/Analysis/ScalarEvolution/ext_min_max.ll +++ b/llvm/test/Analysis/ScalarEvolution/ext_min_max.ll @@ -127,9 +127,9 @@ ; CHECK-LABEL: 'test_umin_seq' ; CHECK-NEXT: Classifying expressions for: @test_umin_seq ; CHECK-NEXT: %x_umin_seq_y = select i1 %x, i1 %y, i1 false -; CHECK-NEXT: --> (%x umin_seq %y) U: full-set S: full-set +; CHECK-NEXT: --> (select %x, %y, false) U: full-set S: full-set ; CHECK-NEXT: %zext_x_umin_seq_y = zext i1 %x_umin_seq_y to i64 -; CHECK-NEXT: --> (zext i1 (%x umin_seq %y) to i64) U: [0,2) S: [0,2) +; CHECK-NEXT: --> (zext i1 (select %x, %y, false) to i64) U: [0,2) S: [0,2) ; CHECK-NEXT: %zext_x = zext i1 %x to i64 ; CHECK-NEXT: --> (zext i1 %x to i64) U: [0,2) S: [0,2) ; CHECK-NEXT: %zext_y = zext i1 %y to i64 diff --git a/llvm/test/Analysis/ScalarEvolution/incorrect-exit-count.ll b/llvm/test/Analysis/ScalarEvolution/incorrect-exit-count.ll --- a/llvm/test/Analysis/ScalarEvolution/incorrect-exit-count.ll +++ b/llvm/test/Analysis/ScalarEvolution/incorrect-exit-count.ll @@ -29,7 +29,7 @@ ; CHECK-NEXT: %storemerge1822.lcssa.ph32 = phi i32 [ 3, %inner.loop ] ; CHECK-NEXT: --> 3 U: [3,4) S: [3,4) ; CHECK-NEXT: %storemerge1822.lcssa = phi i32 [ %storemerge1822.lcssa.ph, %if.end.loopexit ], [ %storemerge1822.lcssa.ph32, %if.end.loopexit31 ] -; CHECK-NEXT: --> %storemerge1822.lcssa U: [0,4) S: [0,4) +; CHECK-NEXT: --> (select %tobool8, 0, 3) U: [0,4) S: [0,4) ; CHECK-NEXT: %i1 = load i32, ptr @e, align 4 ; CHECK-NEXT: --> %i1 U: full-set S: full-set ; CHECK-NEXT: %i2 = load volatile i32, ptr @b, align 4 diff --git a/llvm/test/Analysis/ScalarEvolution/increasing-or-decreasing-iv.ll b/llvm/test/Analysis/ScalarEvolution/increasing-or-decreasing-iv.ll --- a/llvm/test/Analysis/ScalarEvolution/increasing-or-decreasing-iv.ll +++ b/llvm/test/Analysis/ScalarEvolution/increasing-or-decreasing-iv.ll @@ -5,15 +5,15 @@ ; CHECK-LABEL: 'f0' ; CHECK-NEXT: Classifying expressions for: @f0 ; CHECK-NEXT: %start = select i1 %c, i32 127, i32 0 -; CHECK-NEXT: --> %start U: [0,128) S: [0,128) +; CHECK-NEXT: --> (select %c, 127, 0) U: [0,128) S: [0,128) ; CHECK-NEXT: %step = select i1 %c, i32 -1, i32 1 -; CHECK-NEXT: --> %step U: [1,0) S: [-2,2) +; CHECK-NEXT: --> (select %c, -1, 1) U: [-1,2) S: [-1,2) ; CHECK-NEXT: %loop.iv = phi i32 [ 0, %entry ], [ %loop.iv.inc, %loop ] ; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,128) S: [0,128) Exits: 127 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ] -; CHECK-NEXT: --> {%start,+,%step}<%loop> U: [0,128) S: [0,128) Exits: ((127 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(select %c, 127, 0),+,(select %c, -1, 1)}<%loop> U: [0,128) S: [0,128) Exits: ((127 * (select %c, -1, 1)) + (select %c, 127, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.next = add i32 %iv, %step -; CHECK-NEXT: --> {(%step + %start),+,%step}<%loop> U: [-256,256) S: [-256,256) Exits: ((128 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {((select %c, 127, 0) + (select %c, -1, 1)),+,(select %c, -1, 1)}<%loop> U: [-128,256) S: [-128,256) Exits: ((128 * (select %c, -1, 1)) + (select %c, 127, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %loop.iv.inc = add i32 %loop.iv, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,129) S: [1,129) Exits: 128 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: Determining loop execution counts for: @f0 @@ -45,43 +45,43 @@ ; CHECK-LABEL: 'f1' ; CHECK-NEXT: Classifying expressions for: @f1 ; CHECK-NEXT: %start = select i1 %c, i32 120, i32 0 -; CHECK-NEXT: --> %start U: [0,121) S: [0,121) +; CHECK-NEXT: --> (select %c, 120, 0) U: [0,121) S: [0,121) ; CHECK-NEXT: %step = select i1 %c, i32 -8, i32 8 -; CHECK-NEXT: --> %step U: [8,-7) S: [-16,16) +; CHECK-NEXT: --> (select %c, -8, 8) U: [-8,9) S: [-8,9) ; CHECK-NEXT: %loop.iv = phi i32 [ 0, %entry ], [ %loop.iv.inc, %loop ] ; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,16) S: [0,16) Exits: 15 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ] -; CHECK-NEXT: --> {%start,+,%step}<%loop> U: [0,121) S: [0,121) Exits: ((15 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(select %c, 120, 0),+,(select %c, -8, 8)}<%loop> U: [0,121) S: [0,121) Exits: ((15 * (select %c, -8, 8)) + (select %c, 120, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.1 = add i32 %iv, 1 -; CHECK-NEXT: --> {(1 + %start),+,%step}<%loop> U: [1,122) S: [1,122) Exits: (1 + (15 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(1 + (select %c, 120, 0)),+,(select %c, -8, 8)}<%loop> U: [1,122) S: [1,122) Exits: (1 + (15 * (select %c, -8, 8)) + (select %c, 120, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.2 = add i32 %iv, 2 -; CHECK-NEXT: --> {(2 + %start),+,%step}<%loop> U: [2,123) S: [2,123) Exits: (2 + (15 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(2 + (select %c, 120, 0)),+,(select %c, -8, 8)}<%loop> U: [2,123) S: [2,123) Exits: (2 + (15 * (select %c, -8, 8)) + (select %c, 120, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.3 = add i32 %iv, 3 -; CHECK-NEXT: --> {(3 + %start),+,%step}<%loop> U: [3,124) S: [3,124) Exits: (3 + (15 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(3 + (select %c, 120, 0)),+,(select %c, -8, 8)}<%loop> U: [3,124) S: [3,124) Exits: (3 + (15 * (select %c, -8, 8)) + (select %c, 120, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.4 = add i32 %iv, 4 -; CHECK-NEXT: --> {(4 + %start),+,%step}<%loop> U: [4,125) S: [4,125) Exits: (4 + (15 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(4 + (select %c, 120, 0)),+,(select %c, -8, 8)}<%loop> U: [4,125) S: [4,125) Exits: (4 + (15 * (select %c, -8, 8)) + (select %c, 120, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.5 = add i32 %iv, 5 -; CHECK-NEXT: --> {(5 + %start),+,%step}<%loop> U: [5,126) S: [5,126) Exits: (5 + (15 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(5 + (select %c, 120, 0)),+,(select %c, -8, 8)}<%loop> U: [5,126) S: [5,126) Exits: (5 + (15 * (select %c, -8, 8)) + (select %c, 120, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.6 = add i32 %iv, 6 -; CHECK-NEXT: --> {(6 + %start),+,%step}<%loop> U: [6,127) S: [6,127) Exits: (6 + (15 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(6 + (select %c, 120, 0)),+,(select %c, -8, 8)}<%loop> U: [6,127) S: [6,127) Exits: (6 + (15 * (select %c, -8, 8)) + (select %c, 120, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.7 = add i32 %iv, 7 -; CHECK-NEXT: --> {(7 + %start),+,%step}<%loop> U: [7,128) S: [7,128) Exits: (7 + (15 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(7 + (select %c, 120, 0)),+,(select %c, -8, 8)}<%loop> U: [7,128) S: [7,128) Exits: (7 + (15 * (select %c, -8, 8)) + (select %c, 120, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.m1 = sub i32 %iv, 1 -; CHECK-NEXT: --> {(-1 + %start),+,%step}<%loop> U: [-1,120) S: [-1,120) Exits: (-1 + (15 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(-1 + (select %c, 120, 0)),+,(select %c, -8, 8)}<%loop> U: [-1,120) S: [-1,120) Exits: (-1 + (15 * (select %c, -8, 8)) + (select %c, 120, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.m2 = sub i32 %iv, 2 -; CHECK-NEXT: --> {(-2 + %start),+,%step}<%loop> U: [0,-1) S: [-2,119) Exits: (-2 + (15 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(-2 + (select %c, 120, 0)),+,(select %c, -8, 8)}<%loop> U: [-2,119) S: [-2,119) Exits: (-2 + (15 * (select %c, -8, 8)) + (select %c, 120, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.m3 = sub i32 %iv, 3 -; CHECK-NEXT: --> {(-3 + %start),+,%step}<%loop> U: [-3,118) S: [-3,118) Exits: (-3 + (15 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(-3 + (select %c, 120, 0)),+,(select %c, -8, 8)}<%loop> U: [-3,118) S: [-3,118) Exits: (-3 + (15 * (select %c, -8, 8)) + (select %c, 120, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.m4 = sub i32 %iv, 4 -; CHECK-NEXT: --> {(-4 + %start),+,%step}<%loop> U: [0,-3) S: [-4,117) Exits: (-4 + (15 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(-4 + (select %c, 120, 0)),+,(select %c, -8, 8)}<%loop> U: [-4,117) S: [-4,117) Exits: (-4 + (15 * (select %c, -8, 8)) + (select %c, 120, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.m5 = sub i32 %iv, 5 -; CHECK-NEXT: --> {(-5 + %start),+,%step}<%loop> U: [-5,116) S: [-5,116) Exits: (-5 + (15 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(-5 + (select %c, 120, 0)),+,(select %c, -8, 8)}<%loop> U: [-5,116) S: [-5,116) Exits: (-5 + (15 * (select %c, -8, 8)) + (select %c, 120, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.m6 = sub i32 %iv, 6 -; CHECK-NEXT: --> {(-6 + %start),+,%step}<%loop> U: [0,-1) S: [-6,115) Exits: (-6 + (15 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(-6 + (select %c, 120, 0)),+,(select %c, -8, 8)}<%loop> U: [-6,115) S: [-6,115) Exits: (-6 + (15 * (select %c, -8, 8)) + (select %c, 120, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.m7 = sub i32 %iv, 7 -; CHECK-NEXT: --> {(-7 + %start),+,%step}<%loop> U: [-7,114) S: [-7,114) Exits: (-7 + (15 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(-7 + (select %c, 120, 0)),+,(select %c, -8, 8)}<%loop> U: [-7,114) S: [-7,114) Exits: (-7 + (15 * (select %c, -8, 8)) + (select %c, 120, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.next = add i32 %iv, %step -; CHECK-NEXT: --> {(%step + %start),+,%step}<%loop> U: [0,-7) S: [-256,361) Exits: ((16 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {((select %c, 120, 0) + (select %c, -8, 8)),+,(select %c, -8, 8)}<%loop> U: [-128,249) S: [-128,249) Exits: ((16 * (select %c, -8, 8)) + (select %c, 120, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %loop.iv.inc = add i32 %loop.iv, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,17) S: [1,17) Exits: 16 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: Determining loop execution counts for: @f1 @@ -132,17 +132,17 @@ ; CHECK-LABEL: 'f2' ; CHECK-NEXT: Classifying expressions for: @f2 ; CHECK-NEXT: %start = select i1 %c, i32 127, i32 0 -; CHECK-NEXT: --> %start U: [0,128) S: [0,128) +; CHECK-NEXT: --> (select %c, 127, 0) U: [0,128) S: [0,128) ; CHECK-NEXT: %step = select i1 %c, i32 -1, i32 1 -; CHECK-NEXT: --> %step U: [1,0) S: [-2,2) +; CHECK-NEXT: --> (select %c, -1, 1) U: [-1,2) S: [-1,2) ; CHECK-NEXT: %loop.iv = phi i32 [ 0, %entry ], [ %loop.iv.inc, %loop ] ; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,128) S: [0,128) Exits: 127 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ] -; CHECK-NEXT: --> {%start,+,%step}<%loop> U: [0,128) S: [0,128) Exits: ((127 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(select %c, 127, 0),+,(select %c, -1, 1)}<%loop> U: [0,128) S: [0,128) Exits: ((127 * (select %c, -1, 1)) + (select %c, 127, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.sext = sext i32 %iv to i64 -; CHECK-NEXT: --> {(zext i32 %start to i64),+,(sext i32 %step to i64)}<%loop> U: [0,128) S: [0,128) Exits: ((zext i32 %start to i64) + (127 * (sext i32 %step to i64))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(zext i32 (select %c, 127, 0) to i64),+,(sext i32 (select %c, -1, 1) to i64)}<%loop> U: [0,128) S: [0,128) Exits: ((zext i32 (select %c, 127, 0) to i64) + (127 * (sext i32 (select %c, -1, 1) to i64))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.next = add i32 %iv, %step -; CHECK-NEXT: --> {(%step + %start),+,%step}<%loop> U: [-256,256) S: [-256,256) Exits: ((128 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {((select %c, 127, 0) + (select %c, -1, 1)),+,(select %c, -1, 1)}<%loop> U: [-128,256) S: [-128,256) Exits: ((128 * (select %c, -1, 1)) + (select %c, 127, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %loop.iv.inc = add i32 %loop.iv, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,129) S: [1,129) Exits: 128 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: Determining loop execution counts for: @f2 @@ -175,17 +175,17 @@ ; CHECK-LABEL: 'f3' ; CHECK-NEXT: Classifying expressions for: @f3 ; CHECK-NEXT: %start = select i1 %c, i16 1000, i16 0 -; CHECK-NEXT: --> %start U: [0,1001) S: [0,1001) +; CHECK-NEXT: --> (select %c, 1000, 0) U: [0,1001) S: [0,1001) ; CHECK-NEXT: %step = select i1 %c, i16 1, i16 509 -; CHECK-NEXT: --> %step U: [1,510) S: [1,510) +; CHECK-NEXT: --> (select %c, 1, 509) U: [1,510) S: [1,510) ; CHECK-NEXT: %loop.iv = phi i16 [ 0, %entry ], [ %loop.iv.inc, %loop ] ; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,128) S: [0,128) Exits: 127 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv = phi i16 [ %start, %entry ], [ %iv.next, %loop ] -; CHECK-NEXT: --> {%start,+,%step}<%loop> U: [0,-892) S: [0,-892) Exits: ((127 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(select %c, 1000, 0),+,(select %c, 1, 509)}<%loop> U: [0,-892) S: [0,-892) Exits: ((127 * (select %c, 1, 509)) + (select %c, 1000, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.zext = zext i16 %iv to i64 -; CHECK-NEXT: --> {(zext i16 %start to i64),+,(zext i16 %step to i64)}<%loop> U: [0,64644) S: [0,64644) Exits: ((zext i16 %start to i64) + (127 * (zext i16 %step to i64))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(zext i16 (select %c, 1000, 0) to i64),+,(zext i16 (select %c, 1, 509) to i64)}<%loop> U: [0,64644) S: [0,64644) Exits: ((zext i16 (select %c, 1000, 0) to i64) + (127 * (zext i16 (select %c, 1, 509) to i64))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.next = add i16 %iv, %step -; CHECK-NEXT: --> {(%step + %start),+,%step}<%loop> U: full-set S: full-set Exits: ((128 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {((select %c, 1, 509) + (select %c, 1000, 0)),+,(select %c, 1, 509)}<%loop> U: full-set S: full-set Exits: ((128 * (select %c, 1, 509)) + (select %c, 1000, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %loop.iv.inc = add i16 %loop.iv, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,129) S: [1,129) Exits: 128 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: Determining loop execution counts for: @f3 @@ -225,17 +225,17 @@ ; CHECK-LABEL: 'f4' ; CHECK-NEXT: Classifying expressions for: @f4 ; CHECK-NEXT: %start = select i1 %c, i32 127, i32 0 -; CHECK-NEXT: --> %start U: [0,128) S: [0,128) +; CHECK-NEXT: --> (select %c, 127, 0) U: [0,128) S: [0,128) ; CHECK-NEXT: %step = select i1 %c, i32 -1, i32 1 -; CHECK-NEXT: --> %step U: [1,0) S: [-2,2) +; CHECK-NEXT: --> (select %c, -1, 1) U: [-1,2) S: [-1,2) ; CHECK-NEXT: %loop.iv = phi i32 [ 0, %entry ], [ %loop.iv.inc, %loop ] ; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,128) S: [0,128) Exits: 127 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ] -; CHECK-NEXT: --> {%start,+,%step}<%loop> U: [0,128) S: [0,128) Exits: ((127 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(select %c, 127, 0),+,(select %c, -1, 1)}<%loop> U: [0,128) S: [0,128) Exits: ((127 * (select %c, -1, 1)) + (select %c, 127, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.trunc = trunc i32 %iv to i16 -; CHECK-NEXT: --> {(trunc i32 %start to i16),+,(trunc i32 %step to i16)}<%loop> U: full-set S: full-set Exits: ((trunc i32 %start to i16) + (127 * (trunc i32 %step to i16))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(trunc i32 (select %c, 127, 0) to i16),+,(trunc i32 (select %c, -1, 1) to i16)}<%loop> U: full-set S: full-set Exits: ((trunc i32 (select %c, 127, 0) to i16) + (127 * (trunc i32 (select %c, -1, 1) to i16))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.next = add i32 %iv, %step -; CHECK-NEXT: --> {(%step + %start),+,%step}<%loop> U: [-256,256) S: [-256,256) Exits: ((128 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {((select %c, 127, 0) + (select %c, -1, 1)),+,(select %c, -1, 1)}<%loop> U: [-128,256) S: [-128,256) Exits: ((128 * (select %c, -1, 1)) + (select %c, 127, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %loop.iv.inc = add i32 %loop.iv, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,129) S: [1,129) Exits: 128 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: Determining loop execution counts for: @f4 @@ -274,17 +274,17 @@ ; CHECK-LABEL: 'f5' ; CHECK-NEXT: Classifying expressions for: @f5 ; CHECK-NEXT: %start = select i1 %c, i32 127, i32 0 -; CHECK-NEXT: --> %start U: [0,128) S: [0,128) +; CHECK-NEXT: --> (select %c, 127, 0) U: [0,128) S: [0,128) ; CHECK-NEXT: %step = select i1 %c, i32 -1, i32 1 -; CHECK-NEXT: --> %step U: [1,0) S: [-2,2) +; CHECK-NEXT: --> (select %c, -1, 1) U: [-1,2) S: [-1,2) ; CHECK-NEXT: %loop.iv = phi i16 [ 0, %entry ], [ %loop.iv.inc, %loop ] ; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,128) S: [0,128) Exits: 127 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ] -; CHECK-NEXT: --> {%start,+,%step}<%loop> U: [0,128) S: [0,128) Exits: ((127 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(select %c, 127, 0),+,(select %c, -1, 1)}<%loop> U: [0,128) S: [0,128) Exits: ((127 * (select %c, -1, 1)) + (select %c, 127, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.trunc = trunc i32 %iv to i16 -; CHECK-NEXT: --> {(trunc i32 %start to i16),+,(trunc i32 %step to i16)}<%loop> U: [0,128) S: [0,128) Exits: ((trunc i32 %start to i16) + (127 * (trunc i32 %step to i16))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(trunc i32 (select %c, 127, 0) to i16),+,(trunc i32 (select %c, -1, 1) to i16)}<%loop> U: [0,128) S: [0,128) Exits: ((trunc i32 (select %c, 127, 0) to i16) + (127 * (trunc i32 (select %c, -1, 1) to i16))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.next = add i32 %iv, %step -; CHECK-NEXT: --> {(%step + %start),+,%step}<%loop> U: [-256,256) S: [-256,256) Exits: ((128 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {((select %c, 127, 0) + (select %c, -1, 1)),+,(select %c, -1, 1)}<%loop> U: [-128,256) S: [-128,256) Exits: ((128 * (select %c, -1, 1)) + (select %c, 127, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %loop.iv.inc = add i16 %loop.iv, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,129) S: [1,129) Exits: 128 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: Determining loop execution counts for: @f5 @@ -318,19 +318,19 @@ ; CHECK-LABEL: 'f6' ; CHECK-NEXT: Classifying expressions for: @f6 ; CHECK-NEXT: %start = select i1 %c, i32 127, i32 0 -; CHECK-NEXT: --> %start U: [0,128) S: [0,128) +; CHECK-NEXT: --> (select %c, 127, 0) U: [0,128) S: [0,128) ; CHECK-NEXT: %step = select i1 %c, i32 -2, i32 0 -; CHECK-NEXT: --> %step U: [0,-1) S: [-2,2) +; CHECK-NEXT: --> (select %c, -2, 0) U: [-2,1) S: [-2,1) ; CHECK-NEXT: %loop.iv = phi i16 [ 0, %entry ], [ %loop.iv.inc, %loop ] ; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,128) S: [0,128) Exits: 127 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ] -; CHECK-NEXT: --> {%start,+,(1 + %step)}<%loop> U: [0,128) S: [0,128) Exits: (127 + (127 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(select %c, 127, 0),+,(1 + (select %c, -2, 0))}<%loop> U: [0,128) S: [0,128) Exits: (127 + (127 * (select %c, -2, 0)) + (select %c, 127, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %step.plus.one = add i32 %step, 1 -; CHECK-NEXT: --> (1 + %step) U: [1,0) S: [-1,3) Exits: (1 + %step) LoopDispositions: { %loop: Invariant } +; CHECK-NEXT: --> (1 + (select %c, -2, 0)) U: [-1,2) S: [-1,2) Exits: (1 + (select %c, -2, 0)) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %iv.next = add i32 %iv, %step.plus.one -; CHECK-NEXT: --> {(1 + %step + %start),+,(1 + %step)}<%loop> U: [-128,384) S: [-128,384) Exits: (128 + (128 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(1 + (select %c, 127, 0) + (select %c, -2, 0)),+,(1 + (select %c, -2, 0))}<%loop> U: [-128,256) S: [-128,256) Exits: (128 + (128 * (select %c, -2, 0)) + (select %c, 127, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.sext = sext i32 %iv to i64 -; CHECK-NEXT: --> {(zext i32 %start to i64),+,(1 + (sext i32 %step to i64))}<%loop> U: [0,128) S: [0,128) Exits: (127 + (zext i32 %start to i64) + (127 * (sext i32 %step to i64))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(zext i32 (select %c, 127, 0) to i64),+,(1 + (sext i32 (select %c, -2, 0) to i64))}<%loop> U: [0,128) S: [0,128) Exits: (127 + (zext i32 (select %c, 127, 0) to i64) + (127 * (sext i32 (select %c, -2, 0) to i64))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %loop.iv.inc = add i16 %loop.iv, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,129) S: [1,129) Exits: 128 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: Determining loop execution counts for: @f6 @@ -365,21 +365,21 @@ ; CHECK-LABEL: 'f7' ; CHECK-NEXT: Classifying expressions for: @f7 ; CHECK-NEXT: %start = select i1 %c, i32 127, i32 0 -; CHECK-NEXT: --> %start U: [0,128) S: [0,128) +; CHECK-NEXT: --> (select %c, 127, 0) U: [0,128) S: [0,128) ; CHECK-NEXT: %step = select i1 %c, i32 -1, i32 1 -; CHECK-NEXT: --> %step U: [1,0) S: [-2,2) +; CHECK-NEXT: --> (select %c, -1, 1) U: [-1,2) S: [-1,2) ; CHECK-NEXT: %loop.iv = phi i16 [ 0, %entry ], [ %loop.iv.inc, %loop ] ; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,128) S: [0,128) Exits: 127 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ] -; CHECK-NEXT: --> {%start,+,%step}<%loop> U: [0,128) S: [0,128) Exits: ((127 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(select %c, 127, 0),+,(select %c, -1, 1)}<%loop> U: [0,128) S: [0,128) Exits: ((127 * (select %c, -1, 1)) + (select %c, 127, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.trunc = trunc i32 %iv to i16 -; CHECK-NEXT: --> {(trunc i32 %start to i16),+,(trunc i32 %step to i16)}<%loop> U: [0,128) S: [0,128) Exits: ((trunc i32 %start to i16) + (127 * (trunc i32 %step to i16))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(trunc i32 (select %c, 127, 0) to i16),+,(trunc i32 (select %c, -1, 1) to i16)}<%loop> U: [0,128) S: [0,128) Exits: ((trunc i32 (select %c, 127, 0) to i16) + (127 * (trunc i32 (select %c, -1, 1) to i16))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.next = add i32 %iv, %step -; CHECK-NEXT: --> {(%step + %start),+,%step}<%loop> U: [-256,256) S: [-256,256) Exits: ((128 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {((select %c, 127, 0) + (select %c, -1, 1)),+,(select %c, -1, 1)}<%loop> U: [-128,256) S: [-128,256) Exits: ((128 * (select %c, -1, 1)) + (select %c, 127, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.trunc.plus.one = add i16 %iv.trunc, 1 -; CHECK-NEXT: --> {(1 + (trunc i32 %start to i16)),+,(trunc i32 %step to i16)}<%loop> U: [1,129) S: [1,129) Exits: (1 + (trunc i32 %start to i16) + (127 * (trunc i32 %step to i16))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(1 + (trunc i32 (select %c, 127, 0) to i16)),+,(trunc i32 (select %c, -1, 1) to i16)}<%loop> U: [1,129) S: [1,129) Exits: (1 + (trunc i32 (select %c, 127, 0) to i16) + (127 * (trunc i32 (select %c, -1, 1) to i16))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.trunc.plus.two = add i16 %iv.trunc, 2 -; CHECK-NEXT: --> {(2 + (trunc i32 %start to i16)),+,(trunc i32 %step to i16)}<%loop> U: [2,130) S: [2,130) Exits: (2 + (trunc i32 %start to i16) + (127 * (trunc i32 %step to i16))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(2 + (trunc i32 (select %c, 127, 0) to i16)),+,(trunc i32 (select %c, -1, 1) to i16)}<%loop> U: [2,130) S: [2,130) Exits: (2 + (trunc i32 (select %c, 127, 0) to i16) + (127 * (trunc i32 (select %c, -1, 1) to i16))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %loop.iv.inc = add i16 %loop.iv, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,129) S: [1,129) Exits: 128 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: Determining loop execution counts for: @f7 diff --git a/llvm/test/Analysis/ScalarEvolution/logical-operations.ll b/llvm/test/Analysis/ScalarEvolution/logical-operations.ll --- a/llvm/test/Analysis/ScalarEvolution/logical-operations.ll +++ b/llvm/test/Analysis/ScalarEvolution/logical-operations.ll @@ -125,7 +125,7 @@ ; CHECK-LABEL: 'logical_or' ; CHECK-NEXT: Classifying expressions for: @logical_or ; CHECK-NEXT: %r = select i1 %x, i1 true, i1 %y -; CHECK-NEXT: --> (true + ((true + %x) umin_seq (true + %y))) U: full-set S: full-set +; CHECK-NEXT: --> (select %x, true, %y) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @logical_or ; %r = select i1 %x, i1 true, i1 %y @@ -136,7 +136,7 @@ ; CHECK-LABEL: 'logical_and' ; CHECK-NEXT: Classifying expressions for: @logical_and ; CHECK-NEXT: %r = select i1 %x, i1 %y, i1 false -; CHECK-NEXT: --> (%x umin_seq %y) U: full-set S: full-set +; CHECK-NEXT: --> (select %x, %y, false) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @logical_and ; %r = select i1 %x, i1 %y, i1 false @@ -147,7 +147,7 @@ ; CHECK-LABEL: 'select_x_or_false' ; CHECK-NEXT: Classifying expressions for: @select_x_or_false ; CHECK-NEXT: %r = select i1 %c, i1 %x, i1 false -; CHECK-NEXT: --> (%c umin_seq %x) U: full-set S: full-set +; CHECK-NEXT: --> (select %c, %x, false) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_x_or_false ; %r = select i1 %c, i1 %x, i1 false @@ -158,7 +158,7 @@ ; CHECK-LABEL: 'select_false_or_x' ; CHECK-NEXT: Classifying expressions for: @select_false_or_x ; CHECK-NEXT: %r = select i1 %c, i1 false, i1 %x -; CHECK-NEXT: --> ((true + %c) umin_seq %x) U: full-set S: full-set +; CHECK-NEXT: --> (select %c, false, %x) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_false_or_x ; %r = select i1 %c, i1 false, i1 %x @@ -169,7 +169,7 @@ ; CHECK-LABEL: 'select_x_or_true' ; CHECK-NEXT: Classifying expressions for: @select_x_or_true ; CHECK-NEXT: %r = select i1 %c, i1 %x, i1 true -; CHECK-NEXT: --> (true + (%c umin_seq (true + %x))) U: full-set S: full-set +; CHECK-NEXT: --> (select %c, %x, true) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_x_or_true ; %r = select i1 %c, i1 %x, i1 true @@ -180,7 +180,7 @@ ; CHECK-LABEL: 'select_true_or_x' ; CHECK-NEXT: Classifying expressions for: @select_true_or_x ; CHECK-NEXT: %r = select i1 %c, i1 true, i1 %x -; CHECK-NEXT: --> (true + ((true + %c) umin_seq (true + %x))) U: full-set S: full-set +; CHECK-NEXT: --> (select %c, true, %x) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_true_or_x ; %r = select i1 %c, i1 true, i1 %x @@ -191,7 +191,7 @@ ; CHECK-LABEL: 'select_x_or_zero' ; CHECK-NEXT: Classifying expressions for: @select_x_or_zero ; CHECK-NEXT: %r = select i1 %c, i32 %x, i32 0 -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %c, %x, 0) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_x_or_zero ; %r = select i1 %c, i32 %x, i32 0 @@ -202,7 +202,7 @@ ; CHECK-LABEL: 'select_zero_or_x' ; CHECK-NEXT: Classifying expressions for: @select_zero_or_x ; CHECK-NEXT: %r = select i1 %c, i32 0, i32 %x -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %c, 0, %x) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_zero_or_x ; %r = select i1 %c, i32 0, i32 %x @@ -213,7 +213,7 @@ ; CHECK-LABEL: 'select_x_or_allones' ; CHECK-NEXT: Classifying expressions for: @select_x_or_allones ; CHECK-NEXT: %r = select i1 %c, i32 %x, i32 -1 -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %c, %x, -1) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_x_or_allones ; %r = select i1 %c, i32 %x, i32 -1 @@ -224,7 +224,7 @@ ; CHECK-LABEL: 'select_allones_or_x' ; CHECK-NEXT: Classifying expressions for: @select_allones_or_x ; CHECK-NEXT: %r = select i1 %c, i32 -1, i32 %x -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %c, -1, %x) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_allones_or_x ; %r = select i1 %c, i32 -1, i32 %x @@ -235,7 +235,7 @@ ; CHECK-LABEL: 'select_x_or_intmax' ; CHECK-NEXT: Classifying expressions for: @select_x_or_intmax ; CHECK-NEXT: %r = select i1 %c, i32 %x, i32 2147483647 -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %c, %x, 2147483647) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_x_or_intmax ; %r = select i1 %c, i32 %x, i32 2147483647 @@ -246,7 +246,7 @@ ; CHECK-LABEL: 'select_intmax_or_x' ; CHECK-NEXT: Classifying expressions for: @select_intmax_or_x ; CHECK-NEXT: %r = select i1 %c, i32 2147483647, i32 %x -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %c, 2147483647, %x) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_intmax_or_x ; %r = select i1 %c, i32 2147483647, i32 %x @@ -257,7 +257,7 @@ ; CHECK-LABEL: 'select_x_or_intmin' ; CHECK-NEXT: Classifying expressions for: @select_x_or_intmin ; CHECK-NEXT: %r = select i1 %c, i32 %x, i32 -2147483648 -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %c, %x, -2147483648) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_x_or_intmin ; %r = select i1 %c, i32 %x, i32 -2147483648 @@ -268,7 +268,7 @@ ; CHECK-LABEL: 'select_intmin_or_x' ; CHECK-NEXT: Classifying expressions for: @select_intmin_or_x ; CHECK-NEXT: %r = select i1 %c, i32 -2147483648, i32 %x -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %c, -2147483648, %x) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_intmin_or_x ; %r = select i1 %c, i32 -2147483648, i32 %x @@ -279,7 +279,7 @@ ; CHECK-LABEL: 'select_x_or_constant' ; CHECK-NEXT: Classifying expressions for: @select_x_or_constant ; CHECK-NEXT: %r = select i1 %c, i32 %x, i32 42 -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %c, %x, 42) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_x_or_constant ; %r = select i1 %c, i32 %x, i32 42 @@ -290,7 +290,7 @@ ; CHECK-LABEL: 'select_constant_or_x' ; CHECK-NEXT: Classifying expressions for: @select_constant_or_x ; CHECK-NEXT: %r = select i1 %c, i32 42, i32 %y -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %c, 42, %y) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_constant_or_x ; %r = select i1 %c, i32 42, i32 %y @@ -301,7 +301,7 @@ ; CHECK-LABEL: 'select_between_constants' ; CHECK-NEXT: Classifying expressions for: @select_between_constants ; CHECK-NEXT: %r = select i1 %c, i32 42, i32 24 -; CHECK-NEXT: --> %r U: [8,59) S: [8,59) +; CHECK-NEXT: --> (select %c, 42, 24) U: [24,43) S: [24,43) ; CHECK-NEXT: Determining loop execution counts for: @select_between_constants ; %r = select i1 %c, i32 42, i32 24 @@ -312,7 +312,7 @@ ; CHECK-LABEL: 'select_x_or_y' ; CHECK-NEXT: Classifying expressions for: @select_x_or_y ; CHECK-NEXT: %r = select i1 %c, i32 %x, i32 %y -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %c, %x, %y) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_x_or_y ; %r = select i1 %c, i32 %x, i32 %y @@ -323,7 +323,7 @@ ; CHECK-LABEL: 'select_x_or_y__noundef' ; CHECK-NEXT: Classifying expressions for: @select_x_or_y__noundef ; CHECK-NEXT: %r = select i1 %c, i32 %x, i32 %y -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %c, %x, %y) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_x_or_y__noundef ; %r = select i1 %c, i32 %x, i32 %y @@ -334,7 +334,7 @@ ; CHECK-LABEL: 'select_x_or_constantexpr' ; CHECK-NEXT: Classifying expressions for: @select_x_or_constantexpr ; CHECK-NEXT: %r = select i1 %c, i32 %x, i32 ptrtoint (ptr @constant to i32) -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %c, %x, (trunc i64 (ptrtoint ptr @constant to i64) to i32)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_x_or_constantexpr ; %r = select i1 %c, i32 %x, i32 ptrtoint (ptr @constant to i32) @@ -345,7 +345,7 @@ ; CHECK-LABEL: 'select_constantexpr_or_x' ; CHECK-NEXT: Classifying expressions for: @select_constantexpr_or_x ; CHECK-NEXT: %r = select i1 %c, i32 ptrtoint (ptr @constant to i32), i32 %x -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %c, (trunc i64 (ptrtoint ptr @constant to i64) to i32), %x) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_constantexpr_or_x ; %r = select i1 %c, i32 ptrtoint (ptr @constant to i32), i32 %x @@ -356,7 +356,7 @@ ; CHECK-LABEL: 'select_x_or_nullptr' ; CHECK-NEXT: Classifying expressions for: @select_x_or_nullptr ; CHECK-NEXT: %r = select i1 %c, ptr %x, ptr null -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %c, %x, null) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_x_or_nullptr ; %r = select i1 %c, ptr %x, ptr null @@ -367,7 +367,7 @@ ; CHECK-LABEL: 'select_null_or_x' ; CHECK-NEXT: Classifying expressions for: @select_null_or_x ; CHECK-NEXT: %r = select i1 %c, ptr null, ptr %x -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %c, null, %x) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_null_or_x ; %r = select i1 %c, ptr null, ptr %x @@ -378,7 +378,7 @@ ; CHECK-LABEL: 'select_x_or_constantptr' ; CHECK-NEXT: Classifying expressions for: @select_x_or_constantptr ; CHECK-NEXT: %r = select i1 %c, ptr %x, ptr @constant -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %c, %x, @constant) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_x_or_constantptr ; %r = select i1 %c, ptr %x, ptr @constant @@ -389,7 +389,7 @@ ; CHECK-LABEL: 'select_constantptr_or_x' ; CHECK-NEXT: Classifying expressions for: @select_constantptr_or_x ; CHECK-NEXT: %r = select i1 %c, ptr @constant, ptr %x -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %c, @constant, %x) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @select_constantptr_or_x ; %r = select i1 %c, ptr @constant, ptr %x @@ -400,7 +400,7 @@ ; CHECK-LABEL: 'select_between_constantptrs' ; CHECK-NEXT: Classifying expressions for: @select_between_constantptrs ; CHECK-NEXT: %r = select i1 %c, ptr @constant, ptr @another_constant -; CHECK-NEXT: --> %r U: [0,-3) S: [-9223372036854775808,9223372036854775805) +; CHECK-NEXT: --> (select %c, @constant, @another_constant) U: [0,-3) S: [-9223372036854775808,9223372036854775805) ; CHECK-NEXT: Determining loop execution counts for: @select_between_constantptrs ; %r = select i1 %c, ptr @constant, ptr @another_constant @@ -508,7 +508,7 @@ ; CHECK-NEXT: %umax = call i32 @llvm.umax.i32(i32 %y, i32 %x) ; CHECK-NEXT: --> (%x umax %y) U: full-set S: full-set ; CHECK-NEXT: %r = select i1 %x.is.zero, i32 0, i32 %umax -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %x.is.zero, 0, (%x umax %y)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @umin_seq_x_y_wrongtype0 ; %umax = call i32 @llvm.umax(i32 %y, i32 %x) @@ -522,7 +522,7 @@ ; CHECK-NEXT: %smax = call i32 @llvm.smax.i32(i32 %y, i32 %x) ; CHECK-NEXT: --> (%x smax %y) U: full-set S: full-set ; CHECK-NEXT: %r = select i1 %x.is.zero, i32 0, i32 %smax -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %x.is.zero, 0, (%x smax %y)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @umin_seq_x_y_wrongtype1 ; %smax = call i32 @llvm.smax(i32 %y, i32 %x) @@ -536,7 +536,7 @@ ; CHECK-NEXT: %smin = call i32 @llvm.smin.i32(i32 %y, i32 %x) ; CHECK-NEXT: --> (%x smin %y) U: full-set S: full-set ; CHECK-NEXT: %r = select i1 %x.is.zero, i32 0, i32 %smin -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %x.is.zero, 0, (%x smin %y)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @umin_seq_x_y_wrongtype2 ; %smin = call i32 @llvm.smin(i32 %y, i32 %x) @@ -553,7 +553,7 @@ ; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %umax, i32 %y) ; CHECK-NEXT: --> ((%x umax %z) umin %y) U: full-set S: full-set ; CHECK-NEXT: %r = select i1 %x.is.zero, i32 0, i32 %umin -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %x.is.zero, 0, ((%x umax %z) umin %y)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @umin_seq_x_y_wrongtype3 ; %umax = call i32 @llvm.umax(i32 %x, i32 %z) @@ -745,7 +745,7 @@ ; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %y, i32 %x) ; CHECK-NEXT: --> ((sext i8 %x.narrow to i32) umin %y) U: full-set S: full-set ; CHECK-NEXT: %r = select i1 %x.is.zero, i32 0, i32 %umin -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %x.is.zero, 0, ((sext i8 %x.narrow to i32) umin %y)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @umin_seq_x_y_sext_in_umin ; %x = sext i8 %x.narrow to i32 @@ -763,7 +763,7 @@ ; CHECK-NEXT: %umin = call i8 @llvm.umin.i8(i8 %y, i8 %x) ; CHECK-NEXT: --> (%x umin %y) U: full-set S: full-set ; CHECK-NEXT: %r = select i1 %x.is.zero, i8 0, i8 %umin -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %x.is.zero, 0, (%x umin %y)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @umin_seq_x_y_sext_in_iszero ; %x.wide = sext i8 %x to i32 @@ -781,7 +781,7 @@ ; CHECK-NEXT: %umin = sext i8 %umin.narrow to i32 ; CHECK-NEXT: --> (sext i8 (%x umin %y) to i32) U: [-128,128) S: [-128,128) ; CHECK-NEXT: %r = select i1 %x.is.zero, i32 0, i32 %umin -; CHECK-NEXT: --> %r U: [-128,128) S: [-128,128) +; CHECK-NEXT: --> (select %x.is.zero, 0, (sext i8 (%x umin %y) to i32)) U: [-128,128) S: [-128,128) ; CHECK-NEXT: Determining loop execution counts for: @umin_seq_x_y_sext_of_umin ; %umin.narrow = call i8 @llvm.umin.i8(i8 %y, i8 %x) @@ -801,7 +801,7 @@ ; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %y, i32 %x.zext) ; CHECK-NEXT: --> ((zext i8 %x.narrow to i32) umin %y) U: [0,256) S: [0,256) ; CHECK-NEXT: %r = select i1 %x.is.zero, i32 0, i32 %umin -; CHECK-NEXT: --> %r U: [0,256) S: [0,256) +; CHECK-NEXT: --> (select %x.is.zero, 0, ((zext i8 %x.narrow to i32) umin %y)) U: [0,256) S: [0,256) ; CHECK-NEXT: Determining loop execution counts for: @umin_seq_x_y_zext_vs_sext ; %x.zext = zext i8 %x.narrow to i32 @@ -821,7 +821,7 @@ ; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %y, i32 %x.sext) ; CHECK-NEXT: --> ((sext i8 %x.narrow to i32) umin %y) U: full-set S: full-set ; CHECK-NEXT: %r = select i1 %x.is.zero, i32 0, i32 %umin -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %x.is.zero, 0, ((sext i8 %x.narrow to i32) umin %y)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @umin_seq_x_y_sext_vs_zext ; %x.zext = zext i8 %x.narrow to i32 diff --git a/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info-rewrite-expressions.ll b/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info-rewrite-expressions.ll --- a/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info-rewrite-expressions.ll +++ b/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info-rewrite-expressions.ll @@ -284,18 +284,16 @@ ; CHECK-NEXT: %N.ext = zext i32 %N to i64 ; CHECK-NEXT: --> (zext i32 %N to i64) U: [0,4294967296) S: [0,4294967296) ; CHECK-NEXT: %init = phi i64 [ 2, %entry ], [ 4, %bb1 ] -; CHECK-NEXT: --> %init U: [2,5) S: [2,5) +; CHECK-NEXT: --> (select %c, 4, 2) U: [2,5) S: [2,5) ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ %init, %loop.ph ] -; CHECK-NEXT: --> {%init,+,2}<%loop> U: [2,17) S: [2,17) Exits: ((2 * ((14 + (-1 * %init)) /u 2)) + %init) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(select %c, 4, 2),+,2}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.next = add i64 %iv, 2 -; CHECK-NEXT: --> {(2 + %init),+,2}<%loop> U: [4,19) S: [4,19) Exits: (2 + (2 * ((14 + (-1 * %init)) /u 2)) + %init) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(2 + (select %c, 4, 2)),+,2}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } ; CHECK-NEXT: Determining loop execution counts for: @guard_pessimizes_analysis_step2 -; CHECK-NEXT: Loop %loop: backedge-taken count is ((14 + (-1 * %init)) /u 2) -; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 6 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((14 + (-1 * %init)) /u 2) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((14 + (-1 * %init)) /u 2) -; CHECK-NEXT: Predicates: -; CHECK: Loop %loop: Trip multiple is 1 +; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count. +; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count. +; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count. +; CHECK-NEXT: Loop %loop: Unpredictable predicated backedge-taken count. ; entry: %N.ext = zext i32 %N to i64 diff --git a/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll b/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll --- a/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll +++ b/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll @@ -887,16 +887,16 @@ ; CHECK-LABEL: 'guard_pessimizes_analysis_step1' ; CHECK-NEXT: Classifying expressions for: @guard_pessimizes_analysis_step1 ; CHECK-NEXT: %init = phi i32 [ 2, %entry ], [ 3, %bb1 ] -; CHECK-NEXT: --> %init U: [2,4) S: [2,4) +; CHECK-NEXT: --> (select %c, 3, 2) U: [2,4) S: [2,4) ; CHECK-NEXT: %iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ] -; CHECK-NEXT: --> {%init,+,1}<%loop> U: [2,11) S: [2,11) Exits: 9 LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(select %c, 3, 2),+,1}<%loop> U: [2,11) S: [2,11) Exits: 9 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.next = add i32 %iv, 1 -; CHECK-NEXT: --> {(1 + %init),+,1}<%loop> U: [3,12) S: [3,12) Exits: 10 LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(1 + (select %c, 3, 2)),+,1}<%loop> U: [3,12) S: [3,12) Exits: 10 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: Determining loop execution counts for: @guard_pessimizes_analysis_step1 -; CHECK-NEXT: Loop %loop: backedge-taken count is (9 + (-1 * %init)) +; CHECK-NEXT: Loop %loop: backedge-taken count is (9 + (-1 * (select %c, 3, 2))) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 7 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (9 + (-1 * %init)) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (9 + (-1 * %init)) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (9 + (-1 * (select %c, 3, 2))) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (9 + (-1 * (select %c, 3, 2))) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 ; @@ -928,16 +928,16 @@ ; CHECK-LABEL: 'guard_pessimizes_analysis_step2' ; CHECK-NEXT: Classifying expressions for: @guard_pessimizes_analysis_step2 ; CHECK-NEXT: %init = phi i32 [ 2, %entry ], [ 3, %bb1 ] -; CHECK-NEXT: --> %init U: [2,4) S: [2,4) +; CHECK-NEXT: --> (select %c, 3, 2) U: [2,4) S: [2,4) ; CHECK-NEXT: %iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ] -; CHECK-NEXT: --> {%init,+,2}<%loop> U: [2,10) S: [2,10) Exits: ((2 * ((8 + (-1 * %init)) /u 2)) + %init) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(select %c, 3, 2),+,2}<%loop> U: [2,10) S: [2,10) Exits: ((2 * ((8 + (-1 * (select %c, 3, 2))) /u 2)) + (select %c, 3, 2)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 2 -; CHECK-NEXT: --> {(2 + %init),+,2}<%loop> U: [4,12) S: [4,12) Exits: (2 + (2 * ((8 + (-1 * %init)) /u 2)) + %init) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(2 + (select %c, 3, 2)),+,2}<%loop> U: [4,12) S: [4,12) Exits: (2 + (2 * ((8 + (-1 * (select %c, 3, 2))) /u 2)) + (select %c, 3, 2)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: Determining loop execution counts for: @guard_pessimizes_analysis_step2 -; CHECK-NEXT: Loop %loop: backedge-taken count is ((8 + (-1 * %init)) /u 2) +; CHECK-NEXT: Loop %loop: backedge-taken count is ((8 + (-1 * (select %c, 3, 2))) /u 2) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 3 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((8 + (-1 * %init)) /u 2) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((8 + (-1 * %init)) /u 2) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((8 + (-1 * (select %c, 3, 2))) /u 2) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((8 + (-1 * (select %c, 3, 2))) /u 2) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 ; @@ -1445,20 +1445,20 @@ ; CHECK-LABEL: 'optimized_range_check_unsigned3' ; CHECK-NEXT: Classifying expressions for: @optimized_range_check_unsigned3 ; CHECK-NEXT: %N = select i1 %c, i32 2, i32 3 -; CHECK-NEXT: --> %N U: [2,4) S: [2,4) +; CHECK-NEXT: --> (select %c, 2, 3) U: [2,4) S: [2,4) ; CHECK-NEXT: %N.off = add i32 %N, -1 -; CHECK-NEXT: --> (-1 + %N) U: [1,3) S: [1,3) +; CHECK-NEXT: --> (-1 + (select %c, 2, 3)) U: [1,3) S: [1,3) ; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,3) S: [0,3) Exits: (-1 + %N) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,3) S: [0,3) Exits: (-1 + (select %c, 2, 3)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %gep = getelementptr inbounds i16, ptr %pred, i32 %iv -; CHECK-NEXT: --> {%pred,+,2}<%loop> U: full-set S: full-set Exits: ((2 * (zext i32 (-1 + %N) to i64)) + %pred) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {%pred,+,2}<%loop> U: full-set S: full-set Exits: ((2 * (zext i32 (-1 + (select %c, 2, 3)) to i64)) + %pred) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,4) S: [1,4) Exits: %N LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,4) S: [1,4) Exits: (select %c, 2, 3) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: Determining loop execution counts for: @optimized_range_check_unsigned3 -; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %N) +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + (select %c, 2, 3)) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 2 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %N) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %N) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + (select %c, 2, 3)) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + (select %c, 2, 3)) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 ; diff --git a/llvm/test/Analysis/ScalarEvolution/min-max-exprs.ll b/llvm/test/Analysis/ScalarEvolution/min-max-exprs.ll --- a/llvm/test/Analysis/ScalarEvolution/min-max-exprs.ll +++ b/llvm/test/Analysis/ScalarEvolution/min-max-exprs.ll @@ -146,7 +146,7 @@ ; CHECK-NEXT: %rhs = add i8 %x, %y ; CHECK-NEXT: --> (%x + %y) U: full-set S: full-set ; CHECK-NEXT: %r = select i1 %x.is.zero, i8 %lhs, i8 %rhs -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %x.is.zero, (2 + %y), (%x + %y)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @umax_basic_eq_off2 ; %x.is.zero = icmp eq i8 %x, 0 @@ -164,7 +164,7 @@ ; CHECK-NEXT: %rhs = add i8 %x, %y ; CHECK-NEXT: --> (%x + %y) U: full-set S: full-set ; CHECK-NEXT: %r = select i1 %x.is.zero, i8 %lhs, i8 %rhs -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %x.is.zero, (%y + %c), (%x + %y)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @umax_basic_eq_var_off ; %x.is.zero = icmp eq i8 %x, 0 diff --git a/llvm/test/Analysis/ScalarEvolution/nsw.ll b/llvm/test/Analysis/ScalarEvolution/nsw.ll --- a/llvm/test/Analysis/ScalarEvolution/nsw.ll +++ b/llvm/test/Analysis/ScalarEvolution/nsw.ll @@ -149,7 +149,7 @@ ; CHECK-NEXT: %tmp2 = add nsw i32 %a, %b ; CHECK-NEXT: --> (%a + %b) U: full-set S: full-set ; CHECK-NEXT: %result = phi i32 [ %a, %entry ], [ %tmp2, %greater ] -; CHECK-NEXT: --> %result U: full-set S: full-set +; CHECK-NEXT: --> (select %cmp, (%a + %b), %a) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @addnsw ; entry: @@ -414,7 +414,7 @@ ; CHECK-NEXT: %iv.next = add nsw i32 %iv, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: <> LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %sel = select i1 %cmp, i32 10, i32 20 -; CHECK-NEXT: --> %sel U: [0,31) S: [0,31) Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cmp, 10, 20) U: [10,21) S: [10,21) Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond = call i1 @cond() ; CHECK-NEXT: --> %cond U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @select_cond_poison_propagation diff --git a/llvm/test/Analysis/ScalarEvolution/pointer-rounding.ll b/llvm/test/Analysis/ScalarEvolution/pointer-rounding.ll --- a/llvm/test/Analysis/ScalarEvolution/pointer-rounding.ll +++ b/llvm/test/Analysis/ScalarEvolution/pointer-rounding.ll @@ -101,7 +101,7 @@ ; CHECK-NEXT: %i6 = getelementptr i8, ptr %i5, i64 16 ; CHECK-NEXT: --> (16 + (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj to i64) to i4) to i64)) + %obj) U: full-set S: full-set ; CHECK-NEXT: %i7 = select i1 %i3, ptr %obj, ptr %i6 -; CHECK-NEXT: --> %i7 U: full-set S: full-set +; CHECK-NEXT: --> (select %i3, %obj, (16 + (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj to i64) to i4) to i64)) + %obj)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @pointer_align_up_with_select ; %i = ptrtoint ptr %obj to i64 @@ -128,7 +128,7 @@ ; CHECK-NEXT: %i6 = getelementptr i8, ptr %i5, i64 16 ; CHECK-NEXT: --> (16 + (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64)) + %obj_to_align) U: full-set S: full-set ; CHECK-NEXT: %i7 = select i1 %i3, ptr %obj_to_align, ptr %i6 -; CHECK-NEXT: --> %i7 U: full-set S: full-set +; CHECK-NEXT: --> (select %i3, %obj_to_align, (16 + (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64)) + %obj_to_align)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @pointer_align_up_with_select_different_donor ; %i = ptrtoint ptr %obj_donor to i64 @@ -155,7 +155,7 @@ ; CHECK-NEXT: %i6 = getelementptr i8, ptr %i5, i64 16 ; CHECK-NEXT: --> (16 + (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64)) + %second_obj) U: full-set S: full-set ; CHECK-NEXT: %i7 = select i1 %i3, ptr %first_obj, ptr %i6 -; CHECK-NEXT: --> %i7 U: full-set S: full-set +; CHECK-NEXT: --> (select %i3, %first_obj, (16 + (-1 * (zext i4 (trunc i64 (ptrtoint ptr %obj_donor to i64) to i4) to i64)) + %second_obj)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @pointer_align_up_with_select_different_objects_bad ; %i = ptrtoint ptr %obj_donor to i64 diff --git a/llvm/test/Analysis/ScalarEvolution/pointer-select.ll b/llvm/test/Analysis/ScalarEvolution/pointer-select.ll --- a/llvm/test/Analysis/ScalarEvolution/pointer-select.ll +++ b/llvm/test/Analysis/ScalarEvolution/pointer-select.ll @@ -5,7 +5,7 @@ ; CHECK-LABEL: 'pointer_select_two_objects' ; CHECK-NEXT: Classifying expressions for: @pointer_select_two_objects ; CHECK-NEXT: %r = select i1 %cond, ptr %first_obj, ptr %second_obj -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %cond, %first_obj, %second_obj) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @pointer_select_two_objects ; %r = select i1 %cond, ptr %first_obj, ptr %second_obj @@ -22,7 +22,7 @@ ; CHECK-NEXT: %false_ptr = getelementptr i8, ptr %obj, i64 24 ; CHECK-NEXT: --> (24 + %obj) U: full-set S: full-set ; CHECK-NEXT: %r = select i1 %cond, ptr %true_ptr, ptr %false_ptr -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %cond, (42 + %obj), (24 + %obj)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @pointer_select_same_object_constant_offsets ; %true_ptr = getelementptr i8, ptr %obj, i64 42 @@ -39,7 +39,7 @@ ; CHECK-NEXT: %false_ptr = getelementptr i8, ptr %obj, i64 %false_off ; CHECK-NEXT: --> (%false_off + %obj) U: full-set S: full-set ; CHECK-NEXT: %r = select i1 %cond, ptr %true_ptr, ptr %false_ptr -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %cond, (%true_off + %obj), (%false_off + %obj)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @pointer_select_same_object_variable_offsets ; %true_ptr = getelementptr i8, ptr %obj, i64 %true_off @@ -56,7 +56,7 @@ ; CHECK-NEXT: %false_ptr = getelementptr i8, ptr %obj, i64 %false_off ; CHECK-NEXT: --> (%false_off + %obj) U: full-set S: full-set ; CHECK-NEXT: %r = select i1 %cond, ptr %true_ptr, ptr %false_ptr -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %cond, (42 + %obj), (%false_off + %obj)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @pointer_select_same_object_constant_offset_vs_variable_offset ; %true_ptr = getelementptr i8, ptr %obj, i64 42 @@ -73,7 +73,7 @@ ; CHECK-NEXT: %false_ptr = getelementptr i8, ptr %obj, i64 42 ; CHECK-NEXT: --> (42 + %obj) U: full-set S: full-set ; CHECK-NEXT: %r = select i1 %cond, ptr %true_ptr, ptr %false_ptr -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %cond, (%true_off + %obj), (42 + %obj)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @pointer_select_same_object_variable_offset_vs_constant_offset ; %true_ptr = getelementptr i8, ptr %obj, i64 %true_off @@ -94,7 +94,7 @@ ; CHECK-NEXT: %false_ptr = getelementptr i8, ptr %obj, i64 24 ; CHECK-NEXT: --> (36 + %obj.base) U: full-set S: full-set ; CHECK-NEXT: %r = select i1 %cond, ptr %true_ptr, ptr %false_ptr -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %cond, (54 + %obj.base), (36 + %obj.base)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @pointer_select_same_object_with_constant_base_offset__constant_offsets ; %obj = getelementptr i8, ptr %obj.base, i64 12 @@ -114,7 +114,7 @@ ; CHECK-NEXT: %false_ptr = getelementptr i8, ptr %obj, i64 %false_off ; CHECK-NEXT: --> (12 + %false_off + %obj.base) U: full-set S: full-set ; CHECK-NEXT: %r = select i1 %cond, ptr %true_ptr, ptr %false_ptr -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %cond, (12 + %true_off + %obj.base), (12 + %false_off + %obj.base)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @pointer_select_same_object_with_constant_base_offset__variable_offsets ; %obj = getelementptr i8, ptr %obj.base, i64 12 @@ -134,7 +134,7 @@ ; CHECK-NEXT: %false_ptr = getelementptr i8, ptr %obj, i64 %false_off ; CHECK-NEXT: --> (12 + %false_off + %obj.base) U: full-set S: full-set ; CHECK-NEXT: %r = select i1 %cond, ptr %true_ptr, ptr %false_ptr -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %cond, (54 + %obj.base), (12 + %false_off + %obj.base)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @pointer_select_same_object_with_constant_base_offset__constant_offset_vs_variable_offset ; %obj = getelementptr i8, ptr %obj.base, i64 12 @@ -154,7 +154,7 @@ ; CHECK-NEXT: %false_ptr = getelementptr i8, ptr %obj, i64 42 ; CHECK-NEXT: --> (54 + %obj.base) U: full-set S: full-set ; CHECK-NEXT: %r = select i1 %cond, ptr %true_ptr, ptr %false_ptr -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %cond, (12 + %true_off + %obj.base), (54 + %obj.base)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @pointer_select_same_object_with_constant_base_offset__variable_offset_vs_constant_offset ; %obj = getelementptr i8, ptr %obj.base, i64 12 @@ -176,7 +176,7 @@ ; CHECK-NEXT: %false_ptr = getelementptr i8, ptr %obj, i64 24 ; CHECK-NEXT: --> (24 + %base_offset + %obj.base) U: full-set S: full-set ; CHECK-NEXT: %r = select i1 %cond, ptr %true_ptr, ptr %false_ptr -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %cond, (42 + %base_offset + %obj.base), (24 + %base_offset + %obj.base)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @pointer_select_same_object_with_variable_base_offset__constant_offsets ; %obj = getelementptr i8, ptr %obj.base, i64 %base_offset @@ -196,7 +196,7 @@ ; CHECK-NEXT: %false_ptr = getelementptr i8, ptr %obj, i64 %false_off ; CHECK-NEXT: --> (%base_offset + %false_off + %obj.base) U: full-set S: full-set ; CHECK-NEXT: %r = select i1 %cond, ptr %true_ptr, ptr %false_ptr -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %cond, (%base_offset + %true_off + %obj.base), (%base_offset + %false_off + %obj.base)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @pointer_select_same_object_with_variable_base_offset__variable_offsets ; %obj = getelementptr i8, ptr %obj.base, i64 %base_offset @@ -216,7 +216,7 @@ ; CHECK-NEXT: %false_ptr = getelementptr i8, ptr %obj, i64 %false_off ; CHECK-NEXT: --> (%base_offset + %false_off + %obj.base) U: full-set S: full-set ; CHECK-NEXT: %r = select i1 %cond, ptr %true_ptr, ptr %false_ptr -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %cond, (42 + %base_offset + %obj.base), (%base_offset + %false_off + %obj.base)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @pointer_select_same_object_with_variable_base_offset__constant_offset_vs_variable_offset ; %obj = getelementptr i8, ptr %obj.base, i64 %base_offset @@ -236,7 +236,7 @@ ; CHECK-NEXT: %false_ptr = getelementptr i8, ptr %obj, i64 42 ; CHECK-NEXT: --> (42 + %base_offset + %obj.base) U: full-set S: full-set ; CHECK-NEXT: %r = select i1 %cond, ptr %true_ptr, ptr %false_ptr -; CHECK-NEXT: --> %r U: full-set S: full-set +; CHECK-NEXT: --> (select %cond, (%base_offset + %true_off + %obj.base), (42 + %base_offset + %obj.base)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @pointer_select_same_object_with_variable_base_offset__variable_offset_vs_constant_offset ; %obj = getelementptr i8, ptr %obj.base, i64 %base_offset diff --git a/llvm/test/Analysis/ScalarEvolution/sext-to-zext.ll b/llvm/test/Analysis/ScalarEvolution/sext-to-zext.ll --- a/llvm/test/Analysis/ScalarEvolution/sext-to-zext.ll +++ b/llvm/test/Analysis/ScalarEvolution/sext-to-zext.ll @@ -5,19 +5,19 @@ ; CHECK-LABEL: 'f' ; CHECK-NEXT: Classifying expressions for: @f ; CHECK-NEXT: %start = select i1 %c, i32 100, i32 0 -; CHECK-NEXT: --> %start U: [0,101) S: [0,101) +; CHECK-NEXT: --> (select %c, 100, 0) U: [0,101) S: [0,101) ; CHECK-NEXT: %step = select i1 %c, i32 -1, i32 1 -; CHECK-NEXT: --> %step U: [1,0) S: [-2,2) +; CHECK-NEXT: --> (select %c, -1, 1) U: [-1,2) S: [-1,2) ; CHECK-NEXT: %iv = phi i32 [ %start, %entry ], [ %iv.dec, %loop ] -; CHECK-NEXT: --> {%start,+,%step}<%loop> U: [0,101) S: [0,101) Exits: ((99 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(select %c, 100, 0),+,(select %c, -1, 1)}<%loop> U: [0,101) S: [0,101) Exits: ((99 * (select %c, -1, 1)) + (select %c, 100, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.tc = phi i32 [ 0, %entry ], [ %iv.tc.inc, %loop ] ; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,100) S: [0,100) Exits: 99 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.tc.inc = add i32 %iv.tc, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,101) S: [1,101) Exits: 100 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.dec = add nsw i32 %iv, %step -; CHECK-NEXT: --> {(%step + %start),+,%step}<%loop> U: [-200,201) S: [-200,201) Exits: ((100 * %step) + %start) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {((select %c, 100, 0) + (select %c, -1, 1)),+,(select %c, -1, 1)}<%loop> U: [-100,201) S: [-100,201) Exits: ((100 * (select %c, -1, 1)) + (select %c, 100, 0)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.sext = sext i32 %iv to i64 -; CHECK-NEXT: --> {(zext i32 %start to i64),+,(sext i32 %step to i64)}<%loop> U: [0,101) S: [0,101) Exits: ((zext i32 %start to i64) + (99 * (sext i32 %step to i64))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {(zext i32 (select %c, 100, 0) to i64),+,(sext i32 (select %c, -1, 1) to i64)}<%loop> U: [0,101) S: [0,101) Exits: ((zext i32 (select %c, 100, 0) to i64) + (99 * (sext i32 (select %c, -1, 1) to i64))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: Determining loop execution counts for: @f ; CHECK-NEXT: Loop %loop: backedge-taken count is 99 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 99 diff --git a/llvm/test/Analysis/ScalarEvolution/shift-recurrences.ll b/llvm/test/Analysis/ScalarEvolution/shift-recurrences.ll --- a/llvm/test/Analysis/ScalarEvolution/shift-recurrences.ll +++ b/llvm/test/Analysis/ScalarEvolution/shift-recurrences.ll @@ -231,7 +231,7 @@ ; CHECK-LABEL: 'test_shl3' ; CHECK-NEXT: Classifying expressions for: @test_shl3 ; CHECK-NEXT: %shiftamt = select i1 %c, i64 1, i64 0 -; CHECK-NEXT: --> %shiftamt U: [0,2) S: [0,2) +; CHECK-NEXT: --> (select %c, 1, 0) U: [0,2) S: [0,2) ; CHECK-NEXT: %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] ; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,5) S: [0,5) Exits: 4 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.shl = phi i64 [ 4, %entry ], [ %iv.shl.next, %loop ] diff --git a/llvm/test/Analysis/ScalarEvolution/symbolic_max_exit_count.ll b/llvm/test/Analysis/ScalarEvolution/symbolic_max_exit_count.ll --- a/llvm/test/Analysis/ScalarEvolution/symbolic_max_exit_count.ll +++ b/llvm/test/Analysis/ScalarEvolution/symbolic_max_exit_count.ll @@ -524,7 +524,7 @@ ; CHECK-NEXT: %c2 = and i1 %zero_check_2, %scam_2 ; CHECK-NEXT: --> (%zero_check_2 umin %scam_2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %merged_cond = select i1 %c1, i1 true, i1 %c2 -; CHECK-NEXT: --> (true + ((true + (%zero_check_1 umin %scam_1)) umin_seq (true + (%zero_check_2 umin %scam_2)))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select (%zero_check_1 umin %scam_1), true, (%zero_check_2 umin %scam_2)) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %iv.minus.1 = add i32 %iv_1, -1 ; CHECK-NEXT: --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv_1.next = add i32 %iv_1, -1 @@ -597,7 +597,7 @@ ; CHECK-NEXT: %c2 = and i1 %zero_check_2, %scam_2 ; CHECK-NEXT: --> (%zero_check_2 umin %scam_2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %merged_cond = select i1 %c1, i1 %c2, i1 false -; CHECK-NEXT: --> ((%zero_check_1 umin %scam_1) umin_seq (%zero_check_2 umin %scam_2)) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select (%zero_check_1 umin %scam_1), (%zero_check_2 umin %scam_2), false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %iv.minus.1 = add i32 %iv_1, -1 ; CHECK-NEXT: --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv_1.next = add i32 %iv_1, -1 diff --git a/llvm/test/Analysis/ScalarEvolution/trip-count-minmax.ll b/llvm/test/Analysis/ScalarEvolution/trip-count-minmax.ll --- a/llvm/test/Analysis/ScalarEvolution/trip-count-minmax.ll +++ b/llvm/test/Analysis/ScalarEvolution/trip-count-minmax.ll @@ -256,7 +256,7 @@ ; CHECK-NEXT: %i.next = add nuw nsw i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,-15) S: [1,-15) Exits: (1 + ((-1 + (1 umax (2 * %n))) umin_seq (-1 + (1 umax (16 * %m))))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (select %cond_p0, %cond_p1, false) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @umin_seq2 ; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 + (1 umax (2 * %n))) umin_seq (-1 + (1 umax (16 * %m)))) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -17 diff --git a/llvm/test/Analysis/ScalarEvolution/trivial-phis.ll b/llvm/test/Analysis/ScalarEvolution/trivial-phis.ll --- a/llvm/test/Analysis/ScalarEvolution/trivial-phis.ll +++ b/llvm/test/Analysis/ScalarEvolution/trivial-phis.ll @@ -24,7 +24,7 @@ ; CHECK-LABEL: @test2 ; CHECK: %tmp24 = phi i64 [ %tmp14, %bb22 ], [ %tmp14, %bb13 ] -; CHECK-NEXT: --> %tmp24 U: full-set S: full-set Exits: <> LoopDispositions: { %bb13: Variant, %bb8: Variant, %bb17: Invariant, %bb27: Invariant } +; CHECK-NEXT: --> {1,+,1}<%bb13> U: [1,9223372036854775807) S: [1,9223372036854775807) Exits: (-2 + %arg) LoopDispositions: { %bb13: Computable, %bb8: Variant, %bb17: Invariant, %bb27: Invariant } define void @test2(i64 %arg, ptr noalias %arg1) { bb: diff --git a/llvm/test/Analysis/StackSafetyAnalysis/local.ll b/llvm/test/Analysis/StackSafetyAnalysis/local.ll --- a/llvm/test/Analysis/StackSafetyAnalysis/local.ll +++ b/llvm/test/Analysis/StackSafetyAnalysis/local.ll @@ -338,8 +338,7 @@ ; CHECK-LABEL: @NonConstantOffset dso_preemptable{{$}} ; CHECK-NEXT: args uses: ; CHECK-NEXT: allocas uses: -; FIXME: SCEV can't look through selects. -; CHECK-NEXT: x[4]: [0,4){{$}} +; CHECK-NEXT: x[4]: [1,3){{$}} ; GLOBAL-NEXT: safe accesses: ; GLOBAL-NEXT: store i8 0, ptr %x2, align 1 ; CHECK-EMPTY: @@ -383,7 +382,7 @@ ; CHECK-LABEL: @NonConstantOffsetOOB dso_preemptable{{$}} ; CHECK-NEXT: args uses: ; CHECK-NEXT: allocas uses: -; CHECK-NEXT: x[4]: [0,6){{$}} +; CHECK-NEXT: x[4]: [1,5){{$}} ; GLOBAL-NEXT: safe accesses: ; CHECK-EMPTY: entry: diff --git a/llvm/test/Analysis/StackSafetyAnalysis/memintrin.ll b/llvm/test/Analysis/StackSafetyAnalysis/memintrin.ll --- a/llvm/test/Analysis/StackSafetyAnalysis/memintrin.ll +++ b/llvm/test/Analysis/StackSafetyAnalysis/memintrin.ll @@ -70,8 +70,9 @@ ; CHECK-LABEL: MemsetNonConstInBounds dso_preemptable{{$}} ; CHECK-NEXT: args uses: ; CHECK-NEXT: allocas uses: -; CHECK-NEXT: x[4]: [0,7){{$}} +; CHECK-NEXT: x[4]: [0,4){{$}} ; GLOBAL-NEXT: safe accesses: +; GLOBAL-NEXT: call void @llvm.memset.p0.i32(ptr %x, i8 42, i32 %size, i1 false) ; CHECK-EMPTY: entry: %x = alloca i32, align 4 diff --git a/llvm/test/Transforms/IRCE/decrementing-loop.ll b/llvm/test/Transforms/IRCE/decrementing-loop.ll --- a/llvm/test/Transforms/IRCE/decrementing-loop.ll +++ b/llvm/test/Transforms/IRCE/decrementing-loop.ll @@ -114,16 +114,11 @@ ret void } -; Check that we can figure out that IV is non-negative via implication through -; Phi node. +; FIXME: we should figure out that IV is non-negative via implication through Phi node. define void @test_03(ptr %a, ptr %a_len_ptr, i1 %cond) { ; CHECK-LABEL: test_03 -; CHECK: mainloop: -; CHECK-NEXT: br label %loop -; CHECK: loop: -; CHECK: br i1 true, label %in.bounds, label %out.of.bounds -; CHECK: loop.preloop: +; CHECK-NOT: mainloop: entry: %len.a = load i32, ptr %a_len_ptr, !range !0 @@ -161,16 +156,11 @@ ret void } -; Check that we can figure out that IV is non-negative via implication through -; two Phi nodes. +; FIXME: we should figure out that IV is non-negative via implication through two Phi nodes. define void @test_04(ptr %a, ptr %a_len_ptr, i1 %cond) { ; CHECK-LABEL: test_04 -; CHECK: mainloop: -; CHECK-NEXT: br label %loop -; CHECK: loop: -; CHECK: br i1 true, label %in.bounds, label %out.of.bounds -; CHECK: loop.preloop: +; CHECK-NOT: mainloop: entry: %len.a = load i32, ptr %a_len_ptr, !range !0 diff --git a/llvm/test/Transforms/IndVarSimplify/lftr-pr20680.ll b/llvm/test/Transforms/IndVarSimplify/lftr-pr20680.ll --- a/llvm/test/Transforms/IndVarSimplify/lftr-pr20680.ll +++ b/llvm/test/Transforms/IndVarSimplify/lftr-pr20680.ll @@ -21,9 +21,6 @@ ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i32 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC13:%.*]] ], [ -14, [[ENTRY:%.*]] ] ; CHECK-NEXT: br i1 [[TOBOOL2]], label [[FOR_INC13]], label [[FOR_BODY3_LR_PH:%.*]] ; CHECK: for.body3.lr.ph: -; CHECK-NEXT: [[TMP2:%.*]] = add nsw i32 [[INDVARS_IV]], 1 -; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i32 [[TMP2]], 3 -; CHECK-NEXT: [[DIV:%.*]] = select i1 [[TMP3]], i32 [[INDVARS_IV]], i32 0 ; CHECK-NEXT: br i1 false, label [[FOR_BODY3_LR_PH_SPLIT_US:%.*]], label [[FOR_BODY3_LR_PH_FOR_BODY3_LR_PH_SPLIT_CRIT_EDGE:%.*]] ; CHECK: for.body3.lr.ph.for.body3.lr.ph.split_crit_edge: ; CHECK-NEXT: br label [[FOR_BODY3_LR_PH_SPLIT:%.*]] @@ -38,8 +35,8 @@ ; CHECK: cond.false.us.us: ; CHECK-NEXT: br label [[COND_END_US_US]] ; CHECK: cond.end.us.us: -; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr @b, align 4 -; CHECK-NEXT: [[CMP91_US_US:%.*]] = icmp slt i32 [[TMP4]], 1 +; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr @b, align 4 +; CHECK-NEXT: [[CMP91_US_US:%.*]] = icmp slt i32 [[TMP2]], 1 ; CHECK-NEXT: br i1 [[CMP91_US_US]], label [[FOR_INC_LR_PH_US_US:%.*]], label [[FOR_COND2_LOOPEXIT_US_US:%.*]] ; CHECK: for.cond2.loopexit.us.us: ; CHECK-NEXT: br i1 true, label [[FOR_COND2_FOR_INC13_CRIT_EDGE_US_LCSSA_US_US_LCSSA_US:%.*]], label [[FOR_BODY3_US_US]] @@ -49,8 +46,8 @@ ; CHECK-NEXT: store i32 1, ptr @b, align 4 ; CHECK-NEXT: br label [[FOR_COND2_LOOPEXIT_US_US]] ; CHECK: for.inc.us.us: -; CHECK-NEXT: [[TMP5:%.*]] = phi i32 [ [[TMP4]], [[FOR_INC_LR_PH_US_US]] ], [ [[INC_US_US:%.*]], [[FOR_INC_US_US]] ] -; CHECK-NEXT: [[INC_US_US]] = add nsw i32 [[TMP5]], 1 +; CHECK-NEXT: [[TMP3:%.*]] = phi i32 [ [[TMP2]], [[FOR_INC_LR_PH_US_US]] ], [ [[INC_US_US:%.*]], [[FOR_INC_US_US]] ] +; CHECK-NEXT: [[INC_US_US]] = add nsw i32 [[TMP3]], 1 ; CHECK-NEXT: [[EXITCOND3:%.*]] = icmp ne i32 [[INC_US_US]], 1 ; CHECK-NEXT: br i1 [[EXITCOND3]], label [[FOR_INC_US_US]], label [[FOR_COND8_FOR_COND2_LOOPEXIT_CRIT_EDGE_US_US:%.*]] ; CHECK: for.cond2.for.inc13_crit_edge.us-lcssa.us.us-lcssa.us: @@ -62,12 +59,12 @@ ; CHECK: cond.false.us: ; CHECK-NEXT: br label [[COND_END_US]] ; CHECK: cond.end.us: -; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr @b, align 4 -; CHECK-NEXT: [[CMP91_US:%.*]] = icmp slt i32 [[TMP6]], 1 +; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr @b, align 4 +; CHECK-NEXT: [[CMP91_US:%.*]] = icmp slt i32 [[TMP4]], 1 ; CHECK-NEXT: br i1 [[CMP91_US]], label [[FOR_INC_LR_PH_US:%.*]], label [[FOR_COND2_LOOPEXIT_US:%.*]] ; CHECK: for.inc.us: -; CHECK-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP6]], [[FOR_INC_LR_PH_US]] ], [ [[INC_US:%.*]], [[FOR_INC_US:%.*]] ] -; CHECK-NEXT: [[INC_US]] = add nsw i32 [[TMP7]], 1 +; CHECK-NEXT: [[TMP5:%.*]] = phi i32 [ [[TMP4]], [[FOR_INC_LR_PH_US]] ], [ [[INC_US:%.*]], [[FOR_INC_US:%.*]] ] +; CHECK-NEXT: [[INC_US]] = add nsw i32 [[TMP5]], 1 ; CHECK-NEXT: [[EXITCOND2:%.*]] = icmp ne i32 [[INC_US]], 1 ; CHECK-NEXT: br i1 [[EXITCOND2]], label [[FOR_INC_US]], label [[FOR_COND8_FOR_COND2_LOOPEXIT_CRIT_EDGE_US:%.*]] ; CHECK: for.cond2.loopexit.us: @@ -80,7 +77,6 @@ ; CHECK: for.cond2.for.inc13_crit_edge.us-lcssa.us.us-lcssa: ; CHECK-NEXT: br label [[FOR_COND2_FOR_INC13_CRIT_EDGE_US_LCSSA_US]] ; CHECK: for.cond2.for.inc13_crit_edge.us-lcssa.us: -; CHECK-NEXT: [[COND_LCSSA_PH_US:%.*]] = phi i32 [ [[DIV]], [[FOR_COND2_FOR_INC13_CRIT_EDGE_US_LCSSA_US_US_LCSSA]] ], [ [[DIV]], [[FOR_COND2_FOR_INC13_CRIT_EDGE_US_LCSSA_US_US_LCSSA_US]] ] ; CHECK-NEXT: br label [[FOR_COND2_FOR_INC13_CRIT_EDGE:%.*]] ; CHECK: for.body3.lr.ph.split: ; CHECK-NEXT: br i1 [[TOBOOL]], label [[FOR_BODY3_LR_PH_SPLIT_SPLIT_US:%.*]], label [[FOR_BODY3_LR_PH_SPLIT_FOR_BODY3_LR_PH_SPLIT_SPLIT_CRIT_EDGE:%.*]] @@ -93,12 +89,12 @@ ; CHECK: cond.false.us4: ; CHECK-NEXT: br label [[COND_END_US5]] ; CHECK: cond.end.us5: -; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr @b, align 4 -; CHECK-NEXT: [[CMP91_US7:%.*]] = icmp slt i32 [[TMP8]], 1 +; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr @b, align 4 +; CHECK-NEXT: [[CMP91_US7:%.*]] = icmp slt i32 [[TMP6]], 1 ; CHECK-NEXT: br i1 [[CMP91_US7]], label [[FOR_INC_LR_PH_US12:%.*]], label [[FOR_COND2_LOOPEXIT_US11:%.*]] ; CHECK: for.inc.us8: -; CHECK-NEXT: [[TMP9:%.*]] = phi i32 [ [[TMP8]], [[FOR_INC_LR_PH_US12]] ], [ [[INC_US9:%.*]], [[FOR_INC_US8:%.*]] ] -; CHECK-NEXT: [[INC_US9]] = add nsw i32 [[TMP9]], 1 +; CHECK-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP6]], [[FOR_INC_LR_PH_US12]] ], [ [[INC_US9:%.*]], [[FOR_INC_US8:%.*]] ] +; CHECK-NEXT: [[INC_US9]] = add nsw i32 [[TMP7]], 1 ; CHECK-NEXT: [[EXITCOND1:%.*]] = icmp ne i32 [[INC_US9]], 1 ; CHECK-NEXT: br i1 [[EXITCOND1]], label [[FOR_INC_US8]], label [[FOR_COND8_FOR_COND2_LOOPEXIT_CRIT_EDGE_US13:%.*]] ; CHECK: for.cond2.loopexit.us11: @@ -122,24 +118,22 @@ ; CHECK: cond.false: ; CHECK-NEXT: br label [[COND_END]] ; CHECK: cond.end: -; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr @b, align 4 -; CHECK-NEXT: [[CMP91:%.*]] = icmp slt i32 [[TMP10]], 1 +; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr @b, align 4 +; CHECK-NEXT: [[CMP91:%.*]] = icmp slt i32 [[TMP8]], 1 ; CHECK-NEXT: br i1 [[CMP91]], label [[FOR_INC_LR_PH:%.*]], label [[FOR_COND2_LOOPEXIT]] ; CHECK: for.inc.lr.ph: ; CHECK-NEXT: br label [[FOR_INC:%.*]] ; CHECK: for.inc: -; CHECK-NEXT: [[TMP11:%.*]] = phi i32 [ [[TMP10]], [[FOR_INC_LR_PH]] ], [ [[INC:%.*]], [[FOR_INC]] ] -; CHECK-NEXT: [[INC]] = add nsw i32 [[TMP11]], 1 +; CHECK-NEXT: [[TMP9:%.*]] = phi i32 [ [[TMP8]], [[FOR_INC_LR_PH]] ], [ [[INC:%.*]], [[FOR_INC]] ] +; CHECK-NEXT: [[INC]] = add nsw i32 [[TMP9]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[INC]], 1 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_INC]], label [[FOR_COND8_FOR_COND2_LOOPEXIT_CRIT_EDGE:%.*]] ; CHECK: for.cond2.for.inc13_crit_edge.us-lcssa.us-lcssa: ; CHECK-NEXT: br label [[FOR_COND2_FOR_INC13_CRIT_EDGE_US_LCSSA]] ; CHECK: for.cond2.for.inc13_crit_edge.us-lcssa: -; CHECK-NEXT: [[COND_LCSSA_PH:%.*]] = phi i32 [ [[INDVARS_IV]], [[FOR_COND2_FOR_INC13_CRIT_EDGE_US_LCSSA_US_LCSSA]] ], [ [[INDVARS_IV]], [[FOR_COND2_FOR_INC13_CRIT_EDGE_US_LCSSA_US_LCSSA_US]] ] ; CHECK-NEXT: br label [[FOR_COND2_FOR_INC13_CRIT_EDGE]] ; CHECK: for.cond2.for.inc13_crit_edge: -; CHECK-NEXT: [[COND_LCSSA:%.*]] = phi i32 [ [[COND_LCSSA_PH]], [[FOR_COND2_FOR_INC13_CRIT_EDGE_US_LCSSA]] ], [ [[COND_LCSSA_PH_US]], [[FOR_COND2_FOR_INC13_CRIT_EDGE_US_LCSSA_US]] ] -; CHECK-NEXT: store i32 [[COND_LCSSA]], ptr @c, align 4 +; CHECK-NEXT: store i32 [[INDVARS_IV]], ptr @c, align 4 ; CHECK-NEXT: br label [[FOR_INC13]] ; CHECK: for.inc13: ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i32 [[INDVARS_IV]], 1 diff --git a/llvm/test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll b/llvm/test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll --- a/llvm/test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll +++ b/llvm/test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll @@ -336,7 +336,8 @@ ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ [[TMP0]], [[PREHEADER]] ] ; CHECK-NEXT: [[EL:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]] ; CHECK-NEXT: store atomic i32 0, ptr [[EL]] unordered, align 4 -; CHECK-NEXT: [[LOOPCOND:%.*]] = icmp slt i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[INDVARS_IV]] to i32 +; CHECK-NEXT: [[LOOPCOND:%.*]] = icmp slt i32 [[TMP1]], 1 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 ; CHECK-NEXT: br i1 [[LOOPCOND]], label [[LOOPEXIT_LOOPEXIT:%.*]], label [[LOOP]] ; @@ -398,7 +399,8 @@ ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ [[TMP0]], [[PREHEADER]] ] ; CHECK-NEXT: [[EL:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]] ; CHECK-NEXT: store atomic i32 0, ptr [[EL]] unordered, align 4 -; CHECK-NEXT: [[LOOPCOND:%.*]] = icmp slt i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[INDVARS_IV]] to i32 +; CHECK-NEXT: [[LOOPCOND:%.*]] = icmp slt i32 [[TMP1]], 1 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1 ; CHECK-NEXT: br i1 [[LOOPCOND]], label [[LOOPEXIT_LOOPEXIT:%.*]], label [[LOOP]] ; diff --git a/llvm/test/Transforms/LoopVectorize/single-value-blend-phis.ll b/llvm/test/Transforms/LoopVectorize/single-value-blend-phis.ll --- a/llvm/test/Transforms/LoopVectorize/single-value-blend-phis.ll +++ b/llvm/test/Transforms/LoopVectorize/single-value-blend-phis.ll @@ -57,7 +57,7 @@ ; CHECK-NEXT: store i16 [[RES]], ptr [[DST_PTR]], align 2 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 ; CHECK-NEXT: [[CMP439:%.*]] = icmp ult i64 [[IV]], 31 -; CHECK-NEXT: br i1 [[CMP439]], label [[LOOP_HEADER]], label [[EXIT]], !llvm.loop [[LOOP2:![0-9]+]] +; CHECK-NEXT: br i1 [[CMP439]], label [[LOOP_HEADER]], label [[EXIT]], !llvm.loop [[LOOP3:![0-9]+]] ; CHECK: exit: ; CHECK-NEXT: ret void ; @@ -194,31 +194,31 @@ ; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <2 x i64> [[BROADCAST_SPLATINSERT]], <2 x i64> poison, <2 x i32> zeroinitializer ; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] ; CHECK: vector.body: -; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[OFFSET_IDX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] -; CHECK-NEXT: [[VEC_IND1:%.*]] = phi <2 x i16> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT2:%.*]], [[VECTOR_BODY]] ] -; CHECK-NEXT: [[VEC_IND3:%.*]] = phi <2 x i16> [ , [[VECTOR_PH]] ], [ [[VEC_IND_NEXT4:%.*]], [[VECTOR_BODY]] ] -; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 -; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt <2 x i64> [[VEC_IND]], [[BROADCAST_SPLAT]] -; CHECK-NEXT: [[TMP2:%.*]] = xor <2 x i1> [[TMP1]], -; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP1]], <2 x i16> [[VEC_IND3]], <2 x i16> [[VEC_IND1]] -; CHECK-NEXT: [[TMP3:%.*]] = extractelement <2 x i16> [[PREDPHI]], i32 0 -; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [32 x i16], ptr @src, i16 0, i16 [[TMP3]] -; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i16> [[PREDPHI]], i32 1 -; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds [32 x i16], ptr @src, i16 0, i16 [[TMP5]] -; CHECK-NEXT: [[TMP7:%.*]] = load i16, ptr [[TMP4]], align 1 -; CHECK-NEXT: [[TMP8:%.*]] = load i16, ptr [[TMP6]], align 1 -; CHECK-NEXT: [[TMP9:%.*]] = insertelement <2 x i16> poison, i16 [[TMP7]], i32 0 -; CHECK-NEXT: [[TMP10:%.*]] = insertelement <2 x i16> [[TMP9]], i16 [[TMP8]], i32 1 -; CHECK-NEXT: [[TMP11:%.*]] = getelementptr inbounds i16, ptr [[DST:%.*]], i64 [[TMP0]] -; CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds i16, ptr [[TMP11]], i32 0 -; CHECK-NEXT: store <2 x i16> [[TMP10]], ptr [[TMP12]], align 2 -; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 +; CHECK-NEXT: [[TMP0:%.*]] = trunc i64 [[OFFSET_IDX]] to i16 +; CHECK-NEXT: [[TMP1:%.*]] = add i16 [[TMP0]], 0 +; CHECK-NEXT: [[BROADCAST_SPLATINSERT3:%.*]] = insertelement <2 x i16> poison, i16 [[TMP1]], i64 0 +; CHECK-NEXT: [[BROADCAST_SPLAT4:%.*]] = shufflevector <2 x i16> [[BROADCAST_SPLATINSERT3]], <2 x i16> poison, <2 x i32> zeroinitializer +; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[OFFSET_IDX]] to i16 +; CHECK-NEXT: [[TMP3:%.*]] = add i16 [[TMP2]], 0 +; CHECK-NEXT: [[BROADCAST_SPLATINSERT1:%.*]] = insertelement <2 x i16> poison, i16 [[TMP3]], i64 0 +; CHECK-NEXT: [[BROADCAST_SPLAT2:%.*]] = shufflevector <2 x i16> [[BROADCAST_SPLATINSERT1]], <2 x i16> poison, <2 x i32> zeroinitializer +; CHECK-NEXT: [[TMP4:%.*]] = add i64 [[OFFSET_IDX]], 0 +; CHECK-NEXT: [[TMP5:%.*]] = icmp ugt <2 x i64> [[VEC_IND]], [[BROADCAST_SPLAT]] +; CHECK-NEXT: [[TMP6:%.*]] = xor <2 x i1> [[TMP5]], +; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP5]], <2 x i16> [[BROADCAST_SPLAT4]], <2 x i16> [[BROADCAST_SPLAT2]] +; CHECK-NEXT: [[TMP7:%.*]] = extractelement <2 x i16> [[PREDPHI]], i32 0 +; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds [32 x i16], ptr @src, i16 0, i16 [[TMP7]] +; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i16, ptr [[TMP8]], i32 0 +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i16>, ptr [[TMP9]], align 1 +; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i16, ptr [[DST:%.*]], i64 [[TMP4]] +; CHECK-NEXT: [[TMP11:%.*]] = getelementptr inbounds i16, ptr [[TMP10]], i32 0 +; CHECK-NEXT: store <2 x i16> [[WIDE_LOAD]], ptr [[TMP11]], align 2 +; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[OFFSET_IDX]], 2 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], -; CHECK-NEXT: [[VEC_IND_NEXT2]] = add <2 x i16> [[VEC_IND1]], -; CHECK-NEXT: [[VEC_IND_NEXT4]] = add <2 x i16> [[VEC_IND3]], -; CHECK-NEXT: [[TMP13:%.*]] = icmp eq i64 [[INDEX_NEXT]], 32 -; CHECK-NEXT: br i1 [[TMP13]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]] +; CHECK-NEXT: [[TMP12:%.*]] = icmp eq i64 [[INDEX_NEXT]], 32 +; CHECK-NEXT: br i1 [[TMP12]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]] ; CHECK: middle.block: ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 32, 32 ; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]] diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/update-scev.ll b/llvm/test/Transforms/SimpleLoopUnswitch/update-scev.ll --- a/llvm/test/Transforms/SimpleLoopUnswitch/update-scev.ll +++ b/llvm/test/Transforms/SimpleLoopUnswitch/update-scev.ll @@ -12,7 +12,7 @@ ; Check that SCEV has no trip count before unswitching. ; SCEV-LABEL: Determining loop execution counts for: @test1 ; SCEV: Loop %inner_loop_begin: Unpredictable backedge-taken count. -; SCEV: Loop %outer_loop_begin: Unpredictable backedge-taken count. +; SCEV: Loop %outer_loop_begin: Predicated backedge-taken count is (-1 + (1 smax %n)) ; ; Now check that after unswitching and simplifying instructions we get clean ; backedge-taken counts. diff --git a/llvm/unittests/Transforms/Utils/ScalarEvolutionExpanderTest.cpp b/llvm/unittests/Transforms/Utils/ScalarEvolutionExpanderTest.cpp --- a/llvm/unittests/Transforms/Utils/ScalarEvolutionExpanderTest.cpp +++ b/llvm/unittests/Transforms/Utils/ScalarEvolutionExpanderTest.cpp @@ -117,8 +117,20 @@ CastInst::CreateBitOrPointerCast(Sel, I32PtrTy, "bitcast2", Br); ScalarEvolution SE = buildSE(*F); - auto *S = SE.getSCEV(CastB); - EXPECT_TRUE(isa(S)); + auto *TrueS = SE.getSCEV(CastB); + + // (select %cmp, (5 + %alloca), (1 + undef)) + auto *ExpectedS = SE.getSelectExpr({ + SE.getSCEV(Cmp), + SE.getAddExpr( + SE.getSCEV(Alloca), + SE.getConstant(SE.getEffectiveSCEVType(Alloca->getType()), 5)), + SE.getAddExpr( + SE.getSCEV(UndefValue::get(I8PtrTy)), + SE.getConstant(SE.getEffectiveSCEVType(Alloca->getType()), 1)), + }); + + EXPECT_EQ(ExpectedS, TrueS); } // Make sure that SCEV doesn't introduce illegal ptrtoint/inttoptr instructions diff --git a/polly/include/polly/Support/SCEVAffinator.h b/polly/include/polly/Support/SCEVAffinator.h --- a/polly/include/polly/Support/SCEVAffinator.h +++ b/polly/include/polly/Support/SCEVAffinator.h @@ -112,6 +112,7 @@ PWACtx visitUMaxExpr(const llvm::SCEVUMaxExpr *E); PWACtx visitUMinExpr(const llvm::SCEVUMinExpr *E); PWACtx visitSequentialUMinExpr(const llvm::SCEVSequentialUMinExpr *E); + PWACtx visitSelectExpr(const llvm::SCEVSelectExpr *E); PWACtx visitUnknown(const llvm::SCEVUnknown *E); PWACtx visitSDivInstruction(llvm::Instruction *SDiv); PWACtx visitSRemInstruction(llvm::Instruction *SRem); diff --git a/polly/lib/Support/SCEVAffinator.cpp b/polly/lib/Support/SCEVAffinator.cpp --- a/polly/lib/Support/SCEVAffinator.cpp +++ b/polly/lib/Support/SCEVAffinator.cpp @@ -470,6 +470,10 @@ llvm_unreachable("SCEVSequentialUMinExpr not yet supported"); } +PWACtx SCEVAffinator::visitSelectExpr(const SCEVSelectExpr *Expr) { + llvm_unreachable("SCEVSelectExpr not yet supported"); +} + PWACtx SCEVAffinator::visitUDivExpr(const SCEVUDivExpr *Expr) { // The handling of unsigned division is basically the same as for signed // division, except the interpretation of the operands. As the divisor diff --git a/polly/lib/Support/SCEVValidator.cpp b/polly/lib/Support/SCEVValidator.cpp --- a/polly/lib/Support/SCEVValidator.cpp +++ b/polly/lib/Support/SCEVValidator.cpp @@ -348,6 +348,11 @@ return ValidatorResult(SCEVType::PARAM, Expr); } + ValidatorResult visitSelectExpr(const SCEVSelectExpr *Expr) { + // FIXME: what do we want to happen here? + return ValidatorResult(SCEVType::INVALID); + } + ValidatorResult visitGenericInst(Instruction *I, const SCEV *S) { if (R->contains(I)) { LLVM_DEBUG(dbgs() << "INVALID: UnknownExpr references an instruction " diff --git a/polly/lib/Support/ScopHelper.cpp b/polly/lib/Support/ScopHelper.cpp --- a/polly/lib/Support/ScopHelper.cpp +++ b/polly/lib/Support/ScopHelper.cpp @@ -398,6 +398,12 @@ NewOps.push_back(visit(Op)); return SE.getUMinExpr(NewOps, /*Sequential=*/true); } + const SCEV *visitSelectExpr(const SCEVSelectExpr *E) { + SmallVector NewOps; + for (const SCEV *Op : E->operands()) + NewOps.push_back(visit(Op)); + return SE.getSelectExpr(NewOps); + } const SCEV *visitAddRecExpr(const SCEVAddRecExpr *E) { SmallVector NewOps; for (const SCEV *Op : E->operands())