diff options
author | Chris Lattner <sabre@nondot.org> | 2007-11-09 17:33:02 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-11-09 17:33:02 +0000 |
commit | f9c0fd748871c39ba4b26a7726faba8bd5f462ea (patch) | |
tree | 05287273ec9c5475fb4dfd89dbab2ac6eeb0ff70 /llvm/lib/Transforms | |
parent | 19d4dbd217ac672dbee381e72ae5011d151a40ec (diff) | |
download | bcm5719-llvm-f9c0fd748871c39ba4b26a7726faba8bd5f462ea.tar.gz bcm5719-llvm-f9c0fd748871c39ba4b26a7726faba8bd5f462ea.zip |
Tighten up a check for folding away loads from (newly constant) globals. This
fixes a crash on Transforms/GlobalOpt/2007-11-09-GEP-GEP-Crash.ll and
rdar://5585488.
llvm-svn: 43949
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/IPO/GlobalOpt.cpp | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp index 779b4a1871c..76f04efda61 100644 --- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -342,12 +342,17 @@ static bool CleanupConstantGlobalUsers(Value *V, Constant *Init) { Changed = true; } } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(U)) { - Constant *SubInit = 0; - ConstantExpr *CE = - dyn_cast_or_null<ConstantExpr>(ConstantFoldInstruction(GEP)); - if (Init && CE && CE->getOpcode() == Instruction::GetElementPtr) - SubInit = ConstantFoldLoadThroughGEPConstantExpr(Init, CE); - Changed |= CleanupConstantGlobalUsers(GEP, SubInit); + // Do not transform "gepinst (gep constexpr (GV))" here, because forming + // "gepconstexpr (gep constexpr (GV))" will cause the two gep's to fold + // and will invalidate our notion of what Init is. + if (!isa<ConstantExpr>(GEP->getOperand(0))) { + ConstantExpr *CE = + dyn_cast_or_null<ConstantExpr>(ConstantFoldInstruction(GEP)); + if (Init && CE && CE->getOpcode() == Instruction::GetElementPtr) + if (Constant *SubInit = + ConstantFoldLoadThroughGEPConstantExpr(Init, CE)) + Changed |= CleanupConstantGlobalUsers(GEP, SubInit); + } if (GEP->use_empty()) { GEP->eraseFromParent(); |