8249749: modify a primitive array through a stream and a for cycle causes jre crash
Check align_to_ref for NULL early and bailout SuperWord optimization. Reviewed-by: vlivanov, thartmann
This commit is contained in:
parent
6cfe3fea08
commit
092389e3c9
src/hotspot/share/opto
test/hotspot/jtreg/compiler/vectorization
@ -499,6 +499,10 @@ void SuperWord::SLP_extract() {
|
||||
|
||||
find_adjacent_refs();
|
||||
|
||||
if (align_to_ref() == NULL) {
|
||||
return; // Did not find memory reference to align vectors
|
||||
}
|
||||
|
||||
extend_packlist();
|
||||
|
||||
if (_do_vector_loop) {
|
||||
@ -575,6 +579,9 @@ void SuperWord::find_adjacent_refs() {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (TraceSuperWord) {
|
||||
tty->print_cr("\nfind_adjacent_refs found %d memops", memops.size());
|
||||
}
|
||||
|
||||
Node_List align_to_refs;
|
||||
int max_idx;
|
||||
@ -3229,15 +3236,15 @@ void SuperWord::compute_vector_element_type() {
|
||||
//------------------------------memory_alignment---------------------------
|
||||
// Alignment within a vector memory reference
|
||||
int SuperWord::memory_alignment(MemNode* s, int iv_adjust) {
|
||||
#ifndef PRODUCT
|
||||
if(TraceSuperWord && Verbose) {
|
||||
tty->print("SuperWord::memory_alignment within a vector memory reference for %d: ", s->_idx); s->dump();
|
||||
}
|
||||
#endif
|
||||
#ifndef PRODUCT
|
||||
if ((TraceSuperWord && Verbose) || is_trace_alignment()) {
|
||||
tty->print("SuperWord::memory_alignment within a vector memory reference for %d: ", s->_idx); s->dump();
|
||||
}
|
||||
#endif
|
||||
NOT_PRODUCT(SWPointer::Tracer::Depth ddd(0);)
|
||||
SWPointer p(s, this, NULL, false);
|
||||
if (!p.valid()) {
|
||||
NOT_PRODUCT(if(is_trace_alignment()) tty->print("SWPointer::memory_alignment: SWPointer p invalid, return bottom_align");)
|
||||
NOT_PRODUCT(if(is_trace_alignment()) tty->print_cr("SWPointer::memory_alignment: SWPointer p invalid, return bottom_align");)
|
||||
return bottom_align;
|
||||
}
|
||||
int vw = get_vw_bytes_special(s);
|
||||
@ -3249,9 +3256,11 @@ int SuperWord::memory_alignment(MemNode* s, int iv_adjust) {
|
||||
offset += iv_adjust*p.memory_size();
|
||||
int off_rem = offset % vw;
|
||||
int off_mod = off_rem >= 0 ? off_rem : off_rem + vw;
|
||||
if (TraceSuperWord && Verbose) {
|
||||
#ifndef PRODUCT
|
||||
if ((TraceSuperWord && Verbose) || is_trace_alignment()) {
|
||||
tty->print_cr("SWPointer::memory_alignment: off_rem = %d, off_mod = %d", off_rem, off_mod);
|
||||
}
|
||||
#endif
|
||||
return off_mod;
|
||||
}
|
||||
|
||||
@ -3766,6 +3775,7 @@ bool SWPointer::invariant(Node* n) {
|
||||
NOT_PRODUCT(_tracer.invariant_1(n, n_c);)
|
||||
return !lpt()->is_member(phase()->get_loop(n_c));
|
||||
}
|
||||
|
||||
//------------------------scaled_iv_plus_offset--------------------
|
||||
// Match: k*iv + offset
|
||||
// where: k is a constant that maybe zero, and
|
||||
@ -3786,20 +3796,20 @@ bool SWPointer::scaled_iv_plus_offset(Node* n) {
|
||||
|
||||
int opc = n->Opcode();
|
||||
if (opc == Op_AddI) {
|
||||
if (scaled_iv(n->in(1)) && offset_plus_k(n->in(2))) {
|
||||
if (offset_plus_k(n->in(2)) && scaled_iv_plus_offset(n->in(1))) {
|
||||
NOT_PRODUCT(_tracer.scaled_iv_plus_offset_4(n);)
|
||||
return true;
|
||||
}
|
||||
if (scaled_iv(n->in(2)) && offset_plus_k(n->in(1))) {
|
||||
if (offset_plus_k(n->in(1)) && scaled_iv_plus_offset(n->in(2))) {
|
||||
NOT_PRODUCT(_tracer.scaled_iv_plus_offset_5(n);)
|
||||
return true;
|
||||
}
|
||||
} else if (opc == Op_SubI) {
|
||||
if (scaled_iv(n->in(1)) && offset_plus_k(n->in(2), true)) {
|
||||
if (offset_plus_k(n->in(2), true) && scaled_iv_plus_offset(n->in(1))) {
|
||||
NOT_PRODUCT(_tracer.scaled_iv_plus_offset_6(n);)
|
||||
return true;
|
||||
}
|
||||
if (scaled_iv(n->in(2)) && offset_plus_k(n->in(1))) {
|
||||
if (offset_plus_k(n->in(1)) && scaled_iv_plus_offset(n->in(2))) {
|
||||
_scale *= -1;
|
||||
NOT_PRODUCT(_tracer.scaled_iv_plus_offset_7(n);)
|
||||
return true;
|
||||
@ -3871,6 +3881,7 @@ bool SWPointer::scaled_iv(Node* n) {
|
||||
int mult = 1 << n->in(2)->get_int();
|
||||
_scale = tmp._scale * mult;
|
||||
_offset += tmp._offset * mult;
|
||||
_invar = tmp._invar;
|
||||
NOT_PRODUCT(_tracer.scaled_iv_9(n, _scale, _offset, mult);)
|
||||
return true;
|
||||
}
|
||||
|
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* 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 8249749
|
||||
* @summary Test vectorization for complex address expressions
|
||||
* @requires vm.compMode != "Xint"
|
||||
* @run main compiler.vectorization.TestComplexAddrExpr test1
|
||||
* @run main compiler.vectorization.TestComplexAddrExpr test2
|
||||
* @run main compiler.vectorization.TestComplexAddrExpr test3
|
||||
* @run main compiler.vectorization.TestComplexAddrExpr test4
|
||||
* @run main compiler.vectorization.TestComplexAddrExpr test5
|
||||
* @run main compiler.vectorization.TestComplexAddrExpr test6
|
||||
*/
|
||||
|
||||
package compiler.vectorization;
|
||||
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class TestComplexAddrExpr {
|
||||
|
||||
static final int n = 1024;
|
||||
|
||||
static void test1(int[] data) {
|
||||
IntStream.range(0, n).forEach(j -> {
|
||||
for (int i = 0; i < n; i++) {
|
||||
data[j * n + i]++;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void test2(int[] data) {
|
||||
IntStream.range(0, n).forEach(j -> {
|
||||
for (int i = n - 1; i >= 0; i--) {
|
||||
data[j * n + i]--;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void test3(int[] data) {
|
||||
IntStream.range(0, n).forEach(j -> {
|
||||
for (int i = 1 - n; i < 1; i++) {
|
||||
data[j * n - i]++;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void test4(int[] data) {
|
||||
IntStream.range(0, n).forEach(j -> {
|
||||
for (int i = 0; i >= 1 - n; i--) {
|
||||
data[j * n - i]--;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void test5(int[] data) {
|
||||
IntStream.range(0, n).forEach(j -> {
|
||||
for (int i = 0; i < n/2; i++) {
|
||||
data[j * n + (i << 1)]++;
|
||||
}
|
||||
for (int i = 0; i < n/2; i++) {
|
||||
data[j * n + i * 2 + 1]++;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void test6(int[] data) {
|
||||
IntStream.range(0, n).forEach(j -> {
|
||||
for (int i = (n - 1)/2; i >= 0; i--) {
|
||||
data[j * n + (i << 1)]--;
|
||||
}
|
||||
for (int i = (n - 1)/2; i >= 0; i--) {
|
||||
data[j * n + i * 2 + 1]--;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void verify(int[] data, int k) {
|
||||
for (int i = 0; i < n * n; i++) {
|
||||
if (data[i] != k) {
|
||||
throw new RuntimeException(" Invalid result: data[" + i + "]: " + data[i] + " != " + k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// int n = 1024;
|
||||
int[] data = new int[n * n];
|
||||
|
||||
if (args.length == 0) {
|
||||
throw new RuntimeException(" Missing test name: test1, test2, test3, test4, test5, test6");
|
||||
}
|
||||
|
||||
if (args[0].equals("test1")) {
|
||||
System.out.println(" Run test1 ...");
|
||||
for (int k = 0; k < n; k++) {
|
||||
test1(data);
|
||||
}
|
||||
verify(data, n);
|
||||
System.out.println(" Finished test1.");
|
||||
}
|
||||
|
||||
if (args[0].equals("test2")) {
|
||||
System.out.println(" Run test2 ...");
|
||||
for (int k = 0; k < n; k++) {
|
||||
test2(data);
|
||||
}
|
||||
verify(data, -n);
|
||||
System.out.println(" Finished test2.");
|
||||
}
|
||||
|
||||
if (args[0].equals("test3")) {
|
||||
System.out.println(" Run test3 ...");
|
||||
for (int k = 0; k < n; k++) {
|
||||
test3(data);
|
||||
}
|
||||
verify(data, n);
|
||||
System.out.println(" Finished test3.");
|
||||
}
|
||||
|
||||
if (args[0].equals("test4")) {
|
||||
System.out.println(" Run test4 ...");
|
||||
for (int k = 0; k < n; k++) {
|
||||
test4(data);
|
||||
}
|
||||
verify(data, -n);
|
||||
System.out.println(" Finished test4.");
|
||||
}
|
||||
|
||||
if (args[0].equals("test5")) {
|
||||
System.out.println(" Run test5 ...");
|
||||
for (int k = 0; k < n; k++) {
|
||||
test5(data);
|
||||
}
|
||||
verify(data, n);
|
||||
System.out.println(" Finished test5.");
|
||||
}
|
||||
|
||||
if (args[0].equals("test6")) {
|
||||
System.out.println(" Run test6 ...");
|
||||
for (int k = 0; k < n; k++) {
|
||||
test6(data);
|
||||
}
|
||||
verify(data, -n);
|
||||
System.out.println(" Finished test6.");
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user