Skip to content

Commit 1438ce0

Browse files
author
Vladimir Kozlov
committed
8252188: Crash in OrINode::Ideal(PhaseGVN*, bool)+0x8b9
Reviewed-by: vlivanov, thartmann, jbhateja
1 parent 224a30f commit 1438ce0

File tree

7 files changed

+996
-378
lines changed

7 files changed

+996
-378
lines changed

src/hotspot/share/opto/addnode.cpp

Lines changed: 45 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -743,41 +743,47 @@ Node* OrINode::Identity(PhaseGVN* phase) {
743743
return AddNode::Identity(phase);
744744
}
745745

746-
Node *OrINode::Ideal(PhaseGVN *phase, bool can_reshape) {
746+
// Find shift value for Integer or Long OR.
747+
Node* rotate_shift(PhaseGVN* phase, Node* lshift, Node* rshift, int mask) {
748+
// val << norm_con_shift | val >> ({32|64} - norm_con_shift) => rotate_left val, norm_con_shift
749+
const TypeInt* lshift_t = phase->type(lshift)->isa_int();
750+
const TypeInt* rshift_t = phase->type(rshift)->isa_int();
751+
if (lshift_t != NULL && lshift_t->is_con() &&
752+
rshift_t != NULL && rshift_t->is_con() &&
753+
((lshift_t->get_con() & mask) == ((mask + 1) - (rshift_t->get_con() & mask)))) {
754+
return phase->intcon(lshift_t->get_con() & mask);
755+
}
756+
// val << var_shift | val >> ({0|32|64} - var_shift) => rotate_left val, var_shift
757+
if (rshift->Opcode() == Op_SubI && rshift->in(2) == lshift && rshift->in(1)->is_Con()){
758+
const TypeInt* shift_t = phase->type(rshift->in(1))->isa_int();
759+
if (shift_t != NULL && shift_t->is_con() &&
760+
(shift_t->get_con() == 0 || shift_t->get_con() == (mask + 1))) {
761+
return lshift;
762+
}
763+
}
764+
return NULL;
765+
}
766+
767+
Node* OrINode::Ideal(PhaseGVN* phase, bool can_reshape) {
747768
int lopcode = in(1)->Opcode();
748769
int ropcode = in(2)->Opcode();
749770
if (Matcher::match_rule_supported(Op_RotateLeft) &&
750771
lopcode == Op_LShiftI && ropcode == Op_URShiftI && in(1)->in(1) == in(2)->in(1)) {
751-
Node *lshift = in(1)->in(2);
752-
Node *rshift = in(2)->in(2);
753-
// val << norm_con_shift | val >> (32 - norm_con_shift) => rotate_left val , norm_con_shift
754-
if (lshift->is_Con() && rshift->is_Con() &&
755-
((lshift->get_int() & 0x1F) == (32 - (rshift->get_int() & 0x1F)))) {
756-
return new RotateLeftNode(in(1)->in(1),
757-
phase->intcon(lshift->get_int() & 0x1F), TypeInt::INT);
758-
}
759-
// val << var_shift | val >> (0/32 - var_shift) => rotate_left val , var_shift
760-
if (rshift->Opcode() == Op_SubI && rshift->in(2) == lshift &&
761-
rshift->in(1)->is_Con() &&
762-
(rshift->in(1)->get_int() == 0 || rshift->in(1)->get_int() == 32)) {
763-
return new RotateLeftNode(in(1)->in(1), lshift, TypeInt::INT);
772+
Node* lshift = in(1)->in(2);
773+
Node* rshift = in(2)->in(2);
774+
Node* shift = rotate_shift(phase, lshift, rshift, 0x1F);
775+
if (shift != NULL) {
776+
return new RotateLeftNode(in(1)->in(1), shift, TypeInt::INT);
764777
}
778+
return NULL;
765779
}
766780
if (Matcher::match_rule_supported(Op_RotateRight) &&
767781
lopcode == Op_URShiftI && ropcode == Op_LShiftI && in(1)->in(1) == in(2)->in(1)) {
768782
Node *rshift = in(1)->in(2);
769783
Node *lshift = in(2)->in(2);
770-
// val >> norm_con_shift | val << (32 - norm_con_shift) => rotate_right val , norm_con_shift
771-
if (rshift->is_Con() && lshift->is_Con() &&
772-
((rshift->get_int() & 0x1F) == (32 - (lshift->get_int() & 0x1F)))) {
773-
return new RotateRightNode(in(1)->in(1),
774-
phase->intcon(rshift->get_int() & 0x1F), TypeInt::INT);
775-
}
776-
// val >> var_shift | val << (0/32 - var_shift) => rotate_right val , var_shift
777-
if (lshift->Opcode() == Op_SubI && lshift->in(2) == rshift &&
778-
lshift->in(1)->is_Con() &&
779-
(lshift->in(1)->get_int() == 0 || lshift->in(1)->get_int() == 32)) {
780-
return new RotateRightNode(in(1)->in(1), rshift, TypeInt::INT);
784+
Node* shift = rotate_shift(phase, rshift, lshift, 0x1F);
785+
if (shift != NULL) {
786+
return new RotateRightNode(in(1)->in(1), shift, TypeInt::INT);
781787
}
782788
}
783789
return NULL;
@@ -824,42 +830,27 @@ Node* OrLNode::Identity(PhaseGVN* phase) {
824830
return AddNode::Identity(phase);
825831
}
826832

827-
Node *OrLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
833+
Node* OrLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
828834
int lopcode = in(1)->Opcode();
829835
int ropcode = in(2)->Opcode();
830836
if (Matcher::match_rule_supported(Op_RotateLeft) &&
831837
lopcode == Op_LShiftL && ropcode == Op_URShiftL && in(1)->in(1) == in(2)->in(1)) {
832-
Node *lshift = in(1)->in(2);
833-
Node *rshift = in(2)->in(2);
834-
// val << norm_con_shift | val >> (64 - norm_con_shift) => rotate_left val , norm_con_shift
835-
if (lshift->is_Con() && rshift->is_Con() &&
836-
((lshift->get_int() & 0x3F) == (64 - (rshift->get_int() & 0x3F)))) {
837-
return new RotateLeftNode(in(1)->in(1),
838-
phase->intcon(lshift->get_int() & 0x3F), TypeLong::LONG);
839-
}
840-
// val << var_shift | val >> (0/64 - var_shift) => rotate_left val , var_shift
841-
if (rshift->Opcode() == Op_SubI && rshift->in(2) == lshift &&
842-
rshift->in(1)->is_Con() &&
843-
(rshift->in(1)->get_int() == 0 || rshift->in(1)->get_int() == 64)) {
844-
return new RotateLeftNode(in(1)->in(1), lshift, TypeLong::LONG);
845-
}
838+
Node* lshift = in(1)->in(2);
839+
Node* rshift = in(2)->in(2);
840+
Node* shift = rotate_shift(phase, lshift, rshift, 0x3F);
841+
if (shift != NULL) {
842+
return new RotateLeftNode(in(1)->in(1), shift, TypeLong::LONG);
843+
}
844+
return NULL;
846845
}
847846
if (Matcher::match_rule_supported(Op_RotateRight) &&
848847
lopcode == Op_URShiftL && ropcode == Op_LShiftL && in(1)->in(1) == in(2)->in(1)) {
849-
Node *rshift = in(1)->in(2);
850-
Node *lshift = in(2)->in(2);
851-
// val >> norm_con_shift | val << (64 - norm_con_shift) => rotate_right val , norm_con_shift
852-
if (rshift->is_Con() && lshift->is_Con() &&
853-
((rshift->get_int() & 0x3F) == (64 - (lshift->get_int() & 0x3F)))) {
854-
return new RotateRightNode(in(1)->in(1),
855-
phase->intcon(rshift->get_int() & 0x3F), TypeLong::LONG);
856-
}
857-
// val >> var_shift | val << (0/64 - var_shift) => rotate_right val , var_shift
858-
if (lshift->Opcode() == Op_SubI && lshift->in(2) == rshift &&
859-
lshift->in(1)->is_Con() &&
860-
(lshift->in(1)->get_int() == 0 || lshift->in(1)->get_int() == 64)) {
861-
return new RotateRightNode(in(1)->in(1), rshift, TypeLong::LONG);
862-
}
848+
Node* rshift = in(1)->in(2);
849+
Node* lshift = in(2)->in(2);
850+
Node* shift = rotate_shift(phase, rshift, lshift, 0x3F);
851+
if (shift != NULL) {
852+
return new RotateRightNode(in(1)->in(1), shift, TypeLong::LONG);
853+
}
863854
}
864855
return NULL;
865856
}

src/hotspot/share/opto/vectornode.cpp

Lines changed: 15 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -835,46 +835,33 @@ MacroLogicVNode* MacroLogicVNode::make(PhaseGVN& gvn, Node* in1, Node* in2, Node
835835

836836
Node* VectorNode::degenerate_vector_rotate(Node* src, Node* cnt, bool is_rotate_left,
837837
int vlen, BasicType bt, PhaseGVN* phase) {
838-
int shiftLOpc;
839-
int shiftROpc;
840-
Node* shiftLCnt = NULL;
841-
Node* shiftRCnt = NULL;
838+
assert(bt == T_INT || bt == T_LONG, "sanity");
842839
const TypeVect* vt = TypeVect::make(bt, vlen);
843840

841+
int shift_mask = (bt == T_INT) ? 0x1F : 0x3F;
842+
int shiftLOpc = (bt == T_INT) ? Op_LShiftI : Op_LShiftL;
843+
int shiftROpc = (bt == T_INT) ? Op_URShiftI: Op_URShiftL;
844+
844845
// Compute shift values for right rotation and
845846
// later swap them in case of left rotation.
846-
if (cnt->is_Con()) {
847+
Node* shiftRCnt = NULL;
848+
Node* shiftLCnt = NULL;
849+
if (cnt->is_Con() && cnt->bottom_type()->isa_int()) {
847850
// Constant shift case.
848-
if (bt == T_INT) {
849-
int shift = cnt->get_int() & 31;
850-
shiftRCnt = phase->intcon(shift);
851-
shiftLCnt = phase->intcon(32 - shift);
852-
shiftLOpc = Op_LShiftI;
853-
shiftROpc = Op_URShiftI;
854-
} else {
855-
int shift = cnt->get_int() & 63;
856-
shiftRCnt = phase->intcon(shift);
857-
shiftLCnt = phase->intcon(64 - shift);
858-
shiftLOpc = Op_LShiftL;
859-
shiftROpc = Op_URShiftL;
860-
}
851+
int shift = cnt->get_int() & shift_mask;
852+
shiftRCnt = phase->intcon(shift);
853+
shiftLCnt = phase->intcon(shift_mask + 1 - shift);
861854
} else {
862855
// Variable shift case.
863856
assert(VectorNode::is_invariant_vector(cnt), "Broadcast expected");
864857
cnt = cnt->in(1);
865-
if (bt == T_INT) {
866-
shiftRCnt = phase->transform(new AndINode(cnt, phase->intcon(31)));
867-
shiftLCnt = phase->transform(new SubINode(phase->intcon(32), shiftRCnt));
868-
shiftLOpc = Op_LShiftI;
869-
shiftROpc = Op_URShiftI;
870-
} else {
858+
if (bt == T_LONG) {
859+
// Shift count vector for Rotate vector has long elements too.
871860
assert(cnt->Opcode() == Op_ConvI2L, "ConvI2L expected");
872861
cnt = cnt->in(1);
873-
shiftRCnt = phase->transform(new AndINode(cnt, phase->intcon(63)));
874-
shiftLCnt = phase->transform(new SubINode(phase->intcon(64), shiftRCnt));
875-
shiftLOpc = Op_LShiftL;
876-
shiftROpc = Op_URShiftL;
877862
}
863+
shiftRCnt = phase->transform(new AndINode(cnt, phase->intcon(shift_mask)));
864+
shiftLCnt = phase->transform(new SubINode(phase->intcon(shift_mask + 1), shiftRCnt));
878865
}
879866

880867
// Swap the computed left and right shift counts.
@@ -908,86 +895,3 @@ Node* RotateRightVNode::Ideal(PhaseGVN* phase, bool can_reshape) {
908895
return NULL;
909896
}
910897

911-
Node* OrVNode::Ideal(PhaseGVN* phase, bool can_reshape) {
912-
int lopcode = in(1)->Opcode();
913-
int ropcode = in(2)->Opcode();
914-
const TypeVect* vt = bottom_type()->is_vect();
915-
int vec_len = vt->length();
916-
BasicType bt = vt->element_basic_type();
917-
918-
// Vector Rotate operations inferencing, this will be useful when vector
919-
// operations are created via non-SLP route i.e. (VectorAPI).
920-
if (Matcher::match_rule_supported_vector(Op_RotateLeftV, vec_len, bt) &&
921-
((ropcode == Op_LShiftVI && lopcode == Op_URShiftVI) ||
922-
(ropcode == Op_LShiftVL && lopcode == Op_URShiftVL)) &&
923-
in(1)->in(1) == in(2)->in(1)) {
924-
assert(Op_RShiftCntV == in(1)->in(2)->Opcode(), "LShiftCntV operand expected");
925-
assert(Op_LShiftCntV == in(2)->in(2)->Opcode(), "RShiftCntV operand expected");
926-
Node* lshift = in(1)->in(2)->in(1);
927-
Node* rshift = in(2)->in(2)->in(1);
928-
int mod_val = bt == T_LONG ? 64 : 32;
929-
int shift_mask = bt == T_LONG ? 0x3F : 0x1F;
930-
// val >> norm_con_shift | val << (32 - norm_con_shift) => rotate_right val ,
931-
// norm_con_shift
932-
if (lshift->is_Con() && rshift->is_Con() &&
933-
((lshift->get_int() & shift_mask) ==
934-
(mod_val - (rshift->get_int() & shift_mask)))) {
935-
return new RotateRightVNode(
936-
in(1)->in(1), phase->intcon(lshift->get_int() & shift_mask), vt);
937-
}
938-
if (lshift->Opcode() == Op_AndI && rshift->Opcode() == Op_AndI &&
939-
lshift->in(2)->is_Con() && rshift->in(2)->is_Con() &&
940-
lshift->in(2)->get_int() == (mod_val - 1) &&
941-
rshift->in(2)->get_int() == (mod_val - 1)) {
942-
lshift = lshift->in(1);
943-
rshift = rshift->in(1);
944-
// val << var_shift | val >> (0/32 - var_shift) => rotate_left val ,
945-
// var_shift
946-
if (lshift->Opcode() == Op_SubI && lshift->in(2) == rshift &&
947-
lshift->in(1)->is_Con() &&
948-
(lshift->in(1)->get_int() == 0 ||
949-
lshift->in(1)->get_int() == mod_val)) {
950-
Node* rotate_cnt = phase->transform(new ReplicateINode(rshift, vt));
951-
return new RotateLeftVNode(in(1)->in(1), rotate_cnt, vt);
952-
}
953-
}
954-
}
955-
956-
if (Matcher::match_rule_supported_vector(Op_RotateRightV, vec_len, bt) &&
957-
((ropcode == Op_URShiftVI && lopcode == Op_LShiftVI) ||
958-
(ropcode == Op_URShiftVL && lopcode == Op_LShiftVL)) &&
959-
in(1)->in(1) == in(2)->in(1)) {
960-
assert(Op_LShiftCntV == in(1)->in(2)->Opcode(), "RShiftCntV operand expected");
961-
assert(Op_RShiftCntV == in(2)->in(2)->Opcode(), "LShiftCntV operand expected");
962-
Node* rshift = in(1)->in(2)->in(1);
963-
Node* lshift = in(2)->in(2)->in(1);
964-
int mod_val = bt == T_LONG ? 64 : 32;
965-
int shift_mask = bt == T_LONG ? 0x3F : 0x1F;
966-
// val << norm_con_shift | val >> (32 - norm_con_shift) => rotate_left val
967-
// , norm_con_shift
968-
if (rshift->is_Con() && lshift->is_Con() &&
969-
((rshift->get_int() & shift_mask) ==
970-
(mod_val - (lshift->get_int() & shift_mask)))) {
971-
return new RotateLeftVNode(
972-
in(1)->in(1), phase->intcon(rshift->get_int() & shift_mask), vt);
973-
}
974-
if (lshift->Opcode() == Op_AndI && rshift->Opcode() == Op_AndI &&
975-
lshift->in(2)->is_Con() && rshift->in(2)->is_Con() &&
976-
rshift->in(2)->get_int() == (mod_val - 1) &&
977-
lshift->in(2)->get_int() == (mod_val - 1)) {
978-
rshift = rshift->in(1);
979-
lshift = lshift->in(1);
980-
// val >> var_shift | val << (0/32 - var_shift) => rotate_right val ,
981-
// var_shift
982-
if (rshift->Opcode() == Op_SubI && rshift->in(2) == lshift &&
983-
rshift->in(1)->is_Con() &&
984-
(rshift->in(1)->get_int() == 0 ||
985-
rshift->in(1)->get_int() == mod_val)) {
986-
Node* rotate_cnt = phase->transform(new ReplicateINode(lshift, vt));
987-
return new RotateRightVNode(in(1)->in(1), rotate_cnt, vt);
988-
}
989-
}
990-
}
991-
return NULL;
992-
}
993-

src/hotspot/share/opto/vectornode.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,6 @@ class OrVNode : public VectorNode {
624624
public:
625625
OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
626626
virtual int Opcode() const;
627-
Node* Ideal(PhaseGVN* phase, bool can_reshape);
628627
};
629628

630629
//------------------------------XorVNode---------------------------------------

0 commit comments

Comments
 (0)