summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-11-03 21:55:12 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-11-03 21:55:12 +0000
commit7e2b9882b147bf9c26faa7b04b56884ec444bd64 (patch)
tree23aee4ea62f1aa2200f2f7c7e08d3d842469a220
parent542616d47c5533a338e54db76dc99765410065ef (diff)
downloadbcm5719-llvm-7e2b9882b147bf9c26faa7b04b56884ec444bd64.tar.gz
bcm5719-llvm-7e2b9882b147bf9c26faa7b04b56884ec444bd64.zip
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. llvm-svn: 221187
-rw-r--r--llvm/lib/Transforms/InstCombine/InstructionCombining.cpp7
-rw-r--r--llvm/test/Transforms/InstCombine/fold-phi.ll37
-rw-r--r--llvm/test/Transforms/InstCombine/pr12338.ll2
3 files changed, 28 insertions, 18 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index c32294f51fb..5a0b01eca5c 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -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(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());
diff --git a/llvm/test/Transforms/InstCombine/fold-phi.ll b/llvm/test/Transforms/InstCombine/fold-phi.ll
index bd01d58aa58..7954caf9754 100644
--- a/llvm/test/Transforms/InstCombine/fold-phi.ll
+++ b/llvm/test/Transforms/InstCombine/fold-phi.ll
@@ -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
}
diff --git a/llvm/test/Transforms/InstCombine/pr12338.ll b/llvm/test/Transforms/InstCombine/pr12338.ll
index d34600f0fa5..614387a452c 100644
--- a/llvm/test/Transforms/InstCombine/pr12338.ll
+++ b/llvm/test/Transforms/InstCombine/pr12338.ll
@@ -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
}
OpenPOWER on IntegriCloud