diff options
author | Chris Lattner <sabre@nondot.org> | 2002-05-14 05:23:45 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2002-05-14 05:23:45 +0000 |
commit | c99428f3c9235e94464a02c3a0db8a609bf33188 (patch) | |
tree | 9bf985a6e794fc86a9f63619ba33e567c82c40de /lib/Transforms/LevelRaise.cpp | |
parent | 18fb2a6682d25e07f017b77a13e4fbff0899ac33 (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.cpp | 42 |
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; |