mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
213 lines
7.0 KiB
Java
213 lines
7.0 KiB
Java
/*
|
|
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
|
|
package compiler.loopopts;
|
|
|
|
import jdk.test.lib.Asserts;
|
|
|
|
/**
|
|
* @test
|
|
* @bug 8351468
|
|
* @summary Test that loads anti-dependent on array fill intrinsics are
|
|
* scheduled correctly, for different load and array fill types.
|
|
* See detailed comments in testShort() below.
|
|
* @library /test/lib
|
|
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions
|
|
* -Xbatch -XX:-TieredCompilation
|
|
* -XX:CompileOnly=compiler.loopopts.TestArrayFillAntiDependence::test*
|
|
* -XX:CompileCommand=quiet -XX:LoopUnrollLimit=0 -XX:+OptimizeFill
|
|
* compiler.loopopts.TestArrayFillAntiDependence
|
|
* @run main/othervm compiler.loopopts.TestArrayFillAntiDependence
|
|
*/
|
|
|
|
public class TestArrayFillAntiDependence {
|
|
|
|
static int N = 10;
|
|
static short M = 4;
|
|
static boolean BOOLEAN_VAL = true;
|
|
static char CHAR_VAL = 42;
|
|
static float FLOAT_VAL = 42.0f;
|
|
static double DOUBLE_VAL = 42.0;
|
|
static byte BYTE_VAL = 42;
|
|
static short SHORT_VAL = 42;
|
|
static int INT_VAL = 42;
|
|
static long LONG_VAL = 42;
|
|
|
|
static boolean testBoolean(int pos, int samePos) {
|
|
assert pos == samePos;
|
|
boolean total = false;
|
|
boolean[] array = new boolean[N];
|
|
array[pos] = BOOLEAN_VAL;
|
|
for (int i = 0; i < M; i++) {
|
|
total |= array[samePos];
|
|
for (int t = 0; t < array.length; t++) {
|
|
array[t] = false;
|
|
}
|
|
}
|
|
return total;
|
|
}
|
|
|
|
static char testChar(int pos, int samePos) {
|
|
assert pos == samePos;
|
|
char total = 0;
|
|
char[] array = new char[N];
|
|
array[pos] = CHAR_VAL;
|
|
for (int i = 0; i < M; i++) {
|
|
total += array[samePos];
|
|
for (int t = 0; t < array.length; t++) {
|
|
array[t] = 0;
|
|
}
|
|
}
|
|
return total;
|
|
}
|
|
|
|
static float testFloat(int pos, int samePos) {
|
|
assert pos == samePos;
|
|
float total = 0.0f;
|
|
float[] array = new float[N];
|
|
array[pos] = FLOAT_VAL;
|
|
for (int i = 0; i < M; i++) {
|
|
total += array[samePos];
|
|
for (int t = 0; t < array.length; t++) {
|
|
array[t] = 0.0f;
|
|
}
|
|
}
|
|
return total;
|
|
}
|
|
|
|
static double testDouble(int pos, int samePos) {
|
|
assert pos == samePos;
|
|
double total = 0.0;
|
|
double[] array = new double[N];
|
|
array[pos] = DOUBLE_VAL;
|
|
for (int i = 0; i < M; i++) {
|
|
total += array[samePos];
|
|
for (int t = 0; t < array.length; t++) {
|
|
array[t] = 0.0;
|
|
}
|
|
}
|
|
return total;
|
|
}
|
|
|
|
static byte testByte(int pos, int samePos) {
|
|
assert pos == samePos;
|
|
byte total = 0;
|
|
byte[] array = new byte[N];
|
|
array[pos] = BYTE_VAL;
|
|
for (int i = 0; i < M; i++) {
|
|
total += array[samePos];
|
|
for (int t = 0; t < array.length; t++) {
|
|
array[t] = 0;
|
|
}
|
|
}
|
|
return total;
|
|
}
|
|
|
|
static short testShort(int pos, int samePos) {
|
|
// This pre-condition is necessary to reproduce the miscompilation, but
|
|
// should not be exploited by C2 for optimization.
|
|
assert pos == samePos;
|
|
short total = 0;
|
|
short[] array = new short[N];
|
|
array[pos] = SHORT_VAL;
|
|
for (int i = 0; i < M; i++) {
|
|
// This load is wrongly scheduled after the loop below, which is
|
|
// transformed into a call to arrayof_jshort_fill and clears the
|
|
// entire array. As a consequence, the function returns 0 instead of
|
|
// the expected SHORT_VAL.
|
|
// The load is wrongly allowed to be moved beyond the loop
|
|
// (arrayof_jshort_fill call) because their anti-dependence is
|
|
// missed. This is because the call operates on a different memory
|
|
// slice (char[] instead of the expected short[]).
|
|
total += array[samePos];
|
|
for (int t = 0; t < array.length; t++) {
|
|
array[t] = 0;
|
|
}
|
|
}
|
|
return total;
|
|
}
|
|
|
|
static int testInt(int pos, int samePos) {
|
|
assert pos == samePos;
|
|
int total = 0;
|
|
int[] array = new int[N];
|
|
array[pos] = INT_VAL;
|
|
for (int i = 0; i < M; i++) {
|
|
total += array[samePos];
|
|
for (int t = 0; t < array.length; t++) {
|
|
array[t] = 0;
|
|
}
|
|
}
|
|
return total;
|
|
}
|
|
|
|
static long testLong(int pos, int samePos) {
|
|
assert pos == samePos;
|
|
long total = 0;
|
|
long[] array = new long[N];
|
|
array[pos] = LONG_VAL;
|
|
for (int i = 0; i < M; i++) {
|
|
total += array[samePos];
|
|
for (int t = 0; t < array.length; t++) {
|
|
array[t] = 0;
|
|
}
|
|
}
|
|
return total;
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
for (int i = 0; i < 10_000; i++) {
|
|
boolean result = testBoolean(0, 0);
|
|
Asserts.assertEquals(BOOLEAN_VAL, result);
|
|
}
|
|
for (int i = 0; i < 10_000; i++) {
|
|
char result = testChar(0, 0);
|
|
Asserts.assertEquals(CHAR_VAL, result);
|
|
}
|
|
for (int i = 0; i < 10_000; i++) {
|
|
float result = testFloat(0, 0);
|
|
Asserts.assertEquals(FLOAT_VAL, result);
|
|
}
|
|
for (int i = 0; i < 10_000; i++) {
|
|
double result = testDouble(0, 0);
|
|
Asserts.assertEquals(DOUBLE_VAL, result);
|
|
}
|
|
for (int i = 0; i < 10_000; i++) {
|
|
byte result = testByte(0, 0);
|
|
Asserts.assertEquals(BYTE_VAL, result);
|
|
}
|
|
for (int i = 0; i < 10_000; i++) {
|
|
short result = testShort(0, 0);
|
|
Asserts.assertEquals(SHORT_VAL, result);
|
|
}
|
|
for (int i = 0; i < 10_000; i++) {
|
|
int result = testInt(0, 0);
|
|
Asserts.assertEquals(INT_VAL, result);
|
|
}
|
|
for (int i = 0; i < 10_000; i++) {
|
|
long result = testLong(0, 0);
|
|
Asserts.assertEquals(LONG_VAL, result);
|
|
}
|
|
}
|
|
}
|