xref: /aosp_15_r20/external/llvm/test/Transforms/IndVarSimplify/lftr-reuse.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -indvars -S | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker;
3*9880d681SAndroid Build Coastguard Worker; Make sure that indvars can perform LFTR without a canonical IV.
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
6*9880d681SAndroid Build Coastguard Worker
7*9880d681SAndroid Build Coastguard Worker; Perform LFTR using the original pointer-type IV.
8*9880d681SAndroid Build Coastguard Worker
9*9880d681SAndroid Build Coastguard Worker;  for(char* p = base; p < base + n; ++p) {
10*9880d681SAndroid Build Coastguard Worker;    *p = p-base;
11*9880d681SAndroid Build Coastguard Worker;  }
12*9880d681SAndroid Build Coastguard Workerdefine void @ptriv(i8* %base, i32 %n) nounwind {
13*9880d681SAndroid Build Coastguard Workerentry:
14*9880d681SAndroid Build Coastguard Worker  %idx.ext = sext i32 %n to i64
15*9880d681SAndroid Build Coastguard Worker  %add.ptr = getelementptr inbounds i8, i8* %base, i64 %idx.ext
16*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp ult i8* %base, %add.ptr
17*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %for.body, label %for.end
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Worker; CHECK: for.body:
20*9880d681SAndroid Build Coastguard Worker; CHECK: phi i8*
21*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: phi
22*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: add
23*9880d681SAndroid Build Coastguard Worker; CHECK: icmp ne i8*
24*9880d681SAndroid Build Coastguard Worker; CHECK: br i1
25*9880d681SAndroid Build Coastguard Workerfor.body:
26*9880d681SAndroid Build Coastguard Worker  %p.02 = phi i8* [ %base, %entry ], [ %incdec.ptr, %for.body ]
27*9880d681SAndroid Build Coastguard Worker  ; cruft to make the IV useful
28*9880d681SAndroid Build Coastguard Worker  %sub.ptr.lhs.cast = ptrtoint i8* %p.02 to i64
29*9880d681SAndroid Build Coastguard Worker  %sub.ptr.rhs.cast = ptrtoint i8* %base to i64
30*9880d681SAndroid Build Coastguard Worker  %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast
31*9880d681SAndroid Build Coastguard Worker  %conv = trunc i64 %sub.ptr.sub to i8
32*9880d681SAndroid Build Coastguard Worker  store i8 %conv, i8* %p.02
33*9880d681SAndroid Build Coastguard Worker  %incdec.ptr = getelementptr inbounds i8, i8* %p.02, i32 1
34*9880d681SAndroid Build Coastguard Worker  %cmp = icmp ult i8* %incdec.ptr, %add.ptr
35*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %for.body, label %for.end
36*9880d681SAndroid Build Coastguard Worker
37*9880d681SAndroid Build Coastguard Workerfor.end:
38*9880d681SAndroid Build Coastguard Worker  ret void
39*9880d681SAndroid Build Coastguard Worker}
40*9880d681SAndroid Build Coastguard Worker
41*9880d681SAndroid Build Coastguard Worker; This test checks that SCEVExpander can handle an outer loop that has been
42*9880d681SAndroid Build Coastguard Worker; simplified, and as a result the inner loop's exit test will be rewritten.
43*9880d681SAndroid Build Coastguard Workerdefine void @expandOuterRecurrence(i32 %arg) nounwind {
44*9880d681SAndroid Build Coastguard Workerentry:
45*9880d681SAndroid Build Coastguard Worker  %sub1 = sub nsw i32 %arg, 1
46*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp slt i32 0, %sub1
47*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %outer, label %exit
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Worker; CHECK: outer:
50*9880d681SAndroid Build Coastguard Worker; CHECK: icmp slt
51*9880d681SAndroid Build Coastguard Workerouter:
52*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ 0, %entry ], [ %i.inc, %outer.inc ]
53*9880d681SAndroid Build Coastguard Worker  %sub2 = sub nsw i32 %arg, %i
54*9880d681SAndroid Build Coastguard Worker  %sub3 = sub nsw i32 %sub2, 1
55*9880d681SAndroid Build Coastguard Worker  %cmp2 = icmp slt i32 0, %sub3
56*9880d681SAndroid Build Coastguard Worker  br i1 %cmp2, label %inner.ph, label %outer.inc
57*9880d681SAndroid Build Coastguard Worker
58*9880d681SAndroid Build Coastguard Workerinner.ph:
59*9880d681SAndroid Build Coastguard Worker  br label %inner
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker; CHECK: inner:
62*9880d681SAndroid Build Coastguard Worker; CHECK: br i1
63*9880d681SAndroid Build Coastguard Workerinner:
64*9880d681SAndroid Build Coastguard Worker  %j = phi i32 [ 0, %inner.ph ], [ %j.inc, %inner ]
65*9880d681SAndroid Build Coastguard Worker  %j.inc = add nsw i32 %j, 1
66*9880d681SAndroid Build Coastguard Worker  %cmp3 = icmp slt i32 %j.inc, %sub3
67*9880d681SAndroid Build Coastguard Worker  br i1 %cmp3, label %inner, label %outer.inc
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker; CHECK: outer.inc:
70*9880d681SAndroid Build Coastguard Worker; CHECK: icmp ne
71*9880d681SAndroid Build Coastguard Worker; CHECK: br i1
72*9880d681SAndroid Build Coastguard Workerouter.inc:
73*9880d681SAndroid Build Coastguard Worker  %i.inc = add nsw i32 %i, 1
74*9880d681SAndroid Build Coastguard Worker  %cmp4 = icmp slt i32 %i.inc, %sub1
75*9880d681SAndroid Build Coastguard Worker  br i1 %cmp4, label %outer, label %exit
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Workerexit:
78*9880d681SAndroid Build Coastguard Worker  ret void
79*9880d681SAndroid Build Coastguard Worker}
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker; Force SCEVExpander to look for an existing well-formed phi.
82*9880d681SAndroid Build Coastguard Worker; Perform LFTR without generating extra preheader code.
83*9880d681SAndroid Build Coastguard Workerdefine void @guardedloop([0 x double]* %matrix, [0 x double]* %vector,
84*9880d681SAndroid Build Coastguard Worker                         i32 %irow, i32 %ilead) nounwind {
85*9880d681SAndroid Build Coastguard Worker; CHECK: entry:
86*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: zext
87*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: add
88*9880d681SAndroid Build Coastguard Worker; CHECK: loop:
89*9880d681SAndroid Build Coastguard Worker; CHECK: phi i64
90*9880d681SAndroid Build Coastguard Worker; CHECK: phi i64
91*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: phi
92*9880d681SAndroid Build Coastguard Worker; CHECK: icmp ne
93*9880d681SAndroid Build Coastguard Worker; CHECK: br i1
94*9880d681SAndroid Build Coastguard Workerentry:
95*9880d681SAndroid Build Coastguard Worker  %cmp = icmp slt i32 1, %irow
96*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %loop, label %return
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Workerloop:
99*9880d681SAndroid Build Coastguard Worker  %rowidx = phi i32 [ 0, %entry ], [ %row.inc, %loop ]
100*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
101*9880d681SAndroid Build Coastguard Worker  %diagidx = add nsw i32 %rowidx, %i
102*9880d681SAndroid Build Coastguard Worker  %diagidxw = sext i32 %diagidx to i64
103*9880d681SAndroid Build Coastguard Worker  %matrixp = getelementptr inbounds [0 x double], [0 x double]* %matrix, i32 0, i64 %diagidxw
104*9880d681SAndroid Build Coastguard Worker  %v1 = load double, double* %matrixp
105*9880d681SAndroid Build Coastguard Worker  %iw = sext i32 %i to i64
106*9880d681SAndroid Build Coastguard Worker  %vectorp = getelementptr inbounds [0 x double], [0 x double]* %vector, i32 0, i64 %iw
107*9880d681SAndroid Build Coastguard Worker  %v2 = load double, double* %vectorp
108*9880d681SAndroid Build Coastguard Worker  %row.inc = add nsw i32 %rowidx, %ilead
109*9880d681SAndroid Build Coastguard Worker  %i.inc = add nsw i32 %i, 1
110*9880d681SAndroid Build Coastguard Worker  %cmp196 = icmp slt i32 %i.inc, %irow
111*9880d681SAndroid Build Coastguard Worker  br i1 %cmp196, label %loop, label %return
112*9880d681SAndroid Build Coastguard Worker
113*9880d681SAndroid Build Coastguard Workerreturn:
114*9880d681SAndroid Build Coastguard Worker  ret void
115*9880d681SAndroid Build Coastguard Worker}
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker; Avoid generating extra code to materialize a trip count. Skip LFTR.
118*9880d681SAndroid Build Coastguard Workerdefine void @unguardedloop([0 x double]* %matrix, [0 x double]* %vector,
119*9880d681SAndroid Build Coastguard Worker                           i32 %irow, i32 %ilead) nounwind {
120*9880d681SAndroid Build Coastguard Workerentry:
121*9880d681SAndroid Build Coastguard Worker  br label %loop
122*9880d681SAndroid Build Coastguard Worker
123*9880d681SAndroid Build Coastguard Worker; CHECK: entry:
124*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: zext
125*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: add
126*9880d681SAndroid Build Coastguard Worker; CHECK: loop:
127*9880d681SAndroid Build Coastguard Worker; CHECK: phi i64
128*9880d681SAndroid Build Coastguard Worker; CHECK: phi i64
129*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: phi
130*9880d681SAndroid Build Coastguard Worker; CHECK: icmp slt
131*9880d681SAndroid Build Coastguard Worker; CHECK: br i1
132*9880d681SAndroid Build Coastguard Workerloop:
133*9880d681SAndroid Build Coastguard Worker  %rowidx = phi i32 [ 0, %entry ], [ %row.inc, %loop ]
134*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
135*9880d681SAndroid Build Coastguard Worker  %diagidx = add nsw i32 %rowidx, %i
136*9880d681SAndroid Build Coastguard Worker  %diagidxw = sext i32 %diagidx to i64
137*9880d681SAndroid Build Coastguard Worker  %matrixp = getelementptr inbounds [0 x double], [0 x double]* %matrix, i32 0, i64 %diagidxw
138*9880d681SAndroid Build Coastguard Worker  %v1 = load double, double* %matrixp
139*9880d681SAndroid Build Coastguard Worker  %iw = sext i32 %i to i64
140*9880d681SAndroid Build Coastguard Worker  %vectorp = getelementptr inbounds [0 x double], [0 x double]* %vector, i32 0, i64 %iw
141*9880d681SAndroid Build Coastguard Worker  %v2 = load double, double* %vectorp
142*9880d681SAndroid Build Coastguard Worker  %row.inc = add nsw i32 %rowidx, %ilead
143*9880d681SAndroid Build Coastguard Worker  %i.inc = add nsw i32 %i, 1
144*9880d681SAndroid Build Coastguard Worker  %cmp196 = icmp slt i32 %i.inc, %irow
145*9880d681SAndroid Build Coastguard Worker  br i1 %cmp196, label %loop, label %return
146*9880d681SAndroid Build Coastguard Worker
147*9880d681SAndroid Build Coastguard Workerreturn:
148*9880d681SAndroid Build Coastguard Worker  ret void
149*9880d681SAndroid Build Coastguard Worker}
150*9880d681SAndroid Build Coastguard Worker
151*9880d681SAndroid Build Coastguard Worker; Remove %i which is only used by the exit test.
152*9880d681SAndroid Build Coastguard Worker; Verify that SCEV can still compute a backedge count from the sign
153*9880d681SAndroid Build Coastguard Worker; extended %n, used for pointer comparison by LFTR.
154*9880d681SAndroid Build Coastguard Worker;
155*9880d681SAndroid Build Coastguard Worker; TODO: Fix for PR13371 currently makes this impossible. See
156*9880d681SAndroid Build Coastguard Worker; IndVarSimplify.cpp hasConcreteDef(). We may want to change to undef rules.
157*9880d681SAndroid Build Coastguard Workerdefine void @geplftr(i8* %base, i32 %x, i32 %y, i32 %n) nounwind {
158*9880d681SAndroid Build Coastguard Workerentry:
159*9880d681SAndroid Build Coastguard Worker  %x.ext = sext i32 %x to i64
160*9880d681SAndroid Build Coastguard Worker  %add.ptr = getelementptr inbounds i8, i8* %base, i64 %x.ext
161*9880d681SAndroid Build Coastguard Worker  %y.ext = sext i32 %y to i64
162*9880d681SAndroid Build Coastguard Worker  %add.ptr10 = getelementptr inbounds i8, i8* %add.ptr, i64 %y.ext
163*9880d681SAndroid Build Coastguard Worker  %lim = add i32 %x, %n
164*9880d681SAndroid Build Coastguard Worker  %cmp.ph = icmp ult i32 %x, %lim
165*9880d681SAndroid Build Coastguard Worker  br i1 %cmp.ph, label %loop, label %exit
166*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @geplftr(
167*9880d681SAndroid Build Coastguard Worker; CHECK: loop:
168*9880d681SAndroid Build Coastguard Worker; CHECK: phi i8*
169*9880d681SAndroid Build Coastguard Worker; DISABLE-NOT: phi      // This check is currently disabled
170*9880d681SAndroid Build Coastguard Worker; CHECK: getelementptr
171*9880d681SAndroid Build Coastguard Worker; CHECK: store
172*9880d681SAndroid Build Coastguard Worker; DISABLE: icmp ne i8*  // This check is currently disabled
173*9880d681SAndroid Build Coastguard Worker; CHECK: br i1
174*9880d681SAndroid Build Coastguard Workerloop:
175*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ %x, %entry ], [ %inc, %loop ]
176*9880d681SAndroid Build Coastguard Worker  %aptr = phi i8* [ %add.ptr10, %entry ], [ %incdec.ptr, %loop ]
177*9880d681SAndroid Build Coastguard Worker  %incdec.ptr = getelementptr inbounds i8, i8* %aptr, i32 1
178*9880d681SAndroid Build Coastguard Worker  store i8 3, i8* %aptr
179*9880d681SAndroid Build Coastguard Worker  %inc = add i32 %i, 1
180*9880d681SAndroid Build Coastguard Worker  %cmp = icmp ult i32 %inc, %lim
181*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %loop, label %exit
182*9880d681SAndroid Build Coastguard Worker
183*9880d681SAndroid Build Coastguard Workerexit:
184*9880d681SAndroid Build Coastguard Worker  ret void
185*9880d681SAndroid Build Coastguard Worker}
186*9880d681SAndroid Build Coastguard Worker
187*9880d681SAndroid Build Coastguard Worker; Exercise backedge taken count verification with a never-taken loop.
188*9880d681SAndroid Build Coastguard Workerdefine void @nevertaken() nounwind uwtable ssp {
189*9880d681SAndroid Build Coastguard Workerentry:
190*9880d681SAndroid Build Coastguard Worker  br label %loop
191*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @nevertaken(
192*9880d681SAndroid Build Coastguard Worker; CHECK: loop:
193*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: phi
194*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: add
195*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: icmp
196*9880d681SAndroid Build Coastguard Worker; CHECK: exit:
197*9880d681SAndroid Build Coastguard Workerloop:
198*9880d681SAndroid Build Coastguard Worker  %i = phi i32 [ 0, %entry ], [ %inc, %loop ]
199*9880d681SAndroid Build Coastguard Worker  %inc = add nsw i32 %i, 1
200*9880d681SAndroid Build Coastguard Worker  %cmp = icmp sle i32 %inc, 0
201*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %loop, label %exit
202*9880d681SAndroid Build Coastguard Worker
203*9880d681SAndroid Build Coastguard Workerexit:
204*9880d681SAndroid Build Coastguard Worker  ret void
205*9880d681SAndroid Build Coastguard Worker}
206*9880d681SAndroid Build Coastguard Worker
207*9880d681SAndroid Build Coastguard Worker; Test LFTR on an IV whose recurrence start is a non-unit pointer type.
208*9880d681SAndroid Build Coastguard Workerdefine void @aryptriv([256 x i8]* %base, i32 %n) nounwind {
209*9880d681SAndroid Build Coastguard Workerentry:
210*9880d681SAndroid Build Coastguard Worker  %ivstart = getelementptr inbounds [256 x i8], [256 x i8]* %base, i32 0, i32 0
211*9880d681SAndroid Build Coastguard Worker  %ivend = getelementptr inbounds [256 x i8], [256 x i8]* %base, i32 0, i32 %n
212*9880d681SAndroid Build Coastguard Worker  %cmp.ph = icmp ult i8* %ivstart, %ivend
213*9880d681SAndroid Build Coastguard Worker  br i1 %cmp.ph, label %loop, label %exit
214*9880d681SAndroid Build Coastguard Worker
215*9880d681SAndroid Build Coastguard Worker; CHECK: loop:
216*9880d681SAndroid Build Coastguard Worker; CHECK: phi i8*
217*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: phi
218*9880d681SAndroid Build Coastguard Worker; CHECK: getelementptr
219*9880d681SAndroid Build Coastguard Worker; CHECK: store
220*9880d681SAndroid Build Coastguard Worker; CHECK: icmp ne i8*
221*9880d681SAndroid Build Coastguard Worker; CHECK: br i1
222*9880d681SAndroid Build Coastguard Workerloop:
223*9880d681SAndroid Build Coastguard Worker  %aptr = phi i8* [ %ivstart, %entry ], [ %incdec.ptr, %loop ]
224*9880d681SAndroid Build Coastguard Worker  %incdec.ptr = getelementptr inbounds i8, i8* %aptr, i32 1
225*9880d681SAndroid Build Coastguard Worker  store i8 3, i8* %aptr
226*9880d681SAndroid Build Coastguard Worker  %cmp = icmp ult i8* %incdec.ptr, %ivend
227*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %loop, label %exit
228*9880d681SAndroid Build Coastguard Worker
229*9880d681SAndroid Build Coastguard Workerexit:
230*9880d681SAndroid Build Coastguard Worker  ret void
231*9880d681SAndroid Build Coastguard Worker}
232