aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-10-18 02:59:09 +0000
committerChris Lattner <sabre@nondot.org>2004-10-18 02:59:09 +0000
commit17be63552aa2ed0c36e7df00e680fb5f87a1ea42 (patch)
treeb2cc4ff5c254e7e4dc4c94cd4c704fcb83280c98
parent77bcee74da8f868c4fc83fda57f35fb72052079f (diff)
downloadexternal_llvm-17be63552aa2ed0c36e7df00e680fb5f87a1ea42.zip
external_llvm-17be63552aa2ed0c36e7df00e680fb5f87a1ea42.tar.gz
external_llvm-17be63552aa2ed0c36e7df00e680fb5f87a1ea42.tar.bz2
Turn things with obviously undefined semantics into 'store -> null'
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17110 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp60
1 files changed, 34 insertions, 26 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index f8373cb..3119e57 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -121,7 +121,6 @@ namespace {
Instruction *visitAllocationInst(AllocationInst &AI);
Instruction *visitFreeInst(FreeInst &FI);
Instruction *visitLoadInst(LoadInst &LI);
- Instruction *visitStoreInst(StoreInst &SI);
Instruction *visitBranchInst(BranchInst &BI);
Instruction *visitSwitchInst(SwitchInst &SI);
@@ -170,7 +169,7 @@ namespace {
} else {
// If we are replacing the instruction with itself, this must be in a
// segment of unreachable code, so just clobber the instruction.
- I.replaceAllUsesWith(Constant::getNullValue(I.getType()));
+ I.replaceAllUsesWith(UndefValue::get(I.getType()));
return &I;
}
}
@@ -3210,15 +3209,25 @@ Instruction *InstCombiner::visitCallSite(CallSite CS) {
Value *Callee = CS.getCalledValue();
- if (isa<ConstantPointerNull>(Callee) || isa<UndefValue>(Callee))
- // This instruction is not reachable, just remove it. Eventually, this
- // should get turned into an unreachable instruction.
- if (!isa<InvokeInst>(CS.getInstruction())) { // Don't hack the CFG!
- if (!CS.getInstruction()->use_empty())
- CS.getInstruction()->
- replaceAllUsesWith(UndefValue::get(CS.getInstruction()->getType()));
- return EraseInstFromFunction(*CS.getInstruction());
+ if (isa<ConstantPointerNull>(Callee) || isa<UndefValue>(Callee)) {
+ // This instruction is not reachable, just remove it. We insert a store to
+ // undef so that we know that this code is not reachable, despite the fact
+ // that we can't modify the CFG here.
+ new StoreInst(ConstantBool::True,
+ UndefValue::get(PointerType::get(Type::BoolTy)),
+ CS.getInstruction());
+
+ if (!CS.getInstruction()->use_empty())
+ CS.getInstruction()->
+ replaceAllUsesWith(UndefValue::get(CS.getInstruction()->getType()));
+
+ if (InvokeInst *II = dyn_cast<InvokeInst>(CS.getInstruction())) {
+ // Don't break the CFG, insert a dummy cond branch.
+ new BranchInst(II->getNormalDest(), II->getUnwindDest(),
+ ConstantBool::True, II);
}
+ return EraseInstFromFunction(*CS.getInstruction());
+ }
const PointerType *PTy = cast<PointerType>(Callee->getType());
const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
@@ -3717,10 +3726,17 @@ Instruction *InstCombiner::visitFreeInst(FreeInst &FI) {
return &FI;
}
+ // free undef -> unreachable.
+ if (isa<UndefValue>(Op)) {
+ // Insert a new store to null because we cannot modify the CFG here.
+ new StoreInst(ConstantBool::True,
+ UndefValue::get(PointerType::get(Type::BoolTy)), &FI);
+ return EraseInstFromFunction(FI);
+ }
+
// If we have 'free null' delete the instruction. This can happen in stl code
// when lots of inlining happens.
- // FIXME: free undef should be xformed into an 'unreachable' instruction.
- if (isa<ConstantPointerNull>(Op) || isa<UndefValue>(Op))
+ if (isa<ConstantPointerNull>(Op))
return EraseInstFromFunction(FI);
return 0;
@@ -3826,9 +3842,13 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
if (Constant *C = dyn_cast<Constant>(Op)) {
if ((C->isNullValue() || isa<UndefValue>(C)) &&
- !LI.isVolatile()) // load null -> undef
- // FIXME: this should become an unreachable instruction
+ !LI.isVolatile()) { // load null/undef -> undef
+ // Insert a new store to null instruction before the load to indicate that
+ // this code is not reachable. We do this instead of inserting an
+ // unreachable instruction directly because we cannot modify the CFG.
+ new StoreInst(UndefValue::get(LI.getType()), C, &LI);
return ReplaceInstUsesWith(LI, UndefValue::get(LI.getType()));
+ }
// Instcombine load (constant global) into the value loaded.
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Op))
@@ -3934,18 +3954,6 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
return 0;
}
-Instruction *InstCombiner::visitStoreInst(StoreInst &SI) {
- if (isa<ConstantPointerNull>(SI.getOperand(1)) ||
- isa<UndefValue>(SI.getOperand(1))) {
- // FIXME: This should become an unreachable instruction.
- return EraseInstFromFunction(SI);
- }
-
-
- return 0;
-}
-
-
Instruction *InstCombiner::visitBranchInst(BranchInst &BI) {
// Change br (not X), label True, label False to: br X, label False, True
Value *X;