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 SadInt {
21 
22   /// CHECK-START: int SadInt.sad1(int, int) instruction_simplifier$after_gvn (before)
23   /// CHECK-DAG: <<Select:i\d+>> Select
24   /// CHECK-DAG:                 Return [<<Select>>]
25   //
26   /// CHECK-START: int SadInt.sad1(int, int) instruction_simplifier$after_gvn (after)
27   /// CHECK-DAG: <<Select:i\d+>> Select
28   /// CHECK-DAG:                 Return [<<Select>>]
29   //
30   /// CHECK-START: int SadInt.sad1(int, int) instruction_simplifier$after_gvn (after)
31   /// CHECK-NOT: Abs
32   //
33   // NOTE: for direct 32-bit operands, this is not an ABS.
sad1(int x, int y)34   static int sad1(int x, int y) {
35     return x >= y ? x - y : y - x;
36   }
37 
38   /// CHECK-START: int SadInt.sad2(int, int) instruction_simplifier$after_gvn (before)
39   /// CHECK-DAG: <<Select:i\d+>> Select
40   /// CHECK-DAG:                 Return [<<Select>>]
41   //
42   /// CHECK-START: int SadInt.sad2(int, int) instruction_simplifier$after_gvn (after)
43   /// CHECK-DAG: <<Intrin:i\d+>> Abs
44   /// CHECK-DAG:                 Return [<<Intrin>>]
sad2(int x, int y)45   static int sad2(int x, int y) {
46     int diff = x - y;
47     if (diff < 0) diff = -diff;
48     return diff;
49   }
50 
51   /// CHECK-START: int SadInt.sad3(int, int) instruction_simplifier$after_gvn (before)
52   /// CHECK-DAG: <<Select:i\d+>> Select
53   /// CHECK-DAG:                 Return [<<Select>>]
54   //
55   /// CHECK-START: int SadInt.sad3(int, int) instruction_simplifier$after_gvn (after)
56   /// CHECK-DAG: <<Intrin:i\d+>> Abs
57   /// CHECK-DAG:                 Return [<<Intrin>>]
sad3(int x, int y)58   static int sad3(int x, int y) {
59     int diff = x - y;
60     return diff >= 0 ? diff : -diff;
61   }
62 
63   /// CHECK-START: int SadInt.sad3Alt(int, int) instruction_simplifier$after_gvn (before)
64   /// CHECK-DAG: <<Select:i\d+>> Select
65   /// CHECK-DAG:                 Return [<<Select>>]
66   //
67   /// CHECK-START: int SadInt.sad3Alt(int, int) instruction_simplifier$after_gvn (after)
68   /// CHECK-DAG: <<Intrin:i\d+>> Abs
69   /// CHECK-DAG:                 Return [<<Intrin>>]
sad3Alt(int x, int y)70   static int sad3Alt(int x, int y) {
71     int diff = x - y;
72     return 0 <= diff ? diff : -diff;
73   }
74 
75   /// CHECK-START: long SadInt.sadL1(int, int) instruction_simplifier$after_gvn (before)
76   /// CHECK-DAG: <<Select:j\d+>> Select
77   /// CHECK-DAG:                 Return [<<Select>>]
78   //
79   /// CHECK-START: long SadInt.sadL1(int, int) instruction_simplifier$after_gvn (after)
80   /// CHECK-DAG: <<Intrin:j\d+>> Abs
81   /// CHECK-DAG:                 Return [<<Intrin>>]
sadL1(int x, int y)82   static long sadL1(int x, int y) {
83     long xl = x;
84     long yl = y;
85     return xl >= yl ? xl - yl : yl - xl;
86   }
87 
88   /// CHECK-START: long SadInt.sadL2(int, int) instruction_simplifier$after_gvn (before)
89   /// CHECK-DAG: <<Select:j\d+>> Select
90   /// CHECK-DAG:                 Return [<<Select>>]
91   //
92   /// CHECK-START: long SadInt.sadL2(int, int) instruction_simplifier$after_gvn (after)
93   /// CHECK-DAG: <<Intrin:j\d+>> Abs
94   /// CHECK-DAG:                 Return [<<Intrin>>]
sadL2(int x, int y)95   static long sadL2(int x, int y) {
96     long diff = x - y;
97     if (diff < 0L) diff = -diff;
98     return diff;
99   }
100 
101   /// CHECK-START: long SadInt.sadL3(int, int) instruction_simplifier$after_gvn (before)
102   /// CHECK-DAG: <<Select:j\d+>> Select
103   /// CHECK-DAG:                 Return [<<Select>>]
104   //
105   /// CHECK-START: long SadInt.sadL3(int, int) instruction_simplifier$after_gvn (after)
106   /// CHECK-DAG: <<Intrin:j\d+>> Abs
107   /// CHECK-DAG:                 Return [<<Intrin>>]
sadL3(int x, int y)108   static long sadL3(int x, int y) {
109     long diff = x - y;
110     return diff >= 0L ? diff : -diff;
111   }
112 
113   /// CHECK-START: long SadInt.sadL3Alt(int, int) instruction_simplifier$after_gvn (before)
114   /// CHECK-DAG: <<Select:j\d+>> Select
115   /// CHECK-DAG:                 Return [<<Select>>]
116   //
117   /// CHECK-START: long SadInt.sadL3Alt(int, int) instruction_simplifier$after_gvn (after)
118   /// CHECK-DAG: <<Intrin:j\d+>> Abs
119   /// CHECK-DAG:                 Return [<<Intrin>>]
sadL3Alt(int x, int y)120   static long sadL3Alt(int x, int y) {
121     long diff = x - y;
122     return 0L <= diff ? diff : -diff;
123   }
124 
main()125   public static void main() {
126     // Use cross-values for the interesting values.
127     int[] interesting = {
128       0x00000000, 0x00000001, 0x00007fff, 0x00008000, 0x00008001, 0x0000ffff,
129       0x00010000, 0x00010001, 0x00017fff, 0x00018000, 0x00018001, 0x0001ffff,
130       0x7fff0000, 0x7fff0001, 0x7fff7fff, 0x7fff8000, 0x7fff8001, 0x7fffffff,
131       0x80000000, 0x80000001, 0x80007fff, 0x80008000, 0x80008001, 0x8000ffff,
132       0x80010000, 0x80010001, 0x80017fff, 0x80018000, 0x80018001, 0x8001ffff,
133       0xffff0000, 0xffff0001, 0xffff7fff, 0xffff8000, 0xffff8001, 0xffffffff
134     };
135     for (int i = 0; i < interesting.length; i++) {
136       for (int j = 0; j < interesting.length; j++) {
137         int x = interesting[i];
138         int y = interesting[j];
139         int e1 = x >= y ? x - y : y - x;  // still select
140         expectEquals(e1, sad1(x, y));
141         int e2 = Math.abs(x - y);  // pure abs
142         expectEquals(e2, sad2(x, y));
143         expectEquals(e2, sad3(x, y));
144         expectEquals(e2, sad3Alt(x, y));
145         long eL1 = Math.abs(((long)x) - ((long)y));  // now, different, but abs
146         expectEquals(eL1, sadL1(x, y));
147         long eL2 = Math.abs((long)(x - y));  // also, different, but abs
148         expectEquals(eL2, sadL2(x, y));
149         expectEquals(eL2, sadL3(x, y));
150         expectEquals(eL2, sadL3Alt(x, y));
151       }
152     }
153     System.out.println("SadInt passed");
154   }
155 
expectEquals(int expected, int result)156   private static void expectEquals(int expected, int result) {
157     if (expected != result) {
158       throw new Error("Expected: " + expected + ", found: " + result);
159     }
160   }
161 
expectEquals(long expected, long result)162   private static void expectEquals(long expected, long result) {
163     if (expected != result) {
164       throw new Error("Expected: " + expected + ", found: " + result);
165     }
166   }
167 }
168