+{"files":[{"patch":"@@ -13025,0 +13025,26 @@\n+\/\/ Manifest a CmpU result in an integer register. Very painful.\n+\/\/ This is the test to avoid.\n+instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags)\n+%{\n+ match(Set dst (CmpU3 src1 src2));\n+ effect(KILL flags);\n+\n+ ins_cost(275); \/\/ XXX\n+ format %{ \"cmpl $src1, $src2\\t# CmpL3\\n\\t\"\n+ \"movl $dst, -1\\n\\t\"\n+ \"jb,u done\\n\\t\"\n+ \"setne $dst\\n\\t\"\n+ \"movzbl $dst, $dst\\n\\t\"\n+ \"done:\" %}\n+ ins_encode %{\n+ Label done;\n+ __ cmpl($src1$$Register, $src2$$Register);\n+ __ movl($dst$$Register, -1);\n+ __ jccb(Assembler::below, done);\n+ __ setne($dst$$Register);\n+ __ movzbl($dst$$Register, $dst$$Register);\n+ __ bind(done);\n+ %}\n+ ins_pipe(pipe_slow);\n+%}\n+\n@@ -13051,0 +13077,26 @@\n+\/\/ Manifest a CmpUL result in an integer register. Very painful.\n+\/\/ This is the test to avoid.\n+instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags)\n+%{\n+ match(Set dst (CmpUL3 src1 src2));\n+ effect(KILL flags);\n+\n+ ins_cost(275); \/\/ XXX\n+ format %{ \"cmpq $src1, $src2\\t# CmpL3\\n\\t\"\n+ \"movl $dst, -1\\n\\t\"\n+ \"jb,u done\\n\\t\"\n+ \"setne $dst\\n\\t\"\n+ \"movzbl $dst, $dst\\n\\t\"\n+ \"done:\" %}\n+ ins_encode %{\n+ Label done;\n+ __ cmpq($src1$$Register, $src2$$Register);\n+ __ movl($dst$$Register, -1);\n+ __ jccb(Assembler::below, done);\n+ __ setne($dst$$Register);\n+ __ movzbl($dst$$Register, $dst$$Register);\n+ __ bind(done);\n+ %}\n+ ins_pipe(pipe_slow);\n+%}\n+\n","filename":"src\/hotspot\/cpu\/x86\/x86_64.ad","additions":52,"deletions":0,"binary":false,"changes":52,"status":"modified"},{"patch":"@@ -129,0 +129,1 @@\n+ do_signature(long2_int_signature, \"(JJ)I\") \\\n@@ -153,3 +154,3 @@\n- do_intrinsic(_fabs, java_lang_Math, abs_name, float_float_signature, F_S) \\\n- do_intrinsic(_iabs, java_lang_Math, abs_name, int_int_signature, F_S) \\\n- do_intrinsic(_labs, java_lang_Math, abs_name, long_long_signature, F_S) \\\n+ do_intrinsic(_fabs, java_lang_Math, abs_name, float_float_signature, F_S) \\\n+ do_intrinsic(_iabs, java_lang_Math, abs_name, int_int_signature, F_S) \\\n+ do_intrinsic(_labs, java_lang_Math, abs_name, long_long_signature, F_S) \\\n@@ -208,1 +209,1 @@\n- do_name( isInfinite_name, \"isInfinite\") \\\n+ do_name( isInfinite_name, \"isInfinite\") \\\n@@ -224,6 +225,11 @@\n- do_intrinsic(_divideUnsigned_i, java_lang_Integer, divideUnsigned_name, int2_int_signature, F_S) \\\n- do_intrinsic(_remainderUnsigned_i, java_lang_Integer, remainderUnsigned_name, int2_int_signature, F_S) \\\n- do_name( divideUnsigned_name, \"divideUnsigned\") \\\n- do_intrinsic(_divideUnsigned_l, java_lang_Long, divideUnsigned_name, long2_long_signature, F_S) \\\n- do_intrinsic(_remainderUnsigned_l, java_lang_Long, remainderUnsigned_name, long2_long_signature, F_S) \\\n- do_name( remainderUnsigned_name, \"remainderUnsigned\") \\\n+ do_intrinsic(_compareUnsigned_i, java_lang_Integer, compareUnsigned_name, int2_int_signature, F_S) \\\n+ do_intrinsic(_compareUnsigned_l, java_lang_Long, compareUnsigned_name, long2_int_signature, F_S) \\\n+ do_name( compareUnsigned_name, \"compareUnsigned\") \\\n+ \\\n+ do_intrinsic(_divideUnsigned_i, java_lang_Integer, divideUnsigned_name, int2_int_signature, F_S) \\\n+ do_intrinsic(_remainderUnsigned_i, java_lang_Integer, remainderUnsigned_name, int2_int_signature, F_S) \\\n+ do_name( divideUnsigned_name, \"divideUnsigned\") \\\n+ do_intrinsic(_divideUnsigned_l, java_lang_Long, divideUnsigned_name, long2_long_signature, F_S) \\\n+ do_intrinsic(_remainderUnsigned_l, java_lang_Long, remainderUnsigned_name, long2_long_signature, F_S) \\\n+ do_name( remainderUnsigned_name, \"remainderUnsigned\") \\\n+ \\\n","filename":"src\/hotspot\/share\/classfile\/vmIntrinsics.hpp","additions":16,"deletions":10,"binary":false,"changes":26,"status":"modified"},{"patch":"@@ -278,0 +278,6 @@\n+ case vmIntrinsics::_compareUnsigned_i:\n+ if (!Matcher::match_rule_supported(Op_CmpU3)) return false;\n+ break;\n+ case vmIntrinsics::_compareUnsigned_l:\n+ if (!Matcher::match_rule_supported(Op_CmpUL3)) return false;\n+ break;\n","filename":"src\/hotspot\/share\/opto\/c2compiler.cpp","additions":6,"deletions":0,"binary":false,"changes":6,"status":"modified"},{"patch":"@@ -100,0 +100,1 @@\n+macro(CmpU3)\n@@ -101,0 +102,1 @@\n+macro(CmpUL3)\n","filename":"src\/hotspot\/share\/opto\/classes.hpp","additions":2,"deletions":0,"binary":false,"changes":2,"status":"modified"},{"patch":"@@ -538,0 +538,3 @@\n+ case vmIntrinsics::_compareUnsigned_i:\n+ case vmIntrinsics::_compareUnsigned_l: return inline_compare_unsigned(intrinsic_id());\n+\n@@ -2250,0 +2253,16 @@\n+\/\/--------------------------inline_number_methods-----------------------------\n+\/\/ inline int Integer.compareUnsigned(int, int)\n+\/\/ inline int Long.compareUnsigned(long, long)\n+bool LibraryCallKit::inline_compare_unsigned(vmIntrinsics::ID id) {\n+ Node* arg1 = argument(0);\n+ Node* arg2 = (id == vmIntrinsics::_compareUnsigned_l) ? argument(2) : argument(1);\n+ Node* n = NULL;\n+ switch (id) {\n+ case vmIntrinsics::_compareUnsigned_i: n = new CmpU3Node(arg1, arg2); break;\n+ case vmIntrinsics::_compareUnsigned_l: n = new CmpUL3Node(arg1, arg2); break;\n+ default: fatal_unexpected_iid(id); break;\n+ }\n+ set_result(_gvn.transform(n));\n+ return true;\n+}\n+\n","filename":"src\/hotspot\/share\/opto\/library_call.cpp","additions":19,"deletions":0,"binary":false,"changes":19,"status":"modified"},{"patch":"@@ -280,0 +280,1 @@\n+ bool inline_compare_unsigned(vmIntrinsics::ID id);\n","filename":"src\/hotspot\/share\/opto\/library_call.hpp","additions":1,"deletions":0,"binary":false,"changes":1,"status":"modified"},{"patch":"@@ -851,0 +851,2 @@\n+ case Op_CmpU3: \/\/ Collapse a CmpU3\/CmpI into a CmpU\n+ return new CmpUNode(in(1)->in(1),in(1)->in(2));\n@@ -853,0 +855,2 @@\n+ case Op_CmpUL3: \/\/ Collapse a CmpUL3\/CmpI into a CmpUL\n+ return new CmpULNode(in(1)->in(1),in(1)->in(2));\n","filename":"src\/hotspot\/share\/opto\/subnode.cpp","additions":4,"deletions":0,"binary":false,"changes":4,"status":"modified"},{"patch":"@@ -176,0 +176,12 @@\n+\/\/------------------------------CmpU3Node--------------------------------------\n+\/\/ Compare 2 unsigned values, returning integer value (-1, 0 or 1).\n+class CmpU3Node : public CmpUNode {\n+public:\n+ CmpU3Node( Node *in1, Node *in2 ) : CmpUNode(in1,in2) {\n+ \/\/ Since it is not consumed by Bools, it is not really a Cmp.\n+ init_class_id(Class_Sub);\n+ }\n+ virtual int Opcode() const;\n+ virtual uint ideal_reg() const { return Op_RegI; }\n+};\n+\n@@ -223,1 +235,13 @@\n- virtual int Opcode() const;\n+ virtual int Opcode() const;\n+ virtual uint ideal_reg() const { return Op_RegI; }\n+};\n+\n+\/\/------------------------------CmpUL3Node-------------------------------------\n+\/\/ Compare 2 unsigned long values, returning integer value (-1, 0 or 1).\n+class CmpUL3Node : public CmpULNode {\n+public:\n+ CmpUL3Node( Node *in1, Node *in2 ) : CmpULNode(in1,in2) {\n+ \/\/ Since it is not consumed by Bools, it is not really a Cmp.\n+ init_class_id(Class_Sub);\n+ }\n+ virtual int Opcode() const;\n","filename":"src\/hotspot\/share\/opto\/subnode.hpp","additions":25,"deletions":1,"binary":false,"changes":26,"status":"modified"},{"patch":"@@ -1711,0 +1711,1 @@\n+ declare_c2_type(CmpU3Node, CmpUNode) \\\n@@ -1716,0 +1717,1 @@\n+ declare_c2_type(CmpUL3Node, CmpULNode) \\\n","filename":"src\/hotspot\/share\/runtime\/vmStructs.cpp","additions":2,"deletions":0,"binary":false,"changes":2,"status":"modified"},{"patch":"@@ -1503,0 +1503,1 @@\n+ @IntrinsicCandidate\n","filename":"src\/java.base\/share\/classes\/java\/lang\/Integer.java","additions":1,"deletions":0,"binary":false,"changes":1,"status":"modified"},{"patch":"@@ -1644,0 +1644,1 @@\n+ @IntrinsicCandidate\n","filename":"src\/java.base\/share\/classes\/java\/lang\/Long.java","additions":1,"deletions":0,"binary":false,"changes":1,"status":"modified"},{"patch":"@@ -0,0 +1,102 @@\n+\/*\n+ * Copyright (c) 2022, Oracle and\/or its affiliates. All rights reserved.\n+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n+ *\n+ * This code is free software; you can redistribute it and\/or modify it\n+ * under the terms of the GNU General Public License version 2 only, as\n+ * published by the Free Software Foundation.\n+ *\n+ * This code is distributed in the hope that it will be useful, but WITHOUT\n+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n+ * version 2 for more details (a copy is included in the LICENSE file that\n+ * accompanied this code).\n+ *\n+ * You should have received a copy of the GNU General Public License version\n+ * 2 along with this work; if not, write to the Free Software Foundation,\n+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n+ *\n+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n+ * or visit www.oracle.com if you need additional information or have any\n+ * questions.\n+ *\/\n+package compiler.intrinsics;\n+\n+import compiler.lib.ir_framework.*;\n+import jdk.test.lib.Asserts;\n+import jdk.test.lib.Utils;\n+\n+\/*\n+ * @test\n+ * @key randomness\n+ * @bug 8283726\n+ * @requires os.arch==\"amd64\" | os.arch==\"x86_64\"\n+ * @summary Test the intrinsics implementation of Integer\/Long::compareUnsigned\n+ * @library \/test\/lib \/\n+ * @run driver compiler.intrinsics.TestCompareUnsigned\n+ *\/\n+public class TestCompareUnsigned {\n+ static final int TRUE_VALUE = 10;\n+ static final int FALSE_VALUE = 4;\n+\n+ public static void main(String[] args) {\n+ var test = new TestFramework(TestCompareUnsigned.class);\n+ test.setDefaultWarmup(1);\n+ test.start();\n+ }\n+\n+ static int expectedResult(int x, int y) {\n+ return Integer.compare(x + Integer.MIN_VALUE, y + Integer.MIN_VALUE);\n+ }\n+\n+ static int expectedResult(long x, long y) {\n+ return Long.compare(x + Long.MIN_VALUE, y + Long.MIN_VALUE);\n+ }\n+\n+ @Test\n+ @IR(failOn = {IRNode.CMP_U3})\n+ @IR(counts = {IRNode.CMP_U, \"1\"})\n+ public int lessThanInt(int x, int y) {\n+ return Integer.compareUnsigned(x, y) < 0 ? TRUE_VALUE : FALSE_VALUE;\n+ }\n+\n+ @Test\n+ @IR(failOn = {IRNode.CMP_UL3})\n+ @IR(counts = {IRNode.CMP_UL, \"1\"})\n+ public int lessThanLong(long x, long y) {\n+ return Long.compareUnsigned(x, y) < 0 ? TRUE_VALUE : FALSE_VALUE;\n+ }\n+\n+ @Test\n+ @IR(counts = {IRNode.CMP_U3, \"1\"})\n+ public int compareInt(int x, int y) {\n+ return Integer.compareUnsigned(x, y);\n+ }\n+\n+ @Test\n+ @IR(counts = {IRNode.CMP_UL3, \"1\"})\n+ public int compareLong(long x, long y) {\n+ return Long.compareUnsigned(x, y);\n+ }\n+\n+ @Run(test = {\"lessThanInt\", \"lessThanLong\", \"compareInt\", \"compareLong\"})\n+ public void runTests() {\n+ var random = Utils.getRandomInstance();\n+ for (int i = 0; i < 1000; i++) {\n+ int x = random.nextInt();\n+ int y = random.nextInt();\n+ Asserts.assertEquals(lessThanInt(x, x), FALSE_VALUE);\n+ Asserts.assertEquals(compareInt(x, x), 0);\n+ Asserts.assertEquals(lessThanInt(x, y), expectedResult(x, y) < 0 ? TRUE_VALUE : FALSE_VALUE);\n+ Asserts.assertEquals(compareInt(x, y), expectedResult(x, y));\n+ }\n+ for (int i = 0; i < 1000; i++) {\n+ long x = random.nextLong();\n+ long y = random.nextLong();\n+ Asserts.assertEquals(lessThanLong(x, x), FALSE_VALUE);\n+ Asserts.assertEquals(compareLong(x, x), 0);\n+ Asserts.assertEquals(lessThanLong(x, y), expectedResult(x, y) < 0 ? TRUE_VALUE : FALSE_VALUE);\n+ Asserts.assertEquals(compareLong(x, y), expectedResult(x, y));\n+ }\n+ }\n+}\n","filename":"test\/hotspot\/jtreg\/compiler\/intrinsics\/TestCompareUnsigned.java","additions":102,"deletions":0,"binary":false,"changes":102,"status":"added"},{"patch":"@@ -174,0 +174,4 @@\n+ public static final String CMP_U = START + \"CmpU\" + MID + END;\n+ public static final String CMP_UL = START + \"CmpUL\" + MID + END;\n+ public static final String CMP_U3 = START + \"CmpU3\" + MID + END;\n+ public static final String CMP_UL3 = START + \"CmpUL3\" + MID + END;\n","filename":"test\/hotspot\/jtreg\/compiler\/lib\/ir_framework\/IRNode.java","additions":4,"deletions":0,"binary":false,"changes":4,"status":"modified"},{"patch":"@@ -55,0 +55,1 @@\n+ private int bound;\n@@ -63,0 +64,1 @@\n+ bound = 50;\n@@ -149,0 +151,16 @@\n+\n+ @Benchmark\n+ public void compareUnsignedIndirect(Blackhole bh) {\n+ for (int i = 0; i < size; i++) {\n+ int r = (Integer.compareUnsigned(intsSmall[i], bound - 16) < 0) ? 1 : 0;\n+ bh.consume(r);\n+ }\n+ }\n+\n+ @Benchmark\n+ public void compareUnsignedDirect(Blackhole bh) {\n+ for (int i = 0; i < size; i++) {\n+ int r = Integer.compareUnsigned(intsSmall[i], bound - 16);\n+ bh.consume(r);\n+ }\n+ }\n","filename":"test\/micro\/org\/openjdk\/bench\/java\/lang\/Integers.java","additions":18,"deletions":0,"binary":false,"changes":18,"status":"modified"},{"patch":"@@ -52,0 +52,1 @@\n+ private long bound;\n@@ -59,0 +60,1 @@\n+ bound = 20000L;\n@@ -144,0 +146,16 @@\n+\n+ @Benchmark\n+ public void compareUnsignedIndirect(Blackhole bh) {\n+ for (int i = 0; i < size; i++) {\n+ int r = (Long.compareUnsigned(longArraySmall[i], bound - 16) < 0) ? 1 : 0;\n+ bh.consume(r);\n+ }\n+ }\n+\n+ @Benchmark\n+ public void compareUnsignedDirect(Blackhole bh) {\n+ for (int i = 0; i < size; i++) {\n+ int r = Long.compareUnsigned(longArraySmall[i], bound - 16);\n+ bh.consume(r);\n+ }\n+ }\n","filename":"test\/micro\/org\/openjdk\/bench\/java\/lang\/Longs.java","additions":18,"deletions":0,"binary":false,"changes":18,"status":"modified"}]}
0 commit comments