1; RUN: opt -inline -S < %s | FileCheck %s
2target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
3
4declare void @llvm.lifetime.start(i64, i8*)
5declare void @llvm.lifetime.end(i64, i8*)
6
7define void @helper_both_markers() {
8  %a = alloca i8
9  ; Size in llvm.lifetime.start / llvm.lifetime.end differs from
10  ; allocation size. We should use the former.
11  call void @llvm.lifetime.start(i64 2, i8* %a)
12  call void @llvm.lifetime.end(i64 2, i8* %a)
13  ret void
14}
15
16define void @test_both_markers() {
17; CHECK-LABEL: @test_both_markers(
18; CHECK: llvm.lifetime.start(i64 2
19; CHECK-NEXT: llvm.lifetime.end(i64 2
20  call void @helper_both_markers()
21; CHECK-NEXT: llvm.lifetime.start(i64 2
22; CHECK-NEXT: llvm.lifetime.end(i64 2
23  call void @helper_both_markers()
24; CHECK-NEXT: ret void
25  ret void
26}
27
28;; Without this, the inliner will simplify out @test_no_marker before adding
29;; any lifetime markers.
30declare void @use(i8* %a)
31
32define void @helper_no_markers() {
33  %a = alloca i8 ; Allocation size is 1 byte.
34  call void @use(i8* %a)
35  ret void
36}
37
38;; We can't use CHECK-NEXT because there's an extra call void @use in between.
39;; Instead, we use CHECK-NOT to verify that there are no other lifetime calls.
40define void @test_no_marker() {
41; CHECK-LABEL: @test_no_marker(
42; CHECK-NOT: lifetime
43; CHECK: llvm.lifetime.start(i64 1
44; CHECK-NOT: lifetime
45; CHECK: llvm.lifetime.end(i64 1
46  call void @helper_no_markers()
47; CHECK-NOT: lifetime
48; CHECK: llvm.lifetime.start(i64 1
49; CHECK-NOT: lifetime
50; CHECK: llvm.lifetime.end(i64 1
51  call void @helper_no_markers()
52; CHECK-NOT: lifetime
53; CHECK: ret void
54  ret void
55}
56
57define void @helper_two_casts() {
58  %a = alloca i32
59  %b = bitcast i32* %a to i8*
60  call void @llvm.lifetime.start(i64 4, i8* %b)
61  %c = bitcast i32* %a to i8*
62  call void @llvm.lifetime.end(i64 4, i8* %c)
63  ret void
64}
65
66define void @test_two_casts() {
67; CHECK-LABEL: @test_two_casts(
68; CHECK-NOT: lifetime
69; CHECK: llvm.lifetime.start(i64 4
70; CHECK-NOT: lifetime
71; CHECK: llvm.lifetime.end(i64 4
72  call void @helper_two_casts()
73; CHECK-NOT: lifetime
74; CHECK: llvm.lifetime.start(i64 4
75; CHECK-NOT: lifetime
76; CHECK: llvm.lifetime.end(i64 4
77  call void @helper_two_casts()
78; CHECK-NOT: lifetime
79; CHECK: ret void
80  ret void
81}
82
83define void @helper_arrays_alloca() {
84  %a = alloca [10 x i32], align 16
85  %1 = bitcast [10 x i32]* %a to i8*
86  call void @use(i8* %1)
87  ret void
88}
89
90define void @test_arrays_alloca() {
91; CHECK-LABEL: @test_arrays_alloca(
92; CHECK-NOT: lifetime
93; CHECK: llvm.lifetime.start(i64 40,
94; CHECK-NOT: lifetime
95; CHECK: llvm.lifetime.end(i64 40,
96  call void @helper_arrays_alloca()
97; CHECK-NOT: lifetime
98; CHECK: ret void
99  ret void
100}
101