[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