xref: /llvm-project/llvm/test/Transforms/IndVarSimplify/dont-recompute.ll (revision 864bb84a427de367528d15270790dd152871daf2)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=indvars -S | FileCheck %s
3
4; This tests that the IV is recomputed outside of the loop even when it is known
5; to be computed by the loop and used in the loop any way, if it is cheap to do
6; so. In the example below the value can be computed outside of the loop,
7; and we should do so because after that IV is no longer used outside of
8; the loop, which is likely beneficial for vectorization.
9;
10; extern void func(unsigned val);
11;
12; void test(unsigned m)
13; {
14;   unsigned a = 0;
15;
16;   for (int i=0; i<186; i++) {
17;     a += m;
18;     func(a);
19;   }
20;
21;   func(a);
22; }
23
24declare void @func(i32)
25
26define void @test(i32 %m) nounwind uwtable {
27; CHECK-LABEL: @test(
28; CHECK-NEXT:  entry:
29; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
30; CHECK:       for.body:
31; CHECK-NEXT:    [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
32; CHECK-NEXT:    [[A_05:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
33; CHECK-NEXT:    [[ADD]] = add i32 [[A_05]], [[M:%.*]]
34; CHECK-NEXT:    tail call void @func(i32 [[ADD]])
35; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_06]], 1
36; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186
37; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]]
38; CHECK:       for.end:
39; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]
40; CHECK-NEXT:    tail call void @func(i32 [[ADD_LCSSA]])
41; CHECK-NEXT:    ret void
42;
43entry:
44  br label %for.body
45
46for.body:                                         ; preds = %for.body, %entry
47  %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
48  %a.05 = phi i32 [ 0, %entry ], [ %add, %for.body ]
49  %add = add i32 %a.05, %m
50  tail call void @func(i32 %add)
51  %inc = add nsw i32 %i.06, 1
52  %exitcond = icmp eq i32 %inc, 186
53  br i1 %exitcond, label %for.end, label %for.body
54
55for.end:                                          ; preds = %for.body
56  tail call void @func(i32 %add)
57  ret void
58}
59
60define i32 @test2(i32 %m) nounwind uwtable {
61; CHECK-LABEL: @test2(
62; CHECK-NEXT:  entry:
63; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
64; CHECK:       for.body:
65; CHECK-NEXT:    [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
66; CHECK-NEXT:    [[A_05:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
67; CHECK-NEXT:    [[ADD]] = add i32 [[A_05]], [[M:%.*]]
68; CHECK-NEXT:    tail call void @func(i32 [[ADD]])
69; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_06]], 1
70; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186
71; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]]
72; CHECK:       for.end:
73; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]
74; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]
75;
76entry:
77  br label %for.body
78
79for.body:                                         ; preds = %for.body, %entry
80  %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
81  %a.05 = phi i32 [ 0, %entry ], [ %add, %for.body ]
82  %add = add i32 %a.05, %m
83  tail call void @func(i32 %add)
84  %inc = add nsw i32 %i.06, 1
85  %exitcond = icmp eq i32 %inc, 186
86  br i1 %exitcond, label %for.end, label %for.body
87
88for.end:                                          ; preds = %for.body
89  ret i32 %add
90}
91
92define void @test3(i32 %m) nounwind uwtable {
93; CHECK-LABEL: @test3(
94; CHECK-NEXT:  entry:
95; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
96; CHECK:       for.body:
97; CHECK-NEXT:    [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
98; CHECK-NEXT:    [[A_05:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
99; CHECK-NEXT:    [[ADD]] = add i32 [[A_05]], [[M:%.*]]
100; CHECK-NEXT:    tail call void @func(i32 [[ADD]])
101; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_06]], 1
102; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186
103; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]]
104; CHECK:       for.end:
105; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]
106; CHECK-NEXT:    tail call void @func(i32 [[ADD_LCSSA]])
107; CHECK-NEXT:    ret void
108;
109entry:
110  br label %for.body
111
112for.body:                                         ; preds = %for.body, %entry
113  %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
114  %a.05 = phi i32 [ 0, %entry ], [ %add, %for.body ]
115  %add = add i32 %a.05, %m
116  mul i32 %add, 1
117  mul i32 %add, 1
118  mul i32 %add, 1
119  mul i32 %add, 1
120  mul i32 %add, 1
121  mul i32 %add, 1
122  tail call void @func(i32 %add)
123  %inc = add nsw i32 %i.06, 1
124  %exitcond = icmp eq i32 %inc, 186
125  br i1 %exitcond, label %for.end, label %for.body
126
127for.end:                                          ; preds = %for.body
128  tail call void @func(i32 %add)
129  ret void
130}
131
132define void @test4(i32 %m) nounwind uwtable {
133; CHECK-LABEL: @test4(
134; CHECK-NEXT:  entry:
135; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
136; CHECK:       for.body:
137; CHECK-NEXT:    [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
138; CHECK-NEXT:    [[A_05:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
139; CHECK-NEXT:    [[ADD]] = add i32 [[A_05]], [[M:%.*]]
140; CHECK-NEXT:    tail call void @func(i32 [[ADD]])
141; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_06]], 1
142; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186
143; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]]
144; CHECK:       for.end:
145; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]
146; CHECK-NEXT:    [[SOFT_USE:%.*]] = add i32 [[ADD_LCSSA]], 123
147; CHECK-NEXT:    tail call void @func(i32 [[SOFT_USE]])
148; CHECK-NEXT:    ret void
149;
150entry:
151  br label %for.body
152
153for.body:                                         ; preds = %for.body, %entry
154  %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
155  %a.05 = phi i32 [ 0, %entry ], [ %add, %for.body ]
156  %add = add i32 %a.05, %m
157  tail call void @func(i32 %add)
158  %inc = add nsw i32 %i.06, 1
159  %exitcond = icmp eq i32 %inc, 186
160  br i1 %exitcond, label %for.end, label %for.body
161
162for.end:                                          ; preds = %for.body
163  %soft_use = add i32 %add, 123
164  tail call void @func(i32 %soft_use)
165  ret void
166}
167
168define void @test5(i32 %m) nounwind uwtable {
169; CHECK-LABEL: @test5(
170; CHECK-NEXT:  entry:
171; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
172; CHECK:       for.body:
173; CHECK-NEXT:    [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
174; CHECK-NEXT:    [[A_05:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
175; CHECK-NEXT:    [[ADD]] = add i32 [[A_05]], [[M:%.*]]
176; CHECK-NEXT:    [[SOFT_USE:%.*]] = add i32 [[ADD]], 123
177; CHECK-NEXT:    tail call void @func(i32 [[SOFT_USE]])
178; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_06]], 1
179; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186
180; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]]
181; CHECK:       for.end:
182; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]
183; CHECK-NEXT:    tail call void @func(i32 [[ADD_LCSSA]])
184; CHECK-NEXT:    ret void
185;
186entry:
187  br label %for.body
188
189for.body:                                         ; preds = %for.body, %entry
190  %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
191  %a.05 = phi i32 [ 0, %entry ], [ %add, %for.body ]
192  %add = add i32 %a.05, %m
193  %soft_use = add i32 %add, 123
194  tail call void @func(i32 %soft_use)
195  %inc = add nsw i32 %i.06, 1
196  %exitcond = icmp eq i32 %inc, 186
197  br i1 %exitcond, label %for.end, label %for.body
198
199for.end:                                          ; preds = %for.body
200  tail call void @func(i32 %add)
201  ret void
202}
203
204define void @test6(i32 %m, ptr %p) nounwind uwtable {
205; CHECK-LABEL: @test6(
206; CHECK-NEXT:  entry:
207; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
208; CHECK:       for.body:
209; CHECK-NEXT:    [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
210; CHECK-NEXT:    [[A_05:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
211; CHECK-NEXT:    [[ADD]] = add i32 [[A_05]], [[M:%.*]]
212; CHECK-NEXT:    [[SOFT_USE:%.*]] = add i32 [[ADD]], 123
213; CHECK-NEXT:    [[PIDX:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 [[ADD]]
214; CHECK-NEXT:    store i32 [[SOFT_USE]], ptr [[PIDX]]
215; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_06]], 1
216; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186
217; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]]
218; CHECK:       for.end:
219; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]
220; CHECK-NEXT:    tail call void @func(i32 [[ADD_LCSSA]])
221; CHECK-NEXT:    ret void
222;
223entry:
224  br label %for.body
225
226for.body:                                         ; preds = %for.body, %entry
227  %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
228  %a.05 = phi i32 [ 0, %entry ], [ %add, %for.body ]
229  %add = add i32 %a.05, %m
230  %soft_use = add i32 %add, 123
231  %pidx = getelementptr i32, ptr %p, i32 %add
232  store i32 %soft_use, ptr %pidx
233  %inc = add nsw i32 %i.06, 1
234  %exitcond = icmp eq i32 %inc, 186
235  br i1 %exitcond, label %for.end, label %for.body
236
237for.end:                                          ; preds = %for.body
238  tail call void @func(i32 %add)
239  ret void
240}
241