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