1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/**
18 * Tests for zero vectorization.
19 */
20public class Main {
21
22  /// CHECK-START: void Main.staticallyAligned(int[]) loop_optimization (before)
23  /// CHECK-DAG: <<Par:l\d+>>   ParameterValue                       loop:none
24  /// CHECK-DAG: <<One:i\d+>>   IntConstant 1                        loop:none
25  /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<One>>,<<AddI:i\d+>>]          loop:<<Loop:B\d+>> outer_loop:none
26  /// CHECK-DAG: <<Get:i\d+>>   ArrayGet [<<Par>>,<<Phi>>]           loop:<<Loop>>      outer_loop:none
27  /// CHECK-DAG: <<Add:i\d+>>   Add [<<Get>>,<<One>>]                loop:<<Loop>>      outer_loop:none
28  /// CHECK-DAG:                ArraySet [<<Par>>,<<Phi>>,<<Add>>]   loop:<<Loop>>      outer_loop:none
29  /// CHECK-DAG: <<AddI>>       Add [<<Phi>>,<<One>>]                loop:<<Loop>>      outer_loop:none
30  //
31  /// CHECK-START-ARM: void Main.staticallyAligned(int[]) loop_optimization (after)
32  /// CHECK-DAG: <<Par:l\d+>>   ParameterValue                       loop:none
33  /// CHECK-DAG: <<Zero:i\d+>>  IntConstant 0                        loop:none
34  /// CHECK-DAG: <<One:i\d+>>   IntConstant 1                        loop:none
35  /// CHECK-DAG: <<Vl:i\d+>>    IntConstant 2                        loop:none
36  /// CHECK-DAG: <<Repl:d\d+>>  VecReplicateScalar [<<One>>]         loop:none
37  /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<Zero>>,<<AddI:i\d+>>]                            loop:<<Loop:B\d+>> outer_loop:none
38  /// CHECK-DAG: <<Nrm:i\d+>>   Add [<<Phi>>,<<One>>]                                   loop:<<Loop>>      outer_loop:none
39  /// CHECK-DAG: <<Load:d\d+>>  VecLoad [<<Par>>,<<Nrm>>]          alignment:ALIGN(8,0) loop:<<Loop>>      outer_loop:none
40  /// CHECK-DAG: <<Add:d\d+>>   VecAdd [<<Load>>,<<Repl>>]                              loop:<<Loop>>      outer_loop:none
41  /// CHECK-DAG:                VecStore [<<Par>>,<<Nrm>>,<<Add>>] alignment:ALIGN(8,0) loop:<<Loop>>      outer_loop:none
42  /// CHECK-DAG: <<AddI>>       Add [<<Phi>>,<<Vl>>]                                    loop:<<Loop>>      outer_loop:none
43  //
44  /// CHECK-NOT:                ArrayGet
45  /// CHECK-NOT:                ArraySet
46  static void staticallyAligned(int[] a) {
47    // Starts at offset 12 (hidden) + 1 * 4 relative to base alignment.
48    // So no peeling, aligned vector, no cleanup.
49    for (int i = 1; i < 9; i++) {
50      a[i] += 1;
51    }
52  }
53
54  /// CHECK-START: void Main.staticallyAlignedN(int[]) loop_optimization (before)
55  /// CHECK-DAG: <<One:i\d+>>   IntConstant 1                        loop:none
56  /// CHECK-DAG: <<Par:l\d+>>   NullCheck                            loop:none
57  /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<One>>,<<AddI:i\d+>>]          loop:<<Loop:B\d+>> outer_loop:none
58  /// CHECK-DAG: <<Get:i\d+>>   ArrayGet [<<Par>>,<<Phi>>]           loop:<<Loop>>      outer_loop:none
59  /// CHECK-DAG: <<Add:i\d+>>   Add [<<Get>>,<<One>>]                loop:<<Loop>>      outer_loop:none
60  /// CHECK-DAG:                ArraySet [<<Par>>,<<Phi>>,<<Add>>]   loop:<<Loop>>      outer_loop:none
61  /// CHECK-DAG: <<AddI>>       Add [<<Phi>>,<<One>>]                loop:<<Loop>>      outer_loop:none
62  //
63  /// CHECK-START-ARM: void Main.staticallyAlignedN(int[]) loop_optimization (after)
64  /// CHECK-DAG: <<Zero:i\d+>>  IntConstant 0                        loop:none
65  /// CHECK-DAG: <<One:i\d+>>   IntConstant 1                        loop:none
66  /// CHECK-DAG: <<Vl:i\d+>>    IntConstant 2                        loop:none
67  /// CHECK-DAG: <<Par:l\d+>>   NullCheck                            loop:none
68  /// CHECK-DAG: <<Repl:d\d+>>  VecReplicateScalar [<<One>>]         loop:none
69  /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<Zero>>,<<AddI:i\d+>>]                            loop:<<Loop:B\d+>> outer_loop:none
70  /// CHECK-DAG: <<Nrm:i\d+>>   Add [<<Phi>>,<<One>>]                                   loop:<<Loop>>      outer_loop:none
71  /// CHECK-DAG: <<Load:d\d+>>  VecLoad [<<Par>>,<<Nrm>>]          alignment:ALIGN(8,0) loop:<<Loop>>      outer_loop:none
72  /// CHECK-DAG: <<Add:d\d+>>   VecAdd [<<Load>>,<<Repl>>]                              loop:<<Loop>>      outer_loop:none
73  /// CHECK-DAG:                VecStore [<<Par>>,<<Nrm>>,<<Add>>] alignment:ALIGN(8,0) loop:<<Loop>>      outer_loop:none
74  /// CHECK-DAG: <<AddI>>       Add [<<Phi>>,<<Vl>>]                                    loop:<<Loop>>      outer_loop:none
75  /// CHECK-DAG: <<PhiC:i\d+>>  Phi [<<Phi>>,<<AddIC:i\d+>>]         loop:<<Clean:B\d+>> outer_loop:none
76  /// CHECK-DAG: <<NrmC:i\d+>>  Add [<<PhiC>>,<<One>>]               loop:<<Clean>>      outer_loop:none
77  /// CHECK-DAG: <<Get:i\d+>>   ArrayGet [<<Par>>,<<NrmC>>]          loop:<<Clean>>      outer_loop:none
78  /// CHECK-DAG: <<AddC:i\d+>>  Add [<<Get>>,<<One>>]                loop:<<Clean>>      outer_loop:none
79  /// CHECK-DAG:                ArraySet [<<Par>>,<<NrmC>>,<<AddC>>] loop:<<Clean>>      outer_loop:none
80  /// CHECK-DAG: <<AddIC>>      Add [<<PhiC>>,<<One>>]               loop:<<Clean>>      outer_loop:none
81  static void staticallyAlignedN(int[] a) {
82    // Starts at offset 12 (hidden) + 1 * 4 relative to base alignment.
83    // So no peeling, aligned vector, cleanup.
84    for (int i = 1; i < a.length; i++) {
85      a[i] += 1;
86    }
87  }
88
89  /// CHECK-START: void Main.staticallyMisaligned(int[]) loop_optimization (before)
90  /// CHECK-DAG: <<Par:l\d+>>   ParameterValue                       loop:none
91  /// CHECK-DAG: <<Zero:i\d+>>  IntConstant 0                        loop:none
92  /// CHECK-DAG: <<One:i\d+>>   IntConstant 1                        loop:none
93  /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<Zero>>,<<AddI:i\d+>>]         loop:<<Loop:B\d+>> outer_loop:none
94  /// CHECK-DAG: <<Get:i\d+>>   ArrayGet [<<Par>>,<<Phi>>]           loop:<<Loop>>      outer_loop:none
95  /// CHECK-DAG: <<Add:i\d+>>   Add [<<Get>>,<<One>>]                loop:<<Loop>>      outer_loop:none
96  /// CHECK-DAG:                ArraySet [<<Par>>,<<Phi>>,<<Add>>]   loop:<<Loop>>      outer_loop:none
97  /// CHECK-DAG: <<AddI>>       Add [<<Phi>>,<<One>>]                loop:<<Loop>>      outer_loop:none
98  //
99  /// CHECK-START-ARM: void Main.staticallyMisaligned(int[]) loop_optimization (after)
100  /// CHECK-DAG: <<Par:l\d+>>   ParameterValue                       loop:none
101  /// CHECK-DAG: <<Zero:i\d+>>  IntConstant 0                        loop:none
102  /// CHECK-DAG: <<One:i\d+>>   IntConstant 1                        loop:none
103  /// CHECK-DAG: <<Vl:i\d+>>    IntConstant 2                        loop:none
104  /// CHECK-DAG: <<PhiP:i\d+>>  Phi [<<Zero>>,<<AddIP:i\d+>>]        loop:<<Peel:B\d+>> outer_loop:none
105  /// CHECK-DAG: <<Get:i\d+>>   ArrayGet [<<Par>>,<<PhiP>>]          loop:<<Peel>>      outer_loop:none
106  /// CHECK-DAG: <<AddP:i\d+>>  Add [<<Get>>,<<One>>]                loop:<<Peel>>      outer_loop:none
107  /// CHECK-DAG:                ArraySet [<<Par>>,<<PhiP>>,<<AddP>>] loop:<<Peel>>      outer_loop:none
108  /// CHECK-DAG: <<AddIP>>      Add [<<PhiP>>,<<One>>]               loop:<<Peel>>      outer_loop:none
109  /// CHECK-DAG: <<Repl:d\d+>>  VecReplicateScalar [<<One>>]         loop:none
110  /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<PhiP>>,<<AddI:i\d+>>]                            loop:<<Loop:B\d+>> outer_loop:none
111  /// CHECK-DAG: <<Load:d\d+>>  VecLoad [<<Par>>,<<Phi>>]          alignment:ALIGN(8,0) loop:<<Loop>>      outer_loop:none
112  /// CHECK-DAG: <<Add:d\d+>>   VecAdd [<<Load>>,<<Repl>>]                              loop:<<Loop>>      outer_loop:none
113  /// CHECK-DAG:                VecStore [<<Par>>,<<Phi>>,<<Add>>] alignment:ALIGN(8,0) loop:<<Loop>>      outer_loop:none
114  /// CHECK-DAG: <<AddI>>       Add [<<Phi>>,<<Vl>>]                                    loop:<<Loop>>      outer_loop:none
115  //
116  /// CHECK-NOT:                ArrayGet
117  /// CHECK-NOT:                ArraySet
118  static void staticallyMisaligned(int[] a) {
119    // Starts at offset 12 (hidden) + 0 * 4 relative to base alignment.
120    // Yes, Art runtime misaligns the most common access pattern :-(
121    // Static peeling to the rescue, aligned vector, no cleanup.
122    for (int i = 0; i < 9; i++) {
123      a[i] += 1;
124    }
125  }
126
127  /// CHECK-START: void Main.staticallyMisalignedN(int[]) loop_optimization (before)
128  /// CHECK-DAG: <<Zero:i\d+>>  IntConstant 0                       loop:none
129  /// CHECK-DAG: <<One:i\d+>>   IntConstant 1                       loop:none
130  /// CHECK-DAG: <<Par:l\d+>>   NullCheck                           loop:none
131  /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<Zero>>,<<AddI:i\d+>>]        loop:<<Loop:B\d+>> outer_loop:none
132  /// CHECK-DAG: <<Get:i\d+>>   ArrayGet [<<Par>>,<<Phi>>]          loop:<<Loop>>      outer_loop:none
133  /// CHECK-DAG: <<Add:i\d+>>   Add [<<Get>>,<<One>>]               loop:<<Loop>>      outer_loop:none
134  /// CHECK-DAG:                ArraySet [<<Par>>,<<Phi>>,<<Add>>]  loop:<<Loop>>      outer_loop:none
135  /// CHECK-DAG: <<AddI>>       Add [<<Phi>>,<<One>>]               loop:<<Loop>>      outer_loop:none
136  //
137  /// CHECK-START-ARM: void Main.staticallyMisalignedN(int[]) loop_optimization (after)
138  /// CHECK-DAG: <<Zero:i\d+>>  IntConstant 0                        loop:none
139  /// CHECK-DAG: <<One:i\d+>>   IntConstant 1                        loop:none
140  /// CHECK-DAG: <<Vl:i\d+>>    IntConstant 2                        loop:none
141  /// CHECK-DAG: <<Par:l\d+>>   NullCheck                            loop:none
142  /// CHECK-DAG: <<PhiP:i\d+>>  Phi [<<Zero>>,<<AddIP:i\d+>>]        loop:<<Peel:B\d+>> outer_loop:none
143  /// CHECK-DAG: <<GetP:i\d+>>  ArrayGet [<<Par>>,<<PhiP>>]          loop:<<Peel>>      outer_loop:none
144  /// CHECK-DAG: <<AddP:i\d+>>  Add [<<GetP>>,<<One>>]               loop:<<Peel>>      outer_loop:none
145  /// CHECK-DAG:                ArraySet [<<Par>>,<<PhiP>>,<<AddP>>] loop:<<Peel>>      outer_loop:none
146  /// CHECK-DAG: <<AddIP>>      Add [<<PhiP>>,<<One>>]               loop:<<Peel>>      outer_loop:none
147  /// CHECK-DAG: <<Repl:d\d+>>  VecReplicateScalar [<<One>>]         loop:none
148  /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<PhiP>>,<<AddI:i\d+>>]                            loop:<<Loop:B\d+>> outer_loop:none
149  /// CHECK-DAG: <<Load:d\d+>>  VecLoad [<<Par>>,<<Phi>>]          alignment:ALIGN(8,0) loop:<<Loop>>      outer_loop:none
150  /// CHECK-DAG: <<Add:d\d+>>   VecAdd [<<Load>>,<<Repl>>]                              loop:<<Loop>>      outer_loop:none
151  /// CHECK-DAG:                VecStore [<<Par>>,<<Phi>>,<<Add>>] alignment:ALIGN(8,0) loop:<<Loop>>      outer_loop:none
152  /// CHECK-DAG: <<AddI>>       Add [<<Phi>>,<<Vl>>]                                    loop:<<Loop>>      outer_loop:none
153  /// CHECK-DAG: <<PhiC:i\d+>>  Phi [<<Phi>>,<<AddIC:i\d+>>]         loop:<<Clean:B\d+>> outer_loop:none
154  /// CHECK-DAG: <<GetC:i\d+>>  ArrayGet [<<Par>>,<<PhiC>>]          loop:<<Clean>>      outer_loop:none
155  /// CHECK-DAG: <<AddC:i\d+>>  Add [<<GetC>>,<<One>>]               loop:<<Clean>>      outer_loop:none
156  /// CHECK-DAG:                ArraySet [<<Par>>,<<PhiC>>,<<AddC>>] loop:<<Clean>>      outer_loop:none
157  /// CHECK-DAG: <<AddIC>>      Add [<<PhiC>>,<<One>>]               loop:<<Clean>>      outer_loop:none
158  static void staticallyMisalignedN(int[] a) {
159    // Starts at offset 12 (hidden) + 0 * 4 relative to base alignment.
160    // Yes, Art runtime misaligns the most common access pattern :-(
161    // Static peeling to the rescue, aligned vector, cleanup.
162    for (int i = 0; i < a.length; i++) {
163      a[i] += 1;
164    }
165  }
166
167  /// CHECK-START: void Main.staticallyUnknownAligned(int[], int) loop_optimization (before)
168  /// CHECK-DAG: <<Par:l\d+>>   ParameterValue                       loop:none
169  /// CHECK-DAG: <<Off:i\d+>>   ParameterValue                       loop:none
170  /// CHECK-DAG: <<Zero:i\d+>>  IntConstant 0                        loop:none
171  /// CHECK-DAG: <<One:i\d+>>   IntConstant 1                        loop:none
172  /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<Zero>>,<<AddI:i\d+>>]         loop:<<Loop:B\d+>> outer_loop:none
173  /// CHECK-DAG: <<Nrm:i\d+>>   Add [<<Off>>,<<Phi>>]                loop:<<Loop>>      outer_loop:none
174  /// CHECK-DAG: <<Get:i\d+>>   ArrayGet [<<Par>>,<<Nrm>>]           loop:<<Loop>>      outer_loop:none
175  /// CHECK-DAG: <<Add:i\d+>>   Add [<<Get>>,<<One>>]                loop:<<Loop>>      outer_loop:none
176  /// CHECK-DAG:                ArraySet [<<Par>>,<<Nrm>>,<<Add>>]   loop:<<Loop>>      outer_loop:none
177  /// CHECK-DAG: <<AddI>>       Add [<<Phi>>,<<One>>]                loop:<<Loop>>      outer_loop:none
178  //
179  /// CHECK-START-ARM: void Main.staticallyUnknownAligned(int[], int) loop_optimization (after)
180  /// CHECK-DAG: <<Par:l\d+>>   ParameterValue                       loop:none
181  /// CHECK-DAG: <<Off:i\d+>>   ParameterValue                       loop:none
182  /// CHECK-DAG: <<Zero:i\d+>>  IntConstant 0                        loop:none
183  /// CHECK-DAG: <<One:i\d+>>   IntConstant 1                        loop:none
184  /// CHECK-DAG: <<Vl:i\d+>>    IntConstant 2                        loop:none
185  /// CHECK-DAG: <<PhiP:i\d+>>  Phi [<<Zero>>,<<AddIP:i\d+>>]        loop:<<Peel:B\d+>> outer_loop:none
186  /// CHECK-DAG: <<NrmP:i\d+>>  Add [<<PhiP>>,<<Off>>]               loop:<<Peel>>      outer_loop:none
187  /// CHECK-DAG: <<Get:i\d+>>   ArrayGet [<<Par>>,<<NrmP>>]          loop:<<Peel>>      outer_loop:none
188  /// CHECK-DAG: <<AddP:i\d+>>  Add [<<Get>>,<<One>>]                loop:<<Peel>>      outer_loop:none
189  /// CHECK-DAG:                ArraySet [<<Par>>,<<NrmP>>,<<AddP>>] loop:<<Peel>>      outer_loop:none
190  /// CHECK-DAG: <<AddIP>>      Add [<<PhiP>>,<<One>>]               loop:<<Peel>>      outer_loop:none
191  /// CHECK-DAG: <<Repl:d\d+>>  VecReplicateScalar [<<One>>]         loop:none
192  /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<PhiP>>,<<AddI:i\d+>>]                            loop:<<Loop:B\d+>> outer_loop:none
193  /// CHECK-DAG: <<Nrm:i\d+>>   Add [<<Phi>>,<<Off>>]                                   loop:<<Loop>>      outer_loop:none
194  /// CHECK-DAG: <<Load:d\d+>>  VecLoad [<<Par>>,<<Nrm>>]          alignment:ALIGN(8,0) loop:<<Loop>>      outer_loop:none
195  /// CHECK-DAG: <<Add:d\d+>>   VecAdd [<<Load>>,<<Repl>>]                              loop:<<Loop>>      outer_loop:none
196  /// CHECK-DAG:                VecStore [<<Par>>,<<Nrm>>,<<Add>>] alignment:ALIGN(8,0) loop:<<Loop>>      outer_loop:none
197  /// CHECK-DAG: <<AddI>>       Add [<<Phi>>,<<Vl>>]                                    loop:<<Loop>>      outer_loop:none
198  /// CHECK-DAG: <<PhiC:i\d+>>  Phi [<<Phi>>,<<AddIC:i\d+>>]         loop:<<Clean:B\d+>> outer_loop:none
199  /// CHECK-DAG: <<NrmC:i\d+>>  Add [<<PhiC>>,<<Off>>]               loop:<<Clean>>      outer_loop:none
200  /// CHECK-DAG: <<GetC:i\d+>>  ArrayGet [<<Par>>,<<NrmC>>]          loop:<<Clean>>      outer_loop:none
201  /// CHECK-DAG: <<AddC:i\d+>>  Add [<<GetC>>,<<One>>]               loop:<<Clean>>      outer_loop:none
202  /// CHECK-DAG:                ArraySet [<<Par>>,<<NrmC>>,<<AddC>>] loop:<<Clean>>      outer_loop:none
203  /// CHECK-DAG: <<AddIC>>      Add [<<PhiC>>,<<One>>]               loop:<<Clean>>      outer_loop:none
204  static void staticallyUnknownAligned(int[] a, int off) {
205    // Starts at an unknown offset due to parameter off.
206    // Dynamic peeling to the rescue, aligned vector, cleanup.
207    for (int i = 0; i < 9; i++) {
208      a[off + i] += 1;
209    }
210  }
211
212  /// CHECK-START: void Main.staticallyUnknownAlignedN(int[], int, int) loop_optimization (before)
213  /// CHECK-DAG: <<Par:l\d+>>   ParameterValue                       loop:none
214  /// CHECK-DAG: <<Off:i\d+>>   ParameterValue                       loop:none
215  /// CHECK-DAG: <<Zero:i\d+>>  IntConstant 0                        loop:none
216  /// CHECK-DAG: <<One:i\d+>>   IntConstant 1                        loop:none
217  /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<Zero>>,<<AddI:i\d+>>]         loop:<<Loop:B\d+>> outer_loop:none
218  /// CHECK-DAG: <<Nrm:i\d+>>   Add [<<Off>>,<<Phi>>]                loop:<<Loop>>      outer_loop:none
219  /// CHECK-DAG: <<Get:i\d+>>   ArrayGet [<<Par>>,<<Nrm>>]           loop:<<Loop>>      outer_loop:none
220  /// CHECK-DAG: <<Add:i\d+>>   Add [<<Get>>,<<One>>]                loop:<<Loop>>      outer_loop:none
221  /// CHECK-DAG:                ArraySet [<<Par>>,<<Nrm>>,<<Add>>]   loop:<<Loop>>      outer_loop:none
222  /// CHECK-DAG: <<AddI>>       Add [<<Phi>>,<<One>>]                loop:<<Loop>>      outer_loop:none
223  //
224  /// CHECK-START-ARM: void Main.staticallyUnknownAlignedN(int[], int, int) loop_optimization (after)
225  /// CHECK-DAG: <<Par:l\d+>>   ParameterValue                       loop:none
226  /// CHECK-DAG: <<Off:i\d+>>   ParameterValue                       loop:none
227  /// CHECK-DAG: <<Zero:i\d+>>  IntConstant 0                        loop:none
228  /// CHECK-DAG: <<One:i\d+>>   IntConstant 1                        loop:none
229  /// CHECK-DAG: <<Vl:i\d+>>    IntConstant 2                        loop:none
230  /// CHECK-DAG: <<PhiP:i\d+>>  Phi [<<Zero>>,<<AddIP:i\d+>>]        loop:<<Peel:B\d+>> outer_loop:none
231  /// CHECK-DAG: <<NrmP:i\d+>>  Add [<<PhiP>>,<<Off>>]               loop:<<Peel>>      outer_loop:none
232  /// CHECK-DAG: <<Get:i\d+>>   ArrayGet [<<Par>>,<<NrmP>>]          loop:<<Peel>>      outer_loop:none
233  /// CHECK-DAG: <<AddP:i\d+>>  Add [<<Get>>,<<One>>]                loop:<<Peel>>      outer_loop:none
234  /// CHECK-DAG:                ArraySet [<<Par>>,<<NrmP>>,<<AddP>>] loop:<<Peel>>      outer_loop:none
235  /// CHECK-DAG: <<AddIP>>      Add [<<PhiP>>,<<One>>]               loop:<<Peel>>      outer_loop:none
236  /// CHECK-DAG: <<Repl:d\d+>>  VecReplicateScalar [<<One>>]         loop:none
237  /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<PhiP>>,<<AddI:i\d+>>]                            loop:<<Loop:B\d+>> outer_loop:none
238  /// CHECK-DAG: <<Nrm:i\d+>>   Add [<<Phi>>,<<Off>>]                                   loop:<<Loop>>      outer_loop:none
239  /// CHECK-DAG: <<Load:d\d+>>  VecLoad [<<Par>>,<<Nrm>>]          alignment:ALIGN(8,0) loop:<<Loop>>      outer_loop:none
240  /// CHECK-DAG: <<Add:d\d+>>   VecAdd [<<Load>>,<<Repl>>]                              loop:<<Loop>>      outer_loop:none
241  /// CHECK-DAG:                VecStore [<<Par>>,<<Nrm>>,<<Add>>] alignment:ALIGN(8,0) loop:<<Loop>>      outer_loop:none
242  /// CHECK-DAG: <<AddI>>       Add [<<Phi>>,<<Vl>>]                                    loop:<<Loop>>      outer_loop:none
243  /// CHECK-DAG: <<PhiC:i\d+>>  Phi [<<Phi>>,<<AddIC:i\d+>>]         loop:<<Clean:B\d+>> outer_loop:none
244  /// CHECK-DAG: <<NrmC:i\d+>>  Add [<<PhiC>>,<<Off>>]               loop:<<Clean>>      outer_loop:none
245  /// CHECK-DAG: <<GetC:i\d+>>  ArrayGet [<<Par>>,<<NrmC>>]          loop:<<Clean>>      outer_loop:none
246  /// CHECK-DAG: <<AddC:i\d+>>  Add [<<GetC>>,<<One>>]               loop:<<Clean>>      outer_loop:none
247  /// CHECK-DAG:                ArraySet [<<Par>>,<<NrmC>>,<<AddC>>] loop:<<Clean>>      outer_loop:none
248  /// CHECK-DAG: <<AddIC>>      Add [<<PhiC>>,<<One>>]               loop:<<Clean>>      outer_loop:none
249  static void staticallyUnknownAlignedN(int[] a, int off, int n) {
250    // Starts at an unknown offset due to parameter off.
251    // Dynamic peeling to the rescue, aligned vector, cleanup.
252    for (int i = 0; i < n; i++) {
253      a[off + i] += 1;
254    }
255  }
256
257  //
258  // Test drivers.
259  //
260
261  private static void test1() {
262    int[] a = new int[9];
263    staticallyAligned(a);
264    for (int i = 0; i < a.length; i++) {
265      int e = i > 0 ? 1 : 0;
266      expectEquals(e, a[i]);
267    }
268  }
269
270  private static void test2() {
271    for (int n = 0; n <= 71; n++) {
272      int[] a = new int[n];
273      staticallyAlignedN(a);
274      for (int i = 0; i < a.length; i++) {
275        int e = i > 0 ? 1 : 0;
276        expectEquals(e, a[i]);
277      }
278    }
279  }
280
281  private static void test3() {
282    int[] a = new int[9];
283    staticallyMisaligned(a);
284    for (int i = 0; i < a.length; i++) {
285      expectEquals(1, a[i]);
286    }
287  }
288
289  private static void test4() {
290    for (int n = 0; n <= 71; n++) {
291      int[] a = new int[n];
292      staticallyMisalignedN(a);
293      for (int i = 0; i < a.length; i++) {
294        expectEquals(1, a[i]);
295      }
296    }
297  }
298
299  private static void test5() {
300    for (int off = 0; off <= 8; off++) {
301      int[] a = new int[17];
302      staticallyUnknownAligned(a, off);
303      for (int i = 0; i < a.length; i++) {
304        int e = (off <= i && i < off + 9) ? 1 : 0;
305        expectEquals(e, a[i]);
306      }
307    }
308  }
309
310  private static void test6() {
311    for (int off = 0; off <= 8; off++) {
312      for (int n = 0; n <= 9; n++) {
313        int[] a = new int[17];
314        staticallyUnknownAlignedN(a, off, n);
315        for (int i = 0; i < a.length; i++) {
316          int e = (off <= i && i < off + n) ? 1 : 0;
317          expectEquals(e, a[i]);
318        }
319      }
320    }
321  }
322
323  public static void main(String[] args) {
324    test1();
325    test2();
326    test4();
327    test5();
328    test6();
329    System.out.println("passed");
330  }
331
332  private static void expectEquals(int expected, int result) {
333    if (expected != result) {
334      throw new Error("Expected: " + expected + ", found: " + result);
335    }
336  }
337}
338