| Issue |
182475
|
| Summary |
Infinite compile in InstCombine
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
rahulana-quic
|
InstCombine causes an infinite compile after https://github.com/llvm/llvm-project/pull/154336. The issue seems to be an oscillation between a new freeze being created in foldOpIntoPhi and then later in pushFreezeToPreventPoisonFromPropagating the same freeze is removed. Following is a snippet from the debug output:
```
IC: Visiting: %.fr = freeze i32 %71
...
ADD DEFERRED: %68 = freeze i32 %67
ADD DEFERRED: %72 = phi i32
IC: Replacing %.fr = freeze i32 %73
with %72 = phi i32 [ 52, %42 ], [ %68, %43 ]
...
ADD: %.fr = phi i32 [ 52, %42 ], [ %68, %43 ]
ADD: %68 = freeze i32 %67
IC: Visiting: %68 = freeze i32 %67
...
IC: Replacing %68 = freeze i32 %67
with %67 = select i1 %65, i32 54, i32 %66
IC: ERASE %68 = freeze i32 %67
ADD DEFERRED: %.fr = phi i32 [ 52, %42 ], [ %67, %43 ]
...
IC: Visiting: %.fr1 = freeze i32 %.fr
...
IC: Replacing %.fr1 = freeze i32 %72
with %.fr = phi i32 [ 52, %42 ], [ %68, %43 ]
...
ADD: %68 = freeze i32 %67
IC: Visiting: %68 = freeze i32 %67
IC: Replacing %68 = freeze i32 %67
with %67 = select i1 %65, i32 54, i32 %66
IC: ERASE %68 = freeze i32 %67
```
This issue was found while running spec2000/crafty with Ofast and thin-lto (in the function InitializeRandomHash from evaluate.c during the lto step).
I have been trying to get a reduced test case but I haven't had much success there. I currently have the following patch for this which I will be uploading soon after some testing:
```
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index c4beacdd1268..3a44253f8ecb 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -1980,6 +1980,12 @@ Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN,
Value *InVal = PN->getIncomingValue(i);
BasicBlock *InBB = PN->getIncomingBlock(i);
+ // Avoid repeatedly sinking a freeze into a PHI only for some of the newly
+ // created incoming freezes to be trivially removable again. That pattern
+ // can cause oscillation between freeze(phi(...)) and phi(..., freeze(x), ...).
+ if (isa<FreezeInst>(&I) && isGuaranteedNotToBeUndefOrPoison(InVal))
+ return nullptr;
+
if (auto *NewVal = simplifyInstructionWithPHI(I, PN, InVal, InBB, DL, SQ)) {
NewPhiValues.push_back(NewVal);
continue;
@@ -5214,6 +5220,11 @@ InstCombinerImpl::pushFreezeToPreventPoisonFromPropagating(FreezeInst &OrigFI) {
if (!isa<Instruction>(V) || isa<PHINode>(V))
return false;
+ // Don't push through an existing freeze. Otherwise we can repeatedly
+ // create redundant freeze instructions during instcombine iterations.
+ if (isa<FreezeInst>(V))
+ return false;
+
// We can't push the freeze through an instruction which can itself create
// poison. If the only source of new poison is flags, we can simply
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs