Skip to content

Commit 392fcc9

Browse files
author
Jatin Bhateja
committed
8271589: fatal error with variable shift count integer rotate operation.
Reviewed-by: kvn, sviswanathan
1 parent 9f1edaf commit 392fcc9

File tree

3 files changed

+101
-12
lines changed

3 files changed

+101
-12
lines changed

src/hotspot/share/opto/superword.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2488,7 +2488,6 @@ void SuperWord::output() {
24882488
} else if (VectorNode::is_scalar_rotate(n)) {
24892489
Node* in1 = low_adr->in(1);
24902490
Node* in2 = p->at(0)->in(2);
2491-
assert(in2->bottom_type()->isa_int(), "Shift must always be an int value");
24922491
// If rotation count is non-constant or greater than 8bit value create a vector.
24932492
if (!in2->is_Con() || -0x80 > in2->get_int() || in2->get_int() >= 0x80) {
24942493
in2 = vector_opd(p, 2);

src/hotspot/share/opto/vectornode.cpp

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "opto/mulnode.hpp"
2828
#include "opto/subnode.hpp"
2929
#include "opto/vectornode.hpp"
30+
#include "opto/convertnode.hpp"
3031
#include "utilities/powerOfTwo.hpp"
3132
#include "utilities/globalDefinitions.hpp"
3233

@@ -311,6 +312,14 @@ bool VectorNode::is_vector_rotate_supported(int vopc, uint vlen, BasicType bt) {
311312
return true;
312313
}
313314

315+
// If target does not support variable shift operations then no point
316+
// in creating a rotate vector node since it will not be disintegratable.
317+
// Adding a pessimistic check to avoid complex pattern mathing which
318+
// may not be full proof.
319+
if (!Matcher::supports_vector_variable_shifts()) {
320+
return false;
321+
}
322+
314323
// Validate existence of nodes created in case of rotate degeneration.
315324
switch (bt) {
316325
case T_INT:
@@ -1142,31 +1151,61 @@ Node* VectorNode::degenerate_vector_rotate(Node* src, Node* cnt, bool is_rotate_
11421151
// later swap them in case of left rotation.
11431152
Node* shiftRCnt = NULL;
11441153
Node* shiftLCnt = NULL;
1145-
if (cnt->is_Con() && cnt->bottom_type()->isa_int()) {
1146-
// Constant shift case.
1147-
int shift = cnt->get_int() & shift_mask;
1154+
const TypeInt* cnt_type = cnt->bottom_type()->isa_int();
1155+
bool is_binary_vector_op = false;
1156+
if (cnt_type && cnt_type->is_con()) {
1157+
// Constant shift.
1158+
int shift = cnt_type->get_con() & shift_mask;
11481159
shiftRCnt = phase->intcon(shift);
11491160
shiftLCnt = phase->intcon(shift_mask + 1 - shift);
1150-
} else {
1151-
// Variable shift case.
1152-
assert(VectorNode::is_invariant_vector(cnt), "Broadcast expected");
1161+
} else if (VectorNode::is_invariant_vector(cnt)) {
1162+
// Scalar variable shift, handle replicates generated by auto vectorizer.
11531163
cnt = cnt->in(1);
11541164
if (bt == T_LONG) {
11551165
// Shift count vector for Rotate vector has long elements too.
1156-
assert(cnt->Opcode() == Op_ConvI2L, "ConvI2L expected");
1157-
cnt = cnt->in(1);
1166+
if (cnt->Opcode() == Op_ConvI2L) {
1167+
cnt = cnt->in(1);
1168+
} else {
1169+
assert(cnt->bottom_type()->isa_long() &&
1170+
cnt->bottom_type()->is_long()->is_con(), "Long constant expected");
1171+
cnt = phase->transform(new ConvL2INode(cnt));
1172+
}
11581173
}
11591174
shiftRCnt = phase->transform(new AndINode(cnt, phase->intcon(shift_mask)));
11601175
shiftLCnt = phase->transform(new SubINode(phase->intcon(shift_mask + 1), shiftRCnt));
1176+
} else {
1177+
// Vector variable shift.
1178+
assert(Matcher::supports_vector_variable_shifts(), "");
1179+
assert(bt == T_INT, "Variable vector case supported for integer type rotation");
1180+
1181+
assert(cnt->bottom_type()->isa_vect(), "Unexpected shift");
1182+
const Type* elem_ty = Type::get_const_basic_type(bt);
1183+
1184+
Node* shift_mask_node = phase->intcon(shift_mask);
1185+
Node* const_one_node = phase->intcon(1);
1186+
1187+
int subVopc = VectorNode::opcode(Op_SubI, bt);
1188+
int addVopc = VectorNode::opcode(Op_AddI, bt);
1189+
1190+
Node* vector_mask = phase->transform(VectorNode::scalar2vector(shift_mask_node, vlen, elem_ty));
1191+
Node* vector_one = phase->transform(VectorNode::scalar2vector(const_one_node, vlen, elem_ty));
1192+
1193+
shiftRCnt = cnt;
1194+
shiftRCnt = phase->transform(VectorNode::make(Op_AndV, shiftRCnt, vector_mask, vt));
1195+
vector_mask = phase->transform(VectorNode::make(addVopc, vector_one, vector_mask, vt));
1196+
shiftLCnt = phase->transform(VectorNode::make(subVopc, vector_mask, shiftRCnt, vt));
1197+
is_binary_vector_op = true;
11611198
}
11621199

11631200
// Swap the computed left and right shift counts.
11641201
if (is_rotate_left) {
11651202
swap(shiftRCnt,shiftLCnt);
11661203
}
11671204

1168-
shiftLCnt = phase->transform(new LShiftCntVNode(shiftLCnt, vt));
1169-
shiftRCnt = phase->transform(new RShiftCntVNode(shiftRCnt, vt));
1205+
if (!is_binary_vector_op) {
1206+
shiftLCnt = phase->transform(new LShiftCntVNode(shiftLCnt, vt));
1207+
shiftRCnt = phase->transform(new RShiftCntVNode(shiftRCnt, vt));
1208+
}
11701209

11711210
return new OrVNode(phase->transform(VectorNode::make(shiftLOpc, src, shiftLCnt, vlen, bt)),
11721211
phase->transform(VectorNode::make(shiftROpc, src, shiftRCnt, vlen, bt)),

test/hotspot/jtreg/compiler/c2/cr6340864/TestIntVectRotate.java

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,23 @@
3737

3838
public class TestIntVectRotate {
3939
private static final int ARRLEN = 997;
40+
private static final int REPCOUNT = 16;
4041
private static final int ITERS = 11000;
4142
private static final int ADD_INIT = Integer.MAX_VALUE-500;
4243
private static final int VALUE = 15;
4344
private static final int SHIFT = 32;
4445
private static final int SHIFT_LT_IMM8 = -128;
4546
private static final int SHIFT_GT_IMM8 = 128;
4647

48+
private static final int [] rolRes = {
49+
15, 32, 68, 144, 304, 640, 1344, 2816, 5888, 12288, 25600, 53248, 110592, 229376, 475136, 983040
50+
};
51+
52+
private static final int [] rorRes = {
53+
15, 8, 1073741828, 1073741826, 805306369, -1610612736, 1409286144, 738197504, 385875968, 201326592,
54+
104857600, 54525952, 28311552, 14680064, 7602176, 3932160
55+
};
56+
4757
public static void main(String args[]) {
4858
System.out.println("Testing Integer Rotate vectors");
4959
test();
@@ -58,12 +68,16 @@ public static void main(String args[]) {
5868

5969
static int[] a0 = new int[ARRLEN];
6070
static int[] a1 = new int[ARRLEN];
71+
static int[] a2 = new int[ARRLEN];
72+
static int[] a3 = new int[ARRLEN];
6173

6274
static void test() {
6375
// Initialize
6476
for (int i=0; i<ARRLEN; i++) {
6577
int val = (int)(ADD_INIT+i);
6678
a1[i] = val;
79+
a2[i] = (i & (REPCOUNT-1)) + VALUE;
80+
a3[i] = i & (REPCOUNT-1);
6781
}
6882
System.out.println("Warmup");
6983
for (int i=0; i<ITERS; i++) {
@@ -93,6 +107,9 @@ static void test() {
93107
test_rolv(a0, a1, -SHIFT);
94108
test_rorc_on(a0, a1);
95109
test_rorv(a0, a1, -SHIFT);
110+
111+
test_rolv_vec(a0, a2, a3);
112+
test_rorv_vec(a0, a2, a3);
96113
}
97114
}
98115

@@ -188,7 +205,14 @@ static int verify() {
188205
for (int i=0; i<ARRLEN; i++) {
189206
errn += verify("test_rolv_on: ", i, a0[i], (int)(((int)(ADD_INIT+i)<<(-SHIFT)) | (int)(ADD_INIT+i)>>>SHIFT));
190207
}
191-
208+
test_rolv_vec(a0, a2, a3);
209+
for (int i=0; i<ARRLEN; i++) {
210+
errn += verify("test_rolv_vec: ", i, a0[i], rolRes[i & (REPCOUNT-1)]);
211+
}
212+
test_rorv_vec(a0, a2, a3);
213+
for (int i=0; i<ARRLEN; i++) {
214+
errn += verify("test_rorv_vec: ", i, a0[i], rorRes[i & (REPCOUNT-1)]);
215+
}
192216
test_rorc_on(a0, a1);
193217
for (int i=0; i<ARRLEN; i++) {
194218
errn += verify("test_rorc_on: ", i, a0[i], (int)(((int)(ADD_INIT+i)>>>(-SHIFT)) | (int)(ADD_INIT+i)<<SHIFT));
@@ -358,6 +382,20 @@ static void times() {
358382
}
359383
end = System.currentTimeMillis();
360384
System.out.println("test_rorv_on: " + (end - start));
385+
386+
start = System.currentTimeMillis();
387+
for (int i=0; i<ITERS; i++) {
388+
test_rorv_vec(a0, a2, a3);
389+
}
390+
end = System.currentTimeMillis();
391+
System.out.println("test_rorv_vec: " + (end - start));
392+
393+
start = System.currentTimeMillis();
394+
for (int i=0; i<ITERS; i++) {
395+
test_rolv_vec(a0, a2, a3);
396+
}
397+
end = System.currentTimeMillis();
398+
System.out.println("test_rolv_vec: " + (end - start));
361399
}
362400

363401
static void test_rolc(int[] a0, int[] a1) {
@@ -384,6 +422,19 @@ static void test_rolc_on(int[] a0, int[] a1) {
384422
}
385423
}
386424

425+
static void test_rolv_vec(int[] a0, int[] a1, int [] a2) {
426+
for (int i = 0; i < a0.length; i+=1) {
427+
a0[i] = (int)(Integer.rotateLeft(a1[i], a2[i]));
428+
}
429+
}
430+
431+
static void test_rorv_vec(int[] a0, int[] a1, int [] a2) {
432+
for (int i = 0; i < a0.length; i+=1) {
433+
a0[i] = (int)(Integer.rotateRight(a1[i], a2[i]));
434+
}
435+
}
436+
437+
387438
static void test_rolv(int[] a0, int[] a1, int shift) {
388439
for (int i = 0; i < a0.length; i+=1) {
389440
a0[i] = (int)(Integer.rotateLeft(a1[i], shift));

0 commit comments

Comments
 (0)