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 public class Main {
18 
assertIntEquals(int expected, int result)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
checkIntCase(int[] a)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]+}}]
checkByteCase(byte[] a)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
checkSingleAccess(int[] a)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
checkInt2Float(int[] a, float[] b)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 
calcArraySum(int[] a, byte[] b, float[] c)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 
main(String[] args)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