blob: 0c02d612c02c39f581a6951945294c94700e5044 [file] [log] [blame]
From 6f85225ef3791357f9b1aa097b575b0a2b0dff48 Mon Sep 17 00:00:00 2001
From: Peter Collingbourne <peter@pcc.me.uk>
Date: Wed, 18 Aug 2021 15:03:03 -0700
Subject: [PATCH] StackLifetime: Remove asserts for multiple lifetime
intrinsics.
According to the langref, it is valid to have multiple consecutive
lifetime start or end intrinsics on the same object.
For llvm.lifetime.start:
"If ptr [...] is a stack object that is already alive, it simply
fills all bytes of the object with poison."
For llvm.lifetime.end:
"Calling llvm.lifetime.end on an already dead alloca is no-op."
However, we currently fail an assertion in such cases. I've observed
the assertion failure when the loop vectorization pass duplicates
the intrinsic.
We can conservatively handle these intrinsics by ignoring all but
the first one, which can be implemented by removing the assertions.
Differential Revision: https://reviews.llvm.org/D108337
---
llvm/lib/Analysis/StackLifetime.cpp | 2 --
.../Analysis/StackSafetyAnalysis/lifetime.ll | 25 +++++++++++++++++++
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Analysis/StackLifetime.cpp b/llvm/lib/Analysis/StackLifetime.cpp
index ab5f2db7d1cd..a3d5c81e261d 100644
--- a/llvm/lib/Analysis/StackLifetime.cpp
+++ b/llvm/lib/Analysis/StackLifetime.cpp
@@ -257,14 +257,12 @@ void StackLifetime::calculateLiveIntervals() {
unsigned AllocaNo = It.second.AllocaNo;
if (IsStart) {
- assert(!Started.test(AllocaNo) || Start[AllocaNo] == BBStart);
if (!Started.test(AllocaNo)) {
Started.set(AllocaNo);
Ended.reset(AllocaNo);
Start[AllocaNo] = InstNo;
}
} else {
- assert(!Ended.test(AllocaNo));
if (Started.test(AllocaNo)) {
LiveRanges[AllocaNo].addRange(Start[AllocaNo], InstNo);
Started.reset(AllocaNo);
diff --git a/llvm/test/Analysis/StackSafetyAnalysis/lifetime.ll b/llvm/test/Analysis/StackSafetyAnalysis/lifetime.ll
index 45c68b5e3d02..f88e38ce52cc 100644
--- a/llvm/test/Analysis/StackSafetyAnalysis/lifetime.ll
+++ b/llvm/test/Analysis/StackSafetyAnalysis/lifetime.ll
@@ -924,6 +924,31 @@ entry:
ret void
}
+define void @multiple_start_end() {
+; CHECK-LABEL: define void @multiple_start_end
+entry:
+; CHECK: entry:
+; CHECK-NEXT: Alive: <>
+ %x = alloca i8
+ call void @llvm.lifetime.start.p0i8(i64 1, i8* %x)
+; CHECK: call void @llvm.lifetime.start.p0i8(i64 1, i8* %x)
+; CHECK-NEXT: Alive: <x>
+
+ call void @llvm.lifetime.start.p0i8(i64 1, i8* %x)
+; CHECK: call void @llvm.lifetime.start.p0i8(i64 1, i8* %x)
+; CHECK-NEXT: Alive: <x>
+
+ call void @llvm.lifetime.end.p0i8(i64 1, i8* %x)
+; CHECK: call void @llvm.lifetime.end.p0i8(i64 1, i8* %x)
+; CHECK-NEXT: Alive: <>
+
+ call void @llvm.lifetime.end.p0i8(i64 1, i8* %x)
+; CHECK: call void @llvm.lifetime.end.p0i8(i64 1, i8* %x)
+; CHECK-NEXT: Alive: <>
+
+ ret void
+}
+
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
declare void @llvm.lifetime.start.p0i32(i64, i32* nocapture)
--
2.33.0.rc2.250.ged5fa647cd-goog