1 /*
2  * Copyright (c) 2017, 2018, 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 package org.graalvm.compiler.replacements.test;
26 
27 import java.util.Arrays;
28 
29 import org.graalvm.compiler.code.CompilationResult;
30 import org.graalvm.compiler.core.test.GraalCompilerTest;
31 import org.graalvm.compiler.nodes.ConstantNode;
32 import org.graalvm.compiler.nodes.StructuredGraph;
33 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
34 import org.junit.Test;
35 
36 import jdk.vm.ci.code.InstalledCode;
37 import jdk.vm.ci.meta.ResolvedJavaMethod;
38 
39 public class FloatArraysEqualsTest extends GraalCompilerTest {
40 
testFloatArraySnippet(float[] a, float[] b)41     public static boolean testFloatArraySnippet(float[] a, float[] b) {
42         return Arrays.equals(a, b);
43     }
44 
testEqualInFloatArray(int arraySize, int index, float f1, float f2)45     private void testEqualInFloatArray(int arraySize, int index, float f1, float f2) {
46         if (arraySize > 0 && index >= 0 && index < arraySize) {
47             float[] a1 = new float[arraySize];
48             float[] a2 = new float[arraySize];
49             a1[index] = f1;
50             a2[index] = f2;
51             test("testFloatArraySnippet", a1, a2);
52         }
53     }
54 
55     public static final int FLOAT_TAIL = 1;
56     public static final int FLOAT_8BYTE_ALIGNED = 2;
57     public static final int FLOAT_8BYTE_UNALIGNED = 3;
58     public static final int FLOAT_VECTOR_ALIGNED = 8;
59     public static final int FLOAT_VECTOR_UNALIGNED = 9;
60 
61     @Test
testFloatArray()62     public void testFloatArray() {
63         for (int size : new int[]{FLOAT_TAIL, FLOAT_8BYTE_ALIGNED, FLOAT_8BYTE_UNALIGNED, FLOAT_VECTOR_ALIGNED, FLOAT_VECTOR_UNALIGNED}) {
64             for (int index : new int[]{0, size - 1}) {
65                 testEqualInFloatArray(size, index, 1024, 1024);
66                 testEqualInFloatArray(size, index, 0.0f, -0.0f);
67                 testEqualInFloatArray(size, index, Float.intBitsToFloat(0x7fc00000), Float.intBitsToFloat(0x7fc00000));
68                 testEqualInFloatArray(size, index, Float.intBitsToFloat(0x7fc00000), Float.intBitsToFloat(0x7f800001));
69                 testEqualInFloatArray(size, index, Float.intBitsToFloat(0x7fc00000), 1024);
70             }
71         }
72     }
73 
testDoubleArraySnippet(double[] a, double[] b)74     public static boolean testDoubleArraySnippet(double[] a, double[] b) {
75         return Arrays.equals(a, b);
76     }
77 
78     public static final int DOUBLE_8BYTE_ALIGNED = 1;
79     public static final int DOUBLE_VECTOR_ALIGNED = 4;
80     public static final int DOUBLE_VECTOR_UNALIGNED = 5;
81 
testEqualInDoubleArray(int arraySize, int index, double d1, double d2)82     private void testEqualInDoubleArray(int arraySize, int index, double d1, double d2) {
83         if (arraySize > 0 && index >= 0 && index < arraySize) {
84             double[] a1 = new double[arraySize];
85             double[] a2 = new double[arraySize];
86             a1[index] = d1;
87             a2[index] = d2;
88             test("testDoubleArraySnippet", a1, a2);
89         }
90     }
91 
92     @Test
testDoubleArrayOrdinary()93     public void testDoubleArrayOrdinary() {
94         for (int size : new int[]{DOUBLE_8BYTE_ALIGNED, DOUBLE_VECTOR_ALIGNED, DOUBLE_VECTOR_UNALIGNED}) {
95             for (int index : new int[]{0, size - 1}) {
96                 testEqualInDoubleArray(size, index, 1024, 1024);
97                 testEqualInDoubleArray(size, index, 0.0d, -0.0d);
98                 testEqualInDoubleArray(size, index, Double.longBitsToDouble(0x7ff8000000000000L), Double.longBitsToDouble(0x7ff8000000000000L));
99                 testEqualInDoubleArray(size, index, Double.longBitsToDouble(0x7ff8000000000000L), Double.longBitsToDouble(0x7ff0000000000001L));
100                 testEqualInDoubleArray(size, index, Double.longBitsToDouble(0x7ff8000000000000L), 1024);
101             }
102         }
103     }
104 
testFloatArrayWithPEASnippet0()105     public static boolean testFloatArrayWithPEASnippet0() {
106         return Arrays.equals(new float[]{0.0f}, new float[]{-0.0f});
107     }
108 
testFloatArrayWithPEASnippet1()109     public static boolean testFloatArrayWithPEASnippet1() {
110         return Arrays.equals(new float[]{Float.intBitsToFloat(0x7fc00000)}, new float[]{Float.intBitsToFloat(0x7fc00000)});
111     }
112 
testFloatArrayWithPEASnippet2()113     public static boolean testFloatArrayWithPEASnippet2() {
114         return Arrays.equals(new float[]{Float.intBitsToFloat(0x7fc00000)}, new float[]{Float.intBitsToFloat(0x7f800001)});
115 
116     }
117 
118     @Test
testFloatArrayWithPEA()119     public void testFloatArrayWithPEA() {
120         test("testFloatArrayWithPEASnippet0");
121         test("testFloatArrayWithPEASnippet1");
122         test("testFloatArrayWithPEASnippet2");
123     }
124 
testDoubleArrayWithPEASnippet0()125     public static boolean testDoubleArrayWithPEASnippet0() {
126         return Arrays.equals(new double[]{0.0d}, new double[]{-0.0d});
127     }
128 
testDoubleArrayWithPEASnippet1()129     public static boolean testDoubleArrayWithPEASnippet1() {
130         return Arrays.equals(new double[]{Double.longBitsToDouble(0x7ff8000000000000L)}, new double[]{Double.longBitsToDouble(0x7ff8000000000000L)});
131     }
132 
testDoubleArrayWithPEASnippet2()133     public static boolean testDoubleArrayWithPEASnippet2() {
134         return Arrays.equals(new double[]{Double.longBitsToDouble(0x7ff8000000000000L)}, new double[]{Double.longBitsToDouble(0x7ff0000000000001L)});
135     }
136 
137     @Test
testDoubleArrayWithPEA()138     public void testDoubleArrayWithPEA() {
139         test("testDoubleArrayWithPEASnippet0");
140         test("testDoubleArrayWithPEASnippet1");
141         test("testDoubleArrayWithPEASnippet2");
142     }
143 
144     public static final float[] FLOAT_ARRAY1 = new float[]{0.0f};
145     public static final float[] FLOAT_ARRAY2 = new float[]{-0.0f};
146     public static final float[] FLOAT_ARRAY3 = new float[]{Float.intBitsToFloat(0x7fc00000)};
147     public static final float[] FLOAT_ARRAY4 = new float[]{Float.intBitsToFloat(0x7f800001)};
148 
149     public static final double[] DOUBLE_ARRAY1 = new double[]{0.0d};
150     public static final double[] DOUBLE_ARRAY2 = new double[]{-0.0d};
151     public static final double[] DOUBLE_ARRAY3 = new double[]{Double.longBitsToDouble(0x7ff8000000000000L)};
152     public static final double[] DOUBLE_ARRAY4 = new double[]{Double.longBitsToDouble(0x7ff0000000000001L)};
153 
testStableFloatArraySnippet0()154     public static boolean testStableFloatArraySnippet0() {
155         return Arrays.equals(FLOAT_ARRAY1, FLOAT_ARRAY2);
156     }
157 
testStableFloatArraySnippet1()158     public static boolean testStableFloatArraySnippet1() {
159         return Arrays.equals(FLOAT_ARRAY1, FLOAT_ARRAY2);
160     }
161 
testStableDoubleArraySnippet0()162     public static boolean testStableDoubleArraySnippet0() {
163         return Arrays.equals(DOUBLE_ARRAY1, DOUBLE_ARRAY2);
164     }
165 
testStableDoubleArraySnippet1()166     public static boolean testStableDoubleArraySnippet1() {
167         return Arrays.equals(DOUBLE_ARRAY3, DOUBLE_ARRAY4);
168     }
169 
testStableArray(String methodName)170     public void testStableArray(String methodName) {
171         ResolvedJavaMethod method = getResolvedJavaMethod(methodName);
172         Result expected = executeExpected(method, null);
173 
174         StructuredGraph graph = parseEager(method, AllowAssumptions.YES);
175 
176         for (ConstantNode constantNode : graph.getNodes().filter(ConstantNode.class).snapshot()) {
177             if (getConstantReflection().readArrayLength(constantNode.asJavaConstant()) != null) {
178                 ConstantNode newConstantNode = ConstantNode.forConstant(constantNode.asJavaConstant(), 1, true, getMetaAccess());
179                 newConstantNode = graph.unique(newConstantNode);
180                 constantNode.replaceAndDelete(newConstantNode);
181             }
182         }
183 
184         CompilationResult result = compile(method, graph);
185         InstalledCode code = addMethod(graph.getDebug(), method, result);
186 
187         Result actual;
188 
189         try {
190             actual = new Result(code.executeVarargs(), null);
191         } catch (Exception e) {
192             actual = new Result(null, e);
193         }
194 
195         assertEquals(expected, actual);
196     }
197 
198     @Test
testStableArray()199     public void testStableArray() {
200         testStableArray("testStableFloatArraySnippet0");
201         testStableArray("testStableFloatArraySnippet1");
202         testStableArray("testStableDoubleArraySnippet0");
203         testStableArray("testStableDoubleArraySnippet1");
204     }
205 
206 }
207