InstCombine: Remove infinite loop caused by FoldOpIntoPhi
authorDavid Majnemer <david.majnemer@gmail.com>
Mon, 3 Nov 2014 21:55:12 +0000 (21:55 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Mon, 3 Nov 2014 21:55:12 +0000 (21:55 +0000)
FoldOpIntoPhi could create an infinite loop if the PHI could potentially
reach a BB it was considering inserting instructions into.  The
instructions it would insert would eventually lead to other combines
firing which would, again, lead to FoldOpIntoPhi firing.

The solution is to handicap FoldOpIntoPhi so that it doesn't attempt to
insert instructions that the PHI might reach.

This fixes PR21377.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221187 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstructionCombining.cpp
test/Transforms/InstCombine/fold-phi.ll
test/Transforms/InstCombine/pr12338.ll

index c32294f51fbad5043afa51bab1017653c4856ba7..5a0b01eca5c5f043645b53c5f3ba996b33e7cc0b 100644 (file)
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Analysis/AssumptionTracker.h"
+#include "llvm/Analysis/CFG.h"
 #include "llvm/Analysis/ConstantFolding.h"
 #include "llvm/Analysis/InstructionSimplify.h"
+#include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/MemoryBuiltins.h"
 #include "llvm/Analysis/ValueTracking.h"
 #include "llvm/IR/CFG.h"
@@ -794,13 +796,14 @@ Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) {
     // 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 (NonConstBB == I.getParent())
+    if (isPotentiallyReachable(I.getParent(), NonConstBB, DT,
+                               getAnalysisIfAvailable<LoopInfo>()))
       return nullptr;
   }
 
   // If there is exactly one non-constant value, we can insert a copy of the
   // operation in that block.  However, if this is a critical edge, we would be
-  // inserting the computation one some other paths (e.g. inside a loop).  Only
+  // inserting the computation on some other paths (e.g. inside a loop).  Only
   // do this if the pred block is unconditionally branching into the phi block.
   if (NonConstBB != nullptr) {
     BranchInst *BI = dyn_cast<BranchInst>(NonConstBB->getTerminator());
index bd01d58aa586041e3357226a7ea090a8fad787f7..7954caf9754c5c763f5240ce3cf7a47c1b5235f6 100644 (file)
@@ -17,23 +17,30 @@ end:
   ret float %add5
 }
 
-; CHECK: fold_phi
-define float @fold_phi(float %a) nounwind {
+; CHECK-LABEL: @pr21377(
+define void @pr21377(i32, i32) {
 entry:
-  br label %for.body
+  br label %while.cond.i
 
-for.body:
-; CHECK: phi float
-; CHECK-NEXT: br i1 undef
-  %sum.057 = phi float [ 0.000000e+00, %entry ], [ %add5, %bb0 ]
-  %add5 = fadd float %sum.057, 1.0 ;; Should be moved to the latch!
-  br i1 undef, label %bb0, label %end
+while.cond.i:                                     ; preds = %while.end.i, %entry
+  %g.0.i = phi i64 [ 0, %entry ], [ %phitmp5.i, %while.end.i ]
+  br i1 undef, label %fn2.exit, label %while.body.i
 
-; CHECK: bb0:
-bb0:
-; CHECK: fadd float
-  br label %for.body
+while.body.i:                                     ; preds = %while.cond.i
+  %conv.i = zext i32 %0 to i64
+  %phitmp3.i = or i64 %g.0.i, %conv.i
+  br label %while.cond3.i
 
-end:
-  ret float %add5
+while.cond3.i:                                    ; preds = %while.cond3.i, %while.body.i
+  %g.1.i = phi i64 [ %phitmp3.i, %while.body.i ], [ 0, %while.cond3.i ]
+  br i1 undef, label %while.end.i, label %while.cond3.i
+
+while.end.i:                                      ; preds = %while.cond3.i
+  %conv.i.i = zext i32 %1 to i64
+  %or7.i = or i64 %g.1.i, %conv.i.i
+  %phitmp5.i = and i64 %or7.i, 4294967295
+  br label %while.cond.i
+
+fn2.exit:                                         ; preds = %while.cond.i
+  ret void
 }
index d34600f0fa58707e9a235120dc47afce1d2e09b2..614387a452cf42a2a867eed445023279478a3e14 100644 (file)
@@ -6,7 +6,6 @@ entry:
 
 for.cond:
   %local = phi <1 x i32> [ <i32 0>, %entry ], [ %phi2, %cond.end47 ]
-; CHECK: sub <1 x i32> <i32 92>, %local
   %phi3 = sub <1 x i32> zeroinitializer, %local
   br label %cond.end
 
@@ -19,6 +18,7 @@ cond.end:
 
 cond.end47:
   %sum = add <1 x i32> %cond, <i32 92>
+; CHECK: sub <1 x i32> <i32 -92>, %cond
   %phi2 = sub <1 x i32> zeroinitializer, %sum
   br label %for.cond
 }