From f8f9148016662578804479180a70e3732b08c11c Mon Sep 17 00:00:00 2001
From: Quan Anh Mai <anhmdq99@gmail.com>
Date: Tue, 4 Jan 2022 22:59:33 +0000
Subject: [PATCH] 8278948: compiler/vectorapi/reshape/TestVectorCastAVX1.java
 crashes in assembler

Reviewed-by: kvn, sviswanathan
---
 src/hotspot/cpu/x86/x86.ad                    | 25 +++---
 .../jtreg/compiler/vectorapi/Test8278948.java | 82 +++++++++++++++++++
 2 files changed, 92 insertions(+), 15 deletions(-)
 create mode 100644 test/hotspot/jtreg/compiler/vectorapi/Test8278948.java

diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad
index 298e874e331..8b36de39cdc 100644
--- a/src/hotspot/cpu/x86/x86.ad
+++ b/src/hotspot/cpu/x86/x86.ad
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2011, 2022, 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
@@ -1783,17 +1783,9 @@ const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType
       }
       break;
     case Op_VectorCastB2X:
-      if (size_in_bits == 256 && UseAVX < 2) {
-        return false; // Implementation limitation
-      }
-      break;
     case Op_VectorCastS2X:
-      if (is_integral_type(bt) && size_in_bits == 256 && UseAVX < 2) {
-        return false;
-      }
-      break;
     case Op_VectorCastI2X:
-      if (is_integral_type(bt) && size_in_bits == 256 && UseAVX < 2) {
+      if (bt != T_DOUBLE && size_in_bits == 256 && UseAVX < 2) {
         return false;
       }
       break;
@@ -6906,11 +6898,12 @@ instruct vcastBtoX(vec dst, vec src) %{
       case T_LONG:
         __ vpmovsxbq($dst$$XMMRegister, $src$$XMMRegister, vlen_enc);
         break;
-      case T_DOUBLE:
-        __ vpmovsxbd($dst$$XMMRegister, $src$$XMMRegister, vlen_enc);
+      case T_DOUBLE: {
+        int mid_vlen_enc = (vlen_enc == Assembler::AVX_512bit) ? Assembler::AVX_256bit : Assembler::AVX_128bit;
+        __ vpmovsxbd($dst$$XMMRegister, $src$$XMMRegister, mid_vlen_enc);
         __ vcvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister, vlen_enc);
         break;
-
+      }
       default: assert(false, "%s", type2name(to_elem_bt));
     }
   %}
@@ -6977,10 +6970,12 @@ instruct vcastStoX_evex(vec dst, vec src) %{
       case T_LONG:
         __ vpmovsxwq($dst$$XMMRegister, $src$$XMMRegister, vlen_enc);
         break;
-      case T_DOUBLE:
-        __ vpmovsxwd($dst$$XMMRegister, $src$$XMMRegister, vlen_enc);
+      case T_DOUBLE: {
+        int mid_vlen_enc = (vlen_enc == Assembler::AVX_512bit) ? Assembler::AVX_256bit : Assembler::AVX_128bit;
+        __ vpmovsxwd($dst$$XMMRegister, $src$$XMMRegister, mid_vlen_enc);
         __ vcvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister, vlen_enc);
         break;
+      }
       default:
         ShouldNotReachHere();
     }
diff --git a/test/hotspot/jtreg/compiler/vectorapi/Test8278948.java b/test/hotspot/jtreg/compiler/vectorapi/Test8278948.java
new file mode 100644
index 00000000000..5218e10c4af
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/vectorapi/Test8278948.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2022, 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.
+ */
+
+package compiler.vectorapi;
+
+import java.util.Random;
+import jdk.incubator.vector.ByteVector;
+import jdk.incubator.vector.DoubleVector;
+import jdk.incubator.vector.ShortVector;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Utils;
+
+/*
+ * @test
+ * @bug 8278948
+ * @summary Intermediate integer promotion vector length encoding is calculated incorrectly on x86
+ * @modules jdk.incubator.vector
+ * @library /test/lib
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:CompileThreshold=100 -XX:UseAVX=1
+ *                   compiler.vectorapi.Test8278948
+ */
+public class Test8278948 {
+    static final int INVOCATIONS = 10000;
+
+    static final Random random = Utils.getRandomInstance();
+    static final byte[] BYTES = new byte[8];
+    static final short[] SHORTS = new short[4];
+    static final double[] DOUBLES = new double[4];
+
+
+    public static void main(String[] args) {
+        for (int i = 0; i < INVOCATIONS; i++) {
+            for (int j = 0; j < DOUBLES.length; j++) {
+                BYTES[j] = (byte)random.nextInt();
+            }
+            bytesToDoubles();
+            for (int j = 0; j < DOUBLES.length; j++) {
+                Asserts.assertEquals((double)BYTES[j], DOUBLES[j]);
+            }
+
+            for (int j = 0; j < DOUBLES.length; j++) {
+                SHORTS[j] = (short)random.nextInt();
+            }
+            shortsToDoubles();
+            for (int j = 0; j < DOUBLES.length; j++) {
+                Asserts.assertEquals((double)SHORTS[j], DOUBLES[j]);
+            }
+        }
+    }
+
+    static void bytesToDoubles() {
+        ((DoubleVector)ByteVector.fromArray(ByteVector.SPECIES_64, BYTES, 0)
+                .castShape(DoubleVector.SPECIES_256, 0))
+                .intoArray(DOUBLES, 0);
+    }
+
+    static void shortsToDoubles() {
+        ((DoubleVector)ShortVector.fromArray(ShortVector.SPECIES_64, SHORTS, 0)
+                .castShape(DoubleVector.SPECIES_256, 0))
+                .intoArray(DOUBLES, 0);
+    }
+}