[llvm] e10e782 - [StackSafety] Skip ambiguous lifetime analysis
Vitaly Buka via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 16 18:06:04 PDT 2020
Author: Vitaly Buka
Date: 2020-08-16T18:05:52-07:00
New Revision: e10e7829bf6f10c053c05e42b676d7acaf54a221
URL: https://github.com/llvm/llvm-project/commit/e10e7829bf6f10c053c05e42b676d7acaf54a221
DIFF: https://github.com/llvm/llvm-project/commit/e10e7829bf6f10c053c05e42b676d7acaf54a221.diff
LOG: [StackSafety] Skip ambiguous lifetime analysis
If we can't identify alloca used in lifetime marker we
need to assume to worst case scenario.
Reviewed By: eugenis
Differential Revision: https://reviews.llvm.org/D84630
Added:
llvm/test/Transforms/SafeStack/X86/no-crash-on-lifetime.ll
Modified:
llvm/include/llvm/Analysis/StackLifetime.h
llvm/lib/Analysis/StackLifetime.cpp
llvm/test/Analysis/StackSafetyAnalysis/lifetime.ll
llvm/test/CodeGen/AArch64/stack-tagging.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/StackLifetime.h b/llvm/include/llvm/Analysis/StackLifetime.h
index 8abc6cc1ce00..1c0e10368daf 100644
--- a/llvm/include/llvm/Analysis/StackLifetime.h
+++ b/llvm/include/llvm/Analysis/StackLifetime.h
@@ -121,6 +121,8 @@ class StackLifetime {
DenseMap<const BasicBlock *, SmallVector<std::pair<unsigned, Marker>, 4>>
BBMarkers;
+ bool HasUnknownLifetimeStartOrEnd = false;
+
void dumpAllocas() const;
void dumpBlockLiveness() const;
void dumpLiveRanges() const;
diff --git a/llvm/lib/Analysis/StackLifetime.cpp b/llvm/lib/Analysis/StackLifetime.cpp
index 9727b7a33d1f..ef8103f6c516 100644
--- a/llvm/lib/Analysis/StackLifetime.cpp
+++ b/llvm/lib/Analysis/StackLifetime.cpp
@@ -11,6 +11,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/AssemblyAnnotationWriter.h"
#include "llvm/IR/BasicBlock.h"
@@ -63,42 +64,30 @@ bool StackLifetime::isAliveAfter(const AllocaInst *AI,
return getLiveRange(AI).test(InstNum);
}
-static bool readMarker(const Instruction *I, bool *IsStart) {
- if (!I->isLifetimeStartOrEnd())
- return false;
-
- auto *II = cast<IntrinsicInst>(I);
- *IsStart = II->getIntrinsicID() == Intrinsic::lifetime_start;
- return true;
-}
-
void StackLifetime::collectMarkers() {
InterestingAllocas.resize(NumAllocas);
DenseMap<const BasicBlock *, SmallDenseMap<const IntrinsicInst *, Marker>>
BBMarkerSet;
// Compute the set of start/end markers per basic block.
- for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) {
- const AllocaInst *AI = Allocas[AllocaNo];
- SmallVector<const Instruction *, 8> WorkList;
- WorkList.push_back(AI);
- while (!WorkList.empty()) {
- const Instruction *I = WorkList.pop_back_val();
- for (const User *U : I->users()) {
- if (auto *BI = dyn_cast<BitCastInst>(U)) {
- WorkList.push_back(BI);
- continue;
- }
- auto *UI = dyn_cast<IntrinsicInst>(U);
- if (!UI)
- continue;
- bool IsStart;
- if (!readMarker(UI, &IsStart))
- continue;
- if (IsStart)
- InterestingAllocas.set(AllocaNo);
- BBMarkerSet[UI->getParent()][UI] = {AllocaNo, IsStart};
+ for (const BasicBlock *BB : depth_first(&F)) {
+ for (const Instruction &I : *BB) {
+ const IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I);
+ if (!II || !II->isLifetimeStartOrEnd())
+ continue;
+ const AllocaInst *AI = llvm::findAllocaForValue(II->getArgOperand(1));
+ if (!AI) {
+ HasUnknownLifetimeStartOrEnd = true;
+ continue;
}
+ auto It = AllocaNumbering.find(AI);
+ if (It == AllocaNumbering.end())
+ continue;
+ auto AllocaNo = It->second;
+ bool IsStart = II->getIntrinsicID() == Intrinsic::lifetime_start;
+ if (IsStart)
+ InterestingAllocas.set(AllocaNo);
+ BBMarkerSet[BB][II] = {AllocaNo, IsStart};
}
}
@@ -304,6 +293,20 @@ StackLifetime::StackLifetime(const Function &F,
}
void StackLifetime::run() {
+ if (HasUnknownLifetimeStartOrEnd) {
+ // There is marker which we can't assign to a specific alloca, so we
+ // fallback to the most conservative results for the type.
+ switch (Type) {
+ case LivenessType::May:
+ LiveRanges.resize(NumAllocas, getFullLiveRange());
+ break;
+ case LivenessType::Must:
+ LiveRanges.resize(NumAllocas, LiveRange(Instructions.size()));
+ break;
+ }
+ return;
+ }
+
LiveRanges.resize(NumAllocas, LiveRange(Instructions.size()));
for (unsigned I = 0; I < NumAllocas; ++I)
if (!InterestingAllocas.test(I))
diff --git a/llvm/test/Analysis/StackSafetyAnalysis/lifetime.ll b/llvm/test/Analysis/StackSafetyAnalysis/lifetime.ll
index 1c7eeb5ac69c..470450a3a977 100644
--- a/llvm/test/Analysis/StackSafetyAnalysis/lifetime.ll
+++ b/llvm/test/Analysis/StackSafetyAnalysis/lifetime.ll
@@ -742,7 +742,7 @@ if.end:
; MAY-NEXT: Alive: <x y>
; MUST-NEXT: Alive: <y>
-ret void
+ ret void
}
define void @unreachable() {
@@ -778,7 +778,62 @@ end:
; CHECK: end:
; CHECK-NEXT: Alive: <x y>
-ret void
+ ret void
+}
+
+define void @non_alloca(i8* %p) {
+; CHECK-LABEL: define void @non_alloca
+entry:
+; CHECK: entry:
+; MAY-NEXT: Alive: <x y>
+; MUST-NEXT: Alive: <>
+ %x = alloca i8, align 4
+ %y = alloca i8, align 4
+
+ call void @llvm.lifetime.start.p0i8(i64 4, i8* %p)
+; CHECK: call void @llvm.lifetime.start.p0i8(i64 4, i8* %p)
+; MAY-NEXT: Alive: <x y>
+; MUST-NEXT: Alive: <>
+
+ call void @llvm.lifetime.start.p0i8(i64 4, i8* %x)
+; CHECK: call void @llvm.lifetime.start.p0i8(i64 4, i8* %x)
+; MAY-NEXT: Alive: <x y>
+; MUST-NEXT: Alive: <>
+
+ call void @llvm.lifetime.end.p0i8(i64 4, i8* %p)
+; CHECK: call void @llvm.lifetime.end.p0i8(i64 4, i8* %p)
+; MAY-NEXT: Alive: <x y>
+; MUST-NEXT: Alive: <>
+
+ ret void
+}
+
+define void @select_alloca(i1 %v) {
+; CHECK-LABEL: define void @select_alloca
+entry:
+; CHECK: entry:
+; MAY-NEXT: Alive: <x y>
+; MUST-NEXT: Alive: <>
+ %x = alloca i8, align 4
+ %y = alloca i8, align 4
+ %cxcy = select i1 %v, i8* %x, i8* %y
+
+ call void @llvm.lifetime.start.p0i8(i64 1, i8* %cxcy)
+; CHECK: call void @llvm.lifetime.start.p0i8(i64 1, i8* %cxcy)
+; MAY-NEXT: Alive: <x y>
+; MUST-NEXT: Alive: <>
+
+ call void @llvm.lifetime.start.p0i8(i64 1, i8* %x)
+; CHECK: call void @llvm.lifetime.start.p0i8(i64 1, i8* %x)
+; MAY-NEXT: Alive: <x y>
+; MUST-NEXT: Alive: <>
+
+ call void @llvm.lifetime.end.p0i8(i64 1, i8* %x)
+; CHECK: call void @llvm.lifetime.end.p0i8(i64 1, i8* %x)
+; MAY-NEXT: Alive: <x y>
+; MUST-NEXT: Alive: <>
+
+ ret void
}
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
diff --git a/llvm/test/CodeGen/AArch64/stack-tagging.ll b/llvm/test/CodeGen/AArch64/stack-tagging.ll
index 275b8a7dbad7..83fe4025ea0c 100644
--- a/llvm/test/CodeGen/AArch64/stack-tagging.ll
+++ b/llvm/test/CodeGen/AArch64/stack-tagging.ll
@@ -192,10 +192,9 @@ another_bb:
; CHECK: alloca { i32, [12 x i8] }, align 16
; CHECK: call { i32, [12 x i8] }* @llvm.aarch64.tagp
; CHECK: call void @llvm.aarch64.settag(
-; SSI: alloca i32, align 4
-; NOSSI: alloca { i32, [12 x i8] }, align 16
-; NOSSI: call { i32, [12 x i8] }* @llvm.aarch64.tagp
-; NOSSI: call void @llvm.aarch64.settag(
+; CHECK: alloca { i32, [12 x i8] }, align 16
+; CHECK: call { i32, [12 x i8] }* @llvm.aarch64.tagp
+; CHECK: call void @llvm.aarch64.settag(
; CHECK: store i32
; CHECK: call void @noUse32(i32*
; CHECK: store i32
@@ -203,7 +202,7 @@ another_bb:
; CHECK: call void @noUse32(i32*
; CHECK: call void @llvm.aarch64.settag(
; CHECK: call void @llvm.aarch64.settag(
-; NOSSI: call void @llvm.aarch64.settag(
+; CHECK: call void @llvm.aarch64.settag(
; CHECK: ret void
-!0 = !{}
\ No newline at end of file
+!0 = !{}
diff --git a/llvm/test/Transforms/SafeStack/X86/no-crash-on-lifetime.ll b/llvm/test/Transforms/SafeStack/X86/no-crash-on-lifetime.ll
new file mode 100644
index 000000000000..ee4261813e7f
--- /dev/null
+++ b/llvm/test/Transforms/SafeStack/X86/no-crash-on-lifetime.ll
@@ -0,0 +1,16 @@
+; RUN: opt -safe-stack -S -mtriple=x86_64-pc-linux-gnu < %s -o -d
+
+%class.F = type { %class.o, i8, [7 x i8] }
+%class.o = type <{ i8*, i32, [4 x i8] }>
+
+define dso_local void @_ZN1s1tE1F(%class.F* byval(%class.F) %g) local_unnamed_addr safestack align 32 {
+entry:
+ %ref.tmp.i.i.i = alloca i64, align 1
+ call void undef(%class.F* %g)
+ %ref.tmp.i.i.0..sroa_idx.i5 = bitcast i64* %ref.tmp.i.i.i to i8*
+ call void @llvm.lifetime.start.p0i8(i64 3, i8* %ref.tmp.i.i.0..sroa_idx.i5)
+ ret void
+}
+
+declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1
+
More information about the llvm-commits
mailing list