From: Eli Friedman Date: Mon, 8 Aug 2016 01:30:53 +0000 (+0000) Subject: [SROA] Fix crash with lifetime intrinsic partially covering alloca. X-Git-Tag: android-x86-7.1-r4~29023 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=0ba29b6226e8eef38bb778e54d8f287028c35136;p=android-x86%2Fexternal-llvm.git [SROA] Fix crash with lifetime intrinsic partially covering alloca. Summary: PromoteMemToReg looks specifically for the pattern bitcast+lifetime.start (or a bitcast-equivalent GEP); any offset will lead to an assertion failure. Fixes https://llvm.org/bugs/show_bug.cgi?id=27999 . Differential Revision: https://reviews.llvm.org/D22737 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@277969 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp index 7d33259c030..67d90a346f2 100644 --- a/lib/Transforms/Scalar/SROA.cpp +++ b/lib/Transforms/Scalar/SROA.cpp @@ -2890,7 +2890,13 @@ private: (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) { diff --git a/test/Transforms/SROA/basictest.ll b/test/Transforms/SROA/basictest.ll index 968669ad4f6..75fe279849d 100644 --- a/test/Transforms/SROA/basictest.ll +++ b/test/Transforms/SROA/basictest.ll @@ -1669,3 +1669,18 @@ entry: } 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 +}