summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2012-02-27 02:13:03 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2012-02-27 02:13:03 +0000
commit23b6ec906a081259dad4672ec386ddfb52cd0d9f (patch)
tree3d096d26405e54dbce0d50439a3bf008fefa56f0
parent930a1ebd929aa0ab4c2610e7f7a721c18dcfe052 (diff)
downloadllvm-23b6ec906a081259dad4672ec386ddfb52cd0d9f.tar.gz
llvm-23b6ec906a081259dad4672ec386ddfb52cd0d9f.tar.bz2
llvm-23b6ec906a081259dad4672ec386ddfb52cd0d9f.tar.xz
Fix this assert. IP can point to an instruction with strange dominance
properties (invoke). Just assert that the instruction we return dominates the insertion point. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@151511 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/ScalarEvolutionExpander.cpp35
-rw-r--r--test/Transforms/LoopStrengthReduce/dominate-assert.ll30
2 files changed, 50 insertions, 15 deletions
diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp
index 95c1df9d5a..69507beeaa 100644
--- a/lib/Analysis/ScalarEvolutionExpander.cpp
+++ b/lib/Analysis/ScalarEvolutionExpander.cpp
@@ -34,16 +34,15 @@ Value *SCEVExpander::ReuseOrCreateCast(Value *V, Type *Ty,
// This function must be called with the builder having a valid insertion
// point. It doesn't need to be the actual IP where the uses of the returned
// cast will be added, but it must dominate such IP.
- // We use this precondition to assert that we can produce a cast that will
- // dominate all its uses. In particular, this is crucial for the case
- // where the builder's insertion point *is* the point where we were asked
- // to put the cast.
+ // We use this precondition to produce a cast that will dominate all its
+ // uses. In particular, this is crucial for the case where the builder's
+ // insertion point *is* the point where we were asked to put the cast.
// Since we don't know the the builder's insertion point is actually
// where the uses will be added (only that it dominates it), we are
// not allowed to move it.
BasicBlock::iterator BIP = Builder.GetInsertPoint();
- assert(BIP == IP || SE.DT->dominates(IP, BIP));
+ Instruction *Ret = NULL;
// Check to see if there is already a cast!
for (Value::use_iterator UI = V->use_begin(), E = V->use_end();
@@ -59,22 +58,28 @@ Value *SCEVExpander::ReuseOrCreateCast(Value *V, Type *Ty,
// Create a new cast, and leave the old cast in place in case
// it is being used as an insert point. Clear its operand
// so that it doesn't hold anything live.
- Instruction *NewCI = CastInst::Create(Op, V, Ty, "", IP);
- NewCI->takeName(CI);
- CI->replaceAllUsesWith(NewCI);
+ Ret = CastInst::Create(Op, V, Ty, "", IP);
+ Ret->takeName(CI);
+ CI->replaceAllUsesWith(Ret);
CI->setOperand(0, UndefValue::get(V->getType()));
- rememberInstruction(NewCI);
- return NewCI;
+ break;
}
- rememberInstruction(CI);
- return CI;
+ Ret = CI;
+ break;
}
}
// Create a new cast.
- Instruction *I = CastInst::Create(Op, V, Ty, V->getName(), IP);
- rememberInstruction(I);
- return I;
+ if (!Ret)
+ Ret = CastInst::Create(Op, V, Ty, V->getName(), IP);
+
+ // We assert at the end of the function since IP might point to an
+ // instruction with different dominance properties than a cast
+ // (an invoke for example) and not dominate BIP (but the cast does).
+ assert(SE.DT->dominates(Ret, BIP));
+
+ rememberInstruction(Ret);
+ return Ret;
}
/// InsertNoopCastOfTo - Insert a cast of V to the specified type,
diff --git a/test/Transforms/LoopStrengthReduce/dominate-assert.ll b/test/Transforms/LoopStrengthReduce/dominate-assert.ll
index 89f2f60334..b87bf620de 100644
--- a/test/Transforms/LoopStrengthReduce/dominate-assert.ll
+++ b/test/Transforms/LoopStrengthReduce/dominate-assert.ll
@@ -38,3 +38,33 @@ bb8:
bb9:
resume { i8*, i32 } zeroinitializer
}
+
+
+define void @h() {
+bb1:
+ invoke void @g() optsize
+ to label %bb2 unwind label %bb5
+bb2:
+ %arrayctor.cur = phi i8* [ undef, %bb1 ], [ %arrayctor.next, %bb3 ]
+ invoke void @g() optsize
+ to label %bb3 unwind label %bb6
+bb3:
+ %arrayctor.next = getelementptr inbounds i8* %arrayctor.cur, i64 1
+ br label %bb2
+bb4:
+ ret void
+bb5:
+ %tmp = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
+ invoke void @g() optsize
+ to label %bb4 unwind label %bb7
+bb6:
+ %tmp1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
+ %arraydestroy.isempty = icmp eq i8* undef, %arrayctor.cur
+ ret void
+bb7:
+ %lpad.nonloopexit = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ catch i8* null
+ ret void
+}