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

Reply via email to