Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / CorrelatedValuePropagation / non-null.ll
blob35d866ed2d92ebfe6a142314192419ba0a820dc0
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s
4 define void @test1(ptr %ptr) {
5 ; CHECK-LABEL: @test1(
6 ; CHECK-NEXT:    [[A:%.*]] = load i8, ptr [[PTR:%.*]], align 1
7 ; CHECK-NEXT:    br label [[BB:%.*]]
8 ; CHECK:       bb:
9 ; CHECK-NEXT:    ret void
11   %A = load i8, ptr %ptr
12   br label %bb
13 bb:
14   icmp ne ptr %ptr, null
15   ret void
18 define void @test1_no_null_opt(ptr %ptr) #0 {
19 ; CHECK-LABEL: @test1_no_null_opt(
20 ; CHECK-NEXT:    [[A:%.*]] = load i8, ptr [[PTR:%.*]], align 1
21 ; CHECK-NEXT:    br label [[BB:%.*]]
22 ; CHECK:       bb:
23 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne ptr [[PTR]], null
24 ; CHECK-NEXT:    ret void
26   %A = load i8, ptr %ptr
27   br label %bb
28 bb:
29   icmp ne ptr %ptr, null
30   ret void
33 define void @test2(ptr %ptr) {
34 ; CHECK-LABEL: @test2(
35 ; CHECK-NEXT:    store i8 0, ptr [[PTR:%.*]], align 1
36 ; CHECK-NEXT:    br label [[BB:%.*]]
37 ; CHECK:       bb:
38 ; CHECK-NEXT:    ret void
40   store i8 0, ptr %ptr
41   br label %bb
42 bb:
43   icmp ne ptr %ptr, null
44   ret void
47 define void @test2_no_null_opt(ptr %ptr) #0 {
48 ; CHECK-LABEL: @test2_no_null_opt(
49 ; CHECK-NEXT:    store i8 0, ptr [[PTR:%.*]], align 1
50 ; CHECK-NEXT:    br label [[BB:%.*]]
51 ; CHECK:       bb:
52 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne ptr [[PTR]], null
53 ; CHECK-NEXT:    ret void
55   store i8 0, ptr %ptr
56   br label %bb
57 bb:
58   icmp ne ptr %ptr, null
59   ret void
62 define void @test3() {
63 ; CHECK-LABEL: @test3(
64 ; CHECK-NEXT:    [[PTR:%.*]] = alloca i8, align 1
65 ; CHECK-NEXT:    br label [[BB:%.*]]
66 ; CHECK:       bb:
67 ; CHECK-NEXT:    ret void
69   %ptr = alloca i8
70   br label %bb
71 bb:
72   icmp ne ptr %ptr, null
73   ret void
76 ;; OK to remove icmp here since ptr is coming from alloca.
78 define void @test3_no_null_opt() #0 {
79 ; CHECK-LABEL: @test3_no_null_opt(
80 ; CHECK-NEXT:    [[PTR:%.*]] = alloca i8, align 1
81 ; CHECK-NEXT:    br label [[BB:%.*]]
82 ; CHECK:       bb:
83 ; CHECK-NEXT:    ret void
85   %ptr = alloca i8
86   br label %bb
87 bb:
88   icmp ne ptr %ptr, null
89   ret void
92 declare void @llvm.memcpy.p0.p0.i32(ptr, ptr, i32, i1)
94 define void @test4(ptr %dest, ptr %src) {
95 ; CHECK-LABEL: @test4(
96 ; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr [[DEST:%.*]], ptr [[SRC:%.*]], i32 1, i1 false)
97 ; CHECK-NEXT:    br label [[BB:%.*]]
98 ; CHECK:       bb:
99 ; CHECK-NEXT:    ret void
101   call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr %src, i32 1, i1 false)
102   br label %bb
104   icmp ne ptr %dest, null
105   icmp ne ptr %src, null
106   ret void
109 define void @test4_no_null_opt(ptr %dest, ptr %src) #0 {
110 ; CHECK-LABEL: @test4_no_null_opt(
111 ; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr [[DEST:%.*]], ptr [[SRC:%.*]], i32 1, i1 false)
112 ; CHECK-NEXT:    br label [[BB:%.*]]
113 ; CHECK:       bb:
114 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne ptr [[DEST]], null
115 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne ptr [[SRC]], null
116 ; CHECK-NEXT:    ret void
118   call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr %src, i32 1, i1 false)
119   br label %bb
121   icmp ne ptr %dest, null
122   icmp ne ptr %src, null
123   ret void
126 declare void @llvm.memmove.p0.p0.i32(ptr, ptr, i32, i1)
127 define void @test5(ptr %dest, ptr %src) {
128 ; CHECK-LABEL: @test5(
129 ; CHECK-NEXT:    call void @llvm.memmove.p0.p0.i32(ptr [[DEST:%.*]], ptr [[SRC:%.*]], i32 1, i1 false)
130 ; CHECK-NEXT:    br label [[BB:%.*]]
131 ; CHECK:       bb:
132 ; CHECK-NEXT:    ret void
134   call void @llvm.memmove.p0.p0.i32(ptr %dest, ptr %src, i32 1, i1 false)
135   br label %bb
137   icmp ne ptr %dest, null
138   icmp ne ptr %src, null
139   ret void
142 define void @test5_no_null_opt(ptr %dest, ptr %src) #0 {
143 ; CHECK-LABEL: @test5_no_null_opt(
144 ; CHECK-NEXT:    call void @llvm.memmove.p0.p0.i32(ptr [[DEST:%.*]], ptr [[SRC:%.*]], i32 1, i1 false)
145 ; CHECK-NEXT:    br label [[BB:%.*]]
146 ; CHECK:       bb:
147 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne ptr [[DEST]], null
148 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne ptr [[SRC]], null
149 ; CHECK-NEXT:    ret void
151   call void @llvm.memmove.p0.p0.i32(ptr %dest, ptr %src, i32 1, i1 false)
152   br label %bb
154   icmp ne ptr %dest, null
155   icmp ne ptr %src, null
156   ret void
159 declare void @llvm.memset.p0.i32(ptr, i8, i32, i1)
160 define void @test6(ptr %dest) {
161 ; CHECK-LABEL: @test6(
162 ; CHECK-NEXT:    call void @llvm.memset.p0.i32(ptr [[DEST:%.*]], i8 -1, i32 1, i1 false)
163 ; CHECK-NEXT:    br label [[BB:%.*]]
164 ; CHECK:       bb:
165 ; CHECK-NEXT:    ret void
167   call void @llvm.memset.p0.i32(ptr %dest, i8 255, i32 1, i1 false)
168   br label %bb
170   icmp ne ptr %dest, null
171   ret void
174 define void @test6_no_null_opt(ptr %dest) #0 {
175 ; CHECK-LABEL: @test6_no_null_opt(
176 ; CHECK-NEXT:    call void @llvm.memset.p0.i32(ptr [[DEST:%.*]], i8 -1, i32 1, i1 false)
177 ; CHECK-NEXT:    br label [[BB:%.*]]
178 ; CHECK:       bb:
179 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne ptr [[DEST]], null
180 ; CHECK-NEXT:    ret void
182   call void @llvm.memset.p0.i32(ptr %dest, i8 255, i32 1, i1 false)
183   br label %bb
185   icmp ne ptr %dest, null
186   ret void
189 define void @test7(ptr %dest, ptr %src, i32 %len) {
190 ; CHECK-LABEL: @test7(
191 ; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr [[DEST:%.*]], ptr [[SRC:%.*]], i32 [[LEN:%.*]], i1 false)
192 ; CHECK-NEXT:    br label [[BB:%.*]]
193 ; CHECK:       bb:
194 ; CHECK-NEXT:    [[KEEP1:%.*]] = icmp ne ptr [[DEST]], null
195 ; CHECK-NEXT:    [[KEEP2:%.*]] = icmp ne ptr [[SRC]], null
196 ; CHECK-NEXT:    ret void
198   call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr %src, i32 %len, i1 false)
199   br label %bb
201   %KEEP1 = icmp ne ptr %dest, null
202   %KEEP2 = icmp ne ptr %src, null
203   ret void
206 declare void @llvm.memcpy.p1.p1.i32(ptr addrspace(1), ptr addrspace(1), i32, i1)
207 define void @test8(ptr addrspace(1) %dest, ptr addrspace(1) %src) {
208 ; CHECK-LABEL: @test8(
209 ; CHECK-NEXT:    call void @llvm.memcpy.p1.p1.i32(ptr addrspace(1) [[DEST:%.*]], ptr addrspace(1) [[SRC:%.*]], i32 1, i1 false)
210 ; CHECK-NEXT:    br label [[BB:%.*]]
211 ; CHECK:       bb:
212 ; CHECK-NEXT:    [[KEEP1:%.*]] = icmp ne ptr addrspace(1) [[DEST]], null
213 ; CHECK-NEXT:    [[KEEP2:%.*]] = icmp ne ptr addrspace(1) [[SRC]], null
214 ; CHECK-NEXT:    ret void
216   call void @llvm.memcpy.p1.p1.i32(ptr addrspace(1) %dest, ptr addrspace(1) %src, i32 1, i1 false)
217   br label %bb
219   %KEEP1 = icmp ne ptr addrspace(1) %dest, null
220   %KEEP2 = icmp ne ptr addrspace(1) %src, null
221   ret void
224 define void @test9(ptr %dest, ptr %src) {
225 ; CHECK-LABEL: @test9(
226 ; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr [[DEST:%.*]], ptr [[SRC:%.*]], i32 1, i1 true)
227 ; CHECK-NEXT:    br label [[BB:%.*]]
228 ; CHECK:       bb:
229 ; CHECK-NEXT:    [[KEEP1:%.*]] = icmp ne ptr [[DEST]], null
230 ; CHECK-NEXT:    [[KEEP2:%.*]] = icmp ne ptr [[SRC]], null
231 ; CHECK-NEXT:    ret void
233   call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr %src, i32 1, i1 true)
234   br label %bb
236   %KEEP1 = icmp ne ptr %dest, null
237   %KEEP2 = icmp ne ptr %src, null
238   ret void
241 declare void @test10_helper(ptr %arg1, ptr %arg2, i32 %non-pointer-arg)
243 define void @test10(ptr %arg1, ptr %arg2, i32 %non-pointer-arg) {
244 ; CHECK-LABEL: @test10(
245 ; CHECK-NEXT:  entry:
246 ; CHECK-NEXT:    [[IS_NULL:%.*]] = icmp eq ptr [[ARG1:%.*]], null
247 ; CHECK-NEXT:    br i1 [[IS_NULL]], label [[NULL:%.*]], label [[NON_NULL:%.*]]
248 ; CHECK:       non_null:
249 ; CHECK-NEXT:    call void @test10_helper(ptr nonnull [[ARG1]], ptr [[ARG2:%.*]], i32 [[NON_POINTER_ARG:%.*]])
250 ; CHECK-NEXT:    br label [[NULL]]
251 ; CHECK:       null:
252 ; CHECK-NEXT:    call void @test10_helper(ptr [[ARG1]], ptr [[ARG2]], i32 [[NON_POINTER_ARG]])
253 ; CHECK-NEXT:    ret void
255 entry:
256   %is_null = icmp eq ptr %arg1, null
257   br i1 %is_null, label %null, label %non_null
259 non_null:
260   call void @test10_helper(ptr %arg1, ptr %arg2, i32 %non-pointer-arg)
261   br label %null
263 null:
264   call void @test10_helper(ptr %arg1, ptr %arg2, i32 %non-pointer-arg)
265   ret void
268 declare void @test11_helper(ptr %arg)
270 define void @test11(ptr %arg1, ptr %arg2) {
271 ; CHECK-LABEL: @test11(
272 ; CHECK-NEXT:  entry:
273 ; CHECK-NEXT:    [[IS_NULL:%.*]] = icmp eq ptr [[ARG1:%.*]], null
274 ; CHECK-NEXT:    br i1 [[IS_NULL]], label [[NULL:%.*]], label [[NON_NULL:%.*]]
275 ; CHECK:       non_null:
276 ; CHECK-NEXT:    br label [[MERGE:%.*]]
277 ; CHECK:       null:
278 ; CHECK-NEXT:    [[ANOTHER_ARG:%.*]] = alloca i8, align 1
279 ; CHECK-NEXT:    br label [[MERGE]]
280 ; CHECK:       merge:
281 ; CHECK-NEXT:    [[MERGED_ARG:%.*]] = phi ptr [ [[ANOTHER_ARG]], [[NULL]] ], [ [[ARG1]], [[NON_NULL]] ]
282 ; CHECK-NEXT:    call void @test11_helper(ptr nonnull [[MERGED_ARG]])
283 ; CHECK-NEXT:    ret void
285 entry:
286   %is_null = icmp eq ptr %arg1, null
287   br i1 %is_null, label %null, label %non_null
289 non_null:
290   br label %merge
292 null:
293   %another_arg = alloca i8
294   br label %merge
296 merge:
297   %merged_arg = phi ptr [%another_arg, %null], [%arg1, %non_null]
298   call void @test11_helper(ptr %merged_arg)
299   ret void
302 declare void @test12_helper(ptr %arg)
304 define void @test12(ptr %arg1, ptr %arg2) {
305 ; CHECK-LABEL: @test12(
306 ; CHECK-NEXT:  entry:
307 ; CHECK-NEXT:    [[IS_NULL:%.*]] = icmp eq ptr [[ARG1:%.*]], null
308 ; CHECK-NEXT:    br i1 [[IS_NULL]], label [[NULL:%.*]], label [[NON_NULL:%.*]]
309 ; CHECK:       non_null:
310 ; CHECK-NEXT:    br label [[MERGE:%.*]]
311 ; CHECK:       null:
312 ; CHECK-NEXT:    [[ANOTHER_ARG:%.*]] = load ptr, ptr [[ARG2:%.*]], align 8, !nonnull !0
313 ; CHECK-NEXT:    br label [[MERGE]]
314 ; CHECK:       merge:
315 ; CHECK-NEXT:    [[MERGED_ARG:%.*]] = phi ptr [ [[ANOTHER_ARG]], [[NULL]] ], [ [[ARG1]], [[NON_NULL]] ]
316 ; CHECK-NEXT:    call void @test12_helper(ptr nonnull [[MERGED_ARG]])
317 ; CHECK-NEXT:    ret void
319 entry:
320   %is_null = icmp eq ptr %arg1, null
321   br i1 %is_null, label %null, label %non_null
323 non_null:
324   br label %merge
326 null:
327   %another_arg = load ptr, ptr %arg2, !nonnull !{}
328   br label %merge
330 merge:
331   %merged_arg = phi ptr [%another_arg, %null], [%arg1, %non_null]
332   call void @test12_helper(ptr %merged_arg)
333   ret void
336 define i1 @test_store_same_block(ptr %arg) {
337 ; CHECK-LABEL: @test_store_same_block(
338 ; CHECK-NEXT:    store i8 0, ptr [[ARG:%.*]], align 1
339 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne ptr [[ARG]], null
340 ; CHECK-NEXT:    ret i1 true
342   store i8 0, ptr %arg
343   %cmp = icmp ne ptr %arg, null
344   ret i1 %cmp
347 attributes #0 = { null_pointer_is_valid }