xref: /aosp_15_r20/external/llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt -print-memderefs -analyze -S <%s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Worker; Uses the print-deref (+ analyze to print) pass to run
4*9880d681SAndroid Build Coastguard Worker; isDereferenceablePointer() on many load instruction operands
5*9880d681SAndroid Build Coastguard Worker
6*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-i32:32:64"
7*9880d681SAndroid Build Coastguard Worker
8*9880d681SAndroid Build Coastguard Worker%TypeOpaque = type opaque
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Workerdeclare zeroext i1 @return_i1()
11*9880d681SAndroid Build Coastguard Worker
12*9880d681SAndroid Build Coastguard Workerdeclare i32* @foo()
13*9880d681SAndroid Build Coastguard Worker@globalstr = global [6 x i8] c"hello\00"
14*9880d681SAndroid Build Coastguard Worker@globali32ptr = external global i32*
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Worker%struct.A = type { [8 x i8], [5 x i8] }
17*9880d681SAndroid Build Coastguard Worker@globalstruct = external global %struct.A
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Worker@globalptr.align1 = external global i8, align 1
20*9880d681SAndroid Build Coastguard Worker@globalptr.align16 = external global i8, align 16
21*9880d681SAndroid Build Coastguard Worker
22*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: 'test'
23*9880d681SAndroid Build Coastguard Workerdefine void @test(i32 addrspace(1)* dereferenceable(8) %dparam,
24*9880d681SAndroid Build Coastguard Worker                  i8 addrspace(1)* dereferenceable(32) align 1 %dparam.align1,
25*9880d681SAndroid Build Coastguard Worker                  i8 addrspace(1)* dereferenceable(32) align 16 %dparam.align16)
26*9880d681SAndroid Build Coastguard Worker    gc "statepoint-example" {
27*9880d681SAndroid Build Coastguard Worker; CHECK: The following are dereferenceable:
28*9880d681SAndroid Build Coastguard Workerentry:
29*9880d681SAndroid Build Coastguard Worker; CHECK: %globalptr{{.*}}(aligned)
30*9880d681SAndroid Build Coastguard Worker    %globalptr = getelementptr inbounds [6 x i8], [6 x i8]* @globalstr, i32 0, i32 0
31*9880d681SAndroid Build Coastguard Worker    %load1 = load i8, i8* %globalptr
32*9880d681SAndroid Build Coastguard Worker
33*9880d681SAndroid Build Coastguard Worker; CHECK: %alloca{{.*}}(aligned)
34*9880d681SAndroid Build Coastguard Worker    %alloca = alloca i1
35*9880d681SAndroid Build Coastguard Worker    %load2 = load i1, i1* %alloca
36*9880d681SAndroid Build Coastguard Worker
37*9880d681SAndroid Build Coastguard Worker; CHECK: %dparam{{.*}}(aligned)
38*9880d681SAndroid Build Coastguard Worker    %load3 = load i32, i32 addrspace(1)* %dparam
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard Worker; CHECK: %relocate{{.*}}(aligned)
41*9880d681SAndroid Build Coastguard Worker    %tok = tail call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %dparam)
42*9880d681SAndroid Build Coastguard Worker    %relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 7, i32 7)
43*9880d681SAndroid Build Coastguard Worker    %load4 = load i32, i32 addrspace(1)* %relocate
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %nparam
46*9880d681SAndroid Build Coastguard Worker    %dpa = call i32 addrspace(1)* @func1(i32 addrspace(1)* %dparam)
47*9880d681SAndroid Build Coastguard Worker    %nparam = getelementptr i32, i32 addrspace(1)* %dpa, i32 5
48*9880d681SAndroid Build Coastguard Worker    %load5 = load i32, i32 addrspace(1)* %nparam
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker    ; Load from a non-dereferenceable load
51*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %nd_load
52*9880d681SAndroid Build Coastguard Worker    %nd_load = load i32*, i32** @globali32ptr
53*9880d681SAndroid Build Coastguard Worker    %load6 = load i32, i32* %nd_load
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker    ; Load from a dereferenceable load
56*9880d681SAndroid Build Coastguard Worker; CHECK: %d4_load{{.*}}(aligned)
57*9880d681SAndroid Build Coastguard Worker    %d4_load = load i32*, i32** @globali32ptr, !dereferenceable !0
58*9880d681SAndroid Build Coastguard Worker    %load7 = load i32, i32* %d4_load
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Worker    ; Load from an offset not covered by the dereferenceable portion
61*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %d2_load
62*9880d681SAndroid Build Coastguard Worker    %d2_load = load i32*, i32** @globali32ptr, !dereferenceable !1
63*9880d681SAndroid Build Coastguard Worker    %load8 = load i32, i32* %d2_load
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Worker    ; Load from a potentially null pointer with dereferenceable_or_null
66*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %d_or_null_load
67*9880d681SAndroid Build Coastguard Worker    %d_or_null_load = load i32*, i32** @globali32ptr, !dereferenceable_or_null !0
68*9880d681SAndroid Build Coastguard Worker    %load9 = load i32, i32* %d_or_null_load
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Worker    ; Load from a non-null pointer with dereferenceable_or_null
71*9880d681SAndroid Build Coastguard Worker; CHECK: %d_or_null_non_null_load{{.*}}(aligned)
72*9880d681SAndroid Build Coastguard Worker    %d_or_null_non_null_load = load i32*, i32** @globali32ptr, !nonnull !2, !dereferenceable_or_null !0
73*9880d681SAndroid Build Coastguard Worker    %load10 = load i32, i32* %d_or_null_non_null_load
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Worker    ; It's OK to overrun static array size as long as we stay within underlying object size
76*9880d681SAndroid Build Coastguard Worker; CHECK: %within_allocation{{.*}}(aligned)
77*9880d681SAndroid Build Coastguard Worker    %within_allocation = getelementptr inbounds %struct.A, %struct.A* @globalstruct, i64 0, i32 0, i64 10
78*9880d681SAndroid Build Coastguard Worker    %load11 = load i8, i8* %within_allocation
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Worker    ; GEP is outside the underlying object size
81*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %outside_allocation
82*9880d681SAndroid Build Coastguard Worker    %outside_allocation = getelementptr inbounds %struct.A, %struct.A* @globalstruct, i64 0, i32 1, i64 10
83*9880d681SAndroid Build Coastguard Worker    %load12 = load i8, i8* %outside_allocation
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker    ; Loads from aligned globals
86*9880d681SAndroid Build Coastguard Worker; CHECK: @globalptr.align1{{.*}}(unaligned)
87*9880d681SAndroid Build Coastguard Worker; CHECK: @globalptr.align16{{.*}}(aligned)
88*9880d681SAndroid Build Coastguard Worker    %load13 = load i8, i8* @globalptr.align1, align 16
89*9880d681SAndroid Build Coastguard Worker    %load14 = load i8, i8* @globalptr.align16, align 16
90*9880d681SAndroid Build Coastguard Worker
91*9880d681SAndroid Build Coastguard Worker    ; Loads from aligned arguments
92*9880d681SAndroid Build Coastguard Worker; CHECK: %dparam.align1{{.*}}(unaligned)
93*9880d681SAndroid Build Coastguard Worker; CHECK: %dparam.align16{{.*}}(aligned)
94*9880d681SAndroid Build Coastguard Worker    %load15 = load i8, i8 addrspace(1)* %dparam.align1, align 16
95*9880d681SAndroid Build Coastguard Worker    %load16 = load i8, i8 addrspace(1)* %dparam.align16, align 16
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Worker    ; Loads from aligned allocas
98*9880d681SAndroid Build Coastguard Worker; CHECK: %alloca.align1{{.*}}(unaligned)
99*9880d681SAndroid Build Coastguard Worker; CHECK: %alloca.align16{{.*}}(aligned)
100*9880d681SAndroid Build Coastguard Worker    %alloca.align1 = alloca i1, align 1
101*9880d681SAndroid Build Coastguard Worker    %alloca.align16 = alloca i1, align 16
102*9880d681SAndroid Build Coastguard Worker    %load17 = load i1, i1* %alloca.align1, align 16
103*9880d681SAndroid Build Coastguard Worker    %load18 = load i1, i1* %alloca.align16, align 16
104*9880d681SAndroid Build Coastguard Worker
105*9880d681SAndroid Build Coastguard Worker    ; Loads from GEPs
106*9880d681SAndroid Build Coastguard Worker; CHECK: %gep.align1.offset1{{.*}}(unaligned)
107*9880d681SAndroid Build Coastguard Worker; CHECK: %gep.align16.offset1{{.*}}(unaligned)
108*9880d681SAndroid Build Coastguard Worker; CHECK: %gep.align1.offset16{{.*}}(unaligned)
109*9880d681SAndroid Build Coastguard Worker; CHECK: %gep.align16.offset16{{.*}}(aligned)
110*9880d681SAndroid Build Coastguard Worker    %gep.align1.offset1 = getelementptr inbounds i8, i8 addrspace(1)* %dparam.align1, i32 1
111*9880d681SAndroid Build Coastguard Worker    %gep.align16.offset1 = getelementptr inbounds i8, i8 addrspace(1)* %dparam.align16, i32 1
112*9880d681SAndroid Build Coastguard Worker    %gep.align1.offset16 = getelementptr inbounds i8, i8 addrspace(1)* %dparam.align1, i32 16
113*9880d681SAndroid Build Coastguard Worker    %gep.align16.offset16 = getelementptr inbounds i8, i8 addrspace(1)* %dparam.align16, i32 16
114*9880d681SAndroid Build Coastguard Worker    %load19 = load i8, i8 addrspace(1)* %gep.align1.offset1, align 16
115*9880d681SAndroid Build Coastguard Worker    %load20 = load i8, i8 addrspace(1)* %gep.align16.offset1, align 16
116*9880d681SAndroid Build Coastguard Worker    %load21 = load i8, i8 addrspace(1)* %gep.align1.offset16, align 16
117*9880d681SAndroid Build Coastguard Worker    %load22 = load i8, i8 addrspace(1)* %gep.align16.offset16, align 16
118*9880d681SAndroid Build Coastguard Worker
119*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %no_deref_return
120*9880d681SAndroid Build Coastguard Worker; CHECK: %deref_return{{.*}}(unaligned)
121*9880d681SAndroid Build Coastguard Worker; CHECK: %deref_and_aligned_return{{.*}}(aligned)
122*9880d681SAndroid Build Coastguard Worker    %no_deref_return = call i32* @foo()
123*9880d681SAndroid Build Coastguard Worker    %deref_return = call dereferenceable(32) i32* @foo()
124*9880d681SAndroid Build Coastguard Worker    %deref_and_aligned_return = call dereferenceable(32) align 16 i32* @foo()
125*9880d681SAndroid Build Coastguard Worker    %load23 = load i32, i32* %no_deref_return
126*9880d681SAndroid Build Coastguard Worker    %load24 = load i32, i32* %deref_return, align 16
127*9880d681SAndroid Build Coastguard Worker    %load25 = load i32, i32* %deref_and_aligned_return, align 16
128*9880d681SAndroid Build Coastguard Worker
129*9880d681SAndroid Build Coastguard Worker    ; Load from a dereferenceable and aligned load
130*9880d681SAndroid Build Coastguard Worker; CHECK: %d4_unaligned_load{{.*}}(unaligned)
131*9880d681SAndroid Build Coastguard Worker; CHECK: %d4_aligned_load{{.*}}(aligned)
132*9880d681SAndroid Build Coastguard Worker    %d4_unaligned_load = load i32*, i32** @globali32ptr, !dereferenceable !0
133*9880d681SAndroid Build Coastguard Worker    %d4_aligned_load = load i32*, i32** @globali32ptr, !dereferenceable !0, !align !{i64 16}
134*9880d681SAndroid Build Coastguard Worker    %load26 = load i32, i32* %d4_unaligned_load, align 16
135*9880d681SAndroid Build Coastguard Worker    %load27 = load i32, i32* %d4_aligned_load, align 16
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Worker   ; Alloca with no explicit alignment is aligned to preferred alignment of
138*9880d681SAndroid Build Coastguard Worker   ; the type (specified by datalayout string).
139*9880d681SAndroid Build Coastguard Worker; CHECK: %alloca.noalign{{.*}}(aligned)
140*9880d681SAndroid Build Coastguard Worker    %alloca.noalign = alloca i32
141*9880d681SAndroid Build Coastguard Worker    %load28 = load i32, i32* %alloca.noalign, align 8
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker    ret void
144*9880d681SAndroid Build Coastguard Worker}
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker; Just check that we don't crash.
147*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: 'opaque_type_crasher'
148*9880d681SAndroid Build Coastguard Workerdefine void @opaque_type_crasher(%TypeOpaque* dereferenceable(16) %a) {
149*9880d681SAndroid Build Coastguard Workerentry:
150*9880d681SAndroid Build Coastguard Worker  %bc = bitcast %TypeOpaque* %a to i8*
151*9880d681SAndroid Build Coastguard Worker  %ptr8 = getelementptr inbounds i8, i8* %bc, i32 8
152*9880d681SAndroid Build Coastguard Worker  %ptr32 = bitcast i8* %ptr8 to i32*
153*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %if.then, label %if.end
154*9880d681SAndroid Build Coastguard Worker
155*9880d681SAndroid Build Coastguard Workerif.then:
156*9880d681SAndroid Build Coastguard Worker  %res = load i32, i32* %ptr32, align 4
157*9880d681SAndroid Build Coastguard Worker  br label %if.end
158*9880d681SAndroid Build Coastguard Worker
159*9880d681SAndroid Build Coastguard Workerif.end:
160*9880d681SAndroid Build Coastguard Worker  ret void
161*9880d681SAndroid Build Coastguard Worker}
162*9880d681SAndroid Build Coastguard Worker
163*9880d681SAndroid Build Coastguard Workerdeclare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
164*9880d681SAndroid Build Coastguard Workerdeclare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32, i32)
165*9880d681SAndroid Build Coastguard Worker
166*9880d681SAndroid Build Coastguard Workerdeclare i32 addrspace(1)* @func1(i32 addrspace(1)* returned) nounwind argmemonly
167*9880d681SAndroid Build Coastguard Worker
168*9880d681SAndroid Build Coastguard Worker!0 = !{i64 4}
169*9880d681SAndroid Build Coastguard Worker!1 = !{i64 2}
170*9880d681SAndroid Build Coastguard Worker!2 = !{}
171