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 SAD (sum of absolute differences).
19  */
20 public class SadLong {
21 
22   /// CHECK-START: long SadLong.sad1(long, long) instruction_simplifier$after_gvn (before)
23   /// CHECK-DAG: <<Select:j\d+>> Select
24   /// CHECK-DAG:                 Return [<<Select>>]
25   //
26   /// CHECK-START: long SadLong.sad1(long, long) instruction_simplifier$after_gvn (after)
27   /// CHECK-DAG: <<Select:j\d+>> Select
28   /// CHECK-DAG:                 Return [<<Select>>]
29   //
30   /// CHECK-START: long SadLong.sad1(long, long) instruction_simplifier$after_gvn (after)
31   /// CHECK-NOT: Abs
32   //
33   // NOTE: for direct 64-bit operands, this is not an ABS.
sad1(long x, long y)34   static long sad1(long x, long y) {
35     return x >= y ? x - y : y - x;
36   }
37 
38   /// CHECK-START: long SadLong.sad2(long, long) instruction_simplifier$after_gvn (before)
39   /// CHECK-DAG: <<Select:j\d+>> Select
40   /// CHECK-DAG:                 Return [<<Select>>]
41   //
42   /// CHECK-START: long SadLong.sad2(long, long) instruction_simplifier$after_gvn (after)
43   /// CHECK-DAG: <<Intrin:j\d+>> Abs
44   /// CHECK-DAG:                 Return [<<Intrin>>]
sad2(long x, long y)45   static long sad2(long x, long y) {
46     long diff = x - y;
47     if (diff < 0) diff = -diff;
48     return diff;
49   }
50 
51   /// CHECK-START: long SadLong.sad3(long, long) instruction_simplifier$after_gvn (before)
52   /// CHECK-DAG: <<Select:j\d+>> Select
53   /// CHECK-DAG:                 Return [<<Select>>]
54   //
55   /// CHECK-START: long SadLong.sad3(long, long) instruction_simplifier$after_gvn (after)
56   /// CHECK-DAG: <<Intrin:j\d+>> Abs
57   /// CHECK-DAG:                 Return [<<Intrin>>]
sad3(long x, long y)58   static long sad3(long x, long y) {
59     long diff = x - y;
60     return diff >= 0 ? diff : -diff;
61   }
62 
63   /// CHECK-START: long SadLong.sad3Alt(long, long) instruction_simplifier$after_gvn (before)
64   /// CHECK-DAG: <<Select:j\d+>> Select
65   /// CHECK-DAG:                 Return [<<Select>>]
66   //
67   /// CHECK-START: long SadLong.sad3Alt(long, long) instruction_simplifier$after_gvn (after)
68   /// CHECK-DAG: <<Intrin:j\d+>> Abs
69   /// CHECK-DAG:                 Return [<<Intrin>>]
sad3Alt(long x, long y)70   static long sad3Alt(long x, long y) {
71     long diff = x - y;
72     return 0 <= diff ? diff : -diff;
73   }
74 
main()75   public static void main() {
76     // Use cross-values for the interesting values.
77     long[] interesting = {
78       0x0000000000000000L, 0x0000000000000001L, 0x000000007fffffffL,
79       0x0000000080000000L, 0x0000000080000001L, 0x00000000ffffffffL,
80       0x0000000100000000L, 0x0000000100000001L, 0x000000017fffffffL,
81       0x0000000180000000L, 0x0000000180000001L, 0x00000001ffffffffL,
82       0x7fffffff00000000L, 0x7fffffff00000001L, 0x7fffffff7fffffffL,
83       0x7fffffff80000000L, 0x7fffffff80000001L, 0x7fffffffffffffffL,
84       0x8000000000000000L, 0x8000000000000001L, 0x800000007fffffffL,
85       0x8000000080000000L, 0x8000000080000001L, 0x80000000ffffffffL,
86       0x8000000100000000L, 0x8000000100000001L, 0x800000017fffffffL,
87       0x8000000180000000L, 0x8000000180000001L, 0x80000001ffffffffL,
88       0xffffffff00000000L, 0xffffffff00000001L, 0xffffffff7fffffffL,
89       0xffffffff80000000L, 0xffffffff80000001L, 0xffffffffffffffffL
90     };
91     for (int i = 0; i < interesting.length; i++) {
92       for (int j = 0; j < interesting.length; j++) {
93         long x = interesting[i];
94         long y = interesting[j];
95         long e1 = x >= y ? x - y : y - x;  // still select
96         expectEquals(e1, sad1(x, y));
97         long e2 = Math.abs(x - y);  // pure abs
98         expectEquals(e2, sad2(x, y));
99         expectEquals(e2, sad3(x, y));
100         expectEquals(e2, sad3Alt(x, y));
101       }
102     }
103     System.out.println("SadLong passed");
104   }
105 
expectEquals(long expected, long result)106   private static void expectEquals(long expected, long result) {
107     if (expected != result) {
108       throw new Error("Expected: " + expected + ", found: " + result);
109     }
110   }
111 }
112