From 1438ce097f4b327570504066a3f999163802a14f Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Sat, 19 Sep 2020 16:06:35 +0000 Subject: [PATCH] 8252188: Crash in OrINode::Ideal(PhaseGVN*, bool)+0x8b9 Reviewed-by: vlivanov, thartmann, jbhateja --- src/hotspot/share/opto/addnode.cpp | 99 ++-- src/hotspot/share/opto/vectornode.cpp | 126 +---- src/hotspot/share/opto/vectornode.hpp | 1 - .../compiler/c2/cr6340864/TestIntVect.java | 109 +--- .../c2/cr6340864/TestIntVectRotate.java | 467 ++++++++++++++++++ .../compiler/c2/cr6340864/TestLongVect.java | 105 ---- .../c2/cr6340864/TestLongVectRotate.java | 467 ++++++++++++++++++ 7 files changed, 996 insertions(+), 378 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/c2/cr6340864/TestIntVectRotate.java create mode 100644 test/hotspot/jtreg/compiler/c2/cr6340864/TestLongVectRotate.java diff --git a/src/hotspot/share/opto/addnode.cpp b/src/hotspot/share/opto/addnode.cpp index f83938ad28a..1ac85cce122 100644 --- a/src/hotspot/share/opto/addnode.cpp +++ b/src/hotspot/share/opto/addnode.cpp @@ -743,41 +743,47 @@ Node* OrINode::Identity(PhaseGVN* phase) { return AddNode::Identity(phase); } -Node *OrINode::Ideal(PhaseGVN *phase, bool can_reshape) { +// Find shift value for Integer or Long OR. +Node* rotate_shift(PhaseGVN* phase, Node* lshift, Node* rshift, int mask) { + // val << norm_con_shift | val >> ({32|64} - norm_con_shift) => rotate_left val, norm_con_shift + const TypeInt* lshift_t = phase->type(lshift)->isa_int(); + const TypeInt* rshift_t = phase->type(rshift)->isa_int(); + if (lshift_t != NULL && lshift_t->is_con() && + rshift_t != NULL && rshift_t->is_con() && + ((lshift_t->get_con() & mask) == ((mask + 1) - (rshift_t->get_con() & mask)))) { + return phase->intcon(lshift_t->get_con() & mask); + } + // val << var_shift | val >> ({0|32|64} - var_shift) => rotate_left val, var_shift + if (rshift->Opcode() == Op_SubI && rshift->in(2) == lshift && rshift->in(1)->is_Con()){ + const TypeInt* shift_t = phase->type(rshift->in(1))->isa_int(); + if (shift_t != NULL && shift_t->is_con() && + (shift_t->get_con() == 0 || shift_t->get_con() == (mask + 1))) { + return lshift; + } + } + return NULL; +} + +Node* OrINode::Ideal(PhaseGVN* phase, bool can_reshape) { int lopcode = in(1)->Opcode(); int ropcode = in(2)->Opcode(); if (Matcher::match_rule_supported(Op_RotateLeft) && lopcode == Op_LShiftI && ropcode == Op_URShiftI && in(1)->in(1) == in(2)->in(1)) { - Node *lshift = in(1)->in(2); - Node *rshift = in(2)->in(2); - // val << norm_con_shift | val >> (32 - norm_con_shift) => rotate_left val , norm_con_shift - if (lshift->is_Con() && rshift->is_Con() && - ((lshift->get_int() & 0x1F) == (32 - (rshift->get_int() & 0x1F)))) { - return new RotateLeftNode(in(1)->in(1), - phase->intcon(lshift->get_int() & 0x1F), TypeInt::INT); - } - // val << var_shift | val >> (0/32 - var_shift) => rotate_left val , var_shift - if (rshift->Opcode() == Op_SubI && rshift->in(2) == lshift && - rshift->in(1)->is_Con() && - (rshift->in(1)->get_int() == 0 || rshift->in(1)->get_int() == 32)) { - return new RotateLeftNode(in(1)->in(1), lshift, TypeInt::INT); + Node* lshift = in(1)->in(2); + Node* rshift = in(2)->in(2); + Node* shift = rotate_shift(phase, lshift, rshift, 0x1F); + if (shift != NULL) { + return new RotateLeftNode(in(1)->in(1), shift, TypeInt::INT); } + return NULL; } if (Matcher::match_rule_supported(Op_RotateRight) && lopcode == Op_URShiftI && ropcode == Op_LShiftI && in(1)->in(1) == in(2)->in(1)) { Node *rshift = in(1)->in(2); Node *lshift = in(2)->in(2); - // val >> norm_con_shift | val << (32 - norm_con_shift) => rotate_right val , norm_con_shift - if (rshift->is_Con() && lshift->is_Con() && - ((rshift->get_int() & 0x1F) == (32 - (lshift->get_int() & 0x1F)))) { - return new RotateRightNode(in(1)->in(1), - phase->intcon(rshift->get_int() & 0x1F), TypeInt::INT); - } - // val >> var_shift | val << (0/32 - var_shift) => rotate_right val , var_shift - if (lshift->Opcode() == Op_SubI && lshift->in(2) == rshift && - lshift->in(1)->is_Con() && - (lshift->in(1)->get_int() == 0 || lshift->in(1)->get_int() == 32)) { - return new RotateRightNode(in(1)->in(1), rshift, TypeInt::INT); + Node* shift = rotate_shift(phase, rshift, lshift, 0x1F); + if (shift != NULL) { + return new RotateRightNode(in(1)->in(1), shift, TypeInt::INT); } } return NULL; @@ -824,42 +830,27 @@ Node* OrLNode::Identity(PhaseGVN* phase) { return AddNode::Identity(phase); } -Node *OrLNode::Ideal(PhaseGVN *phase, bool can_reshape) { +Node* OrLNode::Ideal(PhaseGVN* phase, bool can_reshape) { int lopcode = in(1)->Opcode(); int ropcode = in(2)->Opcode(); if (Matcher::match_rule_supported(Op_RotateLeft) && lopcode == Op_LShiftL && ropcode == Op_URShiftL && in(1)->in(1) == in(2)->in(1)) { - Node *lshift = in(1)->in(2); - Node *rshift = in(2)->in(2); - // val << norm_con_shift | val >> (64 - norm_con_shift) => rotate_left val , norm_con_shift - if (lshift->is_Con() && rshift->is_Con() && - ((lshift->get_int() & 0x3F) == (64 - (rshift->get_int() & 0x3F)))) { - return new RotateLeftNode(in(1)->in(1), - phase->intcon(lshift->get_int() & 0x3F), TypeLong::LONG); - } - // val << var_shift | val >> (0/64 - var_shift) => rotate_left val , var_shift - if (rshift->Opcode() == Op_SubI && rshift->in(2) == lshift && - rshift->in(1)->is_Con() && - (rshift->in(1)->get_int() == 0 || rshift->in(1)->get_int() == 64)) { - return new RotateLeftNode(in(1)->in(1), lshift, TypeLong::LONG); - } + Node* lshift = in(1)->in(2); + Node* rshift = in(2)->in(2); + Node* shift = rotate_shift(phase, lshift, rshift, 0x3F); + if (shift != NULL) { + return new RotateLeftNode(in(1)->in(1), shift, TypeLong::LONG); + } + return NULL; } if (Matcher::match_rule_supported(Op_RotateRight) && lopcode == Op_URShiftL && ropcode == Op_LShiftL && in(1)->in(1) == in(2)->in(1)) { - Node *rshift = in(1)->in(2); - Node *lshift = in(2)->in(2); - // val >> norm_con_shift | val << (64 - norm_con_shift) => rotate_right val , norm_con_shift - if (rshift->is_Con() && lshift->is_Con() && - ((rshift->get_int() & 0x3F) == (64 - (lshift->get_int() & 0x3F)))) { - return new RotateRightNode(in(1)->in(1), - phase->intcon(rshift->get_int() & 0x3F), TypeLong::LONG); - } - // val >> var_shift | val << (0/64 - var_shift) => rotate_right val , var_shift - if (lshift->Opcode() == Op_SubI && lshift->in(2) == rshift && - lshift->in(1)->is_Con() && - (lshift->in(1)->get_int() == 0 || lshift->in(1)->get_int() == 64)) { - return new RotateRightNode(in(1)->in(1), rshift, TypeLong::LONG); - } + Node* rshift = in(1)->in(2); + Node* lshift = in(2)->in(2); + Node* shift = rotate_shift(phase, rshift, lshift, 0x3F); + if (shift != NULL) { + return new RotateRightNode(in(1)->in(1), shift, TypeLong::LONG); + } } return NULL; } diff --git a/src/hotspot/share/opto/vectornode.cpp b/src/hotspot/share/opto/vectornode.cpp index d94f3a5329a..b3703e11403 100644 --- a/src/hotspot/share/opto/vectornode.cpp +++ b/src/hotspot/share/opto/vectornode.cpp @@ -835,46 +835,33 @@ MacroLogicVNode* MacroLogicVNode::make(PhaseGVN& gvn, Node* in1, Node* in2, Node Node* VectorNode::degenerate_vector_rotate(Node* src, Node* cnt, bool is_rotate_left, int vlen, BasicType bt, PhaseGVN* phase) { - int shiftLOpc; - int shiftROpc; - Node* shiftLCnt = NULL; - Node* shiftRCnt = NULL; + assert(bt == T_INT || bt == T_LONG, "sanity"); const TypeVect* vt = TypeVect::make(bt, vlen); + int shift_mask = (bt == T_INT) ? 0x1F : 0x3F; + int shiftLOpc = (bt == T_INT) ? Op_LShiftI : Op_LShiftL; + int shiftROpc = (bt == T_INT) ? Op_URShiftI: Op_URShiftL; + // Compute shift values for right rotation and // later swap them in case of left rotation. - if (cnt->is_Con()) { + Node* shiftRCnt = NULL; + Node* shiftLCnt = NULL; + if (cnt->is_Con() && cnt->bottom_type()->isa_int()) { // Constant shift case. - if (bt == T_INT) { - int shift = cnt->get_int() & 31; - shiftRCnt = phase->intcon(shift); - shiftLCnt = phase->intcon(32 - shift); - shiftLOpc = Op_LShiftI; - shiftROpc = Op_URShiftI; - } else { - int shift = cnt->get_int() & 63; - shiftRCnt = phase->intcon(shift); - shiftLCnt = phase->intcon(64 - shift); - shiftLOpc = Op_LShiftL; - shiftROpc = Op_URShiftL; - } + int shift = cnt->get_int() & shift_mask; + shiftRCnt = phase->intcon(shift); + shiftLCnt = phase->intcon(shift_mask + 1 - shift); } else { // Variable shift case. assert(VectorNode::is_invariant_vector(cnt), "Broadcast expected"); cnt = cnt->in(1); - if (bt == T_INT) { - shiftRCnt = phase->transform(new AndINode(cnt, phase->intcon(31))); - shiftLCnt = phase->transform(new SubINode(phase->intcon(32), shiftRCnt)); - shiftLOpc = Op_LShiftI; - shiftROpc = Op_URShiftI; - } else { + if (bt == T_LONG) { + // Shift count vector for Rotate vector has long elements too. assert(cnt->Opcode() == Op_ConvI2L, "ConvI2L expected"); cnt = cnt->in(1); - shiftRCnt = phase->transform(new AndINode(cnt, phase->intcon(63))); - shiftLCnt = phase->transform(new SubINode(phase->intcon(64), shiftRCnt)); - shiftLOpc = Op_LShiftL; - shiftROpc = Op_URShiftL; } + shiftRCnt = phase->transform(new AndINode(cnt, phase->intcon(shift_mask))); + shiftLCnt = phase->transform(new SubINode(phase->intcon(shift_mask + 1), shiftRCnt)); } // Swap the computed left and right shift counts. @@ -908,86 +895,3 @@ Node* RotateRightVNode::Ideal(PhaseGVN* phase, bool can_reshape) { return NULL; } -Node* OrVNode::Ideal(PhaseGVN* phase, bool can_reshape) { - int lopcode = in(1)->Opcode(); - int ropcode = in(2)->Opcode(); - const TypeVect* vt = bottom_type()->is_vect(); - int vec_len = vt->length(); - BasicType bt = vt->element_basic_type(); - - // Vector Rotate operations inferencing, this will be useful when vector - // operations are created via non-SLP route i.e. (VectorAPI). - if (Matcher::match_rule_supported_vector(Op_RotateLeftV, vec_len, bt) && - ((ropcode == Op_LShiftVI && lopcode == Op_URShiftVI) || - (ropcode == Op_LShiftVL && lopcode == Op_URShiftVL)) && - in(1)->in(1) == in(2)->in(1)) { - assert(Op_RShiftCntV == in(1)->in(2)->Opcode(), "LShiftCntV operand expected"); - assert(Op_LShiftCntV == in(2)->in(2)->Opcode(), "RShiftCntV operand expected"); - Node* lshift = in(1)->in(2)->in(1); - Node* rshift = in(2)->in(2)->in(1); - int mod_val = bt == T_LONG ? 64 : 32; - int shift_mask = bt == T_LONG ? 0x3F : 0x1F; - // val >> norm_con_shift | val << (32 - norm_con_shift) => rotate_right val , - // norm_con_shift - if (lshift->is_Con() && rshift->is_Con() && - ((lshift->get_int() & shift_mask) == - (mod_val - (rshift->get_int() & shift_mask)))) { - return new RotateRightVNode( - in(1)->in(1), phase->intcon(lshift->get_int() & shift_mask), vt); - } - if (lshift->Opcode() == Op_AndI && rshift->Opcode() == Op_AndI && - lshift->in(2)->is_Con() && rshift->in(2)->is_Con() && - lshift->in(2)->get_int() == (mod_val - 1) && - rshift->in(2)->get_int() == (mod_val - 1)) { - lshift = lshift->in(1); - rshift = rshift->in(1); - // val << var_shift | val >> (0/32 - var_shift) => rotate_left val , - // var_shift - if (lshift->Opcode() == Op_SubI && lshift->in(2) == rshift && - lshift->in(1)->is_Con() && - (lshift->in(1)->get_int() == 0 || - lshift->in(1)->get_int() == mod_val)) { - Node* rotate_cnt = phase->transform(new ReplicateINode(rshift, vt)); - return new RotateLeftVNode(in(1)->in(1), rotate_cnt, vt); - } - } - } - - if (Matcher::match_rule_supported_vector(Op_RotateRightV, vec_len, bt) && - ((ropcode == Op_URShiftVI && lopcode == Op_LShiftVI) || - (ropcode == Op_URShiftVL && lopcode == Op_LShiftVL)) && - in(1)->in(1) == in(2)->in(1)) { - assert(Op_LShiftCntV == in(1)->in(2)->Opcode(), "RShiftCntV operand expected"); - assert(Op_RShiftCntV == in(2)->in(2)->Opcode(), "LShiftCntV operand expected"); - Node* rshift = in(1)->in(2)->in(1); - Node* lshift = in(2)->in(2)->in(1); - int mod_val = bt == T_LONG ? 64 : 32; - int shift_mask = bt == T_LONG ? 0x3F : 0x1F; - // val << norm_con_shift | val >> (32 - norm_con_shift) => rotate_left val - // , norm_con_shift - if (rshift->is_Con() && lshift->is_Con() && - ((rshift->get_int() & shift_mask) == - (mod_val - (lshift->get_int() & shift_mask)))) { - return new RotateLeftVNode( - in(1)->in(1), phase->intcon(rshift->get_int() & shift_mask), vt); - } - if (lshift->Opcode() == Op_AndI && rshift->Opcode() == Op_AndI && - lshift->in(2)->is_Con() && rshift->in(2)->is_Con() && - rshift->in(2)->get_int() == (mod_val - 1) && - lshift->in(2)->get_int() == (mod_val - 1)) { - rshift = rshift->in(1); - lshift = lshift->in(1); - // val >> var_shift | val << (0/32 - var_shift) => rotate_right val , - // var_shift - if (rshift->Opcode() == Op_SubI && rshift->in(2) == lshift && - rshift->in(1)->is_Con() && - (rshift->in(1)->get_int() == 0 || - rshift->in(1)->get_int() == mod_val)) { - Node* rotate_cnt = phase->transform(new ReplicateINode(lshift, vt)); - return new RotateRightVNode(in(1)->in(1), rotate_cnt, vt); - } - } - } - return NULL; -} - diff --git a/src/hotspot/share/opto/vectornode.hpp b/src/hotspot/share/opto/vectornode.hpp index 570f0645a01..719070f8ed2 100644 --- a/src/hotspot/share/opto/vectornode.hpp +++ b/src/hotspot/share/opto/vectornode.hpp @@ -624,7 +624,6 @@ class OrVNode : public VectorNode { public: OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} virtual int Opcode() const; - Node* Ideal(PhaseGVN* phase, bool can_reshape); }; //------------------------------XorVNode--------------------------------------- diff --git a/test/hotspot/jtreg/compiler/c2/cr6340864/TestIntVect.java b/test/hotspot/jtreg/compiler/c2/cr6340864/TestIntVect.java index 1c7129392b7..2ba6a29a3d1 100644 --- a/test/hotspot/jtreg/compiler/c2/cr6340864/TestIntVect.java +++ b/test/hotspot/jtreg/compiler/c2/cr6340864/TestIntVect.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,8 +42,6 @@ public class TestIntVect { private static final int BIT_MASK = 0xEC80F731; private static final int VALUE = 15; private static final int SHIFT = 32; - private static final int SHIFT_LT_IMM8 = -128; - private static final int SHIFT_GT_IMM8 = 128; public static void main(String args[]) { System.out.println("Testing Integer vectors"); @@ -151,13 +149,6 @@ public class TestIntVect { test_srac_and(a0, a1); test_srav_and(a0, a1, BIT_MASK); - test1_ror(a0, a1); - test1_rol(a0, a1); - test2_ror(a0, a1); - test2_rol(a0, a1); - test3_ror(a0, a1, SHIFT); - test3_rol(a0, a1, SHIFT); - test_pack2(p2, a1); test_unpack2(a0, p2); test_pack2_swap(p2, a1); @@ -385,30 +376,6 @@ public class TestIntVect { for (int i=0; i>SHIFT)); } - test1_ror(a0, a1); - for (int i=0; i>>SHIFT_GT_IMM8) | (int)(ADD_INIT+i)<<-SHIFT_GT_IMM8)); - } - test1_rol(a0, a1); - for (int i=0; i>>-SHIFT_GT_IMM8)); - } - test2_ror(a0, a1); - for (int i=0; i>>SHIFT_LT_IMM8) | (int)(ADD_INIT+i)<<-SHIFT_LT_IMM8)); - } - test2_rol(a0, a1); - for (int i=0; i>>-SHIFT_LT_IMM8)); - } - test3_rol(a0, a1, SHIFT); - for (int i=0; i>>-SHIFT)); - } - test3_ror(a0, a1, SHIFT); - for (int i=0; i>>SHIFT) | (int)(ADD_INIT+i)<<-SHIFT)); - } test_sllc_on(a0, a1); for (int i=0; i 0) { + System.err.println("FAILED: " + errn + " errors"); + System.exit(97); + } + times(); + System.out.println("PASSED"); + } + + static int[] a0 = new int[ARRLEN]; + static int[] a1 = new int[ARRLEN]; + + static void test() { + // Initialize + for (int i=0; i>>SHIFT_GT_IMM8) | (int)(ADD_INIT+i)<<-SHIFT_GT_IMM8)); + } + test1_rol(a0, a1); + for (int i=0; i>>-SHIFT_GT_IMM8)); + } + test2_ror(a0, a1); + for (int i=0; i>>SHIFT_LT_IMM8) | (int)(ADD_INIT+i)<<-SHIFT_LT_IMM8)); + } + test2_rol(a0, a1); + for (int i=0; i>>-SHIFT_LT_IMM8)); + } + test3_rol(a0, a1, SHIFT); + for (int i=0; i>>-SHIFT)); + } + test3_ror(a0, a1, SHIFT); + for (int i=0; i>>SHIFT) | (int)(ADD_INIT+i)<<-SHIFT)); + } + + test_rolc(a0, a1); + for (int i=0; i>>(-VALUE))); + } + test_rolv(a0, a1, VALUE); + for (int i=0; i>>(-VALUE))); + } + + test_rorc(a0, a1); + for (int i=0; i>>VALUE) | (int)(ADD_INIT+i)<<(-VALUE))); + } + test_rorv(a0, a1, VALUE); + for (int i=0; i>>VALUE) | (int)(ADD_INIT+i)<<(-VALUE))); + } + + test_rolc_n(a0, a1); + for (int i=0; i>>VALUE)); + } + test_rolv(a0, a1, -VALUE); + for (int i=0; i>>VALUE)); + } + + test_rorc_n(a0, a1); + for (int i=0; i>>(-VALUE)) | (int)(ADD_INIT+i)<>>(-VALUE)) | (int)(ADD_INIT+i)<>>(-SHIFT))); + } + test_rolv(a0, a1, SHIFT); + for (int i=0; i>>(-SHIFT))); + } + + test_rorc_o(a0, a1); + for (int i=0; i>>SHIFT) | (int)(ADD_INIT+i)<<(-SHIFT))); + } + test_rorv(a0, a1, SHIFT); + for (int i=0; i>>SHIFT) | (int)(ADD_INIT+i)<<(-SHIFT))); + } + + test_rolc_on(a0, a1); + for (int i=0; i>>SHIFT)); + } + test_rolv(a0, a1, -SHIFT); + for (int i=0; i>>SHIFT)); + } + + test_rorc_on(a0, a1); + for (int i=0; i>>(-SHIFT)) | (int)(ADD_INIT+i)<>>(-SHIFT)) | (int)(ADD_INIT+i)<>VALUE)); } - test1_ror(a0, a1); - for (int i=0; i>>SHIFT_GT_IMM8) | (long)(ADD_INIT+i)<<-SHIFT_GT_IMM8)); - } - test1_rol(a0, a1); - for (int i=0; i>>-SHIFT_GT_IMM8)); - } - test2_ror(a0, a1); - for (int i=0; i>>SHIFT_LT_IMM8) | (long)(ADD_INIT+i)<<-SHIFT_LT_IMM8)); - } - test2_rol(a0, a1); - for (int i=0; i>>-SHIFT_LT_IMM8)); - } - test3_rol(a0, a1, SHIFT); - for (int i=0; i>>-SHIFT)); - } - test3_ror(a0, a1, SHIFT); - for (int i=0; i>>SHIFT) | (long)(ADD_INIT+i)<<-SHIFT)); - } } if (errn > 0) @@ -886,48 +853,6 @@ public class TestLongVect { end = System.currentTimeMillis(); System.out.println("test_srav_and: " + (end - start)); - start = System.currentTimeMillis(); - for (int i=0; i>VALUE); } } - static void test1_rol(long[] a0, long[] a1) { - for (int i = 0; i < a0.length; i+=1) { - a0[i] = (long)(Long.rotateLeft(a1[i], SHIFT_GT_IMM8)); - } - } - static void test1_ror(long[] a0, long[] a1) { - for (int i = 0; i < a0.length; i+=1) { - a0[i] = (long)(Long.rotateRight(a1[i], SHIFT_GT_IMM8)); - } - } - static void test2_rol(long[] a0, long[] a1) { - for (int i = 0; i < a0.length; i+=1) { - a0[i] = (long)(Long.rotateLeft(a1[i], SHIFT_LT_IMM8)); - } - } - static void test2_ror(long[] a0, long[] a1) { - for (int i = 0; i < a0.length; i+=1) { - a0[i] = (long)(Long.rotateRight(a1[i], SHIFT_LT_IMM8)); - } - } - static void test3_rol(long[] a0, long[] a1, int shift) { - for (int i = 0; i < a0.length; i+=1) { - a0[i] = (long)(Long.rotateLeft(a1[i], shift)); - } - } - static void test3_ror(long[] a0, long[] a1, int shift) { - for (int i = 0; i < a0.length; i+=1) { - a0[i] = (long)(Long.rotateRight(a1[i], shift)); - } - } static int verify(String text, int i, long elem, long val) { if (elem != val) { diff --git a/test/hotspot/jtreg/compiler/c2/cr6340864/TestLongVectRotate.java b/test/hotspot/jtreg/compiler/c2/cr6340864/TestLongVectRotate.java new file mode 100644 index 00000000000..d926df12545 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/cr6340864/TestLongVectRotate.java @@ -0,0 +1,467 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8248830 + * @summary Implement Rotate vectorization optimizations in hotspot-server + * + * @run main/othervm/timeout=400 -Xbatch -Xmx128m compiler.c2.cr6340864.TestLongVectRotate + * @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=8 compiler.c2.cr6340864.TestLongVectRotate + * @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=16 compiler.c2.cr6340864.TestLongVectRotate + * @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:MaxVectorSize=32 compiler.c2.cr6340864.TestLongVectRotate + * @run main/othervm/timeout=400 -Xbatch -Xmx128m -XX:+IgnoreUnrecognizedVMOptions -XX:UseAVX=3 compiler.c2.cr6340864.TestLongVectRotate + */ + +package compiler.c2.cr6340864; + +public class TestLongVectRotate { + private static final int ARRLEN = 997; + private static final int ITERS = 11000; + private static final long ADD_INIT = Long.MAX_VALUE-500; + private static final int VALUE = 31; + private static final int SHIFT = 64; + private static final int SHIFT_LT_IMM8 = -128; + private static final int SHIFT_GT_IMM8 = 128; + + public static void main(String args[]) { + System.out.println("Testing Long Rotate vectors"); + test(); + int errn = verify(); + if (errn > 0) { + System.err.println("FAILED: " + errn + " errors"); + System.exit(97); + } + times(); + System.out.println("PASSED"); + } + + static long[] a0 = new long[ARRLEN]; + static long[] a1 = new long[ARRLEN]; + + static void test() { + // Initialize + for (int i=0; i>>SHIFT_GT_IMM8) | (long)(ADD_INIT+i)<<-SHIFT_GT_IMM8)); + } + test1_rol(a0, a1); + for (int i=0; i>>-SHIFT_GT_IMM8)); + } + test2_ror(a0, a1); + for (int i=0; i>>SHIFT_LT_IMM8) | (long)(ADD_INIT+i)<<-SHIFT_LT_IMM8)); + } + test2_rol(a0, a1); + for (int i=0; i>>-SHIFT_LT_IMM8)); + } + test3_rol(a0, a1, SHIFT); + for (int i=0; i>>-SHIFT)); + } + test3_ror(a0, a1, SHIFT); + for (int i=0; i>>SHIFT) | (long)(ADD_INIT+i)<<-SHIFT)); + } + + test_rolc(a0, a1); + for (int i=0; i>>(-VALUE))); + } + test_rolv(a0, a1, VALUE); + for (int i=0; i>>(-VALUE))); + } + + test_rorc(a0, a1); + for (int i=0; i>>VALUE) | (long)(ADD_INIT+i)<<(-VALUE))); + } + test_rorv(a0, a1, VALUE); + for (int i=0; i>>VALUE) | (long)(ADD_INIT+i)<<(-VALUE))); + } + + test_rolc_n(a0, a1); + for (int i=0; i>>VALUE)); + } + test_rolv(a0, a1, -VALUE); + for (int i=0; i>>VALUE)); + } + + test_rorc_n(a0, a1); + for (int i=0; i>>(-VALUE)) | (long)(ADD_INIT+i)<>>(-VALUE)) | (long)(ADD_INIT+i)<>>(-SHIFT))); + } + test_rolv(a0, a1, SHIFT); + for (int i=0; i>>(-SHIFT))); + } + + test_rorc_o(a0, a1); + for (int i=0; i>>SHIFT) | (long)(ADD_INIT+i)<<(-SHIFT))); + } + test_rorv(a0, a1, SHIFT); + for (int i=0; i>>SHIFT) | (long)(ADD_INIT+i)<<(-SHIFT))); + } + + test_rolc_on(a0, a1); + for (int i=0; i>>SHIFT)); + } + test_rolv(a0, a1, -SHIFT); + for (int i=0; i>>SHIFT)); + } + + test_rorc_on(a0, a1); + for (int i=0; i>>(-SHIFT)) | (long)(ADD_INIT+i)<>>(-SHIFT)) | (long)(ADD_INIT+i)<