[rtsan] Add fork/execve interceptors (#117198)
[llvm-project.git] / llvm / test / Transforms / DeadStoreElimination / lifetime.ll
blob73b9903a75fb08f301c7ff4db5ab5cddba82dd3f
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=dse < %s | FileCheck %s
4 target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
6 declare void @llvm.lifetime.start.p0(i64, ptr nocapture) nounwind
7 declare void @llvm.lifetime.end.p0(i64, ptr nocapture) nounwind
8 declare void @llvm.memset.p0.i8(ptr nocapture, i8, i8, i1) nounwind
10 define void @test1() {
11 ; CHECK-LABEL: @test1(
12 ; CHECK-NEXT:    [[A:%.*]] = alloca i8, align 1
13 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 1, ptr [[A]])
14 ; CHECK-NEXT:    ret void
16   %A = alloca i8
18   store i8 0, ptr %A  ;; Written to by memset
19   call void @llvm.lifetime.end.p0(i64 1, ptr %A)
21   call void @llvm.memset.p0.i8(ptr %A, i8 0, i8 -1, i1 false)
23   ret void
26 define void @test2(ptr %P) {
27 ; CHECK-LABEL: @test2(
28 ; CHECK-NEXT:    [[Q:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1
29 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr [[Q]])
30 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr [[Q]])
31 ; CHECK-NEXT:    ret void
33   %Q = getelementptr i32, ptr %P, i32 1
34   call void @llvm.lifetime.start.p0(i64 4, ptr %Q)
35   store i32 0, ptr %Q  ;; This store is dead.
36   call void @llvm.lifetime.end.p0(i64 4, ptr %Q)
37   ret void
40 ; lifetime.end only marks the first two bytes of %A as dead. Make sure
41 ; `store i8 20, ptr %A.2 is not removed.
42 define void @test3_lifetime_end_partial() {
43 ; CHECK-LABEL: @test3_lifetime_end_partial(
44 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
45 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 2, ptr [[A]])
46 ; CHECK-NEXT:    [[A_1:%.*]] = getelementptr i8, ptr [[A]], i64 1
47 ; CHECK-NEXT:    [[A_2:%.*]] = getelementptr i8, ptr [[A]], i64 2
48 ; CHECK-NEXT:    store i8 20, ptr [[A_2]], align 1
49 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 2, ptr [[A]])
50 ; CHECK-NEXT:    call void @use(ptr [[A_1]])
51 ; CHECK-NEXT:    ret void
53   %A = alloca i32
55   call void @llvm.lifetime.start.p0(i64 2, ptr %A)
56   %A.1 = getelementptr i8, ptr %A, i64 1
57   %A.2 = getelementptr i8, ptr %A, i64 2
59   store i8 0, ptr %A
60   store i8 10, ptr %A.1
61   store i8 20, ptr %A.2
63   call void @llvm.lifetime.end.p0(i64 2, ptr %A)
64   call void @use(ptr %A.1)
65   ret void
68 ; lifetime.end only marks the first two bytes of %A as dead. Make sure
69 ; `store i8 20, ptr %A.2 is not removed.
70 define void @test4_lifetime_end_partial_loop() {
71 ; CHECK-LABEL: @test4_lifetime_end_partial_loop(
72 ; CHECK-NEXT:  entry:
73 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
74 ; CHECK-NEXT:    br label [[LOOP:%.*]]
75 ; CHECK:       loop:
76 ; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
77 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 2, ptr [[A]])
78 ; CHECK-NEXT:    [[A_1:%.*]] = getelementptr i8, ptr [[A]], i64 1
79 ; CHECK-NEXT:    [[A_2:%.*]] = getelementptr i8, ptr [[A]], i64 2
80 ; CHECK-NEXT:    call void @use(ptr [[A_1]])
81 ; CHECK-NEXT:    store i8 20, ptr [[A_2]], align 1
82 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 2, ptr [[A]])
83 ; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 10
84 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i8 [[IV_NEXT]], 10
85 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[EXIT:%.*]], label [[LOOP]]
86 ; CHECK:       exit:
87 ; CHECK-NEXT:    ret void
89 entry:
90   %A = alloca i32
92   br label %loop
94 loop:
95   %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
96   call void @llvm.lifetime.start.p0(i64 2, ptr %A)
97   %A.1 = getelementptr i8, ptr %A, i64 1
98   %A.2 = getelementptr i8, ptr %A, i64 2
100   call void @use(ptr %A.1)
102   store i8 20, ptr %A.2
103   store i8 10, ptr %A.1
104   store i8 0, ptr %A
105   call void @llvm.lifetime.end.p0(i64 2, ptr %A)
107   %iv.next = add i8 %iv, 10
108   %exitcond = icmp eq i8 %iv.next, 10
109   br i1 %exitcond, label %exit, label %loop
111 exit:
112   ret void
115 ; lifetime.end only marks the first two bytes of %A as dead. Make sure
116 ; `store i8 20, ptr %A.2 is not removed.
117 define void @test5_lifetime_end_partial(ptr %A) {
118 ; CHECK-LABEL: @test5_lifetime_end_partial(
119 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 2, ptr [[A:%.*]])
120 ; CHECK-NEXT:    [[A_1:%.*]] = getelementptr i8, ptr [[A]], i64 1
121 ; CHECK-NEXT:    [[A_2:%.*]] = getelementptr i8, ptr [[A]], i64 2
122 ; CHECK-NEXT:    store i8 20, ptr [[A_2]], align 1
123 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 2, ptr [[A]])
124 ; CHECK-NEXT:    call void @use(ptr [[A_1]])
125 ; CHECK-NEXT:    store i8 30, ptr [[A_1]], align 1
126 ; CHECK-NEXT:    store i8 40, ptr [[A_2]], align 1
127 ; CHECK-NEXT:    ret void
130   call void @llvm.lifetime.start.p0(i64 2, ptr %A)
131   %A.1 = getelementptr i8, ptr %A, i64 1
132   %A.2 = getelementptr i8, ptr %A, i64 2
134   store i8 0, ptr %A
135   store i8 10, ptr %A.1
136   store i8 20, ptr %A.2
138   call void @llvm.lifetime.end.p0(i64 2, ptr %A)
140   call void @use(ptr %A.1)
141   store i8 30, ptr %A.1
142   store i8 40, ptr %A.2
143   ret void
146 declare void @use(ptr) readonly