[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / Transforms / CorrelatedValuePropagation / non-null.ll
blobd86031d312fbfe78a81dff06b835f90aa131a1e9
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -correlated-propagation -S | FileCheck %s
4 define void @test1(i8* %ptr) {
5 ; CHECK-LABEL: @test1(
6 ; CHECK-NEXT:    [[A:%.*]] = load i8, i8* [[PTR:%.*]]
7 ; CHECK-NEXT:    br label [[BB:%.*]]
8 ; CHECK:       bb:
9 ; CHECK-NEXT:    ret void
11   %A = load i8, i8* %ptr
12   br label %bb
13 bb:
14   icmp ne i8* %ptr, null
15   ret void
18 define void @test1_no_null_opt(i8* %ptr) #0 {
19 ; CHECK-LABEL: @test1_no_null_opt(
20 ; CHECK-NEXT:    [[A:%.*]] = load i8, i8* [[PTR:%.*]]
21 ; CHECK-NEXT:    br label [[BB:%.*]]
22 ; CHECK:       bb:
23 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i8* [[PTR]], null
24 ; CHECK-NEXT:    ret void
26   %A = load i8, i8* %ptr
27   br label %bb
28 bb:
29   icmp ne i8* %ptr, null
30   ret void
33 define void @test2(i8* %ptr) {
34 ; CHECK-LABEL: @test2(
35 ; CHECK-NEXT:    store i8 0, i8* [[PTR:%.*]]
36 ; CHECK-NEXT:    br label [[BB:%.*]]
37 ; CHECK:       bb:
38 ; CHECK-NEXT:    ret void
40   store i8 0, i8* %ptr
41   br label %bb
42 bb:
43   icmp ne i8* %ptr, null
44   ret void
47 define void @test2_no_null_opt(i8* %ptr) #0 {
48 ; CHECK-LABEL: @test2_no_null_opt(
49 ; CHECK-NEXT:    store i8 0, i8* [[PTR:%.*]]
50 ; CHECK-NEXT:    br label [[BB:%.*]]
51 ; CHECK:       bb:
52 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i8* [[PTR]], null
53 ; CHECK-NEXT:    ret void
55   store i8 0, i8* %ptr
56   br label %bb
57 bb:
58   icmp ne i8* %ptr, null
59   ret void
62 define void @test3() {
63 ; CHECK-LABEL: @test3(
64 ; CHECK-NEXT:    [[PTR:%.*]] = alloca i8
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 i8* %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
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 i8* %ptr, null
89   ret void
92 declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i1)
94 define void @test4(i8* %dest, i8* %src) {
95 ; CHECK-LABEL: @test4(
96 ; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[DEST:%.*]], i8* [[SRC:%.*]], i32 1, i1 false)
97 ; CHECK-NEXT:    br label [[BB:%.*]]
98 ; CHECK:       bb:
99 ; CHECK-NEXT:    ret void
101   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 1, i1 false)
102   br label %bb
104   icmp ne i8* %dest, null
105   icmp ne i8* %src, null
106   ret void
109 define void @test4_no_null_opt(i8* %dest, i8* %src) #0 {
110 ; CHECK-LABEL: @test4_no_null_opt(
111 ; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[DEST:%.*]], i8* [[SRC:%.*]], i32 1, i1 false)
112 ; CHECK-NEXT:    br label [[BB:%.*]]
113 ; CHECK:       bb:
114 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i8* [[DEST]], null
115 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8* [[SRC]], null
116 ; CHECK-NEXT:    ret void
118   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 1, i1 false)
119   br label %bb
121   icmp ne i8* %dest, null
122   icmp ne i8* %src, null
123   ret void
126 declare void @llvm.memmove.p0i8.p0i8.i32(i8*, i8*, i32, i1)
127 define void @test5(i8* %dest, i8* %src) {
128 ; CHECK-LABEL: @test5(
129 ; CHECK-NEXT:    call void @llvm.memmove.p0i8.p0i8.i32(i8* [[DEST:%.*]], i8* [[SRC:%.*]], i32 1, i1 false)
130 ; CHECK-NEXT:    br label [[BB:%.*]]
131 ; CHECK:       bb:
132 ; CHECK-NEXT:    ret void
134   call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 1, i1 false)
135   br label %bb
137   icmp ne i8* %dest, null
138   icmp ne i8* %src, null
139   ret void
142 define void @test5_no_null_opt(i8* %dest, i8* %src) #0 {
143 ; CHECK-LABEL: @test5_no_null_opt(
144 ; CHECK-NEXT:    call void @llvm.memmove.p0i8.p0i8.i32(i8* [[DEST:%.*]], i8* [[SRC:%.*]], i32 1, i1 false)
145 ; CHECK-NEXT:    br label [[BB:%.*]]
146 ; CHECK:       bb:
147 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i8* [[DEST]], null
148 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8* [[SRC]], null
149 ; CHECK-NEXT:    ret void
151   call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 1, i1 false)
152   br label %bb
154   icmp ne i8* %dest, null
155   icmp ne i8* %src, null
156   ret void
159 declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i1)
160 define void @test6(i8* %dest) {
161 ; CHECK-LABEL: @test6(
162 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i32(i8* [[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.p0i8.i32(i8* %dest, i8 255, i32 1, i1 false)
168   br label %bb
170   icmp ne i8* %dest, null
171   ret void
174 define void @test6_no_null_opt(i8* %dest) #0 {
175 ; CHECK-LABEL: @test6_no_null_opt(
176 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i32(i8* [[DEST:%.*]], i8 -1, i32 1, i1 false)
177 ; CHECK-NEXT:    br label [[BB:%.*]]
178 ; CHECK:       bb:
179 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i8* [[DEST]], null
180 ; CHECK-NEXT:    ret void
182   call void @llvm.memset.p0i8.i32(i8* %dest, i8 255, i32 1, i1 false)
183   br label %bb
185   icmp ne i8* %dest, null
186   ret void
189 define void @test7(i8* %dest, i8* %src, i32 %len) {
190 ; CHECK-LABEL: @test7(
191 ; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[DEST:%.*]], i8* [[SRC:%.*]], i32 [[LEN:%.*]], i1 false)
192 ; CHECK-NEXT:    br label [[BB:%.*]]
193 ; CHECK:       bb:
194 ; CHECK-NEXT:    [[KEEP1:%.*]] = icmp ne i8* [[DEST]], null
195 ; CHECK-NEXT:    [[KEEP2:%.*]] = icmp ne i8* [[SRC]], null
196 ; CHECK-NEXT:    ret void
198   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 false)
199   br label %bb
201   %KEEP1 = icmp ne i8* %dest, null
202   %KEEP2 = icmp ne i8* %src, null
203   ret void
206 declare void @llvm.memcpy.p1i8.p1i8.i32(i8 addrspace(1) *, i8 addrspace(1) *, i32, i1)
207 define void @test8(i8 addrspace(1) * %dest, i8 addrspace(1) * %src) {
208 ; CHECK-LABEL: @test8(
209 ; CHECK-NEXT:    call void @llvm.memcpy.p1i8.p1i8.i32(i8 addrspace(1)* [[DEST:%.*]], i8 addrspace(1)* [[SRC:%.*]], i32 1, i1 false)
210 ; CHECK-NEXT:    br label [[BB:%.*]]
211 ; CHECK:       bb:
212 ; CHECK-NEXT:    [[KEEP1:%.*]] = icmp ne i8 addrspace(1)* [[DEST]], null
213 ; CHECK-NEXT:    [[KEEP2:%.*]] = icmp ne i8 addrspace(1)* [[SRC]], null
214 ; CHECK-NEXT:    ret void
216   call void @llvm.memcpy.p1i8.p1i8.i32(i8 addrspace(1) * %dest, i8 addrspace(1) * %src, i32 1, i1 false)
217   br label %bb
219   %KEEP1 = icmp ne i8 addrspace(1) * %dest, null
220   %KEEP2 = icmp ne i8 addrspace(1) * %src, null
221   ret void
224 define void @test9(i8* %dest, i8* %src) {
225 ; CHECK-LABEL: @test9(
226 ; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[DEST:%.*]], i8* [[SRC:%.*]], i32 1, i1 true)
227 ; CHECK-NEXT:    br label [[BB:%.*]]
228 ; CHECK:       bb:
229 ; CHECK-NEXT:    [[KEEP1:%.*]] = icmp ne i8* [[DEST]], null
230 ; CHECK-NEXT:    [[KEEP2:%.*]] = icmp ne i8* [[SRC]], null
231 ; CHECK-NEXT:    ret void
233   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 1, i1 true)
234   br label %bb
236   %KEEP1 = icmp ne i8* %dest, null
237   %KEEP2 = icmp ne i8* %src, null
238   ret void
241 declare void @test10_helper(i8* %arg1, i8* %arg2, i32 %non-pointer-arg)
243 define void @test10(i8* %arg1, i8* %arg2, i32 %non-pointer-arg) {
244 ; CHECK-LABEL: @test10(
245 ; CHECK-NEXT:  entry:
246 ; CHECK-NEXT:    [[IS_NULL:%.*]] = icmp eq i8* [[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(i8* nonnull [[ARG1]], i8* [[ARG2:%.*]], i32 [[NON_POINTER_ARG:%.*]])
250 ; CHECK-NEXT:    br label [[NULL]]
251 ; CHECK:       null:
252 ; CHECK-NEXT:    call void @test10_helper(i8* [[ARG1]], i8* [[ARG2]], i32 [[NON_POINTER_ARG]])
253 ; CHECK-NEXT:    ret void
255 entry:
256   %is_null = icmp eq i8* %arg1, null
257   br i1 %is_null, label %null, label %non_null
259 non_null:
260   call void @test10_helper(i8* %arg1, i8* %arg2, i32 %non-pointer-arg)
261   br label %null
263 null:
264   call void @test10_helper(i8* %arg1, i8* %arg2, i32 %non-pointer-arg)
265   ret void
268 declare void @test11_helper(i8* %arg)
270 define void @test11(i8* %arg1, i8** %arg2) {
271 ; CHECK-LABEL: @test11(
272 ; CHECK-NEXT:  entry:
273 ; CHECK-NEXT:    [[IS_NULL:%.*]] = icmp eq i8* [[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
279 ; CHECK-NEXT:    br label [[MERGE]]
280 ; CHECK:       merge:
281 ; CHECK-NEXT:    [[MERGED_ARG:%.*]] = phi i8* [ [[ANOTHER_ARG]], [[NULL]] ], [ [[ARG1]], [[NON_NULL]] ]
282 ; CHECK-NEXT:    call void @test11_helper(i8* nonnull [[MERGED_ARG]])
283 ; CHECK-NEXT:    ret void
285 entry:
286   %is_null = icmp eq i8* %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 i8* [%another_arg, %null], [%arg1, %non_null]
298   call void @test11_helper(i8* %merged_arg)
299   ret void
302 declare void @test12_helper(i8* %arg)
304 define void @test12(i8* %arg1, i8** %arg2) {
305 ; CHECK-LABEL: @test12(
306 ; CHECK-NEXT:  entry:
307 ; CHECK-NEXT:    [[IS_NULL:%.*]] = icmp eq i8* [[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 i8*, i8** [[ARG2:%.*]], !nonnull !0
313 ; CHECK-NEXT:    br label [[MERGE]]
314 ; CHECK:       merge:
315 ; CHECK-NEXT:    [[MERGED_ARG:%.*]] = phi i8* [ [[ANOTHER_ARG]], [[NULL]] ], [ [[ARG1]], [[NON_NULL]] ]
316 ; CHECK-NEXT:    call void @test12_helper(i8* nonnull [[MERGED_ARG]])
317 ; CHECK-NEXT:    ret void
319 entry:
320   %is_null = icmp eq i8* %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 i8*, i8** %arg2, !nonnull !{}
328   br label %merge
330 merge:
331   %merged_arg = phi i8* [%another_arg, %null], [%arg1, %non_null]
332   call void @test12_helper(i8* %merged_arg)
333   ret void
336 attributes #0 = { "null-pointer-is-valid"="true" }