1/*
2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/**
25 * @test
26 * @bug 8160425
27 * @summary Test vectorization with a signalling NaN.
28 * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-OptimizeFill
29 *      compiler.vectorization.TestNaNVector
30 * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-OptimizeFill
31 *      -XX:MaxVectorSize=4 compiler.vectorization.TestNaNVector
32 */
33
34package compiler.vectorization;
35
36public class TestNaNVector {
37    private char[] array;
38    private static final int LEN = 1024;
39
40    public static void main(String args[]) {
41        TestNaNVector test = new TestNaNVector();
42        // Check double precision NaN
43        for (int i = 0; i < 10_000; ++i) {
44          test.vectorizeNaNDP();
45        }
46        System.out.println("Checking double precision Nan");
47        test.checkResult(0xfff7);
48
49        // Check single precision NaN
50        for (int i = 0; i < 10_000; ++i) {
51          test.vectorizeNaNSP();
52        }
53        System.out.println("Checking single precision Nan");
54        test.checkResult(0xff80);
55    }
56
57    public TestNaNVector() {
58        array = new char[LEN];
59    }
60
61    public void vectorizeNaNDP() {
62        // This loop will be vectorized and the array store will be replaced by
63        // a 64-bit vector store to four subsequent array elements. The vector
64        // should look like this '0xfff7fff7fff7fff7' and is read from the constant
65        // table. However, in floating point arithmetic this is a signalling NaN
66        // which may be converted to a quiet NaN when processed by the x87 FPU.
67        // If the signalling bit is set, the vector ends up in the constant table
68        // as '0xfffffff7fff7fff7' which leads to an incorrect result.
69        for (int i = 0; i < LEN; ++i) {
70            array[i] = 0xfff7;
71        }
72    }
73
74    public void vectorizeNaNSP() {
75        // Same as above but with single precision
76        for (int i = 0; i < LEN; ++i) {
77            array[i] = 0xff80;
78        }
79    }
80
81    public void checkResult(int expected) {
82        for (int i = 0; i < LEN; ++i) {
83            if (array[i] != expected) {
84                throw new RuntimeException("Invalid result: array[" + i + "] = " + (int)array[i] + " != " + expected);
85            }
86        }
87    }
88}
89
90