diff options
-rw-r--r-- | lib/Transforms/Scalar/CodeGenPrepare.cpp | 26 | ||||
-rw-r--r-- | test/Transforms/CodeGenPrepare/basic.ll | 24 |
2 files changed, 40 insertions, 10 deletions
diff --git a/lib/Transforms/Scalar/CodeGenPrepare.cpp b/lib/Transforms/Scalar/CodeGenPrepare.cpp index ae827871b5..921cec8351 100644 --- a/lib/Transforms/Scalar/CodeGenPrepare.cpp +++ b/lib/Transforms/Scalar/CodeGenPrepare.cpp @@ -42,6 +42,7 @@ #include "llvm/Support/PatternMatch.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/IRBuilder.h" +#include "llvm/Support/ValueHandle.h" using namespace llvm; using namespace llvm::PatternMatch; @@ -634,8 +635,18 @@ bool CodeGenPrepare::OptimizeCallInst(CallInst *CI) { bool Min = (cast<ConstantInt>(II->getArgOperand(1))->getZExtValue() == 1); const Type *ReturnTy = CI->getType(); Constant *RetVal = ConstantInt::get(ReturnTy, Min ? 0 : -1ULL); - CI->replaceAllUsesWith(RetVal); - CI->eraseFromParent(); + + // Substituting this can cause recursive simplifications, which can + // invalidate our iterator. Use a WeakVH to hold onto it in case this + // happens. + WeakVH IterHandle(CurInstIterator); + + ReplaceAndSimplifyAllUses(CI, RetVal, TLI ? TLI->getTargetData() : 0, DT); + + // If the iterator instruction was recursively deleted, start over at the + // start of the block. + if (IterHandle != CurInstIterator) + CurInstIterator = BB->begin(); return true; } @@ -653,6 +664,7 @@ bool CodeGenPrepare::OptimizeCallInst(CallInst *CI) { CodeGenPrepareFortifiedLibCalls Simplifier; return Simplifier.fold(CI, TD); } + //===----------------------------------------------------------------------===// // Memory Optimization //===----------------------------------------------------------------------===// @@ -1076,14 +1088,8 @@ bool CodeGenPrepare::OptimizeBlock(BasicBlock &BB) { SunkAddrs.clear(); CurInstIterator = BB.begin(); - for (BasicBlock::iterator E = BB.end(); CurInstIterator != E; ) { - Instruction *I = CurInstIterator++; - - if (CallInst *CI = dyn_cast<CallInst>(I)) - MadeChange |= OptimizeCallInst(CI); - else - MadeChange |= OptimizeInst(I); - } + for (BasicBlock::iterator E = BB.end(); CurInstIterator != E; ) + MadeChange |= OptimizeInst(CurInstIterator++); return MadeChange; } diff --git a/test/Transforms/CodeGenPrepare/basic.ll b/test/Transforms/CodeGenPrepare/basic.ll new file mode 100644 index 0000000000..c3e57b4d20 --- /dev/null +++ b/test/Transforms/CodeGenPrepare/basic.ll @@ -0,0 +1,24 @@ +; RUN: opt -codegenprepare %s -S -o - | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-apple-darwin10.0.0" + +; CHECK: @test1 +define i32 @test1(i8* %ptr) nounwind ssp noredzone align 2 { +entry: + %0 = tail call i64 @llvm.objectsize.i64(i8* %ptr, i1 false) + %1 = icmp ugt i64 %0, 3 + br i1 %1, label %T, label %trap + +; CHECK: br i1 true, label +trap: ; preds = %0, %entry + tail call void @llvm.trap() noreturn nounwind + unreachable + +T: + ret i32 4 +} + +declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readonly + +declare void @llvm.trap() nounwind |