[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Analysis / ValueTracking / deref-bitcast-of-gep.ll
blob8d5dc6a878681b923753ad39f9249e590e8778b0
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -licm < %s | FileCheck %s
4 ; Note: the !invariant.load is there just solely to let us call @use()
5 ; to add a fake use, and still have the aliasing work out.  The call
6 ; to @use(0) is just to provide a may-unwind exit out of the loop, so
7 ; that LICM cannot hoist out the load simply because it is guaranteed
8 ; to execute.
10 declare void @use(i32)
12 define void @f_0(i8* align 4 dereferenceable(1024) %ptr) nofree nosync {
13 ; CHECK-LABEL: @f_0(
14 ; CHECK-NEXT:  entry:
15 ; CHECK-NEXT:    [[PTR_GEP:%.*]] = getelementptr i8, i8* [[PTR:%.*]], i32 32
16 ; CHECK-NEXT:    [[PTR_I32:%.*]] = bitcast i8* [[PTR_GEP]] to i32*
17 ; CHECK-NEXT:    [[VAL:%.*]] = load i32, i32* [[PTR_I32]], align 4
18 ; CHECK-NEXT:    br label [[LOOP:%.*]]
19 ; CHECK:       loop:
20 ; CHECK-NEXT:    call void @use(i32 0)
21 ; CHECK-NEXT:    call void @use(i32 [[VAL]])
22 ; CHECK-NEXT:    br label [[LOOP]]
26 entry:
27   %ptr.gep = getelementptr i8, i8* %ptr, i32 32
28   %ptr.i32 = bitcast i8* %ptr.gep to i32*
29   br label %loop
31 loop:
32   call void @use(i32 0)
33   %val = load i32, i32* %ptr.i32, !invariant.load !{}
34   call void @use(i32 %val)
35   br label %loop
38 define void @f_1(i8* align 4 dereferenceable_or_null(1024) %ptr) nofree nosync {
39 ; CHECK-LABEL: @f_1(
40 ; CHECK-NEXT:  entry:
41 ; CHECK-NEXT:    [[PTR_GEP:%.*]] = getelementptr i8, i8* [[PTR:%.*]], i32 32
42 ; CHECK-NEXT:    [[PTR_I32:%.*]] = bitcast i8* [[PTR_GEP]] to i32*
43 ; CHECK-NEXT:    [[PTR_IS_NULL:%.*]] = icmp eq i8* [[PTR]], null
44 ; CHECK-NEXT:    br i1 [[PTR_IS_NULL]], label [[LEAVE:%.*]], label [[LOOP_PREHEADER:%.*]]
45 ; CHECK:       loop.preheader:
46 ; CHECK-NEXT:    [[VAL:%.*]] = load i32, i32* [[PTR_I32]], align 4
47 ; CHECK-NEXT:    br label [[LOOP:%.*]]
48 ; CHECK:       loop:
49 ; CHECK-NEXT:    call void @use(i32 0)
50 ; CHECK-NEXT:    call void @use(i32 [[VAL]])
51 ; CHECK-NEXT:    br label [[LOOP]]
52 ; CHECK:       leave:
53 ; CHECK-NEXT:    ret void
55 entry:
56   %ptr.gep = getelementptr i8, i8* %ptr, i32 32
57   %ptr.i32 = bitcast i8* %ptr.gep to i32*
58   %ptr_is_null = icmp eq i8* %ptr, null
59   br i1 %ptr_is_null, label %leave, label %loop
62 loop:
63   call void @use(i32 0)
64   %val = load i32, i32* %ptr.i32, !invariant.load !{}
65   call void @use(i32 %val)
66   br label %loop
68 leave:
69   ret void
72 define void @f_2(i8* align 4 dereferenceable_or_null(1024) %ptr) {
73 ; CHECK-LABEL: @f_2(
74 ; CHECK-NEXT:  entry:
75 ; CHECK-NEXT:    [[PTR_GEP:%.*]] = getelementptr i8, i8* [[PTR:%.*]], i32 30
76 ; CHECK-NEXT:    [[PTR_I32:%.*]] = bitcast i8* [[PTR_GEP]] to i32*
77 ; CHECK-NEXT:    [[PTR_IS_NULL:%.*]] = icmp eq i8* [[PTR]], null
78 ; CHECK-NEXT:    br i1 [[PTR_IS_NULL]], label [[LEAVE:%.*]], label [[LOOP_PREHEADER:%.*]]
79 ; CHECK:       loop.preheader:
80 ; CHECK-NEXT:    br label [[LOOP:%.*]]
81 ; CHECK:       loop:
82 ; CHECK-NEXT:    call void @use(i32 0)
83 ; CHECK-NEXT:    [[VAL:%.*]] = load i32, i32* [[PTR_I32]], align 4, !invariant.load !0
84 ; CHECK-NEXT:    call void @use(i32 [[VAL]])
85 ; CHECK-NEXT:    br label [[LOOP]]
86 ; CHECK:       leave:
87 ; CHECK-NEXT:    ret void
90 entry:
91   ;; Can't hoist, since the alignment does not work out -- (<4 byte
92   ;; aligned> + 30) is not necessarily 4 byte aligned.
94   %ptr.gep = getelementptr i8, i8* %ptr, i32 30
95   %ptr.i32 = bitcast i8* %ptr.gep to i32*
96   %ptr_is_null = icmp eq i8* %ptr, null
97   br i1 %ptr_is_null, label %leave, label %loop
99 loop:
100   call void @use(i32 0)
101   %val = load i32, i32* %ptr.i32, !invariant.load !{}
102   call void @use(i32 %val)
103   br label %loop
105 leave:
106   ret void
109 define void @checkLaunder(i8* align 4 dereferenceable(1024) %p) nofree nosync {
110 ; CHECK-LABEL: @checkLaunder(
111 ; CHECK-NEXT:  entry:
112 ; CHECK-NEXT:    [[L:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* [[P:%.*]])
113 ; CHECK-NEXT:    [[VAL:%.*]] = load i8, i8* [[L]], align 1
114 ; CHECK-NEXT:    br label [[LOOP:%.*]]
115 ; CHECK:       loop:
116 ; CHECK-NEXT:    call void @use(i32 0)
117 ; CHECK-NEXT:    call void @use8(i8 [[VAL]])
118 ; CHECK-NEXT:    br label [[LOOP]]
121 entry:
122   %l = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
123   br label %loop
125 loop:
126   call void @use(i32 0)
127   %val = load i8, i8* %l, !invariant.load !{}
128   call void @use8(i8 %val)
129   br label %loop
132 declare i8* @llvm.launder.invariant.group.p0i8(i8*)
134 declare void @use8(i8)