[llvm] r221187 - InstCombine: Remove infinite loop caused by FoldOpIntoPhi

David Majnemer david.majnemer at gmail.com
Mon Nov 3 13:55:13 PST 2014


Author: majnemer
Date: Mon Nov  3 15:55:12 2014
New Revision: 221187

URL: http://llvm.org/viewvc/llvm-project?rev=221187&view=rev
Log:
InstCombine: Remove infinite loop caused by FoldOpIntoPhi

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.

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
    llvm/trunk/test/Transforms/InstCombine/fold-phi.ll
    llvm/trunk/test/Transforms/InstCombine/pr12338.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=221187&r1=221186&r2=221187&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Mon Nov  3 15:55:12 2014
@@ -40,8 +40,10 @@
 #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
     // 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());

Modified: llvm/trunk/test/Transforms/InstCombine/fold-phi.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fold-phi.ll?rev=221187&r1=221186&r2=221187&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/fold-phi.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/fold-phi.ll Mon Nov  3 15:55:12 2014
@@ -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
-
-; CHECK: bb0:
-bb0:
-; CHECK: fadd float
-  br label %for.body
+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
 
-end:
-  ret float %add5
+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
+
+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
 }

Modified: llvm/trunk/test/Transforms/InstCombine/pr12338.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/pr12338.ll?rev=221187&r1=221186&r2=221187&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/pr12338.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/pr12338.ll Mon Nov  3 15:55:12 2014
@@ -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
 }





More information about the llvm-commits mailing list