diff options
| -rw-r--r-- | test/631-checker-fp-abs/expected.txt | 1 | ||||
| -rw-r--r-- | test/631-checker-fp-abs/info.txt | 1 | ||||
| -rw-r--r-- | test/631-checker-fp-abs/src/Main.java | 163 |
3 files changed, 165 insertions, 0 deletions
diff --git a/test/631-checker-fp-abs/expected.txt b/test/631-checker-fp-abs/expected.txt new file mode 100644 index 0000000000..b0aad4deb5 --- /dev/null +++ b/test/631-checker-fp-abs/expected.txt @@ -0,0 +1 @@ +passed diff --git a/test/631-checker-fp-abs/info.txt b/test/631-checker-fp-abs/info.txt new file mode 100644 index 0000000000..0a1499e72c --- /dev/null +++ b/test/631-checker-fp-abs/info.txt @@ -0,0 +1 @@ +Tests on floating-point Math.abs. diff --git a/test/631-checker-fp-abs/src/Main.java b/test/631-checker-fp-abs/src/Main.java new file mode 100644 index 0000000000..eef52965c2 --- /dev/null +++ b/test/631-checker-fp-abs/src/Main.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * A few tests of Math.abs for floating-point data. + */ +public class Main { + + public static boolean doThrow = false; + + /// CHECK-START: float Main.$opt$noinline$absSP(float) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:f\d+>> InvokeStaticOrDirect intrinsic:MathAbsFloat + /// CHECK-DAG: Return [<<Result>>] + private static float $opt$noinline$absSP(float f) { + if (doThrow) { + throw new Error("Something to prevent inlining"); + } + return Math.abs(f); + } + + /// CHECK-START: double Main.$opt$noinline$absDP(double) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:d\d+>> InvokeStaticOrDirect intrinsic:MathAbsDouble + /// CHECK-DAG: Return [<<Result>>] + private static double $opt$noinline$absDP(double d) { + if (doThrow) { + throw new Error("Something to prevent inlining"); + } + return Math.abs(d); + } + + public static void main(String args[]) { + // A few obvious numbers. + for (float f = -100.0f; f < 0.0f; f += 0.5f) { + expectEqualsSP(-f, $opt$noinline$absSP(f)); + } + for (float f = 0.0f; f <= 100.0f; f += 0.5f) { + expectEqualsSP(f, $opt$noinline$absSP(f)); + } + for (float f = -1.5f; f <= -1.499f; f = Math.nextAfter(f, Float.POSITIVE_INFINITY)) { + expectEqualsSP(-f, $opt$noinline$absSP(f)); + } + for (float f = 1.499f; f <= 1.5f; f = Math.nextAfter(f, Float.POSITIVE_INFINITY)) { + expectEqualsSP(f, $opt$noinline$absSP(f)); + } + + // Zero + expectEquals32(0, Float.floatToRawIntBits($opt$noinline$absSP(+0.0f))); + expectEquals32(0, Float.floatToRawIntBits($opt$noinline$absSP(-0.0f))); + + // Inf. + expectEqualsSP(Float.POSITIVE_INFINITY, $opt$noinline$absSP(Float.NEGATIVE_INFINITY)); + expectEqualsSP(Float.POSITIVE_INFINITY, $opt$noinline$absSP(Float.POSITIVE_INFINITY)); + + // A few NaN numbers. + // + // Note, as a "quality of implementation" rather than pure "spec compliance" we require that + // Math.abs() clears the sign bit (but nothing else) for all NaN numbers. This requirement + // should hold regardless of whether Art uses the interpreter, library, or compiler. + // + int[] spnans = { + 0x7f800001, + 0x7fa00000, + 0x7fc00000, + 0x7fffffff, + 0xff800001, + 0xffa00000, + 0xffc00000, + 0xffffffff + }; + for (int i = 0; i < spnans.length; i++) { + float f = Float.intBitsToFloat(spnans[i]); + expectEquals32( + spnans[i] & Integer.MAX_VALUE, + Float.floatToRawIntBits($opt$noinline$absSP(f))); + } + + // A few obvious numbers. + for (double d = -100.0; d < 0.0; d += 0.5) { + expectEqualsDP(-d, $opt$noinline$absDP(d)); + } + for (double d = 0.0; d <= 100.0; d += 0.5) { + expectEqualsDP(d, $opt$noinline$absDP(d)); + } + for (double d = -1.5d; d <= -1.49999999999d; d = Math.nextAfter(d, Double.POSITIVE_INFINITY)) { + expectEqualsDP(-d, $opt$noinline$absDP(d)); + } + for (double d = 1.49999999999d; d <= 1.5; d = Math.nextAfter(d, Double.POSITIVE_INFINITY)) { + expectEqualsDP(d, $opt$noinline$absDP(d)); + } + + // Zero + expectEquals64(0L, Double.doubleToRawLongBits($opt$noinline$absDP(+0.0f))); + expectEquals64(0L, Double.doubleToRawLongBits($opt$noinline$absDP(-0.0f))); + + // Inf. + expectEqualsDP(Double.POSITIVE_INFINITY, $opt$noinline$absDP(Double.NEGATIVE_INFINITY)); + expectEqualsDP(Double.POSITIVE_INFINITY, $opt$noinline$absDP(Double.POSITIVE_INFINITY)); + + // A few NaN numbers. + // + // Note, as a "quality of implementation" rather than pure "spec compliance" we require that + // Math.abs() clears the sign bit (but nothing else) for all NaN numbers. This requirement + // should hold regardless of whether Art uses the interpreter, library, or compiler. + // + long[] dpnans = { + 0x7ff0000000000001L, + 0x7ff4000000000000L, + 0x7ff8000000000000L, + 0x7fffffffffffffffL, + 0xfff0000000000001L, + 0xfff4000000000000L, + 0xfff8000000000000L, + 0xffffffffffffffffL + }; + for (int i = 0; i < dpnans.length; i++) { + double d = Double.longBitsToDouble(dpnans[i]); + expectEquals64( + dpnans[i] & Long.MAX_VALUE, + Double.doubleToRawLongBits($opt$noinline$absDP(d))); + } + + System.out.println("passed"); + } + + private static void expectEquals32(int expected, int result) { + if (expected != result) { + throw new Error("Expected: 0x" + Integer.toHexString(expected) + + ", found: 0x" + Integer.toHexString(result)); + } + } + + private static void expectEquals64(long expected, long result) { + if (expected != result) { + throw new Error("Expected: 0x" + Long.toHexString(expected) + + ", found: 0x" + Long.toHexString(result)); + } + } + + private static void expectEqualsSP(float expected, float result) { + if (expected != result) { + throw new Error("Expected: " + expected + ", found: " + result); + } + } + + private static void expectEqualsDP(double expected, double result) { + if (expected != result) { + throw new Error("Expected: " + expected + ", found: " + result); + } + } +} |