[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Transforms / SCCP / resolvedundefsin-tracked-fn.ll
blobf56b4cad149cc4bc12526936409c9156f6360845
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
2 ; RUN: opt -passes=ipsccp -S %s | FileCheck %s
4 %t1 = type opaque
6 @e = common global i32 0, align 4
8 ; Test that we a skip unknown values depending on a unknown tracked call, until the call gets resolved. The @test1 and @test2 variants are very similar, they just check 2 different kinds of users (icmp and zext)
10 define i32 @test1_m(i32 %h) {
11 ; CHECK-LABEL: define {{[^@]+}}@test1_m
12 ; CHECK-SAME: (i32 [[H:%.*]])
13 ; CHECK-NEXT:  entry:
14 ; CHECK-NEXT:    [[CONV:%.*]] = trunc i32 [[H]] to i8
15 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @test1_k(i8 [[CONV]], i32 0)
16 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[H]] to i64
17 ; CHECK-NEXT:    [[TMP0:%.*]] = inttoptr i64 [[CONV1]] to %t1*
18 ; CHECK-NEXT:    [[CALL2:%.*]] = call i1 @test1_g(%t1* [[TMP0]], i32 1)
19 ; CHECK-NEXT:    ret i32 undef
21 entry:
22   %conv = trunc i32 %h to i8
23   %call = call i32 @test1_k(i8 %conv, i32 0)
24   %conv1 = sext i32 %h to i64
25   %0 = inttoptr i64 %conv1 to %t1*
26   %call2 = call i1 @test1_g(%t1* %0, i32 1)
27   ret i32 undef
29 ; uselistorder directives
30   uselistorder i32 %h, { 1, 0 }
33 declare void @use.1(i1)
35 define internal i32 @test1_k(i8 %h, i32 %i) {
36 ; CHECK-LABEL: define {{[^@]+}}@test1_k
37 ; CHECK-SAME: (i8 [[H:%.*]], i32 [[I:%.*]])
38 ; CHECK-NEXT:  entry:
39 ; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* @e, align 4
40 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[TMP0]] to i64
41 ; CHECK-NEXT:    [[TMP1:%.*]] = inttoptr i64 [[CONV]] to %t1*
42 ; CHECK-NEXT:    [[CALL:%.*]] = call i1 @test1_g(%t1* [[TMP1]], i32 0)
43 ; CHECK-NEXT:    call void @use.1(i1 false)
44 ; CHECK-NEXT:    ret i32 undef
46 entry:
47   %0 = load i32, i32* @e, align 4
48   %conv = sext i32 %0 to i64
49   %1 = inttoptr i64 %conv to %t1*
50   %call = call i1 @test1_g(%t1* %1, i32 %i)
51   %frombool.1 = zext i1 %call to i8
52   %tobool.1 = trunc i8 %frombool.1 to i1
53   call void @use.1(i1 %tobool.1)
54   ret i32 undef
57 define internal i1 @test1_g(%t1* %h, i32 %i) #0 {
58 ; CHECK-LABEL: define {{[^@]+}}@test1_g
59 ; CHECK-SAME: (%t1* [[H:%.*]], i32 [[I:%.*]])
60 ; CHECK-NEXT:  entry:
61 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[I]], 0
62 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[LAND_RHS:%.*]], label [[LAND_END:%.*]]
63 ; CHECK:       land.rhs:
64 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 (...) @test1_j()
65 ; CHECK-NEXT:    [[TOBOOL1:%.*]] = icmp ne i32 [[CALL]], 0
66 ; CHECK-NEXT:    br label [[LAND_END]]
67 ; CHECK:       land.end:
68 ; CHECK-NEXT:    [[TMP0:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[TOBOOL1]], [[LAND_RHS]] ]
69 ; CHECK-NEXT:    ret i1 undef
71 entry:
72   %tobool = icmp ne i32 %i, 0
73   br i1 %tobool, label %land.rhs, label %land.end
75 land.rhs:                                         ; preds = %entry
76   %call = call i32 (...) @test1_j()
77   %tobool1 = icmp ne i32 %call, 0
78   br label %land.end
80 land.end:                                         ; preds = %land.rhs, %entry
81   %0 = phi i1 [ false, %entry ], [ %tobool1, %land.rhs ]
82   ret i1 false
85 declare i32 @test1_j(...)
87 define i32 @test2_m(i32 %h) #0 {
88 ; CHECK-LABEL: define {{[^@]+}}@test2_m
89 ; CHECK-SAME: (i32 [[H:%.*]])
90 ; CHECK-NEXT:  entry:
91 ; CHECK-NEXT:    [[CONV:%.*]] = trunc i32 [[H]] to i8
92 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @test2_k(i8 [[CONV]], i32 0)
93 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[H]] to i64
94 ; CHECK-NEXT:    [[TMP0:%.*]] = inttoptr i64 [[CONV1]] to %t1*
95 ; CHECK-NEXT:    [[CALL2:%.*]] = call i1 @test2_g(%t1* [[TMP0]], i32 1)
96 ; CHECK-NEXT:    ret i32 undef
98 entry:
99   %conv = trunc i32 %h to i8
100   %call = call i32 @test2_k(i8 %conv, i32 0)
101   %conv1 = sext i32 %h to i64
102   %0 = inttoptr i64 %conv1 to %t1*
103   %call2 = call i1 @test2_g(%t1* %0, i32 1)
104   ret i32 undef
106 ; uselistorder directives
107   uselistorder i32 %h, { 1, 0 }
110 ; TODO: We could do better for the return value of call i1 @test3_g, if we
111 ;       resolve the unknown values there first.
112 define internal i32 @test2_k(i8 %h, i32 %i) {
113 ; CHECK-LABEL: define {{[^@]+}}@test2_k
114 ; CHECK-SAME: (i8 [[H:%.*]], i32 [[I:%.*]])
115 ; CHECK-NEXT:  entry:
116 ; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* @e, align 4
117 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[TMP0]] to i64
118 ; CHECK-NEXT:    [[TMP1:%.*]] = inttoptr i64 [[CONV]] to %t1*
119 ; CHECK-NEXT:    [[CALL:%.*]] = call i1 @test3_g(%t1* [[TMP1]], i32 0)
120 ; CHECK-NEXT:    call void @use.1(i1 false)
121 ; CHECK-NEXT:    ret i32 undef
123 entry:
124   %0 = load i32, i32* @e, align 4
125   %conv = sext i32 %0 to i64
126   %1 = inttoptr i64 %conv to %t1*
127   %call = call i1 @test3_g(%t1* %1, i32 %i)
128   %frombool = icmp slt i1 %call, 1
129   %add = add i1 %frombool, %frombool
130   call void @use.1(i1 %frombool)
131   ret i32 undef
135 define internal i1 @test2_g(%t1* %h, i32 %i) {
136 ; CHECK-LABEL: define {{[^@]+}}@test2_g
137 ; CHECK-SAME: (%t1* [[H:%.*]], i32 [[I:%.*]])
138 ; CHECK-NEXT:  entry:
139 ; CHECK-NEXT:    br label [[LAND_RHS:%.*]]
140 ; CHECK:       land.rhs:
141 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 (...) @test2_j()
142 ; CHECK-NEXT:    [[TOBOOL1:%.*]] = icmp ne i32 [[CALL]], 0
143 ; CHECK-NEXT:    br label [[LAND_END:%.*]]
144 ; CHECK:       land.end:
145 ; CHECK-NEXT:    ret i1 undef
147 entry:
148   %tobool = icmp ne i32 %i, 0
149   br i1 %tobool, label %land.rhs, label %land.end
151 land.rhs:                                         ; preds = %entry
152   %call = call i32 (...) @test2_j()
153   %tobool1 = icmp ne i32 %call, 0
154   br label %land.end
156 land.end:                                         ; preds = %land.rhs, %entry
157   %0 = phi i1 [ false, %entry ], [ %tobool1, %land.rhs ]
158   ret i1 false
161 declare i32 @test2_j(...)
165 ; Same as test_2*, but with a PHI node depending on a tracked  call result.
166 define i32 @test3_m(i32 %h) #0 {
167 ; CHECK-LABEL: define {{[^@]+}}@test3_m
168 ; CHECK-SAME: (i32 [[H:%.*]])
169 ; CHECK-NEXT:  entry:
170 ; CHECK-NEXT:    [[CONV:%.*]] = trunc i32 [[H]] to i8
171 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @test3_k(i8 [[CONV]], i32 0)
172 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[H]] to i64
173 ; CHECK-NEXT:    [[TMP0:%.*]] = inttoptr i64 [[CONV1]] to %t1*
174 ; CHECK-NEXT:    [[CALL2:%.*]] = call i1 @test3_g(%t1* [[TMP0]], i32 1)
175 ; CHECK-NEXT:    ret i32 undef
177 entry:
178   %conv = trunc i32 %h to i8
179   %call = call i32 @test3_k(i8 %conv, i32 0)
180   %conv1 = sext i32 %h to i64
181   %0 = inttoptr i64 %conv1 to %t1*
182   %call2 = call i1 @test3_g(%t1* %0, i32 1)
183   ret i32 undef
185 ; uselistorder directives
186   uselistorder i32 %h, { 1, 0 }
189 define internal i32 @test3_k(i8 %h, i32 %i) {
190 ; CHECK-LABEL: define {{[^@]+}}@test3_k
191 ; CHECK-SAME: (i8 [[H:%.*]], i32 [[I:%.*]])
192 ; CHECK-NEXT:  entry:
193 ; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* @e, align 4
194 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[TMP0]] to i64
195 ; CHECK-NEXT:    [[TMP1:%.*]] = inttoptr i64 [[CONV]] to %t1*
196 ; CHECK-NEXT:    br label [[LOOP:%.*]]
197 ; CHECK:       loop:
198 ; CHECK-NEXT:    [[CALL:%.*]] = call i1 @test3_g(%t1* [[TMP1]], i32 0)
199 ; CHECK-NEXT:    call void @use.1(i1 false)
200 ; CHECK-NEXT:    br label [[EXIT:%.*]]
201 ; CHECK:       exit:
202 ; CHECK-NEXT:    ret i32 undef
204 entry:
205   %0 = load i32, i32* @e, align 4
206   %conv = sext i32 %0 to i64
207   %1 = inttoptr i64 %conv to %t1*
208   br label %loop
210 loop:
211   %phi = phi i1 [ undef, %entry], [ %call, %loop ]
212   %call = call i1 @test3_g(%t1* %1, i32 %i)
213   %frombool = icmp slt i1 %call, 1
214   %add = add i1 %frombool, %frombool
215   call void @use.1(i1 %frombool)
216   br i1 %call, label %loop, label %exit
218 exit:
219   ret i32 undef
222 define internal i1 @test3_g(%t1* %h, i32 %i) {
223 ; CHECK-LABEL: define {{[^@]+}}@test3_g
224 ; CHECK-SAME: (%t1* [[H:%.*]], i32 [[I:%.*]])
225 ; CHECK-NEXT:  entry:
226 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[I]], 0
227 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[LAND_RHS:%.*]], label [[LAND_END:%.*]]
228 ; CHECK:       land.rhs:
229 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 (...) @test3_j()
230 ; CHECK-NEXT:    [[TOBOOL1:%.*]] = icmp ne i32 [[CALL]], 0
231 ; CHECK-NEXT:    br label [[LAND_END]]
232 ; CHECK:       land.end:
233 ; CHECK-NEXT:    [[TMP0:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[TOBOOL1]], [[LAND_RHS]] ]
234 ; CHECK-NEXT:    ret i1 undef
236 entry:
237   %tobool = icmp ne i32 %i, 0
238   br i1 %tobool, label %land.rhs, label %land.end
240 land.rhs:                                         ; preds = %entry
241   %call = call i32 (...) @test3_j()
242   %tobool1 = icmp ne i32 %call, 0
243   br label %land.end
245 land.end:                                         ; preds = %land.rhs, %entry
246   %0 = phi i1 [ false, %entry ], [ %tobool1, %land.rhs ]
247   ret i1 false
250 declare i32 @test3_j(...)
253 ; TODO: We can eliminate the bitcast, if we resolve the unknown argument of
254 ;       @test4_b first.
256 declare void @use.16(i16*)
257 declare void @use.8(i8*)
259 define void @test4_a() {
260 ; CHECK-LABEL: define {{[^@]+}}@test4_a()
261 ; CHECK-NEXT:  bb:
262 ; CHECK-NEXT:    [[TMP:%.*]] = call i8* @test4_c(i8* null)
263 ; CHECK-NEXT:    call void @test4_b(i8* null)
264 ; CHECK-NEXT:    ret void
267   %tmp = call i8* @test4_c(i8* null)
268   call void @test4_b(i8* %tmp)
269   ret void
272 define internal void @test4_b(i8* %arg) {
273 ; CHECK-LABEL: define {{[^@]+}}@test4_b
274 ; CHECK-SAME: (i8* [[ARG:%.*]])
275 ; CHECK-NEXT:  bb:
276 ; CHECK-NEXT:    [[TMP:%.*]] = bitcast i8* null to i16*
277 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 false, i8* null, i8* null
278 ; CHECK-NEXT:    call void @use.16(i16* [[TMP]])
279 ; CHECK-NEXT:    call void @use.8(i8* [[SEL]])
280 ; CHECK-NEXT:    ret void
283   %tmp = bitcast i8* %arg to i16*
284   %sel = select i1 false, i8* %arg, i8* %arg
285   call void @use.16(i16* %tmp)
286   call void @use.8(i8* %sel)
287   ret void
290 define internal i8* @test4_c(i8* %arg) {
291 ; CHECK-LABEL: define {{[^@]+}}@test4_c
292 ; CHECK-SAME: (i8* [[ARG:%.*]])
293 ; CHECK-NEXT:  bb1:
294 ; CHECK-NEXT:    [[TMP:%.*]] = and i1 undef, undef
295 ; CHECK-NEXT:    br i1 [[TMP]], label [[BB3:%.*]], label [[BB2:%.*]]
296 ; CHECK:       bb2:
297 ; CHECK-NEXT:    unreachable
298 ; CHECK:       bb3:
299 ; CHECK-NEXT:    ret i8* undef
301 bb1:                                              ; preds = %bb
302   %tmp = and i1 undef, undef
303   br i1 %tmp, label %bb3, label %bb2
305 bb2:                                              ; preds = %bb1
306   unreachable
308 bb3:                                              ; preds = %bb1
309   ret i8* null
312 ; TODO: Same as test4, but with a select instead of a bitcast.
314 define void @test5_a() {
315 ; CHECK-LABEL: define {{[^@]+}}@test5_a()
316 ; CHECK-NEXT:  bb:
317 ; CHECK-NEXT:    [[TMP:%.*]] = call i8* @test5_c(i8* null)
318 ; CHECK-NEXT:    call void @test5_b(i8* null)
319 ; CHECK-NEXT:    ret void
322   %tmp = call i8* @test5_c(i8* null)
323   call void @test5_b(i8* %tmp)
324   ret void
327 define internal void @test5_b(i8* %arg) {
328 ; CHECK-LABEL: define {{[^@]+}}@test5_b
329 ; CHECK-SAME: (i8* [[ARG:%.*]])
330 ; CHECK-NEXT:  bb:
331 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 false, i8* null, i8* null
332 ; CHECK-NEXT:    call void @use.8(i8* [[SEL]])
333 ; CHECK-NEXT:    ret void
336   %sel = select i1 false, i8* %arg, i8* %arg
337   call void @use.8(i8* %sel)
338   ret void
341 define internal i8* @test5_c(i8* %arg) {
342 ; CHECK-LABEL: define {{[^@]+}}@test5_c
343 ; CHECK-SAME: (i8* [[ARG:%.*]])
344 ; CHECK-NEXT:  bb1:
345 ; CHECK-NEXT:    [[TMP:%.*]] = and i1 undef, undef
346 ; CHECK-NEXT:    br i1 [[TMP]], label [[BB3:%.*]], label [[BB2:%.*]]
347 ; CHECK:       bb2:
348 ; CHECK-NEXT:    unreachable
349 ; CHECK:       bb3:
350 ; CHECK-NEXT:    ret i8* undef
352 bb1:                                              ; preds = %bb
353   %tmp = and i1 undef, undef
354   br i1 %tmp, label %bb3, label %bb2
356 bb2:                                              ; preds = %bb1
357   unreachable
359 bb3:                                              ; preds = %bb1
360   ret i8* null
365 @contextsize = external dso_local local_unnamed_addr global i32, align 4
366 @pcount = internal local_unnamed_addr global i32 0, align 4
367 @maxposslen = external dso_local local_unnamed_addr global i32, align 4
369 define void @test3() {
370 ; CHECK-LABEL: define {{[^@]+}}@test3()
371 ; CHECK-NEXT:  entry:
372 ; CHECK-NEXT:    br label [[IF_END16:%.*]]
373 ; CHECK:       if.end16:
374 ; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* @contextsize, align 4
375 ; CHECK-NEXT:    [[SUB18:%.*]] = sub i32 undef, [[TMP0]]
376 ; CHECK-NEXT:    [[SUB19:%.*]] = sub i32 [[SUB18]], undef
377 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* @maxposslen, align 4
378 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP1]], 8
379 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 undef, [[ADD]]
380 ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, i32* @pcount, align 4
381 ; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[DIV]], [[SUB19]]
382 ; CHECK-NEXT:    [[CMP20:%.*]] = icmp sgt i32 [[TMP2]], [[MUL]]
383 ; CHECK-NEXT:    br i1 [[CMP20]], label [[IF_THEN22:%.*]], label [[IF_END24:%.*]]
384 ; CHECK:       if.then22:
385 ; CHECK-NEXT:    store i32 [[MUL]], i32* @pcount, align 4
386 ; CHECK-NEXT:    ret void
387 ; CHECK:       if.end24:
388 ; CHECK-NEXT:    [[CMP25474:%.*]] = icmp sgt i32 [[TMP2]], 0
389 ; CHECK-NEXT:    br i1 [[CMP25474]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
390 ; CHECK:       for.body:
391 ; CHECK-NEXT:    ret void
392 ; CHECK:       for.end:
393 ; CHECK-NEXT:    ret void
395 entry:
396   br label %if.end16
398 if.end16:                                         ; preds = %entry
399   %0 = load i32, i32* @contextsize, align 4
400   %sub18 = sub i32 undef, %0
401   %sub19 = sub i32 %sub18, undef
402   %1 = load i32, i32* @maxposslen, align 4
403   %add = add nsw i32 %1, 8
404   %div = sdiv i32 undef, %add
405   %2 = load i32, i32* @pcount, align 4
406   %mul = mul nsw i32 %div, %sub19
407   %cmp20 = icmp sgt i32 %2, %mul
408   br i1 %cmp20, label %if.then22, label %if.end24
410 if.then22:                                        ; preds = %if.end16
411   store i32 %mul, i32* @pcount, align 4
412   ret void
414 if.end24:                                         ; preds = %if.end16
415   %cmp25474 = icmp sgt i32 %2, 0
416   br i1 %cmp25474, label %for.body, label %for.end
418 for.body:                                         ; preds = %if.end24
419   %3 = trunc i64 0 to i32
420   %div30 = sdiv i32 %3, %sub19
421   ret void
423 for.end:                                          ; preds = %if.end24
424   ret void