1 /*
2  * Copyright (C) 2018 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  * Functional tests for detecting abs.
19  */
20 public class TestAbs {
21 
22   //
23   // Intrinsics.
24   //
25 
26   /// CHECK-START: int TestAbs.absI(int) builder (after)
27   /// CHECK-DAG: <<Par:i\d+>> ParameterValue
28   /// CHECK-DAG: <<Abs:i\d+>> Abs [<<Par>>]
29   /// CHECK-DAG:              Return [<<Abs>>]
30   //
31   /// CHECK-START: int TestAbs.absI(int) builder (after)
32   /// CHECK-NOT:              InvokeStaticOrDirect
absI(int a)33   public static int absI(int a) {
34     return Math.abs(a);
35   }
36 
37   /// CHECK-START: long TestAbs.absL(long) builder (after)
38   /// CHECK-DAG: <<Par:j\d+>> ParameterValue
39   /// CHECK-DAG: <<Abs:j\d+>> Abs [<<Par>>]
40   /// CHECK-DAG:              Return [<<Abs>>]
41   //
42   /// CHECK-START: long TestAbs.absL(long) builder (after)
43   /// CHECK-NOT:              InvokeStaticOrDirect
absL(long a)44   public static long absL(long a) {
45     return Math.abs(a);
46   }
47 
48   //
49   // Types.
50   //
51 
52   /// CHECK-START: int TestAbs.abs1(int) instruction_simplifier$after_gvn (before)
53   /// CHECK-DAG: <<Par:i\d+>> ParameterValue
54   /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0
55   /// CHECK-DAG: <<Cnd:z\d+>> GreaterThanOrEqual [<<Par>>,<<Zer>>]
56   /// CHECK-DAG: <<Neg:i\d+>> [<<Par>>]
57   /// CHECK-DAG: <<Sel:i\d+>> Select [<<Neg>>,<<Par>>,<<Cnd>>]
58   /// CHECK-DAG:              Return [<<Sel>>]
59   //
60   /// CHECK-START: int TestAbs.abs1(int) instruction_simplifier$after_gvn (after)
61   /// CHECK-DAG: <<Par:i\d+>> ParameterValue
62   /// CHECK-DAG: <<Abs:i\d+>> Abs [<<Par>>]
63   /// CHECK-DAG:              Return [<<Abs>>]
64   //
65   /// CHECK-START: int TestAbs.abs1(int) instruction_simplifier$after_gvn (after)
66   /// CHECK-NOT:              Select
abs1(int a)67   public static int abs1(int a) {
68     return a < 0 ? -a : a;
69   }
70 
71   /// CHECK-START: int TestAbs.abs2(int) instruction_simplifier$after_gvn (before)
72   /// CHECK-DAG: <<Par:i\d+>> ParameterValue
73   /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0
74   /// CHECK-DAG: <<Cnd:z\d+>> GreaterThan [<<Par>>,<<Zer>>]
75   /// CHECK-DAG: <<Neg:i\d+>> [<<Par>>]
76   /// CHECK-DAG: <<Sel:i\d+>> Select [<<Neg>>,<<Par>>,<<Cnd>>]
77   /// CHECK-DAG:              Return [<<Sel>>]
78   //
79   /// CHECK-START: int TestAbs.abs2(int) instruction_simplifier$after_gvn (after)
80   /// CHECK-DAG: <<Par:i\d+>> ParameterValue
81   /// CHECK-DAG: <<Abs:i\d+>> Abs [<<Par>>]
82   /// CHECK-DAG:              Return [<<Abs>>]
83   //
84   /// CHECK-START: int TestAbs.abs2(int) instruction_simplifier$after_gvn (after)
85   /// CHECK-NOT:              Select
abs2(int a)86   public static int abs2(int a) {
87     return a <= 0 ? -a : a;
88   }
89 
90   /// CHECK-START: int TestAbs.abs3(int) instruction_simplifier$after_gvn (before)
91   /// CHECK-DAG: <<Par:i\d+>> ParameterValue
92   /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0
93   /// CHECK-DAG: <<Cnd:z\d+>> LessThanOrEqual [<<Par>>,<<Zer>>]
94   /// CHECK-DAG: <<Neg:i\d+>> [<<Par>>]
95   /// CHECK-DAG: <<Sel:i\d+>> Select [<<Par>>,<<Neg>>,<<Cnd>>]
96   /// CHECK-DAG:              Return [<<Sel>>]
97   //
98   /// CHECK-START: int TestAbs.abs3(int) instruction_simplifier$after_gvn (after)
99   /// CHECK-DAG: <<Par:i\d+>> ParameterValue
100   /// CHECK-DAG: <<Abs:i\d+>> Abs [<<Par>>]
101   /// CHECK-DAG:              Return [<<Abs>>]
102   //
103   /// CHECK-START: int TestAbs.abs3(int) instruction_simplifier$after_gvn (after)
104   /// CHECK-NOT:              Select
abs3(int a)105   public static int abs3(int a) {
106     return a > 0 ? a : -a;
107   }
108 
109   /// CHECK-START: int TestAbs.abs4(int) instruction_simplifier$after_gvn (before)
110   /// CHECK-DAG: <<Par:i\d+>> ParameterValue
111   /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0
112   /// CHECK-DAG: <<Cnd:z\d+>> LessThan [<<Par>>,<<Zer>>]
113   /// CHECK-DAG: <<Neg:i\d+>> [<<Par>>]
114   /// CHECK-DAG: <<Sel:i\d+>> Select [<<Par>>,<<Neg>>,<<Cnd>>]
115   /// CHECK-DAG:              Return [<<Sel>>]
116   //
117   /// CHECK-START: int TestAbs.abs4(int) instruction_simplifier$after_gvn (after)
118   /// CHECK-DAG: <<Par:i\d+>> ParameterValue
119   /// CHECK-DAG: <<Abs:i\d+>> Abs [<<Par>>]
120   /// CHECK-DAG:              Return [<<Abs>>]
121   //
122   /// CHECK-START: int TestAbs.abs4(int) instruction_simplifier$after_gvn (after)
123   /// CHECK-NOT:              Select
abs4(int a)124   public static int abs4(int a) {
125     return a >= 0 ? a : -a;
126   }
127 
128   /// CHECK-START: int TestAbs.abs5(short) instruction_simplifier$after_gvn (before)
129   /// CHECK-DAG: <<Par:s\d+>> ParameterValue
130   /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0
131   /// CHECK-DAG: <<Cnd:z\d+>> LessThan [<<Par>>,<<Zer>>]
132   /// CHECK-DAG: <<Neg:i\d+>> [<<Par>>]
133   /// CHECK-DAG: <<Sel:i\d+>> Select [<<Par>>,<<Neg>>,<<Cnd>>]
134   /// CHECK-DAG:              Return [<<Sel>>]
135   //
136   /// CHECK-START: int TestAbs.abs5(short) instruction_simplifier$after_gvn (after)
137   /// CHECK-DAG: <<Par:s\d+>> ParameterValue
138   /// CHECK-DAG: <<Abs:i\d+>> Abs [<<Par>>]
139   /// CHECK-DAG:              Return [<<Abs>>]
140   //
141   /// CHECK-START: int TestAbs.abs5(short) instruction_simplifier$after_gvn (after)
142   /// CHECK-NOT:              Select
abs5(short a)143   public static int abs5(short a) {
144     return a >= 0 ? a : -a;
145   }
146 
147   /// CHECK-START: int TestAbs.abs6(byte) instruction_simplifier$after_gvn (before)
148   /// CHECK-DAG: <<Par:b\d+>> ParameterValue
149   /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0
150   /// CHECK-DAG: <<Cnd:z\d+>> LessThan [<<Par>>,<<Zer>>]
151   /// CHECK-DAG: <<Neg:i\d+>> [<<Par>>]
152   /// CHECK-DAG: <<Sel:i\d+>> Select [<<Par>>,<<Neg>>,<<Cnd>>]
153   /// CHECK-DAG:              Return [<<Sel>>]
154   //
155   /// CHECK-START: int TestAbs.abs6(byte) instruction_simplifier$after_gvn (after)
156   /// CHECK-DAG: <<Par:b\d+>> ParameterValue
157   /// CHECK-DAG: <<Abs:i\d+>> Abs [<<Par>>]
158   /// CHECK-DAG:              Return [<<Abs>>]
159   //
160   /// CHECK-START: int TestAbs.abs6(byte) instruction_simplifier$after_gvn (after)
161   /// CHECK-NOT:              Select
abs6(byte a)162   public static int abs6(byte a) {
163     return a >= 0 ? a : -a;
164   }
165 
166   /// CHECK-START: long TestAbs.abs7(long) instruction_simplifier$after_gvn (before)
167   /// CHECK-DAG: <<Par:j\d+>> ParameterValue
168   /// CHECK-DAG: <<Zer:j\d+>> LongConstant 0
169   /// CHECK-DAG: <<Cnd:z\d+>> LessThan [<<Par>>,<<Zer>>]
170   /// CHECK-DAG: <<Neg:j\d+>> [<<Par>>]
171   /// CHECK-DAG: <<Sel:j\d+>> Select [<<Par>>,<<Neg>>,<<Cnd>>]
172   /// CHECK-DAG:              Return [<<Sel>>]
173   //
174   /// CHECK-START: long TestAbs.abs7(long) instruction_simplifier$after_gvn (after)
175   /// CHECK-DAG: <<Par:j\d+>> ParameterValue
176   /// CHECK-DAG: <<Abs:j\d+>> Abs [<<Par>>]
177   /// CHECK-DAG:              Return [<<Abs>>]
178   //
179   /// CHECK-START: long TestAbs.abs7(long) instruction_simplifier$after_gvn (after)
180   /// CHECK-NOT:              Select
abs7(long a)181   public static long abs7(long a) {
182     return a >= 0 ? a : -a;
183   }
184 
185   //
186   // Complications.
187   //
188 
189   /// CHECK-START: int TestAbs.abs0(int[]) instruction_simplifier$after_gvn (before)
190   /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0
191   /// CHECK-DAG: <<Arr:i\d+>> ArrayGet [{{l\d+}},{{i\d+}}]
192   /// CHECK-DAG: <<Cnd:z\d+>> LessThan [<<Arr>>,<<Zer>>]
193   /// CHECK-DAG: <<Neg:i\d+>> [<<Arr>>]
194   /// CHECK-DAG: <<Sel:i\d+>> Select [<<Arr>>,<<Neg>>,<<Cnd>>]
195   /// CHECK-DAG:              Return [<<Sel>>]
196   //
197   /// CHECK-START: int TestAbs.abs0(int[]) instruction_simplifier$after_gvn (after)
198   /// CHECK-DAG: <<Arr:i\d+>> ArrayGet [{{l\d+}},{{i\d+}}]
199   /// CHECK-DAG: <<Abs:i\d+>> Abs [<<Arr>>]
200   /// CHECK-DAG:              Return [<<Abs>>]
201   //
202   /// CHECK-START: int TestAbs.abs0(int[]) instruction_simplifier$after_gvn (after)
203   /// CHECK-NOT:              Select
abs0(int[] a)204   public static int abs0(int[] a) {
205     return a[0] >= 0 ? a[0] : -a[0];
206   }
207 
208   //
209   // Nop zero extension.
210   //
211 
212   /// CHECK-START: int TestAbs.zabs1(byte) instruction_simplifier (before)
213   /// CHECK-DAG: <<Par:b\d+>> ParameterValue
214   /// CHECK-DAG: <<Msk:i\d+>> IntConstant 255
215   /// CHECK-DAG: <<And:i\d+>> [<<Par>>,<<Msk>>]
216   /// CHECK-DAG: <<Abs:i\d+>> Abs
217   /// CHECK-DAG:              Return [<<Abs>>]
218   //
219   /// CHECK-START: int TestAbs.zabs1(byte) instruction_simplifier (after)
220   /// CHECK-DAG: <<Par:b\d+>> ParameterValue
221   /// CHECK-DAG: <<Cnv:a\d+>> TypeConversion [<<Par>>]
222   /// CHECK-DAG:              Return [<<Cnv>>]
223   //
224   /// CHECK-START: int TestAbs.zabs1(byte) instruction_simplifier (after)
225   /// CHECK-NOT:              Abs
zabs1(byte a)226   public static int zabs1(byte a) {
227     return Math.abs(a & 0xff);
228   }
229 
230   /// CHECK-START: int TestAbs.zabs2(short) instruction_simplifier (before)
231   /// CHECK-DAG: <<Par:s\d+>> ParameterValue
232   /// CHECK-DAG: <<Msk:i\d+>> IntConstant 65535
233   /// CHECK-DAG: <<And:i\d+>> [<<Msk>>,<<Par>>]
234   /// CHECK-DAG: <<Abs:i\d+>> Abs
235   /// CHECK-DAG:              Return [<<Abs>>]
236   //
237   /// CHECK-START: int TestAbs.zabs2(short) instruction_simplifier (after)
238   /// CHECK-DAG: <<Par:s\d+>> ParameterValue
239   /// CHECK-DAG: <<Cnv:c\d+>> TypeConversion [<<Par>>]
240   /// CHECK-DAG:              Return [<<Cnv>>]
241   //
242   /// CHECK-START: int TestAbs.zabs2(short) instruction_simplifier (after)
243   /// CHECK-NOT:              Abs
zabs2(short a)244   public static int zabs2(short a) {
245     return Math.abs(a & 0xffff);
246   }
247 
248   /// CHECK-START: int TestAbs.zabs3(char) instruction_simplifier (before)
249   /// CHECK-DAG: <<Par:c\d+>> ParameterValue
250   /// CHECK-DAG: <<Abs:i\d+>> Abs
251   /// CHECK-DAG:              Return [<<Abs>>]
252   //
253   /// CHECK-START: int TestAbs.zabs3(char) instruction_simplifier (after)
254   /// CHECK-DAG: <<Par:c\d+>> ParameterValue
255   /// CHECK-DAG:              Return [<<Par>>]
256   //
257   /// CHECK-START: int TestAbs.zabs3(char) instruction_simplifier (after)
258   /// CHECK-NOT:              Abs
zabs3(char a)259   public static int zabs3(char a) {
260     return Math.abs(a);
261   }
262 
main()263   public static void main() {
264     // Intrinsics.
265     expectEquals(10, absI(-10));
266     expectEquals(20, absI(20));
267     expectEquals(10L, absL(-10L));
268     expectEquals(20L, absL(20L));
269     // Types.
270     expectEquals(10, abs1(-10));
271     expectEquals(20, abs1(20));
272     expectEquals(10, abs2(-10));
273     expectEquals(20, abs2(20));
274     expectEquals(10, abs3(-10));
275     expectEquals(20, abs3(20));
276     expectEquals(10, abs4(-10));
277     expectEquals(20, abs4(20));
278     expectEquals(10, abs4((short) -10));
279     expectEquals(20, abs4((short) 20));
280     expectEquals(10, abs6((byte) -10));
281     expectEquals(20, abs6((byte) 20));
282     expectEquals(10L, abs7(-10L));
283     expectEquals(20L, abs7(20L));
284     // Complications.
285     int[] a = { 13 };
286     int[] b = { -11 };
287     expectEquals(13, abs0(a));
288     expectEquals(11, abs0(b));
289     // Nop zero extension.
290     expectEquals(1, zabs1((byte) 1));
291     expectEquals(0xff, zabs1((byte) -1));
292     expectEquals(1, zabs2((short) 1));
293     expectEquals(0xffff, zabs2((short) -1));
294     expectEquals(1, zabs3((char) 1));
295     expectEquals(0xffff, zabs3((char) -1));
296     System.out.println("TestAbs passed");
297   }
298 
expectEquals(int expected, int result)299   private static void expectEquals(int expected, int result) {
300     if (expected != result) {
301       throw new Error("Expected: " + expected + ", found: " + result);
302     }
303   }
304 
expectEquals(long expected, long result)305   private static void expectEquals(long expected, long result) {
306     if (expected != result) {
307       throw new Error("Expected: " + expected + ", found: " + result);
308     }
309   }
310 }
311