diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp --- a/llvm/lib/Transforms/Scalar/SROA.cpp +++ b/llvm/lib/Transforms/Scalar/SROA.cpp @@ -1983,13 +1983,22 @@ uint64_t RelBegin = S.beginOffset() - AllocBeginOffset; uint64_t RelEnd = S.endOffset() - AllocBeginOffset; + Use *U = S.getUse(); + + // Lifetime intrinsics operate over the whole alloca whose sizes are usually + // larger than other load/store slices (RelEnd > Size). But lifetime are + // always promotable and should not impact other slices' promotability of the + // partition. + if (IntrinsicInst *II = dyn_cast(U->getUser())) { + if (II->isLifetimeStartOrEnd() || II->isDroppable()) + return true; + } + // We can't reasonably handle cases where the load or store extends past // the end of the alloca's type and into its padding. if (RelEnd > Size) return false; - Use *U = S.getUse(); - if (LoadInst *LI = dyn_cast(U->getUser())) { if (LI->isVolatile()) return false; @@ -2044,9 +2053,6 @@ return false; if (!S.isSplittable()) return false; // Skip any unsplittable intrinsics. - } else if (IntrinsicInst *II = dyn_cast(U->getUser())) { - if (!II->isLifetimeStartOrEnd() && !II->isDroppable()) - return false; } else { return false; } diff --git a/llvm/test/Transforms/SROA/lifetime-intrinsic.ll b/llvm/test/Transforms/SROA/lifetime-intrinsic.ll --- a/llvm/test/Transforms/SROA/lifetime-intrinsic.ll +++ b/llvm/test/Transforms/SROA/lifetime-intrinsic.ll @@ -11,11 +11,9 @@ define i16 @with_lifetime(i32 %a, i32 %b) #0 { ; CHECK-LABEL: @with_lifetime( -; CHECK-NEXT: [[ARR_SROA_0_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i32 [[A:%.*]] to i16 -; CHECK-NEXT: [[ARR_SROA_0_SROA_4_0_EXTRACT_SHIFT:%.*]] = lshr i32 [[A]], 16 -; CHECK-NEXT: [[ARR_SROA_0_SROA_4_0_EXTRACT_TRUNC:%.*]] = trunc i32 [[ARR_SROA_0_SROA_4_0_EXTRACT_SHIFT]] to i16 +; CHECK-NEXT: [[ARR_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i32 [[A:%.*]] to i16 ; CHECK-NEXT: [[ARR_SROA_4_4_EXTRACT_TRUNC:%.*]] = trunc i32 [[B:%.*]] to i16 -; CHECK-NEXT: [[RET:%.*]] = add i16 [[ARR_SROA_0_SROA_0_0_EXTRACT_TRUNC]], [[ARR_SROA_4_4_EXTRACT_TRUNC]] +; CHECK-NEXT: [[RET:%.*]] = add i16 [[ARR_SROA_0_0_EXTRACT_TRUNC]], [[ARR_SROA_4_4_EXTRACT_TRUNC]] ; CHECK-NEXT: ret i16 [[RET]] ; %arr = alloca %i32x2, align 4