xref: /aosp_15_r20/external/llvm/test/Transforms/LoopInterchange/profitability.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -basicaa -loop-interchange -S | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker;; We test profitability model in these test cases.
3*9880d681SAndroid Build Coastguard Worker
4*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5*9880d681SAndroid Build Coastguard Workertarget triple = "x86_64-unknown-linux-gnu"
6*9880d681SAndroid Build Coastguard Worker
7*9880d681SAndroid Build Coastguard Worker@A = common global [100 x [100 x i32]] zeroinitializer
8*9880d681SAndroid Build Coastguard Worker@B = common global [100 x [100 x i32]] zeroinitializer
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker;;---------------------------------------Test case 01---------------------------------
11*9880d681SAndroid Build Coastguard Worker;; Loops interchange will result in code vectorization and hence profitable. Check for interchange.
12*9880d681SAndroid Build Coastguard Worker;;   for(int i=1;i<N;i++)
13*9880d681SAndroid Build Coastguard Worker;;     for(int j=1;j<N;j++)
14*9880d681SAndroid Build Coastguard Worker;;       A[j][i] = A[j - 1][i] + B[j][i];
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Workerdefine void @interchange_01(i32 %N) {
17*9880d681SAndroid Build Coastguard Workerentry:
18*9880d681SAndroid Build Coastguard Worker  %cmp27 = icmp sgt i32 %N, 1
19*9880d681SAndroid Build Coastguard Worker  br i1 %cmp27, label %for.cond1.preheader.lr.ph, label %for.end16
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard Workerfor.cond1.preheader.lr.ph:
22*9880d681SAndroid Build Coastguard Worker  %0 = add i32 %N, -1
23*9880d681SAndroid Build Coastguard Worker  br label %for.body3.preheader
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Workerfor.body3.preheader:
26*9880d681SAndroid Build Coastguard Worker  %indvars.iv30 = phi i64 [ 1, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next31, %for.inc14 ]
27*9880d681SAndroid Build Coastguard Worker  br label %for.body3
28*9880d681SAndroid Build Coastguard Worker
29*9880d681SAndroid Build Coastguard Workerfor.body3:
30*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ %indvars.iv.next, %for.body3 ], [ 1, %for.body3.preheader ]
31*9880d681SAndroid Build Coastguard Worker  %1 = add nsw i64 %indvars.iv, -1
32*9880d681SAndroid Build Coastguard Worker  %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %1, i64 %indvars.iv30
33*9880d681SAndroid Build Coastguard Worker  %2 = load i32, i32* %arrayidx5
34*9880d681SAndroid Build Coastguard Worker  %arrayidx9 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @B, i64 0, i64 %indvars.iv, i64 %indvars.iv30
35*9880d681SAndroid Build Coastguard Worker  %3 = load i32, i32* %arrayidx9
36*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %3, %2
37*9880d681SAndroid Build Coastguard Worker  %arrayidx13 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv, i64 %indvars.iv30
38*9880d681SAndroid Build Coastguard Worker  store i32 %add, i32* %arrayidx13
39*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
40*9880d681SAndroid Build Coastguard Worker  %lftr.wideiv = trunc i64 %indvars.iv to i32
41*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %lftr.wideiv, %0
42*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.inc14, label %for.body3
43*9880d681SAndroid Build Coastguard Worker
44*9880d681SAndroid Build Coastguard Workerfor.inc14:
45*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next31 = add nuw nsw i64 %indvars.iv30, 1
46*9880d681SAndroid Build Coastguard Worker  %lftr.wideiv32 = trunc i64 %indvars.iv30 to i32
47*9880d681SAndroid Build Coastguard Worker  %exitcond33 = icmp eq i32 %lftr.wideiv32, %0
48*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond33, label %for.end16, label %for.body3.preheader
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Workerfor.end16:
51*9880d681SAndroid Build Coastguard Worker  ret void
52*9880d681SAndroid Build Coastguard Worker}
53*9880d681SAndroid Build Coastguard Worker;; Here we are checking partial .ll to check if loop are interchanged.
54*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @interchange_01
55*9880d681SAndroid Build Coastguard Worker; CHECK:  for.body3.preheader:                              ; preds = %for.inc14, %for.cond1.preheader.lr.ph
56*9880d681SAndroid Build Coastguard Worker; CHECK:    %indvars.iv30 = phi i64 [ 1, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next31, %for.inc14 ]
57*9880d681SAndroid Build Coastguard Worker; CHECK:    br label %for.body3.split2
58*9880d681SAndroid Build Coastguard Worker
59*9880d681SAndroid Build Coastguard Worker; CHECK:  for.body3.preheader1:                             ; preds = %entry
60*9880d681SAndroid Build Coastguard Worker; CHECK:    br label %for.body3
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker; CHECK:  for.body3:                                        ; preds = %for.body3.preheader1, %for.body3.split
63*9880d681SAndroid Build Coastguard Worker; CHECK:    %indvars.iv = phi i64 [ %indvars.iv.next, %for.body3.split ], [ 1, %for.body3.preheader1 ]
64*9880d681SAndroid Build Coastguard Worker; CHECK:    br label %for.cond1.preheader.lr.ph
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Worker; CHECK:  for.body3.split2:                                 ; preds = %for.body3.preheader
67*9880d681SAndroid Build Coastguard Worker; CHECK:    %1 = add nsw i64 %indvars.iv, -1
68*9880d681SAndroid Build Coastguard Worker; CHECK:    %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %1, i64 %indvars.iv30
69*9880d681SAndroid Build Coastguard Worker; CHECK:    %2 = load i32, i32* %arrayidx5
70*9880d681SAndroid Build Coastguard Worker; CHECK:    %arrayidx9 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @B, i64 0, i64 %indvars.iv, i64 %indvars.iv30
71*9880d681SAndroid Build Coastguard Worker; CHECK:    %3 = load i32, i32* %arrayidx9
72*9880d681SAndroid Build Coastguard Worker; CHECK:    %add = add nsw i32 %3, %2
73*9880d681SAndroid Build Coastguard Worker; CHECK:    %arrayidx13 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv, i64 %indvars.iv30
74*9880d681SAndroid Build Coastguard Worker; CHECK:    store i32 %add, i32* %arrayidx13
75*9880d681SAndroid Build Coastguard Worker; CHECK:    br label %for.inc14
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker;; ---------------------------------------Test case 02---------------------------------
79*9880d681SAndroid Build Coastguard Worker;; Check loop interchange profitability model.
80*9880d681SAndroid Build Coastguard Worker;; This tests profitability model when operands of getelementpointer and not exactly the induction variable but some
81*9880d681SAndroid Build Coastguard Worker;; arithmetic operation on them.
82*9880d681SAndroid Build Coastguard Worker;;   for(int i=1;i<N;i++)
83*9880d681SAndroid Build Coastguard Worker;;    for(int j=1;j<N;j++)
84*9880d681SAndroid Build Coastguard Worker;;       A[j-1][i-1] = A[j - 1][i-1] + B[j-1][i-1];
85*9880d681SAndroid Build Coastguard Worker
86*9880d681SAndroid Build Coastguard Workerdefine void @interchange_02(i32 %N) {
87*9880d681SAndroid Build Coastguard Workerentry:
88*9880d681SAndroid Build Coastguard Worker  %cmp32 = icmp sgt i32 %N, 1
89*9880d681SAndroid Build Coastguard Worker  br i1 %cmp32, label %for.cond1.preheader.lr.ph, label %for.end21
90*9880d681SAndroid Build Coastguard Worker
91*9880d681SAndroid Build Coastguard Workerfor.cond1.preheader.lr.ph:
92*9880d681SAndroid Build Coastguard Worker  %0 = add i32 %N, -1
93*9880d681SAndroid Build Coastguard Worker  br label %for.body3.lr.ph
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Workerfor.body3.lr.ph:
96*9880d681SAndroid Build Coastguard Worker  %indvars.iv35 = phi i64 [ 1, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next36, %for.inc19 ]
97*9880d681SAndroid Build Coastguard Worker  %1 = add nsw i64 %indvars.iv35, -1
98*9880d681SAndroid Build Coastguard Worker  br label %for.body3
99*9880d681SAndroid Build Coastguard Worker
100*9880d681SAndroid Build Coastguard Workerfor.body3:
101*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ 1, %for.body3.lr.ph ], [ %indvars.iv.next, %for.body3 ]
102*9880d681SAndroid Build Coastguard Worker  %2 = add nsw i64 %indvars.iv, -1
103*9880d681SAndroid Build Coastguard Worker  %arrayidx6 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %2, i64 %1
104*9880d681SAndroid Build Coastguard Worker  %3 = load i32, i32* %arrayidx6
105*9880d681SAndroid Build Coastguard Worker  %arrayidx12 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @B, i64 0, i64 %2, i64 %1
106*9880d681SAndroid Build Coastguard Worker  %4 = load i32, i32* %arrayidx12
107*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %4, %3
108*9880d681SAndroid Build Coastguard Worker  store i32 %add, i32* %arrayidx6
109*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
110*9880d681SAndroid Build Coastguard Worker  %lftr.wideiv = trunc i64 %indvars.iv to i32
111*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %lftr.wideiv, %0
112*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.inc19, label %for.body3
113*9880d681SAndroid Build Coastguard Worker
114*9880d681SAndroid Build Coastguard Workerfor.inc19:
115*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next36 = add nuw nsw i64 %indvars.iv35, 1
116*9880d681SAndroid Build Coastguard Worker  %lftr.wideiv38 = trunc i64 %indvars.iv35 to i32
117*9880d681SAndroid Build Coastguard Worker  %exitcond39 = icmp eq i32 %lftr.wideiv38, %0
118*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond39, label %for.end21, label %for.body3.lr.ph
119*9880d681SAndroid Build Coastguard Worker
120*9880d681SAndroid Build Coastguard Workerfor.end21:
121*9880d681SAndroid Build Coastguard Worker  ret void
122*9880d681SAndroid Build Coastguard Worker}
123*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @interchange_02
124*9880d681SAndroid Build Coastguard Worker; CHECK:  for.body3.lr.ph:                                  ; preds = %for.inc19, %for.cond1.preheader.lr.ph
125*9880d681SAndroid Build Coastguard Worker; CHECK:    %indvars.iv35 = phi i64 [ 1, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next36, %for.inc19 ]
126*9880d681SAndroid Build Coastguard Worker; CHECK:    %0 = add nsw i64 %indvars.iv35, -1
127*9880d681SAndroid Build Coastguard Worker; CHECK:    br label %for.body3.split1
128*9880d681SAndroid Build Coastguard Worker
129*9880d681SAndroid Build Coastguard Worker; CHECK:  for.body3.preheader:                              ; preds = %entry
130*9880d681SAndroid Build Coastguard Worker; CHECK:    %1 = add i32 %N, -1
131*9880d681SAndroid Build Coastguard Worker; CHECK:    br label %for.body3
132*9880d681SAndroid Build Coastguard Worker
133*9880d681SAndroid Build Coastguard Worker; CHECK:  for.body3:                                        ; preds = %for.body3.preheader, %for.body3.split
134*9880d681SAndroid Build Coastguard Worker; CHECK:    %indvars.iv = phi i64 [ %indvars.iv.next, %for.body3.split ], [ 1, %for.body3.preheader ]
135*9880d681SAndroid Build Coastguard Worker; CHECK:    br label %for.cond1.preheader.lr.ph
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Worker; CHECK:  for.body3.split1:                                 ; preds = %for.body3.lr.ph
138*9880d681SAndroid Build Coastguard Worker; CHECK:    %2 = add nsw i64 %indvars.iv, -1
139*9880d681SAndroid Build Coastguard Worker; CHECK:    %arrayidx6 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %2, i64 %0
140*9880d681SAndroid Build Coastguard Worker; CHECK:    %3 = load i32, i32* %arrayidx6
141*9880d681SAndroid Build Coastguard Worker; CHECK:    %arrayidx12 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @B, i64 0, i64 %2, i64 %0
142*9880d681SAndroid Build Coastguard Worker; CHECK:    %4 = load i32, i32* %arrayidx12
143*9880d681SAndroid Build Coastguard Worker; CHECK:    %add = add nsw i32 %4, %3
144*9880d681SAndroid Build Coastguard Worker; CHECK:    store i32 %add, i32* %arrayidx6
145*9880d681SAndroid Build Coastguard Worker; CHECK:    br label %for.inc19
146*9880d681SAndroid Build Coastguard Worker
147*9880d681SAndroid Build Coastguard Worker
148*9880d681SAndroid Build Coastguard Worker;;---------------------------------------Test case 03---------------------------------
149*9880d681SAndroid Build Coastguard Worker;; Loops interchange is not profitable.
150*9880d681SAndroid Build Coastguard Worker;;   for(int i=1;i<N;i++)
151*9880d681SAndroid Build Coastguard Worker;;     for(int j=1;j<N;j++)
152*9880d681SAndroid Build Coastguard Worker;;       A[i-1][j-1] = A[i - 1][j-1] + B[i][j];
153*9880d681SAndroid Build Coastguard Worker
154*9880d681SAndroid Build Coastguard Workerdefine void @interchange_03(i32 %N){
155*9880d681SAndroid Build Coastguard Workerentry:
156*9880d681SAndroid Build Coastguard Worker  %cmp31 = icmp sgt i32 %N, 1
157*9880d681SAndroid Build Coastguard Worker  br i1 %cmp31, label %for.cond1.preheader.lr.ph, label %for.end19
158*9880d681SAndroid Build Coastguard Worker
159*9880d681SAndroid Build Coastguard Workerfor.cond1.preheader.lr.ph:
160*9880d681SAndroid Build Coastguard Worker  %0 = add i32 %N, -1
161*9880d681SAndroid Build Coastguard Worker  br label %for.body3.lr.ph
162*9880d681SAndroid Build Coastguard Worker
163*9880d681SAndroid Build Coastguard Workerfor.body3.lr.ph:
164*9880d681SAndroid Build Coastguard Worker  %indvars.iv34 = phi i64 [ 1, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next35, %for.inc17 ]
165*9880d681SAndroid Build Coastguard Worker  %1 = add nsw i64 %indvars.iv34, -1
166*9880d681SAndroid Build Coastguard Worker  br label %for.body3
167*9880d681SAndroid Build Coastguard Worker
168*9880d681SAndroid Build Coastguard Workerfor.body3:
169*9880d681SAndroid Build Coastguard Worker  %indvars.iv = phi i64 [ 1, %for.body3.lr.ph ], [ %indvars.iv.next, %for.body3 ]
170*9880d681SAndroid Build Coastguard Worker  %2 = add nsw i64 %indvars.iv, -1
171*9880d681SAndroid Build Coastguard Worker  %arrayidx6 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %1, i64 %2
172*9880d681SAndroid Build Coastguard Worker  %3 = load i32, i32* %arrayidx6
173*9880d681SAndroid Build Coastguard Worker  %arrayidx10 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @B, i64 0, i64 %indvars.iv34, i64 %indvars.iv
174*9880d681SAndroid Build Coastguard Worker  %4 = load i32, i32* %arrayidx10
175*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %4, %3
176*9880d681SAndroid Build Coastguard Worker  store i32 %add, i32* %arrayidx6
177*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
178*9880d681SAndroid Build Coastguard Worker  %lftr.wideiv = trunc i64 %indvars.iv to i32
179*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %lftr.wideiv, %0
180*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.inc17, label %for.body3
181*9880d681SAndroid Build Coastguard Worker
182*9880d681SAndroid Build Coastguard Workerfor.inc17:
183*9880d681SAndroid Build Coastguard Worker  %indvars.iv.next35 = add nuw nsw i64 %indvars.iv34, 1
184*9880d681SAndroid Build Coastguard Worker  %lftr.wideiv37 = trunc i64 %indvars.iv34 to i32
185*9880d681SAndroid Build Coastguard Worker  %exitcond38 = icmp eq i32 %lftr.wideiv37, %0
186*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond38, label %for.end19, label %for.body3.lr.ph
187*9880d681SAndroid Build Coastguard Worker
188*9880d681SAndroid Build Coastguard Workerfor.end19:
189*9880d681SAndroid Build Coastguard Worker  ret void
190*9880d681SAndroid Build Coastguard Worker}
191*9880d681SAndroid Build Coastguard Worker
192*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @interchange_03
193*9880d681SAndroid Build Coastguard Worker; CHECK:  for.body3.lr.ph:
194*9880d681SAndroid Build Coastguard Worker; CHECK:    %indvars.iv34 = phi i64 [ 1, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next35, %for.inc17 ]
195*9880d681SAndroid Build Coastguard Worker; CHECK:    %1 = add nsw i64 %indvars.iv34, -1
196*9880d681SAndroid Build Coastguard Worker; CHECK:    br label %for.body3.preheader
197*9880d681SAndroid Build Coastguard Worker; CHECK:  for.body3.preheader:
198*9880d681SAndroid Build Coastguard Worker; CHECK:    br label %for.body3
199*9880d681SAndroid Build Coastguard Worker; CHECK:  for.body3:
200*9880d681SAndroid Build Coastguard Worker; CHECK:    %indvars.iv = phi i64 [ %indvars.iv.next, %for.body3 ], [ 1, %for.body3.preheader ]
201*9880d681SAndroid Build Coastguard Worker; CHECK:    %2 = add nsw i64 %indvars.iv, -1
202*9880d681SAndroid Build Coastguard Worker; CHECK:    %arrayidx6 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %1, i64 %2
203*9880d681SAndroid Build Coastguard Worker; CHECK:    %3 = load i32, i32* %arrayidx6
204*9880d681SAndroid Build Coastguard Worker; CHECK:    %arrayidx10 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @B, i64 0, i64 %indvars.iv34, i64 %indvars.iv
205*9880d681SAndroid Build Coastguard Worker; CHECK:    %4 = load i32, i32* %arrayidx10
206