jdk-24/test/hotspot/jtreg/compiler/c2/irTests/TestShiftAndMask.java
2024-02-09 05:30:20 +00:00

487 lines
16 KiB
Java

/*
* Copyright (c) 2021, Red Hat, Inc. 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.c2.irTests;
import compiler.lib.ir_framework.*;
import jdk.test.lib.Utils;
import java.util.Random;
import java.util.Objects;
/*
* @test
* @bug 8277850 8278949 8285793
* @summary C2: optimize mask checks in counted loops
* @library /test/lib /
* @run driver compiler.c2.irTests.TestShiftAndMask
*/
public class TestShiftAndMask {
private static final Random RANDOM = Utils.getRandomInstance();
public static void main(String[] args) {
TestFramework.run();
}
@Test
@Arguments(values = Argument.RANDOM_EACH)
@IR(failOn = { IRNode.AND_I, IRNode.LSHIFT_I })
public static int shiftMaskInt(int i) {
return (i << 2) & 3; // transformed to: return 0;
}
@Check(test = "shiftMaskInt")
public static void checkShiftMaskInt(int res) {
if (res != 0) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@Arguments(values = Argument.RANDOM_EACH)
@IR(failOn = { IRNode.AND_L, IRNode.LSHIFT_L })
public static long shiftMaskLong(long i) {
return (i << 2) & 3; // transformed to: return 0;
}
@Check(test = "shiftMaskLong")
public static void checkShiftMaskLong(long res) {
if (res != 0) {
throw new RuntimeException("incorrect result: " + res);
}
}
static volatile int barrier;
@Test
@Arguments(values = {Argument.RANDOM_EACH, Argument.BOOLEAN_TOGGLE_FIRST_TRUE})
@IR(failOn = { IRNode.AND_I, IRNode.LSHIFT_I })
public static int shiftNonConstMaskInt(int i, boolean flag) {
int mask;
if (flag) {
barrier = 42;
mask = 3;
} else {
mask = 1;
}
return mask & (i << 2); // transformed to: return 0;
}
@Check(test = "shiftNonConstMaskInt")
public static void checkShiftNonConstMaskInt(int res) {
if (res != 0) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@Arguments(values = {Argument.RANDOM_EACH, Argument.BOOLEAN_TOGGLE_FIRST_TRUE})
@IR(failOn = { IRNode.AND_L, IRNode.LSHIFT_L })
public static long shiftNonConstMaskLong(long i, boolean flag) {
long mask;
if (flag) {
barrier = 42;
mask = 3;
} else {
mask = 1;
}
return mask & (i << 2); // transformed to: return 0;
}
@Check(test = "shiftNonConstMaskLong")
public static void checkShiftNonConstMaskLong(long res) {
if (res != 0) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@IR(counts = { IRNode.AND_I, "1" })
@IR(failOn = { IRNode.ADD_I, IRNode.LSHIFT_I })
public static int addShiftMaskInt(int i, int j) {
return (j + (i << 2)) & 3; // transformed to: return j & 3;
}
@Run(test = "addShiftMaskInt")
public static void addShiftMaskInt_runner() {
int i = RANDOM.nextInt();
int j = RANDOM.nextInt();
int res = addShiftMaskInt(i, j);
if (res != (j & 3)) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@IR(counts = { IRNode.AND_I, "1" })
@IR(failOn = { IRNode.ADD_I, IRNode.LSHIFT_I })
public static int addSshiftNonConstMaskInt(int i, int j, boolean flag) {
int mask;
if (flag) {
barrier = 42;
mask = 3;
} else {
mask = 1;
}
return mask & (j + (i << 2)); // transformed to: return j & mask;
}
@Run(test = "addSshiftNonConstMaskInt")
public static void addSshiftNonConstMaskInt_runner() {
int i = RANDOM.nextInt();
int j = RANDOM.nextInt();
int res = addSshiftNonConstMaskInt(i, j, true);
if (res != (j & 3)) {
throw new RuntimeException("incorrect result: " + res);
}
res = addSshiftNonConstMaskInt(i, j, false);
if (res != (j & 1)) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@IR(counts = { IRNode.AND_L, "1" })
@IR(failOn = { IRNode.ADD_L, IRNode.LSHIFT_L })
public static long addShiftMaskLong(long i, long j) {
return (j + (i << 2)) & 3; // transformed to: return j & 3;
}
@Run(test = "addShiftMaskLong")
public static void addShiftMaskLong_runner() {
long i = RANDOM.nextLong();
long j = RANDOM.nextLong();
long res = addShiftMaskLong(i, j);
if (res != (j & 3)) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@IR(counts = { IRNode.AND_L, "1" })
@IR(failOn = { IRNode.ADD_L, IRNode.LSHIFT_L })
public static long addSshiftNonConstMaskLong(long i, long j, boolean flag) {
int mask;
if (flag) {
barrier = 42;
mask = 3;
} else {
mask = 1;
}
return mask & (j + (i << 2)); // transformed to: return j & mask;
}
@Run(test = "addSshiftNonConstMaskLong")
public static void addSshiftNonConstMaskLong_runner() {
long i = RANDOM.nextLong();
long j = RANDOM.nextLong();
long res = addSshiftNonConstMaskLong(i, j, true);
if (res != (j & 3)) {
throw new RuntimeException("incorrect result: " + res);
}
res = addSshiftNonConstMaskLong(i, j, false);
if (res != (j & 1)) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@IR(failOn = { IRNode.AND_I, IRNode.ADD_I, IRNode.LSHIFT_I })
public static int addShiftMaskInt2(int i, int j) {
return ((j << 2) + (i << 2)) & 3; // transformed to: return 0;
}
@Check(test = "addShiftMaskInt2")
public static void checkAddShiftMaskInt2(int res) {
if (res != 0) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@IR(failOn = { IRNode.AND_L, IRNode.ADD_L, IRNode.LSHIFT_L })
public static long addShiftMaskLong2(long i, long j) {
return ((j << 2) + (i << 2)) & 3; // transformed to: return 0;
}
@Check(test = "addShiftMaskLong2")
public static void checkAddShiftMaskLong2(long res) {
if (res != 0) {
throw new RuntimeException("incorrect result: " + res);
}
}
// Try to get add inputs swapped compared to other tests
@Test
@IR(counts = { IRNode.AND_I, "1" })
@IR(failOn = { IRNode.ADD_I, IRNode.LSHIFT_I })
public static int addShiftMaskInt3(int i, long j) {
int add1 = (i << 2);
int add2 = (int)j;
return (add1 + add2) & 3; // transformed to: return j & 3;
}
@Run(test = "addShiftMaskInt3")
public static void addShiftMaskInt3_runner() {
int i = RANDOM.nextInt();
int j = RANDOM.nextInt();
int res = addShiftMaskInt3(i, j);
if (res != (j & 3)) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@IR(counts = { IRNode.AND_L, "1" })
@IR(failOn = { IRNode.ADD_L, IRNode.LSHIFT_L })
public static long addShiftMaskLong3(long i, float j) {
long add1 = (i << 2);
long add2 = (long)j;
return (add1 + add2) & 3; // transformed to: return j & 3;
}
@Run(test = "addShiftMaskLong3")
public static void addShiftMaskLong3_runner() {
long i = RANDOM.nextLong();
float j = RANDOM.nextFloat();
long res = addShiftMaskLong3(i, j);
if (res != (((long)j) & 3)) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@Arguments(values = {Argument.RANDOM_EACH})
@IR(failOn = { IRNode.AND_L, IRNode.LSHIFT_I, IRNode.CONV_I2L })
public static long shiftConvMask(int i) {
return ((long)(i << 2)) & 3; // transformed to: return 0;
}
@Check(test = "shiftConvMask")
public static void checkShiftConvMask(long res) {
if (res != 0) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@Arguments(values = {Argument.RANDOM_EACH, Argument.BOOLEAN_TOGGLE_FIRST_TRUE})
@IR(failOn = { IRNode.AND_L, IRNode.LSHIFT_I, IRNode.CONV_I2L })
public static long shiftNotConstConvMask(int i, boolean flag) {
long mask;
if (flag) {
barrier = 42;
mask = 3;
} else {
mask = 1;
}
return mask & ((long)(i << 2)); // transformed to: return 0;
}
@Check(test = "shiftNotConstConvMask")
public static void checkShiftNotConstConvMask(long res) {
if (res != 0) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@IR(counts = { IRNode.AND_L, "1" })
@IR(failOn = { IRNode.ADD_L, IRNode.LSHIFT_I, IRNode.CONV_I2L })
public static long addShiftConvMask(int i, long j) {
return (j + (i << 2)) & 3; // transformed to: return j & 3;
}
@Run(test = "addShiftConvMask")
public static void addShiftConvMask_runner() {
int i = RANDOM.nextInt();
long j = RANDOM.nextLong();
long res = addShiftConvMask(i, j);
if (res != (j & 3)) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@IR(failOn = { IRNode.AND_L, IRNode.ADD_L, IRNode.LSHIFT_I, IRNode.CONV_I2L })
public static long addShiftConvMask2(int i, int j) {
return (((long)(j << 2)) + ((long)(i << 2))) & 3; // transformed to: return 0;
}
@Check(test = "addShiftConvMask2")
public static void checkAddShiftConvMask2(long res) {
if (res != 0) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@IR(failOn = { IRNode.AND_I })
public static int shiftMaskIntCheckIndex(int i, int length) {
return Objects.checkIndex(i << 2, length) & 3; // transformed to: return 0;
}
@Run(test = "shiftMaskIntCheckIndex")
public static void shiftMaskIntCheckIndex_runner() {
int i = RANDOM.nextInt((Integer.MAX_VALUE - 1) >> 2);
int res = shiftMaskIntCheckIndex(i, (i << 2) + 1);
if (res != 0) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@IR(failOn = { IRNode.AND_L })
public static long shiftMaskLongCheckIndex(long i, long length) {
return Objects.checkIndex(i << 2, length) & 3; // transformed to: return 0;
}
@Run(test = "shiftMaskLongCheckIndex")
public static void shiftMaskLongCheckIndex_runner() {
long i = RANDOM.nextInt((Integer.MAX_VALUE - 1) >> 2);
long res = shiftMaskLongCheckIndex(i, (i << 2) + 1);
if (res != 0) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@IR(counts = { IRNode.AND_I, "1" })
@IR(failOn = { IRNode.ADD_I })
public static int addShiftMaskIntCheckIndex(int i, int j, int length) {
return (j + Objects.checkIndex(i << 2, length)) & 3; // transformed to: return j & 3;
}
@Run(test = "addShiftMaskIntCheckIndex")
public static void addShiftMaskIntCheckIndex_runner() {
int i = RANDOM.nextInt((Integer.MAX_VALUE - 1) >> 2);
int j = RANDOM.nextInt();
int res = addShiftMaskIntCheckIndex(i, j, (i << 2) + 1);
if (res != (j & 3)) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@IR(counts = { IRNode.AND_L, "1" })
@IR(failOn = { IRNode.ADD_L })
public static long addShiftMaskLongCheckIndex(long i, long j, long length) {
return (j + Objects.checkIndex(i << 2, length)) & 3; // transformed to: return j & 3;
}
@Run(test = "addShiftMaskLongCheckIndex")
public static void addShiftMaskLongCheckIndex_runner() {
long i = RANDOM.nextInt((Integer.MAX_VALUE - 1) >> 2);
long j = RANDOM.nextLong();
long res = addShiftMaskLongCheckIndex(i, j, (i << 2) + 1);
if (res != (j & 3)) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@IR(failOn = { IRNode.AND_I, IRNode.ADD_I })
public static int addShiftMaskIntCheckIndex2(int i, int j, int length) {
return (Objects.checkIndex(j << 2, length) + Objects.checkIndex(i << 2, length)) & 3; // transformed to: return 0;
}
@Run(test = "addShiftMaskIntCheckIndex2")
public static void addShiftMaskIntCheckIndex2_runner() {
int i = RANDOM.nextInt((Integer.MAX_VALUE - 1) >> 2);
int j = RANDOM.nextInt((Integer.MAX_VALUE - 1) >> 2);
int res = addShiftMaskIntCheckIndex2(i, j, (Integer.max(i, j) << 2) + 1);
if (res != 0) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@IR(failOn = { IRNode.AND_L, IRNode.ADD_L })
public static long addShiftMaskLongCheckIndex2(long i, long j, long length) {
return (Objects.checkIndex(j << 2, length) + Objects.checkIndex(i << 2, length)) & 3; // transformed to: return 0;
}
@Run(test = "addShiftMaskLongCheckIndex2")
public static void addShiftMaskLongCheckIndex2_runner() {
long i = RANDOM.nextInt((Integer.MAX_VALUE - 1) >> 2);
long j = RANDOM.nextInt((Integer.MAX_VALUE - 1) >> 2);
long res = addShiftMaskLongCheckIndex2(i, j, (Long.max(i, j) << 2) + 1);
if (res != 0) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@IR(failOn = { IRNode.AND_L, IRNode.CONV_I2L })
public static long shiftConvMaskCheckIndex(int i, int length) {
return ((long)Objects.checkIndex(i << 2, length)) & 3; // transformed to: return 0;
}
@Run(test = "shiftConvMaskCheckIndex")
public static void shiftConvMaskCheckIndex_runner() {
int i = RANDOM.nextInt((Integer.MAX_VALUE - 1) >> 2);
long res = shiftConvMaskCheckIndex(i, (i << 2) + 1);
if (res != 0) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@IR(counts = { IRNode.AND_L, "1" })
@IR(failOn = { IRNode.ADD_L, IRNode.CONV_I2L })
public static long addShiftConvMaskCheckIndex(int i, long j, int length) {
return (j + Objects.checkIndex(i << 2, length)) & 3; // transformed to: return j & 3;
}
@Run(test = "addShiftConvMaskCheckIndex")
public static void addShiftConvMaskCheckIndex_runner() {
int i = RANDOM.nextInt((Integer.MAX_VALUE - 1) >> 2);
long j = RANDOM.nextLong();
long res = addShiftConvMaskCheckIndex(i, j, (i << 2) + 1);
if (res != (j & 3)) {
throw new RuntimeException("incorrect result: " + res);
}
}
@Test
@IR(failOn = { IRNode.AND_L, IRNode.ADD_L })
public static long addShiftConvMaskCheckIndex2(int i, int j, int length) {
return (((long)Objects.checkIndex(j << 2, length)) + ((long)Objects.checkIndex(i << 2, length))) & 3; // transformed to: return 0;
}
@Run(test = "addShiftConvMaskCheckIndex2")
public static void addShiftConvMaskCheckIndex2_runner() {
int i = RANDOM.nextInt((Integer.MAX_VALUE - 1) >> 2);
int j = RANDOM.nextInt((Integer.MAX_VALUE - 1) >> 2);
long res = addShiftConvMaskCheckIndex2(i, j, (Integer.max(i, j) << 2) + 1);
if (res != 0) {
throw new RuntimeException("incorrect result: " + res);
}
}
}