aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/LevelRaise.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2002-05-14 05:23:45 +0000
committerChris Lattner <sabre@nondot.org>2002-05-14 05:23:45 +0000
commitc99428f3c9235e94464a02c3a0db8a609bf33188 (patch)
tree9bf985a6e794fc86a9f63619ba33e567c82c40de /lib/Transforms/LevelRaise.cpp
parent18fb2a6682d25e07f017b77a13e4fbff0899ac33 (diff)
Fix a major source of "type unsafety", where a cast is neccesary, but can
be put either before or after a load. We chose to cast the value loaded instead of the pointer to load from. Fixes bug: test/Regression/Transforms/LevelRaise/2002-05-10-LoadPeephole.ll git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2621 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/LevelRaise.cpp')
-rw-r--r--lib/Transforms/LevelRaise.cpp42
1 files changed, 40 insertions, 2 deletions
diff --git a/lib/Transforms/LevelRaise.cpp b/lib/Transforms/LevelRaise.cpp
index af6555cc20..de45b0a243 100644
--- a/lib/Transforms/LevelRaise.cpp
+++ b/lib/Transforms/LevelRaise.cpp
@@ -356,7 +356,6 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
}
#endif
-#if 1
} else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
Value *Val = SI->getOperand(0);
Value *Pointer = SI->getPointerOperand();
@@ -396,6 +395,46 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
return true;
}
+ } else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
+ Value *Pointer = LI->getOperand(0);
+ const Type *PtrElType =
+ cast<PointerType>(Pointer->getType())->getElementType();
+
+ // Peephole optimize the following instructions:
+ // %Val = cast <T1>* to <T2>* ;; If T1 is losslessly convertable to T2
+ // %t = load <T2>* %P
+ //
+ // Into:
+ // %t = load <T1>* %P
+ // %Val = cast <T1> to <T2>
+ //
+ // Note: This is not taken care of by expr conversion because there might
+ // not be a cast available for the store to convert the incoming value of.
+ // This code is basically here to make sure that pointers don't have casts
+ // if possible.
+ //
+ if (CastInst *CI = dyn_cast<CastInst>(Pointer))
+ if (Value *CastSrc = CI->getOperand(0)) // CSPT = CastSrcPointerType
+ if (PointerType *CSPT = dyn_cast<PointerType>(CastSrc->getType()))
+ // convertable types?
+ if (PtrElType->isLosslesslyConvertableTo(CSPT->getElementType()) &&
+ !LI->hasIndices()) { // No subscripts yet!
+ PRINT_PEEPHOLE2("load-src-cast:in ", Pointer, LI);
+
+ // Create the new load instruction... loading the pre-casted value
+ LoadInst *NewLI = new LoadInst(CastSrc, LI->getName());
+
+ // Insert the new T cast instruction... stealing old T's name
+ CastInst *NCI = new CastInst(NewLI, LI->getType(), CI->getName());
+ BI = BB->getInstList().insert(BI, NewLI)+1;
+
+ // Replace the old store with a new one!
+ ReplaceInstWithInst(BB->getInstList(), BI, NCI);
+ PRINT_PEEPHOLE3("load-src-cast:out", NCI, CastSrc, NewLI);
+ ++NumLoadStorePeepholes;
+ return true;
+ }
+
} else if (I->getOpcode() == Instruction::Add &&
isa<CastInst>(I->getOperand(1))) {
@@ -404,7 +443,6 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
++NumGEPInstFormed;
return true;
}
-#endif
}
return false;