Skip to content

Commit cc44419

Browse files
Fei GaoPengfei Li
Fei Gao
authored and
Pengfei Li
committed
8295407: C2 crash: Error: ShouldNotReachHere() in multiple vector tests with -XX:-MonomorphicArrayCheck -XX:-UncommonNullCast
Reviewed-by: thartmann, kvn
1 parent e2269fd commit cc44419

File tree

3 files changed

+131
-102
lines changed

3 files changed

+131
-102
lines changed

src/hotspot/share/opto/superword.cpp

+58-89
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ bool SuperWord::SLP_extract() {
535535

536536
construct_my_pack_map();
537537
if (UseVectorCmov) {
538-
merge_packs_to_cmovd();
538+
merge_packs_to_cmove();
539539
}
540540

541541
filter_packs();
@@ -1411,7 +1411,7 @@ int SuperWord::data_size(Node* s) {
14111411
if (use != NULL) {
14121412
return data_size(use);
14131413
}
1414-
use = _cmovev_kit.is_CmpD_candidate(s);
1414+
use = _cmovev_kit.is_Cmp_candidate(s);
14151415
if (use != NULL) {
14161416
return data_size(use);
14171417
}
@@ -1845,33 +1845,19 @@ void SuperWord::filter_packs() {
18451845
#endif
18461846
}
18471847

1848-
// Clear the unused cmove pack and its related packs from superword candidate packset.
1849-
void SuperWord::remove_cmove_and_related_packs(Node_List* cmove_pk) {
1850-
Node* cmove = cmove_pk->at(0);
1851-
Node* bol = cmove->as_CMove()->in(CMoveNode::Condition);
1852-
if (my_pack(bol)) {
1853-
remove_pack(my_pack(bol));
1854-
}
1855-
Node* cmp = bol->in(1);
1856-
if (my_pack(cmp)) {
1857-
remove_pack(my_pack(cmp));
1858-
}
1859-
remove_pack(cmove_pk);
1860-
}
1861-
1862-
//------------------------------merge_packs_to_cmovd---------------------------
1863-
// Merge qualified CMoveD into new vector-nodes
1864-
// We want to catch this pattern and subsume CmpD and Bool into CMoveD
1848+
//------------------------------merge_packs_to_cmove---------------------------
1849+
// Merge qualified CMove into new vector-nodes
1850+
// We want to catch this pattern and subsume Cmp and Bool into CMove
18651851
//
1866-
// SubD ConD
1852+
// Sub Con
18671853
// / | /
18681854
// / | / /
18691855
// / | / /
18701856
// / | / /
18711857
// / / /
18721858
// / / | /
18731859
// v / | /
1874-
// CmpD | /
1860+
// Cmp | /
18751861
// | | /
18761862
// v | /
18771863
// Bool | /
@@ -1880,25 +1866,20 @@ void SuperWord::remove_cmove_and_related_packs(Node_List* cmove_pk) {
18801866
// \ | /
18811867
// \ | /
18821868
// \ v /
1883-
// CMoveD
1869+
// CMove
18841870
//
1885-
// Also delete unqualified CMove pack from the packset and clear all info.
18861871

1887-
void SuperWord::merge_packs_to_cmovd() {
1872+
void SuperWord::merge_packs_to_cmove() {
18881873
for (int i = _packset.length() - 1; i >= 0; i--) {
18891874
Node_List* pk = _packset.at(i);
1890-
if (_cmovev_kit.is_cmove_pack_candidate(pk)) {
1891-
if (_cmovev_kit.can_merge_cmove_pack(pk)) {
1892-
_cmovev_kit.make_cmove_pack(pk);
1893-
} else {
1894-
remove_cmove_and_related_packs(pk);
1895-
}
1875+
if (_cmovev_kit.can_merge_cmove_pack(pk)) {
1876+
_cmovev_kit.make_cmove_pack(pk);
18961877
}
18971878
}
18981879

18991880
#ifndef PRODUCT
19001881
if (TraceSuperWord) {
1901-
tty->print_cr("\nSuperWord::merge_packs_to_cmovd(): After merge");
1882+
tty->print_cr("\nSuperWord::merge_packs_to_cmove(): After merge");
19021883
print_packset();
19031884
tty->cr();
19041885
}
@@ -1919,7 +1900,7 @@ Node* CMoveKit::is_Bool_candidate(Node* def) const {
19191900
return use;
19201901
}
19211902

1922-
Node* CMoveKit::is_CmpD_candidate(Node* def) const {
1903+
Node* CMoveKit::is_Cmp_candidate(Node* def) const {
19231904
Node* use = NULL;
19241905
if (!def->is_Cmp() || def->in(0) != NULL || def->outcnt() != 1) {
19251906
return NULL;
@@ -1933,32 +1914,28 @@ Node* CMoveKit::is_CmpD_candidate(Node* def) const {
19331914
return use;
19341915
}
19351916

1936-
bool CMoveKit::is_cmove_pack_candidate(Node_List* cmove_pk) {
1937-
Node* cmove = cmove_pk->at(0);
1938-
if ((cmove->Opcode() != Op_CMoveF && cmove->Opcode() != Op_CMoveD) ||
1939-
pack(cmove) != NULL /* already in the cmove pack */) {
1940-
return false;
1941-
}
1942-
return true;
1943-
}
1944-
19451917
// Determine if the current pack is an ideal cmove pack, and if its related packs,
19461918
// i.e. bool node pack and cmp node pack, can be successfully merged for vectorization.
19471919
bool CMoveKit::can_merge_cmove_pack(Node_List* cmove_pk) {
19481920
Node* cmove = cmove_pk->at(0);
19491921

1922+
if (!SuperWord::is_cmove_fp_opcode(cmove->Opcode()) ||
1923+
pack(cmove) != NULL /* already in the cmove pack */) {
1924+
return false;
1925+
}
1926+
19501927
if (cmove->in(0) != NULL) {
1951-
NOT_PRODUCT(if(_sw->is_trace_cmov()) {tty->print("CMoveKit::make_cmove_pack: CMove %d has control flow, escaping...", cmove->_idx); cmove->dump();})
1928+
NOT_PRODUCT(if(_sw->is_trace_cmov()) {tty->print("CMoveKit::can_merge_cmove_pack: CMove %d has control flow, escaping...", cmove->_idx); cmove->dump();})
19521929
return false;
19531930
}
19541931

19551932
Node* bol = cmove->as_CMove()->in(CMoveNode::Condition);
19561933
if (!bol->is_Bool() ||
19571934
bol->outcnt() != 1 ||
19581935
!_sw->same_generation(bol, cmove) ||
1959-
bol->in(0) != NULL || // BoolNode has control flow!!
1936+
bol->in(0) != NULL || // Bool node has control flow!!
19601937
_sw->my_pack(bol) == NULL) {
1961-
NOT_PRODUCT(if(_sw->is_trace_cmov()) {tty->print("CMoveKit::make_cmove_pack: Bool %d does not fit CMove %d for building vector, escaping...", bol->_idx, cmove->_idx); bol->dump();})
1938+
NOT_PRODUCT(if(_sw->is_trace_cmov()) {tty->print("CMoveKit::can_merge_cmove_pack: Bool %d does not fit CMove %d for building vector, escaping...", bol->_idx, cmove->_idx); bol->dump();})
19621939
return false;
19631940
}
19641941
Node_List* bool_pk = _sw->my_pack(bol);
@@ -1970,18 +1947,18 @@ bool CMoveKit::can_merge_cmove_pack(Node_List* cmove_pk) {
19701947
if (!cmp->is_Cmp() ||
19711948
cmp->outcnt() != 1 ||
19721949
!_sw->same_generation(cmp, cmove) ||
1973-
cmp->in(0) != NULL || // CmpNode has control flow!!
1950+
cmp->in(0) != NULL || // Cmp node has control flow!!
19741951
_sw->my_pack(cmp) == NULL) {
1975-
NOT_PRODUCT(if(_sw->is_trace_cmov()) {tty->print("CMoveKit::make_cmove_pack: Cmp %d does not fit CMove %d for building vector, escaping...", cmp->_idx, cmove->_idx); cmp->dump();})
1952+
NOT_PRODUCT(if(_sw->is_trace_cmov()) {tty->print("CMoveKit::can_merge_cmove_pack: Cmp %d does not fit CMove %d for building vector, escaping...", cmp->_idx, cmove->_idx); cmp->dump();})
19761953
return false;
19771954
}
19781955
Node_List* cmp_pk = _sw->my_pack(cmp);
19791956
if (cmp_pk->size() != cmove_pk->size() ) {
19801957
return false;
19811958
}
19821959

1983-
if (!test_cmpd_pack(cmp_pk, cmove_pk)) {
1984-
NOT_PRODUCT(if(_sw->is_trace_cmov()) {tty->print("CMoveKit::make_cmove_pack: cmp pack for Cmp %d failed vectorization test", cmp->_idx); cmp->dump();})
1960+
if (!test_cmp_pack(cmp_pk, cmove_pk)) {
1961+
NOT_PRODUCT(if(_sw->is_trace_cmov()) {tty->print("CMoveKit::can_merge_cmove_pack: cmp pack for Cmp %d failed vectorization test", cmp->_idx); cmp->dump();})
19851962
return false;
19861963
}
19871964

@@ -2019,59 +1996,59 @@ void CMoveKit::make_cmove_pack(Node_List* cmove_pk) {
20191996
NOT_PRODUCT(if(_sw->is_trace_cmov()) {tty->print_cr("CMoveKit::make_cmove_pack: added syntactic CMove pack"); _sw->print_pack(new_cmove_pk);})
20201997
}
20211998

2022-
bool CMoveKit::test_cmpd_pack(Node_List* cmpd_pk, Node_List* cmovd_pk) {
2023-
Node* cmpd0 = cmpd_pk->at(0);
2024-
assert(cmpd0->is_Cmp(), "CMoveKit::test_cmpd_pack: should be CmpDNode");
2025-
assert(cmovd_pk->at(0)->is_CMove(), "CMoveKit::test_cmpd_pack: should be CMoveD");
2026-
assert(cmpd_pk->size() == cmovd_pk->size(), "CMoveKit::test_cmpd_pack: should be same size");
2027-
Node* in1 = cmpd0->in(1);
2028-
Node* in2 = cmpd0->in(2);
1999+
bool CMoveKit::test_cmp_pack(Node_List* cmp_pk, Node_List* cmove_pk) {
2000+
Node* cmp0 = cmp_pk->at(0);
2001+
assert(cmp0->is_Cmp(), "CMoveKit::test_cmp_pack: should be Cmp Node");
2002+
assert(cmove_pk->at(0)->is_CMove(), "CMoveKit::test_cmp_pack: should be CMove");
2003+
assert(cmp_pk->size() == cmove_pk->size(), "CMoveKit::test_cmp_pack: should be same size");
2004+
Node* in1 = cmp0->in(1);
2005+
Node* in2 = cmp0->in(2);
20292006
Node_List* in1_pk = _sw->my_pack(in1);
20302007
Node_List* in2_pk = _sw->my_pack(in2);
20312008

2032-
if ( (in1_pk != NULL && in1_pk->size() != cmpd_pk->size())
2033-
|| (in2_pk != NULL && in2_pk->size() != cmpd_pk->size()) ) {
2009+
if ( (in1_pk != NULL && in1_pk->size() != cmp_pk->size())
2010+
|| (in2_pk != NULL && in2_pk->size() != cmp_pk->size()) ) {
20342011
return false;
20352012
}
20362013

20372014
// test if "all" in1 are in the same pack or the same node
20382015
if (in1_pk == NULL) {
2039-
for (uint j = 1; j < cmpd_pk->size(); j++) {
2040-
if (cmpd_pk->at(j)->in(1) != in1) {
2016+
for (uint j = 1; j < cmp_pk->size(); j++) {
2017+
if (cmp_pk->at(j)->in(1) != in1) {
20412018
return false;
20422019
}
2043-
}//for: in1_pk is not pack but all CmpD nodes in the pack have the same in(1)
2020+
}//for: in1_pk is not pack but all Cmp nodes in the pack have the same in(1)
20442021
}
20452022
// test if "all" in2 are in the same pack or the same node
20462023
if (in2_pk == NULL) {
2047-
for (uint j = 1; j < cmpd_pk->size(); j++) {
2048-
if (cmpd_pk->at(j)->in(2) != in2) {
2024+
for (uint j = 1; j < cmp_pk->size(); j++) {
2025+
if (cmp_pk->at(j)->in(2) != in2) {
20492026
return false;
20502027
}
2051-
}//for: in2_pk is not pack but all CmpD nodes in the pack have the same in(2)
2052-
}
2053-
//now check if cmpd_pk may be subsumed in vector built for cmovd_pk
2054-
int cmovd_ind1, cmovd_ind2;
2055-
if (cmpd_pk->at(0)->in(1) == cmovd_pk->at(0)->as_CMove()->in(CMoveNode::IfFalse)
2056-
&& cmpd_pk->at(0)->in(2) == cmovd_pk->at(0)->as_CMove()->in(CMoveNode::IfTrue)) {
2057-
cmovd_ind1 = CMoveNode::IfFalse;
2058-
cmovd_ind2 = CMoveNode::IfTrue;
2059-
} else if (cmpd_pk->at(0)->in(2) == cmovd_pk->at(0)->as_CMove()->in(CMoveNode::IfFalse)
2060-
&& cmpd_pk->at(0)->in(1) == cmovd_pk->at(0)->as_CMove()->in(CMoveNode::IfTrue)) {
2061-
cmovd_ind2 = CMoveNode::IfFalse;
2062-
cmovd_ind1 = CMoveNode::IfTrue;
2028+
}//for: in2_pk is not pack but all Cmp nodes in the pack have the same in(2)
2029+
}
2030+
//now check if cmp_pk may be subsumed in vector built for cmove_pk
2031+
int cmove_ind1, cmove_ind2;
2032+
if (cmp_pk->at(0)->in(1) == cmove_pk->at(0)->as_CMove()->in(CMoveNode::IfFalse)
2033+
&& cmp_pk->at(0)->in(2) == cmove_pk->at(0)->as_CMove()->in(CMoveNode::IfTrue)) {
2034+
cmove_ind1 = CMoveNode::IfFalse;
2035+
cmove_ind2 = CMoveNode::IfTrue;
2036+
} else if (cmp_pk->at(0)->in(2) == cmove_pk->at(0)->as_CMove()->in(CMoveNode::IfFalse)
2037+
&& cmp_pk->at(0)->in(1) == cmove_pk->at(0)->as_CMove()->in(CMoveNode::IfTrue)) {
2038+
cmove_ind2 = CMoveNode::IfFalse;
2039+
cmove_ind1 = CMoveNode::IfTrue;
20632040
}
20642041
else {
20652042
return false;
20662043
}
20672044

2068-
for (uint j = 1; j < cmpd_pk->size(); j++) {
2069-
if (cmpd_pk->at(j)->in(1) != cmovd_pk->at(j)->as_CMove()->in(cmovd_ind1)
2070-
|| cmpd_pk->at(j)->in(2) != cmovd_pk->at(j)->as_CMove()->in(cmovd_ind2)) {
2045+
for (uint j = 1; j < cmp_pk->size(); j++) {
2046+
if (cmp_pk->at(j)->in(1) != cmove_pk->at(j)->as_CMove()->in(cmove_ind1)
2047+
|| cmp_pk->at(j)->in(2) != cmove_pk->at(j)->as_CMove()->in(cmove_ind2)) {
20712048
return false;
20722049
}//if
20732050
}
2074-
NOT_PRODUCT(if(_sw->is_trace_cmov()) { tty->print("CMoveKit::test_cmpd_pack: cmpd pack for 1st CmpD %d is OK for vectorization: ", cmpd0->_idx); cmpd0->dump(); })
2051+
NOT_PRODUCT(if(_sw->is_trace_cmov()) { tty->print("CMoveKit::test_cmp_pack: cmp pack for 1st Cmp %d is OK for vectorization: ", cmp0->_idx); cmp0->dump(); })
20752052
return true;
20762053
}
20772054

@@ -2099,6 +2076,9 @@ bool SuperWord::implemented(Node_List* p) {
20992076
// integer subword types with superword vectorization.
21002077
// See JDK-8294816 for miscompilation issues with shorts.
21012078
return false;
2079+
} else if (is_cmove_fp_opcode(opc)) {
2080+
retValue = is_cmov_pack(p) && VectorNode::implemented(opc, size, velt_basic_type(p0));
2081+
NOT_PRODUCT(if(retValue && is_trace_cmov()) {tty->print_cr("SWPointer::implemented: found cmove pack"); print_pack(p);})
21022082
} else {
21032083
// Vector unsigned right shift for signed subword types behaves differently
21042084
// from Java Spec. But when the shift amount is a constant not greater than
@@ -2108,7 +2088,6 @@ bool SuperWord::implemented(Node_List* p) {
21082088
opc = Op_RShiftI;
21092089
}
21102090
retValue = VectorNode::implemented(opc, size, velt_basic_type(p0));
2111-
NOT_PRODUCT(if(retValue && is_trace_cmov() && is_cmov_pack(p)) {tty->print_cr("SWPointer::implemented: found cmpd pack"); print_pack(p);})
21122091
}
21132092
}
21142093
return retValue;
@@ -3719,16 +3698,6 @@ void SuperWord::remove_pack_at(int pos) {
37193698
_packset.remove_at(pos);
37203699
}
37213700

3722-
//------------------------------remove_pack------------------------------
3723-
// Remove the pack in the packset
3724-
void SuperWord::remove_pack(Node_List* p) {
3725-
for (uint i = 0; i < p->size(); i++) {
3726-
Node* s = p->at(i);
3727-
set_my_pack(s, NULL);
3728-
}
3729-
_packset.remove(p);
3730-
}
3731-
37323701
void SuperWord::packset_sort(int n) {
37333702
// simple bubble sort so that we capitalize with O(n) when its already sorted
37343703
while (n != 0) {

src/hotspot/share/opto/superword.hpp

+8-13
Original file line numberDiff line numberDiff line change
@@ -214,13 +214,11 @@ class CMoveKit {
214214
void unmap(Node* key) { _dict->Delete(_2p(key)); }
215215
Node_List* pack(Node* key) const { return (Node_List*)_dict->operator[](_2p(key)); }
216216
Node* is_Bool_candidate(Node* nd) const; // if it is the right candidate return corresponding CMove* ,
217-
Node* is_CmpD_candidate(Node* nd) const; // otherwise return NULL
218-
// If the input pack is a cmove candidate, return true, otherwise return false.
219-
bool is_cmove_pack_candidate(Node_List* cmove_pk);
220-
// Determine if the current cmove pack can be vectorized.
217+
Node* is_Cmp_candidate(Node* nd) const; // otherwise return NULL
218+
// Determine if the current pack is a cmove candidate that can be vectorized.
221219
bool can_merge_cmove_pack(Node_List* cmove_pk);
222-
void make_cmove_pack(Node_List* cmovd_pk);
223-
bool test_cmpd_pack(Node_List* cmpd_pk, Node_List* cmovd_pk);
220+
void make_cmove_pack(Node_List* cmove_pk);
221+
bool test_cmp_pack(Node_List* cmp_pk, Node_List* cmove_pk);
224222
};//class CMoveKit
225223

226224
// JVMCI: OrderedPair is moved up to deal with compilation issues on Windows
@@ -455,9 +453,10 @@ class SuperWord : public ResourceObj {
455453
// my_pack
456454
Node_List* my_pack(Node* n) { return !in_bb(n) ? NULL : _node_info.adr_at(bb_idx(n))->_my_pack; }
457455
void set_my_pack(Node* n, Node_List* p) { int i = bb_idx(n); grow_node_info(i); _node_info.adr_at(i)->_my_pack = p; }
458-
// is pack good for converting into one vector node replacing 12 nodes of Cmp, Bool, CMov
456+
// is pack good for converting into one vector node replacing bunches of Cmp, Bool, CMov nodes.
459457
bool is_cmov_pack(Node_List* p);
460458
bool is_cmov_pack_internal_node(Node_List* p, Node* nd) { return is_cmov_pack(p) && !nd->is_CMove(); }
459+
static bool is_cmove_fp_opcode(int opc) { return (opc == Op_CMoveF || opc == Op_CMoveD); }
461460
// For pack p, are all idx operands the same?
462461
bool same_inputs(Node_List* p, int idx);
463462
// CloneMap utilities
@@ -540,10 +539,8 @@ class SuperWord : public ResourceObj {
540539
void construct_my_pack_map();
541540
// Remove packs that are not implemented or not profitable.
542541
void filter_packs();
543-
// Clear the unused cmove pack and its related packs from superword candidate packset.
544-
void remove_cmove_and_related_packs(Node_List* cmove_pk);
545-
// Merge CMoveD into new vector-nodes
546-
void merge_packs_to_cmovd();
542+
// Merge CMove into new vector-nodes
543+
void merge_packs_to_cmove();
547544
// Adjust the memory graph for the packed operations
548545
void schedule();
549546
// Remove "current" from its current position in the memory graph and insert
@@ -590,8 +587,6 @@ class SuperWord : public ResourceObj {
590587
Node_List* in_pack(Node* s, Node_List* p);
591588
// Remove the pack at position pos in the packset
592589
void remove_pack_at(int pos);
593-
// Remove the pack in the packset
594-
void remove_pack(Node_List* p);
595590
// Return the node executed first in pack p.
596591
Node* executed_first(Node_List* p);
597592
// Return the node executed last in pack p.

0 commit comments

Comments
 (0)