[llvm] a406605 - [StackSafety] Ignore allocas with partial lifetime markers
Vitaly Buka via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 27 13:54:52 PDT 2020
Author: Vitaly Buka
Date: 2020-08-27T13:54:41-07:00
New Revision: a40660551ea1ed01f69406d81e39efe73d86cbec
URL: https://github.com/llvm/llvm-project/commit/a40660551ea1ed01f69406d81e39efe73d86cbec
DIFF: https://github.com/llvm/llvm-project/commit/a40660551ea1ed01f69406d81e39efe73d86cbec.diff
LOG: [StackSafety] Ignore allocas with partial lifetime markers
Reviewed By: eugenis
Differential Revision: https://reviews.llvm.org/D86672
Added:
Modified:
llvm/lib/Analysis/StackLifetime.cpp
llvm/test/Analysis/StackSafetyAnalysis/lifetime.ll
llvm/test/Transforms/SafeStack/X86/layout-frag.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/StackLifetime.cpp b/llvm/lib/Analysis/StackLifetime.cpp
index ef8103f6c516..f95a8918afbb 100644
--- a/llvm/lib/Analysis/StackLifetime.cpp
+++ b/llvm/lib/Analysis/StackLifetime.cpp
@@ -64,18 +64,44 @@ bool StackLifetime::isAliveAfter(const AllocaInst *AI,
return getLiveRange(AI).test(InstNum);
}
+// Returns unique alloca annotated by lifetime marker only if
+// markers has the same size and points to the alloca start.
+static const AllocaInst *findMatchingAlloca(const IntrinsicInst &II,
+ const DataLayout &DL) {
+ const AllocaInst *AI = findAllocaForValue(II.getArgOperand(1), true);
+ if (!AI)
+ return nullptr;
+
+ auto AllocaSizeInBits = AI->getAllocationSizeInBits(DL);
+ if (!AllocaSizeInBits)
+ return nullptr;
+ int64_t AllocaSize = AllocaSizeInBits.getValue() / 8;
+
+ auto *Size = dyn_cast<ConstantInt>(II.getArgOperand(0));
+ if (!Size)
+ return nullptr;
+ int64_t LifetimeSize = Size->getSExtValue();
+
+ if (LifetimeSize != -1 && LifetimeSize != AllocaSize)
+ return nullptr;
+
+ return AI;
+}
+
void StackLifetime::collectMarkers() {
InterestingAllocas.resize(NumAllocas);
DenseMap<const BasicBlock *, SmallDenseMap<const IntrinsicInst *, Marker>>
BBMarkerSet;
+ const DataLayout &DL = F.getParent()->getDataLayout();
+
// Compute the set of start/end markers per basic block.
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));
+ const AllocaInst *AI = findMatchingAlloca(*II, DL);
if (!AI) {
HasUnknownLifetimeStartOrEnd = true;
continue;
diff --git a/llvm/test/Analysis/StackSafetyAnalysis/lifetime.ll b/llvm/test/Analysis/StackSafetyAnalysis/lifetime.ll
index d29029530b6c..45c68b5e3d02 100644
--- a/llvm/test/Analysis/StackSafetyAnalysis/lifetime.ll
+++ b/llvm/test/Analysis/StackSafetyAnalysis/lifetime.ll
@@ -648,8 +648,8 @@ entry:
; CHECK: entry:
; CHECK-NEXT: Alive: <>
%x = alloca i8, align 4
- call void @llvm.lifetime.start.p0i8(i64 4, i8* %x)
-; CHECK: call void @llvm.lifetime.start.p0i8(i64 4, i8* %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>
br label %l2
@@ -659,8 +659,8 @@ l2: ; preds = %l2, %entry
; MAY-NEXT: Alive: <x>
; MUST-NEXT: Alive: <>
call void @capture8(i8* %x)
- call void @llvm.lifetime.end.p0i8(i64 4, i8* %x)
-; CHECK: call void @llvm.lifetime.end.p0i8(i64 4, i8* %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: <>
br label %l2
@@ -673,8 +673,8 @@ entry:
; CHECK-NEXT: Alive: <>
%x = alloca i8, align 4
%y = alloca i8, align 4
- call void @llvm.lifetime.start.p0i8(i64 4, i8* %x)
-; CHECK: call void @llvm.lifetime.start.p0i8(i64 4, i8* %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>
br label %l2
@@ -682,17 +682,17 @@ entry:
l2: ; preds = %l2, %entry
; CHECK: l2:
; CHECK-NEXT: Alive: <x>
- call void @llvm.lifetime.start.p0i8(i64 4, i8* %y)
-; CHECK: call void @llvm.lifetime.start.p0i8(i64 4, i8* %y)
+ call void @llvm.lifetime.start.p0i8(i64 1, i8* %y)
+; CHECK: call void @llvm.lifetime.start.p0i8(i64 1, i8* %y)
; CHECK-NEXT: Alive: <x y>
call void @capture8(i8* %y)
- call void @llvm.lifetime.end.p0i8(i64 4, i8* %y)
-; CHECK: call void @llvm.lifetime.end.p0i8(i64 4, i8* %y)
+ call void @llvm.lifetime.end.p0i8(i64 1, i8* %y)
+; CHECK: call void @llvm.lifetime.end.p0i8(i64 1, i8* %y)
; CHECK-NEXT: Alive: <x>
- call void @llvm.lifetime.start.p0i8(i64 4, i8* %x)
-; CHECK: call void @llvm.lifetime.start.p0i8(i64 4, i8* %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 @capture8(i8* %x)
@@ -758,8 +758,8 @@ entry:
if.then:
; CHECK: if.then:
; CHECK-NEXT: Alive: <>
- call void @llvm.lifetime.start.p0i8(i64 4, i8* %y)
-; CHECK: call void @llvm.lifetime.start.p0i8(i64 4, i8* %y)
+ call void @llvm.lifetime.start.p0i8(i64 1, i8* %y)
+; CHECK: call void @llvm.lifetime.start.p0i8(i64 1, i8* %y)
; CHECK-NEXT: Alive: <y>
br label %if.end
@@ -769,12 +769,12 @@ if.then:
if.else:
; CHECK: if.else:
; CHECK-NEXT: Alive: <>
- call void @llvm.lifetime.start.p0i8(i64 4, i8* %y)
-; CHECK: call void @llvm.lifetime.start.p0i8(i64 4, i8* %y)
+ call void @llvm.lifetime.start.p0i8(i64 1, i8* %y)
+; CHECK: call void @llvm.lifetime.start.p0i8(i64 1, i8* %y)
; CHECK-NEXT: Alive: <y>
- call void @llvm.lifetime.start.p0i8(i64 4, i8* %x)
-; CHECK: call void @llvm.lifetime.start.p0i8(i64 4, i8* %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 y>
br label %if.end
@@ -797,12 +797,12 @@ entry:
%x = alloca i8, align 4
%y = alloca i8, align 4
- call void @llvm.lifetime.start.p0i8(i64 4, i8* %y)
-; CHECK: call void @llvm.lifetime.start.p0i8(i64 4, i8* %y)
+ call void @llvm.lifetime.start.p0i8(i64 1, i8* %y)
+; CHECK: call void @llvm.lifetime.start.p0i8(i64 1, i8* %y)
; CHECK-NEXT: Alive: <y>
- call void @llvm.lifetime.start.p0i8(i64 4, i8* %x)
-; CHECK: call void @llvm.lifetime.start.p0i8(i64 4, i8* %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 y>
br label %end
@@ -880,8 +880,54 @@ entry:
ret void
}
+define void @alloca_offset() {
+; CHECK-LABEL: define void @alloca_offset
+entry:
+; CHECK: entry:
+; MAY-NEXT: Alive: <x>
+; MUST-NEXT: Alive: <>
+ %x = alloca [5 x i32], align 4
+ %x2 = getelementptr [5 x i32], [5 x i32]* %x, i64 0, i64 1
+
+ call void @llvm.lifetime.start.p0i32(i64 20, i32* %x2)
+; CHECK: call void @llvm.lifetime.start.p0i32(i64 20, i32* %x2)
+; MAY-NEXT: Alive: <x>
+; MUST-NEXT: Alive: <>
+
+ call void @llvm.lifetime.end.p0i32(i64 20, i32* %x2)
+; CHECK: call void @llvm.lifetime.end.p0i32(i64 20, i32* %x2)
+; MAY-NEXT: Alive: <x>
+; MUST-NEXT: Alive: <>
+
+ ret void
+}
+
+define void @alloca_size() {
+; CHECK-LABEL: define void @alloca_size
+entry:
+; CHECK: entry:
+; MAY-NEXT: Alive: <x>
+; MUST-NEXT: Alive: <>
+ %x = alloca [5 x i32], align 4
+ %x2 = getelementptr [5 x i32], [5 x i32]* %x, i64 0, i64 0
+
+ call void @llvm.lifetime.start.p0i32(i64 15, i32* %x2)
+; CHECK: call void @llvm.lifetime.start.p0i32(i64 15, i32* %x2)
+; MAY-NEXT: Alive: <x>
+; MUST-NEXT: Alive: <>
+
+ call void @llvm.lifetime.end.p0i32(i64 15, i32* %x2)
+; CHECK: call void @llvm.lifetime.end.p0i32(i64 15, i32* %x2)
+; MAY-NEXT: Alive: <x>
+; MUST-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)
+declare void @llvm.lifetime.end.p0i32(i64, i32* nocapture)
declare void @capture8(i8*)
declare void @capture32(i32*)
declare void @capture64(i64*)
diff --git a/llvm/test/Transforms/SafeStack/X86/layout-frag.ll b/llvm/test/Transforms/SafeStack/X86/layout-frag.ll
index b9831c26b74c..40b9cf7f8129 100644
--- a/llvm/test/Transforms/SafeStack/X86/layout-frag.ll
+++ b/llvm/test/Transforms/SafeStack/X86/layout-frag.ll
@@ -14,16 +14,16 @@ entry:
%x0a = bitcast i64* %x0 to i8*
%x2a = bitcast i64* %x2 to i8*
- call void @llvm.lifetime.start.p0i8(i64 4, i8* %x0a)
+ call void @llvm.lifetime.start.p0i8(i64 8, i8* %x0a)
call void @capture64(i64* %x0)
- call void @llvm.lifetime.end.p0i8(i64 4, i8* %x0a)
+ call void @llvm.lifetime.end.p0i8(i64 8, i8* %x0a)
- call void @llvm.lifetime.start.p0i8(i64 4, i8* %x1)
- call void @llvm.lifetime.start.p0i8(i64 4, i8* %x2a)
+ call void @llvm.lifetime.start.p0i8(i64 1, i8* %x1)
+ call void @llvm.lifetime.start.p0i8(i64 8, i8* %x2a)
call void @capture8(i8* %x1)
call void @capture64(i64* %x2)
- call void @llvm.lifetime.end.p0i8(i64 4, i8* %x1)
- call void @llvm.lifetime.end.p0i8(i64 4, i8* %x2a)
+ call void @llvm.lifetime.end.p0i8(i64 1, i8* %x1)
+ call void @llvm.lifetime.end.p0i8(i64 8, i8* %x2a)
; Test that i64 allocas share space.
; CHECK: getelementptr i8, i8* %unsafe_stack_ptr, i32 -8
More information about the llvm-commits
mailing list