Add missing check for presence of target data.

This avoids a crash in visitAllocaInst when target data isn't available.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164539 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Richard Osborne 2012-09-24 17:10:03 +00:00
parent 84d882ee56
commit bdc76fc75a
2 changed files with 41 additions and 20 deletions

View File

@ -264,26 +264,28 @@ Instruction *InstCombiner::visitAllocaInst(AllocaInst &AI) {
} }
} }
// Check to see if this allocation is only modified by a memcpy/memmove from if (TD) {
// a constant global whose alignment is equal to or exceeds that of the // Check to see if this allocation is only modified by a memcpy/memmove from
// allocation. If this is the case, we can change all users to use // a constant global whose alignment is equal to or exceeds that of the
// the constant global instead. This is commonly produced by the CFE by // allocation. If this is the case, we can change all users to use
// constructs like "void foo() { int A[] = {1,2,3,4,5,6,7,8,9...}; }" if 'A' // the constant global instead. This is commonly produced by the CFE by
// is only subsequently read. // constructs like "void foo() { int A[] = {1,2,3,4,5,6,7,8,9...}; }" if 'A'
SmallVector<Instruction *, 4> ToDelete; // is only subsequently read.
if (MemTransferInst *Copy = isOnlyCopiedFromConstantGlobal(&AI, ToDelete)) { SmallVector<Instruction *, 4> ToDelete;
if (AI.getAlignment() <= getPointeeAlignment(Copy->getSource(), *TD)) { if (MemTransferInst *Copy = isOnlyCopiedFromConstantGlobal(&AI, ToDelete)) {
DEBUG(dbgs() << "Found alloca equal to global: " << AI << '\n'); if (AI.getAlignment() <= getPointeeAlignment(Copy->getSource(), *TD)) {
DEBUG(dbgs() << " memcpy = " << *Copy << '\n'); DEBUG(dbgs() << "Found alloca equal to global: " << AI << '\n');
for (unsigned i = 0, e = ToDelete.size(); i != e; ++i) DEBUG(dbgs() << " memcpy = " << *Copy << '\n');
EraseInstFromFunction(*ToDelete[i]); for (unsigned i = 0, e = ToDelete.size(); i != e; ++i)
Constant *TheSrc = cast<Constant>(Copy->getSource()); EraseInstFromFunction(*ToDelete[i]);
Instruction *NewI Constant *TheSrc = cast<Constant>(Copy->getSource());
= ReplaceInstUsesWith(AI, ConstantExpr::getBitCast(TheSrc, Instruction *NewI
AI.getType())); = ReplaceInstUsesWith(AI, ConstantExpr::getBitCast(TheSrc,
EraseInstFromFunction(*Copy); AI.getType()));
++NumGlobalCopies; EraseInstFromFunction(*Copy);
return NewI; ++NumGlobalCopies;
return NewI;
}
} }
} }

View File

@ -0,0 +1,19 @@
; RUN: opt < %s -instcombine -S | FileCheck %s
; Check we don't crash due to lack of target data.
@G = constant [100 x i8] zeroinitializer
declare void @bar(i8*)
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
define void @test() {
; CHECK: @test
; CHECK: llvm.memcpy
; CHECK ret void
%A = alloca [100 x i8]
%a = getelementptr inbounds [100 x i8]* %A, i64 0, i64 0
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* getelementptr inbounds ([100 x i8]* @G, i64 0, i32 0), i64 100, i32 4, i1 false)
call void @bar(i8* %a) readonly
ret void
}