[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / Analysis / ValueTracking / deref-bitcast-of-gep.ll
blob69c00819aa38771ec5fc82f80e1508cc19eb1109
1 ; RUN: opt -S -licm < %s | FileCheck %s
3 ; Note: the !invariant.load is there just solely to let us call @use()
4 ; to add a fake use, and still have the aliasing work out.  The call
5 ; to @use(0) is just to provide a may-unwind exit out of the loop, so
6 ; that LICM cannot hoist out the load simply because it is guaranteed
7 ; to execute.
9 declare void @use(i32)
11 define void @f_0(i8* align 4 dereferenceable(1024) %ptr) {
12 ; CHECK-LABEL: @f_0(
13 ; CHECK: entry:
14 ; CHECK:  %val = load i32, i32* %ptr.i32
15 ; CHECK:  br label %loop
16 ; CHECK: loop:
17 ; CHECK:  call void @use(i32 0)
18 ; CHECK-NEXT:  call void @use(i32 %val)
21 entry:
22   %ptr.gep = getelementptr i8, i8* %ptr, i32 32
23   %ptr.i32 = bitcast i8* %ptr.gep to i32*
24   br label %loop
26 loop:
27   call void @use(i32 0)
28   %val = load i32, i32* %ptr.i32, !invariant.load !{}
29   call void @use(i32 %val)
30   br label %loop
33 define void @f_1(i8* align 4 dereferenceable_or_null(1024) %ptr) {
34 ; CHECK-LABEL: @f_1(
35 entry:
36   %ptr.gep = getelementptr i8, i8* %ptr, i32 32
37   %ptr.i32 = bitcast i8* %ptr.gep to i32*
38   %ptr_is_null = icmp eq i8* %ptr, null
39   br i1 %ptr_is_null, label %leave, label %loop
41 ; CHECK: loop.preheader:
42 ; CHECK:   %val = load i32, i32* %ptr.i32
43 ; CHECK:   br label %loop
44 ; CHECK: loop:
45 ; CHECK:  call void @use(i32 0)
46 ; CHECK-NEXT:  call void @use(i32 %val)
48 loop:
49   call void @use(i32 0)
50   %val = load i32, i32* %ptr.i32, !invariant.load !{}
51   call void @use(i32 %val)
52   br label %loop
54 leave:
55   ret void
58 define void @f_2(i8* align 4 dereferenceable_or_null(1024) %ptr) {
59 ; CHECK-LABEL: @f_2(
60 ; CHECK-NOT: load
61 ; CHECK:  call void @use(i32 0)
62 ; CHECK-NEXT:  %val = load i32, i32* %ptr.i32, !invariant.load !0
63 ; CHECK-NEXT:  call void @use(i32 %val)
65 entry:
66   ;; Can't hoist, since the alignment does not work out -- (<4 byte
67   ;; aligned> + 30) is not necessarily 4 byte aligned.
69   %ptr.gep = getelementptr i8, i8* %ptr, i32 30
70   %ptr.i32 = bitcast i8* %ptr.gep to i32*
71   %ptr_is_null = icmp eq i8* %ptr, null
72   br i1 %ptr_is_null, label %leave, label %loop
74 loop:
75   call void @use(i32 0)
76   %val = load i32, i32* %ptr.i32, !invariant.load !{}
77   call void @use(i32 %val)
78   br label %loop
80 leave:
81   ret void
84 define void @checkLaunder(i8* align 4 dereferenceable(1024) %p) {
85 ; CHECK-LABEL: @checkLaunder(
86 ; CHECK: entry:
87 ; CHECK:  %l = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
88 ; CHECK:  %val = load i8, i8* %l
89 ; CHECK:  br label %loop
90 ; CHECK: loop:
91 ; CHECK:  call void @use(i32 0)
92 ; CHECK-NEXT:  call void @use8(i8 %val)
94 entry:
95   %l = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
96   br label %loop
98 loop:
99   call void @use(i32 0)
100   %val = load i8, i8* %l, !invariant.load !{}
101   call void @use8(i8 %val)
102   br label %loop
105 declare i8* @llvm.launder.invariant.group.p0i8(i8*)
107 declare void @use8(i8)