diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-12-18 20:30:12 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2024-04-19 21:12:03 +0000 |
| commit | c9157d925c489f07ba9c0b2ce47e5149b75969a5 (patch) | |
| tree | 08bc4a3d9cad3f9ebffa558ddf140b9d9257b219 /contrib/llvm-project/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp | |
| parent | 2a66844f606a35d68ad8a8061f4bea204274b3bc (diff) | |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp | 390 |
1 files changed, 183 insertions, 207 deletions
diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp index 20844271b943..cd3ac317cd23 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp @@ -170,11 +170,10 @@ Value *SCEVExpander::InsertNoopCastOfTo(Value *V, Type *Ty) { if (Op == Instruction::IntToPtr) { auto *PtrTy = cast<PointerType>(Ty); if (DL.isNonIntegralPointerType(PtrTy)) { - auto *Int8PtrTy = Builder.getInt8PtrTy(PtrTy->getAddressSpace()); assert(DL.getTypeAllocSize(Builder.getInt8Ty()) == 1 && "alloc size of i8 must by 1 byte for the GEP to be correct"); return Builder.CreateGEP( - Builder.getInt8Ty(), Constant::getNullValue(Int8PtrTy), V, "scevgep"); + Builder.getInt8Ty(), Constant::getNullValue(PtrTy), V, "scevgep"); } } // Short-circuit unnecessary bitcasts. @@ -313,11 +312,11 @@ Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode, /// loop-invariant portions of expressions, after considering what /// can be folded using target addressing modes. /// -Value *SCEVExpander::expandAddToGEP(const SCEV *Offset, Type *Ty, Value *V) { +Value *SCEVExpander::expandAddToGEP(const SCEV *Offset, Value *V) { assert(!isa<Instruction>(V) || SE.DT.dominates(cast<Instruction>(V), &*Builder.GetInsertPoint())); - Value *Idx = expandCodeForImpl(Offset, Ty); + Value *Idx = expand(Offset); // Fold a GEP with constant operands. if (Constant *CLHS = dyn_cast<Constant>(V)) @@ -339,7 +338,7 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *Offset, Type *Ty, Value *V) { if (IP->getOpcode() == Instruction::GetElementPtr && IP->getOperand(0) == V && IP->getOperand(1) == Idx && cast<GEPOperator>(&*IP)->getSourceElementType() == - Type::getInt8Ty(Ty->getContext())) + Builder.getInt8Ty()) return &*IP; if (IP == BlockBegin) break; } @@ -457,8 +456,6 @@ public: } Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) { - Type *Ty = SE.getEffectiveSCEVType(S->getType()); - // Collect all the add operands in a loop, along with their associated loops. // Iterate in reverse so that constants are emitted last, all else equal, and // so that pointer operands are inserted first, which the code below relies on @@ -498,20 +495,19 @@ Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) { X = SE.getSCEV(U->getValue()); NewOps.push_back(X); } - Sum = expandAddToGEP(SE.getAddExpr(NewOps), Ty, Sum); + Sum = expandAddToGEP(SE.getAddExpr(NewOps), Sum); } else if (Op->isNonConstantNegative()) { // Instead of doing a negate and add, just do a subtract. - Value *W = expandCodeForImpl(SE.getNegativeSCEV(Op), Ty); - Sum = InsertNoopCastOfTo(Sum, Ty); + Value *W = expand(SE.getNegativeSCEV(Op)); Sum = InsertBinop(Instruction::Sub, Sum, W, SCEV::FlagAnyWrap, /*IsSafeToHoist*/ true); ++I; } else { // A simple add. - Value *W = expandCodeForImpl(Op, Ty); - Sum = InsertNoopCastOfTo(Sum, Ty); + Value *W = expand(Op); // Canonicalize a constant to the RHS. - if (isa<Constant>(Sum)) std::swap(Sum, W); + if (isa<Constant>(Sum)) + std::swap(Sum, W); Sum = InsertBinop(Instruction::Add, Sum, W, S->getNoWrapFlags(), /*IsSafeToHoist*/ true); ++I; @@ -522,7 +518,7 @@ Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) { } Value *SCEVExpander::visitMulExpr(const SCEVMulExpr *S) { - Type *Ty = SE.getEffectiveSCEVType(S->getType()); + Type *Ty = S->getType(); // Collect all the mul operands in a loop, along with their associated loops. // Iterate in reverse so that constants are emitted last, all else equal. @@ -541,7 +537,7 @@ Value *SCEVExpander::visitMulExpr(const SCEVMulExpr *S) { // Expand the calculation of X pow N in the following manner: // Let N = P1 + P2 + ... + PK, where all P are powers of 2. Then: // X pow N = (X pow P1) * (X pow P2) * ... * (X pow PK). - const auto ExpandOpBinPowN = [this, &I, &OpsAndLoops, &Ty]() { + const auto ExpandOpBinPowN = [this, &I, &OpsAndLoops]() { auto E = I; // Calculate how many times the same operand from the same loop is included // into this power. @@ -559,7 +555,7 @@ Value *SCEVExpander::visitMulExpr(const SCEVMulExpr *S) { // Calculate powers with exponents 1, 2, 4, 8 etc. and include those of them // that are needed into the result. - Value *P = expandCodeForImpl(I->second, Ty); + Value *P = expand(I->second); Value *Result = nullptr; if (Exponent & 1) Result = P; @@ -584,14 +580,12 @@ Value *SCEVExpander::visitMulExpr(const SCEVMulExpr *S) { Prod = ExpandOpBinPowN(); } else if (I->second->isAllOnesValue()) { // Instead of doing a multiply by negative one, just do a negate. - Prod = InsertNoopCastOfTo(Prod, Ty); Prod = InsertBinop(Instruction::Sub, Constant::getNullValue(Ty), Prod, SCEV::FlagAnyWrap, /*IsSafeToHoist*/ true); ++I; } else { // A simple mul. Value *W = ExpandOpBinPowN(); - Prod = InsertNoopCastOfTo(Prod, Ty); // Canonicalize a constant to the RHS. if (isa<Constant>(Prod)) std::swap(Prod, W); const APInt *RHS; @@ -616,18 +610,16 @@ Value *SCEVExpander::visitMulExpr(const SCEVMulExpr *S) { } Value *SCEVExpander::visitUDivExpr(const SCEVUDivExpr *S) { - Type *Ty = SE.getEffectiveSCEVType(S->getType()); - - Value *LHS = expandCodeForImpl(S->getLHS(), Ty); + Value *LHS = expand(S->getLHS()); if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(S->getRHS())) { const APInt &RHS = SC->getAPInt(); if (RHS.isPowerOf2()) return InsertBinop(Instruction::LShr, LHS, - ConstantInt::get(Ty, RHS.logBase2()), + ConstantInt::get(SC->getType(), RHS.logBase2()), SCEV::FlagAnyWrap, /*IsSafeToHoist*/ true); } - Value *RHS = expandCodeForImpl(S->getRHS(), Ty); + Value *RHS = expand(S->getRHS()); return InsertBinop(Instruction::UDiv, LHS, RHS, SCEV::FlagAnyWrap, /*IsSafeToHoist*/ SE.isKnownNonZero(S->getRHS())); } @@ -803,12 +795,11 @@ bool SCEVExpander::isExpandedAddRecExprPHI(PHINode *PN, Instruction *IncV, /// Typically this is the LatchBlock terminator or IVIncInsertPos, but we may /// need to materialize IV increments elsewhere to handle difficult situations. Value *SCEVExpander::expandIVInc(PHINode *PN, Value *StepV, const Loop *L, - Type *ExpandTy, Type *IntTy, bool useSubtract) { Value *IncV; // If the PHI is a pointer, use a GEP, otherwise use an add or sub. - if (ExpandTy->isPointerTy()) { - IncV = expandAddToGEP(SE.getSCEV(StepV), IntTy, PN); + if (PN->getType()->isPointerTy()) { + IncV = expandAddToGEP(SE.getSCEV(StepV), PN); } else { IncV = useSubtract ? Builder.CreateSub(PN, StepV, Twine(IVName) + ".iv.next") : @@ -824,12 +815,11 @@ static bool canBeCheaplyTransformed(ScalarEvolution &SE, const SCEVAddRecExpr *Requested, bool &InvertStep) { // We can't transform to match a pointer PHI. - if (Phi->getType()->isPointerTy()) + Type *PhiTy = Phi->getType(); + Type *RequestedTy = Requested->getType(); + if (PhiTy->isPointerTy() || RequestedTy->isPointerTy()) return false; - Type *PhiTy = SE.getEffectiveSCEVType(Phi->getType()); - Type *RequestedTy = SE.getEffectiveSCEVType(Requested->getType()); - if (RequestedTy->getIntegerBitWidth() > PhiTy->getIntegerBitWidth()) return false; @@ -886,12 +876,10 @@ static bool IsIncrementNUW(ScalarEvolution &SE, const SCEVAddRecExpr *AR) { /// values, and return the PHI. PHINode * SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized, - const Loop *L, - Type *ExpandTy, - Type *IntTy, - Type *&TruncTy, + const Loop *L, Type *&TruncTy, bool &InvertStep) { - assert((!IVIncInsertLoop||IVIncInsertPos) && "Uninitialized insert position"); + assert((!IVIncInsertLoop || IVIncInsertPos) && + "Uninitialized insert position"); // Reuse a previously-inserted PHI, if present. BasicBlock *LatchBlock = L->getLoopLatch(); @@ -962,7 +950,7 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized, // later. AddRecPhiMatch = &PN; IncV = TempIncV; - TruncTy = SE.getEffectiveSCEVType(Normalized->getType()); + TruncTy = Normalized->getType(); } } @@ -996,8 +984,7 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized, assert(L->getLoopPreheader() && "Can't expand add recurrences without a loop preheader!"); Value *StartV = - expandCodeForImpl(Normalized->getStart(), ExpandTy, - L->getLoopPreheader()->getTerminator()); + expand(Normalized->getStart(), L->getLoopPreheader()->getTerminator()); // StartV must have been be inserted into L's preheader to dominate the new // phi. @@ -1008,6 +995,7 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized, // Expand code for the step value. Do this before creating the PHI so that PHI // reuse code doesn't see an incomplete PHI. const SCEV *Step = Normalized->getStepRecurrence(SE); + Type *ExpandTy = Normalized->getType(); // If the stride is negative, insert a sub instead of an add for the increment // (unless it's a constant, because subtracts of constants are canonicalized // to adds). @@ -1015,8 +1003,7 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized, if (useSubtract) Step = SE.getNegativeSCEV(Step); // Expand the step somewhere that dominates the loop header. - Value *StepV = expandCodeForImpl( - Step, IntTy, &*L->getHeader()->getFirstInsertionPt()); + Value *StepV = expand(Step, L->getHeader()->getFirstInsertionPt()); // The no-wrap behavior proved by IsIncrement(NUW|NSW) is only applicable if // we actually do emit an addition. It does not apply if we emit a @@ -1047,7 +1034,7 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized, Instruction *InsertPos = L == IVIncInsertLoop ? IVIncInsertPos : Pred->getTerminator(); Builder.SetInsertPoint(InsertPos); - Value *IncV = expandIVInc(PN, StepV, L, ExpandTy, IntTy, useSubtract); + Value *IncV = expandIVInc(PN, StepV, L, useSubtract); if (isa<OverflowingBinaryOperator>(IncV)) { if (IncrementIsNUW) @@ -1070,8 +1057,6 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized, } Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) { - Type *STy = S->getType(); - Type *IntTy = SE.getEffectiveSCEVType(STy); const Loop *L = S->getLoop(); // Determine a normalized form of this expression, which is the expression @@ -1084,51 +1069,17 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) { normalizeForPostIncUse(S, Loops, SE, /*CheckInvertible=*/false)); } - // Strip off any non-loop-dominating component from the addrec start. - const SCEV *Start = Normalized->getStart(); - const SCEV *PostLoopOffset = nullptr; - if (!SE.properlyDominates(Start, L->getHeader())) { - PostLoopOffset = Start; - Start = SE.getConstant(Normalized->getType(), 0); - Normalized = cast<SCEVAddRecExpr>( - SE.getAddRecExpr(Start, Normalized->getStepRecurrence(SE), - Normalized->getLoop(), - Normalized->getNoWrapFlags(SCEV::FlagNW))); - } - - // Strip off any non-loop-dominating component from the addrec step. + [[maybe_unused]] const SCEV *Start = Normalized->getStart(); const SCEV *Step = Normalized->getStepRecurrence(SE); - const SCEV *PostLoopScale = nullptr; - if (!SE.dominates(Step, L->getHeader())) { - PostLoopScale = Step; - Step = SE.getConstant(Normalized->getType(), 1); - if (!Start->isZero()) { - // The normalization below assumes that Start is constant zero, so if - // it isn't re-associate Start to PostLoopOffset. - assert(!PostLoopOffset && "Start not-null but PostLoopOffset set?"); - PostLoopOffset = Start; - Start = SE.getConstant(Normalized->getType(), 0); - } - Normalized = - cast<SCEVAddRecExpr>(SE.getAddRecExpr( - Start, Step, Normalized->getLoop(), - Normalized->getNoWrapFlags(SCEV::FlagNW))); - } - - // Expand the core addrec. If we need post-loop scaling, force it to - // expand to an integer type to avoid the need for additional casting. - Type *ExpandTy = PostLoopScale ? IntTy : STy; - // We can't use a pointer type for the addrec if the pointer type is - // non-integral. - Type *AddRecPHIExpandTy = - DL.isNonIntegralPointerType(STy) ? Normalized->getType() : ExpandTy; + assert(SE.properlyDominates(Start, L->getHeader()) && + "Start does not properly dominate loop header"); + assert(SE.dominates(Step, L->getHeader()) && "Step not dominate loop header"); // In some cases, we decide to reuse an existing phi node but need to truncate // it and/or invert the step. Type *TruncTy = nullptr; bool InvertStep = false; - PHINode *PN = getAddRecExprPHILiterally(Normalized, L, AddRecPHIExpandTy, - IntTy, TruncTy, InvertStep); + PHINode *PN = getAddRecExprPHILiterally(Normalized, L, TruncTy, InvertStep); // Accommodate post-inc mode, if necessary. Value *Result; @@ -1167,59 +1118,29 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) { // inserting an extra IV increment. StepV might fold into PostLoopOffset, // but hopefully expandCodeFor handles that. bool useSubtract = - !ExpandTy->isPointerTy() && Step->isNonConstantNegative(); + !S->getType()->isPointerTy() && Step->isNonConstantNegative(); if (useSubtract) Step = SE.getNegativeSCEV(Step); Value *StepV; { // Expand the step somewhere that dominates the loop header. SCEVInsertPointGuard Guard(Builder, this); - StepV = expandCodeForImpl( - Step, IntTy, &*L->getHeader()->getFirstInsertionPt()); + StepV = expand(Step, L->getHeader()->getFirstInsertionPt()); } - Result = expandIVInc(PN, StepV, L, ExpandTy, IntTy, useSubtract); + Result = expandIVInc(PN, StepV, L, useSubtract); } } // We have decided to reuse an induction variable of a dominating loop. Apply // truncation and/or inversion of the step. if (TruncTy) { - Type *ResTy = Result->getType(); - // Normalize the result type. - if (ResTy != SE.getEffectiveSCEVType(ResTy)) - Result = InsertNoopCastOfTo(Result, SE.getEffectiveSCEVType(ResTy)); // Truncate the result. if (TruncTy != Result->getType()) Result = Builder.CreateTrunc(Result, TruncTy); // Invert the result. if (InvertStep) - Result = Builder.CreateSub( - expandCodeForImpl(Normalized->getStart(), TruncTy), Result); - } - - // Re-apply any non-loop-dominating scale. - if (PostLoopScale) { - assert(S->isAffine() && "Can't linearly scale non-affine recurrences."); - Result = InsertNoopCastOfTo(Result, IntTy); - Result = Builder.CreateMul(Result, - expandCodeForImpl(PostLoopScale, IntTy)); - } - - // Re-apply any non-loop-dominating offset. - if (PostLoopOffset) { - if (isa<PointerType>(ExpandTy)) { - if (Result->getType()->isIntegerTy()) { - Value *Base = expandCodeForImpl(PostLoopOffset, ExpandTy); - Result = expandAddToGEP(SE.getUnknown(Result), IntTy, Base); - } else { - Result = expandAddToGEP(PostLoopOffset, IntTy, Result); - } - } else { - Result = InsertNoopCastOfTo(Result, IntTy); - Result = Builder.CreateAdd( - Result, expandCodeForImpl(PostLoopOffset, IntTy)); - } + Result = Builder.CreateSub(expand(Normalized->getStart()), Result); } return Result; @@ -1260,8 +1181,7 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) { S->getNoWrapFlags(SCEV::FlagNW))); BasicBlock::iterator NewInsertPt = findInsertPointAfter(cast<Instruction>(V), &*Builder.GetInsertPoint()); - V = expandCodeForImpl(SE.getTruncateExpr(SE.getUnknown(V), Ty), nullptr, - &*NewInsertPt); + V = expand(SE.getTruncateExpr(SE.getUnknown(V), Ty), NewInsertPt); return V; } @@ -1269,7 +1189,7 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) { if (!S->getStart()->isZero()) { if (isa<PointerType>(S->getType())) { Value *StartV = expand(SE.getPointerBase(S)); - return expandAddToGEP(SE.removePointerBase(S), Ty, StartV); + return expandAddToGEP(SE.removePointerBase(S), StartV); } SmallVector<const SCEV *, 4> NewOps(S->operands()); @@ -1292,8 +1212,8 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) { // specified loop. BasicBlock *Header = L->getHeader(); pred_iterator HPB = pred_begin(Header), HPE = pred_end(Header); - CanonicalIV = PHINode::Create(Ty, std::distance(HPB, HPE), "indvar", - &Header->front()); + CanonicalIV = PHINode::Create(Ty, std::distance(HPB, HPE), "indvar"); + CanonicalIV->insertBefore(Header->begin()); rememberInstruction(CanonicalIV); SmallSet<BasicBlock *, 4> PredSeen; @@ -1361,34 +1281,25 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) { } Value *SCEVExpander::visitPtrToIntExpr(const SCEVPtrToIntExpr *S) { - Value *V = - expandCodeForImpl(S->getOperand(), S->getOperand()->getType()); + Value *V = expand(S->getOperand()); return ReuseOrCreateCast(V, S->getType(), CastInst::PtrToInt, GetOptimalInsertionPointForCastOf(V)); } Value *SCEVExpander::visitTruncateExpr(const SCEVTruncateExpr *S) { - Type *Ty = SE.getEffectiveSCEVType(S->getType()); - Value *V = expandCodeForImpl( - S->getOperand(), SE.getEffectiveSCEVType(S->getOperand()->getType()) - ); - return Builder.CreateTrunc(V, Ty); + Value *V = expand(S->getOperand()); + return Builder.CreateTrunc(V, S->getType()); } Value *SCEVExpander::visitZeroExtendExpr(const SCEVZeroExtendExpr *S) { - Type *Ty = SE.getEffectiveSCEVType(S->getType()); - Value *V = expandCodeForImpl( - S->getOperand(), SE.getEffectiveSCEVType(S->getOperand()->getType()) - ); - return Builder.CreateZExt(V, Ty); + Value *V = expand(S->getOperand()); + return Builder.CreateZExt(V, S->getType(), "", + SE.isKnownNonNegative(S->getOperand())); } Value *SCEVExpander::visitSignExtendExpr(const SCEVSignExtendExpr *S) { - Type *Ty = SE.getEffectiveSCEVType(S->getType()); - Value *V = expandCodeForImpl( - S->getOperand(), SE.getEffectiveSCEVType(S->getOperand()->getType()) - ); - return Builder.CreateSExt(V, Ty); + Value *V = expand(S->getOperand()); + return Builder.CreateSExt(V, S->getType()); } Value *SCEVExpander::expandMinMaxExpr(const SCEVNAryExpr *S, @@ -1399,7 +1310,7 @@ Value *SCEVExpander::expandMinMaxExpr(const SCEVNAryExpr *S, if (IsSequential) LHS = Builder.CreateFreeze(LHS); for (int i = S->getNumOperands() - 2; i >= 0; --i) { - Value *RHS = expandCodeForImpl(S->getOperand(i), Ty); + Value *RHS = expand(S->getOperand(i)); if (IsSequential && i != 0) RHS = Builder.CreateFreeze(RHS); Value *Sel; @@ -1440,14 +1351,14 @@ Value *SCEVExpander::visitVScale(const SCEVVScale *S) { return Builder.CreateVScale(ConstantInt::get(S->getType(), 1)); } -Value *SCEVExpander::expandCodeForImpl(const SCEV *SH, Type *Ty, - Instruction *IP) { +Value *SCEVExpander::expandCodeFor(const SCEV *SH, Type *Ty, + BasicBlock::iterator IP) { setInsertPoint(IP); - Value *V = expandCodeForImpl(SH, Ty); + Value *V = expandCodeFor(SH, Ty); return V; } -Value *SCEVExpander::expandCodeForImpl(const SCEV *SH, Type *Ty) { +Value *SCEVExpander::expandCodeFor(const SCEV *SH, Type *Ty) { // Expand the code for this SCEV. Value *V = expand(SH); @@ -1459,8 +1370,64 @@ Value *SCEVExpander::expandCodeForImpl(const SCEV *SH, Type *Ty) { return V; } -Value *SCEVExpander::FindValueInExprValueMap(const SCEV *S, - const Instruction *InsertPt) { +static bool +canReuseInstruction(ScalarEvolution &SE, const SCEV *S, Instruction *I, + SmallVectorImpl<Instruction *> &DropPoisonGeneratingInsts) { + // If the instruction cannot be poison, it's always safe to reuse. + if (programUndefinedIfPoison(I)) + return true; + + // Otherwise, it is possible that I is more poisonous that S. Collect the + // poison-contributors of S, and then check whether I has any additional + // poison-contributors. Poison that is contributed through poison-generating + // flags is handled by dropping those flags instead. + SmallPtrSet<const Value *, 8> PoisonVals; + SE.getPoisonGeneratingValues(PoisonVals, S); + + SmallVector<Value *> Worklist; + SmallPtrSet<Value *, 8> Visited; + Worklist.push_back(I); + while (!Worklist.empty()) { + Value *V = Worklist.pop_back_val(); + if (!Visited.insert(V).second) + continue; + + // Avoid walking large instruction graphs. + if (Visited.size() > 16) + return false; + + // Either the value can't be poison, or the S would also be poison if it + // is. + if (PoisonVals.contains(V) || isGuaranteedNotToBePoison(V)) + continue; + + auto *I = dyn_cast<Instruction>(V); + if (!I) + return false; + + // FIXME: Ignore vscale, even though it technically could be poison. Do this + // because SCEV currently assumes it can't be poison. Remove this special + // case once we proper model when vscale can be poison. + if (auto *II = dyn_cast<IntrinsicInst>(I); + II && II->getIntrinsicID() == Intrinsic::vscale) + continue; + + if (canCreatePoison(cast<Operator>(I), /*ConsiderFlagsAndMetadata*/ false)) + return false; + + // If the instruction can't create poison, we can recurse to its operands. + if (I->hasPoisonGeneratingFlagsOrMetadata()) + DropPoisonGeneratingInsts.push_back(I); + + for (Value *Op : I->operands()) + Worklist.push_back(Op); + } + return true; +} + +Value *SCEVExpander::FindValueInExprValueMap( + const SCEV *S, const Instruction *InsertPt, + SmallVectorImpl<Instruction *> &DropPoisonGeneratingInsts) { // If the expansion is not in CanonicalMode, and the SCEV contains any // sub scAddRecExpr type SCEV, it is required to expand the SCEV literally. if (!CanonicalMode && SE.containsAddRecurrence(S)) @@ -1470,20 +1437,24 @@ Value *SCEVExpander::FindValueInExprValueMap(const SCEV *S, if (isa<SCEVConstant>(S)) return nullptr; - // Choose a Value from the set which dominates the InsertPt. - // InsertPt should be inside the Value's parent loop so as not to break - // the LCSSA form. for (Value *V : SE.getSCEVValues(S)) { Instruction *EntInst = dyn_cast<Instruction>(V); if (!EntInst) continue; + // Choose a Value from the set which dominates the InsertPt. + // InsertPt should be inside the Value's parent loop so as not to break + // the LCSSA form. assert(EntInst->getFunction() == InsertPt->getFunction()); - if (S->getType() == V->getType() && - SE.DT.dominates(EntInst, InsertPt) && - (SE.LI.getLoopFor(EntInst->getParent()) == nullptr || - SE.LI.getLoopFor(EntInst->getParent())->contains(InsertPt))) + if (S->getType() != V->getType() || !SE.DT.dominates(EntInst, InsertPt) || + !(SE.LI.getLoopFor(EntInst->getParent()) == nullptr || + SE.LI.getLoopFor(EntInst->getParent())->contains(InsertPt))) + continue; + + // Make sure reusing the instruction is poison-safe. + if (canReuseInstruction(SE, S, EntInst, DropPoisonGeneratingInsts)) return V; + DropPoisonGeneratingInsts.clear(); } return nullptr; } @@ -1497,7 +1468,7 @@ Value *SCEVExpander::FindValueInExprValueMap(const SCEV *S, Value *SCEVExpander::expand(const SCEV *S) { // Compute an insertion point for this SCEV object. Hoist the instructions // as far out in the loop nest as possible. - Instruction *InsertPt = &*Builder.GetInsertPoint(); + BasicBlock::iterator InsertPt = Builder.GetInsertPoint(); // We can move insertion point only if there is no div or rem operations // otherwise we are risky to move it over the check for zero denominator. @@ -1521,24 +1492,25 @@ Value *SCEVExpander::expand(const SCEV *S) { L = L->getParentLoop()) { if (SE.isLoopInvariant(S, L)) { if (!L) break; - if (BasicBlock *Preheader = L->getLoopPreheader()) - InsertPt = Preheader->getTerminator(); - else + if (BasicBlock *Preheader = L->getLoopPreheader()) { + InsertPt = Preheader->getTerminator()->getIterator(); + } else { // LSR sets the insertion point for AddRec start/step values to the // block start to simplify value reuse, even though it's an invalid // position. SCEVExpander must correct for this in all cases. - InsertPt = &*L->getHeader()->getFirstInsertionPt(); + InsertPt = L->getHeader()->getFirstInsertionPt(); + } } else { // If the SCEV is computable at this level, insert it into the header // after the PHIs (and after any other instructions that we've inserted // there) so that it is guaranteed to dominate any user inside the loop. if (L && SE.hasComputableLoopEvolution(S, L) && !PostIncLoops.count(L)) - InsertPt = &*L->getHeader()->getFirstInsertionPt(); + InsertPt = L->getHeader()->getFirstInsertionPt(); - while (InsertPt->getIterator() != Builder.GetInsertPoint() && - (isInsertedInstruction(InsertPt) || - isa<DbgInfoIntrinsic>(InsertPt))) { - InsertPt = &*std::next(InsertPt->getIterator()); + while (InsertPt != Builder.GetInsertPoint() && + (isInsertedInstruction(&*InsertPt) || + isa<DbgInfoIntrinsic>(&*InsertPt))) { + InsertPt = std::next(InsertPt); } break; } @@ -1546,26 +1518,40 @@ Value *SCEVExpander::expand(const SCEV *S) { } // Check to see if we already expanded this here. - auto I = InsertedExpressions.find(std::make_pair(S, InsertPt)); + auto I = InsertedExpressions.find(std::make_pair(S, &*InsertPt)); if (I != InsertedExpressions.end()) return I->second; SCEVInsertPointGuard Guard(Builder, this); - Builder.SetInsertPoint(InsertPt); + Builder.SetInsertPoint(InsertPt->getParent(), InsertPt); // Expand the expression into instructions. - Value *V = FindValueInExprValueMap(S, InsertPt); + SmallVector<Instruction *> DropPoisonGeneratingInsts; + Value *V = FindValueInExprValueMap(S, &*InsertPt, DropPoisonGeneratingInsts); if (!V) { V = visit(S); V = fixupLCSSAFormFor(V); } else { - // If we're reusing an existing instruction, we are effectively CSEing two - // copies of the instruction (with potentially different flags). As such, - // we need to drop any poison generating flags unless we can prove that - // said flags must be valid for all new users. - if (auto *I = dyn_cast<Instruction>(V)) - if (I->hasPoisonGeneratingFlags() && !programUndefinedIfPoison(I)) - I->dropPoisonGeneratingFlags(); + for (Instruction *I : DropPoisonGeneratingInsts) { + I->dropPoisonGeneratingFlagsAndMetadata(); + // See if we can re-infer from first principles any of the flags we just + // dropped. + if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(I)) + if (auto Flags = SE.getStrengthenedNoWrapFlagsFromBinOp(OBO)) { + auto *BO = cast<BinaryOperator>(I); + BO->setHasNoUnsignedWrap( + ScalarEvolution::maskFlags(*Flags, SCEV::FlagNUW) == SCEV::FlagNUW); + BO->setHasNoSignedWrap( + ScalarEvolution::maskFlags(*Flags, SCEV::FlagNSW) == SCEV::FlagNSW); + } + if (auto *NNI = dyn_cast<PossiblyNonNegInst>(I)) { + auto *Src = NNI->getOperand(0); + if (isImpliedByDomCondition(ICmpInst::ICMP_SGE, Src, + Constant::getNullValue(Src->getType()), I, + DL).value_or(false)) + NNI->setNonNeg(true); + } + } } // Remember the expanded value for this SCEV at this location. // @@ -1573,7 +1559,7 @@ Value *SCEVExpander::expand(const SCEV *S) { // the expression at this insertion point. If the mapped value happened to be // a postinc expansion, it could be reused by a non-postinc user, but only if // its insertion point was already at the head of the loop. - InsertedExpressions[std::make_pair(S, InsertPt)] = V; + InsertedExpressions[std::make_pair(S, &*InsertPt)] = V; return V; } @@ -1710,13 +1696,13 @@ SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT, << *IsomorphicInc << '\n'); Value *NewInc = OrigInc; if (OrigInc->getType() != IsomorphicInc->getType()) { - Instruction *IP = nullptr; + BasicBlock::iterator IP; if (PHINode *PN = dyn_cast<PHINode>(OrigInc)) - IP = &*PN->getParent()->getFirstInsertionPt(); + IP = PN->getParent()->getFirstInsertionPt(); else - IP = OrigInc->getNextNode(); + IP = OrigInc->getNextNonDebugInstruction()->getIterator(); - IRBuilder<> Builder(IP); + IRBuilder<> Builder(IP->getParent(), IP); Builder.SetCurrentDebugLocation(IsomorphicInc->getDebugLoc()); NewInc = Builder.CreateTruncOrBitCast( OrigInc, IsomorphicInc->getType(), IVName); @@ -1734,7 +1720,8 @@ SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT, ++NumElim; Value *NewIV = OrigPhiRef; if (OrigPhiRef->getType() != Phi->getType()) { - IRBuilder<> Builder(&*L->getHeader()->getFirstInsertionPt()); + IRBuilder<> Builder(L->getHeader(), + L->getHeader()->getFirstInsertionPt()); Builder.SetCurrentDebugLocation(Phi->getDebugLoc()); NewIV = Builder.CreateTruncOrBitCast(OrigPhiRef, Phi->getType(), IVName); } @@ -1744,9 +1731,9 @@ SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT, return NumElim; } -Value *SCEVExpander::getRelatedExistingExpansion(const SCEV *S, - const Instruction *At, - Loop *L) { +bool SCEVExpander::hasRelatedExistingExpansion(const SCEV *S, + const Instruction *At, + Loop *L) { using namespace llvm::PatternMatch; SmallVector<BasicBlock *, 4> ExitingBlocks; @@ -1763,17 +1750,18 @@ Value *SCEVExpander::getRelatedExistingExpansion(const SCEV *S, continue; if (SE.getSCEV(LHS) == S && SE.DT.dominates(LHS, At)) - return LHS; + return true; if (SE.getSCEV(RHS) == S && SE.DT.dominates(RHS, At)) - return RHS; + return true; } // Use expand's logic which is used for reusing a previous Value in // ExprValueMap. Note that we don't currently model the cost of // needing to drop poison generating flags on the instruction if we // want to reuse it. We effectively assume that has zero cost. - return FindValueInExprValueMap(S, At); + SmallVector<Instruction *> DropPoisonGeneratingInsts; + return FindValueInExprValueMap(S, At, DropPoisonGeneratingInsts) != nullptr; } template<typename T> static InstructionCost costAndCollectOperands( @@ -1951,7 +1939,7 @@ bool SCEVExpander::isHighCostExpansionHelper( // If we can find an existing value for this scev available at the point "At" // then consider the expression cheap. - if (getRelatedExistingExpansion(S, &At, L)) + if (hasRelatedExistingExpansion(S, &At, L)) return false; // Consider the expression to be free. TargetTransformInfo::TargetCostKind CostKind = @@ -1993,7 +1981,7 @@ bool SCEVExpander::isHighCostExpansionHelper( // At the beginning of this function we already tried to find existing // value for plain 'S'. Now try to lookup 'S + 1' since it is common // pattern involving division. This is just a simple search heuristic. - if (getRelatedExistingExpansion( + if (hasRelatedExistingExpansion( SE.getAddExpr(S, SE.getConstant(S->getType(), 1)), &At, L)) return false; // Consider it to be free. @@ -2045,10 +2033,8 @@ Value *SCEVExpander::expandCodeForPredicate(const SCEVPredicate *Pred, Value *SCEVExpander::expandComparePredicate(const SCEVComparePredicate *Pred, Instruction *IP) { - Value *Expr0 = - expandCodeForImpl(Pred->getLHS(), Pred->getLHS()->getType(), IP); - Value *Expr1 = - expandCodeForImpl(Pred->getRHS(), Pred->getRHS()->getType(), IP); + Value *Expr0 = expand(Pred->getLHS(), IP); + Value *Expr1 = expand(Pred->getRHS(), IP); Builder.SetInsertPoint(IP); auto InvPred = ICmpInst::getInversePredicate(Pred->getPredicate()); @@ -2080,17 +2066,15 @@ Value *SCEVExpander::generateOverflowCheck(const SCEVAddRecExpr *AR, // Step >= 0, Start + |Step| * Backedge > Start // and |Step| * Backedge doesn't unsigned overflow. - IntegerType *CountTy = IntegerType::get(Loc->getContext(), SrcBits); Builder.SetInsertPoint(Loc); - Value *TripCountVal = expandCodeForImpl(ExitCount, CountTy, Loc); + Value *TripCountVal = expand(ExitCount, Loc); IntegerType *Ty = IntegerType::get(Loc->getContext(), SE.getTypeSizeInBits(ARTy)); - Value *StepValue = expandCodeForImpl(Step, Ty, Loc); - Value *NegStepValue = - expandCodeForImpl(SE.getNegativeSCEV(Step), Ty, Loc); - Value *StartValue = expandCodeForImpl(Start, ARTy, Loc); + Value *StepValue = expand(Step, Loc); + Value *NegStepValue = expand(SE.getNegativeSCEV(Step), Loc); + Value *StartValue = expand(Start, Loc); ConstantInt *Zero = ConstantInt::get(Loc->getContext(), APInt::getZero(DstBits)); @@ -2136,9 +2120,7 @@ Value *SCEVExpander::generateOverflowCheck(const SCEVAddRecExpr *AR, bool NeedPosCheck = !SE.isKnownNegative(Step); bool NeedNegCheck = !SE.isKnownPositive(Step); - if (PointerType *ARPtrTy = dyn_cast<PointerType>(ARTy)) { - StartValue = InsertNoopCastOfTo( - StartValue, Builder.getInt8PtrTy(ARPtrTy->getAddressSpace())); + if (isa<PointerType>(ARTy)) { Value *NegMulV = Builder.CreateNeg(MulV); if (NeedPosCheck) Add = Builder.CreateGEP(Builder.getInt8Ty(), StartValue, MulV); @@ -2171,7 +2153,7 @@ Value *SCEVExpander::generateOverflowCheck(const SCEVAddRecExpr *AR, // If the backedge taken count type is larger than the AR type, // check that we don't drop any bits by truncating it. If we are // dropping bits, then we have overflow (unless the step is zero). - if (SE.getTypeSizeInBits(CountTy) > SE.getTypeSizeInBits(Ty)) { + if (SrcBits > DstBits) { auto MaxVal = APInt::getMaxValue(DstBits).zext(SrcBits); auto *BackedgeCheck = Builder.CreateICmp(ICmpInst::ICMP_UGT, TripCountVal, @@ -2244,7 +2226,7 @@ Value *SCEVExpander::fixupLCSSAFormFor(Value *V) { // instruction. Type *ToTy; if (DefI->getType()->isIntegerTy()) - ToTy = DefI->getType()->getPointerTo(); + ToTy = PointerType::get(DefI->getContext(), 0); else ToTy = Type::getInt32Ty(DefI->getContext()); Instruction *User = @@ -2306,12 +2288,6 @@ struct SCEVFindUnsafe { } } if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) { - const SCEV *Step = AR->getStepRecurrence(SE); - if (!AR->isAffine() && !SE.dominates(Step, AR->getLoop()->getHeader())) { - IsUnsafe = true; - return false; - } - // For non-affine addrecs or in non-canonical mode we need a preheader // to insert into. if (!AR->getLoop()->getLoopPreheader() && |
