xref: /llvm-project/llvm/test/Transforms/Inline/lifetime.ll (revision 650041a7f1852e95c3543c9852ab63f75165b223)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2; RUN: opt -passes=inline -S < %s | FileCheck %s
3target 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"
4
5declare void @llvm.lifetime.start.p0(i64, ptr)
6declare void @llvm.lifetime.end.p0(i64, ptr)
7
8define void @helper_both_markers() {
9; CHECK-LABEL: define void @helper_both_markers() {
10; CHECK-NEXT:    [[A:%.*]] = alloca i8, align 1
11; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 2, ptr [[A]])
12; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 2, ptr [[A]])
13; CHECK-NEXT:    ret void
14;
15  %a = alloca i8
16  ; Size in llvm.lifetime.start / llvm.lifetime.end differs from
17  ; allocation size. We should use the former.
18  call void @llvm.lifetime.start.p0(i64 2, ptr %a)
19  call void @llvm.lifetime.end.p0(i64 2, ptr %a)
20  ret void
21}
22
23define void @test_both_markers() {
24; CHECK-LABEL: define void @test_both_markers() {
25; CHECK-NEXT:    [[A_I1:%.*]] = alloca i8, align 1
26; CHECK-NEXT:    [[A_I:%.*]] = alloca i8, align 1
27; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 2, ptr [[A_I]])
28; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 2, ptr [[A_I]])
29; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 2, ptr [[A_I1]])
30; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 2, ptr [[A_I1]])
31; CHECK-NEXT:    ret void
32;
33  call void @helper_both_markers()
34  call void @helper_both_markers()
35  ret void
36}
37
38;; Without this, the inliner will simplify out @test_no_marker before adding
39;; any lifetime markers.
40declare void @use(ptr %a)
41
42define void @helper_no_markers() {
43; CHECK-LABEL: define void @helper_no_markers() {
44; CHECK-NEXT:    [[A:%.*]] = alloca i8, align 1
45; CHECK-NEXT:    call void @use(ptr [[A]])
46; CHECK-NEXT:    ret void
47;
48  %a = alloca i8 ; Allocation size is 1 byte.
49  call void @use(ptr %a)
50  ret void
51}
52
53define void @test_no_marker() {
54; CHECK-LABEL: define void @test_no_marker() {
55; CHECK-NEXT:    [[A_I1:%.*]] = alloca i8, align 1
56; CHECK-NEXT:    [[A_I:%.*]] = alloca i8, align 1
57; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 1, ptr [[A_I]])
58; CHECK-NEXT:    call void @use(ptr [[A_I]])
59; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 1, ptr [[A_I]])
60; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 1, ptr [[A_I1]])
61; CHECK-NEXT:    call void @use(ptr [[A_I1]])
62; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 1, ptr [[A_I1]])
63; CHECK-NEXT:    ret void
64;
65  call void @helper_no_markers()
66  call void @helper_no_markers()
67  ret void
68}
69
70define void @helper_two_casts() {
71; CHECK-LABEL: define void @helper_two_casts() {
72; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
73; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr [[A]])
74; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr [[A]])
75; CHECK-NEXT:    ret void
76;
77  %a = alloca i32
78  call void @llvm.lifetime.start.p0(i64 4, ptr %a)
79  call void @llvm.lifetime.end.p0(i64 4, ptr %a)
80  ret void
81}
82
83define void @test_two_casts() {
84; CHECK-LABEL: define void @test_two_casts() {
85; CHECK-NEXT:    [[A_I1:%.*]] = alloca i32, align 4
86; CHECK-NEXT:    [[A_I:%.*]] = alloca i32, align 4
87; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr [[A_I]])
88; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr [[A_I]])
89; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr [[A_I1]])
90; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr [[A_I1]])
91; CHECK-NEXT:    ret void
92;
93  call void @helper_two_casts()
94  call void @helper_two_casts()
95  ret void
96}
97
98define void @helper_arrays_alloca() {
99; CHECK-LABEL: define void @helper_arrays_alloca() {
100; CHECK-NEXT:    [[A:%.*]] = alloca [10 x i32], align 16
101; CHECK-NEXT:    call void @use(ptr [[A]])
102; CHECK-NEXT:    ret void
103;
104  %a = alloca [10 x i32], align 16
105  call void @use(ptr %a)
106  ret void
107}
108
109define void @test_arrays_alloca() {
110; CHECK-LABEL: define void @test_arrays_alloca() {
111; CHECK-NEXT:    [[A_I:%.*]] = alloca [10 x i32], align 16
112; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 40, ptr [[A_I]])
113; CHECK-NEXT:    call void @use(ptr [[A_I]])
114; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 40, ptr [[A_I]])
115; CHECK-NEXT:    ret void
116;
117  call void @helper_arrays_alloca()
118  ret void
119}
120
121%swift.error = type opaque
122
123define void @helper_swifterror_alloca() {
124; CHECK-LABEL: define void @helper_swifterror_alloca() {
125; CHECK-NEXT:  entry:
126; CHECK-NEXT:    [[SWIFTERROR:%.*]] = alloca swifterror ptr, align 8
127; CHECK-NEXT:    store ptr null, ptr [[SWIFTERROR]], align 8
128; CHECK-NEXT:    ret void
129;
130entry:
131  %swifterror = alloca swifterror ptr, align 8
132  store ptr null, ptr %swifterror, align 8
133  ret void
134}
135
136define void @test_swifterror_alloca() {
137; CHECK-LABEL: define void @test_swifterror_alloca() {
138; CHECK-NEXT:    [[SWIFTERROR_I:%.*]] = alloca swifterror ptr, align 8
139; CHECK-NEXT:    store ptr null, ptr [[SWIFTERROR_I]], align 8
140; CHECK-NEXT:    ret void
141;
142  call void @helper_swifterror_alloca()
143  ret void
144}
145