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) {
6 ; CHECK-NEXT: [[A:%.*]] = load i8, i8* [[PTR:%.*]]
7 ; CHECK-NEXT: br label [[BB:%.*]]
11 %A = load i8, i8* %ptr
14 icmp ne i8* %ptr, null
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:%.*]]
23 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8* [[PTR]], null
24 ; CHECK-NEXT: ret void
26 %A = load i8, i8* %ptr
29 icmp ne i8* %ptr, null
33 define void @test2(i8* %ptr) {
34 ; CHECK-LABEL: @test2(
35 ; CHECK-NEXT: store i8 0, i8* [[PTR:%.*]]
36 ; CHECK-NEXT: br label [[BB:%.*]]
38 ; CHECK-NEXT: ret void
43 icmp ne i8* %ptr, null
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:%.*]]
52 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8* [[PTR]], null
53 ; CHECK-NEXT: ret void
58 icmp ne i8* %ptr, null
62 define void @test3() {
63 ; CHECK-LABEL: @test3(
64 ; CHECK-NEXT: [[PTR:%.*]] = alloca i8
65 ; CHECK-NEXT: br label [[BB:%.*]]
67 ; CHECK-NEXT: ret void
72 icmp ne i8* %ptr, null
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:%.*]]
83 ; CHECK-NEXT: ret void
88 icmp ne i8* %ptr, null
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:%.*]]
99 ; CHECK-NEXT: ret void
101 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 1, i1 false)
104 icmp ne i8* %dest, null
105 icmp ne i8* %src, null
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:%.*]]
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)
121 icmp ne i8* %dest, null
122 icmp ne i8* %src, null
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:%.*]]
132 ; CHECK-NEXT: ret void
134 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 1, i1 false)
137 icmp ne i8* %dest, null
138 icmp ne i8* %src, null
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:%.*]]
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)
154 icmp ne i8* %dest, null
155 icmp ne i8* %src, null
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:%.*]]
165 ; CHECK-NEXT: ret void
167 call void @llvm.memset.p0i8.i32(i8* %dest, i8 255, i32 1, i1 false)
170 icmp ne i8* %dest, null
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:%.*]]
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)
185 icmp ne i8* %dest, null
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:%.*]]
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)
201 %KEEP1 = icmp ne i8* %dest, null
202 %KEEP2 = icmp ne i8* %src, null
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:%.*]]
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)
219 %KEEP1 = icmp ne i8 addrspace(1) * %dest, null
220 %KEEP2 = icmp ne i8 addrspace(1) * %src, null
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:%.*]]
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)
236 %KEEP1 = icmp ne i8* %dest, null
237 %KEEP2 = icmp ne i8* %src, null
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(
246 ; CHECK-NEXT: [[IS_NULL:%.*]] = icmp eq i8* [[ARG1:%.*]], null
247 ; CHECK-NEXT: br i1 [[IS_NULL]], label [[NULL:%.*]], label [[NON_NULL:%.*]]
249 ; CHECK-NEXT: call void @test10_helper(i8* nonnull [[ARG1]], i8* [[ARG2:%.*]], i32 [[NON_POINTER_ARG:%.*]])
250 ; CHECK-NEXT: br label [[NULL]]
252 ; CHECK-NEXT: call void @test10_helper(i8* [[ARG1]], i8* [[ARG2]], i32 [[NON_POINTER_ARG]])
253 ; CHECK-NEXT: ret void
256 %is_null = icmp eq i8* %arg1, null
257 br i1 %is_null, label %null, label %non_null
260 call void @test10_helper(i8* %arg1, i8* %arg2, i32 %non-pointer-arg)
264 call void @test10_helper(i8* %arg1, i8* %arg2, i32 %non-pointer-arg)
268 declare void @test11_helper(i8* %arg)
270 define void @test11(i8* %arg1, i8** %arg2) {
271 ; CHECK-LABEL: @test11(
273 ; CHECK-NEXT: [[IS_NULL:%.*]] = icmp eq i8* [[ARG1:%.*]], null
274 ; CHECK-NEXT: br i1 [[IS_NULL]], label [[NULL:%.*]], label [[NON_NULL:%.*]]
276 ; CHECK-NEXT: br label [[MERGE:%.*]]
278 ; CHECK-NEXT: [[ANOTHER_ARG:%.*]] = alloca i8
279 ; CHECK-NEXT: br label [[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
286 %is_null = icmp eq i8* %arg1, null
287 br i1 %is_null, label %null, label %non_null
293 %another_arg = alloca i8
297 %merged_arg = phi i8* [%another_arg, %null], [%arg1, %non_null]
298 call void @test11_helper(i8* %merged_arg)
302 declare void @test12_helper(i8* %arg)
304 define void @test12(i8* %arg1, i8** %arg2) {
305 ; CHECK-LABEL: @test12(
307 ; CHECK-NEXT: [[IS_NULL:%.*]] = icmp eq i8* [[ARG1:%.*]], null
308 ; CHECK-NEXT: br i1 [[IS_NULL]], label [[NULL:%.*]], label [[NON_NULL:%.*]]
310 ; CHECK-NEXT: br label [[MERGE:%.*]]
312 ; CHECK-NEXT: [[ANOTHER_ARG:%.*]] = load i8*, i8** [[ARG2:%.*]], !nonnull !0
313 ; CHECK-NEXT: br label [[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
320 %is_null = icmp eq i8* %arg1, null
321 br i1 %is_null, label %null, label %non_null
327 %another_arg = load i8*, i8** %arg2, !nonnull !{}
331 %merged_arg = phi i8* [%another_arg, %null], [%arg1, %non_null]
332 call void @test12_helper(i8* %merged_arg)
336 attributes #0 = { "null-pointer-is-valid"="true" }