From d90e06af7bd3acd8f77cc243dc3d432882673203 Mon Sep 17 00:00:00 2001
From: Jie Fu <jiefu@openjdk.org>
Date: Fri, 22 Jan 2021 00:13:58 +0000
Subject: [PATCH] 8259775: [Vector API] Incorrect code-gen for
 VectorReinterpret operation

Reviewed-by: rbackman, neliasso, kvn
---
 src/hotspot/cpu/x86/macroAssembler_x86.cpp    |  2 -
 src/hotspot/cpu/x86/macroAssembler_x86.hpp    |  3 +
 src/hotspot/cpu/x86/x86.ad                    |  2 +-
 .../vectorapi/VectorReinterpretTest.java      | 77 +++++++++++++++++++
 4 files changed, 81 insertions(+), 3 deletions(-)
 create mode 100644 test/hotspot/jtreg/compiler/vectorapi/VectorReinterpretTest.java

diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp b/src/hotspot/cpu/x86/macroAssembler_x86.cpp
index e26d9cd50f6..a4f26f992d2 100644
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp
@@ -2485,7 +2485,6 @@ void MacroAssembler::movdqu(XMMRegister dst, Address src) {
 
 void MacroAssembler::movdqu(XMMRegister dst, XMMRegister src) {
     assert(((dst->encoding() < 16  && src->encoding() < 16) || VM_Version::supports_avx512vl()),"XMM register should be 0-15");
-    if (dst->encoding() == src->encoding()) return;
     Assembler::movdqu(dst, src);
 }
 
@@ -2510,7 +2509,6 @@ void MacroAssembler::vmovdqu(XMMRegister dst, Address src) {
 
 void MacroAssembler::vmovdqu(XMMRegister dst, XMMRegister src) {
     assert(((dst->encoding() < 16  && src->encoding() < 16) || VM_Version::supports_avx512vl()),"XMM register should be 0-15");
-    if (dst->encoding() == src->encoding()) return;
     Assembler::vmovdqu(dst, src);
 }
 
diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.hpp b/src/hotspot/cpu/x86/macroAssembler_x86.hpp
index f1bb8f104c9..93b4ae2a29c 100644
--- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp
@@ -168,6 +168,9 @@ class MacroAssembler: public Assembler {
   void movflt(XMMRegister dst, AddressLiteral src);
   void movflt(Address dst, XMMRegister src) { movss(dst, src); }
 
+  // Move with zero extension
+  void movfltz(XMMRegister dst, XMMRegister src) { movss(dst, src); }
+
   void movdbl(XMMRegister dst, XMMRegister src) {
     if (dst-> encoding() == src->encoding()) return;
     if (UseXmmRegToRegMoveAll) { movapd(dst, src); return; }
diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad
index d324900b36b..725da2b922e 100644
--- a/src/hotspot/cpu/x86/x86.ad
+++ b/src/hotspot/cpu/x86/x86.ad
@@ -3375,7 +3375,7 @@ instruct reinterpret_shrink(vec dst, legVec src) %{
   format %{ "vector_reinterpret_shrink $dst,$src\t!" %}
   ins_encode %{
     switch (vector_length_in_bytes(this)) {
-      case  4: __ movflt ($dst$$XMMRegister, $src$$XMMRegister); break;
+      case  4: __ movfltz($dst$$XMMRegister, $src$$XMMRegister); break;
       case  8: __ movq   ($dst$$XMMRegister, $src$$XMMRegister); break;
       case 16: __ movdqu ($dst$$XMMRegister, $src$$XMMRegister); break;
       case 32: __ vmovdqu($dst$$XMMRegister, $src$$XMMRegister); break;
diff --git a/test/hotspot/jtreg/compiler/vectorapi/VectorReinterpretTest.java b/test/hotspot/jtreg/compiler/vectorapi/VectorReinterpretTest.java
new file mode 100644
index 00000000000..b453311f857
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/vectorapi/VectorReinterpretTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company. 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 jdk.incubator.vector.ByteVector;
+import jdk.incubator.vector.VectorOperators;
+import jdk.incubator.vector.VectorSpecies;
+
+/*
+ * @test
+ * @bug 8259775
+ * @summary Incorrect code-gen for VectorReinterpret operation
+ * @modules jdk.incubator.vector
+ * @run main/othervm -Xbatch compiler.vectorapi.VectorReinterpretTest
+ */
+
+public class VectorReinterpretTest {
+    static final VectorSpecies<Byte> SPECIES_128 = ByteVector.SPECIES_128;
+    static final VectorSpecies<Byte> SPECIES_256 = ByteVector.SPECIES_256;
+    static final VectorSpecies<Byte> SPECIES_512 = ByteVector.SPECIES_512;
+
+    static byte[] a = new byte[64];
+
+    private static void test256_128_256() {
+        ByteVector av = ByteVector.fromArray(SPECIES_256, a, 0);
+        ByteVector bv = (ByteVector)av.reinterpretShape(SPECIES_128, 0);
+        ByteVector cv = (ByteVector)bv.reinterpretShape(SPECIES_256, 0);
+
+        if (bv.reduceLanes(VectorOperators.ADD) != 16 ||
+            cv.reduceLanes(VectorOperators.ADD) != 16) {
+            throw new Error("Failed");
+        }
+    }
+
+    private static void test512_256_512() {
+        ByteVector av = ByteVector.fromArray(SPECIES_512, a, 0);
+        ByteVector bv = (ByteVector)av.reinterpretShape(SPECIES_256, 0);
+        ByteVector cv = (ByteVector)bv.reinterpretShape(SPECIES_512, 0);
+
+        if (bv.reduceLanes(VectorOperators.ADD) != 32 ||
+            cv.reduceLanes(VectorOperators.ADD) != 32) {
+            throw new Error("Failed");
+        }
+    }
+
+    public static void main(String[] args) {
+        for (int i = 0; i < a.length; i++) {
+            a[i] = 1;
+        }
+
+        for (int i = 0; i < 100000; i++) {
+            test256_128_256();
+            test512_256_512();
+        }
+    }
+}