mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
264 lines
9.7 KiB
Java
264 lines
9.7 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 java.lang.foreign.*;
|
|
import java.util.*;
|
|
import jdk.test.lib.Asserts;
|
|
import compiler.lib.ir_framework.*;
|
|
|
|
/**
|
|
* @test
|
|
* @bug 8351468
|
|
* @summary Test replacement of array-filling loops with intrinsic calls in the
|
|
* face of matching and mismatching stores.
|
|
* @library /test/lib /
|
|
* @run driver compiler.loopopts.TestArrayFillIntrinsic
|
|
*/
|
|
|
|
public class TestArrayFillIntrinsic {
|
|
|
|
public static void main(String[] args) {
|
|
// Disabling unrolling is necessary for test robustness, otherwise the
|
|
// compiler might decide to unroll the array-filling loop instead of
|
|
// replacing it with an intrinsic call even if OptimizeFill is enabled.
|
|
TestFramework framework = new TestFramework();
|
|
framework.addScenarios(new Scenario(0),
|
|
new Scenario(1, "-XX:LoopUnrollLimit=0", "-XX:+OptimizeFill"));
|
|
framework.start();
|
|
}
|
|
|
|
@Test
|
|
@IR(applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"},
|
|
applyIfAnd = {"LoopUnrollLimit", "0", "OptimizeFill", "true"},
|
|
counts = {IRNode.CALL_OF, "(arrayof_)?jbyte_fill", "1"})
|
|
static void testFillBooleanArray(boolean[] array, boolean val) {
|
|
for (int i = 0; i < array.length; i++) {
|
|
array[i] = val;
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"},
|
|
applyIfAnd = {"LoopUnrollLimit", "0", "OptimizeFill", "true"},
|
|
counts = {IRNode.CALL_OF, "(arrayof_)?jbyte_fill", "1"})
|
|
static void testFillByteArray(byte[] array, byte val) {
|
|
for (int i = 0; i < array.length; i++) {
|
|
array[i] = val;
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"},
|
|
applyIfAnd = {"LoopUnrollLimit", "0", "OptimizeFill", "true"},
|
|
counts = {IRNode.CALL_OF, "(arrayof_)?jshort_fill", "1"})
|
|
static void testFillCharArray(char[] array, char val) {
|
|
for (int i = 0; i < array.length; i++) {
|
|
array[i] = val;
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"},
|
|
applyIfAnd = {"LoopUnrollLimit", "0", "OptimizeFill", "true"},
|
|
counts = {IRNode.CALL_OF, "(arrayof_)?jshort_fill", "1"})
|
|
static void testFillShortArray(short[] array, short val) {
|
|
for (int i = 0; i < array.length; i++) {
|
|
array[i] = val;
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"},
|
|
applyIfAnd = {"LoopUnrollLimit", "0", "OptimizeFill", "true"},
|
|
counts = {IRNode.CALL_OF, "(arrayof_)?jint_fill", "1"})
|
|
static void testFillIntArray(int[] array, int val) {
|
|
for (int i = 0; i < array.length; i++) {
|
|
array[i] = val;
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"},
|
|
applyIfAnd = {"LoopUnrollLimit", "0", "OptimizeFill", "true"},
|
|
counts = {IRNode.CALL_OF, "(arrayof_)?jint_fill", "1"})
|
|
static void testFillFloatArray(float[] array, float val) {
|
|
for (int i = 0; i < array.length; i++) {
|
|
array[i] = val;
|
|
}
|
|
}
|
|
|
|
@Run(test = {"testFillByteArray",
|
|
"testFillBooleanArray",
|
|
"testFillCharArray",
|
|
"testFillShortArray",
|
|
"testFillIntArray",
|
|
"testFillFloatArray"})
|
|
public void runPositiveTests() {
|
|
Random r = RunInfo.getRandom();
|
|
int N = r.ints(1, 1024).findFirst().getAsInt();
|
|
{
|
|
boolean[] array = new boolean[N];
|
|
boolean val = r.nextBoolean();
|
|
testFillBooleanArray(array, val);
|
|
for (int i = 0; i < array.length; i++) {
|
|
Asserts.assertEquals(val, array[i]);
|
|
}
|
|
}
|
|
{
|
|
byte[] array = new byte[N];
|
|
byte val = (byte)r.nextInt();
|
|
testFillByteArray(array, val);
|
|
for (int i = 0; i < array.length; i++) {
|
|
Asserts.assertEquals(val, array[i]);
|
|
}
|
|
}
|
|
{
|
|
char[] array = new char[N];
|
|
char val = (char)r.nextInt();
|
|
testFillCharArray(array, val);
|
|
for (int i = 0; i < array.length; i++) {
|
|
Asserts.assertEquals(val, array[i]);
|
|
}
|
|
}
|
|
{
|
|
short[] array = new short[N];
|
|
short val = (short)r.nextInt();
|
|
testFillShortArray(array, val);
|
|
for (int i = 0; i < array.length; i++) {
|
|
Asserts.assertEquals(val, array[i]);
|
|
}
|
|
}
|
|
{
|
|
int[] array = new int[N];
|
|
int val = r.nextInt();
|
|
testFillIntArray(array, val);
|
|
for (int i = 0; i < array.length; i++) {
|
|
Asserts.assertEquals(val, array[i]);
|
|
}
|
|
}
|
|
{
|
|
float[] array = new float[N];
|
|
float val = r.nextFloat();
|
|
testFillFloatArray(array, val);
|
|
for (int i = 0; i < array.length; i++) {
|
|
Asserts.assertEquals(val, array[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(failOn = {IRNode.CALL_OF, "(arrayof_)?.*_fill"})
|
|
static void testFillShortArrayWithByte(MemorySegment array, int n, byte val) {
|
|
for (int i = 0; i < n; i++) {
|
|
array.setAtIndex(ValueLayout.JAVA_BYTE, i, val);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(failOn = {IRNode.CALL_OF, "(arrayof_)?.*_fill"})
|
|
static void testFillIntArrayWithByte(MemorySegment array, int n, byte val) {
|
|
for (int i = 0; i < n; i++) {
|
|
array.setAtIndex(ValueLayout.JAVA_BYTE, i, val);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(failOn = {IRNode.CALL_OF, "(arrayof_)?.*_fill"})
|
|
static void testFillIntArrayWithShort(MemorySegment array, int n, short val) {
|
|
for (int i = 0; i < n; i++) {
|
|
array.setAtIndex(ValueLayout.JAVA_SHORT, i, val);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(failOn = {IRNode.CALL_OF, "(arrayof_)?.*_fill"})
|
|
static void testFillByteArrayWithBoolean(MemorySegment array, int n, boolean val) {
|
|
for (int i = 0; i < n; i++) {
|
|
array.setAtIndex(ValueLayout.JAVA_BOOLEAN, i, val);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(failOn = {IRNode.CALL_OF, "(arrayof_)?.*_fill"})
|
|
static void testFillShortArrayWithChar(MemorySegment array, int n, char val) {
|
|
for (int i = 0; i < n; i++) {
|
|
array.setAtIndex(ValueLayout.JAVA_CHAR, i, val);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(failOn = {IRNode.CALL_OF, "(arrayof_)?.*_fill"})
|
|
static void testFillCharArrayWithShort(MemorySegment array, int n, short val) {
|
|
for (int i = 0; i < n; i++) {
|
|
array.setAtIndex(ValueLayout.JAVA_SHORT, i, val);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(failOn = {IRNode.CALL_OF, "(arrayof_)?.*_fill"})
|
|
static void testFillIntArrayWithFloat(MemorySegment array, int n, float val) {
|
|
for (int i = 0; i < n; i++) {
|
|
array.setAtIndex(ValueLayout.JAVA_FLOAT, i, val);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(failOn = {IRNode.CALL_OF, "(arrayof_)?.*_fill"})
|
|
static void testFillFloatArrayWithInt(MemorySegment array, int n, int val) {
|
|
for (int i = 0; i < n; i++) {
|
|
array.setAtIndex(ValueLayout.JAVA_INT, i, val);
|
|
}
|
|
}
|
|
|
|
@Run(test = {"testFillShortArrayWithByte",
|
|
"testFillIntArrayWithByte",
|
|
"testFillIntArrayWithShort",
|
|
"testFillByteArrayWithBoolean",
|
|
"testFillShortArrayWithChar",
|
|
"testFillCharArrayWithShort",
|
|
"testFillIntArrayWithFloat",
|
|
"testFillFloatArrayWithInt"})
|
|
public void runTypeMismatchTests() {
|
|
Random r = RunInfo.getRandom();
|
|
int N = r.ints(1, 1024).findFirst().getAsInt();
|
|
testFillShortArrayWithByte(MemorySegment.ofArray(new short[N]), N,
|
|
(byte)r.nextInt());
|
|
testFillIntArrayWithByte(MemorySegment.ofArray(new int[N]), N,
|
|
(byte)r.nextInt());
|
|
testFillIntArrayWithShort(MemorySegment.ofArray(new int[N]), N,
|
|
(short)r.nextInt());
|
|
testFillByteArrayWithBoolean(MemorySegment.ofArray(new byte[N]), N,
|
|
r.nextBoolean());
|
|
testFillShortArrayWithChar(MemorySegment.ofArray(new short[N]), N,
|
|
(char)r.nextInt());
|
|
testFillCharArrayWithShort(MemorySegment.ofArray(new char[N]), N,
|
|
(short)r.nextInt());
|
|
testFillIntArrayWithFloat(MemorySegment.ofArray(new int[N]), N,
|
|
r.nextFloat());
|
|
testFillFloatArrayWithInt(MemorySegment.ofArray(new float[N]), N,
|
|
r.nextInt());
|
|
}
|
|
}
|