Skip to content

Commit 108cd69

Browse files
merykittyJatin Bhateja
authored andcommitted
8283726: x86_64 intrinsics for compareUnsigned method in Integer and Long
Reviewed-by: kvn, jbhateja
1 parent b96ba19 commit 108cd69

File tree

15 files changed

+271
-11
lines changed

15 files changed

+271
-11
lines changed

src/hotspot/cpu/x86/x86_64.ad

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13022,6 +13022,32 @@ instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero)
1302213022
ins_pipe(ialu_cr_reg_mem);
1302313023
%}
1302413024

13025+
// Manifest a CmpU result in an integer register. Very painful.
13026+
// This is the test to avoid.
13027+
instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags)
13028+
%{
13029+
match(Set dst (CmpU3 src1 src2));
13030+
effect(KILL flags);
13031+
13032+
ins_cost(275); // XXX
13033+
format %{ "cmpl $src1, $src2\t# CmpL3\n\t"
13034+
"movl $dst, -1\n\t"
13035+
"jb,u done\n\t"
13036+
"setne $dst\n\t"
13037+
"movzbl $dst, $dst\n\t"
13038+
"done:" %}
13039+
ins_encode %{
13040+
Label done;
13041+
__ cmpl($src1$$Register, $src2$$Register);
13042+
__ movl($dst$$Register, -1);
13043+
__ jccb(Assembler::below, done);
13044+
__ setne($dst$$Register);
13045+
__ movzbl($dst$$Register, $dst$$Register);
13046+
__ bind(done);
13047+
%}
13048+
ins_pipe(pipe_slow);
13049+
%}
13050+
1302513051
// Manifest a CmpL result in an integer register. Very painful.
1302613052
// This is the test to avoid.
1302713053
instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags)
@@ -13048,6 +13074,32 @@ instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags)
1304813074
ins_pipe(pipe_slow);
1304913075
%}
1305013076

13077+
// Manifest a CmpUL result in an integer register. Very painful.
13078+
// This is the test to avoid.
13079+
instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags)
13080+
%{
13081+
match(Set dst (CmpUL3 src1 src2));
13082+
effect(KILL flags);
13083+
13084+
ins_cost(275); // XXX
13085+
format %{ "cmpq $src1, $src2\t# CmpL3\n\t"
13086+
"movl $dst, -1\n\t"
13087+
"jb,u done\n\t"
13088+
"setne $dst\n\t"
13089+
"movzbl $dst, $dst\n\t"
13090+
"done:" %}
13091+
ins_encode %{
13092+
Label done;
13093+
__ cmpq($src1$$Register, $src2$$Register);
13094+
__ movl($dst$$Register, -1);
13095+
__ jccb(Assembler::below, done);
13096+
__ setne($dst$$Register);
13097+
__ movzbl($dst$$Register, $dst$$Register);
13098+
__ bind(done);
13099+
%}
13100+
ins_pipe(pipe_slow);
13101+
%}
13102+
1305113103
// Unsigned long compare Instructions; really, same as signed long except they
1305213104
// produce an rFlagsRegU instead of rFlagsReg.
1305313105
instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2)

src/hotspot/share/classfile/vmIntrinsics.hpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ class methodHandle;
126126
do_signature(float2_float_signature, "(FF)F") \
127127
do_signature(float3_float_signature, "(FFF)F") \
128128
do_signature(int2_int_signature, "(II)I") \
129+
do_signature(long2_int_signature, "(JJ)I") \
129130
do_signature(long2_long_signature, "(JJ)J") \
130131
\
131132
/* here are the math names, all together: */ \
@@ -150,9 +151,9 @@ class methodHandle;
150151
do_name(expand_name,"expand") \
151152
\
152153
do_intrinsic(_dabs, java_lang_Math, abs_name, double_double_signature, F_S) \
153-
do_intrinsic(_fabs, java_lang_Math, abs_name, float_float_signature, F_S) \
154-
do_intrinsic(_iabs, java_lang_Math, abs_name, int_int_signature, F_S) \
155-
do_intrinsic(_labs, java_lang_Math, abs_name, long_long_signature, F_S) \
154+
do_intrinsic(_fabs, java_lang_Math, abs_name, float_float_signature, F_S) \
155+
do_intrinsic(_iabs, java_lang_Math, abs_name, int_int_signature, F_S) \
156+
do_intrinsic(_labs, java_lang_Math, abs_name, long_long_signature, F_S) \
156157
do_intrinsic(_dsin, java_lang_Math, sin_name, double_double_signature, F_S) \
157158
do_intrinsic(_floor, java_lang_Math, floor_name, double_double_signature, F_S) \
158159
do_intrinsic(_ceil, java_lang_Math, ceil_name, double_double_signature, F_S) \
@@ -205,7 +206,7 @@ class methodHandle;
205206
do_intrinsic(_dsqrt_strict, java_lang_StrictMath, sqrt_name, double_double_signature, F_SN) \
206207
\
207208
do_intrinsic(_floatIsInfinite, java_lang_Float, isInfinite_name, float_bool_signature, F_S) \
208-
do_name( isInfinite_name, "isInfinite") \
209+
do_name( isInfinite_name, "isInfinite") \
209210
do_intrinsic(_doubleIsInfinite, java_lang_Double, isInfinite_name, double_bool_signature, F_S) \
210211
\
211212
do_intrinsic(_floatToRawIntBits, java_lang_Float, floatToRawIntBits_name, float_int_signature, F_SN) \
@@ -221,12 +222,17 @@ class methodHandle;
221222
do_intrinsic(_longBitsToDouble, java_lang_Double, longBitsToDouble_name, long_double_signature, F_SN)\
222223
do_name( longBitsToDouble_name, "longBitsToDouble") \
223224
\
224-
do_intrinsic(_divideUnsigned_i, java_lang_Integer, divideUnsigned_name, int2_int_signature, F_S) \
225-
do_intrinsic(_remainderUnsigned_i, java_lang_Integer, remainderUnsigned_name, int2_int_signature, F_S) \
226-
do_name( divideUnsigned_name, "divideUnsigned") \
227-
do_intrinsic(_divideUnsigned_l, java_lang_Long, divideUnsigned_name, long2_long_signature, F_S) \
228-
do_intrinsic(_remainderUnsigned_l, java_lang_Long, remainderUnsigned_name, long2_long_signature, F_S) \
229-
do_name( remainderUnsigned_name, "remainderUnsigned") \
225+
do_intrinsic(_compareUnsigned_i, java_lang_Integer, compareUnsigned_name, int2_int_signature, F_S) \
226+
do_intrinsic(_compareUnsigned_l, java_lang_Long, compareUnsigned_name, long2_int_signature, F_S) \
227+
do_name( compareUnsigned_name, "compareUnsigned") \
228+
\
229+
do_intrinsic(_divideUnsigned_i, java_lang_Integer, divideUnsigned_name, int2_int_signature, F_S) \
230+
do_intrinsic(_remainderUnsigned_i, java_lang_Integer, remainderUnsigned_name, int2_int_signature, F_S) \
231+
do_name( divideUnsigned_name, "divideUnsigned") \
232+
do_intrinsic(_divideUnsigned_l, java_lang_Long, divideUnsigned_name, long2_long_signature, F_S) \
233+
do_intrinsic(_remainderUnsigned_l, java_lang_Long, remainderUnsigned_name, long2_long_signature, F_S) \
234+
do_name( remainderUnsigned_name, "remainderUnsigned") \
235+
\
230236
do_intrinsic(_numberOfLeadingZeros_i, java_lang_Integer, numberOfLeadingZeros_name,int_int_signature, F_S) \
231237
do_intrinsic(_numberOfLeadingZeros_l, java_lang_Long, numberOfLeadingZeros_name,long_int_signature, F_S) \
232238
\

src/hotspot/share/opto/c2compiler.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,12 @@ bool C2Compiler::is_intrinsic_supported(const methodHandle& method, bool is_virt
275275
case vmIntrinsics::_reverseBytes_l:
276276
if (!Matcher::match_rule_supported(Op_ReverseBytesL)) return false;
277277
break;
278+
case vmIntrinsics::_compareUnsigned_i:
279+
if (!Matcher::match_rule_supported(Op_CmpU3)) return false;
280+
break;
281+
case vmIntrinsics::_compareUnsigned_l:
282+
if (!Matcher::match_rule_supported(Op_CmpUL3)) return false;
283+
break;
278284
case vmIntrinsics::_divideUnsigned_i:
279285
if (!Matcher::match_rule_supported(Op_UDivI)) return false;
280286
break;

src/hotspot/share/opto/classes.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ macro(CmpL3)
9797
macro(CmpLTMask)
9898
macro(CmpP)
9999
macro(CmpU)
100+
macro(CmpU3)
100101
macro(CmpUL)
102+
macro(CmpUL3)
101103
macro(CompareAndSwapB)
102104
macro(CompareAndSwapS)
103105
macro(CompareAndSwapI)

src/hotspot/share/opto/library_call.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,9 @@ bool LibraryCallKit::try_to_inline(int predicate) {
535535
case vmIntrinsics::_expand_i:
536536
case vmIntrinsics::_expand_l: return inline_bitshuffle_methods(intrinsic_id());
537537

538+
case vmIntrinsics::_compareUnsigned_i:
539+
case vmIntrinsics::_compareUnsigned_l: return inline_compare_unsigned(intrinsic_id());
540+
538541
case vmIntrinsics::_divideUnsigned_i:
539542
case vmIntrinsics::_divideUnsigned_l:
540543
case vmIntrinsics::_remainderUnsigned_i:
@@ -2247,6 +2250,22 @@ bool LibraryCallKit::inline_bitshuffle_methods(vmIntrinsics::ID id) {
22472250
return true;
22482251
}
22492252

2253+
//--------------------------inline_number_methods-----------------------------
2254+
// inline int Integer.compareUnsigned(int, int)
2255+
// inline int Long.compareUnsigned(long, long)
2256+
bool LibraryCallKit::inline_compare_unsigned(vmIntrinsics::ID id) {
2257+
Node* arg1 = argument(0);
2258+
Node* arg2 = (id == vmIntrinsics::_compareUnsigned_l) ? argument(2) : argument(1);
2259+
Node* n = NULL;
2260+
switch (id) {
2261+
case vmIntrinsics::_compareUnsigned_i: n = new CmpU3Node(arg1, arg2); break;
2262+
case vmIntrinsics::_compareUnsigned_l: n = new CmpUL3Node(arg1, arg2); break;
2263+
default: fatal_unexpected_iid(id); break;
2264+
}
2265+
set_result(_gvn.transform(n));
2266+
return true;
2267+
}
2268+
22502269
//--------------------------inline_unsigned_divmod_methods-----------------------------
22512270
// inline int Integer.divideUnsigned(int, int)
22522271
// inline int Integer.remainderUnsigned(int, int)

src/hotspot/share/opto/library_call.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ class LibraryCallKit : public GraphKit {
277277
bool inline_fp_range_check(vmIntrinsics::ID id);
278278
bool inline_number_methods(vmIntrinsics::ID id);
279279
bool inline_bitshuffle_methods(vmIntrinsics::ID id);
280+
bool inline_compare_unsigned(vmIntrinsics::ID id);
280281
bool inline_divmod_methods(vmIntrinsics::ID id);
281282
bool inline_reference_get();
282283
bool inline_reference_refersTo0(bool is_phantom);

src/hotspot/share/opto/subnode.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,8 +848,12 @@ bool CmpUNode::is_index_range_check() const {
848848
Node *CmpINode::Ideal( PhaseGVN *phase, bool can_reshape ) {
849849
if (phase->type(in(2))->higher_equal(TypeInt::ZERO)) {
850850
switch (in(1)->Opcode()) {
851+
case Op_CmpU3: // Collapse a CmpU3/CmpI into a CmpU
852+
return new CmpUNode(in(1)->in(1),in(1)->in(2));
851853
case Op_CmpL3: // Collapse a CmpL3/CmpI into a CmpL
852854
return new CmpLNode(in(1)->in(1),in(1)->in(2));
855+
case Op_CmpUL3: // Collapse a CmpUL3/CmpI into a CmpUL
856+
return new CmpULNode(in(1)->in(1),in(1)->in(2));
853857
case Op_CmpF3: // Collapse a CmpF3/CmpI into a CmpF
854858
return new CmpFNode(in(1)->in(1),in(1)->in(2));
855859
case Op_CmpD3: // Collapse a CmpD3/CmpI into a CmpD

src/hotspot/share/opto/subnode.hpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,18 @@ class CmpUNode : public CmpNode {
173173
bool is_index_range_check() const;
174174
};
175175

176+
//------------------------------CmpU3Node--------------------------------------
177+
// Compare 2 unsigned values, returning integer value (-1, 0 or 1).
178+
class CmpU3Node : public CmpUNode {
179+
public:
180+
CmpU3Node( Node *in1, Node *in2 ) : CmpUNode(in1,in2) {
181+
// Since it is not consumed by Bools, it is not really a Cmp.
182+
init_class_id(Class_Sub);
183+
}
184+
virtual int Opcode() const;
185+
virtual uint ideal_reg() const { return Op_RegI; }
186+
};
187+
176188
//------------------------------CmpPNode---------------------------------------
177189
// Compare 2 pointer values, returning condition codes (-1, 0 or 1).
178190
class CmpPNode : public CmpNode {
@@ -220,7 +232,19 @@ class CmpL3Node : public CmpLNode {
220232
// Since it is not consumed by Bools, it is not really a Cmp.
221233
init_class_id(Class_Sub);
222234
}
223-
virtual int Opcode() const;
235+
virtual int Opcode() const;
236+
virtual uint ideal_reg() const { return Op_RegI; }
237+
};
238+
239+
//------------------------------CmpUL3Node-------------------------------------
240+
// Compare 2 unsigned long values, returning integer value (-1, 0 or 1).
241+
class CmpUL3Node : public CmpULNode {
242+
public:
243+
CmpUL3Node( Node *in1, Node *in2 ) : CmpULNode(in1,in2) {
244+
// Since it is not consumed by Bools, it is not really a Cmp.
245+
init_class_id(Class_Sub);
246+
}
247+
virtual int Opcode() const;
224248
virtual uint ideal_reg() const { return Op_RegI; }
225249
};
226250

src/hotspot/share/runtime/vmStructs.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1708,11 +1708,13 @@
17081708
declare_c2_type(CmpNode, SubNode) \
17091709
declare_c2_type(CmpINode, CmpNode) \
17101710
declare_c2_type(CmpUNode, CmpNode) \
1711+
declare_c2_type(CmpU3Node, CmpUNode) \
17111712
declare_c2_type(CmpPNode, CmpNode) \
17121713
declare_c2_type(CmpNNode, CmpNode) \
17131714
declare_c2_type(CmpLNode, CmpNode) \
17141715
declare_c2_type(CmpULNode, CmpNode) \
17151716
declare_c2_type(CmpL3Node, CmpLNode) \
1717+
declare_c2_type(CmpUL3Node, CmpULNode) \
17161718
declare_c2_type(CmpFNode, CmpNode) \
17171719
declare_c2_type(CmpF3Node, CmpFNode) \
17181720
declare_c2_type(CmpDNode, CmpNode) \

src/java.base/share/classes/java/lang/Integer.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,6 +1500,7 @@ public static int compare(int x, int y) {
15001500
* unsigned values
15011501
* @since 1.8
15021502
*/
1503+
@IntrinsicCandidate
15031504
public static int compareUnsigned(int x, int y) {
15041505
return compare(x + MIN_VALUE, y + MIN_VALUE);
15051506
}

0 commit comments

Comments
 (0)