summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2011-04-14 21:35:50 +0000
committerOwen Anderson <resistor@mac.com>2011-04-14 21:35:50 +0000
commit92651ec37497dbc222790846cb756488dccd7852 (patch)
treeeb549900504fb99e0bcebdc2ca250333243c4585
parentbc2ee9382c82d7119dbf11421f6c6a9728fd5e53 (diff)
downloadbcm5719-llvm-92651ec37497dbc222790846cb756488dccd7852.tar.gz
bcm5719-llvm-92651ec37497dbc222790846cb756488dccd7852.zip
Fix an infinite alternation in JumpThreading where two transforms would repeatedly undo each other. The solution is to perform more aggressive constant folding to make one of the edges just folded away rather than trying to thread it.
Fixes <rdar://problem/9284786>. Discovered with CSmith. llvm-svn: 129538
-rw-r--r--llvm/lib/Transforms/Scalar/JumpThreading.cpp18
-rw-r--r--llvm/test/Transforms/JumpThreading/2011-04-14-InfLoop.ll31
2 files changed, 46 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index 8f90dfe1f25..7168177a76b 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -16,6 +16,7 @@
#include "llvm/IntrinsicInst.h"
#include "llvm/LLVMContext.h"
#include "llvm/Pass.h"
+#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LazyValueInfo.h"
#include "llvm/Analysis/Loads.h"
@@ -170,9 +171,9 @@ bool JumpThreading::runOnFunction(Function &F) {
Changed = true;
continue;
}
-
+
BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator());
-
+
// Can't thread an unconditional jump, but if the block is "almost
// empty", we can replace uses of it with uses of the successor and make
// this dead.
@@ -608,7 +609,7 @@ static unsigned GetBestDestForJumpOnUndef(BasicBlock *BB) {
static bool hasAddressTakenAndUsed(BasicBlock *BB) {
if (!BB->hasAddressTaken()) return false;
-
+
// If the block has its address taken, it may be a tree of dead constants
// hanging off of it. These shouldn't keep the block alive.
BlockAddress *BA = BlockAddress::get(BB);
@@ -668,6 +669,17 @@ bool JumpThreading::ProcessBlock(BasicBlock *BB) {
return false; // Must be an invoke.
}
+ // Run constant folding to see if we can reduce the condition to a simple
+ // constant.
+ if (Instruction *I = dyn_cast<Instruction>(Condition)) {
+ Value *SimpleVal = ConstantFoldInstruction(I, TD);
+ if (SimpleVal) {
+ I->replaceAllUsesWith(SimpleVal);
+ I->eraseFromParent();
+ Condition = SimpleVal;
+ }
+ }
+
// If the terminator is branching on an undef, we can pick any of the
// successors to branch to. Let GetBestDestForJumpOnUndef decide.
if (isa<UndefValue>(Condition)) {
diff --git a/llvm/test/Transforms/JumpThreading/2011-04-14-InfLoop.ll b/llvm/test/Transforms/JumpThreading/2011-04-14-InfLoop.ll
new file mode 100644
index 00000000000..46aaa00380e
--- /dev/null
+++ b/llvm/test/Transforms/JumpThreading/2011-04-14-InfLoop.ll
@@ -0,0 +1,31 @@
+; RUN: opt -jump-threading < %s
+; <rdar://problem/9284786>
+
+%0 = type <{ i64, i16, i64, i8, i8 }>
+
+@g_338 = external global %0, align 8
+
+define void @func_1() nounwind ssp {
+entry:
+ ret void
+
+for.cond1177:
+ %inc1187 = add nsw i32 0, 1
+ %cmp1179 = icmp slt i32 %inc1187, 5
+ br i1 %cmp1179, label %for.cond1177, label %land.rhs1320
+
+land.rhs1320:
+ %tmp1324 = volatile load i64* getelementptr inbounds (%0* @g_338, i64 0, i32 2), align 1, !tbaa !0
+ br label %if.end.i
+
+if.end.i:
+ %tobool.pr.i = phi i1 [ false, %if.end.i ], [ false, %land.rhs1320 ]
+ br i1 %tobool.pr.i, label %return, label %if.end.i
+
+return:
+ ret void
+}
+
+!0 = metadata !{metadata !"long long", metadata !1}
+!1 = metadata !{metadata !"omnipotent char", metadata !2}
+!2 = metadata !{metadata !"Simple C/C++ TBAA", null}
OpenPOWER on IntegriCloud