< prev index next > test/hotspot/jtreg/compiler/c2/cmove/TestScalarConditionalMoveCmpObj.java
Print this page
/*
* Copyright (c) 2025, Rivos Inc. All rights reserved.
+ * Copyright (c) 2026, 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.
* 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.c2.irTests;
import compiler.lib.ir_framework.*;
import java.util.Random;
import jdk.test.lib.Asserts;
import jdk.test.lib.Utils;
* 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.c2.cmove;
import compiler.lib.ir_framework.*;
import java.util.Random;
import jdk.test.lib.Asserts;
import jdk.test.lib.Utils;
"-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:+UseCompressedOops");
TestFramework.runWithFlags("-XX:+UseCMoveUnconditionally", "-XX:-UseVectorCmov",
"-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:-UseCompressedOops");
}
+ // While a value of type Object can be a value object, a value of type NotValue
+ // cannot since it is a non-abstract non-value class and so cannot be the base
+ // class of a value class. This makes sure that comparisons between values of
+ // this type are simply pointer comparisons, and not substitutability
+ static class NotValue {}
+
// Object comparison
// O for I
private int cmoveOEQforI(Object a, Object b, int c, int d) {
return (a == b) ? c : d;
}
@IR(failOn = {IRNode.STORE_VECTOR})
@IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_P, ">0"},
applyIf = {"UseCompressedOops", "false"})
@IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_N, ">0"},
applyIf = {"UseCompressedOops", "true"})
! private static void testCMoveOEQforI(Object[] a, Object[] b, int[] c, int[] d, int[] r, int[] r2) {
for (int i = 0; i < a.length; i++) {
int cc = c[i];
int dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] == b[i]) ? cc : dd;
@IR(failOn = {IRNode.STORE_VECTOR})
@IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_P, ">0"},
applyIf = {"UseCompressedOops", "false"})
@IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_N, ">0"},
applyIf = {"UseCompressedOops", "true"})
! private static void testCMoveOEQforI(NotValue[] a, NotValue[] b, int[] c, int[] d, int[] r, int[] r2) {
for (int i = 0; i < a.length; i++) {
int cc = c[i];
int dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] == b[i]) ? cc : dd;
@IR(failOn = {IRNode.STORE_VECTOR})
@IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_P, ">0"},
applyIf = {"UseCompressedOops", "false"})
@IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_N, ">0"},
applyIf = {"UseCompressedOops", "true"})
! private static void testCMoveONEforI(Object[] a, Object[] b, int[] c, int[] d, int[] r, int[] r2) {
for (int i = 0; i < a.length; i++) {
int cc = c[i];
int dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] != b[i]) ? cc : dd;
@IR(failOn = {IRNode.STORE_VECTOR})
@IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_P, ">0"},
applyIf = {"UseCompressedOops", "false"})
@IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_N, ">0"},
applyIf = {"UseCompressedOops", "true"})
! private static void testCMoveONEforI(NotValue[] a, NotValue[] b, int[] c, int[] d, int[] r, int[] r2) {
for (int i = 0; i < a.length; i++) {
int cc = c[i];
int dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] != b[i]) ? cc : dd;
@IR(failOn = {IRNode.STORE_VECTOR})
// @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_P, ">0"},
// applyIf = {"UseCompressedOops", "false"})
// @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_N, ">0"},
// applyIf = {"UseCompressedOops", "true"})
! private static void testCMoveOEQforL(Object[] a, Object[] b, long[] c, long[] d, long[] r, long[] r2) {
for (int i = 0; i < a.length; i++) {
long cc = c[i];
long dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] == b[i]) ? cc : dd;
@IR(failOn = {IRNode.STORE_VECTOR})
// @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_P, ">0"},
// applyIf = {"UseCompressedOops", "false"})
// @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_N, ">0"},
// applyIf = {"UseCompressedOops", "true"})
! private static void testCMoveOEQforL(NotValue[] a, NotValue[] b, long[] c, long[] d, long[] r, long[] r2) {
for (int i = 0; i < a.length; i++) {
long cc = c[i];
long dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] == b[i]) ? cc : dd;
@IR(failOn = {IRNode.STORE_VECTOR})
// @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_P, ">0"},
// applyIf = {"UseCompressedOops", "false"})
// @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_N, ">0"},
// applyIf = {"UseCompressedOops", "true"})
! private static void testCMoveONEforL(Object[] a, Object[] b, long[] c, long[] d, long[] r, long[] r2) {
for (int i = 0; i < a.length; i++) {
long cc = c[i];
long dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] != b[i]) ? cc : dd;
@IR(failOn = {IRNode.STORE_VECTOR})
// @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_P, ">0"},
// applyIf = {"UseCompressedOops", "false"})
// @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_N, ">0"},
// applyIf = {"UseCompressedOops", "true"})
! private static void testCMoveONEforL(NotValue[] a, NotValue[] b, long[] c, long[] d, long[] r, long[] r2) {
for (int i = 0; i < a.length; i++) {
long cc = c[i];
long dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] != b[i]) ? cc : dd;
@IR(failOn = {IRNode.STORE_VECTOR})
@IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_P, ">0"},
applyIf = {"UseCompressedOops", "false"})
@IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_N, ">0"},
applyIf = {"UseCompressedOops", "true"})
! private static void testCMoveOEQforF(Object[] a, Object[] b, float[] c, float[] d, float[] r, float[] r2) {
for (int i = 0; i < a.length; i++) {
float cc = c[i];
float dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] == b[i]) ? cc : dd;
@IR(failOn = {IRNode.STORE_VECTOR})
@IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_P, ">0"},
applyIf = {"UseCompressedOops", "false"})
@IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_N, ">0"},
applyIf = {"UseCompressedOops", "true"})
! private static void testCMoveOEQforF(NotValue[] a, NotValue[] b, float[] c, float[] d, float[] r, float[] r2) {
for (int i = 0; i < a.length; i++) {
float cc = c[i];
float dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] == b[i]) ? cc : dd;
@IR(failOn = {IRNode.STORE_VECTOR})
@IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_P, ">0"},
applyIf = {"UseCompressedOops", "false"})
@IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_N, ">0"},
applyIf = {"UseCompressedOops", "true"})
! private static void testCMoveONEforF(Object[] a, Object[] b, float[] c, float[] d, float[] r, float[] r2) {
for (int i = 0; i < a.length; i++) {
float cc = c[i];
float dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] != b[i]) ? cc : dd;
@IR(failOn = {IRNode.STORE_VECTOR})
@IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_P, ">0"},
applyIf = {"UseCompressedOops", "false"})
@IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_N, ">0"},
applyIf = {"UseCompressedOops", "true"})
! private static void testCMoveONEforF(NotValue[] a, NotValue[] b, float[] c, float[] d, float[] r, float[] r2) {
for (int i = 0; i < a.length; i++) {
float cc = c[i];
float dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] != b[i]) ? cc : dd;
@IR(failOn = {IRNode.STORE_VECTOR})
@IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_P, ">0"},
applyIf = {"UseCompressedOops", "false"})
@IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_N, ">0"},
applyIf = {"UseCompressedOops", "true"})
! private static void testCMoveOEQforD(Object[] a, Object[] b, double[] c, double[] d, double[] r, double[] r2) {
for (int i = 0; i < a.length; i++) {
double cc = c[i];
double dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] == b[i]) ? cc : dd;
@IR(failOn = {IRNode.STORE_VECTOR})
@IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_P, ">0"},
applyIf = {"UseCompressedOops", "false"})
@IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_N, ">0"},
applyIf = {"UseCompressedOops", "true"})
! private static void testCMoveOEQforD(NotValue[] a, NotValue[] b, double[] c, double[] d, double[] r, double[] r2) {
for (int i = 0; i < a.length; i++) {
double cc = c[i];
double dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] == b[i]) ? cc : dd;
@IR(failOn = {IRNode.STORE_VECTOR})
@IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_P, ">0"},
applyIf = {"UseCompressedOops", "false"})
@IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_N, ">0"},
applyIf = {"UseCompressedOops", "true"})
! private static void testCMoveONEforD(Object[] a, Object[] b, double[] c, double[] d, double[] r, double[] r2) {
for (int i = 0; i < a.length; i++) {
double cc = c[i];
double dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] != b[i]) ? cc : dd;
@IR(failOn = {IRNode.STORE_VECTOR})
@IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_P, ">0"},
applyIf = {"UseCompressedOops", "false"})
@IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_N, ">0"},
applyIf = {"UseCompressedOops", "true"})
! private static void testCMoveONEforD(NotValue[] a, NotValue[] b, double[] c, double[] d, double[] r, double[] r2) {
for (int i = 0; i < a.length; i++) {
double cc = c[i];
double dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] != b[i]) ? cc : dd;
"testCMoveONEforF",
"testCMoveOEQforD",
"testCMoveONEforD",
})
private void testCMove_runner_two() {
! Object[] aO = new Object[SIZE];
! Object[] bO = new Object[SIZE];
int[] cI = new int[SIZE];
int[] dI = new int[SIZE];
int[] rI = new int[SIZE];
long[] cL = new long[SIZE];
long[] dL = new long[SIZE];
"testCMoveONEforF",
"testCMoveOEQforD",
"testCMoveONEforD",
})
private void testCMove_runner_two() {
! NotValue[] aO = new NotValue[SIZE];
! NotValue[] bO = new NotValue[SIZE];
int[] cI = new int[SIZE];
int[] dI = new int[SIZE];
int[] rI = new int[SIZE];
long[] cL = new long[SIZE];
long[] dL = new long[SIZE];
double[] dD = new double[SIZE];
double[] rD = new double[SIZE];
init(aO);
shuffle(aO, bO);
+ init(cI);
+ init(dI);
init(cL);
init(dL);
init(cF);
init(dF);
init(cD);
Asserts.assertEquals(rD[i], cmoveONEforD(aO[i], bO[i], cD[i], dD[i]));
}
}
! private static void init(Object[] a) {
for (int i = 0; i < SIZE; i++) {
! a[i] = new Object();
}
}
! private static void shuffle(Object[] a, Object[] b) {
for (int i = 0; i < a.length; i++) {
b[i] = a[i];
}
Random rand = new Random();
for (int i = 0; i < SIZE; i++) {
if (rand.nextInt(5) == 0) {
! Object t = b[i];
b[i] = b[SIZE-1-i];
b[SIZE-1-i] = t;
}
}
}
Asserts.assertEquals(rD[i], cmoveONEforD(aO[i], bO[i], cD[i], dD[i]));
}
}
! private static void init(NotValue[] a) {
for (int i = 0; i < SIZE; i++) {
! a[i] = new NotValue();
}
}
! private static void shuffle(NotValue[] a, NotValue[] b) {
for (int i = 0; i < a.length; i++) {
b[i] = a[i];
}
Random rand = new Random();
for (int i = 0; i < SIZE; i++) {
if (rand.nextInt(5) == 0) {
! NotValue t = b[i];
b[i] = b[SIZE-1-i];
b[SIZE-1-i] = t;
}
}
}
< prev index next >