Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 14 additions & 16 deletions llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5032,32 +5032,28 @@ Instruction *InstCombinerImpl::foldFreezeIntoRecurrence(FreezeInst &FI,
// backedge values (possibly dropping poison flags along the way) until we
// reach the phi again. In that case, we can move the freeze to the start
// value.
Use *StartU = nullptr;
SmallVector<Use *> StartUses;
SmallVector<Value *> Worklist;
for (Use &U : PN->incoming_values()) {
if (DT.dominates(PN->getParent(), PN->getIncomingBlock(U))) {
BasicBlock *StartBB = PN->getIncomingBlock(U);
Value *StartV = U.get();
if (DT.dominates(PN->getParent(), StartBB)) {
// Add backedge value to worklist.
Worklist.push_back(U.get());
Worklist.push_back(StartV);
continue;
}

// Don't bother handling multiple start values.
if (StartU)
bool StartNeedsFreeze = !isGuaranteedNotToBeUndefOrPoison(StartV);
// We can't insert freeze if a start value is the result of the
// terminator (e.g. an invoke).
if (StartNeedsFreeze && StartBB->getTerminator() == StartV)
return nullptr;
StartU = &U;
StartUses.push_back(&U);
}

if (!StartU || Worklist.empty())
if (StartUses.empty() || Worklist.empty())
return nullptr; // Not a recurrence.

Value *StartV = StartU->get();
BasicBlock *StartBB = PN->getIncomingBlock(*StartU);
bool StartNeedsFreeze = !isGuaranteedNotToBeUndefOrPoison(StartV);
// We can't insert freeze if the start value is the result of the
// terminator (e.g. an invoke).
if (StartNeedsFreeze && StartBB->getTerminator() == StartV)
return nullptr;

SmallPtrSet<Value *, 32> Visited;
SmallVector<Instruction *> DropFlags;
while (!Worklist.empty()) {
Expand All @@ -5084,7 +5080,9 @@ Instruction *InstCombinerImpl::foldFreezeIntoRecurrence(FreezeInst &FI,
for (Instruction *I : DropFlags)
I->dropPoisonGeneratingAnnotations();

if (StartNeedsFreeze) {
for (Use *StartU : StartUses) {
Value *StartV = StartU->get();
BasicBlock *StartBB = PN->getIncomingBlock(*StartU);
Builder.SetInsertPoint(StartBB->getTerminator());
Value *FrozenStartV = Builder.CreateFreeze(StartV,
StartV->getName() + ".fr");
Expand Down
7 changes: 4 additions & 3 deletions llvm/test/Transforms/InstCombine/freeze.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1106,13 +1106,14 @@ define void @fold_phi_multiple_start_values(i1 %c, i32 %init, i32 %init2, i32 %n
; CHECK-LABEL: define void @fold_phi_multiple_start_values(
; CHECK-SAME: i1 [[C:%.*]], i32 [[INIT:%.*]], i32 [[INIT2:%.*]], i32 [[N:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: [[INIT_FR:%.*]] = freeze i32 [[INIT]]
; CHECK-NEXT: br i1 [[C]], label %[[IF:.*]], label %[[LOOP:.*]]
; CHECK: [[IF]]:
; CHECK-NEXT: [[INIT2_FR:%.*]] = freeze i32 [[INIT2]]
; CHECK-NEXT: br label %[[LOOP]]
; CHECK: [[LOOP]]:
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT]], %[[ENTRY]] ], [ [[INIT2]], %[[IF]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ]
; CHECK-NEXT: [[I_FR:%.*]] = freeze i32 [[I]]
; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I_FR]], 1
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT_FR]], %[[ENTRY]] ], [ [[INIT2_FR]], %[[IF]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ]
; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]
; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]
; CHECK: [[EXIT]]:
Expand Down