summaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
commit344a3780b2e33f6ca763666c380202b18aab72a3 (patch)
treef0b203ee6eb71d7fdd792373e3c81eb18d6934dd /llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
parentb60736ec1405bb0a8dd40989f67ef4c93da068ab (diff)
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstructionCombining.cpp')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstructionCombining.cpp405
1 files changed, 286 insertions, 119 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 518e909e8ab4..4e3b18e805ee 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -346,6 +346,25 @@ static bool simplifyAssocCastAssoc(BinaryOperator *BinOp1,
return true;
}
+// Simplifies IntToPtr/PtrToInt RoundTrip Cast To BitCast.
+// inttoptr ( ptrtoint (x) ) --> x
+Value *InstCombinerImpl::simplifyIntToPtrRoundTripCast(Value *Val) {
+ auto *IntToPtr = dyn_cast<IntToPtrInst>(Val);
+ if (IntToPtr && DL.getPointerTypeSizeInBits(IntToPtr->getDestTy()) ==
+ DL.getTypeSizeInBits(IntToPtr->getSrcTy())) {
+ auto *PtrToInt = dyn_cast<PtrToIntInst>(IntToPtr->getOperand(0));
+ Type *CastTy = IntToPtr->getDestTy();
+ if (PtrToInt &&
+ CastTy->getPointerAddressSpace() ==
+ PtrToInt->getSrcTy()->getPointerAddressSpace() &&
+ DL.getPointerTypeSizeInBits(PtrToInt->getSrcTy()) ==
+ DL.getTypeSizeInBits(PtrToInt->getDestTy())) {
+ return Builder.CreateBitCast(PtrToInt->getOperand(0), CastTy);
+ }
+ }
+ return nullptr;
+}
+
/// This performs a few simplifications for operators that are associative or
/// commutative:
///
@@ -924,6 +943,12 @@ Value *InstCombinerImpl::dyn_castNegVal(Value *V) const {
return ConstantExpr::getNeg(CV);
}
+ // Negate integer vector splats.
+ if (auto *CV = dyn_cast<Constant>(V))
+ if (CV->getType()->isVectorTy() &&
+ CV->getType()->getScalarType()->isIntegerTy() && CV->getSplatValue())
+ return ConstantExpr::getNeg(CV);
+
return nullptr;
}
@@ -932,6 +957,22 @@ static Value *foldOperationIntoSelectOperand(Instruction &I, Value *SO,
if (auto *Cast = dyn_cast<CastInst>(&I))
return Builder.CreateCast(Cast->getOpcode(), SO, I.getType());
+ if (auto *II = dyn_cast<IntrinsicInst>(&I)) {
+ assert(canConstantFoldCallTo(II, cast<Function>(II->getCalledOperand())) &&
+ "Expected constant-foldable intrinsic");
+ Intrinsic::ID IID = II->getIntrinsicID();
+ if (II->getNumArgOperands() == 1)
+ return Builder.CreateUnaryIntrinsic(IID, SO);
+
+ // This works for real binary ops like min/max (where we always expect the
+ // constant operand to be canonicalized as op1) and unary ops with a bonus
+ // constant argument like ctlz/cttz.
+ // TODO: Handle non-commutative binary intrinsics as below for binops.
+ assert(II->getNumArgOperands() == 2 && "Expected binary intrinsic");
+ assert(isa<Constant>(II->getArgOperand(1)) && "Expected constant operand");
+ return Builder.CreateBinaryIntrinsic(IID, SO, II->getArgOperand(1));
+ }
+
assert(I.isBinaryOp() && "Unexpected opcode for select folding");
// Figure out if the constant is the left or the right argument.
@@ -1098,7 +1139,7 @@ Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) {
// If the incoming non-constant value is in I's block, we will remove one
// instruction, but insert another equivalent one, leading to infinite
// instcombine.
- if (isPotentiallyReachable(I.getParent(), NonConstBB, &DT, LI))
+ if (isPotentiallyReachable(I.getParent(), NonConstBB, nullptr, &DT, LI))
return nullptr;
}
@@ -1682,7 +1723,7 @@ Instruction *InstCombinerImpl::foldVectorBinop(BinaryOperator &Inst) {
Constant *MaybeUndef =
ConstOp1 ? ConstantExpr::get(Opcode, UndefScalar, CElt)
: ConstantExpr::get(Opcode, CElt, UndefScalar);
- if (!isa<UndefValue>(MaybeUndef)) {
+ if (!match(MaybeUndef, m_Undef())) {
MayChange = false;
break;
}
@@ -1842,10 +1883,11 @@ static Instruction *foldSelectGEP(GetElementPtrInst &GEP,
// Note: using IRBuilder to create the constants for efficiency.
SmallVector<Value *, 4> IndexC(GEP.indices());
bool IsInBounds = GEP.isInBounds();
- Value *NewTrueC = IsInBounds ? Builder.CreateInBoundsGEP(TrueC, IndexC)
- : Builder.CreateGEP(TrueC, IndexC);
- Value *NewFalseC = IsInBounds ? Builder.CreateInBoundsGEP(FalseC, IndexC)
- : Builder.CreateGEP(FalseC, IndexC);
+ Type *Ty = GEP.getSourceElementType();
+ Value *NewTrueC = IsInBounds ? Builder.CreateInBoundsGEP(Ty, TrueC, IndexC)
+ : Builder.CreateGEP(Ty, TrueC, IndexC);
+ Value *NewFalseC = IsInBounds ? Builder.CreateInBoundsGEP(Ty, FalseC, IndexC)
+ : Builder.CreateGEP(Ty, FalseC, IndexC);
return SelectInst::Create(Cond, NewTrueC, NewFalseC, "", nullptr, Sel);
}
@@ -2034,54 +2076,70 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
if (!shouldMergeGEPs(*cast<GEPOperator>(&GEP), *Src))
return nullptr;
- // Try to reassociate loop invariant GEP chains to enable LICM.
- if (LI && Src->getNumOperands() == 2 && GEP.getNumOperands() == 2 &&
+ if (Src->getNumOperands() == 2 && GEP.getNumOperands() == 2 &&
Src->hasOneUse()) {
- if (Loop *L = LI->getLoopFor(GEP.getParent())) {
- Value *GO1 = GEP.getOperand(1);
- Value *SO1 = Src->getOperand(1);
- // Reassociate the two GEPs if SO1 is variant in the loop and GO1 is
- // invariant: this breaks the dependence between GEPs and allows LICM
- // to hoist the invariant part out of the loop.
- if (L->isLoopInvariant(GO1) && !L->isLoopInvariant(SO1)) {
- // We have to be careful here.
- // We have something like:
- // %src = getelementptr <ty>, <ty>* %base, <ty> %idx
- // %gep = getelementptr <ty>, <ty>* %src, <ty> %idx2
- // If we just swap idx & idx2 then we could inadvertantly
- // change %src from a vector to a scalar, or vice versa.
- // Cases:
- // 1) %base a scalar & idx a scalar & idx2 a vector
- // => Swapping idx & idx2 turns %src into a vector type.
- // 2) %base a scalar & idx a vector & idx2 a scalar
- // => Swapping idx & idx2 turns %src in a scalar type
- // 3) %base, %idx, and %idx2 are scalars
- // => %src & %gep are scalars
- // => swapping idx & idx2 is safe
- // 4) %base a vector
- // => %src is a vector
- // => swapping idx & idx2 is safe.
- auto *SO0 = Src->getOperand(0);
- auto *SO0Ty = SO0->getType();
- if (!isa<VectorType>(GEPType) || // case 3
- isa<VectorType>(SO0Ty)) { // case 4
- Src->setOperand(1, GO1);
- GEP.setOperand(1, SO1);
- return &GEP;
- } else {
- // Case 1 or 2
- // -- have to recreate %src & %gep
- // put NewSrc at same location as %src
- Builder.SetInsertPoint(cast<Instruction>(PtrOp));
- auto *NewSrc = cast<GetElementPtrInst>(
- Builder.CreateGEP(GEPEltType, SO0, GO1, Src->getName()));
- NewSrc->setIsInBounds(Src->isInBounds());
- auto *NewGEP = GetElementPtrInst::Create(GEPEltType, NewSrc, {SO1});
- NewGEP->setIsInBounds(GEP.isInBounds());
- return NewGEP;
+ Value *GO1 = GEP.getOperand(1);
+ Value *SO1 = Src->getOperand(1);
+
+ if (LI) {
+ // Try to reassociate loop invariant GEP chains to enable LICM.
+ if (Loop *L = LI->getLoopFor(GEP.getParent())) {
+ // Reassociate the two GEPs if SO1 is variant in the loop and GO1 is
+ // invariant: this breaks the dependence between GEPs and allows LICM
+ // to hoist the invariant part out of the loop.
+ if (L->isLoopInvariant(GO1) && !L->isLoopInvariant(SO1)) {
+ // We have to be careful here.
+ // We have something like:
+ // %src = getelementptr <ty>, <ty>* %base, <ty> %idx
+ // %gep = getelementptr <ty>, <ty>* %src, <ty> %idx2
+ // If we just swap idx & idx2 then we could inadvertantly
+ // change %src from a vector to a scalar, or vice versa.
+ // Cases:
+ // 1) %base a scalar & idx a scalar & idx2 a vector
+ // => Swapping idx & idx2 turns %src into a vector type.
+ // 2) %base a scalar & idx a vector & idx2 a scalar
+ // => Swapping idx & idx2 turns %src in a scalar type
+ // 3) %base, %idx, and %idx2 are scalars
+ // => %src & %gep are scalars
+ // => swapping idx & idx2 is safe
+ // 4) %base a vector
+ // => %src is a vector
+ // => swapping idx & idx2 is safe.
+ auto *SO0 = Src->getOperand(0);
+ auto *SO0Ty = SO0->getType();
+ if (!isa<VectorType>(GEPType) || // case 3
+ isa<VectorType>(SO0Ty)) { // case 4
+ Src->setOperand(1, GO1);
+ GEP.setOperand(1, SO1);
+ return &GEP;
+ } else {
+ // Case 1 or 2
+ // -- have to recreate %src & %gep
+ // put NewSrc at same location as %src
+ Builder.SetInsertPoint(cast<Instruction>(PtrOp));
+ auto *NewSrc = cast<GetElementPtrInst>(
+ Builder.CreateGEP(GEPEltType, SO0, GO1, Src->getName()));
+ NewSrc->setIsInBounds(Src->isInBounds());
+ auto *NewGEP =
+ GetElementPtrInst::Create(GEPEltType, NewSrc, {SO1});
+ NewGEP->setIsInBounds(GEP.isInBounds());
+ return NewGEP;
+ }
}
}
}
+
+ // Fold (gep(gep(Ptr,Idx0),Idx1) -> gep(Ptr,add(Idx0,Idx1))
+ if (GO1->getType() == SO1->getType()) {
+ bool NewInBounds = GEP.isInBounds() && Src->isInBounds();
+ auto *NewIdx =
+ Builder.CreateAdd(GO1, SO1, GEP.getName() + ".idx",
+ /*HasNUW*/ false, /*HasNSW*/ NewInBounds);
+ auto *NewGEP = GetElementPtrInst::Create(
+ GEPEltType, Src->getPointerOperand(), {NewIdx});
+ NewGEP->setIsInBounds(NewInBounds);
+ return NewGEP;
+ }
}
// Note that if our source is a gep chain itself then we wait for that
@@ -2172,24 +2230,15 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
Matched = true;
}
- if (Matched) {
- // Canonicalize (gep i8* X, -(ptrtoint Y))
- // to (inttoptr (sub (ptrtoint X), (ptrtoint Y)))
- // The GEP pattern is emitted by the SCEV expander for certain kinds of
- // pointer arithmetic.
- if (match(V, m_Neg(m_PtrToInt(m_Value())))) {
- Operator *Index = cast<Operator>(V);
- Value *PtrToInt = Builder.CreatePtrToInt(PtrOp, Index->getType());
- Value *NewSub = Builder.CreateSub(PtrToInt, Index->getOperand(1));
- return CastInst::Create(Instruction::IntToPtr, NewSub, GEPType);
- }
- // Canonicalize (gep i8* X, (ptrtoint Y)-(ptrtoint X))
- // to (bitcast Y)
- Value *Y;
- if (match(V, m_Sub(m_PtrToInt(m_Value(Y)),
- m_PtrToInt(m_Specific(GEP.getOperand(0))))))
- return CastInst::CreatePointerBitCastOrAddrSpaceCast(Y, GEPType);
- }
+ // Canonicalize (gep i8* X, (ptrtoint Y)-(ptrtoint X)) to (bitcast Y), but
+ // only if both point to the same underlying object (otherwise provenance
+ // is not necessarily retained).
+ Value *Y;
+ Value *X = GEP.getOperand(0);
+ if (Matched &&
+ match(V, m_Sub(m_PtrToInt(m_Value(Y)), m_PtrToInt(m_Specific(X)))) &&
+ getUnderlyingObject(X) == getUnderlyingObject(Y))
+ return CastInst::CreatePointerBitCastOrAddrSpaceCast(Y, GEPType);
}
}
@@ -2433,13 +2482,21 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
// analysis of unions. If "A" is also a bitcast, wait for A/X to be merged.
unsigned OffsetBits = DL.getIndexTypeSizeInBits(GEPType);
APInt Offset(OffsetBits, 0);
- if (!isa<BitCastInst>(SrcOp) && GEP.accumulateConstantOffset(DL, Offset)) {
+
+ // If the bitcast argument is an allocation, The bitcast is for convertion
+ // to actual type of allocation. Removing such bitcasts, results in having
+ // GEPs with i8* base and pure byte offsets. That means GEP is not aware of
+ // struct or array hierarchy.
+ // By avoiding such GEPs, phi translation and MemoryDependencyAnalysis have
+ // a better chance to succeed.
+ if (!isa<BitCastInst>(SrcOp) && GEP.accumulateConstantOffset(DL, Offset) &&
+ !isAllocationFn(SrcOp, &TLI)) {
// If this GEP instruction doesn't move the pointer, just replace the GEP
// with a bitcast of the real input to the dest type.
if (!Offset) {
// If the bitcast is of an allocation, and the allocation will be
// converted to match the type of the cast, don't touch this.
- if (isa<AllocaInst>(SrcOp) || isAllocationFn(SrcOp, &TLI)) {
+ if (isa<AllocaInst>(SrcOp)) {
// See if the bitcast simplifies, if so, don't nuke this GEP yet.
if (Instruction *I = visitBitCast(*BCI)) {
if (I != BCI) {
@@ -2578,6 +2635,11 @@ static bool isAllocSiteRemovable(Instruction *AI,
case Intrinsic::objectsize:
Users.emplace_back(I);
continue;
+ case Intrinsic::launder_invariant_group:
+ case Intrinsic::strip_invariant_group:
+ Users.emplace_back(I);
+ Worklist.push_back(I);
+ continue;
}
}
@@ -2659,7 +2721,7 @@ Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) {
} else {
// Casts, GEP, or anything else: we're about to delete this instruction,
// so it can not have any valid uses.
- replaceInstUsesWith(*I, UndefValue::get(I->getType()));
+ replaceInstUsesWith(*I, PoisonValue::get(I->getType()));
}
eraseInstFromFunction(*I);
}
@@ -2848,27 +2910,31 @@ Instruction *InstCombinerImpl::visitReturnInst(ReturnInst &RI) {
return nullptr;
}
+// WARNING: keep in sync with SimplifyCFGOpt::simplifyUnreachable()!
Instruction *InstCombinerImpl::visitUnreachableInst(UnreachableInst &I) {
// Try to remove the previous instruction if it must lead to unreachable.
// This includes instructions like stores and "llvm.assume" that may not get
// removed by simple dead code elimination.
- Instruction *Prev = I.getPrevNonDebugInstruction();
- if (Prev && !Prev->isEHPad() &&
- isGuaranteedToTransferExecutionToSuccessor(Prev)) {
- // Temporarily disable removal of volatile stores preceding unreachable,
- // pending a potential LangRef change permitting volatile stores to trap.
- // TODO: Either remove this code, or properly integrate the check into
- // isGuaranteedToTransferExecutionToSuccessor().
- if (auto *SI = dyn_cast<StoreInst>(Prev))
- if (SI->isVolatile())
- return nullptr;
+ while (Instruction *Prev = I.getPrevNonDebugInstruction()) {
+ // While we theoretically can erase EH, that would result in a block that
+ // used to start with an EH no longer starting with EH, which is invalid.
+ // To make it valid, we'd need to fixup predecessors to no longer refer to
+ // this block, but that changes CFG, which is not allowed in InstCombine.
+ if (Prev->isEHPad())
+ return nullptr; // Can not drop any more instructions. We're done here.
+
+ if (!isGuaranteedToTransferExecutionToSuccessor(Prev))
+ return nullptr; // Can not drop any more instructions. We're done here.
+ // Otherwise, this instruction can be freely erased,
+ // even if it is not side-effect free.
// A value may still have uses before we process it here (for example, in
- // another unreachable block), so convert those to undef.
- replaceInstUsesWith(*Prev, UndefValue::get(Prev->getType()));
+ // another unreachable block), so convert those to poison.
+ replaceInstUsesWith(*Prev, PoisonValue::get(Prev->getType()));
eraseInstFromFunction(*Prev);
- return &I;
}
+ assert(I.getParent()->sizeWithoutDebug() == 1 && "The block is now empty.");
+ // FIXME: recurse into unconditional predecessors?
return nullptr;
}
@@ -3058,18 +3124,41 @@ Instruction *InstCombinerImpl::visitExtractValueInst(ExtractValueInst &EV) {
if (*EV.idx_begin() == 0) {
Instruction::BinaryOps BinOp = WO->getBinaryOp();
Value *LHS = WO->getLHS(), *RHS = WO->getRHS();
- replaceInstUsesWith(*WO, UndefValue::get(WO->getType()));
+ // Replace the old instruction's uses with poison.
+ replaceInstUsesWith(*WO, PoisonValue::get(WO->getType()));
eraseInstFromFunction(*WO);
return BinaryOperator::Create(BinOp, LHS, RHS);
}
- // If the normal result of the add is dead, and the RHS is a constant,
- // we can transform this into a range comparison.
- // overflow = uadd a, -4 --> overflow = icmp ugt a, 3
- if (WO->getIntrinsicID() == Intrinsic::uadd_with_overflow)
- if (ConstantInt *CI = dyn_cast<ConstantInt>(WO->getRHS()))
- return new ICmpInst(ICmpInst::ICMP_UGT, WO->getLHS(),
- ConstantExpr::getNot(CI));
+ assert(*EV.idx_begin() == 1 &&
+ "unexpected extract index for overflow inst");
+
+ // If only the overflow result is used, and the right hand side is a
+ // constant (or constant splat), we can remove the intrinsic by directly
+ // checking for overflow.
+ const APInt *C;
+ if (match(WO->getRHS(), m_APInt(C))) {
+ // Compute the no-wrap range [X,Y) for LHS given RHS=C, then
+ // check for the inverted range using range offset trick (i.e.
+ // use a subtract to shift the range to bottom of either the
+ // signed or unsigned domain and then use a single compare to
+ // check range membership).
+ ConstantRange NWR =
+ ConstantRange::makeExactNoWrapRegion(WO->getBinaryOp(), *C,
+ WO->getNoWrapKind());
+ APInt Min = WO->isSigned() ? NWR.getSignedMin() : NWR.getUnsignedMin();
+ NWR = NWR.subtract(Min);
+
+ CmpInst::Predicate Pred;
+ APInt NewRHSC;
+ if (NWR.getEquivalentICmp(Pred, NewRHSC)) {
+ auto *OpTy = WO->getRHS()->getType();
+ auto *NewLHS = Builder.CreateSub(WO->getLHS(),
+ ConstantInt::get(OpTy, Min));
+ return new ICmpInst(ICmpInst::getInversePredicate(Pred), NewLHS,
+ ConstantInt::get(OpTy, NewRHSC));
+ }
+ }
}
}
if (LoadInst *L = dyn_cast<LoadInst>(Agg))
@@ -3083,9 +3172,8 @@ Instruction *InstCombinerImpl::visitExtractValueInst(ExtractValueInst &EV) {
SmallVector<Value*, 4> Indices;
// Prefix an i32 0 since we need the first element.
Indices.push_back(Builder.getInt32(0));
- for (ExtractValueInst::idx_iterator I = EV.idx_begin(), E = EV.idx_end();
- I != E; ++I)
- Indices.push_back(Builder.getInt32(*I));
+ for (unsigned Idx : EV.indices())
+ Indices.push_back(Builder.getInt32(Idx));
// We need to insert these at the location of the old load, not at that of
// the extractvalue.
@@ -3458,6 +3546,73 @@ Instruction *InstCombinerImpl::visitLandingPadInst(LandingPadInst &LI) {
return nullptr;
}
+Value *
+InstCombinerImpl::pushFreezeToPreventPoisonFromPropagating(FreezeInst &OrigFI) {
+ // Try to push freeze through instructions that propagate but don't produce
+ // poison as far as possible. If an operand of freeze follows three
+ // conditions 1) one-use, 2) does not produce poison, and 3) has all but one
+ // guaranteed-non-poison operands then push the freeze through to the one
+ // operand that is not guaranteed non-poison. The actual transform is as
+ // follows.
+ // Op1 = ... ; Op1 can be posion
+ // Op0 = Inst(Op1, NonPoisonOps...) ; Op0 has only one use and only have
+ // ; single guaranteed-non-poison operands
+ // ... = Freeze(Op0)
+ // =>
+ // Op1 = ...
+ // Op1.fr = Freeze(Op1)
+ // ... = Inst(Op1.fr, NonPoisonOps...)
+ auto *OrigOp = OrigFI.getOperand(0);
+ auto *OrigOpInst = dyn_cast<Instruction>(OrigOp);
+
+ // While we could change the other users of OrigOp to use freeze(OrigOp), that
+ // potentially reduces their optimization potential, so let's only do this iff
+ // the OrigOp is only used by the freeze.
+ if (!OrigOpInst || !OrigOpInst->hasOneUse() || isa<PHINode>(OrigOp) ||
+ canCreateUndefOrPoison(dyn_cast<Operator>(OrigOp)))
+ return nullptr;
+
+ // If operand is guaranteed not to be poison, there is no need to add freeze
+ // to the operand. So we first find the operand that is not guaranteed to be
+ // poison.
+ Use *MaybePoisonOperand = nullptr;
+ for (Use &U : OrigOpInst->operands()) {
+ if (isGuaranteedNotToBeUndefOrPoison(U.get()))
+ continue;
+ if (!MaybePoisonOperand)
+ MaybePoisonOperand = &U;
+ else
+ return nullptr;
+ }
+
+ // If all operands are guaranteed to be non-poison, we can drop freeze.
+ if (!MaybePoisonOperand)
+ return OrigOp;
+
+ auto *FrozenMaybePoisonOperand = new FreezeInst(
+ MaybePoisonOperand->get(), MaybePoisonOperand->get()->getName() + ".fr");
+
+ replaceUse(*MaybePoisonOperand, FrozenMaybePoisonOperand);
+ FrozenMaybePoisonOperand->insertBefore(OrigOpInst);
+ return OrigOp;
+}
+
+bool InstCombinerImpl::freezeDominatedUses(FreezeInst &FI) {
+ Value *Op = FI.getOperand(0);
+
+ if (isa<Constant>(Op))
+ return false;
+
+ bool Changed = false;
+ Op->replaceUsesWithIf(&FI, [&](Use &U) -> bool {
+ bool Dominates = DT.dominates(&FI, U);
+ Changed |= Dominates;
+ return Dominates;
+ });
+
+ return Changed;
+}
+
Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) {
Value *Op0 = I.getOperand(0);
@@ -3470,6 +3625,9 @@ Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) {
return NV;
}
+ if (Value *NI = pushFreezeToPreventPoisonFromPropagating(I))
+ return replaceInstUsesWith(I, NI);
+
if (match(Op0, m_Undef())) {
// If I is freeze(undef), see its uses and fold it to the best constant.
// - or: pick -1
@@ -3498,6 +3656,10 @@ Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) {
return replaceInstUsesWith(I, BestValue);
}
+ // Replace all dominated uses of Op to freeze(Op).
+ if (freezeDominatedUses(I))
+ return &I;
+
return nullptr;
}
@@ -3564,37 +3726,44 @@ static bool TryToSinkInstruction(Instruction *I, BasicBlock *DestBlock) {
// here, but that computation has been sunk.
SmallVector<DbgVariableIntrinsic *, 2> DbgUsers;
findDbgUsers(DbgUsers, I);
-
- // Update the arguments of a dbg.declare instruction, so that it
- // does not point into a sunk instruction.
- auto updateDbgDeclare = [&I](DbgVariableIntrinsic *DII) {
- if (!isa<DbgDeclareInst>(DII))
- return false;
-
- if (isa<CastInst>(I))
- DII->setOperand(
- 0, MetadataAsValue::get(I->getContext(),
- ValueAsMetadata::get(I->getOperand(0))));
- return true;
- };
+ // Process the sinking DbgUsers in reverse order, as we only want to clone the
+ // last appearing debug intrinsic for each given variable.
+ SmallVector<DbgVariableIntrinsic *, 2> DbgUsersToSink;
+ for (DbgVariableIntrinsic *DVI : DbgUsers)
+ if (DVI->getParent() == SrcBlock)
+ DbgUsersToSink.push_back(DVI);
+ llvm::sort(DbgUsersToSink,
+ [](auto *A, auto *B) { return B->comesBefore(A); });
SmallVector<DbgVariableIntrinsic *, 2> DIIClones;
- for (auto User : DbgUsers) {
+ SmallSet<DebugVariable, 4> SunkVariables;
+ for (auto User : DbgUsersToSink) {
// A dbg.declare instruction should not be cloned, since there can only be
// one per variable fragment. It should be left in the original place
// because the sunk instruction is not an alloca (otherwise we could not be
// here).
- if (User->getParent() != SrcBlock || updateDbgDeclare(User))
+ if (isa<DbgDeclareInst>(User))
+ continue;
+
+ DebugVariable DbgUserVariable =
+ DebugVariable(User->getVariable(), User->getExpression(),
+ User->getDebugLoc()->getInlinedAt());
+
+ if (!SunkVariables.insert(DbgUserVariable).second)
continue;
DIIClones.emplace_back(cast<DbgVariableIntrinsic>(User->clone()));
+ if (isa<DbgDeclareInst>(User) && isa<CastInst>(I))
+ DIIClones.back()->replaceVariableLocationOp(I, I->getOperand(0));
LLVM_DEBUG(dbgs() << "CLONE: " << *DIIClones.back() << '\n');
}
// Perform salvaging without the clones, then sink the clones.
if (!DIIClones.empty()) {
salvageDebugInfoForDbgValues(*I, DbgUsers);
- for (auto &DIIClone : DIIClones) {
+ // The clones are in reverse order of original appearance, reverse again to
+ // maintain the original order.
+ for (auto &DIIClone : llvm::reverse(DIIClones)) {
DIIClone->insertBefore(&*InsertPos);
LLVM_DEBUG(dbgs() << "SINK: " << *DIIClone << '\n');
}
@@ -3878,9 +4047,10 @@ static bool prepareICWorklistFromFunction(Function &F, const DataLayout &DL,
}
}
- // Skip processing debug intrinsics in InstCombine. Processing these call instructions
- // consumes non-trivial amount of time and provides no value for the optimization.
- if (!isa<DbgInfoIntrinsic>(Inst)) {
+ // Skip processing debug and pseudo intrinsics in InstCombine. Processing
+ // these call instructions consumes non-trivial amount of time and
+ // provides no value for the optimization.
+ if (!Inst->isDebugOrPseudoInst()) {
InstrsForInstCombineWorklist.push_back(Inst);
SeenAliasScopes.analyse(Inst);
}
@@ -3961,8 +4131,8 @@ static bool combineInstructionsOverFunction(
F.getContext(), TargetFolder(DL),
IRBuilderCallbackInserter([&Worklist, &AC](Instruction *I) {
Worklist.add(I);
- if (match(I, m_Intrinsic<Intrinsic::assume>()))
- AC.registerAssumption(cast<CallInst>(I));
+ if (auto *Assume = dyn_cast<AssumeInst>(I))
+ AC.registerAssumption(Assume);
}));
// Lower dbg.declare intrinsics otherwise their value may be clobbered
@@ -4038,9 +4208,6 @@ PreservedAnalyses InstCombinePass::run(Function &F,
// Mark all the analyses that instcombine updates as preserved.
PreservedAnalyses PA;
PA.preserveSet<CFGAnalyses>();
- PA.preserve<AAManager>();
- PA.preserve<BasicAA>();
- PA.preserve<GlobalsAA>();
return PA;
}