From d5d8532ca2ca5cbdcb80af43fb1a192c20af9914 Mon Sep 17 00:00:00 2001 From: Jatin Bhateja Date: Tue, 14 Apr 2026 09:07:14 +0000 Subject: [PATCH] 8381579: C2: "fatal error: LROTATE: double" when using VectorAPI Reviewed-by: mhaessig, qamai --- src/hotspot/share/prims/vectorSupport.cpp | 74 +++++------ .../jdk/incubator/vector/VectorOperators.java | 10 +- .../TestShiftOpOnFloatingVector.java | 121 ++++++++++++++++++ 3 files changed, 163 insertions(+), 42 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/vectorapi/TestShiftOpOnFloatingVector.java diff --git a/src/hotspot/share/prims/vectorSupport.cpp b/src/hotspot/share/prims/vectorSupport.cpp index 7d80ed327fd..5c6010acdf1 100644 --- a/src/hotspot/share/prims/vectorSupport.cpp +++ b/src/hotspot/share/prims/vectorSupport.cpp @@ -226,7 +226,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_LONG: return Op_AddL; case LT_FLOAT: return Op_AddF; case LT_DOUBLE: return Op_AddD; - default: fatal("ADD: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -238,7 +238,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_LONG: return Op_SubL; case LT_FLOAT: return Op_SubF; case LT_DOUBLE: return Op_SubD; - default: fatal("SUB: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -250,7 +250,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_LONG: return Op_MulL; case LT_FLOAT: return Op_MulF; case LT_DOUBLE: return Op_MulD; - default: fatal("MUL: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -262,7 +262,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_LONG: return Op_DivL; case LT_FLOAT: return Op_DivF; case LT_DOUBLE: return Op_DivD; - default: fatal("DIV: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -274,7 +274,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_LONG: return Op_MinL; case LT_FLOAT: return Op_MinF; case LT_DOUBLE: return Op_MinD; - default: fatal("MIN: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -286,7 +286,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_LONG: return Op_MaxL; case LT_FLOAT: return Op_MaxF; case LT_DOUBLE: return Op_MaxD; - default: fatal("MAX: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -296,7 +296,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_SHORT: case LT_INT: case LT_LONG: return Op_UMinV; - default: fatal("MIN: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -306,7 +306,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_SHORT: case LT_INT: case LT_LONG: return Op_UMaxV; - default: fatal("MAX: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -318,7 +318,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_LONG: return Op_AbsL; case LT_FLOAT: return Op_AbsF; case LT_DOUBLE: return Op_AbsD; - default: fatal("ABS: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -330,7 +330,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_LONG: return Op_NegL; case LT_FLOAT: return Op_NegF; case LT_DOUBLE: return Op_NegD; - default: fatal("NEG: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -340,7 +340,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_SHORT: // fall-through case LT_INT: return Op_AndI; case LT_LONG: return Op_AndL; - default: fatal("AND: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -350,7 +350,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_SHORT: // fall-through case LT_INT: return Op_OrI; case LT_LONG: return Op_OrL; - default: fatal("OR: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -360,7 +360,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_SHORT: // fall-through case LT_INT: return Op_XorI; case LT_LONG: return Op_XorL; - default: fatal("XOR: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -368,7 +368,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { switch (lt) { case LT_FLOAT: return Op_SqrtF; case LT_DOUBLE: return Op_SqrtD; - default: fatal("SQRT: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -376,7 +376,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { switch (lt) { case LT_FLOAT: return Op_FmaF; case LT_DOUBLE: return Op_FmaD; - default: fatal("FMA: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -386,7 +386,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_SHORT: // fall-through case LT_INT: return Op_LShiftI; case LT_LONG: return Op_LShiftL; - default: fatal("LSHIFT: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -396,7 +396,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_SHORT: // fall-through case LT_INT: return Op_RShiftI; case LT_LONG: return Op_RShiftL; - default: fatal("RSHIFT: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -406,7 +406,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_SHORT: return Op_URShiftS; case LT_INT: return Op_URShiftI; case LT_LONG: return Op_URShiftL; - default: fatal("URSHIFT: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -416,7 +416,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_SHORT: // fall-through case LT_INT: // fall-through case LT_LONG: return Op_RotateLeft; - default: fatal("LROTATE: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -426,7 +426,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_SHORT: // fall-through case LT_INT: // fall-through case LT_LONG: return Op_RotateRight; - default: fatal("RROTATE: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -438,7 +438,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_LONG: // fall-through case LT_FLOAT: // fall-through case LT_DOUBLE: return Op_VectorMaskLastTrue; - default: fatal("MASK_LASTTRUE: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -450,7 +450,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_LONG: // fall-through case LT_FLOAT: // fall-through case LT_DOUBLE: return Op_VectorMaskFirstTrue; - default: fatal("MASK_FIRSTTRUE: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -462,7 +462,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_LONG: // fall-through case LT_FLOAT: // fall-through case LT_DOUBLE: return Op_VectorMaskTrueCount; - default: fatal("MASK_TRUECOUNT: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -474,7 +474,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_LONG: // fall-through case LT_FLOAT: // fall-through case LT_DOUBLE: return Op_VectorMaskToLong; - default: fatal("MASK_TOLONG: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -486,7 +486,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_LONG: // fall-through case LT_FLOAT: // fall-through case LT_DOUBLE: return Op_ExpandV; - default: fatal("EXPAND: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -498,7 +498,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_LONG: // fall-through case LT_FLOAT: // fall-through case LT_DOUBLE: return Op_CompressV; - default: fatal("COMPRESS: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -510,7 +510,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_LONG: // fall-through case LT_FLOAT: // fall-through case LT_DOUBLE: return Op_CompressM; - default: fatal("MASK_COMPRESS: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -520,7 +520,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_SHORT: // for byte and short types temporarily case LT_INT: return Op_PopCountI; case LT_LONG: return Op_PopCountL; - default: fatal("BILT_COUNT: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -530,7 +530,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_SHORT: case LT_INT: return Op_CountTrailingZerosI; case LT_LONG: return Op_CountTrailingZerosL; - default: fatal("TZ_COUNT: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -540,7 +540,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_SHORT: case LT_INT: return Op_CountLeadingZerosI; case LT_LONG: return Op_CountLeadingZerosL; - default: fatal("LZ_COUNT: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -550,7 +550,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_SHORT: // Op_ReverseI for byte and short case LT_INT: return Op_ReverseI; case LT_LONG: return Op_ReverseL; - default: fatal("REVERSE: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -565,7 +565,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_BYTE: // Intentionally fall-through case LT_INT: return Op_ReverseBytesI; case LT_LONG: return Op_ReverseBytesL; - default: fatal("REVERSE_BYTES: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -576,7 +576,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_SHORT: // fall-through case LT_INT: // fall-through case LT_LONG: return Op_SaturatingAddV; - default: fatal("S[U]ADD: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -587,7 +587,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case LT_SHORT: // fall-through case LT_INT: // fall-through case LT_LONG: return Op_SaturatingSubV; - default: fatal("S[U}SUB: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -595,7 +595,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { switch (lt) { case LT_INT: case LT_LONG: return Op_CompressBits; - default: fatal("COMPRESS_BITS: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -603,7 +603,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { switch (lt) { case LT_INT: case LT_LONG: return Op_ExpandBits; - default: fatal("EXPAND_BITS: %s", lanetype2name(lt)); + default: return 0; } break; } @@ -627,7 +627,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) { case VECTOR_OP_EXPM1: // fall-through case VECTOR_OP_HYPOT: return 0; // not supported; should be handled in Java code - default: fatal("unknown op: %d", vop); + default: return 0; } return 0; // Unimplemented } diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorOperators.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorOperators.java index 2f2d33ab130..cc5a7ccbdef 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorOperators.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorOperators.java @@ -560,15 +560,15 @@ public final class VectorOperators { /** Produce {@code a<<(n&(ESIZE*8-1))}. Integral only. */ - public static final /*bitwise*/ Binary LSHL = binary("LSHL", "<<", VectorSupport.VECTOR_OP_LSHIFT, VO_SHIFT); + public static final /*bitwise*/ Binary LSHL = binary("LSHL", "<<", VectorSupport.VECTOR_OP_LSHIFT, VO_SHIFT+VO_NOFP); /** Produce {@code a>>(n&(ESIZE*8-1))}. Integral only. */ - public static final /*bitwise*/ Binary ASHR = binary("ASHR", ">>", VectorSupport.VECTOR_OP_RSHIFT, VO_SHIFT); + public static final /*bitwise*/ Binary ASHR = binary("ASHR", ">>", VectorSupport.VECTOR_OP_RSHIFT, VO_SHIFT+VO_NOFP); /** Produce {@code (a&EMASK)>>>(n&(ESIZE*8-1))}. Integral only. */ - public static final /*bitwise*/ Binary LSHR = binary("LSHR", ">>>", VectorSupport.VECTOR_OP_URSHIFT, VO_SHIFT); + public static final /*bitwise*/ Binary LSHR = binary("LSHR", ">>>", VectorSupport.VECTOR_OP_URSHIFT, VO_SHIFT+VO_NOFP); /** Produce {@code rotateLeft(a,n)}. Integral only. */ - public static final /*bitwise*/ Binary ROL = binary("ROL", "rotateLeft", VectorSupport.VECTOR_OP_LROTATE, VO_SHIFT); + public static final /*bitwise*/ Binary ROL = binary("ROL", "rotateLeft", VectorSupport.VECTOR_OP_LROTATE, VO_SHIFT+VO_NOFP); /** Produce {@code rotateRight(a,n)}. Integral only. */ - public static final /*bitwise*/ Binary ROR = binary("ROR", "rotateRight", VectorSupport.VECTOR_OP_RROTATE, VO_SHIFT); + public static final /*bitwise*/ Binary ROR = binary("ROR", "rotateRight", VectorSupport.VECTOR_OP_RROTATE, VO_SHIFT+VO_NOFP); /** Produce {@code compress(a,n)}. Integral, {@code int} and {@code long}, only. * @since 19 */ diff --git a/test/hotspot/jtreg/compiler/vectorapi/TestShiftOpOnFloatingVector.java b/test/hotspot/jtreg/compiler/vectorapi/TestShiftOpOnFloatingVector.java new file mode 100644 index 00000000000..ea1878bcb53 --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/TestShiftOpOnFloatingVector.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2026, 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 jdk.incubator.vector.*; + +/* + * @test + * @bug 8381579 + * @summary Verify shift operations on floating-point vectors throw UnsupportedOperationException. + * @modules jdk.incubator.vector + * @library /test/lib / + * @run main/othervm -Xbatch -XX:-TieredCompilation + * compiler.vectorapi.TestShiftOpOnFloatingVector + */ + +public class TestShiftOpOnFloatingVector { + + static final int ITERATIONS = 4_000; + static final int ARRAY_LEN = 100; + + static void testROL() { + double[] arr = new double[ARRAY_LEN]; + for (int i = 0; i < arr.length; i++) { + arr[i] = i * 1.5 + 7.89; + } + for (int i = 0; i < arr.length; i += DoubleVector.SPECIES_PREFERRED.length()) { + DoubleVector v = DoubleVector.fromArray(DoubleVector.SPECIES_PREFERRED, arr, i); + DoubleVector r = v.lanewise(VectorOperators.ROL, 7); + r.intoArray(arr, i); + } + } + + static void testROR() { + double[] arr = new double[ARRAY_LEN]; + for (int i = 0; i < arr.length; i++) { + arr[i] = i * 1.5 + 7.89; + } + for (int i = 0; i < arr.length; i += DoubleVector.SPECIES_PREFERRED.length()) { + DoubleVector v = DoubleVector.fromArray(DoubleVector.SPECIES_PREFERRED, arr, i); + DoubleVector r = v.lanewise(VectorOperators.ROR, 3); + r.intoArray(arr, i); + } + } + + static void testLSHL() { + float[] arr = new float[ARRAY_LEN]; + for (int i = 0; i < arr.length; i++) { + arr[i] = i * 0.5f + 1.0f; + } + for (int i = 0; i < arr.length; i += FloatVector.SPECIES_PREFERRED.length()) { + FloatVector v = FloatVector.fromArray(FloatVector.SPECIES_PREFERRED, arr, i); + FloatVector r = v.lanewise(VectorOperators.LSHL, 2); + r.intoArray(arr, i); + } + } + + static void testLSHR() { + float[] arr = new float[ARRAY_LEN]; + for (int i = 0; i < arr.length; i++) { + arr[i] = i * 0.3f + 2.0f; + } + for (int i = 0; i < arr.length; i += FloatVector.SPECIES_PREFERRED.length()) { + FloatVector v = FloatVector.fromArray(FloatVector.SPECIES_PREFERRED, arr, i); + FloatVector r = v.lanewise(VectorOperators.LSHR, 5); + r.intoArray(arr, i); + } + } + + static void testASHR() { + double[] arr = new double[ARRAY_LEN]; + for (int i = 0; i < arr.length; i++) { + arr[i] = i * 2.0 + 3.0; + } + for (int i = 0; i < arr.length; i += DoubleVector.SPECIES_PREFERRED.length()) { + DoubleVector v = DoubleVector.fromArray(DoubleVector.SPECIES_PREFERRED, arr, i); + DoubleVector r = v.lanewise(VectorOperators.ASHR, 4); + r.intoArray(arr, i); + } + } + + static void runTest(Runnable test, String name) { + for (int i = 0; i < ITERATIONS; i++) { + try { + test.run(); + throw new AssertionError(name + ": Expected UnsupportedOperationException was not thrown"); + } catch (UnsupportedOperationException e) { + // expected + } + } + } + + public static void main(String[] args) { + runTest(TestShiftOpOnFloatingVector::testROL, "ROL"); + runTest(TestShiftOpOnFloatingVector::testROR, "ROR"); + runTest(TestShiftOpOnFloatingVector::testLSHL, "LSHL"); + runTest(TestShiftOpOnFloatingVector::testLSHR, "LSHR"); + runTest(TestShiftOpOnFloatingVector::testASHR, "ASHR"); + } +}