diff options
-rw-r--r-- | lib/Transforms/Scalar/JumpThreading.cpp | 18 | ||||
-rw-r--r-- | test/Transforms/JumpThreading/2011-04-14-InfLoop.ll | 31 |
2 files changed, 46 insertions, 3 deletions
diff --git a/lib/Transforms/Scalar/JumpThreading.cpp b/lib/Transforms/Scalar/JumpThreading.cpp index 8f90dfe1f2..7168177a76 100644 --- a/lib/Transforms/Scalar/JumpThreading.cpp +++ b/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/test/Transforms/JumpThreading/2011-04-14-InfLoop.ll b/test/Transforms/JumpThreading/2011-04-14-InfLoop.ll new file mode 100644 index 0000000000..46aaa00380 --- /dev/null +++ b/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} |