Skip to content

Commit eab5644

Browse files
author
Hamlin Li
committed
8370481: C2 SuperWord: Long/Integer.compareUnsigned return wrong value in SLP
Reviewed-by: epeter, tonyp
1 parent 2c07214 commit eab5644

File tree

3 files changed

+782
-3
lines changed

3 files changed

+782
-3
lines changed

src/hotspot/share/opto/subnode.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ struct BoolTest {
331331
mask negate( ) const { return negate_mask(_test); }
332332
// Return the negative mask for the given mask, for both signed and unsigned comparison.
333333
static mask negate_mask(mask btm) { return mask(btm ^ 4); }
334+
static mask unsigned_mask(mask btm) { return mask(btm | unsigned_compare); }
334335
bool is_canonical( ) const { return (_test == BoolTest::ne || _test == BoolTest::lt || _test == BoolTest::le || _test == BoolTest::overflow); }
335336
bool is_less( ) const { return _test == BoolTest::lt || _test == BoolTest::le; }
336337
bool is_greater( ) const { return _test == BoolTest::gt || _test == BoolTest::ge; }

src/hotspot/share/opto/superword.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1698,7 +1698,9 @@ VTransformBoolTest PackSet::get_bool_test(const Node_List* bool_pack) const {
16981698
CmpNode* cmp0 = bol->in(1)->as_Cmp();
16991699
assert(get_pack(cmp0) != nullptr, "Bool must have matching Cmp pack");
17001700

1701-
if (cmp0->Opcode() == Op_CmpF || cmp0->Opcode() == Op_CmpD) {
1701+
switch (cmp0->Opcode()) {
1702+
case Op_CmpF:
1703+
case Op_CmpD:
17021704
// If we have a Float or Double comparison, we must be careful with
17031705
// handling NaN's correctly. CmpF and CmpD have a return code, as
17041706
// they are based on the java bytecodes fcmpl/dcmpl:
@@ -1742,7 +1744,24 @@ VTransformBoolTest PackSet::get_bool_test(const Node_List* bool_pack) const {
17421744
mask = bol->_test.negate();
17431745
is_negated = true;
17441746
}
1745-
}
1747+
break;
1748+
case Op_CmpU:
1749+
case Op_CmpUL:
1750+
// When we have CmpU->Bool, the mask of the Bool has no unsigned-ness information,
1751+
// but the mask is implicitly unsigned only because of the CmpU. Since we will replace
1752+
// the CmpU->Bool with a single VectorMaskCmp, we need to now make the unsigned-ness
1753+
// explicit.
1754+
mask = BoolTest::unsigned_mask(mask);
1755+
break;
1756+
case Op_CmpI:
1757+
case Op_CmpL:
1758+
// The mask of signed int/long scalar comparisons has the same semantics
1759+
// as the mask for vector elementwise int/long comparison with VectorMaskCmp.
1760+
break;
1761+
default:
1762+
// Other Cmp ops are not expected to get here.
1763+
ShouldNotReachHere();
1764+
} // switch
17461765

17471766
return VTransformBoolTest(mask, is_negated);
17481767
}

0 commit comments

Comments
 (0)