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