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