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
17public class Main {
18
19  public static void assertIntEquals(int expected, int result) {
20    if (expected != result) {
21      throw new Error("Expected: " + expected + ", found: " + result);
22    }
23  }
24
25  /// CHECK-START-ARM64: void Main.checkIntCase(int[]) instruction_simplifier_arm64 (before)
26  /// CHECK-DAG:             <<Array:l\d+>>         ParameterValue
27  /// CHECK-DAG:             <<Const5:i\d+>>        IntConstant 5
28  /// CHECK-DAG:             <<Repl:d\d+>>          VecReplicateScalar [<<Const5>>]
29  //  -------------- Loop
30  /// CHECK-DAG:             <<Index:i\d+>>         Phi
31  /// CHECK-DAG:                                    If
32  /// CHECK-DAG:             <<Load:d\d+>>          VecLoad [<<Array>>,<<Index>>]
33  /// CHECK-DAG:             <<Add:d\d+>>           VecAdd [<<Load>>,<<Repl>>]
34  /// CHECK-DAG:                                    VecStore [<<Array>>,<<Index>>,<<Add>>]
35
36  /// CHECK-START-ARM64: void Main.checkIntCase(int[]) instruction_simplifier_arm64 (after)
37  /// CHECK-DAG:             <<Array:l\d+>>         ParameterValue
38  /// CHECK-DAG:             <<Const5:i\d+>>        IntConstant 5
39  /// CHECK-DAG:             <<DataOffset:i\d+>>    IntConstant 12
40  /// CHECK-DAG:             <<Const2:i\d+>>        IntConstant 2
41  /// CHECK-DAG:             <<Repl:d\d+>>          VecReplicateScalar [<<Const5>>]
42  //  -------------- Loop
43  /// CHECK-DAG:             <<Index:i\d+>>         Phi
44  /// CHECK-DAG:                                    If
45  /// CHECK-DAG:             <<Address1:i\d+>>      IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const2>>]
46  /// CHECK-DAG:             <<Load:d\d+>>          VecLoad [<<Array>>,<<Address1>>]
47  /// CHECK-DAG:             <<Add:d\d+>>           VecAdd [<<Load>>,<<Repl>>]
48  /// CHECK-DAG:             <<Address2:i\d+>>      IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const2>>]
49  /// CHECK-DAG:                                    VecStore [<<Array>>,<<Address2>>,<<Add>>]
50
51  /// CHECK-START-ARM64: void Main.checkIntCase(int[]) GVN$after_arch (after)
52  /// CHECK-DAG:             <<Array:l\d+>>         ParameterValue
53  /// CHECK-DAG:             <<Const5:i\d+>>        IntConstant 5
54  /// CHECK-DAG:             <<DataOffset:i\d+>>    IntConstant 12
55  /// CHECK-DAG:             <<Const2:i\d+>>        IntConstant 2
56  /// CHECK-DAG:             <<Repl:d\d+>>          VecReplicateScalar [<<Const5>>]
57  //  -------------- Loop
58  /// CHECK-DAG:             <<Index:i\d+>>         Phi
59  /// CHECK-DAG:                                    If
60  /// CHECK-DAG:             <<Address1:i\d+>>      IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const2>>]
61  /// CHECK-DAG:             <<Load:d\d+>>          VecLoad [<<Array>>,<<Address1>>]
62  /// CHECK-DAG:             <<Add:d\d+>>           VecAdd [<<Load>>,<<Repl>>]
63  /// CHECK-NOT:                                    IntermediateAddress
64  /// CHECK-DAG:                                    VecStore [<<Array>>,<<Address1>>,<<Add>>]
65
66  /// CHECK-START-ARM64: void Main.checkIntCase(int[]) disassembly (after)
67  /// CHECK:                                        IntermediateAddressIndex
68  /// CHECK-NEXT:                                   add w{{[0-9]+}}, w{{[0-9]+}}, w{{[0-9]+}}, lsl #2
69  public static void checkIntCase(int[] a) {
70    for (int i = 0; i < 128; i++) {
71      a[i] += 5;
72    }
73  }
74
75  /// CHECK-START-ARM64: void Main.checkByteCase(byte[]) instruction_simplifier_arm64 (before)
76  /// CHECK-DAG:             <<Array:l\d+>>         ParameterValue
77  /// CHECK-DAG:             <<Const5:i\d+>>        IntConstant 5
78  /// CHECK-DAG:             <<Repl:d\d+>>          VecReplicateScalar [<<Const5>>]
79  //  -------------- Loop
80  /// CHECK-DAG:             <<Index:i\d+>>         Phi
81  /// CHECK-DAG:                                    If
82  /// CHECK-DAG:             <<Load:d\d+>>          VecLoad [<<Array>>,<<Index>>]
83  /// CHECK-DAG:             <<Add:d\d+>>           VecAdd [<<Load>>,<<Repl>>]
84  /// CHECK-DAG:                                    VecStore [<<Array>>,<<Index>>,<<Add>>]
85
86  /// CHECK-START-ARM64: void Main.checkByteCase(byte[]) instruction_simplifier_arm64 (after)
87  /// CHECK-DAG:             <<Array:l\d+>>         ParameterValue
88  /// CHECK-DAG:             <<Const0:i\d+>>        IntConstant 0
89  /// CHECK-DAG:             <<Const5:i\d+>>        IntConstant 5
90  /// CHECK-DAG:             <<DataOffset:i\d+>>    IntConstant 12
91  /// CHECK-DAG:             <<Repl:d\d+>>          VecReplicateScalar [<<Const5>>]
92  //  -------------- Loop
93  /// CHECK-DAG:             <<Index:i\d+>>         Phi
94  /// CHECK-DAG:                                    If
95  /// CHECK-DAG:             <<Address1:i\d+>>      IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const0>>]
96  /// CHECK-DAG:             <<Load:d\d+>>          VecLoad [<<Array>>,<<Address1>>]
97  /// CHECK-DAG:             <<Add:d\d+>>           VecAdd [<<Load>>,<<Repl>>]
98  /// CHECK-DAG:             <<Address2:i\d+>>      IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const0>>]
99  /// CHECK-DAG:                                    VecStore [<<Array>>,<<Address2>>,<<Add>>]
100
101  /// CHECK-START-ARM64: void Main.checkByteCase(byte[]) GVN$after_arch (after)
102  /// CHECK-DAG:             <<Array:l\d+>>         ParameterValue
103  /// CHECK-DAG:             <<Const0:i\d+>>        IntConstant 0
104  /// CHECK-DAG:             <<Const5:i\d+>>        IntConstant 5
105  /// CHECK-DAG:             <<DataOffset:i\d+>>    IntConstant 12
106  /// CHECK-DAG:             <<Repl:d\d+>>          VecReplicateScalar [<<Const5>>]
107  //  -------------- Loop
108  /// CHECK-DAG:             <<Index:i\d+>>         Phi
109  /// CHECK-DAG:                                    If
110  /// CHECK-DAG:             <<Address1:i\d+>>      IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const0>>]
111  /// CHECK-DAG:             <<Load:d\d+>>          VecLoad [<<Array>>,<<Address1>>]
112  /// CHECK-DAG:             <<Add:d\d+>>           VecAdd [<<Load>>,<<Repl>>]
113  /// CHECK-NOT:                                    IntermediateAddress
114  /// CHECK-DAG:                                    VecStore [<<Array>>,<<Address1>>,<<Add>>]
115
116  /// CHECK-START-ARM64: void Main.checkByteCase(byte[]) disassembly (after)
117  /// CHECK:                                        IntermediateAddressIndex
118  /// CHECK-NEXT:                                   add w{{[0-9]+}}, w{{[0-9]+}}, #0x{{[0-9a-fA-F]+}}
119  /// CHECK:                                        VecLoad
120  /// CHECK-NEXT:                                   ldr q{{[0-9]+}}, [x{{[0-9]+}}, x{{[0-9]+}}]
121  /// CHECK:                                        VecStore
122  /// CHECK-NEXT:                                   str q{{[0-9]+}}, [x{{[0-9]+}}, x{{[0-9]+}}]
123  public static void checkByteCase(byte[] a) {
124    for (int i = 0; i < 128; i++) {
125      a[i] += 5;
126    }
127  }
128
129  /// CHECK-START-ARM64: void Main.checkSingleAccess(int[]) instruction_simplifier_arm64 (before)
130  /// CHECK-DAG:             <<Array:l\d+>>         ParameterValue
131  /// CHECK-DAG:             <<Const5:i\d+>>        IntConstant 5
132  /// CHECK-DAG:             <<Repl:d\d+>>          VecReplicateScalar [<<Const5>>]
133  //  -------------- Loop
134  /// CHECK-DAG:             <<Index:i\d+>>         Phi
135  /// CHECK-DAG:                                    If
136  /// CHECK-DAG:                                    VecStore [<<Array>>,<<Index>>,<<Repl>>]
137
138  /// CHECK-START-ARM64: void Main.checkSingleAccess(int[]) instruction_simplifier_arm64 (after)
139  /// CHECK-DAG:             <<Array:l\d+>>         ParameterValue
140  /// CHECK-DAG:             <<Const0:i\d+>>        IntConstant 0
141  /// CHECK-DAG:             <<Const5:i\d+>>        IntConstant 5
142  /// CHECK-DAG:             <<Repl:d\d+>>          VecReplicateScalar [<<Const5>>]
143  //  -------------- Loop
144  /// CHECK-DAG:             <<Index:i\d+>>         Phi
145  /// CHECK-DAG:                                    If
146  /// CHECK-DAG:                                    VecStore [<<Array>>,<<Index>>,<<Repl>>]
147  /// CHECK-NOT:                                    IntermediateAddress
148  public static void checkSingleAccess(int[] a) {
149    for (int i = 0; i < 128; i++) {
150      a[i] = 5;
151    }
152  }
153
154  /// CHECK-START-ARM64: void Main.checkInt2Float(int[], float[]) instruction_simplifier_arm64 (before)
155  /// CHECK-DAG:             <<Array1:l\d+>>        ParameterValue
156  /// CHECK-DAG:             <<Array2:l\d+>>        ParameterValue
157  //  -------------- Loop
158  /// CHECK-DAG:             <<Index:i\d+>>         Phi
159  /// CHECK-DAG:                                    If
160  /// CHECK-DAG:             <<Load:d\d+>>          VecLoad [<<Array1>>,<<Index>>]
161  /// CHECK-DAG:             <<Cnv:d\d+>>           VecCnv [<<Load>>]
162  /// CHECK-DAG:                                    VecStore [<<Array2>>,<<Index>>,<<Cnv>>]
163
164  /// CHECK-START-ARM64: void Main.checkInt2Float(int[], float[]) instruction_simplifier_arm64 (after)
165  /// CHECK-DAG:             <<Array1:l\d+>>        ParameterValue
166  /// CHECK-DAG:             <<Array2:l\d+>>        ParameterValue
167  /// CHECK-DAG:             <<DataOffset:i\d+>>    IntConstant 12
168  /// CHECK-DAG:             <<Const2:i\d+>>        IntConstant 2
169  //  -------------- Loop
170  /// CHECK-DAG:             <<Index:i\d+>>         Phi
171  /// CHECK-DAG:                                    If
172  /// CHECK-DAG:             <<Address1:i\d+>>      IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const2>>]
173  /// CHECK-DAG:             <<Load:d\d+>>          VecLoad [<<Array1>>,<<Address1>>]
174  /// CHECK-DAG:             <<Cnv:d\d+>>           VecCnv [<<Load>>]
175  /// CHECK-DAG:             <<Address2:i\d+>>      IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const2>>]
176  /// CHECK-DAG:                                    VecStore [<<Array2>>,<<Address2>>,<<Cnv>>]
177
178  /// CHECK-START-ARM64: void Main.checkInt2Float(int[], float[]) GVN$after_arch (after)
179  /// CHECK-DAG:             <<Array1:l\d+>>        ParameterValue
180  /// CHECK-DAG:             <<Array2:l\d+>>        ParameterValue
181  /// CHECK-DAG:             <<DataOffset:i\d+>>    IntConstant 12
182  /// CHECK-DAG:             <<Const2:i\d+>>        IntConstant 2
183  //  -------------- Loop
184  /// CHECK-DAG:             <<Index:i\d+>>         Phi
185  /// CHECK-DAG:                                    If
186  /// CHECK-DAG:             <<Address1:i\d+>>      IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const2>>]
187  /// CHECK-DAG:             <<Load:d\d+>>          VecLoad [<<Array1>>,<<Address1>>]
188  /// CHECK-DAG:             <<Cnv:d\d+>>           VecCnv [<<Load>>]
189  /// CHECK-NOT:                                    IntermediateAddress
190  /// CHECK-DAG:                                    VecStore [<<Array2>>,<<Address1>>,<<Cnv>>]
191
192  /// CHECK-START-ARM64: void Main.checkInt2Float(int[], float[]) disassembly (after)
193  /// CHECK:                                        IntermediateAddressIndex
194  /// CHECK-NEXT:                                   add w{{[0-9]+}}, w{{[0-9]+}}, w{{[0-9]+}}, lsl #2
195  public static void checkInt2Float(int[] a, float[] b) {
196    for (int i = 0; i < 128; i++) {
197      b[i] = (float) a[i];
198    }
199  }
200
201  public static final int ARRAY_SIZE = 1024;
202
203  public static int calcArraySum(int[] a, byte[] b, float[] c) {
204    int sum = 0;
205    for (int i = 0; i < 128; i++) {
206      sum += a[i] + b[i] + (int) c[i];
207    }
208    return sum;
209  }
210
211  public static void main(String[] args) {
212    byte[] ba = new byte[ARRAY_SIZE];
213    int[] ia = new int[ARRAY_SIZE];
214    float[] fa = new float[ARRAY_SIZE];
215
216    checkSingleAccess(ia);
217    checkIntCase(ia);
218    checkByteCase(ba);
219    checkInt2Float(ia, fa);
220
221    assertIntEquals(3200, calcArraySum(ia, ba, fa));
222  }
223}
224