[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / InstSimplify / freeze.ll
blobcb418b4e59283624b716aedc552f32da7427abd5
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instsimplify -S | FileCheck %s
4 define i32 @fold(i32 %x) {
5 ; CHECK-LABEL: @fold(
6 ; CHECK-NEXT:    [[Y:%.*]] = freeze i32 [[X:%.*]]
7 ; CHECK-NEXT:    ret i32 [[Y]]
9   %y = freeze i32 %x
10   %z = freeze i32 %y
11   ret i32 %z
14 define i32 @make_const() {
15 ; CHECK-LABEL: @make_const(
16 ; CHECK-NEXT:    ret i32 10
18   %x = freeze i32 10
19   ret i32 %x
22 define float @make_const2() {
23 ; CHECK-LABEL: @make_const2(
24 ; CHECK-NEXT:    ret float 1.000000e+01
26   %x = freeze float 10.0
27   ret float %x
30 @glb = constant i32 0
32 define i32* @make_const_glb() {
33 ; CHECK-LABEL: @make_const_glb(
34 ; CHECK-NEXT:    ret i32* @glb
36   %k = freeze i32* @glb
37   ret i32* %k
40 define i32()* @make_const_fn() {
41 ; CHECK-LABEL: @make_const_fn(
42 ; CHECK-NEXT:    ret i32 ()* @make_const
44   %k = freeze i32()* @make_const
45   ret i32()* %k
48 define i32* @make_const_null() {
49 ; CHECK-LABEL: @make_const_null(
50 ; CHECK-NEXT:    ret i32* null
52   %k = freeze i32* null
53   ret i32* %k
56 define <2 x i32> @constvector() {
57 ; CHECK-LABEL: @constvector(
58 ; CHECK-NEXT:    ret <2 x i32> <i32 0, i32 1>
60   %x = freeze <2 x i32> <i32 0, i32 1>
61   ret <2 x i32> %x
64 define <3 x i5> @constvector_weird() {
65 ; CHECK-LABEL: @constvector_weird(
66 ; CHECK-NEXT:    ret <3 x i5> <i5 0, i5 1, i5 10>
68   %x = freeze <3 x i5> <i5 0, i5 1, i5 42>
69   ret <3 x i5> %x
72 define <2 x float> @constvector_FP() {
73 ; CHECK-LABEL: @constvector_FP(
74 ; CHECK-NEXT:    ret <2 x float> <float 0.000000e+00, float 1.000000e+00>
76   %x = freeze <2 x float> <float 0.0, float 1.0>
77   ret <2 x float> %x
80 ; Negative test
82 define <2 x i32> @constvector_noopt() {
83 ; CHECK-LABEL: @constvector_noopt(
84 ; CHECK-NEXT:    [[X:%.*]] = freeze <2 x i32> <i32 0, i32 undef>
85 ; CHECK-NEXT:    ret <2 x i32> [[X]]
87   %x = freeze <2 x i32> <i32 0, i32 undef>
88   ret <2 x i32> %x
91 ; Negative test
93 define <3 x i5> @constvector_weird_noopt() {
94 ; CHECK-LABEL: @constvector_weird_noopt(
95 ; CHECK-NEXT:    [[X:%.*]] = freeze <3 x i5> <i5 0, i5 undef, i5 10>
96 ; CHECK-NEXT:    ret <3 x i5> [[X]]
98   %x = freeze <3 x i5> <i5 0, i5 undef, i5 42>
99   ret <3 x i5> %x
102 ; Negative test
104 define <2 x float> @constvector_FP_noopt() {
105 ; CHECK-LABEL: @constvector_FP_noopt(
106 ; CHECK-NEXT:    [[X:%.*]] = freeze <2 x float> <float 0.000000e+00, float undef>
107 ; CHECK-NEXT:    ret <2 x float> [[X]]
109   %x = freeze <2 x float> <float 0.0, float undef>
110   ret <2 x float> %x
113 @g = external global i16, align 1
114 @g2 = external global i16, align 1
116 define float @constant_expr() {
117 ; CHECK-LABEL: @constant_expr(
118 ; CHECK-NEXT:    ret float bitcast (i32 ptrtoint (i16* @g to i32) to float)
120   %r = freeze float bitcast (i32 ptrtoint (i16* @g to i32) to float)
121   ret float %r
124 define i8* @constant_expr2() {
125 ; CHECK-LABEL: @constant_expr2(
126 ; CHECK-NEXT:    ret i8* bitcast (i16* @g to i8*)
128   %r = freeze i8* bitcast (i16* @g to i8*)
129   ret i8* %r
132 define i32* @constant_expr3() {
133 ; CHECK-LABEL: @constant_expr3(
134 ; CHECK-NEXT:    ret i32* getelementptr (i32, i32* @glb, i64 3)
136   %r = freeze i32* getelementptr (i32, i32* @glb, i64 3)
137   ret i32* %r
140 define i64 @ptrdiff() {
141 ; CHECK-LABEL: @ptrdiff(
142 ; CHECK-NEXT:    ret i64 sub (i64 ptrtoint (i16* @g to i64), i64 ptrtoint (i16* @g2 to i64))
144   %i = ptrtoint i16* @g to i64
145   %i2 = ptrtoint i16* @g2 to i64
146   %diff = sub i64 %i, %i2
147   %r = freeze i64 %diff
148   ret i64 %r
151 ; Negative test
153 define <2 x i31> @vector_element_constant_expr() {
154 ; CHECK-LABEL: @vector_element_constant_expr(
155 ; CHECK-NEXT:    [[R:%.*]] = freeze <2 x i31> <i31 34, i31 ptrtoint (i16* @g to i31)>
156 ; CHECK-NEXT:    ret <2 x i31> [[R]]
158   %r = freeze <2 x i31> <i31 34, i31 ptrtoint (i16* @g to i31)>
159   ret <2 x i31> %r
162 define void @alloca() {
163 ; CHECK-LABEL: @alloca(
164 ; CHECK-NEXT:    [[P:%.*]] = alloca i8, align 1
165 ; CHECK-NEXT:    call void @f3(i8* [[P]])
166 ; CHECK-NEXT:    ret void
168   %p = alloca i8
169   %y = freeze i8* %p
170   call void @f3(i8* %y)
171   ret void
174 define i8* @gep() {
175 ; CHECK-LABEL: @gep(
176 ; CHECK-NEXT:    [[P:%.*]] = alloca [4 x i8], align 1
177 ; CHECK-NEXT:    [[Q:%.*]] = getelementptr [4 x i8], [4 x i8]* [[P]], i32 0, i32 6
178 ; CHECK-NEXT:    ret i8* [[Q]]
180   %p = alloca [4 x i8]
181   %q = getelementptr [4 x i8], [4 x i8]* %p, i32 0, i32 6
182   %q2 = freeze i8* %q
183   ret i8* %q2
186 define i8* @gep_noopt(i32 %arg) {
187 ; CHECK-LABEL: @gep_noopt(
188 ; CHECK-NEXT:    [[Q:%.*]] = getelementptr [4 x i8], [4 x i8]* null, i32 0, i32 [[ARG:%.*]]
189 ; CHECK-NEXT:    [[Q2:%.*]] = freeze i8* [[Q]]
190 ; CHECK-NEXT:    ret i8* [[Q2]]
192   %q = getelementptr [4 x i8], [4 x i8]* null, i32 0, i32 %arg
193   %q2 = freeze i8* %q
194   ret i8* %q2
197 define i8* @gep_inbounds() {
198 ; CHECK-LABEL: @gep_inbounds(
199 ; CHECK-NEXT:    [[P:%.*]] = alloca [4 x i8], align 1
200 ; CHECK-NEXT:    [[Q:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* [[P]], i32 0, i32 0
201 ; CHECK-NEXT:    ret i8* [[Q]]
203   %p = alloca [4 x i8]
204   %q = getelementptr inbounds [4 x i8], [4 x i8]* %p, i32 0, i32 0
205   %q2 = freeze i8* %q
206   ret i8* %q2
209 define i8* @gep_inbounds_noopt(i32 %arg) {
210 ; CHECK-LABEL: @gep_inbounds_noopt(
211 ; CHECK-NEXT:    [[P:%.*]] = alloca [4 x i8], align 1
212 ; CHECK-NEXT:    [[Q:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* [[P]], i32 0, i32 [[ARG:%.*]]
213 ; CHECK-NEXT:    [[Q2:%.*]] = freeze i8* [[Q]]
214 ; CHECK-NEXT:    ret i8* [[Q2]]
216   %p = alloca [4 x i8]
217   %q = getelementptr inbounds [4 x i8], [4 x i8]* %p, i32 0, i32 %arg
218   %q2 = freeze i8* %q
219   ret i8* %q2
222 define i32* @gep_inbounds_null() {
223 ; CHECK-LABEL: @gep_inbounds_null(
224 ; CHECK-NEXT:    ret i32* null
226   %p = getelementptr inbounds i32, i32* null, i32 0
227   %k = freeze i32* %p
228   ret i32* %k
231 define i32* @gep_inbounds_null_noopt(i32* %p) {
232 ; CHECK-LABEL: @gep_inbounds_null_noopt(
233 ; CHECK-NEXT:    [[K:%.*]] = freeze i32* [[P:%.*]]
234 ; CHECK-NEXT:    ret i32* [[K]]
236   %q = getelementptr inbounds i32, i32* %p, i32 0
237   %k = freeze i32* %q
238   ret i32* %k
241 define i8* @load_ptr(i8* %ptr) {
242 ; CHECK-LABEL: @load_ptr(
243 ; CHECK-NEXT:    [[V:%.*]] = load i8, i8* [[PTR:%.*]], align 1
244 ; CHECK-NEXT:    call void @f4(i8 [[V]])
245 ; CHECK-NEXT:    ret i8* [[PTR]]
247   %v = load i8, i8* %ptr
248   %q = freeze i8* %ptr
249   call void @f4(i8 %v) ; prevents %v from being DCEd
250   ret i8* %q
253 define i8* @store_ptr(i8* %ptr) {
254 ; CHECK-LABEL: @store_ptr(
255 ; CHECK-NEXT:    store i8 0, i8* [[PTR:%.*]], align 1
256 ; CHECK-NEXT:    ret i8* [[PTR]]
258   store i8 0, i8* %ptr
259   %q = freeze i8* %ptr
260   ret i8* %q
263 define i8* @call_noundef_ptr(i8* %ptr) {
264 ; CHECK-LABEL: @call_noundef_ptr(
265 ; CHECK-NEXT:    call void @f3(i8* noundef [[PTR:%.*]])
266 ; CHECK-NEXT:    ret i8* [[PTR]]
268   call void @f3(i8* noundef %ptr)
269   %q = freeze i8* %ptr
270   ret i8* %q
273 define i8* @invoke_noundef_ptr(i8* %ptr) personality i8 1 {
274 ; CHECK-LABEL: @invoke_noundef_ptr(
275 ; CHECK-NEXT:    invoke void @f3(i8* noundef [[PTR:%.*]])
276 ; CHECK-NEXT:    to label [[NORMAL:%.*]] unwind label [[UNWIND:%.*]]
277 ; CHECK:       normal:
278 ; CHECK-NEXT:    ret i8* [[PTR]]
279 ; CHECK:       unwind:
280 ; CHECK-NEXT:    [[TMP1:%.*]] = landingpad i8*
281 ; CHECK-NEXT:    cleanup
282 ; CHECK-NEXT:    resume i8* [[PTR]]
284   %q = freeze i8* %ptr
285   invoke void @f3(i8* noundef %ptr) to label %normal unwind label %unwind
286 normal:
287   ret i8* %q
288 unwind:
289   landingpad i8* cleanup
290   resume i8* %q
293 define i8* @cmpxchg_ptr(i8* %ptr) {
294 ; CHECK-LABEL: @cmpxchg_ptr(
295 ; CHECK-NEXT:    [[TMP1:%.*]] = cmpxchg i8* [[PTR:%.*]], i8 1, i8 2 acq_rel monotonic, align 1
296 ; CHECK-NEXT:    ret i8* [[PTR]]
298   cmpxchg i8* %ptr, i8 1, i8 2 acq_rel monotonic
299   %q = freeze i8* %ptr
300   ret i8* %q
303 define i8* @atomicrmw_ptr(i8* %ptr) {
304 ; CHECK-LABEL: @atomicrmw_ptr(
305 ; CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw add i8* [[PTR:%.*]], i8 1 acquire, align 1
306 ; CHECK-NEXT:    ret i8* [[PTR]]
308   atomicrmw add i8* %ptr, i8 1 acquire
309   %q = freeze i8* %ptr
310   ret i8* %q
313 define i1 @icmp(i32 %a, i32 %b) {
314 ; CHECK-LABEL: @icmp(
315 ; CHECK-NEXT:    [[A_FR:%.*]] = freeze i32 [[A:%.*]]
316 ; CHECK-NEXT:    [[B_FR:%.*]] = freeze i32 [[B:%.*]]
317 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[A_FR]], [[B_FR]]
318 ; CHECK-NEXT:    ret i1 [[C]]
320   %a.fr = freeze i32 %a
321   %b.fr = freeze i32 %b
322   %c = icmp eq i32 %a.fr, %b.fr
323   %c.fr = freeze i1 %c
324   ret i1 %c.fr
327 define i1 @icmp_noopt(i32 %a, i32 %b) {
328 ; CHECK-LABEL: @icmp_noopt(
329 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
330 ; CHECK-NEXT:    [[C_FR:%.*]] = freeze i1 [[C]]
331 ; CHECK-NEXT:    ret i1 [[C_FR]]
333   %c = icmp eq i32 %a, %b
334   %c.fr = freeze i1 %c
335   ret i1 %c.fr
338 define i1 @fcmp(float %x, float %y) {
339 ; CHECK-LABEL: @fcmp(
340 ; CHECK-NEXT:    [[FX:%.*]] = freeze float [[X:%.*]]
341 ; CHECK-NEXT:    [[FY:%.*]] = freeze float [[Y:%.*]]
342 ; CHECK-NEXT:    [[C:%.*]] = fcmp oeq float [[FX]], [[FY]]
343 ; CHECK-NEXT:    ret i1 [[C]]
345   %fx = freeze float %x
346   %fy = freeze float %y
347   %c = fcmp oeq float %fx, %fy
348   %fc = freeze i1 %c
349   ret i1 %fc
352 define i1 @fcmp_noopt(float %x, float %y) {
353 ; CHECK-LABEL: @fcmp_noopt(
354 ; CHECK-NEXT:    [[FX:%.*]] = freeze float [[X:%.*]]
355 ; CHECK-NEXT:    [[FY:%.*]] = freeze float [[Y:%.*]]
356 ; CHECK-NEXT:    [[C:%.*]] = fcmp nnan oeq float [[FX]], [[FY]]
357 ; CHECK-NEXT:    [[FC:%.*]] = freeze i1 [[C]]
358 ; CHECK-NEXT:    ret i1 [[FC]]
360   %fx = freeze float %x
361   %fy = freeze float %y
362   %c = fcmp nnan oeq float %fx, %fy
363   %fc = freeze i1 %c
364   ret i1 %fc
367 define i1 @brcond(i1 %c, i1 %c2) {
368 ; CHECK-LABEL: @brcond(
369 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[A:%.*]], label [[B:%.*]]
370 ; CHECK:       A:
371 ; CHECK-NEXT:    br i1 [[C2:%.*]], label [[A2:%.*]], label [[B]]
372 ; CHECK:       A2:
373 ; CHECK-NEXT:    ret i1 [[C]]
374 ; CHECK:       B:
375 ; CHECK-NEXT:    ret i1 [[C]]
377   br i1 %c, label %A, label %B
379   br i1 %c2, label %A2, label %B
381   %f1 = freeze i1 %c
382   ret i1 %f1
384   %f2 = freeze i1 %c
385   ret i1 %f2
388 define i32 @phi(i1 %cond, i1 %cond2, i32 %a0, i32 %a1) {
389 ; CHECK-LABEL: @phi(
390 ; CHECK-NEXT:  ENTRY:
391 ; CHECK-NEXT:    [[A0_FR:%.*]] = freeze i32 [[A0:%.*]]
392 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
393 ; CHECK:       BB1:
394 ; CHECK-NEXT:    [[A1_FR:%.*]] = freeze i32 [[A1:%.*]]
395 ; CHECK-NEXT:    br i1 [[COND2:%.*]], label [[BB2]], label [[EXIT:%.*]]
396 ; CHECK:       BB2:
397 ; CHECK-NEXT:    [[PHI1:%.*]] = phi i32 [ [[A0_FR]], [[ENTRY:%.*]] ], [ [[A1_FR]], [[BB1]] ]
398 ; CHECK-NEXT:    br label [[EXIT]]
399 ; CHECK:       EXIT:
400 ; CHECK-NEXT:    [[PHI2:%.*]] = phi i32 [ [[A0_FR]], [[BB1]] ], [ [[PHI1]], [[BB2]] ]
401 ; CHECK-NEXT:    ret i32 [[PHI2]]
403 ENTRY:
404   %a0.fr = freeze i32 %a0
405   br i1 %cond, label %BB1, label %BB2
406 BB1:
407   %a1.fr = freeze i32 %a1
408   br i1 %cond2, label %BB2, label %EXIT
409 BB2:
410   %phi1 = phi i32 [%a0.fr, %ENTRY], [%a1.fr, %BB1]
411   br label %EXIT
412 EXIT:
413   %phi2 = phi i32 [%a0.fr, %BB1], [%phi1, %BB2]
414   %phi2.fr = freeze i32 %phi2
415   ret i32 %phi2.fr
418 define i32 @phi_noopt(i1 %cond, i1 %cond2, i32 %a0, i32 %a1) {
419 ; CHECK-LABEL: @phi_noopt(
420 ; CHECK-NEXT:  ENTRY:
421 ; CHECK-NEXT:    [[A0_FR:%.*]] = freeze i32 [[A0:%.*]]
422 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
423 ; CHECK:       BB1:
424 ; CHECK-NEXT:    br i1 [[COND2:%.*]], label [[BB2]], label [[EXIT:%.*]]
425 ; CHECK:       BB2:
426 ; CHECK-NEXT:    [[PHI1:%.*]] = phi i32 [ [[A0_FR]], [[ENTRY:%.*]] ], [ [[A1:%.*]], [[BB1]] ]
427 ; CHECK-NEXT:    br label [[EXIT]]
428 ; CHECK:       EXIT:
429 ; CHECK-NEXT:    [[PHI2:%.*]] = phi i32 [ [[A0_FR]], [[BB1]] ], [ [[PHI1]], [[BB2]] ]
430 ; CHECK-NEXT:    [[PHI2_FR:%.*]] = freeze i32 [[PHI2]]
431 ; CHECK-NEXT:    ret i32 [[PHI2_FR]]
433 ENTRY:
434   %a0.fr = freeze i32 %a0
435   br i1 %cond, label %BB1, label %BB2
436 BB1:
437   br i1 %cond2, label %BB2, label %EXIT
438 BB2:
439   %phi1 = phi i32 [%a0.fr, %ENTRY], [%a1, %BB1]
440   br label %EXIT
441 EXIT:
442   %phi2 = phi i32 [%a0.fr, %BB1], [%phi1, %BB2]
443   %phi2.fr = freeze i32 %phi2
444   ret i32 %phi2.fr
447 define i32 @brcond_switch(i32 %x) {
448 ; CHECK-LABEL: @brcond_switch(
449 ; CHECK-NEXT:    switch i32 [[X:%.*]], label [[EXIT:%.*]] [
450 ; CHECK-NEXT:    i32 0, label [[A:%.*]]
451 ; CHECK-NEXT:    ]
452 ; CHECK:       A:
453 ; CHECK-NEXT:    ret i32 [[X]]
454 ; CHECK:       EXIT:
455 ; CHECK-NEXT:    ret i32 [[X]]
457   switch i32 %x, label %EXIT [ i32 0, label %A ]
459   %fr1 = freeze i32 %x
460   ret i32 %fr1
461 EXIT:
462   %fr2 = freeze i32 %x
463   ret i32 %fr2
466 declare i32 @any_num()
468 define i32 @brcond_call() {
469 ; CHECK-LABEL: @brcond_call(
470 ; CHECK-NEXT:    [[X:%.*]] = call i32 @any_num()
471 ; CHECK-NEXT:    switch i32 [[X]], label [[EXIT:%.*]] [
472 ; CHECK-NEXT:    ]
473 ; CHECK:       EXIT:
474 ; CHECK-NEXT:    ret i32 [[X]]
476   %x = call i32 @any_num()
477   switch i32 %x, label %EXIT []
478 EXIT:
479   %y = freeze i32 %x
480   ret i32 %y
483 define i1 @brcond_noopt(i1 %c, i1 %c2) {
484 ; CHECK-LABEL: @brcond_noopt(
485 ; CHECK-NEXT:    [[F:%.*]] = freeze i1 [[C:%.*]]
486 ; CHECK-NEXT:    call void @f1(i1 [[F]])
487 ; CHECK-NEXT:    call void @f2()
488 ; CHECK-NEXT:    br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
489 ; CHECK:       A:
490 ; CHECK-NEXT:    ret i1 false
491 ; CHECK:       B:
492 ; CHECK-NEXT:    ret i1 true
494   %f = freeze i1 %c
495   call void @f1(i1 %f) ; cannot optimize i1 %f to %c
496   call void @f2()      ; .. because if f2() exits, `br %c` cannot be reached
497   br i1 %c, label %A, label %B
499   ret i1 0
501   ret i1 1
503 declare void @f1(i1)
504 declare void @f2()
505 declare void @f3(i8*)
506 declare void @f4(i8)