xref: /aosp_15_r20/external/llvm/test/Transforms/LICM/hoist-deref-load.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt -S -basicaa -licm < %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker; RUN: opt -aa-pipeline=basic-aa -passes='loop-simplify,require<aa>,require<targetir>,require<scalar-evolution>,loop(simplify-cfg,licm)' -S < %s | FileCheck %s
3*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4*9880d681SAndroid Build Coastguard Workertarget triple = "x86_64-unknown-linux-gnu"
5*9880d681SAndroid Build Coastguard Worker
6*9880d681SAndroid Build Coastguard Worker; This test represents the following function:
7*9880d681SAndroid Build Coastguard Worker; void test1(int * __restrict__ a, int * __restrict__ b, int &c, int n) {
8*9880d681SAndroid Build Coastguard Worker;   for (int i = 0; i < n; ++i)
9*9880d681SAndroid Build Coastguard Worker;     if (a[i] > 0)
10*9880d681SAndroid Build Coastguard Worker;       a[i] = c*b[i];
11*9880d681SAndroid Build Coastguard Worker; }
12*9880d681SAndroid Build Coastguard Worker; and we want to hoist the load of %c out of the loop. This can be done only
13*9880d681SAndroid Build Coastguard Worker; because the dereferenceable attribute is on %c.
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test1
16*9880d681SAndroid Build Coastguard Worker; CHECK: load i32, i32* %c, align 4
17*9880d681SAndroid Build Coastguard Worker; CHECK: for.body:
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Workerdefine void @test1(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull dereferenceable(4) %c, i32 %n) #0 {
20*9880d681SAndroid Build Coastguard Workerentry:
21*9880d681SAndroid Build Coastguard Worker  %cmp11 = icmp sgt i32 %n, 0
22*9880d681SAndroid Build Coastguard Worker  br i1 %cmp11, label %for.body, label %for.end
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %entry, %for.inc
25*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
26*9880d681SAndroid Build Coastguard Worker  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
27*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %arrayidx, align 4
28*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp sgt i32 %0, 0
29*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %if.then, label %for.inc
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %for.body
32*9880d681SAndroid Build Coastguard Worker  %1 = load i32, i32* %c, align 4
33*9880d681SAndroid Build Coastguard Worker  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
34*9880d681SAndroid Build Coastguard Worker  %2 = load i32, i32* %arrayidx3, align 4
35*9880d681SAndroid Build Coastguard Worker  %mul = mul nsw i32 %2, %1
36*9880d681SAndroid Build Coastguard Worker  store i32 %mul, i32* %arrayidx, align 4
37*9880d681SAndroid Build Coastguard Worker  br label %for.inc
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Workerfor.inc:                                          ; preds = %for.body, %if.then
40*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
41*9880d681SAndroid Build Coastguard Worker  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
42*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %lftr.wideiv, %n
43*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.inc, %entry
46*9880d681SAndroid Build Coastguard Worker  ret void
47*9880d681SAndroid Build Coastguard Worker}
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Worker; This is the same as @test1, but without the dereferenceable attribute on %c.
50*9880d681SAndroid Build Coastguard Worker; Without this attribute, we should not hoist the load of %c.
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2
53*9880d681SAndroid Build Coastguard Worker; CHECK: if.then:
54*9880d681SAndroid Build Coastguard Worker; CHECK: load i32, i32* %c, align 4
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Workerdefine void @test2(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull %c, i32 %n) #0 {
57*9880d681SAndroid Build Coastguard Workerentry:
58*9880d681SAndroid Build Coastguard Worker  %cmp11 = icmp sgt i32 %n, 0
59*9880d681SAndroid Build Coastguard Worker  br i1 %cmp11, label %for.body, label %for.end
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %entry, %for.inc
62*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
63*9880d681SAndroid Build Coastguard Worker  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
64*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %arrayidx, align 4
65*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp sgt i32 %0, 0
66*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %if.then, label %for.inc
67*9880d681SAndroid Build Coastguard Worker
68*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %for.body
69*9880d681SAndroid Build Coastguard Worker  %1 = load i32, i32* %c, align 4
70*9880d681SAndroid Build Coastguard Worker  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
71*9880d681SAndroid Build Coastguard Worker  %2 = load i32, i32* %arrayidx3, align 4
72*9880d681SAndroid Build Coastguard Worker  %mul = mul nsw i32 %2, %1
73*9880d681SAndroid Build Coastguard Worker  store i32 %mul, i32* %arrayidx, align 4
74*9880d681SAndroid Build Coastguard Worker  br label %for.inc
75*9880d681SAndroid Build Coastguard Worker
76*9880d681SAndroid Build Coastguard Workerfor.inc:                                          ; preds = %for.body, %if.then
77*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
78*9880d681SAndroid Build Coastguard Worker  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
79*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %lftr.wideiv, %n
80*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.inc, %entry
83*9880d681SAndroid Build Coastguard Worker  ret void
84*9880d681SAndroid Build Coastguard Worker}
85*9880d681SAndroid Build Coastguard Worker
86*9880d681SAndroid Build Coastguard Worker; This test represents the following function:
87*9880d681SAndroid Build Coastguard Worker; void test3(int * restrict a, int * restrict b, int c[static 3], int n) {
88*9880d681SAndroid Build Coastguard Worker;   for (int i = 0; i < n; ++i)
89*9880d681SAndroid Build Coastguard Worker;     if (a[i] > 0)
90*9880d681SAndroid Build Coastguard Worker;       a[i] = c[2]*b[i];
91*9880d681SAndroid Build Coastguard Worker; }
92*9880d681SAndroid Build Coastguard Worker; and we want to hoist the load of c[2] out of the loop. This can be done only
93*9880d681SAndroid Build Coastguard Worker; because the dereferenceable attribute is on %c.
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test3
96*9880d681SAndroid Build Coastguard Worker; CHECK: load i32, i32* %c2, align 4
97*9880d681SAndroid Build Coastguard Worker; CHECK: for.body:
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Workerdefine void @test3(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly dereferenceable(12) %c, i32 %n) #0 {
100*9880d681SAndroid Build Coastguard Workerentry:
101*9880d681SAndroid Build Coastguard Worker  %cmp11 = icmp sgt i32 %n, 0
102*9880d681SAndroid Build Coastguard Worker  br i1 %cmp11, label %for.body, label %for.end
103*9880d681SAndroid Build Coastguard Worker
104*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %entry, %for.inc
105*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
106*9880d681SAndroid Build Coastguard Worker  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
107*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %arrayidx, align 4
108*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp sgt i32 %0, 0
109*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %if.then, label %for.inc
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %for.body
112*9880d681SAndroid Build Coastguard Worker  %c2 = getelementptr inbounds i32, i32* %c, i64 2
113*9880d681SAndroid Build Coastguard Worker  %1 = load i32, i32* %c2, align 4
114*9880d681SAndroid Build Coastguard Worker  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
115*9880d681SAndroid Build Coastguard Worker  %2 = load i32, i32* %arrayidx3, align 4
116*9880d681SAndroid Build Coastguard Worker  %mul = mul nsw i32 %2, %1
117*9880d681SAndroid Build Coastguard Worker  store i32 %mul, i32* %arrayidx, align 4
118*9880d681SAndroid Build Coastguard Worker  br label %for.inc
119*9880d681SAndroid Build Coastguard Worker
120*9880d681SAndroid Build Coastguard Workerfor.inc:                                          ; preds = %for.body, %if.then
121*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
122*9880d681SAndroid Build Coastguard Worker  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
123*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %lftr.wideiv, %n
124*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
125*9880d681SAndroid Build Coastguard Worker
126*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.inc, %entry
127*9880d681SAndroid Build Coastguard Worker  ret void
128*9880d681SAndroid Build Coastguard Worker}
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Worker; This is the same as @test3, but with a dereferenceable attribute on %c with a
131*9880d681SAndroid Build Coastguard Worker; size too small to cover c[2] (and so we should not hoist it).
132*9880d681SAndroid Build Coastguard Worker
133*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test4
134*9880d681SAndroid Build Coastguard Worker; CHECK: if.then:
135*9880d681SAndroid Build Coastguard Worker; CHECK: load i32, i32* %c2, align 4
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Workerdefine void @test4(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly dereferenceable(11) %c, i32 %n) #0 {
138*9880d681SAndroid Build Coastguard Workerentry:
139*9880d681SAndroid Build Coastguard Worker  %cmp11 = icmp sgt i32 %n, 0
140*9880d681SAndroid Build Coastguard Worker  br i1 %cmp11, label %for.body, label %for.end
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %entry, %for.inc
143*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
144*9880d681SAndroid Build Coastguard Worker  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
145*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %arrayidx, align 4
146*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp sgt i32 %0, 0
147*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %if.then, label %for.inc
148*9880d681SAndroid Build Coastguard Worker
149*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %for.body
150*9880d681SAndroid Build Coastguard Worker  %c2 = getelementptr inbounds i32, i32* %c, i64 2
151*9880d681SAndroid Build Coastguard Worker  %1 = load i32, i32* %c2, align 4
152*9880d681SAndroid Build Coastguard Worker  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
153*9880d681SAndroid Build Coastguard Worker  %2 = load i32, i32* %arrayidx3, align 4
154*9880d681SAndroid Build Coastguard Worker  %mul = mul nsw i32 %2, %1
155*9880d681SAndroid Build Coastguard Worker  store i32 %mul, i32* %arrayidx, align 4
156*9880d681SAndroid Build Coastguard Worker  br label %for.inc
157*9880d681SAndroid Build Coastguard Worker
158*9880d681SAndroid Build Coastguard Workerfor.inc:                                          ; preds = %for.body, %if.then
159*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
160*9880d681SAndroid Build Coastguard Worker  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
161*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %lftr.wideiv, %n
162*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.inc, %entry
165*9880d681SAndroid Build Coastguard Worker  ret void
166*9880d681SAndroid Build Coastguard Worker}
167*9880d681SAndroid Build Coastguard Worker
168*9880d681SAndroid Build Coastguard Worker; This test represents the following function:
169*9880d681SAndroid Build Coastguard Worker; void test1(int * __restrict__ a, int *b, int &c, int n) {
170*9880d681SAndroid Build Coastguard Worker;   if (c != null)
171*9880d681SAndroid Build Coastguard Worker;     for (int i = 0; i < n; ++i)
172*9880d681SAndroid Build Coastguard Worker;       if (a[i] > 0)
173*9880d681SAndroid Build Coastguard Worker;         a[i] = c*b[i];
174*9880d681SAndroid Build Coastguard Worker; }
175*9880d681SAndroid Build Coastguard Worker; and we want to hoist the load of %c out of the loop. This can be done only
176*9880d681SAndroid Build Coastguard Worker; because the dereferenceable_or_null attribute is on %c and there is a null
177*9880d681SAndroid Build Coastguard Worker; check on %c.
178*9880d681SAndroid Build Coastguard Worker
179*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test5
180*9880d681SAndroid Build Coastguard Worker; CHECK: load i32, i32* %c, align 4
181*9880d681SAndroid Build Coastguard Worker; CHECK: for.body:
182*9880d681SAndroid Build Coastguard Worker
183*9880d681SAndroid Build Coastguard Workerdefine void @test5(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 {
184*9880d681SAndroid Build Coastguard Workerentry:
185*9880d681SAndroid Build Coastguard Worker  %not_null = icmp ne i32* %c, null
186*9880d681SAndroid Build Coastguard Worker  br i1 %not_null, label %not.null, label %for.end
187*9880d681SAndroid Build Coastguard Worker
188*9880d681SAndroid Build Coastguard Workernot.null:
189*9880d681SAndroid Build Coastguard Worker  %cmp11 = icmp sgt i32 %n, 0
190*9880d681SAndroid Build Coastguard Worker  br i1 %cmp11, label %for.body, label %for.end
191*9880d681SAndroid Build Coastguard Worker
192*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %not.null, %for.inc
193*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ]
194*9880d681SAndroid Build Coastguard Worker  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
195*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %arrayidx, align 4
196*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp sgt i32 %0, 0
197*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %if.then, label %for.inc
198*9880d681SAndroid Build Coastguard Worker
199*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %for.body
200*9880d681SAndroid Build Coastguard Worker  %1 = load i32, i32* %c, align 4
201*9880d681SAndroid Build Coastguard Worker  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
202*9880d681SAndroid Build Coastguard Worker  %2 = load i32, i32* %arrayidx3, align 4
203*9880d681SAndroid Build Coastguard Worker  %mul = mul nsw i32 %2, %1
204*9880d681SAndroid Build Coastguard Worker  store i32 %mul, i32* %arrayidx, align 4
205*9880d681SAndroid Build Coastguard Worker  br label %for.inc
206*9880d681SAndroid Build Coastguard Worker
207*9880d681SAndroid Build Coastguard Workerfor.inc:                                          ; preds = %for.body, %if.then
208*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
209*9880d681SAndroid Build Coastguard Worker  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
210*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %lftr.wideiv, %n
211*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
212*9880d681SAndroid Build Coastguard Worker
213*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.inc, %entry, %not.null
214*9880d681SAndroid Build Coastguard Worker  ret void
215*9880d681SAndroid Build Coastguard Worker}
216*9880d681SAndroid Build Coastguard Worker
217*9880d681SAndroid Build Coastguard Worker; This is the same as @test5, but without the null check on %c.
218*9880d681SAndroid Build Coastguard Worker; Without this check, we should not hoist the load of %c.
219*9880d681SAndroid Build Coastguard Worker
220*9880d681SAndroid Build Coastguard Worker; This test case has an icmp on c but the use of this comparison is
221*9880d681SAndroid Build Coastguard Worker; not a branch.
222*9880d681SAndroid Build Coastguard Worker
223*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test6
224*9880d681SAndroid Build Coastguard Worker; CHECK: if.then:
225*9880d681SAndroid Build Coastguard Worker; CHECK: load i32, i32* %c, align 4
226*9880d681SAndroid Build Coastguard Worker
227*9880d681SAndroid Build Coastguard Workerdefine i1 @test6(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 {
228*9880d681SAndroid Build Coastguard Workerentry:
229*9880d681SAndroid Build Coastguard Worker  %not_null = icmp ne i32* %c, null
230*9880d681SAndroid Build Coastguard Worker  %cmp11 = icmp sgt i32 %n, 0
231*9880d681SAndroid Build Coastguard Worker  br i1 %cmp11, label %for.body, label %for.end
232*9880d681SAndroid Build Coastguard Worker
233*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %entry, %for.inc
234*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
235*9880d681SAndroid Build Coastguard Worker  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
236*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %arrayidx, align 4
237*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp sgt i32 %0, 0
238*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %if.then, label %for.inc
239*9880d681SAndroid Build Coastguard Worker
240*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %for.body
241*9880d681SAndroid Build Coastguard Worker  %1 = load i32, i32* %c, align 4
242*9880d681SAndroid Build Coastguard Worker  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
243*9880d681SAndroid Build Coastguard Worker  %2 = load i32, i32* %arrayidx3, align 4
244*9880d681SAndroid Build Coastguard Worker  %mul = mul nsw i32 %2, %1
245*9880d681SAndroid Build Coastguard Worker  store i32 %mul, i32* %arrayidx, align 4
246*9880d681SAndroid Build Coastguard Worker  br label %for.inc
247*9880d681SAndroid Build Coastguard Worker
248*9880d681SAndroid Build Coastguard Workerfor.inc:                                          ; preds = %for.body, %if.then
249*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
250*9880d681SAndroid Build Coastguard Worker  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
251*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %lftr.wideiv, %n
252*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
253*9880d681SAndroid Build Coastguard Worker
254*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.inc, %entry
255*9880d681SAndroid Build Coastguard Worker  ret i1 %not_null
256*9880d681SAndroid Build Coastguard Worker}
257*9880d681SAndroid Build Coastguard Worker
258*9880d681SAndroid Build Coastguard Worker; This test represents the following function:
259*9880d681SAndroid Build Coastguard Worker; void test1(int * __restrict__ a, int *b, int **cptr, int n) {
260*9880d681SAndroid Build Coastguard Worker;   c = *cptr;
261*9880d681SAndroid Build Coastguard Worker;   for (int i = 0; i < n; ++i)
262*9880d681SAndroid Build Coastguard Worker;     if (a[i] > 0)
263*9880d681SAndroid Build Coastguard Worker;       a[i] = (*c)*b[i];
264*9880d681SAndroid Build Coastguard Worker; }
265*9880d681SAndroid Build Coastguard Worker; and we want to hoist the load of %c out of the loop. This can be done only
266*9880d681SAndroid Build Coastguard Worker; because the dereferenceable meatdata on the c = *cptr load.
267*9880d681SAndroid Build Coastguard Worker
268*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test7
269*9880d681SAndroid Build Coastguard Worker; CHECK: load i32, i32* %c, align 4
270*9880d681SAndroid Build Coastguard Worker; CHECK: for.body:
271*9880d681SAndroid Build Coastguard Worker
272*9880d681SAndroid Build Coastguard Workerdefine void @test7(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 {
273*9880d681SAndroid Build Coastguard Workerentry:
274*9880d681SAndroid Build Coastguard Worker  %c = load i32*, i32** %cptr, !dereferenceable !0
275*9880d681SAndroid Build Coastguard Worker  %cmp11 = icmp sgt i32 %n, 0
276*9880d681SAndroid Build Coastguard Worker  br i1 %cmp11, label %for.body, label %for.end
277*9880d681SAndroid Build Coastguard Worker
278*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %entry, %for.inc
279*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
280*9880d681SAndroid Build Coastguard Worker  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
281*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %arrayidx, align 4
282*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp sgt i32 %0, 0
283*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %if.then, label %for.inc
284*9880d681SAndroid Build Coastguard Worker
285*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %for.body
286*9880d681SAndroid Build Coastguard Worker  %1 = load i32, i32* %c, align 4
287*9880d681SAndroid Build Coastguard Worker  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
288*9880d681SAndroid Build Coastguard Worker  %2 = load i32, i32* %arrayidx3, align 4
289*9880d681SAndroid Build Coastguard Worker  %mul = mul nsw i32 %2, %1
290*9880d681SAndroid Build Coastguard Worker  store i32 %mul, i32* %arrayidx, align 4
291*9880d681SAndroid Build Coastguard Worker  br label %for.inc
292*9880d681SAndroid Build Coastguard Worker
293*9880d681SAndroid Build Coastguard Workerfor.inc:                                          ; preds = %for.body, %if.then
294*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
295*9880d681SAndroid Build Coastguard Worker  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
296*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %lftr.wideiv, %n
297*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
298*9880d681SAndroid Build Coastguard Worker
299*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.inc, %entry
300*9880d681SAndroid Build Coastguard Worker  ret void
301*9880d681SAndroid Build Coastguard Worker}
302*9880d681SAndroid Build Coastguard Worker
303*9880d681SAndroid Build Coastguard Worker; This test represents the following function:
304*9880d681SAndroid Build Coastguard Worker; void test1(int * __restrict__ a, int *b, int **cptr, int n) {
305*9880d681SAndroid Build Coastguard Worker;   c = *cptr;
306*9880d681SAndroid Build Coastguard Worker;   if (c != null)
307*9880d681SAndroid Build Coastguard Worker;     for (int i = 0; i < n; ++i)
308*9880d681SAndroid Build Coastguard Worker;       if (a[i] > 0)
309*9880d681SAndroid Build Coastguard Worker;         a[i] = (*c)*b[i];
310*9880d681SAndroid Build Coastguard Worker; }
311*9880d681SAndroid Build Coastguard Worker; and we want to hoist the load of %c out of the loop. This can be done only
312*9880d681SAndroid Build Coastguard Worker; because the dereferenceable_or_null meatdata on the c = *cptr load and there
313*9880d681SAndroid Build Coastguard Worker; is a null check on %c.
314*9880d681SAndroid Build Coastguard Worker
315*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test8
316*9880d681SAndroid Build Coastguard Worker; CHECK: load i32, i32* %c, align 4
317*9880d681SAndroid Build Coastguard Worker; CHECK: for.body:
318*9880d681SAndroid Build Coastguard Worker
319*9880d681SAndroid Build Coastguard Workerdefine void @test8(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 {
320*9880d681SAndroid Build Coastguard Workerentry:
321*9880d681SAndroid Build Coastguard Worker  %c = load i32*, i32** %cptr, !dereferenceable_or_null !0
322*9880d681SAndroid Build Coastguard Worker  %not_null = icmp ne i32* %c, null
323*9880d681SAndroid Build Coastguard Worker  br i1 %not_null, label %not.null, label %for.end
324*9880d681SAndroid Build Coastguard Worker
325*9880d681SAndroid Build Coastguard Workernot.null:
326*9880d681SAndroid Build Coastguard Worker  %cmp11 = icmp sgt i32 %n, 0
327*9880d681SAndroid Build Coastguard Worker  br i1 %cmp11, label %for.body, label %for.end
328*9880d681SAndroid Build Coastguard Worker
329*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %not.null, %for.inc
330*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ]
331*9880d681SAndroid Build Coastguard Worker  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
332*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %arrayidx, align 4
333*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp sgt i32 %0, 0
334*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %if.then, label %for.inc
335*9880d681SAndroid Build Coastguard Worker
336*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %for.body
337*9880d681SAndroid Build Coastguard Worker  %1 = load i32, i32* %c, align 4
338*9880d681SAndroid Build Coastguard Worker  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
339*9880d681SAndroid Build Coastguard Worker  %2 = load i32, i32* %arrayidx3, align 4
340*9880d681SAndroid Build Coastguard Worker  %mul = mul nsw i32 %2, %1
341*9880d681SAndroid Build Coastguard Worker  store i32 %mul, i32* %arrayidx, align 4
342*9880d681SAndroid Build Coastguard Worker  br label %for.inc
343*9880d681SAndroid Build Coastguard Worker
344*9880d681SAndroid Build Coastguard Workerfor.inc:                                          ; preds = %for.body, %if.then
345*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
346*9880d681SAndroid Build Coastguard Worker  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
347*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %lftr.wideiv, %n
348*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
349*9880d681SAndroid Build Coastguard Worker
350*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.inc, %entry, %not.null
351*9880d681SAndroid Build Coastguard Worker  ret void
352*9880d681SAndroid Build Coastguard Worker}
353*9880d681SAndroid Build Coastguard Worker
354*9880d681SAndroid Build Coastguard Worker; This is the same as @test8, but without the null check on %c.
355*9880d681SAndroid Build Coastguard Worker; Without this check, we should not hoist the load of %c.
356*9880d681SAndroid Build Coastguard Worker
357*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test9
358*9880d681SAndroid Build Coastguard Worker; CHECK: if.then:
359*9880d681SAndroid Build Coastguard Worker; CHECK: load i32, i32* %c, align 4
360*9880d681SAndroid Build Coastguard Worker
361*9880d681SAndroid Build Coastguard Workerdefine void @test9(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 {
362*9880d681SAndroid Build Coastguard Workerentry:
363*9880d681SAndroid Build Coastguard Worker  %c = load i32*, i32** %cptr, !dereferenceable_or_null !0
364*9880d681SAndroid Build Coastguard Worker  %cmp11 = icmp sgt i32 %n, 0
365*9880d681SAndroid Build Coastguard Worker  br i1 %cmp11, label %for.body, label %for.end
366*9880d681SAndroid Build Coastguard Worker
367*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %entry, %for.inc
368*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
369*9880d681SAndroid Build Coastguard Worker  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
370*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %arrayidx, align 4
371*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp sgt i32 %0, 0
372*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %if.then, label %for.inc
373*9880d681SAndroid Build Coastguard Worker
374*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %for.body
375*9880d681SAndroid Build Coastguard Worker  %1 = load i32, i32* %c, align 4
376*9880d681SAndroid Build Coastguard Worker  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
377*9880d681SAndroid Build Coastguard Worker  %2 = load i32, i32* %arrayidx3, align 4
378*9880d681SAndroid Build Coastguard Worker  %mul = mul nsw i32 %2, %1
379*9880d681SAndroid Build Coastguard Worker  store i32 %mul, i32* %arrayidx, align 4
380*9880d681SAndroid Build Coastguard Worker  br label %for.inc
381*9880d681SAndroid Build Coastguard Worker
382*9880d681SAndroid Build Coastguard Workerfor.inc:                                          ; preds = %for.body, %if.then
383*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
384*9880d681SAndroid Build Coastguard Worker  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
385*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %lftr.wideiv, %n
386*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
387*9880d681SAndroid Build Coastguard Worker
388*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.inc, %entry
389*9880d681SAndroid Build Coastguard Worker  ret void
390*9880d681SAndroid Build Coastguard Worker}
391*9880d681SAndroid Build Coastguard Worker
392*9880d681SAndroid Build Coastguard Worker; In this test we should be able to only hoist load from %cptr. We can't hoist
393*9880d681SAndroid Build Coastguard Worker; load from %c because it's dereferenceability can depend on %cmp1 condition.
394*9880d681SAndroid Build Coastguard Worker; By moving it out of the loop we break this dependency and can not rely
395*9880d681SAndroid Build Coastguard Worker; on the dereferenceability anymore.
396*9880d681SAndroid Build Coastguard Worker; In other words this test checks that we strip dereferenceability  metadata
397*9880d681SAndroid Build Coastguard Worker; after hoisting an instruction.
398*9880d681SAndroid Build Coastguard Worker
399*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test10
400*9880d681SAndroid Build Coastguard Worker; CHECK: %c = load i32*, i32** %cptr
401*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dereferenceable
402*9880d681SAndroid Build Coastguard Worker; CHECK: if.then:
403*9880d681SAndroid Build Coastguard Worker; CHECK: load i32, i32* %c, align 4
404*9880d681SAndroid Build Coastguard Worker
405*9880d681SAndroid Build Coastguard Workerdefine void @test10(i32* noalias %a, i32* %b, i32** dereferenceable(8) %cptr, i32 %n) #0 {
406*9880d681SAndroid Build Coastguard Workerentry:
407*9880d681SAndroid Build Coastguard Worker  %cmp11 = icmp sgt i32 %n, 0
408*9880d681SAndroid Build Coastguard Worker  br i1 %cmp11, label %for.body, label %for.end
409*9880d681SAndroid Build Coastguard Worker
410*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %entry, %for.inc
411*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
412*9880d681SAndroid Build Coastguard Worker  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
413*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %arrayidx, align 4
414*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp sgt i32 %0, 0
415*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %if.then, label %for.inc
416*9880d681SAndroid Build Coastguard Worker
417*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %for.body
418*9880d681SAndroid Build Coastguard Worker  %c = load i32*, i32** %cptr, !dereferenceable !0
419*9880d681SAndroid Build Coastguard Worker  %1 = load i32, i32* %c, align 4
420*9880d681SAndroid Build Coastguard Worker  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
421*9880d681SAndroid Build Coastguard Worker  %2 = load i32, i32* %arrayidx3, align 4
422*9880d681SAndroid Build Coastguard Worker  %mul = mul nsw i32 %2, %1
423*9880d681SAndroid Build Coastguard Worker  store i32 %mul, i32* %arrayidx, align 4
424*9880d681SAndroid Build Coastguard Worker  br label %for.inc
425*9880d681SAndroid Build Coastguard Worker
426*9880d681SAndroid Build Coastguard Workerfor.inc:                                          ; preds = %for.body, %if.then
427*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
428*9880d681SAndroid Build Coastguard Worker  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
429*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %lftr.wideiv, %n
430*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
431*9880d681SAndroid Build Coastguard Worker
432*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.inc, %entry
433*9880d681SAndroid Build Coastguard Worker  ret void
434*9880d681SAndroid Build Coastguard Worker}
435*9880d681SAndroid Build Coastguard Worker
436*9880d681SAndroid Build Coastguard Workerdefine void @test11(i32* noalias %a, i32* %b, i32** dereferenceable(8) %cptr, i32 %n) #0 {
437*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test11(
438*9880d681SAndroid Build Coastguard Workerentry:
439*9880d681SAndroid Build Coastguard Worker  %cmp11 = icmp sgt i32 %n, 0
440*9880d681SAndroid Build Coastguard Worker  br i1 %cmp11, label %for.body, label %for.end
441*9880d681SAndroid Build Coastguard Worker
442*9880d681SAndroid Build Coastguard Worker; CHECK: for.body.preheader:
443*9880d681SAndroid Build Coastguard Worker; CHECK:  %c = load i32*, i32** %cptr, !dereferenceable !0
444*9880d681SAndroid Build Coastguard Worker; CHECK:  %d = load i32, i32* %c, align 4
445*9880d681SAndroid Build Coastguard Worker
446*9880d681SAndroid Build Coastguard Worker
447*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %entry, %for.inc
448*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
449*9880d681SAndroid Build Coastguard Worker  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
450*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %arrayidx, align 4
451*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp sgt i32 %0, 0
452*9880d681SAndroid Build Coastguard Worker  %c = load i32*, i32** %cptr, !dereferenceable !0
453*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %if.then, label %for.inc
454*9880d681SAndroid Build Coastguard Worker
455*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %for.body
456*9880d681SAndroid Build Coastguard Worker  %d = load i32, i32* %c, align 4
457*9880d681SAndroid Build Coastguard Worker  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
458*9880d681SAndroid Build Coastguard Worker  %e = load i32, i32* %arrayidx3, align 4
459*9880d681SAndroid Build Coastguard Worker  %mul = mul nsw i32 %e, %d
460*9880d681SAndroid Build Coastguard Worker  store i32 %mul, i32* %arrayidx, align 4
461*9880d681SAndroid Build Coastguard Worker  br label %for.inc
462*9880d681SAndroid Build Coastguard Worker
463*9880d681SAndroid Build Coastguard Workerfor.inc:                                          ; preds = %for.body, %if.then
464*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
465*9880d681SAndroid Build Coastguard Worker  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
466*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %lftr.wideiv, %n
467*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
468*9880d681SAndroid Build Coastguard Worker
469*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.inc, %entry
470*9880d681SAndroid Build Coastguard Worker  ret void
471*9880d681SAndroid Build Coastguard Worker}
472*9880d681SAndroid Build Coastguard Worker
473*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.experimental.guard(i1, ...)
474*9880d681SAndroid Build Coastguard Worker
475*9880d681SAndroid Build Coastguard Workerdefine void @test12(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 {
476*9880d681SAndroid Build Coastguard Worker; Prove non-null ness of %c via a guard, not a branch.
477*9880d681SAndroid Build Coastguard Worker
478*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test12(
479*9880d681SAndroid Build Coastguard Workerentry:
480*9880d681SAndroid Build Coastguard Worker  %not_null = icmp ne i32* %c, null
481*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %not_null) [ "deopt"() ]
482*9880d681SAndroid Build Coastguard Worker  %cmp11 = icmp sgt i32 %n, 0
483*9880d681SAndroid Build Coastguard Worker  br i1 %cmp11, label %for.body, label %for.end
484*9880d681SAndroid Build Coastguard Worker
485*9880d681SAndroid Build Coastguard Worker; CHECK: for.body.preheader:
486*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  [[VAL:%[^ ]]] = load i32, i32* %c, align 4
487*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  br label %for.body
488*9880d681SAndroid Build Coastguard Worker
489*9880d681SAndroid Build Coastguard Worker
490*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %entry, %for.inc
491*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
492*9880d681SAndroid Build Coastguard Worker  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
493*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %arrayidx, align 4
494*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp sgt i32 %0, 0
495*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %if.then, label %for.inc
496*9880d681SAndroid Build Coastguard Worker
497*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %for.body
498*9880d681SAndroid Build Coastguard Worker  %1 = load i32, i32* %c, align 4
499*9880d681SAndroid Build Coastguard Worker  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
500*9880d681SAndroid Build Coastguard Worker  %2 = load i32, i32* %arrayidx3, align 4
501*9880d681SAndroid Build Coastguard Worker  %mul = mul nsw i32 %2, %1
502*9880d681SAndroid Build Coastguard Worker  store i32 %mul, i32* %arrayidx, align 4
503*9880d681SAndroid Build Coastguard Worker  br label %for.inc
504*9880d681SAndroid Build Coastguard Worker
505*9880d681SAndroid Build Coastguard Workerfor.inc:                                          ; preds = %for.body, %if.then
506*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
507*9880d681SAndroid Build Coastguard Worker  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
508*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %lftr.wideiv, %n
509*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
510*9880d681SAndroid Build Coastguard Worker
511*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.inc, %entry, %entry
512*9880d681SAndroid Build Coastguard Worker  ret void
513*9880d681SAndroid Build Coastguard Worker}
514*9880d681SAndroid Build Coastguard Worker
515*9880d681SAndroid Build Coastguard Workerdefine void @test13(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 {
516*9880d681SAndroid Build Coastguard Worker; Like @test12, but has a post-dominating guard, which cannot be used
517*9880d681SAndroid Build Coastguard Worker; to prove %c is nonnull at the point of the load.
518*9880d681SAndroid Build Coastguard Worker
519*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test13(
520*9880d681SAndroid Build Coastguard Workerentry:
521*9880d681SAndroid Build Coastguard Worker  %not_null = icmp ne i32* %c, null
522*9880d681SAndroid Build Coastguard Worker  %cmp11 = icmp sgt i32 %n, 0
523*9880d681SAndroid Build Coastguard Worker  br i1 %cmp11, label %for.body, label %for.end
524*9880d681SAndroid Build Coastguard Worker
525*9880d681SAndroid Build Coastguard Worker; CHECK: for.body.preheader:
526*9880d681SAndroid Build Coastguard Worker; CHECK-NOT:  load i32, i32* %c
527*9880d681SAndroid Build Coastguard Worker; CHECK:  br label %for.body
528*9880d681SAndroid Build Coastguard Worker
529*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %entry, %for.inc
530*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
531*9880d681SAndroid Build Coastguard Worker  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
532*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %arrayidx, align 4
533*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp sgt i32 %0, 0
534*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %if.then, label %for.inc
535*9880d681SAndroid Build Coastguard Worker
536*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %for.body
537*9880d681SAndroid Build Coastguard Worker; CHECK: if.then:
538*9880d681SAndroid Build Coastguard Worker; CHECK:  load i32, i32* %c
539*9880d681SAndroid Build Coastguard Worker; CHECK:  br label %for.inc
540*9880d681SAndroid Build Coastguard Worker  %1 = load i32, i32* %c, align 4
541*9880d681SAndroid Build Coastguard Worker  %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
542*9880d681SAndroid Build Coastguard Worker  %2 = load i32, i32* %arrayidx3, align 4
543*9880d681SAndroid Build Coastguard Worker  %mul = mul nsw i32 %2, %1
544*9880d681SAndroid Build Coastguard Worker  store i32 %mul, i32* %arrayidx, align 4
545*9880d681SAndroid Build Coastguard Worker  br label %for.inc
546*9880d681SAndroid Build Coastguard Worker
547*9880d681SAndroid Build Coastguard Workerfor.inc:                                          ; preds = %for.body, %if.then
548*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
549*9880d681SAndroid Build Coastguard Worker  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
550*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %lftr.wideiv, %n
551*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
552*9880d681SAndroid Build Coastguard Worker
553*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.inc, %entry, %entry
554*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %not_null) [ "deopt"() ]
555*9880d681SAndroid Build Coastguard Worker  ret void
556*9880d681SAndroid Build Coastguard Worker}
557*9880d681SAndroid Build Coastguard Worker
558*9880d681SAndroid Build Coastguard Workerattributes #0 = { nounwind uwtable }
559*9880d681SAndroid Build Coastguard Worker!0 = !{i64 4}
560