|
1 | 1 | /*
|
2 |
| - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
4 | 4 | *
|
5 | 5 | * This code is free software; you can redistribute it and/or modify it
|
|
24 | 24 | */
|
25 | 25 | package jdk.graal.compiler.truffle.test;
|
26 | 26 |
|
27 |
| -import jdk.graal.compiler.nodes.calc.RoundNode; |
28 |
| -import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugins; |
29 |
| -import jdk.graal.compiler.truffle.substitutions.TruffleGraphBuilderPlugins; |
| 27 | +import java.util.Arrays; |
| 28 | + |
30 | 29 | import org.junit.Assert;
|
31 | 30 | import org.junit.Assume;
|
32 | 31 | import org.junit.Test;
|
33 | 32 |
|
34 | 33 | import com.oracle.truffle.api.ExactMath;
|
35 | 34 |
|
| 35 | +import jdk.graal.compiler.nodes.calc.RoundNode; |
| 36 | +import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugins; |
| 37 | +import jdk.graal.compiler.truffle.substitutions.TruffleGraphBuilderPlugins; |
36 | 38 | import jdk.vm.ci.amd64.AMD64;
|
37 | 39 |
|
38 | 40 | public class ExactMathTest extends TruffleCompilerImplTest {
|
@@ -194,6 +196,96 @@ public void testTruncateDoubleIntrinsified() {
|
194 | 196 | Assert.assertEquals(1, getFinalGraph("truncateFloat").getNodes().filter(RoundNode.class).count());
|
195 | 197 | }
|
196 | 198 |
|
| 199 | + @Test |
| 200 | + public void testDoubleToUnsigned() { |
| 201 | + for (String methodName : Arrays.asList("truncateDoubleToUnsignedLong", "truncateDoubleToUnsignedInt")) { |
| 202 | + test(methodName, Double.NEGATIVE_INFINITY); |
| 203 | + test(methodName, -1.0); |
| 204 | + test(methodName, Math.nextUp(-1.0)); |
| 205 | + test(methodName, -Double.MIN_VALUE); |
| 206 | + test(methodName, -0.0); |
| 207 | + test(methodName, 0.0); |
| 208 | + test(methodName, Double.MIN_VALUE); |
| 209 | + test(methodName, 0.5); |
| 210 | + test(methodName, 1.0); |
| 211 | + test(methodName, 1.5); |
| 212 | + test(methodName, Math.nextDown(0x1p31)); |
| 213 | + test(methodName, 0x1p31); |
| 214 | + test(methodName, Math.nextDown(0x1p32)); |
| 215 | + test(methodName, 0x1p32); |
| 216 | + test(methodName, 0x1p52 - 1.0); |
| 217 | + test(methodName, 0x1p52 - 0.5); // largest representable non-integral value |
| 218 | + test(methodName, 0x1p52); |
| 219 | + test(methodName, 0x1p53 - 1.0); // largest exactly representable integral value |
| 220 | + test(methodName, 0x1p53); |
| 221 | + test(methodName, 0x1p63); |
| 222 | + test(methodName, Math.nextDown(0x1p64)); |
| 223 | + test(methodName, 0x1p64); |
| 224 | + test(methodName, Double.MAX_VALUE); |
| 225 | + test(methodName, Double.POSITIVE_INFINITY); |
| 226 | + test(methodName, Double.NaN); |
| 227 | + test(methodName, Double.longBitsToDouble(0x7ff0000000000001L)); // signaling NaN |
| 228 | + } |
| 229 | + } |
| 230 | + |
| 231 | + @Test |
| 232 | + public void testFloatToUnsigned() { |
| 233 | + for (String methodName : Arrays.asList("truncateFloatToUnsignedLong", "truncateFloatToUnsignedInt")) { |
| 234 | + test(methodName, Float.NEGATIVE_INFINITY); |
| 235 | + test(methodName, -1.0f); |
| 236 | + test(methodName, Math.nextUp(-1.0f)); |
| 237 | + test(methodName, -Float.MIN_VALUE); |
| 238 | + test(methodName, -0.0f); |
| 239 | + test(methodName, 0.0f); |
| 240 | + test(methodName, Float.MIN_VALUE); |
| 241 | + test(methodName, 0.5f); |
| 242 | + test(methodName, 1.0f); |
| 243 | + test(methodName, 1.5f); |
| 244 | + test(methodName, 0x1p23f - 1.0f); |
| 245 | + test(methodName, 0x1p23f - 0.5f); // largest representable non-integral value |
| 246 | + test(methodName, 0x1p23f); |
| 247 | + test(methodName, 0x1p24f - 1.0f); // largest exactly representable integral value |
| 248 | + test(methodName, 0x1p24f); |
| 249 | + test(methodName, Math.nextDown(0x1p31f)); |
| 250 | + test(methodName, 0x1p31f); |
| 251 | + test(methodName, Math.nextDown(0x1p32f)); |
| 252 | + test(methodName, 0x1p32f); |
| 253 | + test(methodName, 0x1p63f); |
| 254 | + test(methodName, Math.nextDown(0x1p64f)); |
| 255 | + test(methodName, 0x1p64f); |
| 256 | + test(methodName, Float.MAX_VALUE); |
| 257 | + test(methodName, Float.POSITIVE_INFINITY); |
| 258 | + test(methodName, Float.NaN); |
| 259 | + test(methodName, Float.intBitsToFloat(0x7f800001)); // signaling NaN |
| 260 | + } |
| 261 | + } |
| 262 | + |
| 263 | + @Test |
| 264 | + public void testUnsignedLongToFloat() { |
| 265 | + for (String methodName : Arrays.asList("unsignedLongToFloat", "unsignedLongToDouble")) { |
| 266 | + test(methodName, 0L); |
| 267 | + test(methodName, 1L); |
| 268 | + test(methodName, (long) Integer.MAX_VALUE); |
| 269 | + test(methodName, 1L << 31); |
| 270 | + test(methodName, (1L << 32) - 1L); |
| 271 | + test(methodName, 1L << 32); |
| 272 | + test(methodName, 0x0020000020000000L); |
| 273 | + test(methodName, 0x0020000020000001L); |
| 274 | + test(methodName, 0x7fffffbfffffffffL); |
| 275 | + test(methodName, 0x7fffffc000000000L); |
| 276 | + test(methodName, 0x7ffffffffffffdffL); |
| 277 | + test(methodName, 0x7ffffffffffffc00L); |
| 278 | + test(methodName, Long.MAX_VALUE); |
| 279 | + test(methodName, Long.MIN_VALUE); |
| 280 | + test(methodName, 0x8000008000000001L); |
| 281 | + test(methodName, 0xfffffe8000000001L); |
| 282 | + test(methodName, 0xfffffe8000000002L); |
| 283 | + test(methodName, 0xfffffffffffff401L); |
| 284 | + test(methodName, 0xfffffffffffff402L); |
| 285 | + test(methodName, 0xffffffffffffffffL); |
| 286 | + } |
| 287 | + } |
| 288 | + |
197 | 289 | public static int add(int a, int b) {
|
198 | 290 | return Math.addExact(a, b);
|
199 | 291 | }
|
@@ -273,4 +365,28 @@ public static float truncateFloat(float a) {
|
273 | 365 | public static double truncateDouble(double a) {
|
274 | 366 | return ExactMath.truncate(a);
|
275 | 367 | }
|
| 368 | + |
| 369 | + public static long truncateDoubleToUnsignedLong(double x) { |
| 370 | + return ExactMath.truncateToUnsignedLong(x); |
| 371 | + } |
| 372 | + |
| 373 | + public static long truncateFloatToUnsignedLong(float x) { |
| 374 | + return ExactMath.truncateToUnsignedLong(x); |
| 375 | + } |
| 376 | + |
| 377 | + public static int truncateDoubleToUnsignedInt(double x) { |
| 378 | + return ExactMath.truncateToUnsignedInt(x); |
| 379 | + } |
| 380 | + |
| 381 | + public static int truncateFloatToUnsignedInt(float x) { |
| 382 | + return ExactMath.truncateToUnsignedInt(x); |
| 383 | + } |
| 384 | + |
| 385 | + public static double unsignedLongToDouble(long x) { |
| 386 | + return ExactMath.unsignedToDouble(x); |
| 387 | + } |
| 388 | + |
| 389 | + public static float unsignedLongToFloat(long x) { |
| 390 | + return ExactMath.unsignedToFloat(x); |
| 391 | + } |
276 | 392 | }
|
0 commit comments