xref: /aosp_15_r20/external/llvm/test/Transforms/IndVarSimplify/loop-invariant-conditions.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt -S -indvars %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3*9880d681SAndroid Build Coastguard Workertarget triple = "x86_64-unknown-linux-gnu"
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Workerdefine void @test1(i64 %start) {
6*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test1
7*9880d681SAndroid Build Coastguard Workerentry:
8*9880d681SAndroid Build Coastguard Worker  br label %loop
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Workerloop:
11*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
12*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nsw i64 %indvars.iv, 1
13*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp slt i64 %start, -1
14*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp slt i64 %indvars.iv, -1
15*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %for.end, label %loop
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %if.end, %entry
18*9880d681SAndroid Build Coastguard Worker  ret void
19*9880d681SAndroid Build Coastguard Worker}
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard Workerdefine void @test2(i64 %start) {
22*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2
23*9880d681SAndroid Build Coastguard Workerentry:
24*9880d681SAndroid Build Coastguard Worker  br label %loop
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Workerloop:
27*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
28*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nsw i64 %indvars.iv, 1
29*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp sle i64 %start, -1
30*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp sle i64 %indvars.iv, -1
31*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %for.end, label %loop
32*9880d681SAndroid Build Coastguard Worker
33*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %if.end, %entry
34*9880d681SAndroid Build Coastguard Worker  ret void
35*9880d681SAndroid Build Coastguard Worker}
36*9880d681SAndroid Build Coastguard Worker
37*9880d681SAndroid Build Coastguard Worker; As long as the test dominates the backedge, we're good
38*9880d681SAndroid Build Coastguard Workerdefine void @test3(i64 %start) {
39*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test3
40*9880d681SAndroid Build Coastguard Workerentry:
41*9880d681SAndroid Build Coastguard Worker  br label %loop
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Workerloop:
44*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
45*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nsw i64 %indvars.iv, 1
46*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i64 %indvars.iv.next, 25
47*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %backedge, label %for.end
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Workerbackedge:
50*9880d681SAndroid Build Coastguard Worker  ; prevent flattening, needed to make sure we're testing what we intend
51*9880d681SAndroid Build Coastguard Worker  call void @foo()
52*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp slt i64 %start, -1
53*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp slt i64 %indvars.iv, -1
54*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %for.end, label %loop
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %if.end, %entry
57*9880d681SAndroid Build Coastguard Worker  ret void
58*9880d681SAndroid Build Coastguard Worker}
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Workerdefine void @test4(i64 %start) {
61*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test4
62*9880d681SAndroid Build Coastguard Workerentry:
63*9880d681SAndroid Build Coastguard Worker  br label %loop
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Workerloop:
66*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
67*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nsw i64 %indvars.iv, 1
68*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i64 %indvars.iv.next, 25
69*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %backedge, label %for.end
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard Workerbackedge:
72*9880d681SAndroid Build Coastguard Worker  ; prevent flattening, needed to make sure we're testing what we intend
73*9880d681SAndroid Build Coastguard Worker  call void @foo()
74*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp sgt i64 %start, -1
75*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp sgt i64 %indvars.iv, -1
76*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %loop, label %for.end
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %if.end, %entry
79*9880d681SAndroid Build Coastguard Worker  ret void
80*9880d681SAndroid Build Coastguard Worker}
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Workerdefine void @test5(i64 %start) {
83*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test5
84*9880d681SAndroid Build Coastguard Workerentry:
85*9880d681SAndroid Build Coastguard Worker  br label %loop
86*9880d681SAndroid Build Coastguard Worker
87*9880d681SAndroid Build Coastguard Workerloop:
88*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
89*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nuw i64 %indvars.iv, 1
90*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i64 %indvars.iv.next, 25
91*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %backedge, label %for.end
92*9880d681SAndroid Build Coastguard Worker
93*9880d681SAndroid Build Coastguard Workerbackedge:
94*9880d681SAndroid Build Coastguard Worker  ; prevent flattening, needed to make sure we're testing what we intend
95*9880d681SAndroid Build Coastguard Worker  call void @foo()
96*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp ugt i64 %start, 100
97*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp ugt i64 %indvars.iv, 100
98*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %loop, label %for.end
99*9880d681SAndroid Build Coastguard Worker
100*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %if.end, %entry
101*9880d681SAndroid Build Coastguard Worker  ret void
102*9880d681SAndroid Build Coastguard Worker}
103*9880d681SAndroid Build Coastguard Worker
104*9880d681SAndroid Build Coastguard Workerdefine void @test6(i64 %start) {
105*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test6
106*9880d681SAndroid Build Coastguard Workerentry:
107*9880d681SAndroid Build Coastguard Worker  br label %loop
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Workerloop:
110*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
111*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nuw i64 %indvars.iv, 1
112*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i64 %indvars.iv.next, 25
113*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %backedge, label %for.end
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Workerbackedge:
116*9880d681SAndroid Build Coastguard Worker  ; prevent flattening, needed to make sure we're testing what we intend
117*9880d681SAndroid Build Coastguard Worker  call void @foo()
118*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp ult i64 %start, 100
119*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp ult i64 %indvars.iv, 100
120*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %for.end, label %loop
121*9880d681SAndroid Build Coastguard Worker
122*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %if.end, %entry
123*9880d681SAndroid Build Coastguard Worker  ret void
124*9880d681SAndroid Build Coastguard Worker}
125*9880d681SAndroid Build Coastguard Worker
126*9880d681SAndroid Build Coastguard Workerdefine void @test7(i64 %start, i64* %inc_ptr) {
127*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test7
128*9880d681SAndroid Build Coastguard Workerentry:
129*9880d681SAndroid Build Coastguard Worker  %inc = load i64, i64* %inc_ptr, !range !0
130*9880d681SAndroid Build Coastguard Worker  %ok = icmp sge i64 %inc, 0
131*9880d681SAndroid Build Coastguard Worker  br i1 %ok, label %loop, label %for.end
132*9880d681SAndroid Build Coastguard Worker
133*9880d681SAndroid Build Coastguard Workerloop:
134*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
135*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nsw i64 %indvars.iv, %inc
136*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp slt i64 %start, -1
137*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp slt i64 %indvars.iv, -1
138*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %for.end, label %loop
139*9880d681SAndroid Build Coastguard Worker
140*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %if.end, %entry
141*9880d681SAndroid Build Coastguard Worker  ret void
142*9880d681SAndroid Build Coastguard Worker}
143*9880d681SAndroid Build Coastguard Worker
144*9880d681SAndroid Build Coastguard Worker!0 = !{i64 0, i64 100}
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker; Negative test - we can't show that the internal branch executes, so we can't
147*9880d681SAndroid Build Coastguard Worker; fold the test to a loop invariant one.
148*9880d681SAndroid Build Coastguard Workerdefine void @test1_neg(i64 %start) {
149*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test1_neg
150*9880d681SAndroid Build Coastguard Workerentry:
151*9880d681SAndroid Build Coastguard Worker  br label %loop
152*9880d681SAndroid Build Coastguard Worker
153*9880d681SAndroid Build Coastguard Workerloop:
154*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
155*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nsw i64 %indvars.iv, 1
156*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i64 %indvars.iv.next, 25
157*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %backedge, label %skip
158*9880d681SAndroid Build Coastguard Workerskip:
159*9880d681SAndroid Build Coastguard Worker  ; prevent flattening, needed to make sure we're testing what we intend
160*9880d681SAndroid Build Coastguard Worker  call void @foo()
161*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
162*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp slt i64 %indvars.iv, -1
163*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %for.end, label %backedge
164*9880d681SAndroid Build Coastguard Workerbackedge:
165*9880d681SAndroid Build Coastguard Worker  ; prevent flattening, needed to make sure we're testing what we intend
166*9880d681SAndroid Build Coastguard Worker  call void @foo()
167*9880d681SAndroid Build Coastguard Worker  br label %loop
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %if.end, %entry
170*9880d681SAndroid Build Coastguard Worker  ret void
171*9880d681SAndroid Build Coastguard Worker}
172*9880d681SAndroid Build Coastguard Worker
173*9880d681SAndroid Build Coastguard Worker; Slightly subtle version of @test4 where the icmp dominates the backedge,
174*9880d681SAndroid Build Coastguard Worker; but the exit branch doesn't.
175*9880d681SAndroid Build Coastguard Workerdefine void @test2_neg(i64 %start) {
176*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2_neg
177*9880d681SAndroid Build Coastguard Workerentry:
178*9880d681SAndroid Build Coastguard Worker  br label %loop
179*9880d681SAndroid Build Coastguard Worker
180*9880d681SAndroid Build Coastguard Workerloop:
181*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
182*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nsw i64 %indvars.iv, 1
183*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i64 %indvars.iv.next, 25
184*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
185*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp slt i64 %indvars.iv, -1
186*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %backedge, label %skip
187*9880d681SAndroid Build Coastguard Workerskip:
188*9880d681SAndroid Build Coastguard Worker  ; prevent flattening, needed to make sure we're testing what we intend
189*9880d681SAndroid Build Coastguard Worker  call void @foo()
190*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %for.end, label %backedge
191*9880d681SAndroid Build Coastguard Workerbackedge:
192*9880d681SAndroid Build Coastguard Worker  ; prevent flattening, needed to make sure we're testing what we intend
193*9880d681SAndroid Build Coastguard Worker  call void @foo()
194*9880d681SAndroid Build Coastguard Worker  br label %loop
195*9880d681SAndroid Build Coastguard Worker
196*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %if.end, %entry
197*9880d681SAndroid Build Coastguard Worker  ret void
198*9880d681SAndroid Build Coastguard Worker}
199*9880d681SAndroid Build Coastguard Worker
200*9880d681SAndroid Build Coastguard Worker; The branch has to exit the loop if the condition is true
201*9880d681SAndroid Build Coastguard Workerdefine void @test3_neg(i64 %start) {
202*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test3_neg
203*9880d681SAndroid Build Coastguard Workerentry:
204*9880d681SAndroid Build Coastguard Worker  br label %loop
205*9880d681SAndroid Build Coastguard Worker
206*9880d681SAndroid Build Coastguard Workerloop:
207*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
208*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nsw i64 %indvars.iv, 1
209*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
210*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp slt i64 %indvars.iv, -1
211*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %loop, label %for.end
212*9880d681SAndroid Build Coastguard Worker
213*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %if.end, %entry
214*9880d681SAndroid Build Coastguard Worker  ret void
215*9880d681SAndroid Build Coastguard Worker}
216*9880d681SAndroid Build Coastguard Worker
217*9880d681SAndroid Build Coastguard Workerdefine void @test4_neg(i64 %start) {
218*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test4_neg
219*9880d681SAndroid Build Coastguard Workerentry:
220*9880d681SAndroid Build Coastguard Worker  br label %loop
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Workerloop:
223*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
224*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nsw i64 %indvars.iv, 1
225*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i64 %indvars.iv.next, 25
226*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %backedge, label %for.end
227*9880d681SAndroid Build Coastguard Worker
228*9880d681SAndroid Build Coastguard Workerbackedge:
229*9880d681SAndroid Build Coastguard Worker  ; prevent flattening, needed to make sure we're testing what we intend
230*9880d681SAndroid Build Coastguard Worker  call void @foo()
231*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp sgt i64 %indvars.iv, -1
232*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp sgt i64 %indvars.iv, -1
233*9880d681SAndroid Build Coastguard Worker
234*9880d681SAndroid Build Coastguard Worker; %cmp1 can be made loop invariant only if the branch below goes to
235*9880d681SAndroid Build Coastguard Worker; %the header when %cmp1 is true.
236*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %for.end, label %loop
237*9880d681SAndroid Build Coastguard Worker
238*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %if.end, %entry
239*9880d681SAndroid Build Coastguard Worker  ret void
240*9880d681SAndroid Build Coastguard Worker}
241*9880d681SAndroid Build Coastguard Worker
242*9880d681SAndroid Build Coastguard Workerdefine void @test5_neg(i64 %start, i64 %inc) {
243*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test5_neg
244*9880d681SAndroid Build Coastguard Workerentry:
245*9880d681SAndroid Build Coastguard Worker  br label %loop
246*9880d681SAndroid Build Coastguard Worker
247*9880d681SAndroid Build Coastguard Workerloop:
248*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
249*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nsw i64 %indvars.iv, %inc
250*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
251*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp slt i64 %indvars.iv, -1
252*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %for.end, label %loop
253*9880d681SAndroid Build Coastguard Worker
254*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %if.end, %entry
255*9880d681SAndroid Build Coastguard Worker  ret void
256*9880d681SAndroid Build Coastguard Worker}
257*9880d681SAndroid Build Coastguard Worker
258*9880d681SAndroid Build Coastguard Workerdefine void @test8(i64 %start, i64* %inc_ptr) {
259*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test8
260*9880d681SAndroid Build Coastguard Workerentry:
261*9880d681SAndroid Build Coastguard Worker  %inc = load i64, i64* %inc_ptr, !range !1
262*9880d681SAndroid Build Coastguard Worker  %ok = icmp sge i64 %inc, 0
263*9880d681SAndroid Build Coastguard Worker  br i1 %ok, label %loop, label %for.end
264*9880d681SAndroid Build Coastguard Worker
265*9880d681SAndroid Build Coastguard Workerloop:
266*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
267*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nsw i64 %indvars.iv, %inc
268*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
269*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp slt i64 %indvars.iv, -1
270*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %for.end, label %loop
271*9880d681SAndroid Build Coastguard Worker
272*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %if.end, %entry
273*9880d681SAndroid Build Coastguard Worker  ret void
274*9880d681SAndroid Build Coastguard Worker}
275*9880d681SAndroid Build Coastguard Worker
276*9880d681SAndroid Build Coastguard Worker!1 = !{i64 -1, i64 100}
277*9880d681SAndroid Build Coastguard Worker
278*9880d681SAndroid Build Coastguard Worker
279*9880d681SAndroid Build Coastguard Workerdeclare void @foo()
280