8214344: C2: assert(con.basic_type() != T_ILLEGAL) failed: elembt=byte; loadbt=void; unsigned=0
authorroland
Tue, 27 Nov 2018 08:44:19 +0100
changeset 52779 a432469d2ed5
parent 52778 dbbf46b13d52
child 52780 be588be89f68
8214344: C2: assert(con.basic_type() != T_ILLEGAL) failed: elembt=byte; loadbt=void; unsigned=0 Reviewed-by: kvn, thartmann
src/hotspot/share/opto/vectornode.hpp
test/hotspot/jtreg/compiler/loopopts/LoadVectorFromStableArray.java
--- a/src/hotspot/share/opto/vectornode.hpp	Fri Nov 30 10:29:58 2018 +0000
+++ b/src/hotspot/share/opto/vectornode.hpp	Tue Nov 27 08:44:19 2018 +0100
@@ -553,6 +553,7 @@
   LoadVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt, ControlDependency control_dependency = LoadNode::DependsOnlyOnTest)
     : LoadNode(c, mem, adr, at, vt, MemNode::unordered, control_dependency) {
     init_class_id(Class_LoadVector);
+    set_mismatched_access();
   }
 
   const TypeVect* vect_type() const { return type()->is_vect(); }
@@ -581,6 +582,7 @@
     : StoreNode(c, mem, adr, at, val, MemNode::unordered) {
     assert(val->is_Vector() || val->is_LoadVector(), "sanity");
     init_class_id(Class_StoreVector);
+    set_mismatched_access();
   }
 
   const TypeVect* vect_type() const { return in(MemNode::ValueIn)->bottom_type()->is_vect(); }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/loopopts/LoadVectorFromStableArray.java	Tue Nov 27 08:44:19 2018 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2018, Red Hat, Inc. 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 8214344
+ * @summary LoadVector from a known element of a stable array shouldn't attempt to constant fold
+ * @modules java.base/jdk.internal.vm.annotation
+ *
+ * @run main/bootclasspath/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement LoadVectorFromStableArray
+ *
+ */
+
+import jdk.internal.vm.annotation.Stable;
+
+public class LoadVectorFromStableArray {
+    public static void main(String[] args) {
+        byte[] byte_array = new byte[100];
+        for (int i = 0; i < 20_000; i++) {
+            test_helper(0, 0);
+            test_helper(42, 0);
+            test_helper2(0, 20, byte_array, byte_array);
+        }
+        for (int i = 0; i < 20_000; i++) {
+            test(20, true);
+            test(20, false);
+        }
+    }
+
+    static @Stable byte[] stable_array1 = new byte[100];
+    static @Stable byte[] stable_array2 = new byte[100];
+
+    private static void test(int stop, boolean flag) {
+        int start = 0;
+        byte[] byte_array1 = stable_array1;
+        byte[] byte_array2 = flag ? stable_array1 : stable_array2;
+        int k = 2;
+        for (; k < 4; k *= 2);
+        int i = test_helper(k, stop);
+        // Loop in this method is unrolled and vectorized, then, upper
+        // bound is found to be constant and small. A single iteration
+        // of the main loop is executed. That iteration attempts to
+        // load a vector element from the array at a constant offset.
+        test_helper2(start, i, byte_array1, byte_array2);
+    }
+
+
+    private static void test_helper2(int start, int stop, byte[] byte_array1, byte[] byte_array2) {
+        for (int j = start; j < stop; j++) {
+            byte b = byte_array1[j+3];
+            byte_array2[j+3] = b;
+        }
+    }
+
+    private static int test_helper(int k, int stop) {
+        int i = 0;
+        if (k == 42) {
+            i = stop;
+        } else {
+            i = 5;
+        }
+        return i;
+    }
+}