Index: llvm/trunk/lib/Transforms/Scalar/SROA.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/SROA.cpp +++ llvm/trunk/lib/Transforms/Scalar/SROA.cpp @@ -2890,7 +2890,13 @@ (void)New; DEBUG(dbgs() << " to: " << *New << "\n"); - return true; + + // Lifetime intrinsics are only promotable if they cover the whole alloca. + // (In theory, intrinsics which partially cover an alloca could be + // promoted, but PromoteMemToReg doesn't handle that case.) + bool IsWholeAlloca = NewBeginOffset == NewAllocaBeginOffset && + NewEndOffset == NewAllocaEndOffset; + return IsWholeAlloca; } bool visitPHINode(PHINode &PN) { Index: llvm/trunk/test/Transforms/SROA/basictest.ll =================================================================== --- llvm/trunk/test/Transforms/SROA/basictest.ll +++ llvm/trunk/test/Transforms/SROA/basictest.ll @@ -1669,3 +1669,18 @@ } declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind + +define void @PR27999() unnamed_addr { +; CHECK-LABEL: @PR27999( +; CHECK: alloca [2 x i64], align 8 +; CHECK: call void @llvm.lifetime.start(i64 16, +; CHECK: call void @llvm.lifetime.end(i64 8, +entry-block: + %0 = alloca [2 x i64], align 8 + %1 = bitcast [2 x i64]* %0 to i8* + call void @llvm.lifetime.start(i64 16, i8* %1) + %2 = getelementptr inbounds [2 x i64], [2 x i64]* %0, i32 0, i32 1 + %3 = bitcast i64* %2 to i8* + call void @llvm.lifetime.end(i64 8, i8* %3) + ret void +}