[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Transforms / DeadStoreElimination / multiblock-memintrinsics.ll
blobfe5087646184c71e3ccefbca4a061cf56be2bbbd
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -basic-aa -dse -S | FileCheck %s
4 target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
5 declare void @unknown_func()
6 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
7 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
9 ; Tests where the pointer/object is accessible after the function returns.
11 ; Overwriting store along one path to the exit.
12 define void @accessible_after_return_1(i32* noalias %P, i1 %c) {
13 ; CHECK-LABEL: @accessible_after_return_1(
14 ; CHECK-NEXT:  entry:
15 ; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
16 ; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
17 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 28, i1 false)
18 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
19 ; CHECK:       bb1:
20 ; CHECK-NEXT:    br label [[BB3:%.*]]
21 ; CHECK:       bb2:
22 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
23 ; CHECK-NEXT:    store i32 1, i32* [[ARRAYIDX1]], align 4
24 ; CHECK-NEXT:    br label [[BB3]]
25 ; CHECK:       bb3:
26 ; CHECK-NEXT:    ret void
28 entry:
29   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
30   %p3 = bitcast i32* %arrayidx0 to i8*
31   call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
32   br i1 %c, label %bb1, label %bb2
33 bb1:
34   br label %bb3
35 bb2:
36   %arrayidx1 = getelementptr inbounds i32, i32* %P, i64 1
37   store i32 1, i32* %arrayidx1, align 4
38   br label %bb3
39 bb3:
40   ret void
43 ; Post-dominating store.
44 ; TODO: The memset can be shortened.
45 define void @accessible_after_return_2(i32* noalias %P, i1 %c) {
46 ; CHECK-LABEL: @accessible_after_return_2(
47 ; CHECK-NEXT:  entry:
48 ; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
49 ; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
50 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 28, i1 false)
51 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
52 ; CHECK:       bb1:
53 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
54 ; CHECK-NEXT:    store i32 1, i32* [[ARRAYIDX1]], align 4
55 ; CHECK-NEXT:    br label [[BB3:%.*]]
56 ; CHECK:       bb2:
57 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
58 ; CHECK-NEXT:    store i32 1, i32* [[ARRAYIDX2]], align 4
59 ; CHECK-NEXT:    br label [[BB3]]
60 ; CHECK:       bb3:
61 ; CHECK-NEXT:    ret void
63 entry:
64   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
65   %p3 = bitcast i32* %arrayidx0 to i8*
66   call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
67   br i1 %c, label %bb1, label %bb2
69 bb1:
70   %arrayidx1 = getelementptr inbounds i32, i32* %P, i64 1
71   store i32 1, i32* %arrayidx1, align 4
72   br label %bb3
74 bb2:
75   %arrayidx2 = getelementptr inbounds i32, i32* %P, i64 1
76   store i32 1, i32* %arrayidx2, align 4
77   br label %bb3
79 bb3:
80   ret void
83 ; Stores along  both exit paths.
84 define void @accessible_after_return_3(i32* noalias %P, i1 %c) {
85 ; CHECK-LABEL: @accessible_after_return_3(
86 ; CHECK-NEXT:  entry:
87 ; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
88 ; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
89 ; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
90 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i1 false)
91 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
92 ; CHECK:       bb1:
93 ; CHECK-NEXT:    br label [[BB3:%.*]]
94 ; CHECK:       bb2:
95 ; CHECK-NEXT:    br label [[BB3]]
96 ; CHECK:       bb3:
97 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
98 ; CHECK-NEXT:    store i32 1, i32* [[ARRAYIDX1]], align 4
99 ; CHECK-NEXT:    ret void
101 entry:
102   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
103   %p3 = bitcast i32* %arrayidx0 to i8*
104   call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
105   br i1 %c, label %bb1, label %bb2
107 bb1:
108   br label %bb3
110 bb2:
111   br label %bb3
113 bb3:
114   %arrayidx1 = getelementptr inbounds i32, i32* %P, i64 1
115   store i32 1, i32* %arrayidx1, align 4
116   ret void
120 ; Tests where the pointer/object is *NOT* accessible after the function returns.
122 ; Overwriting store along one path to the exit.
123 define void @alloca_1(i1 %c) {
124 ; CHECK-LABEL: @alloca_1(
125 ; CHECK-NEXT:  entry:
126 ; CHECK-NEXT:    [[P_ALLOCA:%.*]] = alloca [32 x i32], align 4
127 ; CHECK-NEXT:    [[P:%.*]] = bitcast [32 x i32]* [[P_ALLOCA]] to i32*
128 ; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
129 ; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
130 ; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
131 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i1 false)
132 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
133 ; CHECK:       bb1:
134 ; CHECK-NEXT:    br label [[BB3:%.*]]
135 ; CHECK:       bb2:
136 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
137 ; CHECK-NEXT:    store i32 1, i32* [[ARRAYIDX1]], align 4
138 ; CHECK-NEXT:    br label [[BB3]]
139 ; CHECK:       bb3:
140 ; CHECK-NEXT:    ret void
142 entry:
143   %P.alloca = alloca [32 x i32]
144   %P = bitcast [32 x i32]* %P.alloca to i32*
145   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
146   %p3 = bitcast i32* %arrayidx0 to i8*
147   call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
148   br i1 %c, label %bb1, label %bb2
149 bb1:
150   br label %bb3
151 bb2:
152   %arrayidx1 = getelementptr inbounds i32, i32* %P, i64 1
153   store i32 1, i32* %arrayidx1, align 4
154   br label %bb3
155 bb3:
156   ret void
159 ; Post-dominating store.
160 define void @alloca_2(i1 %c) {
161 ; CHECK-LABEL: @alloca_2(
162 ; CHECK-NEXT:  entry:
163 ; CHECK-NEXT:    [[P_ALLOCA:%.*]] = alloca [32 x i32], align 4
164 ; CHECK-NEXT:    [[P:%.*]] = bitcast [32 x i32]* [[P_ALLOCA]] to i32*
165 ; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
166 ; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
167 ; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
168 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i1 false)
169 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
170 ; CHECK:       bb1:
171 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
172 ; CHECK-NEXT:    store i32 1, i32* [[ARRAYIDX1]], align 4
173 ; CHECK-NEXT:    br label [[BB3:%.*]]
174 ; CHECK:       bb2:
175 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
176 ; CHECK-NEXT:    store i32 1, i32* [[ARRAYIDX2]], align 4
177 ; CHECK-NEXT:    br label [[BB3]]
178 ; CHECK:       bb3:
179 ; CHECK-NEXT:    ret void
181 entry:
182   %P.alloca = alloca [32 x i32]
183   %P = bitcast [32 x i32]* %P.alloca to i32*
184   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
185   %p3 = bitcast i32* %arrayidx0 to i8*
186   call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
187   br i1 %c, label %bb1, label %bb2
189 bb1:
190   %arrayidx1 = getelementptr inbounds i32, i32* %P, i64 1
191   store i32 1, i32* %arrayidx1, align 4
192   br label %bb3
194 bb2:
195   %arrayidx2 = getelementptr inbounds i32, i32* %P, i64 1
196   store i32 1, i32* %arrayidx2, align 4
197   br label %bb3
199 bb3:
200   ret void
203 ; Stores along  both exit paths.
204 define void @alloca_3(i1 %c) {
205 ; CHECK-LABEL: @alloca_3(
206 ; CHECK-NEXT:  entry:
207 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
208 ; CHECK:       bb1:
209 ; CHECK-NEXT:    br label [[BB3:%.*]]
210 ; CHECK:       bb2:
211 ; CHECK-NEXT:    br label [[BB3]]
212 ; CHECK:       bb3:
213 ; CHECK-NEXT:    ret void
215 entry:
216   %P.alloca = alloca [32 x i32]
217   %P = bitcast [32 x i32]* %P.alloca to i32*
218   %arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
219   %p3 = bitcast i32* %arrayidx0 to i8*
220   call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
221   br i1 %c, label %bb1, label %bb2
223 bb1:
224   br label %bb3
226 bb2:
227   br label %bb3
229 bb3:
230   %arrayidx1 = getelementptr inbounds i32, i32* %P, i64 1
231   store i32 1, i32* %arrayidx1, align 4
232   ret void