8287925: AArch64: intrinsics for compareUnsigned method in Integer and Long

Reviewed-by: adinn, aph
This commit is contained in:
Hao Sun 2023-01-10 05:37:02 +00:00 committed by Ningsheng Jian
parent 3a66737001
commit 195f31371f
2 changed files with 168 additions and 20 deletions

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2014, 2021, Red Hat, Inc. All rights reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
//
@ -9654,6 +9654,90 @@ instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr)
ins_pipe(pipe_serial);
%}
// Manifest a CmpU result in an integer register.
// (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0)
instruct cmpU3_reg_reg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg flags)
%{
match(Set dst (CmpU3 src1 src2));
effect(KILL flags);
ins_cost(INSN_COST * 3);
format %{
"cmpw $src1, $src2\n\t"
"csetw $dst, ne\n\t"
"cnegw $dst, lo\t# CmpU3(reg)"
%}
ins_encode %{
__ cmpw($src1$$Register, $src2$$Register);
__ csetw($dst$$Register, Assembler::NE);
__ cnegw($dst$$Register, $dst$$Register, Assembler::LO);
%}
ins_pipe(pipe_class_default);
%}
instruct cmpU3_reg_imm(iRegINoSp dst, iRegI src1, immIAddSub src2, rFlagsReg flags)
%{
match(Set dst (CmpU3 src1 src2));
effect(KILL flags);
ins_cost(INSN_COST * 3);
format %{
"subsw zr, $src1, $src2\n\t"
"csetw $dst, ne\n\t"
"cnegw $dst, lo\t# CmpU3(imm)"
%}
ins_encode %{
__ subsw(zr, $src1$$Register, (int32_t)$src2$$constant);
__ csetw($dst$$Register, Assembler::NE);
__ cnegw($dst$$Register, $dst$$Register, Assembler::LO);
%}
ins_pipe(pipe_class_default);
%}
// Manifest a CmpUL result in an integer register.
// (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0)
instruct cmpUL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags)
%{
match(Set dst (CmpUL3 src1 src2));
effect(KILL flags);
ins_cost(INSN_COST * 3);
format %{
"cmp $src1, $src2\n\t"
"csetw $dst, ne\n\t"
"cnegw $dst, lo\t# CmpUL3(reg)"
%}
ins_encode %{
__ cmp($src1$$Register, $src2$$Register);
__ csetw($dst$$Register, Assembler::NE);
__ cnegw($dst$$Register, $dst$$Register, Assembler::LO);
%}
ins_pipe(pipe_class_default);
%}
instruct cmpUL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags)
%{
match(Set dst (CmpUL3 src1 src2));
effect(KILL flags);
ins_cost(INSN_COST * 3);
format %{
"subs zr, $src1, $src2\n\t"
"csetw $dst, ne\n\t"
"cnegw $dst, lo\t# CmpUL3(imm)"
%}
ins_encode %{
__ subs(zr, $src1$$Register, (int32_t)$src2$$constant);
__ csetw($dst$$Register, Assembler::NE);
__ cnegw($dst$$Register, $dst$$Register, Assembler::LO);
%}
ins_pipe(pipe_class_default);
%}
// Manifest a CmpL result in an integer register.
// (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0)
instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags)
@ -9661,13 +9745,12 @@ instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags)
match(Set dst (CmpL3 src1 src2));
effect(KILL flags);
ins_cost(INSN_COST * 6);
ins_cost(INSN_COST * 3);
format %{
"cmp $src1, $src2"
"csetw $dst, ne"
"cnegw $dst, lt"
"cmp $src1, $src2\n\t"
"csetw $dst, ne\n\t"
"cnegw $dst, lt\t# CmpL3(reg)"
%}
// format %{ "CmpL3 $dst, $src1, $src2" %}
ins_encode %{
__ cmp($src1$$Register, $src2$$Register);
__ csetw($dst$$Register, Assembler::NE);
@ -9682,19 +9765,14 @@ instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg fla
match(Set dst (CmpL3 src1 src2));
effect(KILL flags);
ins_cost(INSN_COST * 6);
ins_cost(INSN_COST * 3);
format %{
"cmp $src1, $src2"
"csetw $dst, ne"
"cnegw $dst, lt"
"subs zr, $src1, $src2\n\t"
"csetw $dst, ne\n\t"
"cnegw $dst, lt\t# CmpL3(imm)"
%}
ins_encode %{
int32_t con = (int32_t)$src2$$constant;
if (con < 0) {
__ adds(zr, $src1$$Register, -con);
} else {
__ subs(zr, $src1$$Register, con);
}
__ subs(zr, $src1$$Register, (int32_t)$src2$$constant);
__ csetw($dst$$Register, Assembler::NE);
__ cnegw($dst$$Register, $dst$$Register, Assembler::LT);
%}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2023, 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
@ -29,8 +29,8 @@ import jdk.test.lib.Utils;
/*
* @test
* @key randomness
* @bug 8283726
* @requires os.arch=="amd64" | os.arch=="x86_64"
* @bug 8283726 8287925
* @requires os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64"
* @summary Test the intrinsics implementation of Integer/Long::compareUnsigned
* @library /test/lib /
* @run driver compiler.intrinsics.TestCompareUnsigned
@ -73,13 +73,74 @@ public class TestCompareUnsigned {
return Integer.compareUnsigned(x, y);
}
@Test
@IR(counts = {IRNode.CMP_U3, "1"})
public int compareIntWithImm1(int x) {
return Integer.compareUnsigned(x, 42);
}
@Test
@IR(counts = {IRNode.CMP_U3, "1"})
public int compareIntWithImm2(int x) {
return Integer.compareUnsigned(x, 42 << 12);
}
@Test
@IR(counts = {IRNode.CMP_U3, "1"})
public int compareIntWithImm3(int x) {
return Integer.compareUnsigned(x, 42 << 24);
}
@Test
@IR(counts = {IRNode.CMP_U3, "1"})
public int compareIntWithImm4(int x) {
return Integer.compareUnsigned(x, Integer.MIN_VALUE);
}
@Test
@IR(counts = {IRNode.CMP_UL3, "1"})
public int compareLong(long x, long y) {
return Long.compareUnsigned(x, y);
}
@Run(test = {"lessThanInt", "lessThanLong", "compareInt", "compareLong"})
@Test
@IR(counts = {IRNode.CMP_UL3, "1"})
public int compareLongWithImm1(long x) {
return Long.compareUnsigned(x, 42);
}
@Test
@IR(counts = {IRNode.CMP_UL3, "1"})
public int compareLongWithImm2(long x) {
return Long.compareUnsigned(x, 42 << 12);
}
@Test
@IR(counts = {IRNode.CMP_UL3, "1"})
public int compareLongWithImm3(long x) {
return Long.compareUnsigned(x, 42 << 24);
}
@Test
@IR(counts = {IRNode.CMP_UL3, "1"})
public int compareLongWithImm4(long x) {
return Long.compareUnsigned(x, Integer.MIN_VALUE);
}
@Test
@IR(counts = {IRNode.CMP_UL3, "1"})
public int compareLongWithImm5(long x) {
return Long.compareUnsigned(x, Long.MIN_VALUE);
}
@Run(test = {"lessThanInt", "lessThanLong",
"compareInt",
"compareIntWithImm1", "compareIntWithImm2",
"compareIntWithImm3", "compareIntWithImm4",
"compareLong",
"compareLongWithImm1", "compareLongWithImm2",
"compareLongWithImm3", "compareLongWithImm4",
"compareLongWithImm5"})
public void runTests() {
var random = Utils.getRandomInstance();
for (int i = 0; i < 1000; i++) {
@ -89,6 +150,10 @@ public class TestCompareUnsigned {
Asserts.assertEquals(compareInt(x, x), 0);
Asserts.assertEquals(lessThanInt(x, y), expectedResult(x, y) < 0 ? TRUE_VALUE : FALSE_VALUE);
Asserts.assertEquals(compareInt(x, y), expectedResult(x, y));
Asserts.assertEquals(compareIntWithImm1(x), expectedResult(x, 42));
Asserts.assertEquals(compareIntWithImm2(x), expectedResult(x, 42 << 12));
Asserts.assertEquals(compareIntWithImm3(x), expectedResult(x, 42 << 24));
Asserts.assertEquals(compareIntWithImm4(x), expectedResult(x, Integer.MIN_VALUE));
}
for (int i = 0; i < 1000; i++) {
long x = random.nextLong();
@ -97,6 +162,11 @@ public class TestCompareUnsigned {
Asserts.assertEquals(compareLong(x, x), 0);
Asserts.assertEquals(lessThanLong(x, y), expectedResult(x, y) < 0 ? TRUE_VALUE : FALSE_VALUE);
Asserts.assertEquals(compareLong(x, y), expectedResult(x, y));
Asserts.assertEquals(compareLongWithImm1(x), expectedResult(x, 42));
Asserts.assertEquals(compareLongWithImm2(x), expectedResult(x, 42 << 12));
Asserts.assertEquals(compareLongWithImm3(x), expectedResult(x, 42 << 24));
Asserts.assertEquals(compareLongWithImm4(x), expectedResult(x, Integer.MIN_VALUE));
Asserts.assertEquals(compareLongWithImm5(x), expectedResult(x, Long.MIN_VALUE));
}
}
}