Clang] Fix expansion of response files in -Wp after integrated-cc1 change
[llvm-project.git] / llvm / test / Analysis / ValueTracking / known-nonnull-at.ll
blob9df8c28551329b83d17a4b2d4b24140459ebba50
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -instsimplify < %s | FileCheck %s
4 declare void @bar(i8* %a, i8* nonnull %b)
6 ; 'y' must be nonnull.
8 define i1 @caller1(i8* %x, i8* %y) {
9 ; CHECK-LABEL: @caller1(
10 ; CHECK-NEXT:    call void @bar(i8* [[X:%.*]], i8* [[Y:%.*]])
11 ; CHECK-NEXT:    ret i1 false
13   call void @bar(i8* %x, i8* %y)
14   %null_check = icmp eq i8* %y, null
15   ret i1 %null_check
18 ; Don't know anything about 'y'.
20 define i1 @caller2(i8* %x, i8* %y) {
21 ; CHECK-LABEL: @caller2(
22 ; CHECK-NEXT:    call void @bar(i8* [[Y:%.*]], i8* [[X:%.*]])
23 ; CHECK-NEXT:    [[NULL_CHECK:%.*]] = icmp eq i8* [[Y]], null
24 ; CHECK-NEXT:    ret i1 [[NULL_CHECK]]
26   call void @bar(i8* %y, i8* %x)
27   %null_check = icmp eq i8* %y, null
28   ret i1 %null_check
31 ; 'y' must be nonnull.
33 define i1 @caller3(i8* %x, i8* %y) {
34 ; CHECK-LABEL: @caller3(
35 ; CHECK-NEXT:    call void @bar(i8* [[X:%.*]], i8* [[Y:%.*]])
36 ; CHECK-NEXT:    ret i1 true
38   call void @bar(i8* %x, i8* %y)
39   %null_check = icmp ne i8* %y, null
40   ret i1 %null_check
43 ; FIXME: The call is guaranteed to execute, so 'y' must be nonnull throughout.
45 define i1 @caller4(i8* %x, i8* %y) {
46 ; CHECK-LABEL: @caller4(
47 ; CHECK-NEXT:    [[NULL_CHECK:%.*]] = icmp ne i8* [[Y:%.*]], null
48 ; CHECK-NEXT:    call void @bar(i8* [[X:%.*]], i8* [[Y]])
49 ; CHECK-NEXT:    ret i1 [[NULL_CHECK]]
51   %null_check = icmp ne i8* %y, null
52   call void @bar(i8* %x, i8* %y)
53   ret i1 %null_check
56 ; The call to bar() does not dominate the null check, so no change.
58 define i1 @caller5(i8* %x, i8* %y) {
59 ; CHECK-LABEL: @caller5(
60 ; CHECK-NEXT:    [[NULL_CHECK:%.*]] = icmp eq i8* [[Y:%.*]], null
61 ; CHECK-NEXT:    br i1 [[NULL_CHECK]], label [[T:%.*]], label [[F:%.*]]
62 ; CHECK:       t:
63 ; CHECK-NEXT:    ret i1 [[NULL_CHECK]]
64 ; CHECK:       f:
65 ; CHECK-NEXT:    call void @bar(i8* [[X:%.*]], i8* [[Y]])
66 ; CHECK-NEXT:    ret i1 [[NULL_CHECK]]
68   %null_check = icmp eq i8* %y, null
69   br i1 %null_check, label %t, label %f
71   ret i1 %null_check
73   call void @bar(i8* %x, i8* %y)
74   ret i1 %null_check
77 ; Make sure that an invoke works similarly to a call.
79 declare i32 @esfp(...)
81 define i1 @caller6(i8* %x, i8* %y) personality i8* bitcast (i32 (...)* @esfp to i8*){
82 ; CHECK-LABEL: @caller6(
83 ; CHECK-NEXT:    invoke void @bar(i8* [[X:%.*]], i8* nonnull [[Y:%.*]])
84 ; CHECK-NEXT:    to label [[CONT:%.*]] unwind label [[EXC:%.*]]
85 ; CHECK:       cont:
86 ; CHECK-NEXT:    ret i1 false
87 ; CHECK:       exc:
88 ; CHECK-NEXT:    [[LP:%.*]] = landingpad { i8*, i32 }
89 ; CHECK-NEXT:    filter [0 x i8*] zeroinitializer
90 ; CHECK-NEXT:    unreachable
92   invoke void @bar(i8* %x, i8* nonnull %y)
93   to label %cont unwind label %exc
95 cont:
96   %null_check = icmp eq i8* %y, null
97   ret i1 %null_check
99 exc:
100   %lp = landingpad { i8*, i32 }
101   filter [0 x i8*] zeroinitializer
102   unreachable
105 declare i8* @returningPtr(i8* returned %p)
107 define i1 @nonnullReturnTest(i8* nonnull %x) {
108 ; CHECK-LABEL: @nonnullReturnTest(
109 ; CHECK-NEXT:    [[X2:%.*]] = call i8* @returningPtr(i8* [[X:%.*]])
110 ; CHECK-NEXT:    ret i1 false
112   %x2 = call i8* @returningPtr(i8* %x)
113   %null_check = icmp eq i8* %x2, null
114   ret i1 %null_check
117 define i1 @unknownReturnTest(i8* %x) {
118 ; CHECK-LABEL: @unknownReturnTest(
119 ; CHECK-NEXT:    [[X2:%.*]] = call i8* @returningPtr(i8* [[X:%.*]])
120 ; CHECK-NEXT:    [[NULL_CHECK:%.*]] = icmp eq i8* [[X2]], null
121 ; CHECK-NEXT:    ret i1 [[NULL_CHECK]]
123   %x2 = call i8* @returningPtr(i8* %x)
124   %null_check = icmp eq i8* %x2, null
125   ret i1 %null_check
128 ; Make sure that if load/store happened, the pointer is nonnull.
130 define i32 @test_null_after_store(i32* %0) {
131 ; CHECK-LABEL: @test_null_after_store(
132 ; CHECK-NEXT:    store i32 123, i32* [[TMP0:%.*]], align 4
133 ; CHECK-NEXT:    ret i32 2
135   store i32 123, i32* %0, align 4
136   %2 = icmp eq i32* %0, null
137   %3 = select i1 %2, i32 1, i32 2
138   ret i32 %3
141 define i32 @test_null_after_load(i32* %0) {
142 ; CHECK-LABEL: @test_null_after_load(
143 ; CHECK-NEXT:    ret i32 1
145   %2 = load i32, i32* %0, align 4
146   %3 = icmp eq i32* %0, null
147   %4 = select i1 %3, i32 %2, i32 1
148   ret i32 %4
151 ; Make sure that different address space does not affect null pointer check.
153 define i32 @test_null_after_store_addrspace(i32 addrspace(1)* %0) {
154 ; CHECK-LABEL: @test_null_after_store_addrspace(
155 ; CHECK-NEXT:    store i32 123, i32 addrspace(1)* [[TMP0:%.*]], align 4
156 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 addrspace(1)* [[TMP0]], null
157 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP2]], i32 1, i32 2
158 ; CHECK-NEXT:    ret i32 [[TMP3]]
160   store i32 123, i32 addrspace(1)* %0, align 4
161   %2 = icmp eq i32 addrspace(1)* %0, null
162   %3 = select i1 %2, i32 1, i32 2
163   ret i32 %3
166 define i32 @test_null_after_load_addrspace(i32 addrspace(1)* %0) {
167 ; CHECK-LABEL: @test_null_after_load_addrspace(
168 ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, i32 addrspace(1)* [[TMP0:%.*]], align 4
169 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 addrspace(1)* [[TMP0]], null
170 ; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP3]], i32 [[TMP2]], i32 1
171 ; CHECK-NEXT:    ret i32 [[TMP4]]
173 ; CHECK-NEXT     ret i32 %4
174   %2 = load i32, i32 addrspace(1)* %0, align 4
175   %3 = icmp eq i32 addrspace(1)* %0, null
176   %4 = select i1 %3, i32 %2, i32 1
177   ret i32 %4
180 ; Make sure if store happened after the check, nullptr check is not removed.
182 declare i8* @func(i64)
184 define i8* @test_load_store_after_check(i8* %0) {
185 ; CHECK-LABEL: @test_load_store_after_check(
186 ; CHECK-NEXT:  entry:
187 ; CHECK-NEXT:    [[TMP1:%.*]] = call i8* @func(i64 0)
188 ; CHECK-NEXT:    [[NULL_CHECK:%.*]] = icmp eq i8* [[TMP1]], null
189 ; CHECK-NEXT:    br i1 [[NULL_CHECK]], label [[RETURN:%.*]], label [[IF_END:%.*]]
190 ; CHECK:       if.end:
191 ; CHECK-NEXT:    store i8 7, i8* [[TMP1]]
192 ; CHECK-NEXT:    br label [[RETURN]]
193 ; CHECK:       return:
194 ; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi i8* [ [[TMP1]], [[IF_END]] ], [ null, [[ENTRY:%.*]] ]
195 ; CHECK-NEXT:    ret i8* [[RETVAL_0]]
197 entry:
198   %1 = call i8* @func(i64 0)
199   %null_check = icmp eq i8* %1, null
200   br i1 %null_check, label %return, label %if.end
202 if.end:
203   store i8 7, i8* %1
204   br label %return
206 return:
207   %retval.0 = phi i8* [ %1, %if.end ], [ null, %entry ]
208   ret i8* %retval.0