From d75d876eddfd2e59d9d28c2860fdab4ef3ec3c6b Mon Sep 17 00:00:00 2001
From: Kim Barrett
Date: Mon, 8 Jan 2024 07:30:21 +0000
Subject: [PATCH 001/153] 8322806: Eliminate -Wparentheses warnings in aarch64
code
Reviewed-by: stefank, dholmes
---
src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp b/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp
index f5b46a5351973..5c850c6bcbd65 100644
--- a/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp
+++ b/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -195,7 +195,7 @@ inline bool frame::equal(frame other) const {
&& unextended_sp() == other.unextended_sp()
&& fp() == other.fp()
&& pc() == other.pc();
- assert(!ret || ret && cb() == other.cb() && _deopt_state == other._deopt_state, "inconsistent construction");
+ assert(!ret || (cb() == other.cb() && _deopt_state == other._deopt_state), "inconsistent construction");
return ret;
}
From 7edd10e5fa71dafbbad23455553b7f5ff0a75ac9 Mon Sep 17 00:00:00 2001
From: Per Minborg
Date: Mon, 8 Jan 2024 08:20:07 +0000
Subject: [PATCH 002/153] 8321786: SegmentAllocator:allocateFrom(ValueLayout,
MemorySegment,ValueLayout,long,long) spec mismatch in exception scenario
Reviewed-by: mcimadamore
---
.../java/lang/foreign/MemoryLayout.java | 2 +-
.../java/lang/foreign/MemorySegment.java | 42 +++++++++-
.../java/lang/foreign/SegmentAllocator.java | 6 +-
.../foreign/AbstractMemorySegmentImpl.java | 8 +-
.../classes/jdk/internal/foreign/Utils.java | 21 +++--
.../foreign/layout/AbstractLayout.java | 9 +--
.../foreign/layout/MemoryLayoutUtil.java | 7 --
test/jdk/java/foreign/TestLayouts.java | 4 +-
.../foreign/TestMemoryAccessInstance.java | 7 ++
.../java/foreign/TestScopedOperations.java | 3 +
.../java/foreign/TestSegmentAllocators.java | 77 +++++++++++++++++++
test/jdk/java/foreign/TestSegmentCopy.java | 60 +++++++++++++++
test/jdk/java/foreign/TestSegments.java | 11 ++-
13 files changed, 218 insertions(+), 39 deletions(-)
diff --git a/src/java.base/share/classes/java/lang/foreign/MemoryLayout.java b/src/java.base/share/classes/java/lang/foreign/MemoryLayout.java
index 321d9b09bad34..8a2b3b4df303e 100644
--- a/src/java.base/share/classes/java/lang/foreign/MemoryLayout.java
+++ b/src/java.base/share/classes/java/lang/foreign/MemoryLayout.java
@@ -1016,7 +1016,7 @@ static PaddingLayout paddingLayout(long byteSize) {
* @throws IllegalArgumentException if {@code elementLayout.byteSize() % elementLayout.byteAlignment() != 0}
*/
static SequenceLayout sequenceLayout(long elementCount, MemoryLayout elementLayout) {
- MemoryLayoutUtil.requireNonNegative(elementCount);
+ Utils.checkNonNegativeArgument(elementCount, "elementCount");
Objects.requireNonNull(elementLayout);
Utils.checkElementAlignment(elementLayout,
"Element layout size is not multiple of alignment");
diff --git a/src/java.base/share/classes/java/lang/foreign/MemorySegment.java b/src/java.base/share/classes/java/lang/foreign/MemorySegment.java
index da255b9912b25..faf28b01bf0ac 100644
--- a/src/java.base/share/classes/java/lang/foreign/MemorySegment.java
+++ b/src/java.base/share/classes/java/lang/foreign/MemorySegment.java
@@ -44,6 +44,7 @@
import jdk.internal.foreign.AbstractMemorySegmentImpl;
import jdk.internal.foreign.MemorySessionImpl;
import jdk.internal.foreign.SegmentFactories;
+import jdk.internal.foreign.Utils;
import jdk.internal.javac.Restricted;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.vm.annotation.ForceInline;
@@ -1591,6 +1592,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* incompatible with the alignment constraint
* in the provided layout
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
+ * or {@code offset < 0}
*/
byte get(ValueLayout.OfByte layout, long offset);
@@ -1609,6 +1611,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* incompatible with the alignment constraint
* in the provided layout
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
+ * or {@code offset < 0}
* @throws IllegalArgumentException if this segment is
* {@linkplain #isReadOnly() read-only}
*/
@@ -1629,6 +1632,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* incompatible with the alignment constraint
* in the provided layout
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
+ * or {@code offset < 0}
*/
boolean get(ValueLayout.OfBoolean layout, long offset);
@@ -1647,6 +1651,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* incompatible with the alignment constraint
* in the provided layout
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
+ * or {@code offset < 0}
* @throws IllegalArgumentException if this segment is
* {@linkplain #isReadOnly() read-only}
*/
@@ -1667,6 +1672,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* incompatible with the alignment constraint
* in the provided layout
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
+ * or {@code offset < 0}
*/
char get(ValueLayout.OfChar layout, long offset);
@@ -1685,6 +1691,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* incompatible with the alignment constraint
* in the provided layout
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
+ * or {@code offset < 0}
* @throws IllegalArgumentException if this segment is
* {@linkplain #isReadOnly() read-only}
*/
@@ -1705,6 +1712,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* incompatible with the alignment constraint
* in the provided layout
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
+ * or {@code offset < 0}
*/
short get(ValueLayout.OfShort layout, long offset);
@@ -1723,6 +1731,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* incompatible with the alignment constraint
* in the provided layout
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
+ * or {@code offset < 0}
* @throws IllegalArgumentException if this segment is
* {@linkplain #isReadOnly() read-only}
*/
@@ -1743,6 +1752,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* incompatible with the alignment constraint
* in the provided layout
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
+ * or {@code offset < 0}
*/
int get(ValueLayout.OfInt layout, long offset);
@@ -1761,6 +1771,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* incompatible with the alignment constraint
* in the provided layout
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
+ * or {@code offset < 0}
* @throws IllegalArgumentException if this segment is
* {@linkplain #isReadOnly() read-only}
*/
@@ -1781,6 +1792,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* incompatible with the alignment constraint
* in the provided layout
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
+ * or {@code offset < 0}
*/
float get(ValueLayout.OfFloat layout, long offset);
@@ -1799,6 +1811,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* incompatible with the alignment constraint
* in the provided layout
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
+ * or {@code offset < 0}
* @throws IllegalArgumentException if this segment is
* {@linkplain #isReadOnly() read-only}
*/
@@ -1819,6 +1832,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* incompatible with the alignment constraint
* in the provided layout
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
+ * or {@code offset < 0}
*/
long get(ValueLayout.OfLong layout, long offset);
@@ -1837,6 +1851,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* incompatible with the alignment constraint
* in the provided layout
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
+ * or {@code offset < 0}
* @throws IllegalArgumentException if this segment is
* {@linkplain #isReadOnly() read-only}
*/
@@ -1857,6 +1872,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* incompatible with the alignment constraint
* in the provided layout
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
+ * or {@code offset < 0}
*/
double get(ValueLayout.OfDouble layout, long offset);
@@ -1875,6 +1891,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* incompatible with the alignment constraint
* in the provided layout
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
+ * or {@code offset < 0}
* @throws IllegalArgumentException if this segment is
* {@linkplain #isReadOnly() read-only}
*/
@@ -1905,6 +1922,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* incompatible with the alignment constraint
* in {@code T}
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
+ * or {@code offset < 0}
*/
MemorySegment get(AddressLayout layout, long offset);
@@ -1923,8 +1941,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* incompatible with the alignment constraint
* in the provided layout
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
- * @throws UnsupportedOperationException if this segment is
- * {@linkplain #isReadOnly() read-only}
+ * or {@code offset < 0}
* @throws IllegalArgumentException if {@code value} is not a
* {@linkplain #isNative() native} segment
* @throws IllegalArgumentException if this segment is
@@ -1951,6 +1968,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
+ * or {@code index < 0}
*/
byte getAtIndex(ValueLayout.OfByte layout, long index);
@@ -1973,6 +1991,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
+ * or {@code index < 0}
*/
boolean getAtIndex(ValueLayout.OfBoolean layout, long index);
@@ -1995,6 +2014,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
+ * or {@code index < 0}
*/
char getAtIndex(ValueLayout.OfChar layout, long index);
@@ -2017,7 +2037,8 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
- * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}
+ * or {@code index < 0}
+ * @throws IllegalArgumentException if this segment is {@linkplain #isReadOnly() read-only}
*/
void setAtIndex(ValueLayout.OfChar layout, long index, char value);
@@ -2040,6 +2061,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
+ * or {@code index < 0}
*/
short getAtIndex(ValueLayout.OfShort layout, long index);
@@ -2061,6 +2083,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
+ * or {@code index < 0}
* @throws IllegalArgumentException if this segment is {@linkplain #isReadOnly() read-only}
*/
void setAtIndex(ValueLayout.OfByte layout, long index, byte value);
@@ -2084,6 +2107,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
+ * or {@code index < 0}
* @throws IllegalArgumentException if this segment is {@linkplain #isReadOnly() read-only}
*/
void setAtIndex(ValueLayout.OfBoolean layout, long index, boolean value);
@@ -2107,6 +2131,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
+ * or {@code index < 0}
* @throws IllegalArgumentException if this segment is {@linkplain #isReadOnly() read-only}
*/
void setAtIndex(ValueLayout.OfShort layout, long index, short value);
@@ -2130,6 +2155,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
+ * or {@code index < 0}
*/
int getAtIndex(ValueLayout.OfInt layout, long index);
@@ -2152,6 +2178,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
+ * or {@code index < 0}
* @throws IllegalArgumentException if this segment is {@linkplain #isReadOnly() read-only}
*/
void setAtIndex(ValueLayout.OfInt layout, long index, int value);
@@ -2175,6 +2202,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
+ * or {@code index < 0}
*/
float getAtIndex(ValueLayout.OfFloat layout, long index);
@@ -2197,6 +2225,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
+ * or {@code index < 0}
* @throws IllegalArgumentException if this segment is {@linkplain #isReadOnly() read-only}
*/
void setAtIndex(ValueLayout.OfFloat layout, long index, float value);
@@ -2220,6 +2249,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
+ * or {@code index < 0}
*/
long getAtIndex(ValueLayout.OfLong layout, long index);
@@ -2242,6 +2272,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
+ * or {@code index < 0}
* @throws IllegalArgumentException if this segment is {@linkplain #isReadOnly() read-only}
*/
void setAtIndex(ValueLayout.OfLong layout, long index, long value);
@@ -2265,6 +2296,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
+ * or {@code index < 0}
*/
double getAtIndex(ValueLayout.OfDouble layout, long index);
@@ -2287,6 +2319,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
+ * or {@code index < 0}
* @throws IllegalArgumentException if this segment is {@linkplain #isReadOnly() read-only}
*/
void setAtIndex(ValueLayout.OfDouble layout, long index, double value);
@@ -2319,6 +2352,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* in {@code T}
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
+ * or {@code index < 0}
*/
MemorySegment getAtIndex(AddressLayout layout, long index);
@@ -2341,7 +2375,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
* @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
* @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
- * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}
+ * or {@code index < 0}
* @throws IllegalArgumentException if {@code value} is not a {@linkplain #isNative() native} segment
* @throws IllegalArgumentException if this segment is
* {@linkplain #isReadOnly() read-only}
diff --git a/src/java.base/share/classes/java/lang/foreign/SegmentAllocator.java b/src/java.base/share/classes/java/lang/foreign/SegmentAllocator.java
index 6be9d949ea652..6c9cf51bee8b7 100644
--- a/src/java.base/share/classes/java/lang/foreign/SegmentAllocator.java
+++ b/src/java.base/share/classes/java/lang/foreign/SegmentAllocator.java
@@ -33,6 +33,7 @@
import jdk.internal.foreign.ArenaImpl;
import jdk.internal.foreign.SlicingAllocator;
import jdk.internal.foreign.StringSupport;
+import jdk.internal.foreign.Utils;
import jdk.internal.vm.annotation.ForceInline;
/**
@@ -390,9 +391,10 @@ default MemorySegment allocateFrom(AddressLayout layout, MemorySegment value) {
* with {@code source} is not {@linkplain MemorySegment.Scope#isAlive() alive}
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code source.isAccessibleBy(T) == false}
- * @throws IndexOutOfBoundsException if {@code elementCount * sourceElementLayout.byteSize()} overflows
+ * @throws IllegalArgumentException if {@code elementCount * sourceElementLayout.byteSize()} overflows
+ * @throws IllegalArgumentException if {@code elementCount < 0}
* @throws IndexOutOfBoundsException if {@code sourceOffset > source.byteSize() - (elementCount * sourceElementLayout.byteSize())}
- * @throws IndexOutOfBoundsException if either {@code sourceOffset} or {@code elementCount} are {@code < 0}
+ * @throws IndexOutOfBoundsException if {@code sourceOffset < 0}
*/
@ForceInline
default MemorySegment allocateFrom(ValueLayout elementLayout,
diff --git a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java
index 305594952d44e..0efe62c1e4fbc 100644
--- a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java
+++ b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java
@@ -153,9 +153,7 @@ public final MemorySegment reinterpret(Arena arena, Consumer clea
public MemorySegment reinterpretInternal(Class> callerClass, long newSize, Scope scope, Consumer cleanup) {
Reflection.ensureNativeAccess(callerClass, MemorySegment.class, "reinterpret");
- if (newSize < 0) {
- throw new IllegalArgumentException("newSize < 0");
- }
+ Utils.checkNonNegativeArgument(newSize, "newSize");
if (!isNative()) throw new UnsupportedOperationException("Not a native segment");
Runnable action = cleanup != null ?
() -> cleanup.accept(SegmentFactories.makeNativeSegmentUnchecked(address(), newSize)) :
@@ -594,6 +592,7 @@ public static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout,
MemorySegment dstSegment, ValueLayout dstElementLayout, long dstOffset,
long elementCount) {
+ Utils.checkNonNegativeIndex(elementCount, "elementCount");
AbstractMemorySegmentImpl srcImpl = (AbstractMemorySegmentImpl)srcSegment;
AbstractMemorySegmentImpl dstImpl = (AbstractMemorySegmentImpl)dstSegment;
if (srcElementLayout.byteSize() != dstElementLayout.byteSize()) {
@@ -625,7 +624,7 @@ public static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout,
public static void copy(MemorySegment srcSegment, ValueLayout srcLayout, long srcOffset,
Object dstArray, int dstIndex,
int elementCount) {
-
+ Utils.checkNonNegativeIndex(elementCount, "elementCount");
var dstInfo = Utils.BaseAndScale.of(dstArray);
if (dstArray.getClass().componentType() != srcLayout.carrier()) {
throw new IllegalArgumentException("Incompatible value layout: " + srcLayout);
@@ -652,7 +651,6 @@ public static void copy(MemorySegment srcSegment, ValueLayout srcLayout, long sr
public static void copy(Object srcArray, int srcIndex,
MemorySegment dstSegment, ValueLayout dstLayout, long dstOffset,
int elementCount) {
-
var srcInfo = Utils.BaseAndScale.of(srcArray);
if (srcArray.getClass().componentType() != dstLayout.carrier()) {
throw new IllegalArgumentException("Incompatible value layout: " + dstLayout);
diff --git a/src/java.base/share/classes/jdk/internal/foreign/Utils.java b/src/java.base/share/classes/jdk/internal/foreign/Utils.java
index d0d5c866f6b4e..6a081e23eac0d 100644
--- a/src/java.base/share/classes/jdk/internal/foreign/Utils.java
+++ b/src/java.base/share/classes/jdk/internal/foreign/Utils.java
@@ -200,11 +200,8 @@ public static long pointeeByteAlign(AddressLayout addressLayout) {
}
public static void checkAllocationSizeAndAlign(long byteSize, long byteAlignment) {
- // size should be >= 0
- if (byteSize < 0) {
- throw new IllegalArgumentException("Invalid allocation size : " + byteSize);
- }
-
+ // byteSize should be >= 0
+ Utils.checkNonNegativeArgument(byteSize, "allocation size");
checkAlign(byteAlignment);
}
@@ -216,6 +213,20 @@ public static void checkAlign(long byteAlignment) {
}
}
+ @ForceInline
+ public static void checkNonNegativeArgument(long value, String name) {
+ if (value < 0) {
+ throw new IllegalArgumentException("The provided " + name + " is negative: " + value);
+ }
+ }
+
+ @ForceInline
+ public static void checkNonNegativeIndex(long value, String name) {
+ if (value < 0) {
+ throw new IndexOutOfBoundsException("The provided " + name + " is negative: " + value);
+ }
+ }
+
private static long computePadding(long offset, long align) {
boolean isAligned = offset == 0 || offset % align == 0;
if (isAligned) {
diff --git a/src/java.base/share/classes/jdk/internal/foreign/layout/AbstractLayout.java b/src/java.base/share/classes/jdk/internal/foreign/layout/AbstractLayout.java
index e4d931127af99..3c0cf3902bbd0 100644
--- a/src/java.base/share/classes/jdk/internal/foreign/layout/AbstractLayout.java
+++ b/src/java.base/share/classes/jdk/internal/foreign/layout/AbstractLayout.java
@@ -151,13 +151,8 @@ private static long requirePowerOfTwoAndGreaterOrEqualToOne(long value) {
}
public long scale(long offset, long index) {
- if (offset < 0) {
- throw new IllegalArgumentException("Negative offset: " + offset);
- }
- if (index < 0) {
- throw new IllegalArgumentException("Negative index: " + index);
- }
-
+ Utils.checkNonNegativeArgument(offset, "offset");
+ Utils.checkNonNegativeArgument(index, "index");
return Math.addExact(offset, Math.multiplyExact(byteSize(), index));
}
diff --git a/src/java.base/share/classes/jdk/internal/foreign/layout/MemoryLayoutUtil.java b/src/java.base/share/classes/jdk/internal/foreign/layout/MemoryLayoutUtil.java
index dce061410285f..6b8e7738198cc 100644
--- a/src/java.base/share/classes/jdk/internal/foreign/layout/MemoryLayoutUtil.java
+++ b/src/java.base/share/classes/jdk/internal/foreign/layout/MemoryLayoutUtil.java
@@ -30,13 +30,6 @@ public final class MemoryLayoutUtil {
private MemoryLayoutUtil() {
}
- public static long requireNonNegative(long value) {
- if (value < 0) {
- throw new IllegalArgumentException("The provided value was negative: " + value);
- }
- return value;
- }
-
public static long requireByteSizeValid(long byteSize, boolean allowZero) {
if ((byteSize == 0 && !allowZero) || byteSize < 0) {
throw new IllegalArgumentException("Invalid byte size: " + byteSize);
diff --git a/test/jdk/java/foreign/TestLayouts.java b/test/jdk/java/foreign/TestLayouts.java
index f4048aaa68a08..2aa398468cc9f 100644
--- a/test/jdk/java/foreign/TestLayouts.java
+++ b/test/jdk/java/foreign/TestLayouts.java
@@ -371,13 +371,13 @@ public void testVarHandleCaching() {
}
@Test(expectedExceptions=IllegalArgumentException.class,
- expectedExceptionsMessageRegExp=".*Negative offset.*")
+ expectedExceptionsMessageRegExp=".*offset is negative.*")
public void testScaleNegativeOffset() {
JAVA_INT.scale(-1, 0);
}
@Test(expectedExceptions=IllegalArgumentException.class,
- expectedExceptionsMessageRegExp=".*Negative index.*")
+ expectedExceptionsMessageRegExp=".*index is negative.*")
public void testScaleNegativeIndex() {
JAVA_INT.scale(0, -1);
}
diff --git a/test/jdk/java/foreign/TestMemoryAccessInstance.java b/test/jdk/java/foreign/TestMemoryAccessInstance.java
index d56f44388a4bb..b749c96ac5421 100644
--- a/test/jdk/java/foreign/TestMemoryAccessInstance.java
+++ b/test/jdk/java/foreign/TestMemoryAccessInstance.java
@@ -164,6 +164,13 @@ public void badAccessOverflowInIndexedAccess(String t
}
}
+ @Test(dataProvider = "segmentAccessors")
+ public void negativeOffset(String testName, Accessor accessor) {
+ MemorySegment segment = MemorySegment.ofArray(new byte[100]);
+ assertThrows(IndexOutOfBoundsException.class, () -> accessor.get(segment, -ValueLayout.JAVA_LONG.byteSize()));
+ assertThrows(IndexOutOfBoundsException.class, () -> accessor.set(segment, -ValueLayout.JAVA_LONG.byteSize(), accessor.value));
+ }
+
static final ByteOrder NE = ByteOrder.nativeOrder();
@DataProvider(name = "segmentAccessors")
diff --git a/test/jdk/java/foreign/TestScopedOperations.java b/test/jdk/java/foreign/TestScopedOperations.java
index 70223c00c008d..d680d23414570 100644
--- a/test/jdk/java/foreign/TestScopedOperations.java
+++ b/test/jdk/java/foreign/TestScopedOperations.java
@@ -27,6 +27,7 @@
*/
import java.lang.foreign.Arena;
+import java.lang.foreign.MemoryLayout;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.ValueLayout;
@@ -135,6 +136,8 @@ public void testOpOutsideConfinement(String name, ScopedOperation scopedO
ScopedOperation.ofScope(a -> a.allocateFrom(ValueLayout.JAVA_FLOAT, new float[]{0}), "Arena::allocateFrom/float");
ScopedOperation.ofScope(a -> a.allocateFrom(ValueLayout.JAVA_LONG, new long[]{0}), "Arena::allocateFrom/long");
ScopedOperation.ofScope(a -> a.allocateFrom(ValueLayout.JAVA_DOUBLE, new double[]{0}), "Arena::allocateFrom/double");
+ var source = MemorySegment.ofArray(new byte[]{});
+ ScopedOperation.ofScope(a -> a.allocateFrom(ValueLayout.JAVA_INT, source, JAVA_BYTE, 0, 1), "Arena::allocateFrom/5arg");
};
@DataProvider(name = "scopedOperations")
diff --git a/test/jdk/java/foreign/TestSegmentAllocators.java b/test/jdk/java/foreign/TestSegmentAllocators.java
index 0e0c49320da07..87418f39d90af 100644
--- a/test/jdk/java/foreign/TestSegmentAllocators.java
+++ b/test/jdk/java/foreign/TestSegmentAllocators.java
@@ -44,6 +44,8 @@
import java.nio.ShortBuffer;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiFunction;
import java.util.function.Function;
@@ -189,6 +191,81 @@ public void testAllocatorAllocateFromHeapSegment() {
}
}
+ // Invariant checking tests for the SegmentAllocator method:
+ // MemorySegment allocateFrom(ValueLayout elementLayout,
+ // MemorySegment source,
+ // ValueLayout sourceElementLayout,
+ // long sourceOffset,
+ // long elementCount) {
+ @Test
+ public void testAllocatorAllocateFromArguments() {
+ try (Arena arena = Arena.ofConfined()) {
+ var sourceElements = 2;
+ var source = arena.allocate(ValueLayout.JAVA_LONG, sourceElements);
+ var elementLayout = ValueLayout.JAVA_INT;
+ var sourceElementLayout = ValueLayout.JAVA_INT;
+
+ // IllegalArgumentException if {@code elementLayout.byteSize() != sourceElementLayout.byteSize()}
+ assertThrows(IllegalArgumentException.class, () ->
+ arena.allocateFrom(elementLayout, source, ValueLayout.JAVA_BYTE, 0, 1)
+ );
+
+ // IllegalArgumentException if source segment/offset
+ // are incompatible with the alignment constraint
+ // in the source element layout
+ assertThrows(IllegalArgumentException.class, () ->
+ arena.allocateFrom(elementLayout, source.asSlice(1), sourceElementLayout, 0, 1)
+ );
+ assertThrows(IllegalArgumentException.class, () ->
+ arena.allocateFrom(elementLayout, source, sourceElementLayout, 1, 1)
+ );
+
+ // IllegalArgumentException if {@code elementLayout.byteAlignment() > elementLayout.byteSize()}
+ assertThrows(IllegalArgumentException.class, () ->
+ arena.allocateFrom(elementLayout.withByteAlignment(elementLayout.byteAlignment() * 2), source, sourceElementLayout, 1, 1)
+ );
+
+ // IllegalStateException if the {@linkplain MemorySegment#scope() scope} associated
+ // with {@code source} is not {@linkplain MemorySegment.Scope#isAlive() alive}
+ // This is tested in TestScopedOperations
+
+ // WrongThreadException if this method is called from a thread {@code T},
+ // such that {@code source.isAccessibleBy(T) == false}
+ CompletableFuture future = CompletableFuture.supplyAsync(Arena::ofConfined);
+ try {
+ Arena otherThreadArena = future.get();
+ assertThrows(WrongThreadException.class, () ->
+ otherThreadArena.allocateFrom(elementLayout, source, sourceElementLayout, 0, 1)
+ );
+ } catch (ExecutionException | InterruptedException e) {
+ fail("Unable to create arena", e);
+ }
+
+ // IllegalArgumentException if {@code elementCount * sourceElementLayout.byteSize()} overflows
+ assertThrows(IllegalArgumentException.class, () ->
+ arena.allocateFrom(elementLayout, source, sourceElementLayout, 0, Long.MAX_VALUE)
+ );
+
+ // IndexOutOfBoundsException if {@code sourceOffset > source.byteSize() - (elementCount * sourceElementLayout.byteSize())}
+ assertThrows(IndexOutOfBoundsException.class, () ->
+ arena.allocateFrom(elementLayout, source, sourceElementLayout, source.byteSize() - (1 * sourceElementLayout.byteAlignment()) + elementLayout.byteSize(), 1)
+ );
+
+ // IndexOutOfBoundsException if {@code sourceOffset < 0}
+ assertThrows(IndexOutOfBoundsException.class, () ->
+ arena.allocateFrom(elementLayout, source, sourceElementLayout, -elementLayout.byteSize(), 1)
+ );
+
+ // IllegalArgumentException if {@code elementCount < 0}
+ assertThrows(IllegalArgumentException.class, () ->
+ arena.allocateFrom(elementLayout, source, sourceElementLayout, 0, -1)
+ );
+
+
+ }
+ }
+
+
@Test
public void testArrayAllocateDelegation() {
AtomicInteger calls = new AtomicInteger();
diff --git a/test/jdk/java/foreign/TestSegmentCopy.java b/test/jdk/java/foreign/TestSegmentCopy.java
index 414cd0a8451d9..88636bf5420ce 100644
--- a/test/jdk/java/foreign/TestSegmentCopy.java
+++ b/test/jdk/java/foreign/TestSegmentCopy.java
@@ -145,6 +145,66 @@ public void testHyperAlignedDst() {
MemorySegment.copy(segment, JAVA_BYTE.withByteAlignment(2), 0, segment, 0, 4);
}
+ @Test
+ public void testCopy5ArgWithNegativeValues() {
+ MemorySegment src = MemorySegment.ofArray(new byte[] {1, 2, 3, 4});
+ MemorySegment dst = MemorySegment.ofArray(new byte[] {1, 2, 3, 4});
+ assertThrows(IndexOutOfBoundsException.class, () ->
+ MemorySegment.copy(src, -1, dst, 0, 4)
+ );
+ assertThrows(IndexOutOfBoundsException.class, () ->
+ MemorySegment.copy(src, 0, dst, -1, 4)
+ );
+ assertThrows(IndexOutOfBoundsException.class, () ->
+ MemorySegment.copy(src, 0, dst, 0, -1)
+ );
+ }
+
+ @Test
+ public void testCopy7ArgWithNegativeValues() {
+ MemorySegment src = MemorySegment.ofArray(new byte[] {1, 2, 3, 4});
+ MemorySegment dst = MemorySegment.ofArray(new byte[] {1, 2, 3, 4});
+ assertThrows(IndexOutOfBoundsException.class, () ->
+ MemorySegment.copy(src, JAVA_BYTE, -1, dst, JAVA_BYTE, 0, 4)
+ );
+ assertThrows(IndexOutOfBoundsException.class, () ->
+ MemorySegment.copy(src, JAVA_BYTE, 0, dst, JAVA_BYTE, -1, 4)
+ );
+ assertThrows(IndexOutOfBoundsException.class, () ->
+ MemorySegment.copy(src, JAVA_BYTE, 0, dst, JAVA_BYTE, 0, -1)
+ );
+ }
+
+ @Test
+ public void testCopyFromArrayWithNegativeValues() {
+ MemorySegment src = MemorySegment.ofArray(new byte[] {1, 2, 3, 4});
+ byte[] dst = new byte[] {1, 2, 3, 4};
+ assertThrows(IndexOutOfBoundsException.class, () ->
+ MemorySegment.copy(src, JAVA_BYTE, -1, dst, 0, 4)
+ );
+ assertThrows(IndexOutOfBoundsException.class, () ->
+ MemorySegment.copy(src, JAVA_BYTE, 0, dst, -1, 4)
+ );
+ assertThrows(IndexOutOfBoundsException.class, () ->
+ MemorySegment.copy(src, JAVA_BYTE, 0, dst, 0, -1)
+ );
+ }
+
+ @Test
+ public void testCopyToArrayWithNegativeValues() {
+ byte[] src = new byte[] {1, 2, 3, 4};
+ MemorySegment dst = MemorySegment.ofArray(new byte[] {1, 2, 3, 4});
+ assertThrows(IndexOutOfBoundsException.class, () ->
+ MemorySegment.copy(src, -1, dst, JAVA_BYTE, 0, 4)
+ );
+ assertThrows(IndexOutOfBoundsException.class, () ->
+ MemorySegment.copy(src, 0, dst, JAVA_BYTE, -1, 4)
+ );
+ assertThrows(IndexOutOfBoundsException.class, () ->
+ MemorySegment.copy(src, 0, dst, JAVA_BYTE, 0, -1)
+ );
+ }
+
enum Type {
// Byte
BYTE(byte.class, JAVA_BYTE, i -> (byte)i),
diff --git a/test/jdk/java/foreign/TestSegments.java b/test/jdk/java/foreign/TestSegments.java
index 94b49eb7e594c..44ecd12ba5ebd 100644
--- a/test/jdk/java/foreign/TestSegments.java
+++ b/test/jdk/java/foreign/TestSegments.java
@@ -43,6 +43,7 @@
import java.util.function.Supplier;
import static java.lang.foreign.ValueLayout.JAVA_INT;
+import static java.lang.foreign.ValueLayout.JAVA_LONG;
import static org.testng.Assert.*;
public class TestSegments {
@@ -55,14 +56,13 @@ public void testBadAllocateAlign(long size, long align) {
@Test
public void testZeroLengthNativeSegment() {
try (Arena arena = Arena.ofConfined()) {
- Arena session = arena;
- var segment = session.allocate(0, 1);
+ var segment = arena.allocate(0, 1);
assertEquals(segment.byteSize(), 0);
MemoryLayout seq = MemoryLayout.sequenceLayout(0, JAVA_INT);
- segment = session.allocate(seq);
+ segment = arena.allocate(seq);
assertEquals(segment.byteSize(), 0);
assertEquals(segment.address() % seq.byteAlignment(), 0);
- segment = session.allocate(0, 4);
+ segment = arena.allocate(0, 4);
assertEquals(segment.byteSize(), 0);
assertEquals(segment.address() % 4, 0);
MemorySegment rawAddress = MemorySegment.ofAddress(segment.address());
@@ -133,8 +133,7 @@ public void testDerivedScopes(Supplier segmentSupplier) {
@Test
public void testEqualsOffHeap() {
try (Arena arena = Arena.ofConfined()) {
- Arena scope1 = arena;
- MemorySegment segment = scope1.allocate(100, 1);
+ MemorySegment segment = arena.allocate(100, 1);
assertEquals(segment, segment.asReadOnly());
assertEquals(segment, segment.asSlice(0, 100));
assertNotEquals(segment, segment.asSlice(10, 90));
From a40d397d5d785d29a2d5e848f872d11dab3bf80c Mon Sep 17 00:00:00 2001
From: Kim Barrett
Date: Mon, 8 Jan 2024 09:01:33 +0000
Subject: [PATCH 003/153] 8323110: Eliminate -Wparentheses warnings in ppc code
Reviewed-by: dholmes
---
src/hotspot/cpu/ppc/frame_ppc.inline.hpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/hotspot/cpu/ppc/frame_ppc.inline.hpp b/src/hotspot/cpu/ppc/frame_ppc.inline.hpp
index e7dca45b3c35a..861c6adc491e4 100644
--- a/src/hotspot/cpu/ppc/frame_ppc.inline.hpp
+++ b/src/hotspot/cpu/ppc/frame_ppc.inline.hpp
@@ -78,8 +78,8 @@ inline void frame::setup() {
// Continuation frames on the java heap are not aligned.
// When thawing interpreted frames the sp can be unaligned (see new_stack_frame()).
assert(_on_heap ||
- (is_aligned(_sp, alignment_in_bytes) || is_interpreted_frame()) &&
- (is_aligned(_fp, alignment_in_bytes) || !is_fully_initialized()),
+ ((is_aligned(_sp, alignment_in_bytes) || is_interpreted_frame()) &&
+ (is_aligned(_fp, alignment_in_bytes) || !is_fully_initialized())),
"invalid alignment sp:" PTR_FORMAT " unextended_sp:" PTR_FORMAT " fp:" PTR_FORMAT, p2i(_sp), p2i(_unextended_sp), p2i(_fp));
}
From eb9e754b3a439cc3ce36c2c9393bc8b250343844 Mon Sep 17 00:00:00 2001
From: Aleksey Shipilev
Date: Mon, 8 Jan 2024 10:27:00 +0000
Subject: [PATCH 004/153] 8323065: Unneccesary CodeBlob lookup in
CompiledIC::internal_set_ic_destination
Reviewed-by: dlong, thartmann
---
src/hotspot/share/code/compiledIC.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/hotspot/share/code/compiledIC.cpp b/src/hotspot/share/code/compiledIC.cpp
index b493df73ba88c..28c02d8578c55 100644
--- a/src/hotspot/share/code/compiledIC.cpp
+++ b/src/hotspot/share/code/compiledIC.cpp
@@ -128,11 +128,13 @@ void CompiledIC::internal_set_ic_destination(address entry_point, bool is_icstub
tty->cr();
}
+#ifdef ASSERT
{
CodeBlob* cb = CodeCache::find_blob(_call->instruction_address());
assert(cb != nullptr && cb->is_compiled(), "must be compiled");
- _call->set_destination_mt_safe(entry_point);
}
+#endif
+ _call->set_destination_mt_safe(entry_point);
if (is_optimized() || is_icstub) {
// Optimized call sites don't have a cache value and ICStub call
From 09c6c4ff021b7dc719c0b1e0dfb041b03bba1b5d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Markus=20Gr=C3=B6nlund?=
Date: Mon, 8 Jan 2024 11:41:51 +0000
Subject: [PATCH 005/153] 8322489: 22-b27: Up to 7% regression in all
Footprint3-*-G1/ZGC
Reviewed-by: egahlin
---
src/hotspot/share/jfr/jfr.cpp | 4 +++-
.../checkpoint/jfrCheckpointManager.cpp | 8 +++----
.../checkpoint/jfrCheckpointWriter.hpp | 1 +
.../share/jfr/recorder/jfrRecorder.cpp | 24 +++++++++++++------
.../share/jfr/recorder/jfrRecorder.hpp | 1 +
.../jfr/support/jfrDeprecationManager.cpp | 4 +++-
6 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/src/hotspot/share/jfr/jfr.cpp b/src/hotspot/share/jfr/jfr.cpp
index 45848fb024311..03b47bcd21dc5 100644
--- a/src/hotspot/share/jfr/jfr.cpp
+++ b/src/hotspot/share/jfr/jfr.cpp
@@ -67,7 +67,9 @@ void Jfr::on_create_vm_3() {
}
void Jfr::on_unloading_classes() {
- JfrCheckpointManager::on_unloading_classes();
+ if (JfrRecorder::is_created() || JfrRecorder::is_started_on_commandline()) {
+ JfrCheckpointManager::on_unloading_classes();
+ }
}
bool Jfr::is_excluded(Thread* t) {
diff --git a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp
index 799d6ef899d03..0aed916702e79 100644
--- a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp
+++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp
@@ -117,16 +117,16 @@ bool JfrCheckpointManager::initialize_early() {
assert(_thread_local_mspace == nullptr, "invariant");
_thread_local_mspace = new JfrThreadLocalCheckpointMspace();
if (_thread_local_mspace == nullptr || !_thread_local_mspace->initialize(thread_local_buffer_size,
- thread_local_buffer_prealloc_count,
- thread_local_buffer_prealloc_count)) {
+ thread_local_buffer_prealloc_count,
+ thread_local_buffer_prealloc_count)) {
return false;
}
assert(_virtual_thread_local_mspace == nullptr, "invariant");
_virtual_thread_local_mspace = new JfrThreadLocalCheckpointMspace();
if (_virtual_thread_local_mspace == nullptr || !_virtual_thread_local_mspace->initialize(virtual_thread_local_buffer_size,
- JFR_MSPACE_UNLIMITED_CACHE_SIZE,
- virtual_thread_local_buffer_prealloc_count)) {
+ JFR_MSPACE_UNLIMITED_CACHE_SIZE,
+ virtual_thread_local_buffer_prealloc_count)) {
return false;
}
return true;
diff --git a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointWriter.hpp b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointWriter.hpp
index f99159b3a51c9..a8ec2fd70f538 100644
--- a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointWriter.hpp
+++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointWriter.hpp
@@ -55,6 +55,7 @@ struct JfrCheckpointContext {
class JfrCheckpointWriter : public JfrCheckpointWriterBase {
friend class JfrCheckpointManager;
+ friend class JfrDeprecationManager;
friend class JfrSerializerRegistration;
friend class JfrTypeManager;
private:
diff --git a/src/hotspot/share/jfr/recorder/jfrRecorder.cpp b/src/hotspot/share/jfr/recorder/jfrRecorder.cpp
index 40c3d7a8c4f4d..cc460f8c2aad6 100644
--- a/src/hotspot/share/jfr/recorder/jfrRecorder.cpp
+++ b/src/hotspot/share/jfr/recorder/jfrRecorder.cpp
@@ -86,9 +86,6 @@ bool JfrRecorder::create_oop_storages() {
return ObjectSampler::create_oop_storage();
}
-// Subsystem
-static JfrCheckpointManager* _checkpoint_manager = nullptr;
-
bool JfrRecorder::on_create_vm_1() {
if (!is_disabled()) {
if (FlightRecorder || is_started_on_commandline()) {
@@ -99,9 +96,10 @@ bool JfrRecorder::on_create_vm_1() {
return false;
}
- _checkpoint_manager = JfrCheckpointManager::create();
- if (_checkpoint_manager == nullptr || !_checkpoint_manager->initialize_early()) {
- return false;
+ if (is_started_on_commandline()) {
+ if (!create_checkpoint_manager()) {
+ return false;
+ }
}
// fast time initialization
@@ -292,7 +290,7 @@ bool JfrRecorder::create_components() {
if (!create_storage()) {
return false;
}
- if (!create_checkpoint_manager()) {
+ if (!initialize_checkpoint_manager()) {
return false;
}
if (!create_stacktrace_repository()) {
@@ -321,6 +319,7 @@ static JfrStackTraceRepository* _stack_trace_repository;
static JfrStringPool* _stringpool = nullptr;
static JfrOSInterface* _os_interface = nullptr;
static JfrThreadSampling* _thread_sampling = nullptr;
+static JfrCheckpointManager* _checkpoint_manager = nullptr;
bool JfrRecorder::create_java_event_writer() {
return JfrJavaEventWriter::initialize();
@@ -357,6 +356,17 @@ bool JfrRecorder::create_storage() {
}
bool JfrRecorder::create_checkpoint_manager() {
+ assert(_checkpoint_manager == nullptr, "invariant");
+ _checkpoint_manager = JfrCheckpointManager::create();
+ return _checkpoint_manager != nullptr && _checkpoint_manager->initialize_early();
+}
+
+bool JfrRecorder::initialize_checkpoint_manager() {
+ if (_checkpoint_manager == nullptr) {
+ if (!create_checkpoint_manager()) {
+ return false;
+ }
+ }
assert(_checkpoint_manager != nullptr, "invariant");
assert(_repository != nullptr, "invariant");
return _checkpoint_manager->initialize(&_repository->chunkwriter());
diff --git a/src/hotspot/share/jfr/recorder/jfrRecorder.hpp b/src/hotspot/share/jfr/recorder/jfrRecorder.hpp
index 3e2541fad98ef..9f4969b01872a 100644
--- a/src/hotspot/share/jfr/recorder/jfrRecorder.hpp
+++ b/src/hotspot/share/jfr/recorder/jfrRecorder.hpp
@@ -42,6 +42,7 @@ class JfrRecorder : public JfrCHeapObj {
static bool on_create_vm_2();
static bool on_create_vm_3();
static bool create_checkpoint_manager();
+ static bool initialize_checkpoint_manager();
static bool create_chunk_repository();
static bool create_java_event_writer();
static bool create_jvmti_agent();
diff --git a/src/hotspot/share/jfr/support/jfrDeprecationManager.cpp b/src/hotspot/share/jfr/support/jfrDeprecationManager.cpp
index a36b85dbb7eb1..5f5c87d239c7f 100644
--- a/src/hotspot/share/jfr/support/jfrDeprecationManager.cpp
+++ b/src/hotspot/share/jfr/support/jfrDeprecationManager.cpp
@@ -371,8 +371,10 @@ void JfrDeprecationManager::write_edges(JfrChunkWriter& cw, Thread* thread, bool
void JfrDeprecationManager::on_type_set(JfrCheckpointWriter& writer, JfrChunkWriter* cw, Thread* thread) {
assert(_pending_list.is_empty(), "invariant");
- if (writer.has_data() && _pending_head != nullptr) {
+ if (_pending_head != nullptr) {
save_type_set_blob(writer);
+ } else {
+ writer.cancel();
}
if (cw != nullptr) {
write_edges(*cw, thread);
From 71aac7a5fbb9a32181ada1a04b6a9622fe939c59 Mon Sep 17 00:00:00 2001
From: Matthias Baesken
Date: Mon, 8 Jan 2024 11:45:18 +0000
Subject: [PATCH 006/153] 8276809:
java/awt/font/JNICheck/FreeTypeScalerJNICheck.java shows JNI warning on
Windows
Reviewed-by: rschmelter, stuefe
---
.../native/libawt/windows/awt_Win32GraphicsEnv.cpp | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsEnv.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsEnv.cpp
index 6c949b564e960..7dac7b17b1be4 100644
--- a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsEnv.cpp
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsEnv.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2024, 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
@@ -126,9 +126,15 @@ BOOL DWMIsCompositionEnabled() {
dwmIsCompositionEnabled = bRes;
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
- JNU_CallStaticMethodByName(env, NULL,
+ jboolean hasException;
+ JNU_CallStaticMethodByName(env, &hasException,
"sun/awt/Win32GraphicsEnvironment",
"dwmCompositionChanged", "(Z)V", (jboolean)bRes);
+ if (hasException) {
+ J2dTraceLn(J2D_TRACE_INFO, "Exception occurred in DWMIsCompositionEnabled");
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
return bRes;
}
From 458e563cd994f5e0f590c2144e8ed35d020d53d6 Mon Sep 17 00:00:00 2001
From: Christian Hagedorn
Date: Mon, 8 Jan 2024 12:57:55 +0000
Subject: [PATCH 007/153] 8310711: [IR Framework] Remove safepoint while
printing handling
Reviewed-by: thartmann, epeter
---
.../parser/hotspot/CompilePhaseBlock.java | 31 +---
.../irmatching/parser/hotspot/State.java | 18 +-
.../parser/hotspot/WriterThread.java | 51 ------
.../parser/hotspot/WriterThreads.java | 50 ------
.../tests/TestSafepointWhilePrinting.java | 152 ----------------
.../safepoint_while_printing_hotspot_pid.log | 163 ------------------
6 files changed, 4 insertions(+), 461 deletions(-)
delete mode 100644 test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/hotspot/WriterThread.java
delete mode 100644 test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/hotspot/WriterThreads.java
delete mode 100644 test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestSafepointWhilePrinting.java
delete mode 100644 test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/safepoint_while_printing_hotspot_pid.log
diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/hotspot/CompilePhaseBlock.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/hotspot/CompilePhaseBlock.java
index 16cc62f9c57be..b97c56a57203c 100644
--- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/hotspot/CompilePhaseBlock.java
+++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/hotspot/CompilePhaseBlock.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, 2024, 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
@@ -29,7 +29,6 @@
* This class represents a single compile phase block of a {@link LoggedMethod}.
*/
class CompilePhaseBlock {
- public static final String SAFEPOINT_WHILE_PRINTING_MESSAGE = "";
/**
* Dummy object for a block that we do not need to parse.
@@ -38,11 +37,6 @@ class CompilePhaseBlock {
private final CompilePhase compilePhase;
private final StringBuilder builder;
- /**
- * Stores an incomplete line that was interrupted by a safepoint.
- * Needs to be merged with the immediately following line.
- */
- private String incompleteLine = "";
public CompilePhaseBlock(CompilePhase compilePhase) {
this.compilePhase = compilePhase;
@@ -92,35 +86,14 @@ public static boolean isBlockEndLine(String line) {
}
public void addLine(String line) {
- line = mergeWithIncompleteLine(line);
- if (line.endsWith(SAFEPOINT_WHILE_PRINTING_MESSAGE)) {
- line = removeSafepointMessage(line);
- incompleteLine = line;
- } else {
- appendLine(line);
- }
- }
-
- private String mergeWithIncompleteLine(String line) {
- if (!incompleteLine.isEmpty()) {
- line = incompleteLine + line;
- incompleteLine = "";
- }
- return line;
- }
+ builder.append(escapeXML(line)).append(System.lineSeparator());
- private static String removeSafepointMessage(String line) {
- return line.substring(0, line.lastIndexOf(SAFEPOINT_WHILE_PRINTING_MESSAGE));
}
public String content() {
return builder.toString();
}
- private void appendLine(String line) {
- builder.append(escapeXML(line)).append(System.lineSeparator());
- }
-
private static String escapeXML(String line) {
if (line.contains("&")) {
line = line.replace("<", "<");
diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/hotspot/State.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/hotspot/State.java
index 75d6b060cb243..49f25674dbf6c 100644
--- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/hotspot/State.java
+++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/hotspot/State.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, 2024, 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
@@ -29,8 +29,6 @@
* This class holds the current state of the parsing of the hotspot_pid* file.
*/
class State {
- private final WriterThreads writerThreads;
- private WriterThread writerThread;
private final CompileQueueMessages compileQueueMessages;
private final LoggedMethods loggedMethods;
private LoggedMethod loggedMethod = LoggedMethod.DONT_CARE;
@@ -38,7 +36,6 @@ class State {
public State(String testClassName, TestMethods testMethods) {
this.compileQueueMessages = new CompileQueueMessages(testClassName, testMethods);
this.loggedMethods = new LoggedMethods();
- this.writerThreads = new WriterThreads();
}
public LoggedMethods loggedMethods() {
@@ -46,9 +43,7 @@ public LoggedMethods loggedMethods() {
}
public void update(String line) {
- if (WriterThread.isWriterThreadLine(line)) {
- processWriterThreadLine(line);
- } else if (compileQueueMessages.isTestMethodQueuedLine(line)) {
+ if (compileQueueMessages.isTestMethodQueuedLine(line)) {
processCompileQueueLine(line);
} else if (CompilePhaseBlock.isBlockStartLine(line)) {
processBlockStartLine(line);
@@ -59,15 +54,6 @@ public void update(String line) {
}
}
- private void processWriterThreadLine(String line) {
- if (loggedMethod.hasActiveBlock()) {
- // The current compile phase block was interrupted due to a safepoint. Save and restore later.
- writerThread.saveLoggedMethod(loggedMethod);
- }
- writerThread = writerThreads.parse(line);
- loggedMethod = writerThread.restoreLoggedMethod();
- }
-
private void processCompileQueueLine(String line) {
String methodName = compileQueueMessages.parse(line);
loggedMethods.registerMethod(methodName);
diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/hotspot/WriterThread.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/hotspot/WriterThread.java
deleted file mode 100644
index 302bd203277e1..0000000000000
--- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/hotspot/WriterThread.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2023, 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.lib.ir_framework.driver.irmatching.parser.hotspot;
-
-/**
- * This class represents a writer thread that emits log messages with LogCompilation. It saves and restores a currently
- * parsed {@link LoggedMethod} if a {@link CompilePhaseBlock} was interrupted before reaching the block end tag.
- *
- * @see LoggedMethod
- * @see CompilePhaseBlock
- */
-class WriterThread {
- private LoggedMethod loggedMethod = LoggedMethod.DONT_CARE;
-
- public static boolean isWriterThreadLine(String line) {
- return line.startsWith(" mapIdToThread = new HashMap<>();
-
- WriterThread parse(String line) {
- int writerThreadId = parseWriterThreadId(line);
- return mapIdToThread.computeIfAbsent(writerThreadId, c -> new WriterThread());
- }
-
- private static int parseWriterThreadId(String line) {
- Pattern pattern = Pattern.compile("='(\\d+)'");
- Matcher matcher = pattern.matcher(line);
- TestFramework.check(matcher.find(), "should find writer thread id");
- return Integer.parseInt(matcher.group(1));
- }
-}
diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestSafepointWhilePrinting.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestSafepointWhilePrinting.java
deleted file mode 100644
index 99de3c1510ca7..0000000000000
--- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestSafepointWhilePrinting.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (c) 2023, 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.testlibrary_tests.ir_framework.tests;
-
-import compiler.lib.ir_framework.CompilePhase;
-import compiler.lib.ir_framework.IR;
-import compiler.lib.ir_framework.IRNode;
-import compiler.lib.ir_framework.Test;
-import compiler.lib.ir_framework.driver.irmatching.IRMatcher;
-import compiler.lib.ir_framework.driver.irmatching.Matchable;
-import compiler.lib.ir_framework.driver.irmatching.parser.TestClassParser;
-import jdk.test.lib.Utils;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.StandardCopyOption;
-
-/*
- * @test
- * @bug 8300273
- * @requires vm.debug == true & vm.flagless
- * @summary Test TestClassParser such that it correctly parses the hotspot_pid* files with safepoint interruption messages
- * @library /test/lib /testlibrary_tests /
- * @build jdk.test.whitebox.WhiteBox
- * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
- * @run junit/othervm -Xbootclasspath/a:. -DSkipWhiteBoxInstall=true -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
- * -XX:+WhiteBoxAPI compiler.testlibrary_tests.ir_framework.tests.TestSafepointWhilePrinting
- */
-public class TestSafepointWhilePrinting {
- static int iFld;
-
- @org.junit.Test
- public void test() throws IOException {
- String hotspotPidFileName = "safepoint_while_printing_hotspot_pid.log";
- Path hotspotPidFilePath = Paths.get(Utils.TEST_SRC).resolve(hotspotPidFileName);
- // Copy file to current workdir
- Files.copy(hotspotPidFilePath, Paths.get("").resolve(hotspotPidFileName),
- StandardCopyOption.REPLACE_EXISTING);
-
- String irEncoding =
- """
- ##### IRMatchRulesEncoding - used by TestFramework #####
- ,{comma separated applied @IR rule ids}
- test1,1
- test2,1
- testSafepointInBlock,1
- testQueueInBlock1,1
- testQueueInBlock2,1
- testDoubleInterruptOuter,1
- testDoubleInterruptMiddle,1
- testDoubleInterruptInner,1
- testCompilePhaseBackToBackFirst,1
- testCompilePhaseBackToBackLast,1
- ----- END -----
- ##### IRMatchingVMInfo - used by TestFramework #####
- :
- cpuFeatures:empty_cpu_info
- MaxVectorSize:64
- MaxVectorSizeIsDefault:1
- LoopMaxUnroll:64
- UseAVX:1
- UseAVXIsDefault:1
- ----- END VMInfo -----
- """;
- TestClassParser testClassParser = new TestClassParser(TestSafepointWhilePrinting.class);
- Matchable testClassMatchable = testClassParser.parse(hotspotPidFileName, irEncoding);
- IRMatcher matcher = new IRMatcher(testClassMatchable);
- matcher.match();
- }
-
- @Test
- @IR(counts = {IRNode.CMP_UL3, "1"})
- public void test1() {
- iFld = 34;
- }
-
- @Test
- @IR(counts = {IRNode.CMP_UL3, "1"})
- public void test2() {
- iFld = 34;
- }
-
- @Test
- @IR(counts = {"testSafepointInBlock @ bci:-1", "1"}, phase = CompilePhase.PRINT_IDEAL)
- public void testSafepointInBlock() {
- iFld = 34;
- }
-
- @Test
- @IR(counts = {"testQueueInBlock1 @ bci:-1", "1"}, phase = CompilePhase.PRINT_IDEAL)
- public void testQueueInBlock1() {
- iFld = 34;
- }
-
- @Test
- @IR(counts = {"testQueueInBlock2 @ bci:-1", "1"}, phase = CompilePhase.PRINT_IDEAL)
- public void testQueueInBlock2() {
- iFld = 34;
- }
- @Test
- @IR(counts = {"!jvms: TestSafepointWhilePrinting::testDoubleInterruptOuter", "1"}, phase = CompilePhase.PRINT_IDEAL)
- public void testDoubleInterruptOuter() {
- iFld = 34;
- }
-
- @Test
- @IR(counts = {"testDoubleInterruptMiddle @ bci:-1", "1", IRNode.CMP_UL3, "1"}, phase = CompilePhase.PRINT_IDEAL)
- public void testDoubleInterruptMiddle() {
- iFld = 34;
- }
-
- @Test
- @IR(counts = {IRNode.CON_L, "1"}, phase = CompilePhase.PRINT_IDEAL)
- public void testDoubleInterruptInner() {
- iFld = 34;
- }
-
- @Test
- @IR(counts = {"(line 115)", "1", IRNode.CMP_UL3, "1"}, phase = {CompilePhase.AFTER_PARSING, CompilePhase.BEFORE_MATCHING})
- public void testCompilePhaseBackToBackFirst() {
- iFld = 34;
- }
-
- @Test
- @IR(counts = {"(line 115)", "1", IRNode.CMP_UL3, "1"}, phase = {CompilePhase.AFTER_PARSING, CompilePhase.BEFORE_MATCHING})
- public void testCompilePhaseBackToBackLast() {
- iFld = 34;
- }
-}
diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/safepoint_while_printing_hotspot_pid.log b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/safepoint_while_printing_hotspot_pid.log
deleted file mode 100644
index 2bdd2540f08a5..0000000000000
--- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/safepoint_while_printing_hotspot_pid.log
+++ /dev/null
@@ -1,163 +0,0 @@
-
- 1682 967 b 3 jdk.test.lib.Asserts::assertEquals (7 bytes)
-
-
-
-
-
-
-
-
-
- 1716 995 3 compiler.testlibrary_tests.ir_framework.tests.TestSafepointWhilePrinting::compareLongWithImm5 (8 bytes) made not entrant
-
- 1716 1018 b 4 compiler.testlibrary_tests.ir_framework.tests.TestSafepointWhilePrinting::test1 (8 bytes)
-
-
-
- 1716 1008 b 3 java.util.Arrays::copyOfRange (90 bytes)
-
- 1716 1013 b 4 compiler.testlibrary_tests.ir_framework.tests.TestSafepointWhilePrinting::test2 (8 bytes)
-
-
-
-
-AFTER: print_ideal
- 0 Root === 0 26 [[ 0 1 3 24 ]] inner
- 3 Start === 3 0 [[ 3 5 6 7 8 9 11 ]] #{0:control, 1:abIO, 2:memory, 3:rawptr:BotPTR, 4:return_address, 5:compiler/intrinsics/TestSafepointWhilePrinting:NotNull *, 6:long, 7:half}
- 5 Parm === 3 [[ 26 ]] Control !jvms: TestSafepointWhilePrinting::test1 @ bci:-1 (line 115)
- 6 Parm === 3 [[ 26 ]] I_O !jvms:
-
-
-AFTER: print_ideal
- 0 Root === 0 26 [[ 0 1 3 24 ]] inner
- 3 Start === 3 0 [[ 3 5 6 7 8 9 11 ]] #{0:control, 1:abIO, 2:memory, 3:rawptr:BotPTR, 4:return_address, 5:compiler/intrinsics/TestSafepointWhilePrinting:NotNull *, 6:long, 7:half}
- 5 Parm === 3 [[ 26 ]] Control !jvms: TestSafepointWhilePrinting::test2 @ bci:-1 (line 109)
- 6 Parm === 3 [[ 26 ]] I_O !jvms: TestSafepointWhilePrinting::test2 @ bci:-1 (line 109)
- 7 Parm === 3 [[ 26 ]] Memory Memory: @BotPTR *+bot, idx=Bot; !jvms: TestSafepointWhilePrinting::test2 @ bci:-1 (line 109)
- 8 Parm === 3 [[ 26 ]] FramePtr !jvms: TestSafepointWhilePrinting::test2 @ bci:-1 (line 109)
- 9 Parm === 3 [[ 26 ]] ReturnAdr !jvms: TestSafepointWhilePrinting::test2 @ bci:-1 (line 109)
- 11 Parm === 3 [[ 25 ]] Parm1: long !jvms: TestSafepointWhilePrinting::test2 @ bci:-1 (line 109)
- 24 ConL === 0 [[ 25 ]] #long:42
- 25 CmpUL3 === _ 11 24 [[ 26 ]] !jvms: TestSafepointWhilePrinting::test2 @ bci:4 (line 109)
- 26 Return === 5 6 7 8 9 returns 25 [[ 0 ]]
-
-
- TestSafepointWhilePrinting::test1 @ bci:-1 (line 115)
- 7 Parm === 3 [[ 26 ]] Memory Memory: @BotPTR *+bot, idx=Bot; !jvms: TestSafepointWhilePrinting::test1 @ bci:-1 (line 115)
- 8 Parm === 3 [[ 26 ]] FramePtr !jvms: TestSafepointWhilePrinting::test1 @ bci:-1 (line 115)
- 9 Parm === 3 [[ 26 ]] ReturnAdr !jvms: TestSafepointWhilePrinting::test1 @ bci:-1 (line 115)
- 11 Parm === 3 [[ 25 ]] Parm1: long !jvms: TestSafepointWhilePrinting::test1 @ bci:-1 (line 115)
- 24 ConL === 0 [[ 25 ]] #long:172032
- 25 CmpUL3 === _ 11 24 [[ 26 ]] !jvms: TestSafepointWhilePrinting::test1 @ bci:4 (line 115)
- 26 Return === 5 6 7 8 9 returns 25 [[ 0 ]]
-
-
-
-
- 1784 993 3 compiler.intrinsics.TestCompareUnsigned::compareLongWithImm3 (8 bytes) made not entrant
- 1784 1013 b 4 compiler.intrinsics.TestCompareUnsigned::compareLongWithImm1 (8 bytes)
-
-AFTER: print_ideal
- 0 Root === 0 26 [[ 0 1 3 24 ]] inner
- 8 Parm === 3 [[ 26 ]] FramePtr !jvms: TestSafepointWhilePrinting::testSafepointInBlock
- @ bci:-1 (line 109)
- 24 ConL === 0 [[ 25 ]] #long:42
- 26 Return === 5 6 7 8 9 returns 25 [[ 0 ]]
-
-
-
-
-
-AFTER: print_ideal
- 0 Root === 0 26 [[ 0 1 3 24 ]] inner
- 8 Parm === 3 [[ 26 ]] FramePtr !jvms: TestSafepointWhilePrinting::testQueueInBlock1
-
-
-
- @ bci:-1 (line 109)
- 24 ConL === 0 [[ 25 ]] #long:42
- 26 Return === 5 6 7 8 9 returns 25 [[ 0 ]]
-
-
-AFTER: print_ideal
- 0 Root === 0 26 [[ 0 1 3 24 ]] inner
- 8 Parm === 3 [[ 26 ]] FramePtr !jvms: TestSafepointWhilePrinting::testQueueInBlock2
- @ bci:-1 (line 109)
- 24 ConL === 0 [[ 25 ]] #long:42
- 26 Return === 5 6 7 8 9 returns 25 [[ 0 ]]
-
-
-
-
-
-
-
-AFTER: print_ideal
- 0 Root === 0 26 [[ 0 1 3 24 ]] inner
- 3 Start === 3 0 [[ 3 5 6 7 8 9 11 ]] #{0:control, 1:abIO, 2:memory, 3:rawptr:BotPTR, 4:return_address, 5:compiler/intrinsics/TestSafepointWhilePrinting:NotNull *, 6:long, 7:half}
- 6 Parm === 3 [[ 26 ]] I_O !jvms:
-
-
-AFTER: print_ideal
- 0 Root === 0 26 [[ 0 1 3 24 ]] inner
- 8 Parm === 3 [[ 26 ]] FramePtr !jvms: TestSafepointWhilePrinting::testDoubleInterruptMiddle
- @ bci:-1 (line 109)
- 25 Cmp
-
-
-
-
- 24 ConL === 0 [[ 25 ]] #long:42
- 26 Return === 5 6 7 8 9 returns 25 [[ 0 ]]
-
-
-UL3 === _ 11 24 [[ 26 ]] !jvms: TestSafepointWhilePrinting::test2 @ bci:4 (line 109)
- 26 Return === 5 6 7 8 9 returns 25 [[ 0 ]]
-
-
- TestSafepointWhilePrinting::testDoubleInterruptOuter @ bci:-1 (line 115)
- 7 Parm === 3 [[ 26 ]] Memory Memory: @BotPTR *+bot, idx=Bot; !jvms: TestSafepointWhilePrinting::test1 @ bci:-1 (line 115)
- 8 Parm === 3 [[ 26 ]] FramePtr !jvms: TestSafepointWhilePrinting::test1 @ bci:-1 (line 115)
- 9 Parm === 3 [[ 26 ]] ReturnAdr !jvms: TestSafepointWhilePrinting::test1 @ bci:-1 (line 115)
- 11 Parm === 3 [[ 25 ]] Parm1: long !jvms: TestSafepointWhilePrinting::test1 @ bci:-1 (line 115)
- 24 ConL === 0 [[ 25 ]] #long:172032
- 25 CmpUL3 === _ 11 24 [[ 26 ]] !jvms: TestSafepointWhilePrinting::test1 @ bci:4 (line 115)
- 26 Return === 5 6 7 8 9 returns 25 [[ 0 ]]
-
-
-
-
-
- 24 ConL === 0 [[ 25 ]] #long:172032
- 25 CmpUL
-
-
-
- 24 ConL === 0 [[ 25 ]] #long:172032
- 25 CmpUL3 === _ 11 24 [[ 26 ]] !jvms: TestSafepointWhilePrinting::test1 @ bci:4 (line 115)
-
-
- 24 ConL === 0 [[ 25 ]] #long:172032
- 25 CmpU
-
-3 === _ 11 24 [[ 26 ]] !jvms: TestSafepointWhilePrinting::test1 @ bci:4 (
-
-L3 === _ 11 24 [[ 26 ]] !jvms: TestSafepointWhilePrinting::test1 @ bci:4 (line
-
-line 115)
-
-
-
-
-
- 24 ConL === 0 [[ 25 ]] #long:172032
- 25 CmpU
-
-115)
-
-
-L3 === _ 11 24 [[ 26 ]] !jvms: TestSafepointWhilePrinting::test1 @ bci:4 (line 115)
-
\ No newline at end of file
From fc047508170ab666857d740ccf541c2c3b612277 Mon Sep 17 00:00:00 2001
From: Fredrik Bredberg
Date: Mon, 8 Jan 2024 13:30:23 +0000
Subject: [PATCH 008/153] 8321371: SpinPause() not implemented for
bsd_aarch64/macOS
Reviewed-by: eosterlund, dholmes, dcubed, eastigeevich, shade
---
.../os_cpu/bsd_aarch64/os_bsd_aarch64.cpp | 34 ++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.cpp b/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.cpp
index df5a42fd118b9..fbd7c4eccd403 100644
--- a/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.cpp
+++ b/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.cpp
@@ -514,7 +514,39 @@ static inline void atomic_copy64(const volatile void *src, volatile void *dst) {
extern "C" {
int SpinPause() {
- return 0;
+ // We don't use StubRoutines::aarch64::spin_wait stub in order to
+ // avoid a costly call to os::current_thread_enable_wx() on MacOS.
+ // We should return 1 if SpinPause is implemented, and since there
+ // will be a sequence of 11 instructions for NONE and YIELD and 12
+ // instructions for NOP and ISB, SpinPause will always return 1.
+ uint64_t br_dst;
+ const int instructions_per_case = 2;
+ int64_t off = VM_Version::spin_wait_desc().inst() * instructions_per_case * Assembler::instruction_size;
+
+ assert(VM_Version::spin_wait_desc().inst() >= SpinWait::NONE &&
+ VM_Version::spin_wait_desc().inst() <= SpinWait::YIELD, "must be");
+ assert(-1 == SpinWait::NONE, "must be");
+ assert( 0 == SpinWait::NOP, "must be");
+ assert( 1 == SpinWait::ISB, "must be");
+ assert( 2 == SpinWait::YIELD, "must be");
+
+ asm volatile(
+ " adr %[d], 20 \n" // 20 == PC here + 5 instructions => address
+ // to entry for case SpinWait::NOP
+ " add %[d], %[d], %[o] \n"
+ " br %[d] \n"
+ " b SpinPause_return \n" // case SpinWait::NONE (-1)
+ " nop \n" // padding
+ " nop \n" // case SpinWait::NOP ( 0)
+ " b SpinPause_return \n"
+ " isb \n" // case SpinWait::ISB ( 1)
+ " b SpinPause_return \n"
+ " yield \n" // case SpinWait::YIELD ( 2)
+ "SpinPause_return: \n"
+ : [d]"=&r"(br_dst)
+ : [o]"r"(off)
+ : "memory");
+ return 1;
}
void _Copy_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) {
From 29397d29baac3b29083b1b5d6b2cb06e456af0c3 Mon Sep 17 00:00:00 2001
From: Fredrik Bredberg
Date: Mon, 8 Jan 2024 13:32:17 +0000
Subject: [PATCH 009/153] 8320317: ObjectMonitor NotRunnable is not really an
optimization
Reviewed-by: eosterlund, dholmes, shade, dcubed
---
src/hotspot/share/runtime/objectMonitor.cpp | 67 ---------------------
src/hotspot/share/runtime/objectMonitor.hpp | 1 -
2 files changed, 68 deletions(-)
diff --git a/src/hotspot/share/runtime/objectMonitor.cpp b/src/hotspot/share/runtime/objectMonitor.cpp
index 2214713aa4bf6..a8e2e571c5bbd 100644
--- a/src/hotspot/share/runtime/objectMonitor.cpp
+++ b/src/hotspot/share/runtime/objectMonitor.cpp
@@ -1844,10 +1844,6 @@ int ObjectMonitor::TrySpin(JavaThread* current) {
ctr = _SpinDuration;
if (ctr <= 0) return 0;
- if (NotRunnable(current, static_cast(owner_raw()))) {
- return 0;
- }
-
// We're good to spin ... spin ingress.
// CONSIDER: use Prefetch::write() to avoid RTS->RTO upgrades
// when preparing to LD...CAS _owner, etc and the CAS is likely
@@ -1933,13 +1929,6 @@ int ObjectMonitor::TrySpin(JavaThread* current) {
}
prv = ox;
- // Abort the spin if the owner is not executing.
- // The owner must be executing in order to drop the lock.
- // Spinning while the owner is OFFPROC is idiocy.
- // Consider: ctr -= RunnablePenalty ;
- if (NotRunnable(current, ox)) {
- goto Abort;
- }
if (_succ == nullptr) {
_succ = current;
}
@@ -1972,62 +1961,6 @@ int ObjectMonitor::TrySpin(JavaThread* current) {
return 0;
}
-// NotRunnable() -- informed spinning
-//
-// Don't bother spinning if the owner is not eligible to drop the lock.
-// Spin only if the owner thread is _thread_in_Java or _thread_in_vm.
-// The thread must be runnable in order to drop the lock in timely fashion.
-// If the _owner is not runnable then spinning will not likely be
-// successful (profitable).
-//
-// Beware -- the thread referenced by _owner could have died
-// so a simply fetch from _owner->_thread_state might trap.
-// Instead, we use SafeFetchXX() to safely LD _owner->_thread_state.
-// Because of the lifecycle issues, the _thread_state values
-// observed by NotRunnable() might be garbage. NotRunnable must
-// tolerate this and consider the observed _thread_state value
-// as advisory.
-//
-// Beware too, that _owner is sometimes a BasicLock address and sometimes
-// a thread pointer.
-// Alternately, we might tag the type (thread pointer vs basiclock pointer)
-// with the LSB of _owner. Another option would be to probabilistically probe
-// the putative _owner->TypeTag value.
-//
-// Checking _thread_state isn't perfect. Even if the thread is
-// in_java it might be blocked on a page-fault or have been preempted
-// and sitting on a ready/dispatch queue.
-//
-// The return value from NotRunnable() is *advisory* -- the
-// result is based on sampling and is not necessarily coherent.
-// The caller must tolerate false-negative and false-positive errors.
-// Spinning, in general, is probabilistic anyway.
-
-
-int ObjectMonitor::NotRunnable(JavaThread* current, JavaThread* ox) {
- // Check ox->TypeTag == 2BAD.
- if (ox == nullptr) return 0;
-
- // Avoid transitive spinning ...
- // Say T1 spins or blocks trying to acquire L. T1._Stalled is set to L.
- // Immediately after T1 acquires L it's possible that T2, also
- // spinning on L, will see L.Owner=T1 and T1._Stalled=L.
- // This occurs transiently after T1 acquired L but before
- // T1 managed to clear T1.Stalled. T2 does not need to abort
- // its spin in this circumstance.
- intptr_t BlockedOn = SafeFetchN((intptr_t *) &ox->_Stalled, intptr_t(1));
-
- if (BlockedOn == 1) return 1;
- if (BlockedOn != 0) {
- return BlockedOn != intptr_t(this) && owner_raw() == ox;
- }
-
- assert(sizeof(ox->_thread_state == sizeof(int)), "invariant");
- int jst = SafeFetch32((int *) &ox->_thread_state, -1);;
- // consider also: jst != _thread_in_Java -- but that's overspecific.
- return jst == _thread_blocked || jst == _thread_in_native;
-}
-
// -----------------------------------------------------------------------------
// WaitSet management ...
diff --git a/src/hotspot/share/runtime/objectMonitor.hpp b/src/hotspot/share/runtime/objectMonitor.hpp
index ab48bd19b5e43..281067fe55c6b 100644
--- a/src/hotspot/share/runtime/objectMonitor.hpp
+++ b/src/hotspot/share/runtime/objectMonitor.hpp
@@ -353,7 +353,6 @@ class ObjectMonitor : public CHeapObj {
void ReenterI(JavaThread* current, ObjectWaiter* current_node);
void UnlinkAfterAcquire(JavaThread* current, ObjectWaiter* current_node);
int TryLock(JavaThread* current);
- int NotRunnable(JavaThread* current, JavaThread* Owner);
int TrySpin(JavaThread* current);
void ExitEpilog(JavaThread* current, ObjectWaiter* Wakee);
From c90768c93b26771bb8f4bdbe855d054ad089b337 Mon Sep 17 00:00:00 2001
From: Thomas Stuefe
Date: Mon, 8 Jan 2024 13:47:43 +0000
Subject: [PATCH 010/153] 8318444: Write details about compilation bailouts
into crash reports
Reviewed-by: thartmann, chagedorn
---
src/hotspot/share/c1/c1_Compilation.cpp | 8 +-
src/hotspot/share/c1/c1_Compilation.hpp | 3 +
src/hotspot/share/ci/ciEnv.hpp | 4 +-
.../share/compiler/compilationFailureInfo.cpp | 121 ++++++++++++++++++
.../share/compiler/compilationFailureInfo.hpp | 57 +++++++++
.../share/compiler/compiler_globals.hpp | 4 +
src/hotspot/share/opto/compile.cpp | 12 ++
src/hotspot/share/opto/compile.hpp | 7 +-
src/hotspot/share/runtime/os.cpp | 19 ++-
src/hotspot/share/runtime/os.hpp | 1 +
src/hotspot/share/utilities/vmError.cpp | 7 +
11 files changed, 231 insertions(+), 12 deletions(-)
create mode 100644 src/hotspot/share/compiler/compilationFailureInfo.cpp
create mode 100644 src/hotspot/share/compiler/compilationFailureInfo.hpp
diff --git a/src/hotspot/share/c1/c1_Compilation.cpp b/src/hotspot/share/c1/c1_Compilation.cpp
index 53fb5fbcf9efe..4890cec5bfc7b 100644
--- a/src/hotspot/share/c1/c1_Compilation.cpp
+++ b/src/hotspot/share/c1/c1_Compilation.cpp
@@ -33,10 +33,12 @@
#include "c1/c1_ValueMap.hpp"
#include "c1/c1_ValueStack.hpp"
#include "code/debugInfoRec.hpp"
+#include "compiler/compilationFailureInfo.hpp"
#include "compiler/compilationMemoryStatistic.hpp"
#include "compiler/compilerDirectives.hpp"
#include "compiler/compileLog.hpp"
#include "compiler/compileTask.hpp"
+#include "compiler/compiler_globals.hpp"
#include "compiler/compilerDirectives.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/sharedRuntime.hpp"
@@ -582,6 +584,7 @@ Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* metho
, _has_monitors(false)
, _install_code(install_code)
, _bailout_msg(nullptr)
+, _first_failure_details(nullptr)
, _exception_info_list(nullptr)
, _allocator(nullptr)
, _code(buffer_blob)
@@ -626,7 +629,7 @@ Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* metho
Compilation::~Compilation() {
// simulate crash during compilation
assert(CICrashAt < 0 || (uintx)_env->compile_id() != (uintx)CICrashAt, "just as planned");
-
+ delete _first_failure_details;
_env->set_compiler_data(nullptr);
}
@@ -652,6 +655,9 @@ void Compilation::bailout(const char* msg) {
// keep first bailout message
if (PrintCompilation || PrintBailouts) tty->print_cr("compilation bailout: %s", msg);
_bailout_msg = msg;
+ if (CaptureBailoutInformation) {
+ _first_failure_details = new CompilationFailureInfo(msg);
+ }
}
}
diff --git a/src/hotspot/share/c1/c1_Compilation.hpp b/src/hotspot/share/c1/c1_Compilation.hpp
index b0753a94d1ba7..f344695509ee1 100644
--- a/src/hotspot/share/c1/c1_Compilation.hpp
+++ b/src/hotspot/share/c1/c1_Compilation.hpp
@@ -34,6 +34,7 @@
#include "memory/resourceArea.hpp"
#include "runtime/deoptimization.hpp"
+class CompilationFailureInfo;
class CompilationResourceObj;
class XHandlers;
class ExceptionInfo;
@@ -85,6 +86,7 @@ class Compilation: public StackObj {
bool _has_monitors; // Fastpath monitors detection for Continuations
bool _install_code;
const char* _bailout_msg;
+ CompilationFailureInfo* _first_failure_details; // Details for the first failure happening during compilation
bool _oom;
ExceptionInfoList* _exception_info_list;
ExceptionHandlerTable _exception_handler_table;
@@ -212,6 +214,7 @@ class Compilation: public StackObj {
void bailout(const char* msg);
bool bailed_out() const { return _bailout_msg != nullptr; }
const char* bailout_msg() const { return _bailout_msg; }
+ const CompilationFailureInfo* first_failure_details() const { return _first_failure_details; }
static uint desired_max_code_buffer_size() {
return (uint)NMethodSizeLimit; // default 64K
diff --git a/src/hotspot/share/ci/ciEnv.hpp b/src/hotspot/share/ci/ciEnv.hpp
index 5c39cb58f9ff1..fc12cc0259b71 100644
--- a/src/hotspot/share/ci/ciEnv.hpp
+++ b/src/hotspot/share/ci/ciEnv.hpp
@@ -362,7 +362,7 @@ class ciEnv : StackObj {
// The compiler task which has created this env.
// May be useful to find out compile_id, comp_level, etc.
- CompileTask* task() { return _task; }
+ CompileTask* task() const { return _task; }
// Handy forwards to the task:
int comp_level(); // task()->comp_level()
@@ -444,7 +444,7 @@ class ciEnv : StackObj {
static ciEnv* current(CompilerThread *thread) { return thread->env(); }
// Per-compiler data. (Used by C2 to publish the Compile* pointer.)
- void* compiler_data() { return _compiler_data; }
+ void* compiler_data() const { return _compiler_data; }
void set_compiler_data(void* x) { _compiler_data = x; }
// Notice that a method has been inlined in the current compile;
diff --git a/src/hotspot/share/compiler/compilationFailureInfo.cpp b/src/hotspot/share/compiler/compilationFailureInfo.cpp
new file mode 100644
index 0000000000000..e3f3353589e54
--- /dev/null
+++ b/src/hotspot/share/compiler/compilationFailureInfo.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, Red Hat, Inc. and/or its affiliates.
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+
+#if defined(COMPILER1) || defined(COMPILER2)
+
+#ifdef COMPILER1
+#include "c1/c1_Compilation.hpp"
+#endif
+#include "ci/ciEnv.hpp"
+#include "compiler/abstractCompiler.hpp"
+#include "compiler/compilationFailureInfo.hpp"
+#include "compiler/compileTask.hpp"
+#ifdef COMPILER2
+#include "opto/node.hpp"
+#include "opto/compile.hpp"
+#endif
+#include "runtime/os.hpp"
+#include "utilities/ostream.hpp"
+#include "utilities/nativeCallStack.hpp"
+
+CompilationFailureInfo::CompilationFailureInfo(const char* failure_reason) :
+ _stack(2),
+ _failure_reason(os::strdup(failure_reason)),
+ _elapsed_seconds(os::elapsedTime()),
+ _compile_id(ciEnv::current()->task()->compile_id())
+{}
+
+CompilationFailureInfo::~CompilationFailureInfo() {
+ os::free(_failure_reason);
+}
+
+void CompilationFailureInfo::print_on(outputStream* st) const {
+ st->print(" Time: ");
+ os::print_elapsed_time(st, _elapsed_seconds);
+ st->print_cr(" Compile id: %d", _compile_id);
+ st->print_cr(" Reason: '%s'", _failure_reason);
+ st->print_cr(" Callstack: ");
+ _stack.print_on(st);
+ st->cr();
+}
+
+// Convenience function to print current compile failure iff
+// current thread is compiler thread and there is a pending failure.
+// Otherwise prints nothing.
+bool CompilationFailureInfo::print_pending_compilation_failure(outputStream* st) {
+
+ const CompilationFailureInfo* info = nullptr;
+
+ // Carefully tiptoeing because we are called from the error reporter and
+ // nothing is certain.
+
+ const Thread* const t = Thread::current();
+ if (t == nullptr || !t->is_Compiler_thread()) {
+ return false;
+ }
+
+ const ciEnv* const env = ciEnv::current();
+ if (env == nullptr) {
+ return false;
+ }
+
+ const CompileTask* const task = env->task();
+ if (task == nullptr) {
+ return false;
+ }
+
+ const AbstractCompiler* const compiler = task->compiler();
+ if (compiler == nullptr) {
+ return false;
+ }
+
+#ifdef COMPILER1
+ if (compiler->type() == compiler_c1) {
+ const Compilation* const C = (Compilation*)env->compiler_data();
+ if (C != nullptr) {
+ info = C->first_failure_details();
+ }
+ }
+#endif
+#ifdef COMPILER2
+ if (compiler->type() == compiler_c2) {
+ const Compile* const C = (Compile*)env->compiler_data();
+ if (C != nullptr) {
+ info = C->first_failure_details();
+ }
+ }
+#endif
+
+ if (info != nullptr) {
+ st->print_cr("Pending compilation failure details for thread " PTR_FORMAT ":", p2i(t));
+ info->print_on(st);
+ }
+
+ return true;
+}
+
+#endif // defined(COMPILER1) || defined(COMPILER2)
diff --git a/src/hotspot/share/compiler/compilationFailureInfo.hpp b/src/hotspot/share/compiler/compilationFailureInfo.hpp
new file mode 100644
index 0000000000000..3de62eb69da5a
--- /dev/null
+++ b/src/hotspot/share/compiler/compilationFailureInfo.hpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, Red Hat, Inc. and/or its affiliates.
+ * 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.
+ *
+ */
+
+#ifndef SHARE_COMPILER_COMPILATIONFAILUREINFO_HPP
+#define SHARE_COMPILER_COMPILATIONFAILUREINFO_HPP
+
+#if defined(COMPILER1) || defined(COMPILER2)
+
+#include "memory/allocation.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/nativeCallStack.hpp"
+
+class outputStream;
+class Symbol;
+
+class CompilationFailureInfo : public CHeapObj {
+ NativeCallStack _stack;
+ char* const _failure_reason;
+ const double _elapsed_seconds;
+ const int _compile_id;
+public:
+ CompilationFailureInfo(const char* failure_reason);
+ ~CompilationFailureInfo();
+ void print_on(outputStream* st) const;
+
+ // Convenience function to print, safely, current compile failure iff
+ // current thread is compiler thread and there is an ongoing compilation
+ // and a pending failure.
+ // Otherwise prints nothing.
+ static bool print_pending_compilation_failure(outputStream* st);
+};
+
+#endif // defined(COMPILER1) || defined(COMPILER2)
+
+#endif // SHARE_COMPILER_COMPILATIONFAILUREINFO_HPP
diff --git a/src/hotspot/share/compiler/compiler_globals.hpp b/src/hotspot/share/compiler/compiler_globals.hpp
index 7f1f08b68ef65..71b475392cf69 100644
--- a/src/hotspot/share/compiler/compiler_globals.hpp
+++ b/src/hotspot/share/compiler/compiler_globals.hpp
@@ -379,6 +379,10 @@
"Don't compile methods larger than this if " \
"+DontCompileHugeMethods") \
\
+ product(bool, CaptureBailoutInformation, trueInDebug, DIAGNOSTIC, \
+ "If compilation is stopped with an error, capture diagnostic " \
+ "information at the bailout point") \
+ \
// end of COMPILER_FLAGS
diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp
index 522654803aa19..30701c03707e9 100644
--- a/src/hotspot/share/opto/compile.cpp
+++ b/src/hotspot/share/opto/compile.cpp
@@ -29,9 +29,11 @@
#include "classfile/javaClasses.hpp"
#include "code/exceptionHandlerTable.hpp"
#include "code/nmethod.hpp"
+#include "compiler/compilationFailureInfo.hpp"
#include "compiler/compilationMemoryStatistic.hpp"
#include "compiler/compileBroker.hpp"
#include "compiler/compileLog.hpp"
+#include "compiler/compiler_globals.hpp"
#include "compiler/disassembler.hpp"
#include "compiler/oopMap.hpp"
#include "gc/shared/barrierSet.hpp"
@@ -637,6 +639,7 @@ Compile::Compile( ciEnv* ci_env, ciMethod* target, int osr_bci,
_directive(directive),
_log(ci_env->log()),
_failure_reason(nullptr),
+ _first_failure_details(nullptr),
_intrinsics (comp_arena(), 0, 0, nullptr),
_macro_nodes (comp_arena(), 8, 0, nullptr),
_parse_predicates (comp_arena(), 8, 0, nullptr),
@@ -926,6 +929,7 @@ Compile::Compile( ciEnv* ci_env,
_directive(directive),
_log(ci_env->log()),
_failure_reason(nullptr),
+ _first_failure_details(nullptr),
_congraph(nullptr),
NOT_PRODUCT(_igv_printer(nullptr) COMMA)
_unique(0),
@@ -989,6 +993,11 @@ Compile::Compile( ciEnv* ci_env,
Code_Gen();
}
+Compile::~Compile() {
+ delete _print_inlining_stream;
+ delete _first_failure_details;
+};
+
//------------------------------Init-------------------------------------------
// Prepare for a single compilation
void Compile::Init(bool aliasing) {
@@ -4358,6 +4367,9 @@ void Compile::record_failure(const char* reason) {
if (_failure_reason == nullptr) {
// Record the first failure reason.
_failure_reason = reason;
+ if (CaptureBailoutInformation) {
+ _first_failure_details = new CompilationFailureInfo(reason);
+ }
}
if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) {
diff --git a/src/hotspot/share/opto/compile.hpp b/src/hotspot/share/opto/compile.hpp
index 01d0d727aa7b5..42f866df781c2 100644
--- a/src/hotspot/share/opto/compile.hpp
+++ b/src/hotspot/share/opto/compile.hpp
@@ -53,6 +53,7 @@ class Bundle;
class CallGenerator;
class CallStaticJavaNode;
class CloneMap;
+class CompilationFailureInfo;
class ConnectionGraph;
class IdealGraphPrinter;
class InlineTree;
@@ -363,6 +364,7 @@ class Compile : public Phase {
DirectiveSet* _directive; // Compiler directive
CompileLog* _log; // from CompilerThread
const char* _failure_reason; // for record_failure/failing pattern
+ CompilationFailureInfo* _first_failure_details; // Details for the first failure happening during compilation
GrowableArray _intrinsics; // List of intrinsics.
GrowableArray _macro_nodes; // List of nodes which need to be expanded before matching.
GrowableArray _parse_predicates; // List of Parse Predicates.
@@ -809,6 +811,7 @@ class Compile : public Phase {
CompileLog* log() const { return _log; }
bool failing() const { return _env->failing() || _failure_reason != nullptr; }
const char* failure_reason() const { return (_env->failing()) ? _env->failure_reason() : _failure_reason; }
+ const CompilationFailureInfo* first_failure_details() const { return _first_failure_details; }
bool failure_reason_is(const char* r) const {
return (r == _failure_reason) || (r != nullptr && _failure_reason != nullptr && strcmp(r, _failure_reason) == 0);
@@ -1125,9 +1128,7 @@ class Compile : public Phase {
int is_fancy_jump, bool pass_tls,
bool return_pc, DirectiveSet* directive);
- ~Compile() {
- delete _print_inlining_stream;
- };
+ ~Compile();
// Are we compiling a method?
bool has_method() { return method() != nullptr; }
diff --git a/src/hotspot/share/runtime/os.cpp b/src/hotspot/share/runtime/os.cpp
index 0eb4015a24659..dad10a7b9b4d8 100644
--- a/src/hotspot/share/runtime/os.cpp
+++ b/src/hotspot/share/runtime/os.cpp
@@ -1105,10 +1105,11 @@ void os::print_summary_info(outputStream* st, char* buf, size_t buflen) {
st->cr();
}
+static constexpr int secs_per_day = 86400;
+static constexpr int secs_per_hour = 3600;
+static constexpr int secs_per_min = 60;
+
void os::print_date_and_time(outputStream *st, char* buf, size_t buflen) {
- const int secs_per_day = 86400;
- const int secs_per_hour = 3600;
- const int secs_per_min = 60;
time_t tloc;
(void)time(&tloc);
@@ -1134,9 +1135,15 @@ void os::print_date_and_time(outputStream *st, char* buf, size_t buflen) {
}
double t = os::elapsedTime();
+ st->print(" elapsed time: ");
+ print_elapsed_time(st, t);
+ st->cr();
+}
+
+void os::print_elapsed_time(outputStream* st, double time) {
// NOTE: a crash using printf("%f",...) on Linux was historically noted here.
- int eltime = (int)t; // elapsed time in seconds
- int eltimeFraction = (int) ((t - eltime) * 1000000);
+ int eltime = (int)time; // elapsed time in seconds
+ int eltimeFraction = (int) ((time - eltime) * 1000000);
// print elapsed time in a human-readable format:
int eldays = eltime / secs_per_day;
@@ -1146,7 +1153,7 @@ void os::print_date_and_time(outputStream *st, char* buf, size_t buflen) {
int elmins = (eltime - day_secs - hour_secs) / secs_per_min;
int minute_secs = elmins * secs_per_min;
int elsecs = (eltime - day_secs - hour_secs - minute_secs);
- st->print_cr(" elapsed time: %d.%06d seconds (%dd %dh %dm %ds)", eltime, eltimeFraction, eldays, elhours, elmins, elsecs);
+ st->print("%d.%06d seconds (%dd %dh %dm %ds)", eltime, eltimeFraction, eldays, elhours, elmins, elsecs);
}
diff --git a/src/hotspot/share/runtime/os.hpp b/src/hotspot/share/runtime/os.hpp
index 8ecabde8ca144..f5346c9230753 100644
--- a/src/hotspot/share/runtime/os.hpp
+++ b/src/hotspot/share/runtime/os.hpp
@@ -789,6 +789,7 @@ class os: AllStatic {
static void print_siginfo(outputStream* st, const void* siginfo);
static void print_signal_handlers(outputStream* st, char* buf, size_t buflen);
static void print_date_and_time(outputStream* st, char* buf, size_t buflen);
+ static void print_elapsed_time(outputStream* st, double time);
static void print_user_info(outputStream* st);
static void print_active_locale(outputStream* st);
diff --git a/src/hotspot/share/utilities/vmError.cpp b/src/hotspot/share/utilities/vmError.cpp
index d586c6f4eeacf..d40504d6d2008 100644
--- a/src/hotspot/share/utilities/vmError.cpp
+++ b/src/hotspot/share/utilities/vmError.cpp
@@ -27,6 +27,7 @@
#include "precompiled.hpp"
#include "cds/metaspaceShared.hpp"
#include "code/codeCache.hpp"
+#include "compiler/compilationFailureInfo.hpp"
#include "compiler/compileBroker.hpp"
#include "compiler/disassembler.hpp"
#include "gc/shared/gcConfig.hpp"
@@ -1053,6 +1054,12 @@ void VMError::report(outputStream* st, bool _verbose) {
check_failing_cds_access(st, _siginfo);
st->cr();
+#if defined(COMPILER1) || defined(COMPILER2)
+ STEP_IF("printing pending compilation failure",
+ _verbose && _thread != nullptr && _thread->is_Compiler_thread())
+ CompilationFailureInfo::print_pending_compilation_failure(st);
+#endif
+
STEP_IF("printing registers", _verbose && _context != nullptr)
// printing registers
os::print_context(st, _context);
From 57a65fe436a3617d64bbf0b02d4c7f7c2551448f Mon Sep 17 00:00:00 2001
From: Jan Lahoda
Date: Mon, 8 Jan 2024 14:09:27 +0000
Subject: [PATCH 011/153] 8322003: JShell - Incorrect type inference in lists
of records implementing interfaces
Reviewed-by: vromero
---
.../sun/tools/javac/parser/JavacParser.java | 24 ++--
.../share/classes/jdk/jshell/TaskFactory.java | 107 ++++++++++++++----
test/langtools/jdk/jshell/VariablesTest.java | 13 ++-
3 files changed, 110 insertions(+), 34 deletions(-)
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
index d83fb85b7f2c0..c962862e4bf7d 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
@@ -967,6 +967,20 @@ public JCExpression parseType(boolean allowVar, List annotations)
return result;
}
+ protected JCExpression parseIntersectionType(int pos, JCExpression firstType) {
+ JCExpression t = firstType;
+ int pos1 = pos;
+ List targets = List.of(t);
+ while (token.kind == AMP) {
+ accept(AMP);
+ targets = targets.prepend(parseType());
+ }
+ if (targets.length() > 1) {
+ t = toP(F.at(pos1).TypeIntersection(targets.reverse()));
+ }
+ return t;
+ }
+
public JCExpression unannotatedType(boolean allowVar) {
return unannotatedType(allowVar, TYPE);
}
@@ -1337,15 +1351,7 @@ protected JCExpression term3() {
case CAST:
accept(LPAREN);
selectTypeMode();
- int pos1 = pos;
- List targets = List.of(t = parseType());
- while (token.kind == AMP) {
- accept(AMP);
- targets = targets.prepend(parseType());
- }
- if (targets.length() > 1) {
- t = toP(F.at(pos1).TypeIntersection(targets.reverse()));
- }
+ t = parseIntersectionType(pos, parseType());
accept(RPAREN);
selectExprMode();
JCExpression t1 = term3();
diff --git a/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java b/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java
index ac777435102ba..5360e0d517fc7 100644
--- a/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java
+++ b/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java
@@ -80,8 +80,13 @@
import com.sun.tools.javac.comp.Enter;
import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.comp.Resolve;
+import com.sun.tools.javac.parser.JavacParser;
+import com.sun.tools.javac.parser.Lexer;
import com.sun.tools.javac.parser.Parser;
import com.sun.tools.javac.parser.ParserFactory;
+import com.sun.tools.javac.parser.ScannerFactory;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.AMP;
+import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCTypeCast;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
@@ -363,7 +368,7 @@ private ParseTask(SourceHandler sh,
JavacTaskImpl task,
DiagnosticCollector diagnostics,
boolean forceExpression) {
- super(sh, task, diagnostics);
+ super(sh, task, diagnostics, false);
ReplParserFactory.preRegister(context, forceExpression);
cuts = parse();
units = Util.stream(cuts)
@@ -402,7 +407,7 @@ class AnalyzeTask extends BaseTask {
private AnalyzeTask(SourceHandler sh,
JavacTaskImpl task,
DiagnosticCollector diagnostics) {
- super(sh, task, diagnostics);
+ super(sh, task, diagnostics, true);
cuts = analyze();
}
@@ -440,7 +445,7 @@ class CompileTask extends BaseTask {
CompileTask(SourceHandlersh,
JavacTaskImpl jti,
DiagnosticCollector diagnostics) {
- super(sh, jti, diagnostics);
+ super(sh, jti, diagnostics, true);
}
boolean compile() {
@@ -504,11 +509,15 @@ abstract class BaseTask {
private BaseTask(SourceHandler sh,
JavacTaskImpl task,
- DiagnosticCollector diagnostics) {
+ DiagnosticCollector diagnostics,
+ boolean analyzeParserFactory) {
this.sourceHandler = sh;
this.task = task;
context = task.getContext();
this.diagnostics = diagnostics;
+ if (analyzeParserFactory) {
+ JShellAnalyzeParserFactory.preRegister(context);
+ }
}
abstract Iterable extends CompilationUnitTree> cuTrees();
@@ -693,7 +702,7 @@ private void setVariableType(VarSnippet s) {
Symtab syms = Symtab.instance(context);
Names names = Names.instance(context);
Log log = Log.instance(context);
- ParserFactory parserFactory = ParserFactory.instance(context);
+ JShellAnalyzeParserFactory parserFactory = (JShellAnalyzeParserFactory) ParserFactory.instance(context);
Attr attr = Attr.instance(context);
Enter enter = Enter.instance(context);
DisableAccessibilityResolve rs = (DisableAccessibilityResolve) Resolve.instance(context);
@@ -709,26 +718,28 @@ private void setVariableType(VarSnippet s) {
//ignore any errors:
JavaFileObject prev = log.useSource(null);
DiscardDiagnosticHandler h = new DiscardDiagnosticHandler(log);
- try {
- //parse the type as a cast, i.e. "() x". This is to support
- //intersection types:
- CharBuffer buf = CharBuffer.wrap(("(" + typeName +")x\u0000").toCharArray(), 0, typeName.length() + 3);
- Parser parser = parserFactory.newParser(buf, false, false, false);
- JCExpression expr = parser.parseExpression();
- if (expr.hasTag(Tag.TYPECAST)) {
- //if parsed OK, attribute and set the type:
- var2OriginalType.put(field, field.type);
-
- JCTypeCast tree = (JCTypeCast) expr;
- rs.runWithoutAccessChecks(() -> {
- field.type = attr.attribType(tree.clazz,
- enter.getEnvs().iterator().next().enclClass.sym);
- });
+ parserFactory.runPermitIntersectionTypes(() -> {
+ try {
+ //parse the type as a cast, i.e. "() x". This is to support
+ //intersection types:
+ CharBuffer buf = CharBuffer.wrap(("(" + typeName +")x\u0000").toCharArray(), 0, typeName.length() + 3);
+ Parser parser = parserFactory.newParser(buf, false, false, false);
+ JCExpression expr = parser.parseExpression();
+ if (expr.hasTag(Tag.TYPECAST)) {
+ //if parsed OK, attribute and set the type:
+ var2OriginalType.put(field, field.type);
+
+ JCTypeCast tree = (JCTypeCast) expr;
+ rs.runWithoutAccessChecks(() -> {
+ field.type = attr.attribType(tree.clazz,
+ enter.getEnvs().iterator().next().enclClass.sym);
+ });
+ }
+ } finally {
+ log.popDiagnosticHandler(h);
+ log.useSource(prev);
}
- } finally {
- log.popDiagnosticHandler(h);
- log.useSource(prev);
- }
+ });
}
}
}
@@ -777,4 +788,52 @@ public boolean isAccessible(Env env, Type site, Symbol sym, boolean
private static final class Marker {}
}
+ private static final class JShellAnalyzeParserFactory extends ParserFactory {
+ public static void preRegister(Context context) {
+ if (context.get(Marker.class) == null) {
+ context.put(parserFactoryKey, ((Factory) c -> new JShellAnalyzeParserFactory(c)));
+ context.put(Marker.class, new Marker());
+ }
+ }
+
+ private final ScannerFactory scannerFactory;
+ private boolean permitIntersectionTypes;
+
+ public JShellAnalyzeParserFactory(Context context) {
+ super(context);
+ this.scannerFactory = ScannerFactory.instance(context);
+ }
+
+ /**Run the given Runnable with intersection type permitted.
+ *
+ * @param r Runnnable to run
+ */
+ public void runPermitIntersectionTypes(Runnable r) {
+ boolean prevPermitIntersectionTypes = permitIntersectionTypes;
+ try {
+ permitIntersectionTypes = true;
+ r.run();
+ } finally {
+ permitIntersectionTypes = prevPermitIntersectionTypes;
+ }
+ }
+
+ @Override
+ public JavacParser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap, boolean parseModuleInfo) {
+ com.sun.tools.javac.parser.Lexer lexer = scannerFactory.newScanner(input, keepDocComments);
+ return new JavacParser(this, lexer, keepDocComments, keepLineMap, keepEndPos, parseModuleInfo) {
+ @Override
+ public JCExpression parseType(boolean allowVar, com.sun.tools.javac.util.List annotations) {
+ int pos = token.pos;
+ JCExpression t = super.parseType(allowVar, annotations);
+ if (permitIntersectionTypes) {
+ t = parseIntersectionType(pos, t);
+ }
+ return t;
+ }
+ };
+ }
+
+ private static final class Marker {}
+ }
}
diff --git a/test/langtools/jdk/jshell/VariablesTest.java b/test/langtools/jdk/jshell/VariablesTest.java
index 56546955e0829..98a543e77a9bf 100644
--- a/test/langtools/jdk/jshell/VariablesTest.java
+++ b/test/langtools/jdk/jshell/VariablesTest.java
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8144903 8177466 8191842 8211694 8213725 8239536 8257236 8252409 8294431 8322532
+ * @bug 8144903 8177466 8191842 8211694 8213725 8239536 8257236 8252409 8294431 8322003 8322532
* @summary Tests for EvaluationState.variables
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
@@ -627,4 +627,15 @@ public void underscoreAsLambdaParameter() { //JDK-8322532
" int i;", true);
}
+ public void intersectionTypeAsTypeArgument() { //JDK-8322003
+ assertEval("interface Shape {}");
+ assertEval("record Square(int edge) implements Shape {}");
+ assertEval("record Circle(int radius) implements Shape {}");
+ assertEval("java.util.function.Consumer printShape = System.out::println;");
+ assertEval("Square square = new Square(1);");
+ assertEval("Circle circle = new Circle(1);");
+ assertEval("var shapes = java.util.List.of(square, circle);");
+ assertEval("shapes.forEach(printShape);");
+ }
+
}
From c8fa3e21e6a4fd7846932b545a1748cc1dc6d9f1 Mon Sep 17 00:00:00 2001
From: Jorn Vernee
Date: Mon, 8 Jan 2024 14:55:17 +0000
Subject: [PATCH 012/153] 8320310: CompiledMethod::has_monitors flag can be
incorrect
Reviewed-by: vlivanov, thartmann
---
src/hotspot/share/c1/c1_Compilation.cpp | 6 +---
src/hotspot/share/c1/c1_GraphBuilder.cpp | 22 ++++++------
src/hotspot/share/opto/locknode.cpp | 6 ----
src/hotspot/share/opto/parse1.cpp | 2 +-
.../share/runtime/continuationFreezeThaw.cpp | 34 +++++++++----------
5 files changed, 31 insertions(+), 39 deletions(-)
diff --git a/src/hotspot/share/c1/c1_Compilation.cpp b/src/hotspot/share/c1/c1_Compilation.cpp
index 4890cec5bfc7b..bef1fae7f7496 100644
--- a/src/hotspot/share/c1/c1_Compilation.cpp
+++ b/src/hotspot/share/c1/c1_Compilation.cpp
@@ -390,10 +390,6 @@ int Compilation::compile_java_method() {
BAILOUT_("mdo allocation failed", no_frame_size);
}
- if (method()->is_synchronized()) {
- set_has_monitors(true);
- }
-
{
PhaseTraceTime timeit(_t_buildIR);
build_hir();
@@ -581,7 +577,7 @@ Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* metho
, _would_profile(false)
, _has_method_handle_invokes(false)
, _has_reserved_stack_access(method->has_reserved_stack_access())
-, _has_monitors(false)
+, _has_monitors(method->is_synchronized() || method->has_monitor_bytecodes())
, _install_code(install_code)
, _bailout_msg(nullptr)
, _first_failure_details(nullptr)
diff --git a/src/hotspot/share/c1/c1_GraphBuilder.cpp b/src/hotspot/share/c1/c1_GraphBuilder.cpp
index fb2aa28ec86a3..fe9a8a478365d 100644
--- a/src/hotspot/share/c1/c1_GraphBuilder.cpp
+++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp
@@ -2316,7 +2316,6 @@ void GraphBuilder::instance_of(int klass_index) {
void GraphBuilder::monitorenter(Value x, int bci) {
// save state before locking in case of deoptimization after a NullPointerException
ValueStack* state_before = copy_state_for_exception_with_bci(bci);
- compilation()->set_has_monitors(true);
append_with_bci(new MonitorEnter(x, state()->lock(x), state_before), bci);
kill_all();
}
@@ -3510,6 +3509,15 @@ int GraphBuilder::recursive_inline_level(ciMethod* cur_callee) const {
return recur_level;
}
+static void set_flags_for_inlined_callee(Compilation* compilation, ciMethod* callee) {
+ if (callee->has_reserved_stack_access()) {
+ compilation->set_has_reserved_stack_access(true);
+ }
+ if (callee->is_synchronized() || callee->has_monitor_bytecodes()) {
+ compilation->set_has_monitors(true);
+ }
+}
+
bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known, bool ignore_return, Bytecodes::Code bc, Value receiver) {
const char* msg = nullptr;
@@ -3526,9 +3534,7 @@ bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known, bool ignore_r
// method handle invokes
if (callee->is_method_handle_intrinsic()) {
if (try_method_handle_inline(callee, ignore_return)) {
- if (callee->has_reserved_stack_access()) {
- compilation()->set_has_reserved_stack_access(true);
- }
+ set_flags_for_inlined_callee(compilation(), callee);
return true;
}
return false;
@@ -3539,9 +3545,7 @@ bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known, bool ignore_r
callee->check_intrinsic_candidate()) {
if (try_inline_intrinsics(callee, ignore_return)) {
print_inlining(callee, "intrinsic");
- if (callee->has_reserved_stack_access()) {
- compilation()->set_has_reserved_stack_access(true);
- }
+ set_flags_for_inlined_callee(compilation(), callee);
return true;
}
// try normal inlining
@@ -3559,9 +3563,7 @@ bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known, bool ignore_r
bc = code();
}
if (try_inline_full(callee, holder_known, ignore_return, bc, receiver)) {
- if (callee->has_reserved_stack_access()) {
- compilation()->set_has_reserved_stack_access(true);
- }
+ set_flags_for_inlined_callee(compilation(), callee);
return true;
}
diff --git a/src/hotspot/share/opto/locknode.cpp b/src/hotspot/share/opto/locknode.cpp
index 640109e6c42a4..6354df1ec5914 100644
--- a/src/hotspot/share/opto/locknode.cpp
+++ b/src/hotspot/share/opto/locknode.cpp
@@ -179,8 +179,6 @@ void FastLockNode::create_rtm_lock_counter(JVMState* state) {
void Parse::do_monitor_enter() {
kill_dead_locals();
- C->set_has_monitors(true);
-
// Null check; get casted pointer.
Node* obj = null_check(peek());
// Check for locking null object
@@ -198,10 +196,6 @@ void Parse::do_monitor_enter() {
void Parse::do_monitor_exit() {
kill_dead_locals();
- // need to set it for monitor exit as well.
- // OSR compiled methods can start with lock taken
- C->set_has_monitors(true);
-
pop(); // Pop oop to unlock
// Because monitors are guaranteed paired (else we bail out), we know
// the matching Lock for this Unlock. Hence we know there is no need
diff --git a/src/hotspot/share/opto/parse1.cpp b/src/hotspot/share/opto/parse1.cpp
index d784f3f3240a3..96db18f774fe7 100644
--- a/src/hotspot/share/opto/parse1.cpp
+++ b/src/hotspot/share/opto/parse1.cpp
@@ -423,7 +423,7 @@ Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses)
C->set_has_reserved_stack_access(true);
}
- if (parse_method->is_synchronized()) {
+ if (parse_method->is_synchronized() || parse_method->has_monitor_bytecodes()) {
C->set_has_monitors(true);
}
diff --git a/src/hotspot/share/runtime/continuationFreezeThaw.cpp b/src/hotspot/share/runtime/continuationFreezeThaw.cpp
index 969e14f150e17..26c915852e589 100644
--- a/src/hotspot/share/runtime/continuationFreezeThaw.cpp
+++ b/src/hotspot/share/runtime/continuationFreezeThaw.cpp
@@ -1498,21 +1498,21 @@ static void jvmti_yield_cleanup(JavaThread* thread, ContinuationWrapper& cont) {
#endif // INCLUDE_JVMTI
#ifdef ASSERT
-// static bool monitors_on_stack(JavaThread* thread) {
-// ContinuationEntry* ce = thread->last_continuation();
-// RegisterMap map(thread,
-// RegisterMap::UpdateMap::include,
-// RegisterMap::ProcessFrames::include,
-// RegisterMap::WalkContinuation::skip);
-// map.set_include_argument_oops(false);
-// for (frame f = thread->last_frame(); Continuation::is_frame_in_continuation(ce, f); f = f.sender(&map)) {
-// if ((f.is_interpreted_frame() && ContinuationHelper::InterpretedFrame::is_owning_locks(f)) ||
-// (f.is_compiled_frame() && ContinuationHelper::CompiledFrame::is_owning_locks(map.thread(), &map, f))) {
-// return true;
-// }
-// }
-// return false;
-// }
+static bool monitors_on_stack(JavaThread* thread) {
+ ContinuationEntry* ce = thread->last_continuation();
+ RegisterMap map(thread,
+ RegisterMap::UpdateMap::include,
+ RegisterMap::ProcessFrames::include,
+ RegisterMap::WalkContinuation::skip);
+ map.set_include_argument_oops(false);
+ for (frame f = thread->last_frame(); Continuation::is_frame_in_continuation(ce, f); f = f.sender(&map)) {
+ if ((f.is_interpreted_frame() && ContinuationHelper::InterpretedFrame::is_owning_locks(f)) ||
+ (f.is_compiled_frame() && ContinuationHelper::CompiledFrame::is_owning_locks(map.thread(), &map, f))) {
+ return true;
+ }
+ }
+ return false;
+}
bool FreezeBase::interpreted_native_or_deoptimized_on_stack() {
ContinuationEntry* ce = _thread->last_continuation();
@@ -1575,8 +1575,8 @@ static inline int freeze_internal(JavaThread* current, intptr_t* const sp) {
assert(entry->is_virtual_thread() == (entry->scope(current) == java_lang_VirtualThread::vthread_scope()), "");
- // assert(monitors_on_stack(current) == ((current->held_monitor_count() - current->jni_monitor_count()) > 0),
- // "Held monitor count and locks on stack invariant: " INT64_FORMAT " JNI: " INT64_FORMAT, (int64_t)current->held_monitor_count(), (int64_t)current->jni_monitor_count());
+ assert(monitors_on_stack(current) == ((current->held_monitor_count() - current->jni_monitor_count()) > 0),
+ "Held monitor count and locks on stack invariant: " INT64_FORMAT " JNI: " INT64_FORMAT, (int64_t)current->held_monitor_count(), (int64_t)current->jni_monitor_count());
if (entry->is_pinned() || current->held_monitor_count() > 0) {
log_develop_debug(continuations)("PINNED due to critical section/hold monitor");
From 2acb5bd9924511b58b0e57ea9eb6c2dee9fd3ee8 Mon Sep 17 00:00:00 2001
From: Ilya Gavrilin
Date: Mon, 8 Jan 2024 15:53:58 +0000
Subject: [PATCH 013/153] 8322790: RISC-V: Tune costs for shuffles with no
conversion
Reviewed-by: rehn, fyang
---
src/hotspot/cpu/riscv/riscv.ad | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/hotspot/cpu/riscv/riscv.ad b/src/hotspot/cpu/riscv/riscv.ad
index d5a95b2e3ba5b..7e1291f49d74c 100644
--- a/src/hotspot/cpu/riscv/riscv.ad
+++ b/src/hotspot/cpu/riscv/riscv.ad
@@ -1001,6 +1001,7 @@ definitions %{
int_def LOAD_COST ( 300, 3 * DEFAULT_COST); // load, fpload
int_def STORE_COST ( 100, 1 * DEFAULT_COST); // store, fpstore
int_def XFER_COST ( 300, 3 * DEFAULT_COST); // mfc, mtc, fcvt, fmove, fcmp
+ int_def FMVX_COST ( 100, 1 * DEFAULT_COST); // shuffles with no conversion
int_def BRANCH_COST ( 200, 2 * DEFAULT_COST); // branch, jmp, call
int_def IMUL_COST ( 1000, 10 * DEFAULT_COST); // imul
int_def IDIVSI_COST ( 3400, 34 * DEFAULT_COST); // idivsi
@@ -8674,7 +8675,7 @@ instruct MoveF2I_reg_reg(iRegINoSp dst, fRegF src) %{
effect(DEF dst, USE src);
- ins_cost(XFER_COST);
+ ins_cost(FMVX_COST);
format %{ "fmv.x.w $dst, $src\t#@MoveF2I_reg_reg" %}
@@ -8692,7 +8693,7 @@ instruct MoveI2F_reg_reg(fRegF dst, iRegI src) %{
effect(DEF dst, USE src);
- ins_cost(XFER_COST);
+ ins_cost(FMVX_COST);
format %{ "fmv.w.x $dst, $src\t#@MoveI2F_reg_reg" %}
@@ -8710,7 +8711,7 @@ instruct MoveD2L_reg_reg(iRegLNoSp dst, fRegD src) %{
effect(DEF dst, USE src);
- ins_cost(XFER_COST);
+ ins_cost(FMVX_COST);
format %{ "fmv.x.d $dst, $src\t#@MoveD2L_reg_reg" %}
@@ -8728,7 +8729,7 @@ instruct MoveL2D_reg_reg(fRegD dst, iRegL src) %{
effect(DEF dst, USE src);
- ins_cost(XFER_COST);
+ ins_cost(FMVX_COST);
format %{ "fmv.d.x $dst, $src\t#@MoveL2D_reg_reg" %}
From 827c71dac9a5732f70bc7341743bce314cad302f Mon Sep 17 00:00:00 2001
From: Emanuel Peter
Date: Mon, 8 Jan 2024 16:10:21 +0000
Subject: [PATCH 014/153] 8310190: C2 SuperWord: AlignVector is broken,
generates misaligned packs
Co-authored-by: Christian Hagedorn
Reviewed-by: kvn, chagedorn
---
src/hotspot/cpu/aarch64/aarch64.ad | 20 +-
src/hotspot/cpu/x86/x86.ad | 15 +
src/hotspot/share/adlc/formssel.cpp | 3 +-
src/hotspot/share/opto/c2_globals.hpp | 6 +-
src/hotspot/share/opto/c2compiler.cpp | 10 +-
src/hotspot/share/opto/chaitin.cpp | 16 +-
src/hotspot/share/opto/classes.hpp | 3 +-
src/hotspot/share/opto/compile.cpp | 27 +-
src/hotspot/share/opto/machnode.cpp | 9 +-
src/hotspot/share/opto/node.hpp | 1 +
src/hotspot/share/opto/superword.cpp | 859 ++--
src/hotspot/share/opto/superword.hpp | 39 +-
src/hotspot/share/opto/vectorization.cpp | 675 ++-
src/hotspot/share/opto/vectorization.hpp | 451 +-
src/hotspot/share/opto/vectornode.hpp | 43 +-
.../TestVectorizationMismatchedAccess.java | 17 +-
.../lib/ir_framework/TestFramework.java | 3 +-
.../loopopts/superword/TestAlignVector.java | 1479 ++++++
.../superword/TestAlignVectorFuzzer.java | 1353 +++++
.../superword/TestDependencyOffsets.java | 4489 ++++++++++++++---
.../superword/TestMovingLoadBeforeStore.java | 3 +-
.../loopopts/superword/TestMulAddS2I.java | 18 +-
.../TestBufferVectorization.java | 314 +-
23 files changed, 8530 insertions(+), 1323 deletions(-)
create mode 100644 test/hotspot/jtreg/compiler/loopopts/superword/TestAlignVector.java
create mode 100644 test/hotspot/jtreg/compiler/loopopts/superword/TestAlignVectorFuzzer.java
diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad
index 233f9b6af7c14..f637648b2279c 100644
--- a/src/hotspot/cpu/aarch64/aarch64.ad
+++ b/src/hotspot/cpu/aarch64/aarch64.ad
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2014, 2021, Red Hat, Inc. All rights reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
//
@@ -8237,6 +8237,24 @@ instruct popCountL_mem(iRegINoSp dst, memory8 mem, vRegD tmp) %{
ins_pipe(pipe_class_default);
%}
+// ============================================================================
+// VerifyVectorAlignment Instruction
+
+instruct verify_vector_alignment(iRegP addr, immL_positive_bitmaskI mask, rFlagsReg cr) %{
+ match(Set addr (VerifyVectorAlignment addr mask));
+ effect(KILL cr);
+ format %{ "verify_vector_alignment $addr $mask \t! verify alignment" %}
+ ins_encode %{
+ Label Lskip;
+ // check if masked bits of addr are zero
+ __ tst($addr$$Register, $mask$$constant);
+ __ br(Assembler::EQ, Lskip);
+ __ stop("verify_vector_alignment found a misaligned vector memory access");
+ __ bind(Lskip);
+ %}
+ ins_pipe(pipe_slow);
+%}
+
// ============================================================================
// MemBar Instruction
diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad
index 8d656c136aa89..caa82aab99c2d 100644
--- a/src/hotspot/cpu/x86/x86.ad
+++ b/src/hotspot/cpu/x86/x86.ad
@@ -8965,6 +8965,21 @@ instruct vmasked_store_evex(memory mem, vec src, kReg mask) %{
%}
#ifdef _LP64
+instruct verify_vector_alignment(rRegP addr, immL32 mask, rFlagsReg cr) %{
+ match(Set addr (VerifyVectorAlignment addr mask));
+ effect(KILL cr);
+ format %{ "verify_vector_alignment $addr $mask \t! verify alignment" %}
+ ins_encode %{
+ Label Lskip;
+ // check if masked bits of addr are zero
+ __ testq($addr$$Register, $mask$$constant);
+ __ jccb(Assembler::equal, Lskip);
+ __ stop("verify_vector_alignment found a misaligned vector memory access");
+ __ bind(Lskip);
+ %}
+ ins_pipe(pipe_slow);
+%}
+
instruct vmask_cmp_node(rRegI dst, vec src1, vec src2, kReg mask, kReg ktmp1, kReg ktmp2, rFlagsReg cr) %{
match(Set dst (VectorCmpMasked src1 (Binary src2 mask)));
effect(TEMP_DEF dst, TEMP ktmp1, TEMP ktmp2, KILL cr);
diff --git a/src/hotspot/share/adlc/formssel.cpp b/src/hotspot/share/adlc/formssel.cpp
index 8e2366e5d09ff..ecbf472c59ef4 100644
--- a/src/hotspot/share/adlc/formssel.cpp
+++ b/src/hotspot/share/adlc/formssel.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2024, 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
@@ -794,6 +794,7 @@ bool InstructForm::captures_bottom_type(FormDict &globals) const {
!strcmp(_matrule->_rChild->_opType,"StrInflatedCopy") ||
!strcmp(_matrule->_rChild->_opType,"VectorCmpMasked")||
!strcmp(_matrule->_rChild->_opType,"VectorMaskGen")||
+ !strcmp(_matrule->_rChild->_opType,"VerifyVectorAlignment")||
!strcmp(_matrule->_rChild->_opType,"CompareAndExchangeP") ||
!strcmp(_matrule->_rChild->_opType,"CompareAndExchangeN"))) return true;
else if ( is_ideal_load() == Form::idealP ) return true;
diff --git a/src/hotspot/share/opto/c2_globals.hpp b/src/hotspot/share/opto/c2_globals.hpp
index dc629de1bdfdb..885c0dd75a784 100644
--- a/src/hotspot/share/opto/c2_globals.hpp
+++ b/src/hotspot/share/opto/c2_globals.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2024, 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
@@ -93,6 +93,10 @@
product(bool, AlignVector, true, \
"Perform vector store/load alignment in loop") \
\
+ develop(bool, VerifyAlignVector, false, \
+ "Check that vector stores/loads are aligned if AlignVector" \
+ "is enabled.") \
+ \
product(intx, NumberOfLoopInstrToAlign, 4, \
"Number of first instructions in a loop to align") \
range(0, max_jint) \
diff --git a/src/hotspot/share/opto/c2compiler.cpp b/src/hotspot/share/opto/c2compiler.cpp
index ba383a679e182..b7c761d9b9845 100644
--- a/src/hotspot/share/opto/c2compiler.cpp
+++ b/src/hotspot/share/opto/c2compiler.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2024, 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
@@ -34,6 +34,7 @@
#include "opto/output.hpp"
#include "opto/runtime.hpp"
#include "runtime/stubRoutines.hpp"
+#include "runtime/globals_extension.hpp"
#include "utilities/macros.hpp"
@@ -64,6 +65,13 @@ void compiler_stubs_init(bool in_compiler_thread);
bool C2Compiler::init_c2_runtime() {
+#ifdef ASSERT
+ if (!AlignVector && VerifyAlignVector) {
+ warning("VerifyAlignVector disabled because AlignVector is not enabled.");
+ FLAG_SET_CMDLINE(VerifyAlignVector, false);
+ }
+#endif
+
// Check assumptions used while running ADLC
Compile::adlc_verification();
assert(REG_COUNT <= ConcreteRegisterImpl::number_of_registers, "incompatible register counts");
diff --git a/src/hotspot/share/opto/chaitin.cpp b/src/hotspot/share/opto/chaitin.cpp
index 2f13a8bbd5721..97c45f508445e 100644
--- a/src/hotspot/share/opto/chaitin.cpp
+++ b/src/hotspot/share/opto/chaitin.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2024, 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
@@ -1789,10 +1789,20 @@ void PhaseChaitin::fixup_spills() {
// Helper to stretch above; recursively discover the base Node for a
// given derived Node. Easy for AddP-related machine nodes, but needs
// to be recursive for derived Phis.
-Node *PhaseChaitin::find_base_for_derived( Node **derived_base_map, Node *derived, uint &maxlrg ) {
+Node* PhaseChaitin::find_base_for_derived(Node** derived_base_map, Node* derived, uint& maxlrg) {
// See if already computed; if so return it
- if( derived_base_map[derived->_idx] )
+ if (derived_base_map[derived->_idx]) {
return derived_base_map[derived->_idx];
+ }
+
+#ifdef ASSERT
+ if (derived->is_Mach() && derived->as_Mach()->ideal_Opcode() == Op_VerifyVectorAlignment) {
+ // Bypass the verification node
+ Node* base = find_base_for_derived(derived_base_map, derived->in(1), maxlrg);
+ derived_base_map[derived->_idx] = base;
+ return base;
+ }
+#endif
// See if this happens to be a base.
// NOTE: we use TypePtr instead of TypeOopPtr because we can have
diff --git a/src/hotspot/share/opto/classes.hpp b/src/hotspot/share/opto/classes.hpp
index 7d1a2cd1db0e8..f1da18f464e46 100644
--- a/src/hotspot/share/opto/classes.hpp
+++ b/src/hotspot/share/opto/classes.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, 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
@@ -449,6 +449,7 @@ macro(StoreVectorScatter)
macro(StoreVectorScatterMasked)
macro(LoadVectorMasked)
macro(StoreVectorMasked)
+macro(VerifyVectorAlignment)
macro(VectorCmpMasked)
macro(VectorMaskGen)
macro(VectorMaskOp)
diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp
index 30701c03707e9..acce455b7265d 100644
--- a/src/hotspot/share/opto/compile.cpp
+++ b/src/hotspot/share/opto/compile.cpp
@@ -1065,7 +1065,7 @@ void Compile::Init(bool aliasing) {
set_has_monitors(false);
if (AllowVectorizeOnDemand) {
- if (has_method() && (_directive->VectorizeOption || _directive->VectorizeDebugOption)) {
+ if (has_method() && _directive->VectorizeOption) {
set_do_vector_loop(true);
NOT_PRODUCT(if (do_vector_loop() && Verbose) {tty->print("Compile::Init: do vectorized loops (SIMD like) for method %s\n", method()->name()->as_quoted_ascii());})
} else if (has_method() && method()->name() != 0 &&
@@ -3707,6 +3707,31 @@ void Compile::final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& f
case Op_LoadVector:
case Op_StoreVector:
+#ifdef ASSERT
+ // Add VerifyVectorAlignment node between adr and load / store.
+ if (VerifyAlignVector && Matcher::has_match_rule(Op_VerifyVectorAlignment)) {
+ bool must_verify_alignment = n->is_LoadVector() ? n->as_LoadVector()->must_verify_alignment() :
+ n->as_StoreVector()->must_verify_alignment();
+ if (must_verify_alignment) {
+ jlong vector_width = n->is_LoadVector() ? n->as_LoadVector()->memory_size() :
+ n->as_StoreVector()->memory_size();
+ // The memory access should be aligned to the vector width in bytes.
+ // However, the underlying array is possibly less well aligned, but at least
+ // to ObjectAlignmentInBytes. Hence, even if multiple arrays are accessed in
+ // a loop we can expect at least the following alignment:
+ jlong guaranteed_alignment = MIN2(vector_width, (jlong)ObjectAlignmentInBytes);
+ assert(2 <= guaranteed_alignment && guaranteed_alignment <= 64, "alignment must be in range");
+ assert(is_power_of_2(guaranteed_alignment), "alignment must be power of 2");
+ // Create mask from alignment. e.g. 0b1000 -> 0b0111
+ jlong mask = guaranteed_alignment - 1;
+ Node* mask_con = ConLNode::make(mask);
+ VerifyVectorAlignmentNode* va = new VerifyVectorAlignmentNode(n->in(MemNode::Address), mask_con);
+ n->set_req(MemNode::Address, va);
+ }
+ }
+#endif
+ break;
+
case Op_LoadVectorGather:
case Op_StoreVectorScatter:
case Op_LoadVectorGatherMasked:
diff --git a/src/hotspot/share/opto/machnode.cpp b/src/hotspot/share/opto/machnode.cpp
index 61042dfe71eff..173a38fa9d854 100644
--- a/src/hotspot/share/opto/machnode.cpp
+++ b/src/hotspot/share/opto/machnode.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, 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
@@ -357,6 +357,13 @@ const class TypePtr *MachNode::adr_type() const {
return adr_type; // get_base_and_disp has the answer
}
+#ifdef ASSERT
+ if (base != nullptr && base->is_Mach() && base->as_Mach()->ideal_Opcode() == Op_VerifyVectorAlignment) {
+ // For VerifyVectorAlignment we just pass the type through
+ return base->bottom_type()->is_ptr();
+ }
+#endif
+
// Direct addressing modes have no base node, simply an indirect
// offset, which is always to raw memory.
// %%%%% Someday we'd like to allow constant oop offsets which
diff --git a/src/hotspot/share/opto/node.hpp b/src/hotspot/share/opto/node.hpp
index 7e9c5196942fb..015bf5d5c72ca 100644
--- a/src/hotspot/share/opto/node.hpp
+++ b/src/hotspot/share/opto/node.hpp
@@ -178,6 +178,7 @@ class StoreVectorMaskedNode;
class LoadVectorGatherNode;
class StoreVectorNode;
class StoreVectorScatterNode;
+class VerifyVectorAlignmentNode;
class VectorMaskCmpNode;
class VectorUnboxNode;
class VectorSet;
diff --git a/src/hotspot/share/opto/superword.cpp b/src/hotspot/share/opto/superword.cpp
index c3f0a60af20ff..4b1d9e5457291 100644
--- a/src/hotspot/share/opto/superword.cpp
+++ b/src/hotspot/share/opto/superword.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2024, 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
@@ -557,14 +557,22 @@ bool SuperWord::SLP_extract() {
// Attempt vectorization
find_adjacent_refs();
- if (align_to_ref() == nullptr) {
- return false; // Did not find memory reference to align vectors
+ if (_packset.length() == 0) {
+#ifndef PRODUCT
+ if (TraceSuperWord) {
+ tty->print_cr("\nNo pair packs generated, abort SuperWord.");
+ tty->cr();
+ }
+#endif
+ return false;
}
extend_packlist();
combine_packs();
+ filter_packs_for_alignment();
+
construct_my_pack_map();
filter_packs();
@@ -578,9 +586,9 @@ bool SuperWord::SLP_extract() {
//------------------------------find_adjacent_refs---------------------------
// Find the adjacent memory references and create pack pairs for them.
-// This is the initial set of packs that will then be extended by
-// following use->def and def->use links. The align positions are
-// assigned relative to the reference "align_to_ref"
+// We can find adjacent memory references by comparing their relative
+// alignment. Whether the final vectors can be aligned is determined later
+// once all vectors are extended and combined.
void SuperWord::find_adjacent_refs() {
// Get list of memory operations
Node_List memops;
@@ -598,25 +606,22 @@ void SuperWord::find_adjacent_refs() {
tty->print_cr("\nfind_adjacent_refs found %d memops", memops.size());
}
- Node_List align_to_refs;
int max_idx;
- int best_iv_adjustment = 0;
- MemNode* best_align_to_mem_ref = nullptr;
+
+ // Take the first mem_ref as the reference to align to. The pre-loop trip count is
+ // modified to align this reference to a vector-aligned address. If strict alignment
+ // is required, we may change the reference later (see filter_packs_for_alignment()).
+ MemNode* align_to_mem_ref = nullptr;
while (memops.size() != 0) {
// Find a memory reference to align to.
MemNode* mem_ref = find_align_to_ref(memops, max_idx);
if (mem_ref == nullptr) break;
- align_to_refs.push(mem_ref);
int iv_adjustment = get_iv_adjustment(mem_ref);
- if (best_align_to_mem_ref == nullptr) {
- // Set memory reference which is the best from all memory operations
- // to be used for alignment. The pre-loop trip count is modified to align
- // this reference to a vector-aligned address.
- best_align_to_mem_ref = mem_ref;
- best_iv_adjustment = iv_adjustment;
- NOT_PRODUCT(find_adjacent_refs_trace_1(best_align_to_mem_ref, best_iv_adjustment);)
+ if (align_to_mem_ref == nullptr) {
+ align_to_mem_ref = mem_ref;
+ set_align_to_ref(align_to_mem_ref);
}
VPointer align_to_ref_p(mem_ref, phase(), lpt(), nullptr, false);
@@ -633,90 +638,26 @@ void SuperWord::find_adjacent_refs() {
}
}
- if (mem_ref_has_no_alignment_violation(mem_ref, iv_adjustment, align_to_ref_p,
- best_align_to_mem_ref, best_iv_adjustment,
- align_to_refs)) {
- // Create initial pack pairs of memory operations for which alignment was set.
- for (uint i = 0; i < memops.size(); i++) {
- Node* s1 = memops.at(i);
- int align = alignment(s1);
- if (align == top_align) continue;
- for (uint j = 0; j < memops.size(); j++) {
- Node* s2 = memops.at(j);
- if (alignment(s2) == top_align) continue;
- if (s1 != s2 && are_adjacent_refs(s1, s2)) {
- if (stmts_can_pack(s1, s2, align)) {
- Node_List* pair = new Node_List();
- pair->push(s1);
- pair->push(s2);
- if (!_do_vector_loop || same_origin_idx(s1, s2)) {
- _packset.append(pair);
- }
- }
- }
- }
- }
- } else {
- // Cannot create pairs for mem_ref. Reject all related memops forever.
-
- // First, remove remaining memory ops of the same memory slice from the list.
- for (int i = memops.size() - 1; i >= 0; i--) {
- MemNode* s = memops.at(i)->as_Mem();
- if (same_memory_slice(s, mem_ref) || same_velt_type(s, mem_ref)) {
- memops.remove(i);
- }
- }
-
- // Second, remove already constructed packs of the same memory slice.
- for (int i = _packset.length() - 1; i >= 0; i--) {
- Node_List* p = _packset.at(i);
- MemNode* s = p->at(0)->as_Mem();
- if (same_memory_slice(s, mem_ref) || same_velt_type(s, mem_ref)) {
- remove_pack_at(i);
- }
- }
-
- // If needed find the best memory reference for loop alignment again.
- if (same_memory_slice(mem_ref, best_align_to_mem_ref) || same_velt_type(mem_ref, best_align_to_mem_ref)) {
- // Put memory ops from remaining packs back on memops list for
- // the best alignment search.
- uint orig_msize = memops.size();
- for (int i = 0; i < _packset.length(); i++) {
- Node_List* p = _packset.at(i);
- MemNode* s = p->at(0)->as_Mem();
- assert(!same_velt_type(s, mem_ref), "sanity");
- memops.push(s);
- }
- best_align_to_mem_ref = find_align_to_ref(memops, max_idx);
- if (best_align_to_mem_ref == nullptr) {
- if (TraceSuperWord) {
- tty->print_cr("SuperWord::find_adjacent_refs(): best_align_to_mem_ref == nullptr");
- }
- // best_align_to_mem_ref will be used for adjusting the pre-loop limit in
- // SuperWord::align_initial_loop_index. Find one with the biggest vector size,
- // smallest data size and smallest iv offset from memory ops from remaining packs.
- if (_packset.length() > 0) {
- if (orig_msize == 0) {
- best_align_to_mem_ref = memops.at(max_idx)->as_Mem();
- } else {
- for (uint i = 0; i < orig_msize; i++) {
- memops.remove(0);
- }
- best_align_to_mem_ref = find_align_to_ref(memops, max_idx);
- assert(best_align_to_mem_ref == nullptr, "sanity");
- best_align_to_mem_ref = memops.at(max_idx)->as_Mem();
+ // Create initial pack pairs of memory operations for which alignment was set.
+ for (uint i = 0; i < memops.size(); i++) {
+ Node* s1 = memops.at(i);
+ int align = alignment(s1);
+ if (align == top_align) continue;
+ for (uint j = 0; j < memops.size(); j++) {
+ Node* s2 = memops.at(j);
+ if (alignment(s2) == top_align) continue;
+ if (s1 != s2 && are_adjacent_refs(s1, s2)) {
+ if (stmts_can_pack(s1, s2, align)) {
+ Node_List* pair = new Node_List();
+ pair->push(s1);
+ pair->push(s2);
+ if (!_do_vector_loop || same_origin_idx(s1, s2)) {
+ _packset.append(pair);
}
- assert(best_align_to_mem_ref != nullptr, "sanity");
}
- break;
}
- best_iv_adjustment = get_iv_adjustment(best_align_to_mem_ref);
- NOT_PRODUCT(find_adjacent_refs_trace_1(best_align_to_mem_ref, best_iv_adjustment);)
- // Restore list.
- while (memops.size() > orig_msize)
- (void)memops.pop();
}
- } // unaligned memory accesses
+ }
// Remove used mem nodes.
for (int i = memops.size() - 1; i >= 0; i--) {
@@ -725,66 +666,17 @@ void SuperWord::find_adjacent_refs() {
memops.remove(i);
}
}
+ } // while (memops.size() != 0)
- } // while (memops.size() != 0
- set_align_to_ref(best_align_to_mem_ref);
+ assert(_packset.is_empty() || align_to_mem_ref != nullptr,
+ "packset empty or we find the alignment reference");
+#ifndef PRODUCT
if (TraceSuperWord) {
tty->print_cr("\nAfter find_adjacent_refs");
print_packset();
}
-}
-
-#ifndef PRODUCT
-void SuperWord::find_adjacent_refs_trace_1(Node* best_align_to_mem_ref, int best_iv_adjustment) {
- if (is_trace_adjacent()) {
- tty->print("SuperWord::find_adjacent_refs best_align_to_mem_ref = %d, best_iv_adjustment = %d",
- best_align_to_mem_ref->_idx, best_iv_adjustment);
- best_align_to_mem_ref->dump();
- }
-}
#endif
-
-// If strict memory alignment is required (vectors_should_be_aligned), then check if
-// mem_ref is aligned with best_align_to_mem_ref.
-bool SuperWord::mem_ref_has_no_alignment_violation(MemNode* mem_ref, int iv_adjustment, VPointer& align_to_ref_p,
- MemNode* best_align_to_mem_ref, int best_iv_adjustment,
- Node_List &align_to_refs) {
- if (!vectors_should_be_aligned()) {
- // Alignment is not required by the hardware. No violation possible.
- return true;
- }
-
- // All vectors need to be memory aligned, modulo their vector_width. This is more strict
- // than the hardware probably requires. Most hardware at most requires 4-byte alignment.
- //
- // In the pre-loop, we align best_align_to_mem_ref to its vector_length. To ensure that
- // all mem_ref's are memory aligned modulo their vector_width, we only need to check that
- // they are all aligned to best_align_to_mem_ref, modulo their vector_width. For that,
- // we check the following 3 conditions.
-
- // (1) All packs are aligned with best_align_to_mem_ref.
- if (memory_alignment(mem_ref, best_iv_adjustment) != 0) {
- return false;
- }
- // (2) All other vectors have vector_size less or equal to that of best_align_to_mem_ref.
- int vw = vector_width(mem_ref);
- int vw_best = vector_width(best_align_to_mem_ref);
- if (vw > vw_best) {
- // We only align to vector_width of best_align_to_mem_ref during pre-loop.
- // A mem_ref with a larger vector_width might thus not be vector_width aligned.
- return false;
- }
- // (3) Ensure that all vectors have the same invariant. We model memory accesses like this
- // address = base + k*iv + constant [+ invar]
- // memory_alignment ignores the invariant.
- VPointer p2(best_align_to_mem_ref, phase(), lpt(), nullptr, false);
- if (!align_to_ref_p.invar_equals(p2)) {
- // Do not vectorize memory accesses with different invariants
- // if unaligned memory accesses are not allowed.
- return false;
- }
- return true;
}
//------------------------------find_align_to_ref---------------------------
@@ -798,12 +690,6 @@ MemNode* SuperWord::find_align_to_ref(Node_List &memops, int &idx) {
for (uint i = 0; i < memops.size(); i++) {
MemNode* s1 = memops.at(i)->as_Mem();
VPointer p1(s1, phase(), lpt(), nullptr, false);
- // Only discard unalignable memory references if vector memory references
- // should be aligned on this platform.
- if (vectors_should_be_aligned() && !ref_is_alignable(p1)) {
- *cmp_ct.adr_at(i) = 0;
- continue;
- }
for (uint j = i+1; j < memops.size(); j++) {
MemNode* s2 = memops.at(j)->as_Mem();
if (isomorphic(s1, s2)) {
@@ -892,95 +778,6 @@ MemNode* SuperWord::find_align_to_ref(Node_List &memops, int &idx) {
return nullptr;
}
-//------------------span_works_for_memory_size-----------------------------
-static bool span_works_for_memory_size(MemNode* mem, int span, int mem_size, int offset) {
- bool span_matches_memory = false;
- if ((mem_size == type2aelembytes(T_BYTE) || mem_size == type2aelembytes(T_SHORT))
- && ABS(span) == type2aelembytes(T_INT)) {
- // There is a mismatch on span size compared to memory.
- for (DUIterator_Fast jmax, j = mem->fast_outs(jmax); j < jmax; j++) {
- Node* use = mem->fast_out(j);
- if (!VectorNode::is_type_transition_to_int(use)) {
- return false;
- }
- }
- // If all uses transition to integer, it means that we can successfully align even on mismatch.
- return true;
- }
- else {
- span_matches_memory = ABS(span) == mem_size;
- }
- return span_matches_memory && (ABS(offset) % mem_size) == 0;
-}
-
-//------------------------------ref_is_alignable---------------------------
-// Can the preloop align the reference to position zero in the vector?
-bool SuperWord::ref_is_alignable(VPointer& p) {
- if (!p.has_iv()) {
- return true; // no induction variable
- }
- CountedLoopEndNode* pre_end = lp()->pre_loop_end();
- assert(pre_end->stride_is_con(), "pre loop stride is constant");
- int preloop_stride = pre_end->stride_con();
-
- int span = preloop_stride * p.scale_in_bytes();
- int mem_size = p.memory_size();
- int offset = p.offset_in_bytes();
- // Stride one accesses are alignable if offset is aligned to memory operation size.
- // Offset can be unaligned when UseUnalignedAccesses is used.
- if (span_works_for_memory_size(p.mem(), span, mem_size, offset)) {
- return true;
- }
- // If the initial offset from start of the object is computable,
- // check if the pre-loop can align the final offset accordingly.
- //
- // In other words: Can we find an i such that the offset
- // after i pre-loop iterations is aligned to vw?
- // (init_offset + pre_loop) % vw == 0 (1)
- // where
- // pre_loop = i * span
- // is the number of bytes added to the offset by i pre-loop iterations.
- //
- // For this to hold we need pre_loop to increase init_offset by
- // pre_loop = vw - (init_offset % vw)
- //
- // This is only possible if pre_loop is divisible by span because each
- // pre-loop iteration increases the initial offset by 'span' bytes:
- // (vw - (init_offset % vw)) % span == 0
- //
- int vw = vector_width_in_bytes(p.mem());
- assert(vw > 1, "sanity");
- Node* init_nd = pre_end->init_trip();
- if (init_nd->is_Con() && p.invar() == nullptr) {
- int init = init_nd->bottom_type()->is_int()->get_con();
- int init_offset = init * p.scale_in_bytes() + offset;
- if (init_offset < 0) { // negative offset from object start?
- return false; // may happen in dead loop
- }
- if (vw % span == 0) {
- // If vm is a multiple of span, we use formula (1).
- if (span > 0) {
- return (vw - (init_offset % vw)) % span == 0;
- } else {
- assert(span < 0, "nonzero stride * scale");
- return (init_offset % vw) % -span == 0;
- }
- } else if (span % vw == 0) {
- // If span is a multiple of vw, we can simplify formula (1) to:
- // (init_offset + i * span) % vw == 0
- // =>
- // (init_offset % vw) + ((i * span) % vw) == 0
- // =>
- // init_offset % vw == 0
- //
- // Because we add a multiple of vw to the initial offset, the final
- // offset is a multiple of vw if and only if init_offset is a multiple.
- //
- return (init_offset % vw) == 0;
- }
- }
- return false;
-}
//---------------------------get_vw_bytes_special------------------------
int SuperWord::get_vw_bytes_special(MemNode* s) {
// Get the vector width in bytes.
@@ -1026,10 +823,6 @@ int SuperWord::get_iv_adjustment(MemNode* mem_ref) {
// several iterations are needed to align memory operations in main-loop even
// if offset is 0.
int iv_adjustment_in_bytes = (stride_sign * vw - (offset % vw));
- // iv_adjustment_in_bytes must be a multiple of elt_size if vector memory
- // references should be aligned on this platform.
- assert((ABS(iv_adjustment_in_bytes) % elt_size) == 0 || !vectors_should_be_aligned(),
- "(%d) should be divisible by (%d)", iv_adjustment_in_bytes, elt_size);
iv_adjustment = iv_adjustment_in_bytes/elt_size;
} else {
// This memory op is not dependent on iv (scale == 0)
@@ -1707,6 +1500,12 @@ int SuperWord::unpack_cost(int ct) { return ct; }
//------------------------------combine_packs---------------------------
// Combine packs A and B with A.last == B.first into A.first..,A.last,B.second,..B.last
void SuperWord::combine_packs() {
+#ifdef ASSERT
+ for (int i = 0; i < _packset.length(); i++) {
+ assert(_packset.at(i) != nullptr, "no nullptr in packset");
+ }
+#endif
+
bool changed = true;
// Combine packs regardless max vector size.
while (changed) {
@@ -1802,18 +1601,123 @@ void SuperWord::combine_packs() {
}
}
- // Compress list.
- for (int i = _packset.length() - 1; i >= 0; i--) {
- Node_List* p1 = _packset.at(i);
- if (p1 == nullptr) {
- _packset.remove_at(i);
- }
- }
+ // Remove all nullptr from packset
+ compress_packset();
+#ifndef PRODUCT
if (TraceSuperWord) {
tty->print_cr("\nAfter combine_packs");
print_packset();
}
+#endif
+}
+
+// Find the set of alignment solutions for load/store pack.
+const AlignmentSolution* SuperWord::pack_alignment_solution(Node_List* pack) {
+ assert(pack != nullptr && (pack->at(0)->is_Load() || pack->at(0)->is_Store()), "only load/store packs");
+
+ const MemNode* mem_ref = pack->at(0)->as_Mem();
+ VPointer mem_ref_p(mem_ref, phase(), lpt(), nullptr, false);
+ const CountedLoopEndNode* pre_end = lp()->pre_loop_end();
+ assert(pre_end->stride_is_con(), "pre loop stride is constant");
+
+ AlignmentSolver solver(pack->at(0)->as_Mem(),
+ pack->size(),
+ mem_ref_p.base(),
+ mem_ref_p.offset_in_bytes(),
+ mem_ref_p.invar(),
+ mem_ref_p.invar_factor(),
+ mem_ref_p.scale_in_bytes(),
+ pre_end->init_trip(),
+ pre_end->stride_con(),
+ iv_stride()
+ DEBUG_ONLY(COMMA is_trace_align_vector()));
+ return solver.solve();
+}
+
+// Ensure all packs are aligned, if AlignVector is on.
+// Find an alignment solution: find the set of pre_iter that memory align all packs.
+// Start with the maximal set (pre_iter >= 0) and filter it with the constraints
+// that the packs impose. Remove packs that do not have a compatible solution.
+void SuperWord::filter_packs_for_alignment() {
+ // We do not need to filter if no alignment is required.
+ if (!vectors_should_be_aligned()) {
+ return;
+ }
+
+#ifndef PRODUCT
+ if (TraceSuperWord || is_trace_align_vector()) {
+ tty->print_cr("\nfilter_packs_for_alignment:");
+ }
+#endif
+
+ ResourceMark rm;
+
+ // Start with trivial (unconstrained) solution space
+ AlignmentSolution const* current = new TrivialAlignmentSolution();
+ int mem_ops_count = 0;
+ int mem_ops_rejected = 0;
+ for (int i = 0; i < _packset.length(); i++) {
+ Node_List* p = _packset.at(i);
+ if (p != nullptr) {
+ if (p->at(0)->is_Load() || p->at(0)->is_Store()) {
+ mem_ops_count++;
+ // Find solution for pack p, and filter with current solution.
+ const AlignmentSolution* s = pack_alignment_solution(p);
+ const AlignmentSolution* intersect = current->filter(s);
+
+#ifndef PRODUCT
+ if (is_trace_align_vector()) {
+ tty->print(" solution for pack: ");
+ s->print();
+ tty->print(" intersection with current: ");
+ intersect->print();
+ }
+#endif
+
+ if (intersect->is_empty()) {
+ // Solution failed or is not compatible, remove pack i.
+ _packset.at_put(i, nullptr);
+ mem_ops_rejected++;
+ } else {
+ // Solution is compatible.
+ current = intersect;
+ }
+ }
+ }
+ }
+
+#ifndef PRODUCT
+ if (TraceSuperWord || is_trace_align_vector()) {
+ tty->print("\n final solution: ");
+ current->print();
+ tty->print_cr(" rejected mem_ops packs: %d of %d", mem_ops_rejected, mem_ops_count);
+ tty->cr();
+ }
+#endif
+
+ assert(!current->is_empty(), "solution must be non-empty");
+ if (current->is_constrained()) {
+ // Solution is constrained (not trivial)
+ // -> must change pre-limit to achieve alignment
+ set_align_to_ref(current->as_constrained()->mem_ref());
+ }
+
+ // Remove all nullptr from packset
+ compress_packset();
+}
+
+// Compress packset, such that it has no nullptr entries
+void SuperWord::compress_packset() {
+ int j = 0;
+ for (int i = 0; i < _packset.length(); i++) {
+ Node_List* p = _packset.at(i);
+ if (p != nullptr) {
+ _packset.at_put(j, p);
+ j++;
+ }
+ }
+ _packset.trunc_to(j);
}
//-----------------------------construct_my_pack_map--------------------------
@@ -2493,9 +2397,7 @@ bool SuperWord::output() {
#endif
_phase->C->print_method(PHASE_SUPERWORD2_BEFORE_OUTPUT, 4, cl);
- // Ensure main loop's initial value is properly aligned
- // (iv_initial_value + min_iv_offset) % vector_width_in_bytes() == 0
- align_initial_loop_index(align_to_ref());
+ adjust_pre_loop_limit_to_align_main_loop_vectors();
// Insert extract (unpack) operations for scalar uses
for (int i = 0; i < _packset.length(); i++) {
@@ -2768,6 +2670,17 @@ bool SuperWord::output() {
return false; // bailout
}
+#ifdef ASSERT
+ // Mark Load/Store Vector for alignment verification
+ if (VerifyAlignVector) {
+ if (vn->Opcode() == Op_LoadVector) {
+ vn->as_LoadVector()->set_must_verify_alignment();
+ } else if (vn->Opcode() == Op_StoreVector) {
+ vn->as_StoreVector()->set_must_verify_alignment();
+ }
+ }
+#endif
+
_block.at_put(i, vn);
_igvn.register_new_node_with_optimizer(vn);
_phase->set_ctrl(vn, _phase->get_ctrl(first));
@@ -3553,167 +3466,337 @@ LoadNode::ControlDependency SuperWord::control_dependency(Node_List* p) {
return dep;
}
+#define TRACE_ALIGN_VECTOR_NODE(node) { \
+ DEBUG_ONLY( \
+ if (is_trace_align_vector()) { \
+ tty->print(" " #node ": "); \
+ node->dump(); \
+ } \
+ ) \
+} \
+
+// Ensure that the main loop vectors are aligned by adjusting the pre loop limit. We memory-align
+// the address of "align_to_ref" to the maximal possible vector width. We adjust the pre-loop
+// iteration count by adjusting the pre-loop limit.
+void SuperWord::adjust_pre_loop_limit_to_align_main_loop_vectors() {
+ const MemNode* align_to_ref = _align_to_ref;
+ assert(align_to_ref != nullptr, "align_to_ref must be set");
+ assert(lp()->is_main_loop(), "can only do alignment for main loop");
-//----------------------------align_initial_loop_index---------------------------
-// Adjust pre-loop limit so that in main loop, a load/store reference
-// to align_to_ref will be a position zero in the vector.
-// (iv + k) mod vector_align == 0
-void SuperWord::align_initial_loop_index(MemNode* align_to_ref) {
- assert(lp()->is_main_loop(), "");
- CountedLoopEndNode* pre_end = lp()->pre_loop_end();
- Node* pre_opaq1 = pre_end->limit();
- assert(pre_opaq1->Opcode() == Op_Opaque1, "");
- Opaque1Node* pre_opaq = (Opaque1Node*)pre_opaq1;
- Node* lim0 = pre_opaq->in(1);
+ // The opaque node for the limit, where we adjust the input
+ Opaque1Node* pre_opaq = lp()->pre_loop_end()->limit()->as_Opaque1();
- // Where we put new limit calculations
+ // Current pre-loop limit.
+ Node* old_limit = pre_opaq->in(1);
+
+ // Where we put new limit calculations.
Node* pre_ctrl = lp()->pre_loop_head()->in(LoopNode::EntryControl);
- // Ensure the original loop limit is available from the
- // pre-loop Opaque1 node.
+ // Ensure the original loop limit is available from the pre-loop Opaque1 node.
Node* orig_limit = pre_opaq->original_loop_limit();
assert(orig_limit != nullptr && _igvn.type(orig_limit) != Type::TOP, "");
VPointer align_to_ref_p(align_to_ref, phase(), lpt(), nullptr, false);
assert(align_to_ref_p.valid(), "sanity");
- // Given:
- // lim0 == original pre loop limit
- // V == v_align (power of 2)
- // invar == extra invariant piece of the address expression
- // e == offset [ +/- invar ]
+ // For the main-loop, we want the address of align_to_ref to be memory aligned
+ // with some alignment width (aw, a power of 2). When we enter the main-loop,
+ // we know that iv is equal to the pre-loop limit. If we adjust the pre-loop
+ // limit by executing adjust_pre_iter many extra iterations, we can change the
+ // alignment of the address.
//
- // When reassociating expressions involving '%' the basic rules are:
- // (a - b) % k == 0 => a % k == b % k
- // and:
- // (a + b) % k == 0 => a % k == (k - b) % k
+ // adr = base + offset + invar + scale * iv (1)
+ // adr % aw = 0 (2)
//
- // For stride > 0 && scale > 0,
- // Derive the new pre-loop limit "lim" such that the two constraints:
- // (1) lim = lim0 + N (where N is some positive integer < V)
- // (2) (e + lim) % V == 0
- // are true.
+ // Note, that we are defining the modulo operator "%" such that the remainder is
+ // always positive, see AlignmentSolution::mod(i, q). Since we are only computing
+ // modulo with powers of 2, we can instead simply use the last log2(q) bits of
+ // a number i, to get "i % q". This is performed with a bitmask.
//
- // Substituting (1) into (2),
- // (e + lim0 + N) % V == 0
- // solve for N:
- // N = (V - (e + lim0)) % V
- // substitute back into (1), so that new limit
- // lim = lim0 + (V - (e + lim0)) % V
+ // The limit of the pre-loop needs to be adjusted:
//
- // For stride > 0 && scale < 0
- // Constraints:
- // lim = lim0 + N
- // (e - lim) % V == 0
- // Solving for lim:
- // (e - lim0 - N) % V == 0
- // N = (e - lim0) % V
- // lim = lim0 + (e - lim0) % V
+ // old_limit: current pre-loop limit
+ // new_limit: new pre-loop limit
+ // adjust_pre_iter: additional pre-loop iterations for alignment adjustment
//
- // For stride < 0 && scale > 0
- // Constraints:
- // lim = lim0 - N
- // (e + lim) % V == 0
- // Solving for lim:
- // (e + lim0 - N) % V == 0
- // N = (e + lim0) % V
- // lim = lim0 - (e + lim0) % V
+ // We want to find adjust_pre_iter, such that the address is aligned when entering
+ // the main-loop:
//
- // For stride < 0 && scale < 0
- // Constraints:
- // lim = lim0 - N
- // (e - lim) % V == 0
- // Solving for lim:
- // (e - lim0 + N) % V == 0
- // N = (V - (e - lim0)) % V
- // lim = lim0 - (V - (e - lim0)) % V
-
- int vw = vector_width_in_bytes(align_to_ref);
- int stride = iv_stride();
- int scale = align_to_ref_p.scale_in_bytes();
- int elt_size = align_to_ref_p.memory_size();
- int v_align = vw / elt_size;
- assert(v_align > 1, "sanity");
- int offset = align_to_ref_p.offset_in_bytes() / elt_size;
- Node *offsn = _igvn.intcon(offset);
-
- Node *e = offsn;
- if (align_to_ref_p.invar() != nullptr) {
- // incorporate any extra invariant piece producing (offset +/- invar) >>> log2(elt)
- Node* log2_elt = _igvn.intcon(exact_log2(elt_size));
- Node* invar = align_to_ref_p.invar();
+ // iv = new_limit = old_limit + adjust_pre_iter (3a, stride > 0)
+ // iv = new_limit = old_limit - adjust_pre_iter (3b, stride < 0)
+ //
+ // We define boi as:
+ //
+ // boi = base + offset + invar (4)
+ //
+ // And now we can simplify the address using (1), (3), and (4):
+ //
+ // adr = boi + scale * new_limit
+ // adr = boi + scale * (old_limit + adjust_pre_iter) (5a, stride > 0)
+ // adr = boi + scale * (old_limit - adjust_pre_iter) (5b, stride < 0)
+ //
+ // And hence we can restate (2) with (5), and solve the equation for adjust_pre_iter:
+ //
+ // (boi + scale * (old_limit + adjust_pre_iter) % aw = 0 (6a, stride > 0)
+ // (boi + scale * (old_limit - adjust_pre_iter) % aw = 0 (6b, stride < 0)
+ //
+ // In most cases, scale is the element size, for example:
+ //
+ // for (i = 0; i < a.length; i++) { a[i] = ...; }
+ //
+ // It is thus reasonable to assume that both abs(scale) and abs(stride) are
+ // strictly positive powers of 2. Further, they can be assumed to be non-zero,
+ // otherwise the address does not depend on iv, and the alignment cannot be
+ // affected by adjusting the pre-loop limit.
+ //
+ // Further, if abs(scale) >= aw, then adjust_pre_iter has no effect on alignment, and
+ // we are not able to affect the alignment at all. Hence, we require abs(scale) < aw.
+ //
+ // Moreover, for alignment to be achievable, boi must be a multiple of scale. If strict
+ // alignment is required (i.e. -XX:+AlignVector), this is guaranteed by the filtering
+ // done with the AlignmentSolver / AlignmentSolution. If strict alignment is not
+ // required, then alignment is still preferable for performance, but not necessary.
+ // In many cases boi will be a multiple of scale, but if it is not, then the adjustment
+ // does not guarantee alignment, but the code is still correct.
+ //
+ // Hence, in what follows we assume that boi is a multiple of scale, and in fact all
+ // terms in (6) are multiples of scale. Therefore we divide all terms by scale:
+ //
+ // AW = aw / abs(scale) (power of 2) (7)
+ // BOI = boi / abs(scale) (8)
+ //
+ // and restate (6), using (7) and (8), i.e. we divide (6) by abs(scale):
+ //
+ // (BOI + sign(scale) * (old_limit + adjust_pre_iter) % AW = 0 (9a, stride > 0)
+ // (BOI + sign(scale) * (old_limit - adjust_pre_iter) % AW = 0 (9b, stride < 0)
+ //
+ // where: sign(scale) = scale / abs(scale) = (scale > 0 ? 1 : -1)
+ //
+ // Note, (9) allows for periodic solutions of adjust_pre_iter, with periodicity AW.
+ // But we would like to spend as few iterations in the pre-loop as possible,
+ // hence we want the smallest adjust_pre_iter, and so:
+ //
+ // 0 <= adjust_pre_iter < AW (10)
+ //
+ // We solve (9) for adjust_pre_iter, in the following 4 cases:
+ //
+ // Case A: scale > 0 && stride > 0 (i.e. sign(scale) = 1)
+ // (BOI + old_limit + adjust_pre_iter) % AW = 0
+ // adjust_pre_iter = (-BOI - old_limit) % AW (11a)
+ //
+ // Case B: scale < 0 && stride > 0 (i.e. sign(scale) = -1)
+ // (BOI - old_limit - adjust_pre_iter) % AW = 0
+ // adjust_pre_iter = (BOI - old_limit) % AW (11b)
+ //
+ // Case C: scale > 0 && stride < 0 (i.e. sign(scale) = 1)
+ // (BOI + old_limit - adjust_pre_iter) % AW = 0
+ // adjust_pre_iter = (BOI + old_limit) % AW (11c)
+ //
+ // Case D: scale < 0 && stride < 0 (i.e. sign(scale) = -1)
+ // (BOI - old_limit + adjust_pre_iter) % AW = 0
+ // adjust_pre_iter = (-BOI + old_limit) % AW (11d)
+ //
+ // We now generalize the equations (11*) by using:
+ //
+ // OP: (stride > 0) ? SUB : ADD
+ // XBOI: (stride * scale > 0) ? -BOI : BOI
+ //
+ // which gives us the final pre-loop limit adjustment:
+ //
+ // adjust_pre_iter = (XBOI OP old_limit) % AW (12)
+ //
+ // We can construct XBOI by additionally defining:
+ //
+ // xboi = (stride * scale > 0) ? -boi : boi (13)
+ //
+ // which gives us:
+ //
+ // XBOI = (stride * scale > 0) ? -BOI : BOI
+ // = (stride * scale > 0) ? -boi / abs(scale) : boi / abs(scale)
+ // = xboi / abs(scale) (14)
+ //
+ // When we have computed adjust_pre_iter, we update the pre-loop limit
+ // with (3a, b). However, we have to make sure that the adjust_pre_iter
+ // additional pre-loop iterations do not lead the pre-loop to execute
+ // iterations that would step over the original limit (orig_limit) of
+ // the loop. Hence, we must constrain the updated limit as follows:
+ //
+ // constrained_limit = MIN(old_limit + adjust_pre_iter, orig_limit)
+ // = MIN(new_limit, orig_limit) (15a, stride > 0)
+ // constrained_limit = MAX(old_limit - adjust_pre_iter, orig_limit)
+ // = MAX(new_limit, orig_limit) (15a, stride < 0)
+
+ // We chose an aw that is the maximal possible vector width for the type of
+ // align_to_ref.
+ const int aw = vector_width_in_bytes(align_to_ref);
+ const int stride = iv_stride();
+ const int scale = align_to_ref_p.scale_in_bytes();
+ const int offset = align_to_ref_p.offset_in_bytes();
+ Node* base = align_to_ref_p.adr();
+ Node* invar = align_to_ref_p.invar();
+
+#ifdef ASSERT
+ if (is_trace_align_vector()) {
+ tty->print_cr("\nadjust_pre_loop_limit_to_align_main_loop_vectors:");
+ tty->print(" align_to_ref:");
+ align_to_ref->dump();
+ tty->print_cr(" aw: %d", aw);
+ tty->print_cr(" stride: %d", stride);
+ tty->print_cr(" scale: %d", scale);
+ tty->print_cr(" offset: %d", offset);
+ tty->print(" base:");
+ base->dump();
+ if (invar == nullptr) {
+ tty->print_cr(" invar: null");
+ } else {
+ tty->print(" invar:");
+ invar->dump();
+ }
+ tty->print(" old_limit: ");
+ old_limit->dump();
+ tty->print(" orig_limit: ");
+ orig_limit->dump();
+ }
+#endif
+
+ if (stride == 0 || !is_power_of_2(abs(stride)) ||
+ scale == 0 || !is_power_of_2(abs(scale)) ||
+ abs(scale) >= aw) {
+#ifdef ASSERT
+ if (is_trace_align_vector()) {
+ tty->print_cr(" Alignment cannot be affected by changing pre-loop limit because");
+ tty->print_cr(" stride or scale are not power of 2, or abs(scale) >= aw.");
+ }
+#endif
+ // Cannot affect alignment, abort.
+ return;
+ }
+
+ assert(stride != 0 && is_power_of_2(abs(stride)) &&
+ scale != 0 && is_power_of_2(abs(scale)) &&
+ abs(scale) < aw, "otherwise we cannot affect alignment with pre-loop");
+
+ const int AW = aw / abs(scale);
+
+#ifdef ASSERT
+ if (is_trace_align_vector()) {
+ tty->print_cr(" AW = aw(%d) / abs(scale(%d)) = %d", aw, scale, AW);
+ }
+#endif
+
+ // 1: Compute (13a, b):
+ // xboi = -boi = (-base - offset - invar) (stride * scale > 0)
+ // xboi = +boi = (+base + offset + invar) (stride * scale < 0)
+ const bool is_sub = scale * stride > 0;
+
+ // 1.1: offset
+ Node* xboi = _igvn.intcon(is_sub ? -offset : offset);
+ TRACE_ALIGN_VECTOR_NODE(xboi);
+
+ // 1.2: invar (if it exists)
+ if (invar != nullptr) {
if (_igvn.type(invar)->isa_long()) {
// Computations are done % (vector width/element size) so it's
// safe to simply convert invar to an int and loose the upper 32
// bit half.
invar = new ConvL2INode(invar);
_igvn.register_new_node_with_optimizer(invar);
+ TRACE_ALIGN_VECTOR_NODE(invar);
+ }
+ if (is_sub) {
+ xboi = new SubINode(xboi, invar);
+ } else {
+ xboi = new AddINode(xboi, invar);
}
- Node* aref = new URShiftINode(invar, log2_elt);
- _igvn.register_new_node_with_optimizer(aref);
- _phase->set_ctrl(aref, pre_ctrl);
- e = new AddINode(e, aref);
- _igvn.register_new_node_with_optimizer(e);
- _phase->set_ctrl(e, pre_ctrl);
+ _igvn.register_new_node_with_optimizer(xboi);
+ _phase->set_ctrl(xboi, pre_ctrl);
+ TRACE_ALIGN_VECTOR_NODE(xboi);
}
- if (vw > ObjectAlignmentInBytes || align_to_ref_p.base()->is_top()) {
- // incorporate base e +/- base && Mask >>> log2(elt)
- Node* xbase = new CastP2XNode(nullptr, align_to_ref_p.adr());
+
+ // 1.3: base (unless base is guaranteed aw aligned)
+ if (aw > ObjectAlignmentInBytes || align_to_ref_p.base()->is_top()) {
+ // The base is only aligned with ObjectAlignmentInBytes with arrays.
+ // When the base() is top, we have no alignment guarantee at all.
+ // Hence, we must now take the base into account for the calculation.
+ Node* xbase = new CastP2XNode(nullptr, base);
_igvn.register_new_node_with_optimizer(xbase);
+ TRACE_ALIGN_VECTOR_NODE(xbase);
#ifdef _LP64
xbase = new ConvL2INode(xbase);
_igvn.register_new_node_with_optimizer(xbase);
+ TRACE_ALIGN_VECTOR_NODE(xbase);
#endif
- Node* mask = _igvn.intcon(vw-1);
- Node* masked_xbase = new AndINode(xbase, mask);
- _igvn.register_new_node_with_optimizer(masked_xbase);
- Node* log2_elt = _igvn.intcon(exact_log2(elt_size));
- Node* bref = new URShiftINode(masked_xbase, log2_elt);
- _igvn.register_new_node_with_optimizer(bref);
- _phase->set_ctrl(bref, pre_ctrl);
- e = new AddINode(e, bref);
- _igvn.register_new_node_with_optimizer(e);
- _phase->set_ctrl(e, pre_ctrl);
- }
-
- // compute e +/- lim0
- if (scale < 0) {
- e = new SubINode(e, lim0);
+ if (is_sub) {
+ xboi = new SubINode(xboi, xbase);
+ } else {
+ xboi = new AddINode(xboi, xbase);
+ }
+ _igvn.register_new_node_with_optimizer(xboi);
+ _phase->set_ctrl(xboi, pre_ctrl);
+ TRACE_ALIGN_VECTOR_NODE(xboi);
+ }
+
+ // 2: Compute (14):
+ // XBOI = xboi / abs(scale)
+ // The division is executed as shift
+ Node* log2_abs_scale = _igvn.intcon(exact_log2(abs(scale)));
+ Node* XBOI = new URShiftINode(xboi, log2_abs_scale);
+ _igvn.register_new_node_with_optimizer(XBOI);
+ _phase->set_ctrl(XBOI, pre_ctrl);
+ TRACE_ALIGN_VECTOR_NODE(log2_abs_scale);
+ TRACE_ALIGN_VECTOR_NODE(XBOI);
+
+ // 3: Compute (12):
+ // adjust_pre_iter = (XBOI OP old_limit) % AW
+ //
+ // 3.1: XBOI_OP_old_limit = XBOI OP old_limit
+ Node* XBOI_OP_old_limit = nullptr;
+ if (stride > 0) {
+ XBOI_OP_old_limit = new SubINode(XBOI, old_limit);
} else {
- e = new AddINode(e, lim0);
- }
- _igvn.register_new_node_with_optimizer(e);
- _phase->set_ctrl(e, pre_ctrl);
-
- if (stride * scale > 0) {
- // compute V - (e +/- lim0)
- Node* va = _igvn.intcon(v_align);
- e = new SubINode(va, e);
- _igvn.register_new_node_with_optimizer(e);
- _phase->set_ctrl(e, pre_ctrl);
- }
- // compute N = (exp) % V
- Node* va_msk = _igvn.intcon(v_align - 1);
- Node* N = new AndINode(e, va_msk);
- _igvn.register_new_node_with_optimizer(N);
- _phase->set_ctrl(N, pre_ctrl);
-
- // substitute back into (1), so that new limit
- // lim = lim0 + N
- Node* lim;
+ XBOI_OP_old_limit = new AddINode(XBOI, old_limit);
+ }
+ _igvn.register_new_node_with_optimizer(XBOI_OP_old_limit);
+ _phase->set_ctrl(XBOI_OP_old_limit, pre_ctrl);
+ TRACE_ALIGN_VECTOR_NODE(XBOI_OP_old_limit);
+
+ // 3.2: Compute:
+ // adjust_pre_iter = (XBOI OP old_limit) % AW
+ // = XBOI_OP_old_limit % AW
+ // = XBOI_OP_old_limit AND (AW - 1)
+ // Since AW is a power of 2, the modulo operation can be replaced with
+ // a bitmask operation.
+ Node* mask_AW = _igvn.intcon(AW-1);
+ Node* adjust_pre_iter = new AndINode(XBOI_OP_old_limit, mask_AW);
+ _igvn.register_new_node_with_optimizer(adjust_pre_iter);
+ _phase->set_ctrl(adjust_pre_iter, pre_ctrl);
+ TRACE_ALIGN_VECTOR_NODE(mask_AW);
+ TRACE_ALIGN_VECTOR_NODE(adjust_pre_iter);
+
+ // 4: Compute (3a, b):
+ // new_limit = old_limit + adjust_pre_iter (stride > 0)
+ // new_limit = old_limit - adjust_pre_iter (stride < 0)
+ Node* new_limit = nullptr;
if (stride < 0) {
- lim = new SubINode(lim0, N);
+ new_limit = new SubINode(old_limit, adjust_pre_iter);
} else {
- lim = new AddINode(lim0, N);
- }
- _igvn.register_new_node_with_optimizer(lim);
- _phase->set_ctrl(lim, pre_ctrl);
- Node* constrained =
- (stride > 0) ? (Node*) new MinINode(lim, orig_limit)
- : (Node*) new MaxINode(lim, orig_limit);
- _igvn.register_new_node_with_optimizer(constrained);
- _phase->set_ctrl(constrained, pre_ctrl);
- _igvn.replace_input_of(pre_opaq, 1, constrained);
+ new_limit = new AddINode(old_limit, adjust_pre_iter);
+ }
+ _igvn.register_new_node_with_optimizer(new_limit);
+ _phase->set_ctrl(new_limit, pre_ctrl);
+ TRACE_ALIGN_VECTOR_NODE(new_limit);
+
+ // 5: Compute (15a, b):
+ // Prevent pre-loop from going past the original limit of the loop.
+ Node* constrained_limit =
+ (stride > 0) ? (Node*) new MinINode(new_limit, orig_limit)
+ : (Node*) new MaxINode(new_limit, orig_limit);
+ _igvn.register_new_node_with_optimizer(constrained_limit);
+ _phase->set_ctrl(constrained_limit, pre_ctrl);
+ TRACE_ALIGN_VECTOR_NODE(constrained_limit);
+
+ // 6: Hack the pre-loop limit
+ _igvn.replace_input_of(pre_opaq, 1, constrained_limit);
}
//------------------------------init---------------------------
diff --git a/src/hotspot/share/opto/superword.hpp b/src/hotspot/share/opto/superword.hpp
index 2319636c99abc..db7101b26cb53 100644
--- a/src/hotspot/share/opto/superword.hpp
+++ b/src/hotspot/share/opto/superword.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2024, 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
@@ -247,7 +247,7 @@ class SuperWord : public ResourceObj {
GrowableArray _mem_slice_tail; // Memory slice tail nodes
GrowableArray _node_info; // Info needed per node
CloneMap& _clone_map; // map of nodes created in cloning
- MemNode* _align_to_ref; // Memory reference that pre-loop will align to
+ MemNode const* _align_to_ref; // Memory reference that pre-loop will align to
GrowableArray _disjoint_ptrs; // runtime disambiguated pointer pairs
@@ -281,6 +281,7 @@ class SuperWord : public ResourceObj {
bool is_trace_loop() { return (_vector_loop_debug & 8) > 0; }
bool is_trace_adjacent() { return (_vector_loop_debug & 16) > 0; }
bool is_trace_cmov() { return (_vector_loop_debug & 32) > 0; }
+ bool is_trace_align_vector() { return (_vector_loop_debug & 128) > 0; }
#endif
bool do_vector_loop() { return _do_vector_loop; }
@@ -315,17 +316,17 @@ class SuperWord : public ResourceObj {
}
int iv_stride() const { return lp()->stride_con(); }
- int vector_width(Node* n) {
+ int vector_width(const Node* n) const {
BasicType bt = velt_basic_type(n);
return MIN2(ABS(iv_stride()), Matcher::max_vector_size(bt));
}
- int vector_width_in_bytes(Node* n) {
+ int vector_width_in_bytes(const Node* n) const {
BasicType bt = velt_basic_type(n);
return vector_width(n)*type2aelembytes(bt);
}
int get_vw_bytes_special(MemNode* s);
- MemNode* align_to_ref() { return _align_to_ref; }
- void set_align_to_ref(MemNode* m) { _align_to_ref = m; }
+ const MemNode* align_to_ref() const { return _align_to_ref; }
+ void set_align_to_ref(const MemNode* m) { _align_to_ref = m; }
const Node* ctrl(const Node* n) const { return _phase->has_ctrl(n) ? _phase->get_ctrl(n) : n; }
@@ -360,8 +361,8 @@ class SuperWord : public ResourceObj {
void set_depth(Node* n, int d) { int i = bb_idx(n); grow_node_info(i); _node_info.adr_at(i)->_depth = d; }
// vector element type
- const Type* velt_type(Node* n) { return _node_info.adr_at(bb_idx(n))->_velt_type; }
- BasicType velt_basic_type(Node* n) { return velt_type(n)->array_element_basic_type(); }
+ const Type* velt_type(const Node* n) const { return _node_info.adr_at(bb_idx(n))->_velt_type; }
+ BasicType velt_basic_type(const Node* n) const { return velt_type(n)->array_element_basic_type(); }
void set_velt_type(Node* n, const Type* t) { int i = bb_idx(n); grow_node_info(i); _node_info.adr_at(i)->_velt_type = t; }
bool same_velt_type(Node* n1, Node* n2);
bool same_memory_slice(MemNode* best_align_to_mem_ref, MemNode* mem_ref) const;
@@ -441,21 +442,10 @@ class SuperWord : public ResourceObj {
bool SLP_extract();
// Find the adjacent memory references and create pack pairs for them.
void find_adjacent_refs();
- // Tracing support
- #ifndef PRODUCT
- void find_adjacent_refs_trace_1(Node* best_align_to_mem_ref, int best_iv_adjustment);
- #endif
- // If strict memory alignment is required (vectors_should_be_aligned), then check if
- // mem_ref is aligned with best_align_to_mem_ref.
- bool mem_ref_has_no_alignment_violation(MemNode* mem_ref, int iv_adjustment, VPointer& align_to_ref_p,
- MemNode* best_align_to_mem_ref, int best_iv_adjustment,
- Node_List &align_to_refs);
// Find a memory reference to align the loop induction variable to.
MemNode* find_align_to_ref(Node_List &memops, int &idx);
// Calculate loop's iv adjustment for this memory ops.
int get_iv_adjustment(MemNode* mem);
- // Can the preloop align the reference to position zero in the vector?
- bool ref_is_alignable(VPointer& p);
// Construct dependency graph.
void dependence_graph();
// Return a memory slice (node list) in predecessor order starting at "start"
@@ -497,6 +487,12 @@ class SuperWord : public ResourceObj {
int unpack_cost(int ct);
// Combine packs A and B with A.last == B.first into A.first..,A.last,B.second,..B.last
void combine_packs();
+ // Ensure all packs are aligned, if AlignVector is on.
+ void filter_packs_for_alignment();
+ // Find the set of alignment solutions for load/store pack.
+ const AlignmentSolution* pack_alignment_solution(Node_List* pack);
+ // Compress packset, such that it has no nullptr entries.
+ void compress_packset();
// Construct the map from nodes to packs.
void construct_my_pack_map();
// Remove packs that are not implemented or not profitable.
@@ -544,9 +540,8 @@ class SuperWord : public ResourceObj {
int memory_alignment(MemNode* s, int iv_adjust);
// Smallest type containing range of values
const Type* container_type(Node* n);
- // Adjust pre-loop limit so that in main loop, a load/store reference
- // to align_to_ref will be a position zero in the vector.
- void align_initial_loop_index(MemNode* align_to_ref);
+ // Ensure that the main loop vectors are aligned by adjusting the pre loop limit.
+ void adjust_pre_loop_limit_to_align_main_loop_vectors();
// Is the use of d1 in u1 at the same operand position as d2 in u2?
bool opnd_positions_match(Node* d1, Node* u1, Node* d2, Node* u2);
void init();
diff --git a/src/hotspot/share/opto/vectorization.cpp b/src/hotspot/share/opto/vectorization.cpp
index 7158f40092928..4794140ab0e45 100644
--- a/src/hotspot/share/opto/vectorization.cpp
+++ b/src/hotspot/share/opto/vectorization.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, Arm Limited. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -35,7 +35,8 @@
int VPointer::Tracer::_depth = 0;
#endif
-VPointer::VPointer(MemNode* mem, PhaseIdealLoop* phase, IdealLoopTree* lpt,
+VPointer::VPointer(const MemNode* mem,
+ PhaseIdealLoop* phase, IdealLoopTree* lpt,
Node_Stack* nstack, bool analyze_only) :
_mem(mem), _phase(phase), _lpt(lpt),
_iv(lpt->_head->as_CountedLoop()->phi()->as_Phi()),
@@ -119,6 +120,22 @@ VPointer::VPointer(VPointer* p) :
#endif
{}
+// Biggest detectable factor of the invariant.
+int VPointer::invar_factor() const {
+ Node* n = invar();
+ if (n == nullptr) {
+ return 0;
+ }
+ int opc = n->Opcode();
+ if (opc == Op_LShiftI && n->in(2)->is_Con()) {
+ return 1 << n->in(2)->get_int();
+ } else if (opc == Op_LShiftL && n->in(2)->is_Con()) {
+ return 1 << n->in(2)->get_int();
+ }
+ // All our best-effort has failed.
+ return 1;
+}
+
bool VPointer::is_loop_member(Node* n) const {
Node* n_c = phase()->get_ctrl(n);
return lpt()->is_member(phase()->get_loop(n_c));
@@ -417,7 +434,7 @@ void VPointer::Tracer::print_depth() const {
}
}
-void VPointer::Tracer::ctor_1(Node* mem) {
+void VPointer::Tracer::ctor_1(const Node* mem) {
if (_is_trace_alignment) {
print_depth(); tty->print(" %d VPointer::VPointer: start alignment analysis", mem->_idx); mem->dump();
}
@@ -459,7 +476,7 @@ void VPointer::Tracer::ctor_5(Node* adr, Node* base, int i) {
}
}
-void VPointer::Tracer::ctor_6(Node* mem) {
+void VPointer::Tracer::ctor_6(const Node* mem) {
if (_is_trace_alignment) {
//restore_depth();
print_depth(); tty->print_cr(" %d (adr) VPointer::VPointer: stop analysis", mem->_idx);
@@ -685,5 +702,655 @@ void VPointer::Tracer::offset_plus_k_11(Node* n) {
print_depth(); tty->print_cr(" %d VPointer::offset_plus_k: FAILED", n->_idx);
}
}
+#endif
+
+
+AlignmentSolution* AlignmentSolver::solve() const {
+ DEBUG_ONLY( trace_start_solve(); )
+
+ // Out of simplicity: non power-of-2 stride not supported.
+ if (!is_power_of_2(abs(_pre_stride))) {
+ return new EmptyAlignmentSolution("non power-of-2 stride not supported");
+ }
+ assert(is_power_of_2(abs(_main_stride)), "main_stride is power of 2");
+ assert(_aw > 0 && is_power_of_2(_aw), "aw must be power of 2");
+
+ // Out of simplicity: non power-of-2 scale not supported.
+ if (abs(_scale) == 0 || !is_power_of_2(abs(_scale))) {
+ return new EmptyAlignmentSolution("non power-of-2 scale not supported");
+ }
+
+ // We analyze the address of mem_ref. The idea is to disassemble it into a linear
+ // expression, where we can use the constant factors as the basis for ensuring the
+ // alignment of vector memory accesses.
+ //
+ // The Simple form of the address is disassembled by VPointer into:
+ //
+ // adr = base + offset + invar + scale * iv
+ //
+ // Where the iv can be written as:
+ //
+ // iv = init + pre_stride * pre_iter + main_stride * main_iter
+ //
+ // init: value before pre-loop
+ // pre_stride: increment per pre-loop iteration
+ // pre_iter: number of pre-loop iterations (adjustable via pre-loop limit)
+ // main_stride: increment per main-loop iteration (= pre_stride * unroll_factor)
+ // main_iter: number of main-loop iterations (main_iter >= 0)
+ //
+ // In the following, we restate the Simple form of the address expression, by first
+ // expanding the iv variable. In a second step, we reshape the expression again, and
+ // state it as a linear expression, consisting of 6 terms.
+ //
+ // Simple form Expansion of iv variable Reshaped with constants Comments for terms
+ // ----------- ------------------------ ----------------------- ------------------
+ // adr = base = base = base (base % aw = 0)
+ // + offset + offset + C_const (sum of constant terms)
+ // + invar + invar_factor * var_invar + C_invar * var_invar (term for invariant)
+ // / + scale * init + C_init * var_init (term for variable init)
+ // + scale * iv -> | + scale * pre_stride * pre_iter + C_pre * pre_iter (adjustable pre-loop term)
+ // \ + scale * main_stride * main_iter + C_main * main_iter (main-loop term)
+ //
+ // We describe the 6 terms:
+ // 1) The "base" of the address is the address of a Java object (e.g. array),
+ // and as such ObjectAlignmentInBytes (a power of 2) aligned. We have
+ // defined aw = MIN(vector_width, ObjectAlignmentInBytes), which is also
+ // a power of 2. And hence we know that "base" is thus also aw-aligned:
+ //
+ // base % ObjectAlignmentInBytes = 0 ==> base % aw = 0
+ //
+ // 2) The "C_const" term is the sum of all constant terms. This is "offset",
+ // plus "scale * init" if it is constant.
+ // 3) The "C_invar * var_invar" is the factorization of "invar" into a constant
+ // and variable term. If there is no invariant, then "C_invar" is zero.
+ //
+ // invar = C_invar * var_invar (FAC_INVAR)
+ //
+ // 4) The "C_init * var_init" is the factorization of "scale * init" into a
+ // constant and a variable term. If "init" is constant, then "C_init" is
+ // zero, and "C_const" accounts for "init" instead.
+ //
+ // scale * init = C_init * var_init + scale * C_const_init (FAC_INIT)
+ // C_init = (init is constant) ? 0 : scale
+ // C_const_init = (init is constant) ? init : 0
+ //
+ // 5) The "C_pre * pre_iter" term represents how much the iv is incremented
+ // during the "pre_iter" pre-loop iterations. This term can be adjusted
+ // by changing the pre-loop limit, which defines how many pre-loop iterations
+ // are executed. This allows us to adjust the alignment of the main-loop
+ // memory reference.
+ // 6) The "C_main * main_iter" term represents how much the iv is increased
+ // during "main_iter" main-loop iterations.
+
+ // Attribute init (i.e. _init_node) either to C_const or to C_init term.
+ const int C_const_init = _init_node->is_ConI() ? _init_node->as_ConI()->get_int() : 0;
+ const int C_const = _offset + C_const_init * _scale;
+
+ // Set C_invar depending on if invar is present
+ const int C_invar = (_invar == nullptr) ? 0 : abs(_invar_factor);
+
+ const int C_init = _init_node->is_ConI() ? 0 : _scale;
+ const int C_pre = _scale * _pre_stride;
+ const int C_main = _scale * _main_stride;
+
+ DEBUG_ONLY( trace_reshaped_form(C_const, C_const_init, C_invar, C_init, C_pre, C_main); )
+
+ // We must find a pre_iter, such that adr is aw aligned: adr % aw = 0. Note, that we are defining the
+ // modulo operator "%" such that the remainder is always positive, see AlignmentSolution::mod(i, q).
+ //
+ // Since "base % aw = 0", we only need to ensure alignment of the other 5 terms:
+ //
+ // (C_const + C_invar * var_invar + C_init * var_init + C_pre * pre_iter + C_main * main_iter) % aw = 0 (1)
+ //
+ // Alignment must be maintained over all main-loop iterations, i.e. for any main_iter >= 0, we require:
+ //
+ // C_main % aw = 0 (2)
+ //
+ const int C_main_mod_aw = AlignmentSolution::mod(C_main, _aw);
+
+ DEBUG_ONLY( trace_main_iteration_alignment(C_const, C_invar, C_init, C_pre, C_main, C_main_mod_aw); )
+
+ if (C_main_mod_aw != 0) {
+ return new EmptyAlignmentSolution("EQ(2) not satisfied (cannot align across main-loop iterations)");
+ }
+
+ // In what follows, we need to show that the C_const, init and invar terms can be aligned by
+ // adjusting the pre-loop iteration count (pre_iter), which is controlled by the pre-loop
+ // limit.
+ //
+ // (C_const + C_invar * var_invar + C_init * var_init + C_pre * pre_iter) % aw = 0 (3)
+ //
+ // We strengthen the constraints by splitting the equation into 3 equations, where we
+ // want to find integer solutions for pre_iter_C_const, pre_iter_C_invar, and
+ // pre_iter_C_init, which means that the C_const, init and invar terms can be aligned
+ // independently:
+ //
+ // (C_const + C_pre * pre_iter_C_const) % aw = 0 (4a)
+ // (C_invar * var_invar + C_pre * pre_iter_C_invar) % aw = 0 (4b)
+ // (C_init * var_init + C_pre * pre_iter_C_init ) % aw = 0 (4c)
+ //
+ // We now prove that (4a, b, c) are sufficient as well as necessary to guarantee (3)
+ // for any runtime value of var_invar and var_init (i.e. for any invar and init).
+ // This tells us that the "strengthening" does not restrict the algorithm more than
+ // necessary.
+ //
+ // Sufficient (i.e (4a, b, c) imply (3)):
+ //
+ // pre_iter = pre_iter_C_const + pre_iter_C_invar + pre_iter_C_init
+ //
+ // Adding up (4a, b, c):
+ //
+ // 0 = ( C_const + C_pre * pre_iter_C_const
+ // + C_invar * var_invar + C_pre * pre_iter_C_invar
+ // + C_init * var_init + C_pre * pre_iter_C_init ) % aw
+ //
+ // = ( C_const + C_invar * var_invar + C_init * var_init
+ // + C_pre * (pre_iter_C_const + pre_iter_C_invar + pre_iter_C_init)) % aw
+ //
+ // = ( C_const + C_invar * var_invar + C_init * var_init
+ // + C_pre * pre_iter) % aw
+ //
+ // Necessary (i.e. (3) implies (4a, b, c)):
+ // (4a): Set var_invar = var_init = 0 at runtime. Applying this to (3), we get:
+ //
+ // 0 =
+ // = (C_const + C_invar * var_invar + C_init * var_init + C_pre * pre_iter) % aw
+ // = (C_const + C_invar * 0 + C_init * 0 + C_pre * pre_iter) % aw
+ // = (C_const + C_pre * pre_iter) % aw
+ //
+ // This is of the same form as (4a), and we have a solution:
+ // pre_iter_C_const = pre_iter
+ //
+ // (4b): Set var_init = 0, and assume (4a), which we just proved is implied by (3).
+ // Subtract (4a) from (3):
+ //
+ // 0 =
+ // = (C_const + C_invar * var_invar + C_init * var_init + C_pre * pre_iter) % aw
+ // - (C_const + C_pre * pre_iter_C_const) % aw
+ // = (C_invar * var_invar + C_init * var_init + C_pre * pre_iter - C_pre * pre_iter_C_const) % aw
+ // = (C_invar * var_invar + C_init * 0 + C_pre * (pre_iter - pre_iter_C_const)) % aw
+ // = (C_invar * var_invar + + C_pre * (pre_iter - pre_iter_C_const)) % aw
+ //
+ // This is of the same form as (4b), and we have a solution:
+ // pre_iter_C_invar = pre_iter - pre_iter_C_const
+ //
+ // (4c): Set var_invar = 0, and assume (4a), which we just proved is implied by (3).
+ // Subtract (4a) from (3):
+ //
+ // 0 =
+ // = (C_const + C_invar * var_invar + C_init * var_init + C_pre * pre_iter) % aw
+ // - (C_const + C_pre * pre_iter_C_const) % aw
+ // = (C_invar * var_invar + C_init * var_init + C_pre * pre_iter - C_pre * pre_iter_C_const) % aw
+ // = (C_invar * 0 + C_init * var_init + C_pre * (pre_iter - pre_iter_C_const)) % aw
+ // = ( + C_init * var_init + C_pre * (pre_iter - pre_iter_C_const)) % aw
+ //
+ // This is of the same form as (4c), and we have a solution:
+ // pre_iter_C_invar = pre_iter - pre_iter_C_const
+ //
+ // The solutions of Equations (4a, b, c) for pre_iter_C_const, pre_iter_C_invar, and pre_iter_C_init
+ // respectively, can have one of these states:
+ //
+ // trivial: The solution can be any integer.
+ // constrained: There is a (periodic) solution, but it is not trivial.
+ // empty: Statically we cannot guarantee a solution for all var_invar and var_init.
+ //
+ // We look at (4a):
+ //
+ // abs(C_pre) >= aw
+ // -> Since abs(C_pre) is a power of two, we have C_pre % aw = 0. Therefore:
+ //
+ // For any pre_iter_C_const: (C_pre * pre_iter_C_const) % aw = 0
+ //
+ // (C_const + C_pre * pre_iter_C_const) % aw = 0
+ // C_const % aw = 0
+ //
+ // Hence, we can only satisfy (4a) if C_Const is aw aligned:
+ //
+ // C_const % aw == 0:
+ // -> (4a) has a trivial solution since we can choose any value for pre_iter_C_const.
+ //
+ // C_const % aw != 0:
+ // -> (4a) has an empty solution since no pre_iter_C_const can achieve aw alignment.
+ //
+ // abs(C_pre) < aw:
+ // -> Since both abs(C_pre) and aw are powers of two, we know:
+ //
+ // There exists integer x > 1: aw = abs(C_pre) * x
+ //
+ // C_const % abs(C_pre) == 0:
+ // -> There exists integer z: C_const = C_pre * z
+ //
+ // (C_const + C_pre * pre_iter_C_const) % aw = 0
+ // ==>
+ // (C_pre * z + C_pre * pre_iter_C_const) % aw = 0
+ // ==>
+ // (C_pre * z + C_pre * pre_iter_C_const) % (abs(C_pre) * x) = 0
+ // ==>
+ // ( z + pre_iter_C_const) % x = 0
+ // ==>
+ // for any m: pre_iter_C_const = m * x - z
+ //
+ // Hence, pre_iter_C_const has a non-trivial (because x > 1) periodic (periodicity x)
+ // solution, i.e. it has a constrained solution.
+ //
+ // C_const % abs(C_pre) != 0:
+ // There exists integer x > 1: aw = abs(C_pre) * x
+ //
+ // C_const % abs(C_pre) != 0
+ // ==>
+ // (C_const + C_pre * pre_iter_C_const) % abs(C_pre) != 0
+ // ==>
+ // (C_const + C_pre * pre_iter_C_const) % (abs(C_pre) * x) != 0
+ // ==>
+ // (C_const + C_pre * pre_iter_C_const) % aw != 0
+ //
+ // This is in contradiction with (4a), and therefore there cannot be any solution,
+ // i.e. we have an empty solution.
+ //
+ // In summary, for (4a):
+ //
+ // abs(C_pre) >= aw AND C_const % aw == 0 -> trivial
+ // abs(C_pre) >= aw AND C_const % aw != 0 -> empty
+ // abs(C_pre) < aw AND C_const % abs(C_pre) == 0 -> constrained
+ // abs(C_pre) < aw AND C_const % abs(C_pre) != 0 -> empty
+ //
+ // With analogue argumentation for (4b):
+ //
+ // abs(C_pre) >= aw AND C_invar % aw == 0 -> trivial
+ // abs(C_pre) >= aw AND C_invar % aw != 0 -> empty
+ // abs(C_pre) < aw AND C_invar % abs(C_pre) == 0 -> constrained
+ // abs(C_pre) < aw AND C_invar % abs(C_pre) != 0 -> empty
+ //
+ // With analogue argumentation for (4c):
+ //
+ // abs(C_pre) >= aw AND C_init % aw == 0 -> trivial
+ // abs(C_pre) >= aw AND C_init % aw != 0 -> empty
+ // abs(C_pre) < aw AND C_init % abs(C_pre) == 0 -> constrained
+ // abs(C_pre) < aw AND C_init % abs(C_pre) != 0 -> empty
+ //
+ // Out of these states follows the state for the solution of pre_iter:
+ //
+ // Trivial: If (4a, b, c) are all trivial.
+ // Empty: If any of (4a, b, c) is empty, because then we cannot guarantee a solution
+ // for pre_iter, for all possible invar and init values.
+ // Constrained: Else. Incidentally, (4a, b, c) are all constrained themselves, as we argue below.
+
+ const EQ4 eq4(C_const, C_invar, C_init, C_pre, _aw);
+ const EQ4::State eq4a_state = eq4.eq4a_state();
+ const EQ4::State eq4b_state = eq4.eq4b_state();
+ const EQ4::State eq4c_state = eq4.eq4c_state();
+
+#ifdef ASSERT
+ if (is_trace()) {
+ eq4.trace();
+ }
+#endif
+
+ // If (4a, b, c) are all trivial, then also the solution for pre_iter is trivial:
+ if (eq4a_state == EQ4::State::TRIVIAL &&
+ eq4b_state == EQ4::State::TRIVIAL &&
+ eq4c_state == EQ4::State::TRIVIAL) {
+ return new TrivialAlignmentSolution();
+ }
+
+ // If any of (4a, b, c) is empty, then we also cannot guarantee a solution for pre_iter, for
+ // any init and invar, hence the solution for pre_iter is empty:
+ if (eq4a_state == EQ4::State::EMPTY ||
+ eq4b_state == EQ4::State::EMPTY ||
+ eq4c_state == EQ4::State::EMPTY) {
+ return new EmptyAlignmentSolution("EQ(4a, b, c) not all non-empty: cannot align const, invar and init terms individually");
+ }
+
+ // If abs(C_pre) >= aw, then the solutions to (4a, b, c) are all either trivial or empty, and
+ // hence we would have found the solution to pre_iter above as either trivial or empty. Thus
+ // we now know that:
+ //
+ // abs(C_pre) < aw
+ //
+ assert(abs(C_pre) < _aw, "implied by constrained case");
+
+ // And since abs(C_pre) < aw, the solutions of (4a, b, c) can now only be constrained or empty.
+ // But since we already handled the empty case, the solutions are now all constrained.
+ assert(eq4a_state == EQ4::State::CONSTRAINED &&
+ eq4a_state == EQ4::State::CONSTRAINED &&
+ eq4a_state == EQ4::State::CONSTRAINED, "all must be constrained now");
+
+ // And since they are all constrained, we must have:
+ //
+ // C_const % abs(C_pre) = 0 (5a)
+ // C_invar % abs(C_pre) = 0 (5b)
+ // C_init % abs(C_pre) = 0 (5c)
+ //
+ assert(AlignmentSolution::mod(C_const, abs(C_pre)) == 0, "EQ(5a): C_const must be alignable");
+ assert(AlignmentSolution::mod(C_invar, abs(C_pre)) == 0, "EQ(5b): C_invar must be alignable");
+ assert(AlignmentSolution::mod(C_init, abs(C_pre)) == 0, "EQ(5c): C_init must be alignable");
+
+ // With (5a, b, c), we know that there are integers X, Y, Z:
+ //
+ // C_const = X * abs(C_pre) ==> X = C_const / abs(C_pre) (6a)
+ // C_invar = Y * abs(C_pre) ==> Y = C_invar / abs(C_pre) (6b)
+ // C_init = Z * abs(C_pre) ==> Z = C_init / abs(C_pre) (6c)
+ //
+ // Further, we define:
+ //
+ // sign(C_pre) = C_pre / abs(C_pre) = (C_pre > 0) ? 1 : -1, (7)
+ //
+ // We know that abs(C_pre) as well as aw are powers of 2, and since (5) we can define integer q:
+ //
+ // q = aw / abs(C_pre) (8)
+ //
+ const int q = _aw / abs(C_pre);
+
+ assert(q >= 2, "implied by constrained solution");
+
+ // We now know that all terms in (4a, b, c) are divisible by abs(C_pre):
+ //
+ // (C_const / abs(C_pre) + C_pre * pre_iter_C_const / abs(C_pre)) % (aw / abs(C_pre)) =
+ // (X * abs(C_pre) / abs(C_pre) + C_pre * pre_iter_C_const / abs(C_pre)) % (aw / abs(C_pre)) =
+ // (X + pre_iter_C_const * sign(C_pre)) % q = 0 (9a)
+ //
+ // -> pre_iter_C_const * sign(C_pre) = mx1 * q - X
+ // -> pre_iter_C_const = mx2 * q - sign(C_pre) * X (10a)
+ // (for any integers mx1, mx2)
+ //
+ // (C_invar * var_invar / abs(C_pre) + C_pre * pre_iter_C_invar / abs(C_pre)) % (aw / abs(C_pre)) =
+ // (Y * abs(C_pre) * var_invar / abs(C_pre) + C_pre * pre_iter_C_invar / abs(C_pre)) % (aw / abs(C_pre)) =
+ // (Y * var_invar + pre_iter_C_invar * sign(C_pre)) % q = 0 (9b)
+ //
+ // -> pre_iter_C_invar * sign(C_pre) = my1 * q - Y * var_invar
+ // -> pre_iter_C_invar = my2 * q - sign(C_pre) * Y * var_invar (10b)
+ // (for any integers my1, my2)
+ //
+ // (C_init * var_init / abs(C_pre) + C_pre * pre_iter_C_init / abs(C_pre)) % (aw / abs(C_pre)) =
+ // (Z * abs(C_pre) * var_init / abs(C_pre) + C_pre * pre_iter_C_init / abs(C_pre)) % (aw / abs(C_pre)) =
+ // (Z * var_init + pre_iter_C_init * sign(C_pre)) % q = 0 (9c)
+ //
+ // -> pre_iter_C_init * sign(C_pre) = mz1 * q - Z * var_init
+ // -> pre_iter_C_init = mz2 * q - sign(C_pre) * Z * var_init (10c)
+ // (for any integers mz1, mz2)
+ //
+ //
+ // Having solved the equations using the division, we can re-substitute X, Y, and Z, and apply (FAC_INVAR) as
+ // well as (FAC_INIT). We use the fact that sign(x) == 1 / sign(x) and sign(x) * abs(x) == x:
+ //
+ // pre_iter_C_const = mx2 * q - sign(C_pre) * X
+ // = mx2 * q - sign(C_pre) * C_const / abs(C_pre)
+ // = mx2 * q - C_const / C_pre
+ // = mx2 * q - C_const / (scale * pre_stride) (11a)
+ //
+ // If there is an invariant:
+ //
+ // pre_iter_C_invar = my2 * q - sign(C_pre) * Y * var_invar
+ // = my2 * q - sign(C_pre) * C_invar * var_invar / abs(C_pre)
+ // = my2 * q - sign(C_pre) * invar / abs(C_pre)
+ // = my2 * q - invar / C_pre
+ // = my2 * q - invar / (scale * pre_stride) (11b, with invar)
+ //
+ // If there is no invariant (i.e. C_invar = 0 ==> Y = 0):
+ //
+ // pre_iter_C_invar = my2 * q (11b, no invar)
+ //
+ // If init is variable (i.e. C_init = scale, init = var_init):
+ //
+ // pre_iter_C_init = mz2 * q - sign(C_pre) * Z * var_init
+ // = mz2 * q - sign(C_pre) * C_init * var_init / abs(C_pre)
+ // = mz2 * q - sign(C_pre) * scale * init / abs(C_pre)
+ // = mz2 * q - scale * init / C_pre
+ // = mz2 * q - scale * init / (scale * pre_stride)
+ // = mz2 * q - init / pre_stride (11c, variable init)
+ //
+ // If init is constant (i.e. C_init = 0 ==> Z = 0):
+ //
+ // pre_iter_C_init = mz2 * q (11c, constant init)
+ //
+ // Note, that the solutions found by (11a, b, c) are all periodic with periodicity q. We combine them,
+ // with m = mx2 + my2 + mz2:
+ //
+ // pre_iter = pre_iter_C_const + pre_iter_C_invar + pre_iter_C_init
+ // = mx2 * q - C_const / (scale * pre_stride)
+ // + my2 * q [- invar / (scale * pre_stride) ]
+ // + mz2 * q [- init / pre_stride ]
+ //
+ // = m * q (periodic part)
+ // - C_const / (scale * pre_stride) (align constant term)
+ // [- invar / (scale * pre_stride) ] (align invariant term, if present)
+ // [- init / pre_stride ] (align variable init term, if present) (12)
+ //
+ // We can further simplify this solution by introducing integer 0 <= r < q:
+ //
+ // r = (-C_const / (scale * pre_stride)) % q (13)
+ //
+ const int r = AlignmentSolution::mod(-C_const / (_scale * _pre_stride), q);
+ //
+ // pre_iter = m * q + r
+ // [- invar / (scale * pre_stride) ]
+ // [- init / pre_stride ] (14)
+ //
+ // We thus get a solution that can be stated in terms of:
+ //
+ // q (periodicity), r (constant alignment), invar, scale, pre_stride, init
+ //
+ // However, pre_stride and init are shared by all mem_ref in the loop, hence we do not need to provide
+ // them in the solution description.
+
+ DEBUG_ONLY( trace_constrained_solution(C_const, C_invar, C_init, C_pre, q, r); )
+
+ return new ConstrainedAlignmentSolution(_mem_ref, q, r, _invar, _scale);
+
+ // APPENDIX:
+ // We can now verify the success of the solution given by (12):
+ //
+ // adr % aw =
+ //
+ // -> Simple form
+ // (base + offset + invar + scale * iv) % aw =
+ //
+ // -> Expand iv
+ // (base + offset + invar + scale * (init + pre_stride * pre_iter + main_stride * main_iter)) % aw =
+ //
+ // -> Reshape
+ // (base + offset + invar
+ // + scale * init
+ // + scale * pre_stride * pre_iter
+ // + scale * main_stride * main_iter)) % aw =
+ //
+ // -> base aligned: base % aw = 0
+ // -> main-loop iterations aligned (2): C_main % aw = (scale * main_stride) % aw = 0
+ // (offset + invar + scale * init + scale * pre_stride * pre_iter) % aw =
+ //
+ // -> apply (12)
+ // (offset + invar + scale * init
+ // + scale * pre_stride * (m * q - C_const / (scale * pre_stride)
+ // [- invar / (scale * pre_stride) ]
+ // [- init / pre_stride ]
+ // )
+ // ) % aw =
+ //
+ // -> expand C_const = offset [+ init * scale] (if init const)
+ // (offset + invar + scale * init
+ // + scale * pre_stride * (m * q - offset / (scale * pre_stride)
+ // [- init / pre_stride ] (if init constant)
+ // [- invar / (scale * pre_stride) ] (if invar present)
+ // [- init / pre_stride ] (if init variable)
+ // )
+ // ) % aw =
+ //
+ // -> assuming invar = 0 if it is not present
+ // -> merge the two init terms (variable or constant)
+ // -> apply (8): q = aw / (abs(C_pre)) = aw / abs(scale * pre_stride)
+ // -> and hence: (scale * pre_stride * q) % aw = 0
+ // -> all terms are canceled out
+ // (offset + invar + scale * init
+ // + scale * pre_stride * m * q -> aw aligned
+ // - scale * pre_stride * offset / (scale * pre_stride) -> = offset
+ // - scale * pre_stride * init / pre_stride -> = scale * init
+ // - scale * pre_stride * invar / (scale * pre_stride) -> = invar
+ // ) % aw = 0
+ //
+ // The solution given by (12) does indeed guarantee alignment.
+}
+#ifdef ASSERT
+void print_con_or_idx(const Node* n) {
+ if (n == nullptr) {
+ tty->print("(0)");
+ } else if (n->is_ConI()) {
+ jint val = n->as_ConI()->get_int();
+ tty->print("(%d)", val);
+ } else {
+ tty->print("[%d]", n->_idx);
+ }
+}
+
+void AlignmentSolver::trace_start_solve() const {
+ if (is_trace()) {
+ tty->print(" vector mem_ref:");
+ _mem_ref->dump();
+ tty->print_cr(" vector_width = vector_length(%d) * element_size(%d) = %d",
+ _vector_length, _element_size, _vector_width);
+ tty->print_cr(" aw = alignment_width = min(vector_width(%d), ObjectAlignmentInBytes(%d)) = %d",
+ _vector_width, ObjectAlignmentInBytes, _aw);
+
+ if (!_init_node->is_ConI()) {
+ tty->print(" init:");
+ _init_node->dump();
+ }
+
+ if (_invar != nullptr) {
+ tty->print(" invar:");
+ _invar->dump();
+ }
+
+ tty->print_cr(" invar_factor = %d", _invar_factor);
+
+ // iv = init + pre_iter * pre_stride + main_iter * main_stride
+ tty->print(" iv = init");
+ print_con_or_idx(_init_node);
+ tty->print_cr(" + pre_iter * pre_stride(%d) + main_iter * main_stride(%d)",
+ _pre_stride, _main_stride);
+
+ // adr = base + offset + invar + scale * iv
+ tty->print(" adr = base");
+ print_con_or_idx(_base);
+ tty->print(" + offset(%d) + invar", _offset);
+ print_con_or_idx(_invar);
+ tty->print_cr(" + scale(%d) * iv", _scale);
+ }
+}
+
+void AlignmentSolver::trace_reshaped_form(const int C_const,
+ const int C_const_init,
+ const int C_invar,
+ const int C_init,
+ const int C_pre,
+ const int C_main) const
+{
+ if (is_trace()) {
+ tty->print(" = base[%d] + ", _base->_idx);
+ tty->print_cr("C_const(%d) + C_invar(%d) * var_invar + C_init(%d) * var_init + C_pre(%d) * pre_iter + C_main(%d) * main_iter",
+ C_const, C_invar, C_init, C_pre, C_main);
+ if (_init_node->is_ConI()) {
+ tty->print_cr(" init is constant:");
+ tty->print_cr(" C_const_init = %d", C_const_init);
+ tty->print_cr(" C_init = %d", C_init);
+ } else {
+ tty->print_cr(" init is variable:");
+ tty->print_cr(" C_const_init = %d", C_const_init);
+ tty->print_cr(" C_init = abs(scale)= %d", C_init);
+ }
+ if (_invar != nullptr) {
+ tty->print_cr(" invariant present:");
+ tty->print_cr(" C_invar = abs(invar_factor) = %d", C_invar);
+ } else {
+ tty->print_cr(" no invariant:");
+ tty->print_cr(" C_invar = %d", C_invar);
+ }
+ tty->print_cr(" C_const = offset(%d) + scale(%d) * C_const_init(%d) = %d",
+ _offset, _scale, C_const_init, C_const);
+ tty->print_cr(" C_pre = scale(%d) * pre_stride(%d) = %d",
+ _scale, _pre_stride, C_pre);
+ tty->print_cr(" C_main = scale(%d) * main_stride(%d) = %d",
+ _scale, _main_stride, C_main);
+ }
+}
+
+void AlignmentSolver::trace_main_iteration_alignment(const int C_const,
+ const int C_invar,
+ const int C_init,
+ const int C_pre,
+ const int C_main,
+ const int C_main_mod_aw) const
+{
+ if (is_trace()) {
+ tty->print(" EQ(1 ): (C_const(%d) + C_invar(%d) * var_invar + C_init(%d) * var_init",
+ C_const, C_invar, C_init);
+ tty->print(" + C_pre(%d) * pre_iter + C_main(%d) * main_iter) %% aw(%d) = 0",
+ C_pre, C_main, _aw);
+ tty->print_cr(" (given base aligned -> align rest)");
+ tty->print(" EQ(2 ): C_main(%d) %% aw(%d) = %d = 0",
+ C_main, _aw, C_main_mod_aw);
+ tty->print_cr(" (alignment across iterations)");
+ }
+}
+
+void AlignmentSolver::EQ4::trace() const {
+ tty->print_cr(" EQ(4a): (C_const(%3d) + C_pre(%d) * pre_iter_C_const) %% aw(%d) = 0 (align const term individually)",
+ _C_const, _C_pre, _aw);
+ tty->print_cr(" -> %s", state_to_str(eq4a_state()));
+
+ tty->print_cr(" EQ(4b): (C_invar(%3d) * var_invar + C_pre(%d) * pre_iter_C_invar) %% aw(%d) = 0 (align invar term individually)",
+ _C_invar, _C_pre, _aw);
+ tty->print_cr(" -> %s", state_to_str(eq4b_state()));
+
+ tty->print_cr(" EQ(4c): (C_init( %3d) * var_init + C_pre(%d) * pre_iter_C_init ) %% aw(%d) = 0 (align init term individually)",
+ _C_init, _C_pre, _aw);
+ tty->print_cr(" -> %s", state_to_str(eq4c_state()));
+}
+
+void AlignmentSolver::trace_constrained_solution(const int C_const,
+ const int C_invar,
+ const int C_init,
+ const int C_pre,
+ const int q,
+ const int r) const
+{
+ if (is_trace()) {
+ tty->print_cr(" EQ(4a, b, c) all constrained, hence:");
+ tty->print_cr(" EQ(5a): C_const(%3d) %% abs(C_pre(%d)) = 0", C_const, C_pre);
+ tty->print_cr(" EQ(5b): C_invar(%3d) %% abs(C_pre(%d)) = 0", C_invar, C_pre);
+ tty->print_cr(" EQ(5c): C_init( %3d) %% abs(C_pre(%d)) = 0", C_init, C_pre);
+
+ tty->print_cr(" All terms in EQ(4a, b, c) are divisible by abs(C_pre(%d)).", C_pre);
+ const int X = C_const / abs(C_pre);
+ const int Y = C_invar / abs(C_pre);
+ const int Z = C_init / abs(C_pre);
+ const int sign = (C_pre > 0) ? 1 : -1;
+ tty->print_cr(" X = C_const(%3d) / abs(C_pre(%d)) = %d (6a)", C_const, C_pre, X);
+ tty->print_cr(" Y = C_invar(%3d) / abs(C_pre(%d)) = %d (6b)", C_invar, C_pre, Y);
+ tty->print_cr(" Z = C_init( %3d) / abs(C_pre(%d)) = %d (6c)", C_init , C_pre, Z);
+ tty->print_cr(" q = aw( %3d) / abs(C_pre(%d)) = %d (8)", _aw, C_pre, q);
+ tty->print_cr(" sign(C_pre) = (C_pre(%d) > 0) ? 1 : -1 = %d (7)", C_pre, sign);
+
+ tty->print_cr(" EQ(9a): (X(%3d) + pre_iter_C_const * sign(C_pre)) %% q(%d) = 0", X, q);
+ tty->print_cr(" EQ(9b): (Y(%3d) * var_invar + pre_iter_C_invar * sign(C_pre)) %% q(%d) = 0", Y, q);
+ tty->print_cr(" EQ(9c): (Z(%3d) * var_init + pre_iter_C_init * sign(C_pre)) %% q(%d) = 0", Z, q);
+
+ tty->print_cr(" EQ(10a): pre_iter_C_const = mx2 * q(%d) - sign(C_pre) * X(%d)", q, X);
+ tty->print_cr(" EQ(10b): pre_iter_C_invar = my2 * q(%d) - sign(C_pre) * Y(%d) * var_invar", q, Y);
+ tty->print_cr(" EQ(10c): pre_iter_C_init = mz2 * q(%d) - sign(C_pre) * Z(%d) * var_init ", q, Z);
+
+ tty->print_cr(" r = (-C_const(%d) / (scale(%d) * pre_stride(%d)) %% q(%d) = %d",
+ C_const, _scale, _pre_stride, q, r);
+
+ tty->print_cr(" EQ(14): pre_iter = m * q(%3d) - r(%d)", q, r);
+ if (_invar != nullptr) {
+ tty->print_cr(" - invar / (scale(%d) * pre_stride(%d))",
+ _scale, _pre_stride);
+ }
+ if (!_init_node->is_ConI()) {
+ tty->print_cr(" - init / pre_stride(%d)",
+ _pre_stride);
+ }
+ }
+}
#endif
diff --git a/src/hotspot/share/opto/vectorization.hpp b/src/hotspot/share/opto/vectorization.hpp
index 8df5d0c9a821f..8e63b40d5ac48 100644
--- a/src/hotspot/share/opto/vectorization.hpp
+++ b/src/hotspot/share/opto/vectorization.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, Arm Limited. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -36,7 +36,7 @@
// operation in a counted loop for vectorizable analysis.
class VPointer : public ArenaObj {
protected:
- MemNode* _mem; // My memory reference node
+ const MemNode* _mem; // My memory reference node
PhaseIdealLoop* _phase; // PhaseIdealLoop handle
IdealLoopTree* _lpt; // Current IdealLoopTree
PhiNode* _iv; // The loop induction variable
@@ -80,23 +80,27 @@ class VPointer : public ArenaObj {
NotComparable = (Less | Greater | Equal)
};
- VPointer(MemNode* mem, PhaseIdealLoop* phase, IdealLoopTree* lpt,
- Node_Stack* nstack, bool analyze_only);
+ VPointer(const MemNode* mem,
+ PhaseIdealLoop* phase, IdealLoopTree* lpt,
+ Node_Stack* nstack, bool analyze_only);
// Following is used to create a temporary object during
// the pattern match of an address expression.
VPointer(VPointer* p);
- bool valid() { return _adr != nullptr; }
- bool has_iv() { return _scale != 0; }
+ bool valid() const { return _adr != nullptr; }
+ bool has_iv() const { return _scale != 0; }
- Node* base() { return _base; }
- Node* adr() { return _adr; }
- MemNode* mem() { return _mem; }
- int scale_in_bytes() { return _scale; }
- Node* invar() { return _invar; }
- int offset_in_bytes() { return _offset; }
- int memory_size() { return _mem->memory_size(); }
- Node_Stack* node_stack() { return _nstack; }
+ Node* base() const { return _base; }
+ Node* adr() const { return _adr; }
+ const MemNode* mem() const { return _mem; }
+ int scale_in_bytes() const { return _scale; }
+ Node* invar() const { return _invar; }
+ int offset_in_bytes() const { return _offset; }
+ int memory_size() const { return _mem->memory_size(); }
+ Node_Stack* node_stack() const { return _nstack; }
+
+ // Biggest detectable factor of the invariant.
+ int invar_factor() const;
// Comparable?
bool invar_equals(VPointer& q) {
@@ -165,12 +169,12 @@ class VPointer : public ArenaObj {
Tracer(bool is_trace_alignment) : _is_trace_alignment(is_trace_alignment) {}
// tracing functions
- void ctor_1(Node* mem);
+ void ctor_1(const Node* mem);
void ctor_2(Node* adr);
void ctor_3(Node* adr, int i);
void ctor_4(Node* adr, int i);
void ctor_5(Node* adr, Node* base, int i);
- void ctor_6(Node* mem);
+ void ctor_6(const Node* mem);
void scaled_iv_plus_offset_1(Node* n);
void scaled_iv_plus_offset_2(Node* n);
@@ -259,4 +263,419 @@ class VectorElementSizeStats {
}
};
+// When alignment is required, we must adjust the pre-loop iteration count pre_iter,
+// such that the address is aligned for any main_iter >= 0:
+//
+// adr = base + offset + invar + scale * init
+// + scale * pre_stride * pre_iter
+// + scale * main_stride * main_iter
+//
+// The AlignmentSolver generates solutions of the following forms:
+// 1. Empty: No pre_iter guarantees alignment.
+// 2. Trivial: Any pre_iter guarantees alignment.
+// 3. Constrained: There is a periodic solution, but it is not trivial.
+//
+// The Constrained solution is of the following form:
+//
+// pre_iter = m * q + r (for any integer m)
+// [- invar / (scale * pre_stride) ] (if there is an invariant)
+// [- init / pre_stride ] (if init is variable)
+//
+// The solution is periodic with periodicity q, which is guaranteed to be a power of 2.
+// This periodic solution is "rotated" by three alignment terms: one for constants (r),
+// one for the invariant (if present), and one for init (if it is variable).
+//
+// The "filter" method combines the solutions of two mem_refs, such that the new set of
+// values for pre_iter guarantees alignment for both mem_refs.
+//
+class EmptyAlignmentSolution;
+class TrivialAlignmentSolution;
+class ConstrainedAlignmentSolution;
+
+class AlignmentSolution : public ResourceObj {
+public:
+ virtual bool is_empty() const = 0;
+ virtual bool is_trivial() const = 0;
+ virtual bool is_constrained() const = 0;
+
+ virtual const ConstrainedAlignmentSolution* as_constrained() const {
+ assert(is_constrained(), "must be constrained");
+ return nullptr;
+ }
+
+ // Implemented by each subclass
+ virtual const AlignmentSolution* filter(const AlignmentSolution* other) const = 0;
+ virtual void print() const = 0;
+
+ // Compute modulo and ensure that we get a positive remainder
+ static int mod(int i, int q) {
+ assert(q >= 1, "modulo value must be large enough");
+
+ // Modulo operator: Get positive 0 <= r < q for positive i, but
+ // get negative 0 >= r > -q for negative i.
+ int r = i % q;
+
+ // Make negative r into positive ones:
+ r = (r >= 0) ? r : r + q;
+
+ assert(0 <= r && r < q, "remainder must fit in modulo space");
+ return r;
+ }
+};
+
+class EmptyAlignmentSolution : public AlignmentSolution {
+private:
+ const char* _reason;
+public:
+ EmptyAlignmentSolution(const char* reason) : _reason(reason) {}
+ virtual bool is_empty() const override final { return true; }
+ virtual bool is_trivial() const override final { return false; }
+ virtual bool is_constrained() const override final { return false; }
+ const char* reason() const { return _reason; }
+
+ virtual const AlignmentSolution* filter(const AlignmentSolution* other) const override final {
+ // If "this" cannot be guaranteed to be aligned, then we also cannot guarantee to align
+ // "this" and "other" together.
+ return new EmptyAlignmentSolution("empty solution input to filter");
+ }
+
+ virtual void print() const override final {
+ tty->print_cr("empty solution: %s", reason());
+ };
+};
+
+class TrivialAlignmentSolution : public AlignmentSolution {
+public:
+ TrivialAlignmentSolution() {}
+ virtual bool is_empty() const override final { return false; }
+ virtual bool is_trivial() const override final { return true; }
+ virtual bool is_constrained() const override final { return false; }
+
+ virtual const AlignmentSolution* filter(const AlignmentSolution* other) const override final {
+ if (other->is_empty()) {
+ // If "other" cannot be guaranteed to be aligned, then we also cannot guarantee to align
+ // "this" and "other".
+ return new EmptyAlignmentSolution("empty solution input to filter");
+ }
+ // Since "this" is trivial (no constraints), the solution of "other" guarantees alignment
+ // of both.
+ return other;
+ }
+
+ virtual void print() const override final {
+ tty->print_cr("pre_iter >= 0 (trivial)");
+ };
+};
+
+class ConstrainedAlignmentSolution : public AlignmentSolution {
+private:
+ const MemNode* _mem_ref;
+ const int _q;
+ const int _r;
+ const Node* _invar;
+ const int _scale;
+public:
+ ConstrainedAlignmentSolution(const MemNode* mem_ref,
+ const int q,
+ const int r,
+ const Node* invar,
+ int scale) :
+ _mem_ref(mem_ref),
+ _q(q),
+ _r(r),
+ _invar(invar),
+ _scale(scale) {
+ assert(q > 1 && is_power_of_2(q), "q must be power of 2");
+ assert(0 <= r && r < q, "r must be in modulo space of q");
+ assert(_mem_ref != nullptr, "must have mem_ref");
+ }
+
+ virtual bool is_empty() const override final { return false; }
+ virtual bool is_trivial() const override final { return false; }
+ virtual bool is_constrained() const override final { return true; }
+
+ const MemNode* mem_ref() const { return _mem_ref; }
+
+ virtual const ConstrainedAlignmentSolution* as_constrained() const override final { return this; }
+
+ virtual const AlignmentSolution* filter(const AlignmentSolution* other) const override final {
+ if (other->is_empty()) {
+ // If "other" cannot be guaranteed to be aligned, then we also cannot guarantee to align
+ // "this" and "other" together.
+ return new EmptyAlignmentSolution("empty solution input to filter");
+ }
+ // Since "other" is trivial (no constraints), the solution of "this" guarantees alignment
+ // of both.
+ if (other->is_trivial()) {
+ return this;
+ }
+
+ // Both solutions are constrained:
+ ConstrainedAlignmentSolution const* s1 = this;
+ ConstrainedAlignmentSolution const* s2 = other->as_constrained();
+
+ // Thus, pre_iter is the intersection of two sets, i.e. constrained by these two equations,
+ // for any integers m1 and m2:
+ //
+ // pre_iter = m1 * q1 + r1
+ // [- invar1 / (scale1 * pre_stride) ]
+ // [- init / pre_stride ]
+ //
+ // pre_iter = m2 * q2 + r2
+ // [- invar2 / (scale2 * pre_stride) ]
+ // [- init / pre_stride ]
+ //
+ // Note: pre_stride and init are identical for all mem_refs in the loop.
+ //
+ // The init alignment term either does not exist for both mem_refs, or exists identically
+ // for both. The init alignment term is thus trivially identical.
+ //
+ // The invar alignment term is identical if either:
+ // - both mem_refs have no invariant.
+ // - both mem_refs have the same invariant and the same scale.
+ //
+ if (s1->_invar != s2->_invar) {
+ return new EmptyAlignmentSolution("invar not identical");
+ }
+ if (s1->_invar != nullptr && s1->_scale != s2->_scale) {
+ return new EmptyAlignmentSolution("has invar with different scale");
+ }
+
+ // Now, we have reduced the problem to:
+ //
+ // pre_iter = m1 * q1 + r1 [- x] (S1)
+ // pre_iter = m2 * q2 + r2 [- x] (S2)
+ //
+
+ // Make s2 the bigger modulo space, i.e. has larger periodicity q.
+ // This guarantees that S2 is either identical to, a subset of,
+ // or disjunct from S1 (but cannot be a strict superset of S1).
+ if (s1->_q > s2->_q) {
+ swap(s1, s2);
+ }
+ assert(s1->_q <= s2->_q, "s1 is a smaller modulo space than s2");
+
+ // Is S2 subset of (or equal to) S1?
+ //
+ // for any m2, there are integers a, b, m1: m2 * q2 + r2 =
+ // m2 * a * q1 + b * q1 + r1 =
+ // (m2 * a + b) * q1 + r1
+ //
+ // Since q1 and q2 are both powers of 2, and q1 <= q2, we know there
+ // is an integer a: a * q1 = q2. Thus, it remains to check if there
+ // is an integer b: b * q1 + r1 = r2. This is equivalent to checking:
+ //
+ // r1 = r1 % q1 = r2 % q1
+ //
+ if (mod(s2->_r, s1->_q) != s1->_r) {
+ // Neither is subset of the other -> no intersection
+ return new EmptyAlignmentSolution("empty intersection (r and q)");
+ }
+
+ // Now we know: "s1 = m1 * q1 + r1" is a superset of "s2 = m2 * q2 + r2"
+ // Hence, any solution of S2 guarantees alignment for both mem_refs.
+ return s2; // return the subset
+ }
+
+ virtual void print() const override final {
+ tty->print("m * q(%d) + r(%d)", _q, _r);
+ if (_invar != nullptr) {
+ tty->print(" - invar[%d] / (scale(%d) * pre_stride)", _invar->_idx, _scale);
+ }
+ tty->print_cr(" [- init / pre_stride], mem_ref[%d]", mem_ref()->_idx);
+ };
+};
+
+// When strict alignment is required (e.g. -XX:+AlignVector), then we must ensure
+// that all vector memory accesses can be aligned. We achieve this alignment by
+// adjusting the pre-loop limit, which adjusts the number of iterations executed
+// in the pre-loop.
+//
+// This is how the pre-loop and unrolled main-loop look like for a memref (adr):
+//
+// iv = init
+// i = 0 // single-iteration counter
+//
+// pre-loop:
+// iv = init + i * pre_stride
+// adr = base + offset + invar + scale * iv
+// adr = base + offset + invar + scale * (init + i * pre_stride)
+// iv += pre_stride
+// i++
+//
+// pre_iter = i // number of iterations in the pre-loop
+// iv = init + pre_iter * pre_stride
+//
+// main_iter = 0 // main-loop iteration counter
+// main_stride = unroll_factor * pre_stride
+//
+// main-loop:
+// i = pre_iter + main_iter * unroll_factor
+// iv = init + i * pre_stride = init + pre_iter * pre_stride + main_iter * unroll_factor * pre_stride
+// = init + pre_iter * pre_stride + main_iter * main_stride
+// adr = base + offset + invar + scale * iv // must be aligned
+// iv += main_stride
+// i += unroll_factor
+// main_iter++
+//
+// For each vector memory access, we can find the set of pre_iter (number of pre-loop
+// iterations) which would align its address. The AlignmentSolver finds such an
+// AlignmentSolution. We can then check which solutions are compatible, and thus
+// decide if we have to (partially) reject vectorization if not all vectors have
+// a compatible solutions.
+class AlignmentSolver {
+private:
+ const MemNode* _mem_ref; // first element
+ const uint _vector_length; // number of elements in vector
+ const int _element_size;
+ const int _vector_width; // in bytes
+
+ // All vector loads and stores need to be memory aligned. The alignment width (aw) in
+ // principle is the vector_width. But when vector_width > ObjectAlignmentInBytes this is
+ // too strict, since any memory object is only guaranteed to be ObjectAlignmentInBytes
+ // aligned. For example, the relative offset between two arrays is only guaranteed to
+ // be divisible by ObjectAlignmentInBytes.
+ const int _aw;
+
+ // We analyze the address of mem_ref. The idea is to disassemble it into a linear
+ // expression, where we can use the constant factors as the basis for ensuring the
+ // alignment of vector memory accesses.
+ //
+ // The Simple form of the address is disassembled by VPointer into:
+ //
+ // adr = base + offset + invar + scale * iv
+ //
+ // Where the iv can be written as:
+ //
+ // iv = init + pre_stride * pre_iter + main_stride * main_iter
+ //
+ // pre_iter: number of pre-loop iterations (adjustable via pre-loop limit)
+ // main_iter: number of main-loop iterations (main_iter >= 0)
+ //
+ const Node* _base; // base of address (e.g. Java array object, aw-aligned)
+ const int _offset;
+ const Node* _invar;
+ const int _invar_factor; // known constant factor of invar
+ const int _scale;
+ const Node* _init_node; // value of iv before pre-loop
+ const int _pre_stride; // address increment per pre-loop iteration
+ const int _main_stride; // address increment per main-loop iteration
+
+ DEBUG_ONLY( const bool _is_trace; );
+
+ static const MemNode* mem_ref_not_null(const MemNode* mem_ref) {
+ assert(mem_ref != nullptr, "not nullptr");
+ return mem_ref;
+ }
+
+public:
+ AlignmentSolver(const MemNode* mem_ref,
+ const uint vector_length,
+ const Node* base,
+ const int offset,
+ const Node* invar,
+ const int invar_factor,
+ const int scale,
+ const Node* init_node,
+ const int pre_stride,
+ const int main_stride
+ DEBUG_ONLY( COMMA const bool is_trace)
+ ) :
+ _mem_ref( mem_ref_not_null(mem_ref)),
+ _vector_length( vector_length),
+ _element_size( _mem_ref->memory_size()),
+ _vector_width( _vector_length * _element_size),
+ _aw( MIN2(_vector_width, ObjectAlignmentInBytes)),
+ _base( base),
+ _offset( offset),
+ _invar( invar),
+ _invar_factor( invar_factor),
+ _scale( scale),
+ _init_node( init_node),
+ _pre_stride( pre_stride),
+ _main_stride( main_stride)
+ DEBUG_ONLY( COMMA _is_trace(is_trace) )
+ {
+ assert(_mem_ref != nullptr &&
+ (_mem_ref->is_Load() || _mem_ref->is_Store()),
+ "only load or store vectors allowed");
+ }
+
+ AlignmentSolution* solve() const;
+
+private:
+ class EQ4 {
+ private:
+ const int _C_const;
+ const int _C_invar;
+ const int _C_init;
+ const int _C_pre;
+ const int _aw;
+
+ public:
+ EQ4(const int C_const, const int C_invar, const int C_init, const int C_pre, const int aw) :
+ _C_const(C_const), _C_invar(C_invar), _C_init(C_init), _C_pre(C_pre), _aw(aw) {}
+
+ enum State { TRIVIAL, CONSTRAINED, EMPTY };
+
+ State eq4a_state() const {
+ return (abs(_C_pre) >= _aw) ? ( (C_const_mod_aw() == 0 ) ? TRIVIAL : EMPTY)
+ : ( (C_const_mod_abs_C_pre() == 0) ? CONSTRAINED : EMPTY);
+ }
+
+ State eq4b_state() const {
+ return (abs(_C_pre) >= _aw) ? ( (C_invar_mod_aw() == 0 ) ? TRIVIAL : EMPTY)
+ : ( (C_invar_mod_abs_C_pre() == 0) ? CONSTRAINED : EMPTY);
+ }
+
+ State eq4c_state() const {
+ return (abs(_C_pre) >= _aw) ? ( (C_init_mod_aw() == 0 ) ? TRIVIAL : EMPTY)
+ : ( (C_init_mod_abs_C_pre() == 0) ? CONSTRAINED : EMPTY);
+ }
+
+ private:
+ int C_const_mod_aw() const { return AlignmentSolution::mod(_C_const, _aw); }
+ int C_invar_mod_aw() const { return AlignmentSolution::mod(_C_invar, _aw); }
+ int C_init_mod_aw() const { return AlignmentSolution::mod(_C_init, _aw); }
+ int C_const_mod_abs_C_pre() const { return AlignmentSolution::mod(_C_const, abs(_C_pre)); }
+ int C_invar_mod_abs_C_pre() const { return AlignmentSolution::mod(_C_invar, abs(_C_pre)); }
+ int C_init_mod_abs_C_pre() const { return AlignmentSolution::mod(_C_init, abs(_C_pre)); }
+
+#ifdef ASSERT
+ public:
+ void trace() const;
+
+ private:
+ static const char* state_to_str(State s) {
+ if (s == TRIVIAL) { return "trivial"; }
+ if (s == CONSTRAINED) { return "constrained"; }
+ return "empty";
+ }
+#endif
+ };
+
+#ifdef ASSERT
+ bool is_trace() const { return _is_trace; }
+ void trace_start_solve() const;
+ void trace_reshaped_form(const int C_const,
+ const int C_const_init,
+ const int C_invar,
+ const int C_init,
+ const int C_pre,
+ const int C_main) const;
+ void trace_main_iteration_alignment(const int C_const,
+ const int C_invar,
+ const int C_init,
+ const int C_pre,
+ const int C_main,
+ const int C_main_mod_aw) const;
+ void trace_constrained_solution(const int C_const,
+ const int C_invar,
+ const int C_init,
+ const int C_pre,
+ const int q,
+ const int r) const;
+#endif
+};
+
#endif // SHARE_OPTO_VECTORIZATION_HPP
diff --git a/src/hotspot/share/opto/vectornode.hpp b/src/hotspot/share/opto/vectornode.hpp
index 6992f3516aac8..e4d3d013cd384 100644
--- a/src/hotspot/share/opto/vectornode.hpp
+++ b/src/hotspot/share/opto/vectornode.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2024, 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
@@ -847,6 +847,8 @@ class ExpandVNode: public VectorNode {
//------------------------------LoadVectorNode---------------------------------
// Load Vector from memory
class LoadVectorNode : public LoadNode {
+ private:
+ DEBUG_ONLY( bool _must_verify_alignment = false; );
public:
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) {
@@ -871,6 +873,17 @@ class LoadVectorNode : public LoadNode {
uint vlen, BasicType bt,
ControlDependency control_dependency = LoadNode::DependsOnlyOnTest);
uint element_size(void) { return type2aelembytes(vect_type()->element_basic_type()); }
+
+ // Needed for proper cloning.
+ virtual uint size_of() const { return sizeof(*this); }
+
+#ifdef ASSERT
+ // When AlignVector is enabled, SuperWord only creates aligned vector loads and stores.
+ // VerifyAlignVector verifies this. We need to mark the nodes created in SuperWord,
+ // because nodes created elsewhere (i.e. VectorAPI) may still be misaligned.
+ bool must_verify_alignment() const { return _must_verify_alignment; }
+ void set_must_verify_alignment() { _must_verify_alignment = true; }
+#endif
};
//------------------------------LoadVectorGatherNode------------------------------
@@ -894,6 +907,7 @@ class LoadVectorGatherNode : public LoadVectorNode {
class StoreVectorNode : public StoreNode {
private:
const TypeVect* _vect_type;
+ DEBUG_ONLY( bool _must_verify_alignment = false; );
public:
StoreVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
: StoreNode(c, mem, adr, at, val, MemNode::unordered), _vect_type(val->bottom_type()->is_vect()) {
@@ -918,6 +932,14 @@ class StoreVectorNode : public StoreNode {
// Needed for proper cloning.
virtual uint size_of() const { return sizeof(*this); }
+
+#ifdef ASSERT
+ // When AlignVector is enabled, SuperWord only creates aligned vector loads and stores.
+ // VerifyAlignVector verifies this. We need to mark the nodes created in SuperWord,
+ // because nodes created elsewhere (i.e. VectorAPI) may still be misaligned.
+ bool must_verify_alignment() const { return _must_verify_alignment; }
+ void set_must_verify_alignment() { _must_verify_alignment = true; }
+#endif
};
//------------------------------StoreVectorScatterNode------------------------------
@@ -1017,6 +1039,25 @@ class StoreVectorScatterMaskedNode : public StoreVectorNode {
idx == MemNode::ValueIn + 2; }
};
+// Verify that memory address (adr) is aligned. The mask specifies the
+// least significant bits which have to be zero in the address.
+//
+// if (adr & mask == 0) {
+// return adr
+// } else {
+// stop("verify_vector_alignment found a misaligned vector memory access")
+// }
+//
+// This node is used just before a vector load/store with -XX:+VerifyAlignVector
+class VerifyVectorAlignmentNode : public Node {
+ virtual uint hash() const { return NO_HASH; };
+public:
+ VerifyVectorAlignmentNode(Node* adr, Node* mask) : Node(nullptr, adr, mask) {}
+ virtual int Opcode() const;
+ virtual uint size_of() const { return sizeof(*this); }
+ virtual const Type *bottom_type() const { return in(1)->bottom_type(); }
+};
+
//------------------------------VectorCmpMaskedNode--------------------------------
// Vector Comparison under the influence of a predicate register(mask).
class VectorCmpMaskedNode : public TypeNode {
diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestVectorizationMismatchedAccess.java b/test/hotspot/jtreg/compiler/c2/irTests/TestVectorizationMismatchedAccess.java
index 3b7bf23173051..b68ddfe2799ce 100644
--- a/test/hotspot/jtreg/compiler/c2/irTests/TestVectorizationMismatchedAccess.java
+++ b/test/hotspot/jtreg/compiler/c2/irTests/TestVectorizationMismatchedAccess.java
@@ -50,13 +50,10 @@ public class TestVectorizationMismatchedAccess {
private final static WhiteBox wb = WhiteBox.getWhiteBox();
public static void main(String[] args) {
- Object alignVector = wb.getVMFlag("AlignVector");
- if (alignVector != null && !((Boolean)alignVector)) {
- if (ByteOrder.nativeOrder() != ByteOrder.LITTLE_ENDIAN) {
- throw new RuntimeException("fix test that was written for a little endian platform");
- }
- TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED");
+ if (ByteOrder.nativeOrder() != ByteOrder.LITTLE_ENDIAN) {
+ throw new RuntimeException("fix test that was written for a little endian platform");
}
+ TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED");
}
static int size = 1024;
@@ -189,7 +186,9 @@ public static void testByteLong3_runner() {
}
@Test
- @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" })
+ @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" },
+ applyIf = {"AlignVector", "false"})
+ // AlignVector cannot guarantee that invar is aligned.
public static void testByteLong4(byte[] dest, long[] src, int start, int stop) {
for (int i = start; i < stop; i++) {
UNSAFE.putLongUnaligned(dest, 8 * i + baseOffset, src[i]);
@@ -323,7 +322,9 @@ public static void testOffHeapLong3_runner() {
}
@Test
- @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" })
+ @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" },
+ applyIf = {"AlignVector", "false"})
+ // AlignVector cannot guarantee that invar is aligned.
public static void testOffHeapLong4(long dest, long[] src, int start, int stop) {
for (int i = start; i < stop; i++) {
UNSAFE.putLongUnaligned(null, dest + 8 * i + baseOffset, src[i]);
diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java
index be508bbb81e1a..67fadbc4eac31 100644
--- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java
+++ b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024, 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
@@ -135,6 +135,7 @@ public class TestFramework {
"CompileThreshold",
"Xmixed",
"server",
+ "AlignVector",
"UseAVX",
"UseSSE",
"UseSVE",
diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestAlignVector.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestAlignVector.java
new file mode 100644
index 0000000000000..fe873770ab44d
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestAlignVector.java
@@ -0,0 +1,1479 @@
+/*
+ * Copyright (c) 2024, 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.loopopts.superword;
+
+import compiler.lib.ir_framework.*;
+import jdk.test.lib.Utils;
+import jdk.test.whitebox.WhiteBox;
+import jdk.internal.misc.Unsafe;
+import java.lang.reflect.Array;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Random;
+import java.nio.ByteOrder;
+
+/*
+ * @test id=NoAlignVector
+ * @bug 8310190
+ * @summary Test AlignVector with various loop init, stride, scale, invar, etc.
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib /
+ * @requires vm.compiler2.enabled
+ * @run driver compiler.loopopts.superword.TestAlignVector NoAlignVector
+ */
+
+/*
+ * @test id=AlignVector
+ * @bug 8310190
+ * @summary Test AlignVector with various loop init, stride, scale, invar, etc.
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib /
+ * @requires vm.compiler2.enabled
+ * @run driver compiler.loopopts.superword.TestAlignVector AlignVector
+ */
+
+/*
+ * @test id=VerifyAlignVector
+ * @bug 8310190
+ * @summary Test AlignVector with various loop init, stride, scale, invar, etc.
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib /
+ * @requires vm.compiler2.enabled
+ * @run driver compiler.loopopts.superword.TestAlignVector VerifyAlignVector
+ */
+
+public class TestAlignVector {
+ static int RANGE = 1024*8;
+ static int RANGE_FINAL = 1024*8;
+ private static final Unsafe UNSAFE = Unsafe.getUnsafe();
+ private static final Random RANDOM = Utils.getRandomInstance();
+
+ // Inputs
+ byte[] aB;
+ byte[] bB;
+ byte mB = (byte)31;
+ short[] aS;
+ short[] bS;
+ short mS = (short)0xF0F0;
+ int[] aI;
+ int[] bI;
+ int mI = 0xF0F0F0F0;
+ long[] aL;
+ long[] bL;
+ long mL = 0xF0F0F0F0F0F0F0F0L;
+
+ // List of tests
+ Map tests = new HashMap();
+
+ // List of gold, the results from the first run before compilation
+ Map golds = new HashMap();
+
+ interface TestFunction {
+ Object[] run();
+ }
+
+ public static void main(String[] args) {
+ TestFramework framework = new TestFramework(TestAlignVector.class);
+ framework.addFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED",
+ "-XX:LoopUnrollLimit=250");
+
+ switch (args[0]) {
+ case "NoAlignVector" -> { framework.addFlags("-XX:-AlignVector"); }
+ case "AlignVector" -> { framework.addFlags("-XX:+AlignVector"); }
+ case "VerifyAlignVector" -> { framework.addFlags("-XX:+AlignVector", "-XX:+IgnoreUnrecognizedVMOptions", "-XX:+VerifyAlignVector"); }
+ default -> { throw new RuntimeException("Test argument not recognized: " + args[0]); }
+ }
+ framework.start();
+ }
+
+ public TestAlignVector() {
+ // Generate input once
+ aB = generateB();
+ bB = generateB();
+ aS = generateS();
+ bS = generateS();
+ aI = generateI();
+ bI = generateI();
+ aL = generateL();
+ bL = generateL();
+
+ // Add all tests to list
+ tests.put("test0", () -> { return test0(aB.clone(), bB.clone(), mB); });
+ tests.put("test1", () -> { return test1(aB.clone(), bB.clone(), mB); });
+ tests.put("test2", () -> { return test2(aB.clone(), bB.clone(), mB); });
+ tests.put("test3", () -> { return test3(aB.clone(), bB.clone(), mB); });
+ tests.put("test4", () -> { return test4(aB.clone(), bB.clone(), mB); });
+ tests.put("test5", () -> { return test5(aB.clone(), bB.clone(), mB, 0); });
+ tests.put("test6", () -> { return test6(aB.clone(), bB.clone(), mB); });
+ tests.put("test7", () -> { return test7(aS.clone(), bS.clone(), mS); });
+ tests.put("test8", () -> { return test8(aB.clone(), bB.clone(), mB, 0); });
+ tests.put("test8", () -> { return test8(aB.clone(), bB.clone(), mB, 1); });
+ tests.put("test9", () -> { return test9(aB.clone(), bB.clone(), mB); });
+
+ tests.put("test10a", () -> { return test10a(aB.clone(), bB.clone(), mB); });
+ tests.put("test10b", () -> { return test10b(aB.clone(), bB.clone(), mB); });
+ tests.put("test10c", () -> { return test10c(aS.clone(), bS.clone(), mS); });
+ tests.put("test10d", () -> { return test10d(aS.clone(), bS.clone(), mS); });
+
+ tests.put("test11aB", () -> { return test11aB(aB.clone(), bB.clone(), mB); });
+ tests.put("test11aS", () -> { return test11aS(aS.clone(), bS.clone(), mS); });
+ tests.put("test11aI", () -> { return test11aI(aI.clone(), bI.clone(), mI); });
+ tests.put("test11aL", () -> { return test11aL(aL.clone(), bL.clone(), mL); });
+
+ tests.put("test11bB", () -> { return test11bB(aB.clone(), bB.clone(), mB); });
+ tests.put("test11bS", () -> { return test11bS(aS.clone(), bS.clone(), mS); });
+ tests.put("test11bI", () -> { return test11bI(aI.clone(), bI.clone(), mI); });
+ tests.put("test11bL", () -> { return test11bL(aL.clone(), bL.clone(), mL); });
+
+ tests.put("test11cB", () -> { return test11cB(aB.clone(), bB.clone(), mB); });
+ tests.put("test11cS", () -> { return test11cS(aS.clone(), bS.clone(), mS); });
+ tests.put("test11cI", () -> { return test11cI(aI.clone(), bI.clone(), mI); });
+ tests.put("test11cL", () -> { return test11cL(aL.clone(), bL.clone(), mL); });
+
+ tests.put("test11dB", () -> { return test11dB(aB.clone(), bB.clone(), mB, 0); });
+ tests.put("test11dS", () -> { return test11dS(aS.clone(), bS.clone(), mS, 0); });
+ tests.put("test11dI", () -> { return test11dI(aI.clone(), bI.clone(), mI, 0); });
+ tests.put("test11dL", () -> { return test11dL(aL.clone(), bL.clone(), mL, 0); });
+
+ tests.put("test12", () -> { return test12(aB.clone(), bB.clone(), mB); });
+
+ tests.put("test13aIL", () -> { return test13aIL(aI.clone(), aL.clone()); });
+ tests.put("test13aIB", () -> { return test13aIB(aI.clone(), aB.clone()); });
+ tests.put("test13aIS", () -> { return test13aIS(aI.clone(), aS.clone()); });
+ tests.put("test13aBSIL", () -> { return test13aBSIL(aB.clone(), aS.clone(), aI.clone(), aL.clone()); });
+
+ tests.put("test13bIL", () -> { return test13bIL(aI.clone(), aL.clone()); });
+ tests.put("test13bIB", () -> { return test13bIB(aI.clone(), aB.clone()); });
+ tests.put("test13bIS", () -> { return test13bIS(aI.clone(), aS.clone()); });
+ tests.put("test13bBSIL", () -> { return test13bBSIL(aB.clone(), aS.clone(), aI.clone(), aL.clone()); });
+
+ tests.put("test14aB", () -> { return test14aB(aB.clone()); });
+ tests.put("test14bB", () -> { return test14bB(aB.clone()); });
+ tests.put("test14cB", () -> { return test14cB(aB.clone()); });
+
+ tests.put("test15aB", () -> { return test15aB(aB.clone()); });
+ tests.put("test15bB", () -> { return test15bB(aB.clone()); });
+ tests.put("test15cB", () -> { return test15cB(aB.clone()); });
+
+ tests.put("test16a", () -> { return test16a(aB.clone(), aS.clone()); });
+ tests.put("test16b", () -> { return test16b(aB.clone()); });
+
+ tests.put("test17a", () -> { return test17a(aL.clone()); });
+ tests.put("test17b", () -> { return test17b(aL.clone()); });
+ tests.put("test17c", () -> { return test17c(aL.clone()); });
+ tests.put("test17d", () -> { return test17d(aL.clone()); });
+
+ tests.put("test18a", () -> { return test18a(aB.clone(), aI.clone()); });
+ tests.put("test18b", () -> { return test18b(aB.clone(), aI.clone()); });
+
+ tests.put("test19", () -> { return test19(aI.clone(), bI.clone()); });
+ tests.put("test20", () -> { return test20(aB.clone()); });
+
+ // Compute gold value for all test methods before compilation
+ for (Map.Entry entry : tests.entrySet()) {
+ String name = entry.getKey();
+ TestFunction test = entry.getValue();
+ Object[] gold = test.run();
+ golds.put(name, gold);
+ }
+ }
+
+ @Warmup(100)
+ @Run(test = {"test0",
+ "test1",
+ "test2",
+ "test3",
+ "test4",
+ "test5",
+ "test6",
+ "test7",
+ "test8",
+ "test9",
+ "test10a",
+ "test10b",
+ "test10c",
+ "test10d",
+ "test11aB",
+ "test11aS",
+ "test11aI",
+ "test11aL",
+ "test11bB",
+ "test11bS",
+ "test11bI",
+ "test11bL",
+ "test11cB",
+ "test11cS",
+ "test11cI",
+ "test11cL",
+ "test11dB",
+ "test11dS",
+ "test11dI",
+ "test11dL",
+ "test12",
+ "test13aIL",
+ "test13aIB",
+ "test13aIS",
+ "test13aBSIL",
+ "test13bIL",
+ "test13bIB",
+ "test13bIS",
+ "test13bBSIL",
+ "test14aB",
+ "test14bB",
+ "test14cB",
+ "test15aB",
+ "test15bB",
+ "test15cB",
+ "test16a",
+ "test16b",
+ "test17a",
+ "test17b",
+ "test17c",
+ "test17d",
+ "test18a",
+ "test18b",
+ "test19",
+ "test20"})
+ public void runTests() {
+ for (Map.Entry entry : tests.entrySet()) {
+ String name = entry.getKey();
+ TestFunction test = entry.getValue();
+ // Recall gold value from before compilation
+ Object[] gold = golds.get(name);
+ // Compute new result
+ Object[] result = test.run();
+ // Compare gold and new result
+ verify(name, gold, result);
+ }
+ }
+
+ static byte[] generateB() {
+ byte[] a = new byte[RANGE];
+ for (int i = 0; i < a.length; i++) {
+ a[i] = (byte)RANDOM.nextInt();
+ }
+ return a;
+ }
+
+ static short[] generateS() {
+ short[] a = new short[RANGE];
+ for (int i = 0; i < a.length; i++) {
+ a[i] = (short)RANDOM.nextInt();
+ }
+ return a;
+ }
+
+ static int[] generateI() {
+ int[] a = new int[RANGE];
+ for (int i = 0; i < a.length; i++) {
+ a[i] = RANDOM.nextInt();
+ }
+ return a;
+ }
+
+ static long[] generateL() {
+ long[] a = new long[RANGE];
+ for (int i = 0; i < a.length; i++) {
+ a[i] = RANDOM.nextLong();
+ }
+ return a;
+ }
+
+ static void verify(String name, Object[] gold, Object[] result) {
+ if (gold.length != result.length) {
+ throw new RuntimeException("verify " + name + ": not the same number of outputs: gold.length = " +
+ gold.length + ", result.length = " + result.length);
+ }
+ for (int i = 0; i < gold.length; i++) {
+ Object g = gold[i];
+ Object r = result[i];
+ if (g.getClass() != r.getClass() || !g.getClass().isArray() || !r.getClass().isArray()) {
+ throw new RuntimeException("verify " + name + ": must both be array of same type:" +
+ " gold[" + i + "].getClass() = " + g.getClass().getSimpleName() +
+ " result[" + i + "].getClass() = " + r.getClass().getSimpleName());
+ }
+ if (g == r) {
+ throw new RuntimeException("verify " + name + ": should be two separate arrays (with identical content):" +
+ " gold[" + i + "] == result[" + i + "]");
+ }
+ if (Array.getLength(g) != Array.getLength(r)) {
+ throw new RuntimeException("verify " + name + ": arrays must have same length:" +
+ " gold[" + i + "].length = " + Array.getLength(g) +
+ " result[" + i + "].length = " + Array.getLength(r));
+ }
+ Class c = g.getClass().getComponentType();
+ if (c == byte.class) {
+ verifyB(name, i, (byte[])g, (byte[])r);
+ } else if (c == short.class) {
+ verifyS(name, i, (short[])g, (short[])r);
+ } else if (c == int.class) {
+ verifyI(name, i, (int[])g, (int[])r);
+ } else if (c == long.class) {
+ verifyL(name, i, (long[])g, (long[])r);
+ } else {
+ throw new RuntimeException("verify " + name + ": array type not supported for verify:" +
+ " gold[" + i + "].getClass() = " + g.getClass().getSimpleName() +
+ " result[" + i + "].getClass() = " + r.getClass().getSimpleName());
+ }
+ }
+ }
+
+ static void verifyB(String name, int i, byte[] g, byte[] r) {
+ for (int j = 0; j < g.length; j++) {
+ if (g[j] != r[j]) {
+ throw new RuntimeException("verify " + name + ": arrays must have same content:" +
+ " gold[" + i + "][" + j + "] = " + g[j] +
+ " result[" + i + "][" + j + "] = " + r[j]);
+ }
+ }
+ }
+
+ static void verifyS(String name, int i, short[] g, short[] r) {
+ for (int j = 0; j < g.length; j++) {
+ if (g[j] != r[j]) {
+ throw new RuntimeException("verify " + name + ": arrays must have same content:" +
+ " gold[" + i + "][" + j + "] = " + g[j] +
+ " result[" + i + "][" + j + "] = " + r[j]);
+ }
+ }
+ }
+
+ static void verifyI(String name, int i, int[] g, int[] r) {
+ for (int j = 0; j < g.length; j++) {
+ if (g[j] != r[j]) {
+ throw new RuntimeException("verify " + name + ": arrays must have same content:" +
+ " gold[" + i + "][" + j + "] = " + g[j] +
+ " result[" + i + "][" + j + "] = " + r[j]);
+ }
+ }
+ }
+
+ static void verifyL(String name, int i, long[] g, long[] r) {
+ for (int j = 0; j < g.length; j++) {
+ if (g[j] != r[j]) {
+ throw new RuntimeException("verify " + name + ": arrays must have same content:" +
+ " gold[" + i + "][" + j + "] = " + g[j] +
+ " result[" + i + "][" + j + "] = " + r[j]);
+ }
+ }
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.AND_VB, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIf = {"MaxVectorSize", ">=8"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ static Object[] test0(byte[] a, byte[] b, byte mask) {
+ for (int i = 0; i < RANGE; i+=8) {
+ // Safe to vectorize with AlignVector
+ b[i+0] = (byte)(a[i+0] & mask); // offset 0, align 0
+ b[i+1] = (byte)(a[i+1] & mask);
+ b[i+2] = (byte)(a[i+2] & mask);
+ b[i+3] = (byte)(a[i+3] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0",
+ IRNode.AND_VB, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
+ static Object[] test1(byte[] a, byte[] b, byte mask) {
+ for (int i = 0; i < RANGE; i+=8) {
+ // Safe to vectorize with AlignVector
+ b[i+0] = (byte)(a[i+0] & mask); // offset 0, align 0
+ b[i+1] = (byte)(a[i+1] & mask);
+ b[i+2] = (byte)(a[i+2] & mask);
+ b[i+3] = (byte)(a[i+3] & mask);
+ b[i+4] = (byte)(a[i+4] & mask);
+ b[i+5] = (byte)(a[i+5] & mask);
+ b[i+6] = (byte)(a[i+6] & mask);
+ b[i+7] = (byte)(a[i+7] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.AND_VB, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">=8"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "= 0",
+ IRNode.AND_VB, "= 0",
+ IRNode.STORE_VECTOR, "= 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "true"})
+ static Object[] test2(byte[] a, byte[] b, byte mask) {
+ for (int i = 0; i < RANGE; i+=8) {
+ // Cannot align with AlignVector: 3 + x * 8 % 8 = 3
+ b[i+3] = (byte)(a[i+3] & mask); // at alignment 3
+ b[i+4] = (byte)(a[i+4] & mask);
+ b[i+5] = (byte)(a[i+5] & mask);
+ b[i+6] = (byte)(a[i+6] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.AND_VB, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">=8"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "= 0",
+ IRNode.AND_VB, "= 0",
+ IRNode.STORE_VECTOR, "= 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "true"})
+ static Object[] test3(byte[] a, byte[] b, byte mask) {
+ for (int i = 0; i < RANGE; i+=8) {
+ // Cannot align with AlignVector: 3 + x * 8 % 8 = 3
+
+ // Problematic for AlignVector
+ b[i+0] = (byte)(a[i+0] & mask); // best_memref, align 0
+
+ b[i+3] = (byte)(a[i+3] & mask); // pack at offset 3 bytes
+ b[i+4] = (byte)(a[i+4] & mask);
+ b[i+5] = (byte)(a[i+5] & mask);
+ b[i+6] = (byte)(a[i+6] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE_8, "> 0",
+ IRNode.AND_VB, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.AND_VB, IRNode.VECTOR_SIZE_8, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">=16"})
+ @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE_8, "= 0",// unaligned
+ IRNode.AND_VB, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.AND_VB, IRNode.VECTOR_SIZE_8, "= 0",// unaligned
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">=16"})
+ static Object[] test4(byte[] a, byte[] b, byte mask) {
+ for (int i = 0; i < RANGE/16; i++) {
+ // Problematic for AlignVector
+ b[i*16 + 0 ] = (byte)(a[i*16 + 0 ] & mask); // 4 pack, 0 aligned
+ b[i*16 + 1 ] = (byte)(a[i*16 + 1 ] & mask);
+ b[i*16 + 2 ] = (byte)(a[i*16 + 2 ] & mask);
+ b[i*16 + 3 ] = (byte)(a[i*16 + 3 ] & mask);
+
+ b[i*16 + 5 ] = (byte)(a[i*16 + 5 ] & mask); // 8 pack, 5 aligned
+ b[i*16 + 6 ] = (byte)(a[i*16 + 6 ] & mask);
+ b[i*16 + 7 ] = (byte)(a[i*16 + 7 ] & mask);
+ b[i*16 + 8 ] = (byte)(a[i*16 + 8 ] & mask);
+ b[i*16 + 9 ] = (byte)(a[i*16 + 9 ] & mask);
+ b[i*16 + 10] = (byte)(a[i*16 + 10] & mask);
+ b[i*16 + 11] = (byte)(a[i*16 + 11] & mask);
+ b[i*16 + 12] = (byte)(a[i*16 + 12] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.AND_VB, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">=8"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "= 0",
+ IRNode.AND_VB, "= 0",
+ IRNode.STORE_VECTOR, "= 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "true"})
+ static Object[] test5(byte[] a, byte[] b, byte mask, int inv) {
+ for (int i = 0; i < RANGE; i+=8) {
+ // Cannot align with AlignVector because of invariant
+ b[i+inv+0] = (byte)(a[i+inv+0] & mask);
+
+ b[i+inv+3] = (byte)(a[i+inv+3] & mask);
+ b[i+inv+4] = (byte)(a[i+inv+4] & mask);
+ b[i+inv+5] = (byte)(a[i+inv+5] & mask);
+ b[i+inv+6] = (byte)(a[i+inv+6] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.AND_VB, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">=8"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "= 0",
+ IRNode.AND_VB, "= 0",
+ IRNode.STORE_VECTOR, "= 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "true"})
+ static Object[] test6(byte[] a, byte[] b, byte mask) {
+ for (int i = 0; i < RANGE/8; i+=2) {
+ // Cannot align with AlignVector because offset is odd
+ b[i*4+0] = (byte)(a[i*4+0] & mask);
+
+ b[i*4+3] = (byte)(a[i*4+3] & mask);
+ b[i*4+4] = (byte)(a[i*4+4] & mask);
+ b[i*4+5] = (byte)(a[i*4+5] & mask);
+ b[i*4+6] = (byte)(a[i*4+6] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.AND_VS, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">=16"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "= 0",
+ IRNode.AND_VS, "= 0",
+ IRNode.STORE_VECTOR, "= 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "true"})
+ static Object[] test7(short[] a, short[] b, short mask) {
+ for (int i = 0; i < RANGE/8; i+=2) {
+ // Cannot align with AlignVector because offset is odd
+ b[i*4+0] = (short)(a[i*4+0] & mask);
+
+ b[i*4+3] = (short)(a[i*4+3] & mask);
+ b[i*4+4] = (short)(a[i*4+4] & mask);
+ b[i*4+5] = (short)(a[i*4+5] & mask);
+ b[i*4+6] = (short)(a[i*4+6] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.AND_VB, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">=8"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "= 0",
+ IRNode.AND_VB, "= 0",
+ IRNode.STORE_VECTOR, "= 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "true"})
+ static Object[] test8(byte[] a, byte[] b, byte mask, int init) {
+ for (int i = init; i < RANGE; i+=8) {
+ // Cannot align with AlignVector because of invariant (variable init becomes invar)
+ b[i+0] = (byte)(a[i+0] & mask);
+
+ b[i+3] = (byte)(a[i+3] & mask);
+ b[i+4] = (byte)(a[i+4] & mask);
+ b[i+5] = (byte)(a[i+5] & mask);
+ b[i+6] = (byte)(a[i+6] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.AND_VB, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIf = {"MaxVectorSize", ">=8"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ static Object[] test9(byte[] a, byte[] b, byte mask) {
+ // known non-zero init value does not affect offset, but has implicit effect on iv
+ for (int i = 13; i < RANGE-8; i+=8) {
+ b[i+0] = (byte)(a[i+0] & mask);
+
+ b[i+3] = (byte)(a[i+3] & mask);
+ b[i+4] = (byte)(a[i+4] & mask);
+ b[i+5] = (byte)(a[i+5] & mask);
+ b[i+6] = (byte)(a[i+6] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.AND_VB, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">=8"})
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "= 0",
+ IRNode.AND_VB, "= 0",
+ IRNode.STORE_VECTOR, "= 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "true"})
+ static Object[] test10a(byte[] a, byte[] b, byte mask) {
+ // This is not alignable with pre-loop, because of odd init.
+ for (int i = 3; i < RANGE-8; i+=8) {
+ b[i+0] = (byte)(a[i+0] & mask);
+ b[i+1] = (byte)(a[i+1] & mask);
+ b[i+2] = (byte)(a[i+2] & mask);
+ b[i+3] = (byte)(a[i+3] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.AND_VB, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">=8"})
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "= 0",
+ IRNode.AND_VB, "= 0",
+ IRNode.STORE_VECTOR, "= 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "true"})
+ static Object[] test10b(byte[] a, byte[] b, byte mask) {
+ // This is not alignable with pre-loop, because of odd init.
+ // Seems not correctly handled.
+ for (int i = 13; i < RANGE-8; i+=8) {
+ b[i+0] = (byte)(a[i+0] & mask);
+ b[i+1] = (byte)(a[i+1] & mask);
+ b[i+2] = (byte)(a[i+2] & mask);
+ b[i+3] = (byte)(a[i+3] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.AND_VS, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">=16"})
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "= 0",
+ IRNode.AND_VS, "= 0",
+ IRNode.STORE_VECTOR, "= 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "true"})
+ static Object[] test10c(short[] a, short[] b, short mask) {
+ // This is not alignable with pre-loop, because of odd init.
+ // Seems not correctly handled with MaxVectorSize >= 32.
+ for (int i = 13; i < RANGE-8; i+=8) {
+ b[i+0] = (short)(a[i+0] & mask);
+ b[i+1] = (short)(a[i+1] & mask);
+ b[i+2] = (short)(a[i+2] & mask);
+ b[i+3] = (short)(a[i+3] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.AND_VS, IRNode.VECTOR_SIZE_4, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIf = {"MaxVectorSize", ">=16"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
+ static Object[] test10d(short[] a, short[] b, short mask) {
+ for (int i = 13; i < RANGE-16; i+=8) {
+ // init + offset -> aligned
+ b[i+0+3] = (short)(a[i+0+3] & mask);
+ b[i+1+3] = (short)(a[i+1+3] & mask);
+ b[i+2+3] = (short)(a[i+2+3] & mask);
+ b[i+3+3] = (short)(a[i+3+3] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0",
+ IRNode.AND_VB, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ static Object[] test11aB(byte[] a, byte[] b, byte mask) {
+ for (int i = 0; i < RANGE; i++) {
+ // always alignable
+ b[i+0] = (byte)(a[i+0] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0",
+ IRNode.AND_VS, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ static Object[] test11aS(short[] a, short[] b, short mask) {
+ for (int i = 0; i < RANGE; i++) {
+ // always alignable
+ b[i+0] = (short)(a[i+0] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0",
+ IRNode.AND_VI, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ static Object[] test11aI(int[] a, int[] b, int mask) {
+ for (int i = 0; i < RANGE; i++) {
+ // always alignable
+ b[i+0] = (int)(a[i+0] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0",
+ IRNode.AND_VL, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ static Object[] test11aL(long[] a, long[] b, long mask) {
+ for (int i = 0; i < RANGE; i++) {
+ // always alignable
+ b[i+0] = (long)(a[i+0] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0",
+ IRNode.AND_VB, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ static Object[] test11bB(byte[] a, byte[] b, byte mask) {
+ for (int i = 1; i < RANGE; i++) {
+ // always alignable
+ b[i+0] = (byte)(a[i+0] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0",
+ IRNode.AND_VS, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ static Object[] test11bS(short[] a, short[] b, short mask) {
+ for (int i = 1; i < RANGE; i++) {
+ // always alignable
+ b[i+0] = (short)(a[i+0] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0",
+ IRNode.AND_VI, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ static Object[] test11bI(int[] a, int[] b, int mask) {
+ for (int i = 1; i < RANGE; i++) {
+ // always alignable
+ b[i+0] = (int)(a[i+0] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0",
+ IRNode.AND_VL, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ static Object[] test11bL(long[] a, long[] b, long mask) {
+ for (int i = 1; i < RANGE; i++) {
+ // always alignable
+ b[i+0] = (long)(a[i+0] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0",
+ IRNode.AND_VB, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "false"})
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "= 0",
+ IRNode.AND_VB, "= 0",
+ IRNode.STORE_VECTOR, "= 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "true"})
+ static Object[] test11cB(byte[] a, byte[] b, byte mask) {
+ for (int i = 1; i < RANGE-1; i++) {
+ // 1 byte offset -> not alignable with AlignVector
+ b[i+0] = (byte)(a[i+1] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0",
+ IRNode.AND_VS, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "false"})
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "= 0",
+ IRNode.AND_VS, "= 0",
+ IRNode.STORE_VECTOR, "= 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "true"})
+ static Object[] test11cS(short[] a, short[] b, short mask) {
+ for (int i = 1; i < RANGE-1; i++) {
+ // 2 byte offset -> not alignable with AlignVector
+ b[i+0] = (short)(a[i+1] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0",
+ IRNode.AND_VI, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "false"})
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "= 0",
+ IRNode.AND_VI, "= 0",
+ IRNode.STORE_VECTOR, "= 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "true"})
+ static Object[] test11cI(int[] a, int[] b, int mask) {
+ for (int i = 1; i < RANGE-1; i++) {
+ // 4 byte offset -> not alignable with AlignVector
+ b[i+0] = (int)(a[i+1] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0",
+ IRNode.AND_VL, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ static Object[] test11cL(long[] a, long[] b, long mask) {
+ for (int i = 1; i < RANGE-1; i++) {
+ // always alignable (8 byte offset)
+ b[i+0] = (long)(a[i+1] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0",
+ IRNode.AND_VB, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ static Object[] test11dB(byte[] a, byte[] b, byte mask, int invar) {
+ for (int i = 0; i < RANGE; i++) {
+ b[i+0+invar] = (byte)(a[i+0+invar] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0",
+ IRNode.AND_VS, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ static Object[] test11dS(short[] a, short[] b, short mask, int invar) {
+ for (int i = 0; i < RANGE; i++) {
+ b[i+0+invar] = (short)(a[i+0+invar] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0",
+ IRNode.AND_VI, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ static Object[] test11dI(int[] a, int[] b, int mask, int invar) {
+ for (int i = 0; i < RANGE; i++) {
+ b[i+0+invar] = (int)(a[i+0+invar] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0",
+ IRNode.AND_VL, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ static Object[] test11dL(long[] a, long[] b, long mask, int invar) {
+ for (int i = 0; i < RANGE; i++) {
+ b[i+0+invar] = (long)(a[i+0+invar] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "= 0",
+ IRNode.AND_VB, "= 0",
+ IRNode.STORE_VECTOR, "= 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ static Object[] test12(byte[] a, byte[] b, byte mask) {
+ for (int i = 0; i < RANGE/16; i++) {
+ // Currently does not vectorize at all
+ b[i*6 + 0 ] = (byte)(a[i*6 + 0 ] & mask);
+ b[i*6 + 1 ] = (byte)(a[i*6 + 1 ] & mask);
+ b[i*6 + 2 ] = (byte)(a[i*6 + 2 ] & mask);
+ b[i*6 + 3 ] = (byte)(a[i*6 + 3 ] & mask);
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_long)", "> 0",
+ IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_int, max_long)", "> 0",
+ IRNode.ADD_VI, IRNode.VECTOR_SIZE + "min(max_int, max_long)", "> 0",
+ IRNode.ADD_VL, IRNode.VECTOR_SIZE + "min(max_int, max_long)", "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"avx2", "true"})
+ // require avx to ensure vectors are larger than what unrolling produces
+ static Object[] test13aIL(int[] a, long[] b) {
+ for (int i = 0; i < RANGE; i++) {
+ a[i]++;
+ b[i]++;
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0",
+ IRNode.LOAD_VECTOR_I, "> 0",
+ IRNode.ADD_VB, "> 0",
+ IRNode.ADD_VI, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
+ static Object[] test13aIB(int[] a, byte[] b) {
+ for (int i = 0; i < RANGE; i++) {
+ a[i]++;
+ b[i]++;
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0",
+ IRNode.LOAD_VECTOR_S, "> 0",
+ IRNode.ADD_VI, "> 0",
+ IRNode.ADD_VS, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
+ static Object[] test13aIS(int[] a, short[] b) {
+ for (int i = 0; i < RANGE; i++) {
+ a[i]++;
+ b[i]++;
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0",
+ IRNode.LOAD_VECTOR_S, "> 0",
+ IRNode.LOAD_VECTOR_I, "> 0",
+ IRNode.LOAD_VECTOR_L, "> 0",
+ IRNode.ADD_VB, "> 0",
+ IRNode.ADD_VS, "> 0",
+ IRNode.ADD_VI, "> 0",
+ IRNode.ADD_VL, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
+ static Object[] test13aBSIL(byte[] a, short[] b, int[] c, long[] d) {
+ for (int i = 0; i < RANGE; i++) {
+ a[i]++;
+ b[i]++;
+ c[i]++;
+ d[i]++;
+ }
+ return new Object[]{ a, b, c, d };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_long)", "> 0",
+ IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_int, max_long)", "> 0",
+ IRNode.ADD_VI, IRNode.VECTOR_SIZE + "min(max_int, max_long)", "> 0",
+ IRNode.ADD_VL, IRNode.VECTOR_SIZE + "min(max_int, max_long)", "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"avx2", "true"})
+ // require avx to ensure vectors are larger than what unrolling produces
+ static Object[] test13bIL(int[] a, long[] b) {
+ for (int i = 1; i < RANGE; i++) {
+ a[i]++;
+ b[i]++;
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0",
+ IRNode.LOAD_VECTOR_I, "> 0",
+ IRNode.ADD_VB, "> 0",
+ IRNode.ADD_VI, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
+ static Object[] test13bIB(int[] a, byte[] b) {
+ for (int i = 1; i < RANGE; i++) {
+ a[i]++;
+ b[i]++;
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0",
+ IRNode.LOAD_VECTOR_S, "> 0",
+ IRNode.ADD_VI, "> 0",
+ IRNode.ADD_VS, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
+ static Object[] test13bIS(int[] a, short[] b) {
+ for (int i = 1; i < RANGE; i++) {
+ a[i]++;
+ b[i]++;
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0",
+ IRNode.LOAD_VECTOR_S, "> 0",
+ IRNode.LOAD_VECTOR_I, "> 0",
+ IRNode.LOAD_VECTOR_L, "> 0",
+ IRNode.ADD_VB, "> 0",
+ IRNode.ADD_VS, "> 0",
+ IRNode.ADD_VI, "> 0",
+ IRNode.ADD_VL, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
+ static Object[] test13bBSIL(byte[] a, short[] b, int[] c, long[] d) {
+ for (int i = 1; i < RANGE; i++) {
+ a[i]++;
+ b[i]++;
+ c[i]++;
+ d[i]++;
+ }
+ return new Object[]{ a, b, c, d };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0",
+ IRNode.ADD_VB, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "false"})
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "= 0",
+ IRNode.ADD_VB, "= 0",
+ IRNode.STORE_VECTOR, "= 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "true"})
+ static Object[] test14aB(byte[] a) {
+ // non-power-of-2 stride
+ for (int i = 0; i < RANGE-20; i+=9) {
+ a[i+0]++;
+ a[i+1]++;
+ a[i+2]++;
+ a[i+3]++;
+ a[i+4]++;
+ a[i+5]++;
+ a[i+6]++;
+ a[i+7]++;
+ a[i+8]++;
+ a[i+9]++;
+ a[i+10]++;
+ a[i+11]++;
+ a[i+12]++;
+ a[i+13]++;
+ a[i+14]++;
+ a[i+15]++;
+ }
+ return new Object[]{ a };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0",
+ IRNode.ADD_VB, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "false"})
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "= 0",
+ IRNode.ADD_VB, "= 0",
+ IRNode.STORE_VECTOR, "= 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "true"})
+ static Object[] test14bB(byte[] a) {
+ // non-power-of-2 stride
+ for (int i = 0; i < RANGE-20; i+=3) {
+ a[i+0]++;
+ a[i+1]++;
+ a[i+2]++;
+ a[i+3]++;
+ a[i+4]++;
+ a[i+5]++;
+ a[i+6]++;
+ a[i+7]++;
+ a[i+8]++;
+ a[i+9]++;
+ a[i+10]++;
+ a[i+11]++;
+ a[i+12]++;
+ a[i+13]++;
+ a[i+14]++;
+ a[i+15]++;
+ }
+ return new Object[]{ a };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0",
+ IRNode.ADD_VB, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "false"})
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "= 0",
+ IRNode.ADD_VB, "= 0",
+ IRNode.STORE_VECTOR, "= 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "true"})
+ static Object[] test14cB(byte[] a) {
+ // non-power-of-2 stride
+ for (int i = 0; i < RANGE-20; i+=5) {
+ a[i+0]++;
+ a[i+1]++;
+ a[i+2]++;
+ a[i+3]++;
+ a[i+4]++;
+ a[i+5]++;
+ a[i+6]++;
+ a[i+7]++;
+ a[i+8]++;
+ a[i+9]++;
+ a[i+10]++;
+ a[i+11]++;
+ a[i+12]++;
+ a[i+13]++;
+ a[i+14]++;
+ a[i+15]++;
+ }
+ return new Object[]{ a };
+ }
+
+ @Test
+ // IR rules difficult because of modulo wrapping with offset after peeling.
+ static Object[] test15aB(byte[] a) {
+ // non-power-of-2 scale
+ for (int i = 0; i < RANGE/64-20; i++) {
+ a[53*i+0]++;
+ a[53*i+1]++;
+ a[53*i+2]++;
+ a[53*i+3]++;
+ a[53*i+4]++;
+ a[53*i+5]++;
+ a[53*i+6]++;
+ a[53*i+7]++;
+ a[53*i+8]++;
+ a[53*i+9]++;
+ a[53*i+10]++;
+ a[53*i+11]++;
+ a[53*i+12]++;
+ a[53*i+13]++;
+ a[53*i+14]++;
+ a[53*i+15]++;
+ }
+ return new Object[]{ a };
+ }
+
+ @Test
+ // IR rules difficult because of modulo wrapping with offset after peeling.
+ static Object[] test15bB(byte[] a) {
+ // non-power-of-2 scale
+ for (int i = 0; i < RANGE/64-20; i++) {
+ a[25*i+0]++;
+ a[25*i+1]++;
+ a[25*i+2]++;
+ a[25*i+3]++;
+ a[25*i+4]++;
+ a[25*i+5]++;
+ a[25*i+6]++;
+ a[25*i+7]++;
+ a[25*i+8]++;
+ a[25*i+9]++;
+ a[25*i+10]++;
+ a[25*i+11]++;
+ a[25*i+12]++;
+ a[25*i+13]++;
+ a[25*i+14]++;
+ a[25*i+15]++;
+ }
+ return new Object[]{ a };
+ }
+
+ @Test
+ // IR rules difficult because of modulo wrapping with offset after peeling.
+ static Object[] test15cB(byte[] a) {
+ // non-power-of-2 scale
+ for (int i = 0; i < RANGE/64-20; i++) {
+ a[19*i+0]++;
+ a[19*i+1]++;
+ a[19*i+2]++;
+ a[19*i+3]++;
+ a[19*i+4]++;
+ a[19*i+5]++;
+ a[19*i+6]++;
+ a[19*i+7]++;
+ a[19*i+8]++;
+ a[19*i+9]++;
+ a[19*i+10]++;
+ a[19*i+11]++;
+ a[19*i+12]++;
+ a[19*i+13]++;
+ a[19*i+14]++;
+ a[19*i+15]++;
+ }
+ return new Object[]{ a };
+ }
+
+ @Test
+ static Object[] test16a(byte[] a, short[] b) {
+ // infinite loop issues
+ for (int i = 0; i < RANGE/2-20; i++) {
+ a[2*i+0]++;
+ a[2*i+1]++;
+ a[2*i+2]++;
+ a[2*i+3]++;
+ a[2*i+4]++;
+ a[2*i+5]++;
+ a[2*i+6]++;
+ a[2*i+7]++;
+ a[2*i+8]++;
+ a[2*i+9]++;
+ a[2*i+10]++;
+ a[2*i+11]++;
+ a[2*i+12]++;
+ a[2*i+13]++;
+ a[2*i+14]++;
+
+ b[2*i+0]++;
+ b[2*i+1]++;
+ b[2*i+2]++;
+ b[2*i+3]++;
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ static Object[] test16b(byte[] a) {
+ // infinite loop issues
+ for (int i = 0; i < RANGE/2-20; i++) {
+ a[2*i+0]++;
+ a[2*i+1]++;
+ a[2*i+2]++;
+ a[2*i+3]++;
+ a[2*i+4]++;
+ a[2*i+5]++;
+ a[2*i+6]++;
+ a[2*i+7]++;
+ a[2*i+8]++;
+ a[2*i+9]++;
+ a[2*i+10]++;
+ a[2*i+11]++;
+ a[2*i+12]++;
+ a[2*i+13]++;
+ a[2*i+14]++;
+ }
+ return new Object[]{ a };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0",
+ IRNode.ADD_VL, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ static Object[] test17a(long[] a) {
+ // Unsafe: vectorizes with profiling (not xcomp)
+ for (int i = 0; i < RANGE; i++) {
+ int adr = UNSAFE.ARRAY_LONG_BASE_OFFSET + 8 * i;
+ long v = UNSAFE.getLongUnaligned(a, adr);
+ UNSAFE.putLongUnaligned(a, adr, v + 1);
+ }
+ return new Object[]{ a };
+ }
+
+ @Test
+ // Difficult to write good IR rule. Modulo calculus overflow can create non-power-of-2 packs.
+ static Object[] test17b(long[] a) {
+ // Not alignable
+ for (int i = 0; i < RANGE-1; i++) {
+ int adr = UNSAFE.ARRAY_LONG_BASE_OFFSET + 8 * i + 1;
+ long v = UNSAFE.getLongUnaligned(a, adr);
+ UNSAFE.putLongUnaligned(a, adr, v + 1);
+ }
+ return new Object[]{ a };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE_2, "> 0",
+ IRNode.ADD_VL, IRNode.VECTOR_SIZE_2, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIf = {"MaxVectorSize", ">=32"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ static Object[] test17c(long[] a) {
+ // Unsafe: aligned vectorizes
+ for (int i = 0; i < RANGE-1; i+=4) {
+ int adr = UNSAFE.ARRAY_LONG_BASE_OFFSET + 8 * i;
+ long v0 = UNSAFE.getLongUnaligned(a, adr + 0);
+ long v1 = UNSAFE.getLongUnaligned(a, adr + 8);
+ UNSAFE.putLongUnaligned(a, adr + 0, v0 + 1);
+ UNSAFE.putLongUnaligned(a, adr + 8, v1 + 1);
+ }
+ return new Object[]{ a };
+ }
+
+ @Test
+ @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE_2, "> 0",
+ IRNode.ADD_VL, IRNode.VECTOR_SIZE_2, "> 0",
+ IRNode.STORE_VECTOR, "> 0"},
+ applyIfCPUFeatureOr = {"avx512", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">=64"})
+ // Ensure vector width is large enough to fit 64 byte for longs:
+ // The offsets are: 25, 33, 57, 65
+ // In modulo 32: 25, 1, 25, 1 -> does not vectorize
+ // In modulo 64: 25, 33, 57, 1 -> at least first pair vectorizes
+ // This problem is because we compute modulo vector width in memory_alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "= 0",
+ IRNode.ADD_VL, "= 0",
+ IRNode.STORE_VECTOR, "= 0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIfPlatform = {"64-bit", "true"},
+ applyIf = {"AlignVector", "true"})
+ static Object[] test17d(long[] a) {
+ // Not alignable
+ for (int i = 0; i < RANGE-1; i+=4) {
+ int adr = UNSAFE.ARRAY_LONG_BASE_OFFSET + 8 * i + 1;
+ long v0 = UNSAFE.getLongUnaligned(a, adr + 0);
+ long v1 = UNSAFE.getLongUnaligned(a, adr + 8);
+ UNSAFE.putLongUnaligned(a, adr + 0, v0 + 1);
+ UNSAFE.putLongUnaligned(a, adr + 8, v1 + 1);
+ }
+ return new Object[]{ a };
+ }
+
+ @Test
+ static Object[] test18a(byte[] a, int[] b) {
+ // scale = 0 --> no iv
+ for (int i = 0; i < RANGE; i++) {
+ a[0] = 1;
+ b[i] = 2;
+ a[1] = 1;
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ static Object[] test18b(byte[] a, int[] b) {
+ // scale = 0 --> no iv
+ for (int i = 0; i < RANGE; i++) {
+ a[1] = 1;
+ b[i] = 2;
+ a[2] = 1;
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ static Object[] test19(int[] a, int[] b) {
+ for (int i = 5000; i > 0; i--) {
+ a[RANGE_FINAL - i] = b[RANGE_FINAL - i];
+ }
+ return new Object[]{ a, b };
+ }
+
+ @Test
+ static Object[] test20(byte[] a) {
+ // Example where it is easy to pass alignment check,
+ // but used to fail the alignment calculation
+ for (int i = 1; i < RANGE/2-50; i++) {
+ a[2*i+0+30]++;
+ a[2*i+1+30]++;
+ a[2*i+2+30]++;
+ a[2*i+3+30]++;
+ }
+ return new Object[]{ a };
+ }
+}
diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestAlignVectorFuzzer.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestAlignVectorFuzzer.java
new file mode 100644
index 0000000000000..478cfbcb2c522
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestAlignVectorFuzzer.java
@@ -0,0 +1,1353 @@
+/*
+ * Copyright (c) 2024, 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 id=Vanilla
+ * @bug 8253191
+ * @summary Fuzzing loops with different (random) init, limit, stride, scale etc. Do not force alignment.
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib
+ * @requires vm.compiler2.enabled
+ * @key randomness
+ * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions
+ * -XX:LoopUnrollLimit=250
+ * -XX:CompileCommand=printcompilation,compiler.loopopts.superword.TestAlignVectorFuzzer::*
+ * compiler.loopopts.superword.TestAlignVectorFuzzer
+ */
+
+/*
+ * @test id=VerifyAlignVector
+ * @bug 8253191
+ * @summary Fuzzing loops with different (random) init, limit, stride, scale etc. Verify AlignVector.
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib
+ * @requires vm.compiler2.enabled
+ * @key randomness
+ * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions
+ * -XX:+AlignVector -XX:+VerifyAlignVector
+ * -XX:LoopUnrollLimit=250
+ * -XX:CompileCommand=printcompilation,compiler.loopopts.superword.TestAlignVectorFuzzer::*
+ * compiler.loopopts.superword.TestAlignVectorFuzzer
+ */
+
+/*
+ * @test id=VerifyAlignVector-Align16
+ * @bug 8253191
+ * @summary Fuzzing loops with different (random) init, limit, stride, scale etc. Verify AlignVector.
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib
+ * @requires vm.compiler2.enabled
+ * @requires vm.bits == 64
+ * @key randomness
+ * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions
+ * -XX:+AlignVector -XX:+VerifyAlignVector
+ * -XX:LoopUnrollLimit=250
+ * -XX:CompileCommand=printcompilation,compiler.loopopts.superword.TestAlignVectorFuzzer::*
+ * -XX:ObjectAlignmentInBytes=16
+ * compiler.loopopts.superword.TestAlignVectorFuzzer
+ */
+
+/*
+ * @test id=VerifyAlignVector-NoTieredCompilation-Xbatch
+ * @bug 8253191
+ * @summary Fuzzing loops with different (random) init, limit, stride, scale etc. Verify AlignVector.
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib
+ * @requires vm.compiler2.enabled
+ * @key randomness
+ * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions
+ * -XX:+AlignVector -XX:+VerifyAlignVector
+ * -XX:LoopUnrollLimit=250
+ * -XX:CompileCommand=printcompilation,compiler.loopopts.superword.TestAlignVectorFuzzer::*
+ * -XX:-TieredCompilation -Xbatch
+ * compiler.loopopts.superword.TestAlignVectorFuzzer
+ */
+
+package compiler.loopopts.superword;
+
+import java.lang.reflect.Array;
+import java.util.Map;
+import java.util.HashMap;
+import java.lang.invoke.*;
+import java.util.Random;
+import jdk.test.lib.Utils;
+import jdk.internal.misc.Unsafe;
+
+public class TestAlignVectorFuzzer {
+ static final int ITERATIONS_MAX = 5; // time allowance may lead to fewer iterations
+ static final int RANGE_CON = 1024 * 8;
+ static int ZERO = 0;
+
+ private static final Random random = Utils.getRandomInstance();
+ private static final Unsafe UNSAFE = Unsafe.getUnsafe();
+
+ interface TestFunction {
+ Object[] run();
+ }
+
+ // Setup for variable compile-time constants:
+ private static final CallSite INIT_CS = new MutableCallSite(MethodType.methodType(int.class));
+ private static final CallSite LIMIT_CS = new MutableCallSite(MethodType.methodType(int.class));
+ private static final CallSite STRIDE_CS = new MutableCallSite(MethodType.methodType(int.class));
+ private static final CallSite SCALE_CS = new MutableCallSite(MethodType.methodType(int.class));
+ private static final CallSite OFFSET1_CS = new MutableCallSite(MethodType.methodType(int.class));
+ private static final CallSite OFFSET2_CS = new MutableCallSite(MethodType.methodType(int.class));
+ private static final CallSite OFFSET3_CS = new MutableCallSite(MethodType.methodType(int.class));
+ private static final MethodHandle INIT_MH = INIT_CS.dynamicInvoker();
+ private static final MethodHandle LIMIT_MH = LIMIT_CS.dynamicInvoker();
+ private static final MethodHandle STRIDE_MH = STRIDE_CS.dynamicInvoker();
+ private static final MethodHandle SCALE_MH = SCALE_CS.dynamicInvoker();
+ private static final MethodHandle OFFSET1_MH = OFFSET1_CS.dynamicInvoker();
+ private static final MethodHandle OFFSET2_MH = OFFSET2_CS.dynamicInvoker();
+ private static final MethodHandle OFFSET3_MH = OFFSET3_CS.dynamicInvoker();
+
+ // Toggle if init, limit and offset are constants or variables
+ private static final CallSite INIT_IS_CON_CS = new MutableCallSite(MethodType.methodType(boolean.class));
+ private static final CallSite LIMIT_IS_CON_CS = new MutableCallSite(MethodType.methodType(boolean.class));
+ private static final CallSite OFFSET1_IS_CON_CS = new MutableCallSite(MethodType.methodType(boolean.class));
+ private static final CallSite OFFSET2_IS_CON_CS = new MutableCallSite(MethodType.methodType(boolean.class));
+ private static final CallSite OFFSET3_IS_CON_CS = new MutableCallSite(MethodType.methodType(boolean.class));
+ private static final MethodHandle INIT_IS_CON_MH = INIT_IS_CON_CS.dynamicInvoker();
+ private static final MethodHandle LIMIT_IS_CON_MH = LIMIT_IS_CON_CS.dynamicInvoker();
+ private static final MethodHandle OFFSET1_IS_CON_MH = OFFSET1_IS_CON_CS.dynamicInvoker();
+ private static final MethodHandle OFFSET2_IS_CON_MH = OFFSET2_IS_CON_CS.dynamicInvoker();
+ private static final MethodHandle OFFSET3_IS_CON_MH = OFFSET3_IS_CON_CS.dynamicInvoker();
+
+ // Hand-Unrolling compile-constants
+ private static final CallSite HAND_UNROLLING1_CS = new MutableCallSite(MethodType.methodType(int.class));
+ private static final CallSite HAND_UNROLLING2_CS = new MutableCallSite(MethodType.methodType(int.class));
+ private static final CallSite HAND_UNROLLING3_CS = new MutableCallSite(MethodType.methodType(int.class));
+ private static final MethodHandle HAND_UNROLLING1_MH = HAND_UNROLLING1_CS.dynamicInvoker();
+ private static final MethodHandle HAND_UNROLLING2_MH = HAND_UNROLLING2_CS.dynamicInvoker();
+ private static final MethodHandle HAND_UNROLLING3_MH = HAND_UNROLLING3_CS.dynamicInvoker();
+
+ static void setConstant(CallSite cs, int value) {
+ MethodHandle constant = MethodHandles.constant(int.class, value);
+ cs.setTarget(constant);
+ }
+
+ static void setConstant(CallSite cs, boolean value) {
+ MethodHandle constant = MethodHandles.constant(boolean.class, value);
+ cs.setTarget(constant);
+ }
+
+ static int init_con() { // compile-time constant
+ try {
+ return (int) INIT_MH.invokeExact();
+ } catch (Throwable t) {
+ throw new InternalError(t); // should NOT happen
+ }
+ }
+
+ static boolean init_is_con() { // compile-time constant
+ try {
+ return (boolean) INIT_IS_CON_MH.invokeExact();
+ } catch (Throwable t) {
+ throw new InternalError(t); // should NOT happen
+ }
+ }
+
+ static int init_con_or_var() {
+ int init = init_con();
+ if (!init_is_con()) { // branch constant folds to true or false
+ init += ZERO; // LoadI
+ }
+ return init;
+ }
+
+ static int limit_con() { // compile-time constant
+ try {
+ return (int) LIMIT_MH.invokeExact();
+ } catch (Throwable t) {
+ throw new InternalError(t); // should NOT happen
+ }
+ }
+
+ static boolean limit_is_con() { // compile-time constant
+ try {
+ return (boolean) LIMIT_IS_CON_MH.invokeExact();
+ } catch (Throwable t) {
+ throw new InternalError(t); // should NOT happen
+ }
+ }
+
+ static int limit_con_or_var() {
+ int limit = limit_con();
+ if (!limit_is_con()) { // branch constant folds to true or false
+ limit -= ZERO; // LoadI
+ }
+ return limit;
+ }
+
+ static int stride_con() { // compile-time constant
+ try {
+ return (int) STRIDE_MH.invokeExact();
+ } catch (Throwable t) {
+ throw new InternalError(t); // should NOT happen
+ }
+ }
+
+ static int scale_con() { // compile-time constant
+ try {
+ return (int) SCALE_MH.invokeExact();
+ } catch (Throwable t) {
+ throw new InternalError(t); // should NOT happen
+ }
+ }
+
+ static int offset1_con() { // compile-time constant
+ try {
+ return (int) OFFSET1_MH.invokeExact();
+ } catch (Throwable t) {
+ throw new InternalError(t); // should NOT happen
+ }
+ }
+
+ static int offset2_con() { // compile-time constant
+ try {
+ return (int) OFFSET2_MH.invokeExact();
+ } catch (Throwable t) {
+ throw new InternalError(t); // should NOT happen
+ }
+ }
+
+ static int offset3_con() { // compile-time constant
+ try {
+ return (int) OFFSET3_MH.invokeExact();
+ } catch (Throwable t) {
+ throw new InternalError(t); // should NOT happen
+ }
+ }
+
+ static boolean offset1_is_con() { // compile-time constant
+ try {
+ return (boolean) OFFSET1_IS_CON_MH.invokeExact();
+ } catch (Throwable t) {
+ throw new InternalError(t); // should NOT happen
+ }
+ }
+
+ static boolean offset2_is_con() { // compile-time constant
+ try {
+ return (boolean) OFFSET2_IS_CON_MH.invokeExact();
+ } catch (Throwable t) {
+ throw new InternalError(t); // should NOT happen
+ }
+ }
+
+ static boolean offset3_is_con() { // compile-time constant
+ try {
+ return (boolean) OFFSET3_IS_CON_MH.invokeExact();
+ } catch (Throwable t) {
+ throw new InternalError(t); // should NOT happen
+ }
+ }
+
+ static int offset1_con_or_var() {
+ int offset = offset1_con();
+ if (!offset1_is_con()) { // branch constant folds to true or false
+ offset += ZERO; // LoadI
+ }
+ return offset;
+ }
+
+ static int offset2_con_or_var() {
+ int offset = offset2_con();
+ if (!offset2_is_con()) { // branch constant folds to true or false
+ offset += ZERO; // LoadI
+ }
+ return offset;
+ }
+
+ static int offset3_con_or_var() {
+ int offset = offset3_con();
+ if (!offset3_is_con()) { // branch constant folds to true or false
+ offset += ZERO; // LoadI
+ }
+ return offset;
+ }
+
+ static int opposite_direction_offset1_con_or_var() {
+ // When indexing in the opposite direction to i, we Want to have:
+ //
+ // a[x - i * scale]
+ //
+ // So we want to fulfill these constraints:
+ //
+ // x - init * scale = offset + limit * scale
+ // x - limit * scale = offset + init * scale
+ //
+ // Hence:
+ //
+ // x = offset + limit * scale + init * scale;
+
+ int offset = offset1_con_or_var();
+ int init = init_con();
+ int limit = limit_con();
+ int scale = scale_con();
+ return offset + limit * scale + init * scale;
+ }
+
+ static int opposite_direction_offset2_con_or_var() {
+ int offset = offset2_con_or_var();
+ int init = init_con();
+ int limit = limit_con();
+ int scale = scale_con();
+ return offset + limit * scale + init * scale;
+ }
+
+ static int opposite_direction_offset3_con_or_var() {
+ int offset = offset3_con_or_var();
+ int init = init_con();
+ int limit = limit_con();
+ int scale = scale_con();
+ return offset + limit * scale + init * scale;
+ }
+
+ static int hand_unrolling1_con() { // compile-time constant
+ try {
+ return (int) HAND_UNROLLING1_MH.invokeExact();
+ } catch (Throwable t) {
+ throw new InternalError(t); // should NOT happen
+ }
+ }
+
+ static int hand_unrolling2_con() { // compile-time constant
+ try {
+ return (int) HAND_UNROLLING2_MH.invokeExact();
+ } catch (Throwable t) {
+ throw new InternalError(t); // should NOT happen
+ }
+ }
+
+ static int hand_unrolling3_con() { // compile-time constant
+ try {
+ return (int) HAND_UNROLLING3_MH.invokeExact();
+ } catch (Throwable t) {
+ throw new InternalError(t); // should NOT happen
+ }
+ }
+
+ static int randomStride() {
+ return switch (random.nextInt(6)) {
+ case 0 -> random.nextInt(64) + 1; // [1..64]
+ case 1, 2, 3 -> 1;
+ default -> 1 << random.nextInt(7); // powers of 2: 1..64
+ };
+ }
+
+ static int randomScale() {
+ return switch (random.nextInt(6)) {
+ case 0 -> random.nextInt(64) + 1; // [1..64]
+ case 1, 2, 3 -> 1;
+ default -> 1 << random.nextInt(7); // powers of 2: 1..64
+ };
+ }
+
+ static int randomOffsetDiff() {
+ return switch (random.nextInt(6)) {
+ case 0 -> random.nextInt(256) + 128;
+ case 1, 2, 3 -> 0;
+ case 4 -> +(1 << random.nextInt(8)); // powers of 2: 1..128
+ default -> -(1 << random.nextInt(8)); // powers of 2: -1..-128
+ };
+ }
+
+ static int randomHandUnrolling() {
+ return switch (random.nextInt(2)) {
+ case 0 -> random.nextInt(16) + 1; // [1..16]
+ default -> 1 << random.nextInt(5); // powers of 2: 1..16
+ };
+ }
+
+ static void setRandomConstants() {
+ // We want to create random constants for a loop, but they should never go out of bounds.
+ // We constrain i to be in the range [init..limit], with init < limit. For simplicity, we
+ // always generate:
+ //
+ // 1 <= scale <= 64
+ // 1 <= stride <= 64
+ //
+ // We work with this reference memory access:
+ //
+ // a[offset + i * scale]
+ //
+ // It is up to the test function to re-arrange the the given terms to iterate upward or
+ // downward, to hand-unroll etc.
+ //
+ // We must ensure that the first and last indices are in range:
+ //
+ // 0 + error <= offset + init * scale
+ // offset + limit * scale < range - error
+ //
+ // The "error" term is there such that the test functions have the freedom to slightly
+ // diverge from the reference memory access pattern (for example modify the offset).
+ //
+ // The values for scale and range are already fixed. We now want to generate values for
+ // offset, init and limit.
+ //
+ // (1) Fix offset:
+ //
+ // init >= (error - offset) / scale
+ // limit < (range - error - offset) / scale
+ //
+ // (2) Fix init:
+ //
+ // offset >= error - init * scale
+ // limit < (range - error - offset) / scale
+ //
+ // (3) Fix limit:
+ //
+ // offset < range - error - limit * scale
+ // init >= (error - offset) / scale
+ //
+ // We can still slightly perturb the results in the direction permitted by the inequality.
+
+ int stride = randomStride();
+ int scale = randomScale();
+ int range = RANGE_CON;
+ int error = 1024; // generous
+ int init;
+ int limit;
+ int offset1;
+ switch(random.nextInt(3)) {
+ case 0 -> {
+ offset1 = random.nextInt(2_000_000) - 1_000_000;
+ init = (error - offset1) / scale + random.nextInt(64);
+ limit = (range - error - offset1) / scale - random.nextInt(64);
+ }
+ case 1 -> {
+ init = random.nextInt(2_000_000) - 1_000_000;
+ offset1 = error - init * scale + random.nextInt(64);
+ limit = (range - error - offset1) / scale - random.nextInt(64);
+ }
+ default -> {
+ limit = random.nextInt(2_000_000) - 1_000_000;
+ offset1 = range - error - limit * scale - random.nextInt(64);
+ init = (error - offset1) / scale + random.nextInt(64);
+ }
+ }
+
+ int offset2 = offset1 + randomOffsetDiff();
+ int offset3 = offset1 + randomOffsetDiff();
+
+ // We can toggle the init, limit and offset to either be constant or variable:
+ boolean init_is_con = random.nextInt(3) != 0;
+ boolean limit_is_con = random.nextInt(3) != 0;
+ boolean offset1_is_con = random.nextInt(3) != 0;
+ boolean offset2_is_con = random.nextInt(3) != 0;
+ boolean offset3_is_con = random.nextInt(3) != 0;
+
+ int hand_unrolling1 = randomHandUnrolling();
+ int hand_unrolling2 = randomHandUnrolling();
+ int hand_unrolling3 = randomHandUnrolling();
+
+// Overwrite the fuzzed values below to reproduce a specific failure:
+//
+// init = 1;
+// limit = init + 3000;
+// offset1 = 0;
+// offset2 = 0;
+// offset3 = 32 - 2*init;
+// stride = 1;
+// scale = 2;
+// hand_unrolling1 = 0;
+// hand_unrolling2 = 0;
+// hand_unrolling3 = 4;
+//
+// init_is_con = true;
+// limit_is_con = true;
+// offset1_is_con = true;
+// offset2_is_con = true;
+// offset3_is_con = true;
+
+ System.out.println(" init: " + init + " (con: " + init_is_con + ")");
+ System.out.println(" limit: " + limit + " (con: " + limit_is_con + ")");
+ System.out.println(" offset1: " + offset1 + " (con: " + offset1_is_con + ")");
+ System.out.println(" offset2: " + offset2 + " (con: " + offset2_is_con + ")");
+ System.out.println(" offset3: " + offset3 + " (con: " + offset3_is_con + ")");
+ System.out.println(" stride: " + stride);
+ System.out.println(" scale: " + scale);
+ System.out.println(" hand_unrolling1: " + hand_unrolling1);
+ System.out.println(" hand_unrolling2: " + hand_unrolling2);
+ System.out.println(" hand_unrolling3: " + hand_unrolling3);
+ setConstant(INIT_CS, init);
+ setConstant(LIMIT_CS, limit);
+ setConstant(STRIDE_CS, stride);
+ setConstant(SCALE_CS, scale);
+ setConstant(OFFSET1_CS, offset1);
+ setConstant(OFFSET2_CS, offset2);
+ setConstant(OFFSET3_CS, offset3);
+ setConstant(INIT_IS_CON_CS, init_is_con);
+ setConstant(LIMIT_IS_CON_CS, limit_is_con);
+ setConstant(OFFSET1_IS_CON_CS, offset1_is_con);
+ setConstant(OFFSET2_IS_CON_CS, offset2_is_con);
+ setConstant(OFFSET3_IS_CON_CS, offset3_is_con);
+ setConstant(HAND_UNROLLING1_CS, hand_unrolling1);
+ setConstant(HAND_UNROLLING2_CS, hand_unrolling2);
+ setConstant(HAND_UNROLLING3_CS, hand_unrolling3);
+ }
+
+ public static void main(String[] args) {
+ byte[] aB = generateB();
+ byte[] bB = generateB();
+ byte[] cB = generateB();
+ short[] aS = generateS();
+ short[] bS = generateS();
+ short[] cS = generateS();
+ char[] aC = generateC();
+ char[] bC = generateC();
+ char[] cC = generateC();
+ int[] aI = generateI();
+ int[] bI = generateI();
+ int[] cI = generateI();
+ long[] aL = generateL();
+ long[] bL = generateL();
+ long[] cL = generateL();
+ float[] aF = generateF();
+ float[] bF = generateF();
+ float[] cF = generateF();
+ double[] aD = generateD();
+ double[] bD = generateD();
+ double[] cD = generateD();
+
+ // Add all tests to list
+ Map tests = new HashMap();
+ tests.put("testUUB", () -> { return testUUB(aB.clone()); });
+ tests.put("testDDB", () -> { return testDDB(aB.clone()); });
+ tests.put("testUDB", () -> { return testUDB(aB.clone()); });
+ tests.put("testDUB", () -> { return testDUB(aB.clone()); });
+
+ tests.put("testUUBH", () -> { return testUUBH(aB.clone()); });
+
+ tests.put("testUUBBB", () -> { return testUUBBB(aB.clone(), bB.clone(), cB.clone()); });
+ tests.put("testUUBSI", () -> { return testUUBSI(aB.clone(), bS.clone(), cI.clone()); });
+
+ tests.put("testUUBBBH", () -> { return testUUBBBH(aB.clone(), bB.clone(), cB.clone()); });
+
+ tests.put("testUUBCFH", () -> { return testUUBCFH(aB.clone(), bC.clone(), cF.clone()); });
+ tests.put("testDDBCFH", () -> { return testDDBCFH(aB.clone(), bC.clone(), cF.clone()); });
+ tests.put("testUDBCFH", () -> { return testUDBCFH(aB.clone(), bC.clone(), cF.clone()); });
+ tests.put("testDUBCFH", () -> { return testDUBCFH(aB.clone(), bC.clone(), cF.clone()); });
+
+ tests.put("testMMSFD", () -> { return testMMSFD(aS.clone(), bF.clone(), cD.clone()); });
+
+ tests.put("testUU_unsafe_BasI", () -> { return testUU_unsafe_BasI(aB.clone()); });
+ tests.put("testUU_unsafe_BasIH", () -> { return testUU_unsafe_BasIH(aB.clone(), bB.clone(), cB.clone()); });
+
+
+ // Only run for 90% of the time, and subtract some margin. This ensures the shutdown has sufficient time,
+ // even for very slow runs.
+ long test_time_allowance = System.currentTimeMillis() +
+ (long)(Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT) * 0.9) -
+ 20_000;
+ long test_hard_timeout = System.currentTimeMillis() +
+ Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT);
+
+ for (int i = 1; i <= ITERATIONS_MAX; i++) {
+ setRandomConstants();
+ for (Map.Entry entry : tests.entrySet()) {
+ String name = entry.getKey();
+ TestFunction test = entry.getValue();
+ long allowance = test_time_allowance - System.currentTimeMillis();
+ long until_timeout = test_hard_timeout - System.currentTimeMillis();
+ System.out.println("ITERATION " + i + " of " + ITERATIONS_MAX + ". Test " + name +
+ ", time allowance: " + allowance + ", until timeout: " + until_timeout);
+
+ // Compute gold value, probably deopt first if constants have changed.
+ Object[] gold = test.run();
+
+ // Have enough iterations to (re)compile
+ for (int j = 0; j < 10_000; j++) {
+ Object[] result = test.run();
+ verify(name, gold, result);
+ }
+
+ if (System.currentTimeMillis() > test_time_allowance) {
+ allowance = test_time_allowance - System.currentTimeMillis();
+ until_timeout = test_hard_timeout - System.currentTimeMillis();
+ System.out.println("TEST PASSED: hit maximal time allownance during iteration " + i +
+ ", time allowance: " + allowance + ", until timeout: " + until_timeout);
+ return;
+ }
+ }
+ }
+ long allowance = test_time_allowance - System.currentTimeMillis();
+ long until_timeout = test_hard_timeout - System.currentTimeMillis();
+ System.out.println("TEST PASSED, time allowance: " + allowance + ", until timeout: " + until_timeout);
+ }
+
+ // Test names:
+ // test
+ // {U: i goes up, D: i goes down, M: mixed}
+ // {U: indexing goes up, D: indexing goes down, M: mixed}
+ // BSCILFD (types used)
+
+ // -------------------- BASIC SINGLE --------------------
+
+ static Object[] testUUB(byte[] a) {
+ int init = init_con_or_var();
+ int limit = limit_con_or_var();
+ int stride = stride_con();
+ int scale = scale_con();
+ int offset = offset1_con_or_var();
+
+ for (int i = init; i < limit; i += stride) {
+ a[offset + i * scale]++;
+ }
+ return new Object[]{ a };
+ }
+
+ static Object[] testDDB(byte[] a) {
+ int init = init_con_or_var();
+ int limit = limit_con_or_var();
+ int stride = stride_con();
+ int scale = scale_con();
+ int offset = offset1_con_or_var();
+
+ for (int i = limit; i > init; i -= stride) {
+ a[offset + i * scale]++;
+ }
+ return new Object[]{ a };
+ }
+
+ static Object[] testUDB(byte[] a) {
+ int init = init_con_or_var();
+ int limit = limit_con_or_var();
+ int stride = stride_con();
+ int scale = scale_con();
+ int x = opposite_direction_offset1_con_or_var();
+
+ for (int i = init; i < limit; i += stride) {
+ a[x - i * scale]++;
+ }
+ return new Object[]{ a };
+ }
+
+ static Object[] testDUB(byte[] a) {
+ int init = init_con_or_var();
+ int limit = limit_con_or_var();
+ int stride = stride_con();
+ int scale = scale_con();
+ int x = opposite_direction_offset1_con_or_var();
+
+ for (int i = limit; i > init; i -= stride) {
+ a[x - i * scale]++;
+ }
+ return new Object[]{ a };
+ }
+
+ // -------------------- BASIC HAND UNROLL --------------------
+
+ static Object[] testUUBH(byte[] a) {
+ int init = init_con_or_var();
+ int limit = limit_con_or_var();
+ int stride = stride_con();
+ int scale = scale_con();
+ int offset = offset1_con_or_var();
+
+ // All if statements with constant h fold to true or false
+ int h = hand_unrolling1_con();
+
+ for (int i = init; i < limit; i += stride) {
+ if (h >= 1) { a[offset + i * scale + 0]++; }
+ if (h >= 2) { a[offset + i * scale + 1]++; }
+ if (h >= 3) { a[offset + i * scale + 2]++; }
+ if (h >= 4) { a[offset + i * scale + 3]++; }
+ if (h >= 5) { a[offset + i * scale + 4]++; }
+ if (h >= 6) { a[offset + i * scale + 5]++; }
+ if (h >= 7) { a[offset + i * scale + 6]++; }
+ if (h >= 8) { a[offset + i * scale + 7]++; }
+ if (h >= 9) { a[offset + i * scale + 8]++; }
+ if (h >= 10) { a[offset + i * scale + 9]++; }
+ if (h >= 11) { a[offset + i * scale + 10]++; }
+ if (h >= 12) { a[offset + i * scale + 11]++; }
+ if (h >= 13) { a[offset + i * scale + 12]++; }
+ if (h >= 14) { a[offset + i * scale + 13]++; }
+ if (h >= 15) { a[offset + i * scale + 14]++; }
+ if (h >= 16) { a[offset + i * scale + 15]++; }
+ }
+ return new Object[]{ a };
+ }
+
+ // -------------------- BASIC TRIPPLE --------------------
+
+ static Object[] testUUBBB(byte[] a, byte[] b, byte[] c) {
+ int init = init_con_or_var();
+ int limit = limit_con_or_var();
+ int stride = stride_con();
+ int scale = scale_con();
+ int offset1 = offset1_con_or_var();
+ int offset2 = offset2_con_or_var();
+ int offset3 = offset3_con_or_var();
+
+ for (int i = init; i < limit; i += stride) {
+ a[offset1 + i * scale]++;
+ b[offset2 + i * scale]++;
+ c[offset3 + i * scale]++;
+ }
+ return new Object[]{ a, b, c };
+ }
+
+ static Object[] testUUBSI(byte[] a, short[] b, int[] c) {
+ int init = init_con_or_var();
+ int limit = limit_con_or_var();
+ int stride = stride_con();
+ int scale = scale_con();
+ int offset1 = offset1_con_or_var();
+ int offset2 = offset2_con_or_var();
+ int offset3 = offset3_con_or_var();
+
+ for (int i = init; i < limit; i += stride) {
+ a[offset1 + i * scale]++;
+ b[offset2 + i * scale]++;
+ c[offset3 + i * scale]++;
+ }
+ return new Object[]{ a, b, c };
+ }
+
+ // -------------------- HAND UNROLL TRIPPLE --------------------
+
+ static Object[] testUUBBBH(byte[] a, byte[] b, byte[] c) {
+ int init = init_con_or_var();
+ int limit = limit_con_or_var();
+ int stride = stride_con();
+ int scale = scale_con();
+ int offset1 = offset1_con_or_var();
+ int offset2 = offset2_con_or_var();
+ int offset3 = offset3_con_or_var();
+
+ int h1 = hand_unrolling1_con();
+ int h2 = hand_unrolling2_con();
+ int h3 = hand_unrolling3_con();
+
+ for (int i = init; i < limit; i += stride) {
+ if (h1 >= 1) { a[offset1 + i * scale + 0]++; }
+ if (h1 >= 2) { a[offset1 + i * scale + 1]++; }
+ if (h1 >= 3) { a[offset1 + i * scale + 2]++; }
+ if (h1 >= 4) { a[offset1 + i * scale + 3]++; }
+ if (h1 >= 5) { a[offset1 + i * scale + 4]++; }
+ if (h1 >= 6) { a[offset1 + i * scale + 5]++; }
+ if (h1 >= 7) { a[offset1 + i * scale + 6]++; }
+ if (h1 >= 8) { a[offset1 + i * scale + 7]++; }
+ if (h1 >= 9) { a[offset1 + i * scale + 8]++; }
+ if (h1 >= 10) { a[offset1 + i * scale + 9]++; }
+ if (h1 >= 11) { a[offset1 + i * scale + 10]++; }
+ if (h1 >= 12) { a[offset1 + i * scale + 11]++; }
+ if (h1 >= 13) { a[offset1 + i * scale + 12]++; }
+ if (h1 >= 14) { a[offset1 + i * scale + 13]++; }
+ if (h1 >= 15) { a[offset1 + i * scale + 14]++; }
+ if (h1 >= 16) { a[offset1 + i * scale + 15]++; }
+
+ if (h2 >= 1) { b[offset2 + i * scale + 0]++; }
+ if (h2 >= 2) { b[offset2 + i * scale + 1]++; }
+ if (h2 >= 3) { b[offset2 + i * scale + 2]++; }
+ if (h2 >= 4) { b[offset2 + i * scale + 3]++; }
+ if (h2 >= 5) { b[offset2 + i * scale + 4]++; }
+ if (h2 >= 6) { b[offset2 + i * scale + 5]++; }
+ if (h2 >= 7) { b[offset2 + i * scale + 6]++; }
+ if (h2 >= 8) { b[offset2 + i * scale + 7]++; }
+ if (h2 >= 9) { b[offset2 + i * scale + 8]++; }
+ if (h2 >= 10) { b[offset2 + i * scale + 9]++; }
+ if (h2 >= 11) { b[offset2 + i * scale + 10]++; }
+ if (h2 >= 12) { b[offset2 + i * scale + 11]++; }
+ if (h2 >= 13) { b[offset2 + i * scale + 12]++; }
+ if (h2 >= 14) { b[offset2 + i * scale + 13]++; }
+ if (h2 >= 15) { b[offset2 + i * scale + 14]++; }
+ if (h2 >= 16) { b[offset2 + i * scale + 15]++; }
+
+ if (h3 >= 1) { c[offset3 + i * scale + 0]++; }
+ if (h3 >= 2) { c[offset3 + i * scale + 1]++; }
+ if (h3 >= 3) { c[offset3 + i * scale + 2]++; }
+ if (h3 >= 4) { c[offset3 + i * scale + 3]++; }
+ if (h3 >= 5) { c[offset3 + i * scale + 4]++; }
+ if (h3 >= 6) { c[offset3 + i * scale + 5]++; }
+ if (h3 >= 7) { c[offset3 + i * scale + 6]++; }
+ if (h3 >= 8) { c[offset3 + i * scale + 7]++; }
+ if (h3 >= 9) { c[offset3 + i * scale + 8]++; }
+ if (h3 >= 10) { c[offset3 + i * scale + 9]++; }
+ if (h3 >= 11) { c[offset3 + i * scale + 10]++; }
+ if (h3 >= 12) { c[offset3 + i * scale + 11]++; }
+ if (h3 >= 13) { c[offset3 + i * scale + 12]++; }
+ if (h3 >= 14) { c[offset3 + i * scale + 13]++; }
+ if (h3 >= 15) { c[offset3 + i * scale + 14]++; }
+ if (h3 >= 16) { c[offset3 + i * scale + 15]++; }
+ }
+ return new Object[]{ a, b, c };
+ }
+
+ static Object[] testUUBCFH(byte[] a, char[] b, float[] c) {
+ int init = init_con_or_var();
+ int limit = limit_con_or_var();
+ int stride = stride_con();
+ int scale = scale_con();
+ int offset1 = offset1_con_or_var();
+ int offset2 = offset2_con_or_var();
+ int offset3 = offset3_con_or_var();
+
+ int h1 = hand_unrolling1_con();
+ int h2 = hand_unrolling2_con();
+ int h3 = hand_unrolling3_con();
+
+ for (int i = init; i < limit; i += stride) {
+ if (h1 >= 1) { a[offset1 + i * scale + 0]++; }
+ if (h1 >= 2) { a[offset1 + i * scale + 1]++; }
+ if (h1 >= 3) { a[offset1 + i * scale + 2]++; }
+ if (h1 >= 4) { a[offset1 + i * scale + 3]++; }
+ if (h1 >= 5) { a[offset1 + i * scale + 4]++; }
+ if (h1 >= 6) { a[offset1 + i * scale + 5]++; }
+ if (h1 >= 7) { a[offset1 + i * scale + 6]++; }
+ if (h1 >= 8) { a[offset1 + i * scale + 7]++; }
+ if (h1 >= 9) { a[offset1 + i * scale + 8]++; }
+ if (h1 >= 10) { a[offset1 + i * scale + 9]++; }
+ if (h1 >= 11) { a[offset1 + i * scale + 10]++; }
+ if (h1 >= 12) { a[offset1 + i * scale + 11]++; }
+ if (h1 >= 13) { a[offset1 + i * scale + 12]++; }
+ if (h1 >= 14) { a[offset1 + i * scale + 13]++; }
+ if (h1 >= 15) { a[offset1 + i * scale + 14]++; }
+ if (h1 >= 16) { a[offset1 + i * scale + 15]++; }
+
+ if (h2 >= 1) { b[offset2 + i * scale + 0]++; }
+ if (h2 >= 2) { b[offset2 + i * scale + 1]++; }
+ if (h2 >= 3) { b[offset2 + i * scale + 2]++; }
+ if (h2 >= 4) { b[offset2 + i * scale + 3]++; }
+ if (h2 >= 5) { b[offset2 + i * scale + 4]++; }
+ if (h2 >= 6) { b[offset2 + i * scale + 5]++; }
+ if (h2 >= 7) { b[offset2 + i * scale + 6]++; }
+ if (h2 >= 8) { b[offset2 + i * scale + 7]++; }
+ if (h2 >= 9) { b[offset2 + i * scale + 8]++; }
+ if (h2 >= 10) { b[offset2 + i * scale + 9]++; }
+ if (h2 >= 11) { b[offset2 + i * scale + 10]++; }
+ if (h2 >= 12) { b[offset2 + i * scale + 11]++; }
+ if (h2 >= 13) { b[offset2 + i * scale + 12]++; }
+ if (h2 >= 14) { b[offset2 + i * scale + 13]++; }
+ if (h2 >= 15) { b[offset2 + i * scale + 14]++; }
+ if (h2 >= 16) { b[offset2 + i * scale + 15]++; }
+
+ if (h3 >= 1) { c[offset3 + i * scale + 0]++; }
+ if (h3 >= 2) { c[offset3 + i * scale + 1]++; }
+ if (h3 >= 3) { c[offset3 + i * scale + 2]++; }
+ if (h3 >= 4) { c[offset3 + i * scale + 3]++; }
+ if (h3 >= 5) { c[offset3 + i * scale + 4]++; }
+ if (h3 >= 6) { c[offset3 + i * scale + 5]++; }
+ if (h3 >= 7) { c[offset3 + i * scale + 6]++; }
+ if (h3 >= 8) { c[offset3 + i * scale + 7]++; }
+ if (h3 >= 9) { c[offset3 + i * scale + 8]++; }
+ if (h3 >= 10) { c[offset3 + i * scale + 9]++; }
+ if (h3 >= 11) { c[offset3 + i * scale + 10]++; }
+ if (h3 >= 12) { c[offset3 + i * scale + 11]++; }
+ if (h3 >= 13) { c[offset3 + i * scale + 12]++; }
+ if (h3 >= 14) { c[offset3 + i * scale + 13]++; }
+ if (h3 >= 15) { c[offset3 + i * scale + 14]++; }
+ if (h3 >= 16) { c[offset3 + i * scale + 15]++; }
+ }
+ return new Object[]{ a, b, c };
+ }
+
+ static Object[] testDDBCFH(byte[] a, char[] b, float[] c) {
+ int init = init_con_or_var();
+ int limit = limit_con_or_var();
+ int stride = stride_con();
+ int scale = scale_con();
+ int offset1 = offset1_con_or_var();
+ int offset2 = offset2_con_or_var();
+ int offset3 = offset3_con_or_var();
+
+ int h1 = hand_unrolling1_con();
+ int h2 = hand_unrolling2_con();
+ int h3 = hand_unrolling3_con();
+
+ for (int i = limit; i > init; i -= stride) {
+ if (h1 >= 1) { a[offset1 + i * scale + 0]++; }
+ if (h1 >= 2) { a[offset1 + i * scale + 1]++; }
+ if (h1 >= 3) { a[offset1 + i * scale + 2]++; }
+ if (h1 >= 4) { a[offset1 + i * scale + 3]++; }
+ if (h1 >= 5) { a[offset1 + i * scale + 4]++; }
+ if (h1 >= 6) { a[offset1 + i * scale + 5]++; }
+ if (h1 >= 7) { a[offset1 + i * scale + 6]++; }
+ if (h1 >= 8) { a[offset1 + i * scale + 7]++; }
+ if (h1 >= 9) { a[offset1 + i * scale + 8]++; }
+ if (h1 >= 10) { a[offset1 + i * scale + 9]++; }
+ if (h1 >= 11) { a[offset1 + i * scale + 10]++; }
+ if (h1 >= 12) { a[offset1 + i * scale + 11]++; }
+ if (h1 >= 13) { a[offset1 + i * scale + 12]++; }
+ if (h1 >= 14) { a[offset1 + i * scale + 13]++; }
+ if (h1 >= 15) { a[offset1 + i * scale + 14]++; }
+ if (h1 >= 16) { a[offset1 + i * scale + 15]++; }
+
+ if (h2 >= 1) { b[offset2 + i * scale + 0]++; }
+ if (h2 >= 2) { b[offset2 + i * scale + 1]++; }
+ if (h2 >= 3) { b[offset2 + i * scale + 2]++; }
+ if (h2 >= 4) { b[offset2 + i * scale + 3]++; }
+ if (h2 >= 5) { b[offset2 + i * scale + 4]++; }
+ if (h2 >= 6) { b[offset2 + i * scale + 5]++; }
+ if (h2 >= 7) { b[offset2 + i * scale + 6]++; }
+ if (h2 >= 8) { b[offset2 + i * scale + 7]++; }
+ if (h2 >= 9) { b[offset2 + i * scale + 8]++; }
+ if (h2 >= 10) { b[offset2 + i * scale + 9]++; }
+ if (h2 >= 11) { b[offset2 + i * scale + 10]++; }
+ if (h2 >= 12) { b[offset2 + i * scale + 11]++; }
+ if (h2 >= 13) { b[offset2 + i * scale + 12]++; }
+ if (h2 >= 14) { b[offset2 + i * scale + 13]++; }
+ if (h2 >= 15) { b[offset2 + i * scale + 14]++; }
+ if (h2 >= 16) { b[offset2 + i * scale + 15]++; }
+
+ if (h3 >= 1) { c[offset3 + i * scale + 0]++; }
+ if (h3 >= 2) { c[offset3 + i * scale + 1]++; }
+ if (h3 >= 3) { c[offset3 + i * scale + 2]++; }
+ if (h3 >= 4) { c[offset3 + i * scale + 3]++; }
+ if (h3 >= 5) { c[offset3 + i * scale + 4]++; }
+ if (h3 >= 6) { c[offset3 + i * scale + 5]++; }
+ if (h3 >= 7) { c[offset3 + i * scale + 6]++; }
+ if (h3 >= 8) { c[offset3 + i * scale + 7]++; }
+ if (h3 >= 9) { c[offset3 + i * scale + 8]++; }
+ if (h3 >= 10) { c[offset3 + i * scale + 9]++; }
+ if (h3 >= 11) { c[offset3 + i * scale + 10]++; }
+ if (h3 >= 12) { c[offset3 + i * scale + 11]++; }
+ if (h3 >= 13) { c[offset3 + i * scale + 12]++; }
+ if (h3 >= 14) { c[offset3 + i * scale + 13]++; }
+ if (h3 >= 15) { c[offset3 + i * scale + 14]++; }
+ if (h3 >= 16) { c[offset3 + i * scale + 15]++; }
+ }
+ return new Object[]{ a, b, c };
+ }
+
+ static Object[] testUDBCFH(byte[] a, char[] b, float[] c) {
+ int init = init_con_or_var();
+ int limit = limit_con_or_var();
+ int stride = stride_con();
+ int scale = scale_con();
+ int x1 = opposite_direction_offset1_con_or_var();
+ int x2 = opposite_direction_offset2_con_or_var();
+ int x3 = opposite_direction_offset3_con_or_var();
+
+ int h1 = hand_unrolling1_con();
+ int h2 = hand_unrolling2_con();
+ int h3 = hand_unrolling3_con();
+
+ for (int i = init; i < limit; i += stride) {
+ if (h1 >= 1) { a[x1 - i * scale + 0]++; }
+ if (h1 >= 2) { a[x1 - i * scale + 1]++; }
+ if (h1 >= 3) { a[x1 - i * scale + 2]++; }
+ if (h1 >= 4) { a[x1 - i * scale + 3]++; }
+ if (h1 >= 5) { a[x1 - i * scale + 4]++; }
+ if (h1 >= 6) { a[x1 - i * scale + 5]++; }
+ if (h1 >= 7) { a[x1 - i * scale + 6]++; }
+ if (h1 >= 8) { a[x1 - i * scale + 7]++; }
+ if (h1 >= 9) { a[x1 - i * scale + 8]++; }
+ if (h1 >= 10) { a[x1 - i * scale + 9]++; }
+ if (h1 >= 11) { a[x1 - i * scale + 10]++; }
+ if (h1 >= 12) { a[x1 - i * scale + 11]++; }
+ if (h1 >= 13) { a[x1 - i * scale + 12]++; }
+ if (h1 >= 14) { a[x1 - i * scale + 13]++; }
+ if (h1 >= 15) { a[x1 - i * scale + 14]++; }
+ if (h1 >= 16) { a[x1 - i * scale + 15]++; }
+
+ if (h2 >= 1) { b[x2 - i * scale + 0]++; }
+ if (h2 >= 2) { b[x2 - i * scale + 1]++; }
+ if (h2 >= 3) { b[x2 - i * scale + 2]++; }
+ if (h2 >= 4) { b[x2 - i * scale + 3]++; }
+ if (h2 >= 5) { b[x2 - i * scale + 4]++; }
+ if (h2 >= 6) { b[x2 - i * scale + 5]++; }
+ if (h2 >= 7) { b[x2 - i * scale + 6]++; }
+ if (h2 >= 8) { b[x2 - i * scale + 7]++; }
+ if (h2 >= 9) { b[x2 - i * scale + 8]++; }
+ if (h2 >= 10) { b[x2 - i * scale + 9]++; }
+ if (h2 >= 11) { b[x2 - i * scale + 10]++; }
+ if (h2 >= 12) { b[x2 - i * scale + 11]++; }
+ if (h2 >= 13) { b[x2 - i * scale + 12]++; }
+ if (h2 >= 14) { b[x2 - i * scale + 13]++; }
+ if (h2 >= 15) { b[x2 - i * scale + 14]++; }
+ if (h2 >= 16) { b[x2 - i * scale + 15]++; }
+
+ if (h3 >= 1) { c[x3 - i * scale + 0]++; }
+ if (h3 >= 2) { c[x3 - i * scale + 1]++; }
+ if (h3 >= 3) { c[x3 - i * scale + 2]++; }
+ if (h3 >= 4) { c[x3 - i * scale + 3]++; }
+ if (h3 >= 5) { c[x3 - i * scale + 4]++; }
+ if (h3 >= 6) { c[x3 - i * scale + 5]++; }
+ if (h3 >= 7) { c[x3 - i * scale + 6]++; }
+ if (h3 >= 8) { c[x3 - i * scale + 7]++; }
+ if (h3 >= 9) { c[x3 - i * scale + 8]++; }
+ if (h3 >= 10) { c[x3 - i * scale + 9]++; }
+ if (h3 >= 11) { c[x3 - i * scale + 10]++; }
+ if (h3 >= 12) { c[x3 - i * scale + 11]++; }
+ if (h3 >= 13) { c[x3 - i * scale + 12]++; }
+ if (h3 >= 14) { c[x3 - i * scale + 13]++; }
+ if (h3 >= 15) { c[x3 - i * scale + 14]++; }
+ if (h3 >= 16) { c[x3 - i * scale + 15]++; }
+ }
+ return new Object[]{ a, b, c };
+ }
+
+ static Object[] testDUBCFH(byte[] a, char[] b, float[] c) {
+ int init = init_con_or_var();
+ int limit = limit_con_or_var();
+ int stride = stride_con();
+ int scale = scale_con();
+ int x1 = opposite_direction_offset1_con_or_var();
+ int x2 = opposite_direction_offset2_con_or_var();
+ int x3 = opposite_direction_offset3_con_or_var();
+
+ int h1 = hand_unrolling1_con();
+ int h2 = hand_unrolling2_con();
+ int h3 = hand_unrolling3_con();
+
+ for (int i = limit; i > init; i -= stride) {
+ if (h1 >= 1) { a[x1 - i * scale + 0]++; }
+ if (h1 >= 2) { a[x1 - i * scale + 1]++; }
+ if (h1 >= 3) { a[x1 - i * scale + 2]++; }
+ if (h1 >= 4) { a[x1 - i * scale + 3]++; }
+ if (h1 >= 5) { a[x1 - i * scale + 4]++; }
+ if (h1 >= 6) { a[x1 - i * scale + 5]++; }
+ if (h1 >= 7) { a[x1 - i * scale + 6]++; }
+ if (h1 >= 8) { a[x1 - i * scale + 7]++; }
+ if (h1 >= 9) { a[x1 - i * scale + 8]++; }
+ if (h1 >= 10) { a[x1 - i * scale + 9]++; }
+ if (h1 >= 11) { a[x1 - i * scale + 10]++; }
+ if (h1 >= 12) { a[x1 - i * scale + 11]++; }
+ if (h1 >= 13) { a[x1 - i * scale + 12]++; }
+ if (h1 >= 14) { a[x1 - i * scale + 13]++; }
+ if (h1 >= 15) { a[x1 - i * scale + 14]++; }
+ if (h1 >= 16) { a[x1 - i * scale + 15]++; }
+
+ if (h2 >= 1) { b[x2 - i * scale + 0]++; }
+ if (h2 >= 2) { b[x2 - i * scale + 1]++; }
+ if (h2 >= 3) { b[x2 - i * scale + 2]++; }
+ if (h2 >= 4) { b[x2 - i * scale + 3]++; }
+ if (h2 >= 5) { b[x2 - i * scale + 4]++; }
+ if (h2 >= 6) { b[x2 - i * scale + 5]++; }
+ if (h2 >= 7) { b[x2 - i * scale + 6]++; }
+ if (h2 >= 8) { b[x2 - i * scale + 7]++; }
+ if (h2 >= 9) { b[x2 - i * scale + 8]++; }
+ if (h2 >= 10) { b[x2 - i * scale + 9]++; }
+ if (h2 >= 11) { b[x2 - i * scale + 10]++; }
+ if (h2 >= 12) { b[x2 - i * scale + 11]++; }
+ if (h2 >= 13) { b[x2 - i * scale + 12]++; }
+ if (h2 >= 14) { b[x2 - i * scale + 13]++; }
+ if (h2 >= 15) { b[x2 - i * scale + 14]++; }
+ if (h2 >= 16) { b[x2 - i * scale + 15]++; }
+
+ if (h3 >= 1) { c[x3 - i * scale + 0]++; }
+ if (h3 >= 2) { c[x3 - i * scale + 1]++; }
+ if (h3 >= 3) { c[x3 - i * scale + 2]++; }
+ if (h3 >= 4) { c[x3 - i * scale + 3]++; }
+ if (h3 >= 5) { c[x3 - i * scale + 4]++; }
+ if (h3 >= 6) { c[x3 - i * scale + 5]++; }
+ if (h3 >= 7) { c[x3 - i * scale + 6]++; }
+ if (h3 >= 8) { c[x3 - i * scale + 7]++; }
+ if (h3 >= 9) { c[x3 - i * scale + 8]++; }
+ if (h3 >= 10) { c[x3 - i * scale + 9]++; }
+ if (h3 >= 11) { c[x3 - i * scale + 10]++; }
+ if (h3 >= 12) { c[x3 - i * scale + 11]++; }
+ if (h3 >= 13) { c[x3 - i * scale + 12]++; }
+ if (h3 >= 14) { c[x3 - i * scale + 13]++; }
+ if (h3 >= 15) { c[x3 - i * scale + 14]++; }
+ if (h3 >= 16) { c[x3 - i * scale + 15]++; }
+ }
+ return new Object[]{ a, b, c };
+ }
+
+ // -------------------- MIXED DIRECTION TRIPPLE --------------------
+
+ static Object[] testMMSFD(short[] a, float[] b, double[] c) {
+ int init = init_con_or_var();
+ int limit = limit_con_or_var();
+ int stride = stride_con();
+ int scale = scale_con();
+ int offset1 = offset1_con_or_var();
+ int offset2 = opposite_direction_offset2_con_or_var();
+ int offset3 = offset3_con_or_var();
+
+ for (int i = init; i < limit; i += stride) {
+ a[offset1 + i * scale]++;
+ b[offset2 - i * scale]++;
+ c[offset3 + i * scale]++;
+ }
+ return new Object[]{ a, b, c };
+ }
+
+ // -------------------- UNSAFE --------------------
+
+ static Object[] testUU_unsafe_BasI(byte[] a) {
+ int init = init_con_or_var();
+ int limit = limit_con_or_var();
+ int stride = stride_con();
+ int scale = scale_con();
+ int offset = offset1_con_or_var();
+
+ for (int i = init; i < limit; i += stride) {
+ int adr = UNSAFE.ARRAY_BYTE_BASE_OFFSET + offset + i * scale;
+ int v = UNSAFE.getIntUnaligned(a, adr);
+ UNSAFE.putIntUnaligned(a, adr, v + 1);
+ }
+ return new Object[]{ a };
+ }
+
+ static Object[] testUU_unsafe_BasIH(byte[] a, byte[] b, byte[] c) {
+ int init = init_con_or_var();
+ int limit = limit_con_or_var();
+ int stride = stride_con();
+ int scale = scale_con();
+ int offset1 = offset1_con_or_var();
+ int offset2 = offset2_con_or_var();
+ int offset3 = offset3_con_or_var();
+
+ int h1 = hand_unrolling1_con();
+ int h2 = hand_unrolling2_con();
+ int h3 = hand_unrolling3_con();
+
+ for (int i = init; i < limit; i += stride) {
+ int adr1 = UNSAFE.ARRAY_BYTE_BASE_OFFSET + offset1 + i * scale;
+ int adr2 = UNSAFE.ARRAY_BYTE_BASE_OFFSET + offset2 + i * scale;
+ int adr3 = UNSAFE.ARRAY_BYTE_BASE_OFFSET + offset3 + i * scale;
+
+ if (h1 >= 1) { UNSAFE.putIntUnaligned(a, adr1 + 0*4, UNSAFE.getIntUnaligned(a, adr1 + 0*4) + 1); }
+ if (h1 >= 2) { UNSAFE.putIntUnaligned(a, adr1 + 1*4, UNSAFE.getIntUnaligned(a, adr1 + 1*4) + 1); }
+ if (h1 >= 3) { UNSAFE.putIntUnaligned(a, adr1 + 2*4, UNSAFE.getIntUnaligned(a, adr1 + 2*4) + 1); }
+ if (h1 >= 4) { UNSAFE.putIntUnaligned(a, adr1 + 3*4, UNSAFE.getIntUnaligned(a, adr1 + 3*4) + 1); }
+ if (h1 >= 5) { UNSAFE.putIntUnaligned(a, adr1 + 4*4, UNSAFE.getIntUnaligned(a, adr1 + 4*4) + 1); }
+ if (h1 >= 6) { UNSAFE.putIntUnaligned(a, adr1 + 5*4, UNSAFE.getIntUnaligned(a, adr1 + 5*4) + 1); }
+ if (h1 >= 7) { UNSAFE.putIntUnaligned(a, adr1 + 6*4, UNSAFE.getIntUnaligned(a, adr1 + 6*4) + 1); }
+ if (h1 >= 8) { UNSAFE.putIntUnaligned(a, adr1 + 7*4, UNSAFE.getIntUnaligned(a, adr1 + 7*4) + 1); }
+ if (h1 >= 9) { UNSAFE.putIntUnaligned(a, adr1 + 8*4, UNSAFE.getIntUnaligned(a, adr1 + 8*4) + 1); }
+ if (h1 >= 10) { UNSAFE.putIntUnaligned(a, adr1 + 9*4, UNSAFE.getIntUnaligned(a, adr1 + 9*4) + 1); }
+ if (h1 >= 11) { UNSAFE.putIntUnaligned(a, adr1 + 10*4, UNSAFE.getIntUnaligned(a, adr1 + 10*4) + 1); }
+ if (h1 >= 12) { UNSAFE.putIntUnaligned(a, adr1 + 11*4, UNSAFE.getIntUnaligned(a, adr1 + 11*4) + 1); }
+ if (h1 >= 13) { UNSAFE.putIntUnaligned(a, adr1 + 12*4, UNSAFE.getIntUnaligned(a, adr1 + 12*4) + 1); }
+ if (h1 >= 14) { UNSAFE.putIntUnaligned(a, adr1 + 13*4, UNSAFE.getIntUnaligned(a, adr1 + 13*4) + 1); }
+ if (h1 >= 15) { UNSAFE.putIntUnaligned(a, adr1 + 14*4, UNSAFE.getIntUnaligned(a, adr1 + 14*4) + 1); }
+ if (h1 >= 16) { UNSAFE.putIntUnaligned(a, adr1 + 15*4, UNSAFE.getIntUnaligned(a, adr1 + 15*4) + 1); }
+
+ if (h2 >= 1) { UNSAFE.putIntUnaligned(b, adr2 + 0*4, UNSAFE.getIntUnaligned(b, adr2 + 0*4) + 1); }
+ if (h2 >= 2) { UNSAFE.putIntUnaligned(b, adr2 + 1*4, UNSAFE.getIntUnaligned(b, adr2 + 1*4) + 1); }
+ if (h2 >= 3) { UNSAFE.putIntUnaligned(b, adr2 + 2*4, UNSAFE.getIntUnaligned(b, adr2 + 2*4) + 1); }
+ if (h2 >= 4) { UNSAFE.putIntUnaligned(b, adr2 + 3*4, UNSAFE.getIntUnaligned(b, adr2 + 3*4) + 1); }
+ if (h2 >= 5) { UNSAFE.putIntUnaligned(b, adr2 + 4*4, UNSAFE.getIntUnaligned(b, adr2 + 4*4) + 1); }
+ if (h2 >= 6) { UNSAFE.putIntUnaligned(b, adr2 + 5*4, UNSAFE.getIntUnaligned(b, adr2 + 5*4) + 1); }
+ if (h2 >= 7) { UNSAFE.putIntUnaligned(b, adr2 + 6*4, UNSAFE.getIntUnaligned(b, adr2 + 6*4) + 1); }
+ if (h2 >= 8) { UNSAFE.putIntUnaligned(b, adr2 + 7*4, UNSAFE.getIntUnaligned(b, adr2 + 7*4) + 1); }
+ if (h2 >= 9) { UNSAFE.putIntUnaligned(b, adr2 + 8*4, UNSAFE.getIntUnaligned(b, adr2 + 8*4) + 1); }
+ if (h2 >= 10) { UNSAFE.putIntUnaligned(b, adr2 + 9*4, UNSAFE.getIntUnaligned(b, adr2 + 9*4) + 1); }
+ if (h2 >= 11) { UNSAFE.putIntUnaligned(b, adr2 + 10*4, UNSAFE.getIntUnaligned(b, adr2 + 10*4) + 1); }
+ if (h2 >= 12) { UNSAFE.putIntUnaligned(b, adr2 + 11*4, UNSAFE.getIntUnaligned(b, adr2 + 11*4) + 1); }
+ if (h2 >= 13) { UNSAFE.putIntUnaligned(b, adr2 + 12*4, UNSAFE.getIntUnaligned(b, adr2 + 12*4) + 1); }
+ if (h2 >= 14) { UNSAFE.putIntUnaligned(b, adr2 + 13*4, UNSAFE.getIntUnaligned(b, adr2 + 13*4) + 1); }
+ if (h2 >= 15) { UNSAFE.putIntUnaligned(b, adr2 + 14*4, UNSAFE.getIntUnaligned(b, adr2 + 14*4) + 1); }
+ if (h2 >= 16) { UNSAFE.putIntUnaligned(b, adr2 + 15*4, UNSAFE.getIntUnaligned(b, adr2 + 15*4) + 1); }
+
+ if (h3 >= 1) { UNSAFE.putIntUnaligned(c, adr3 + 0*4, UNSAFE.getIntUnaligned(c, adr3 + 0*4) + 1); }
+ if (h3 >= 2) { UNSAFE.putIntUnaligned(c, adr3 + 1*4, UNSAFE.getIntUnaligned(c, adr3 + 1*4) + 1); }
+ if (h3 >= 3) { UNSAFE.putIntUnaligned(c, adr3 + 2*4, UNSAFE.getIntUnaligned(c, adr3 + 2*4) + 1); }
+ if (h3 >= 4) { UNSAFE.putIntUnaligned(c, adr3 + 3*4, UNSAFE.getIntUnaligned(c, adr3 + 3*4) + 1); }
+ if (h3 >= 5) { UNSAFE.putIntUnaligned(c, adr3 + 4*4, UNSAFE.getIntUnaligned(c, adr3 + 4*4) + 1); }
+ if (h3 >= 6) { UNSAFE.putIntUnaligned(c, adr3 + 5*4, UNSAFE.getIntUnaligned(c, adr3 + 5*4) + 1); }
+ if (h3 >= 7) { UNSAFE.putIntUnaligned(c, adr3 + 6*4, UNSAFE.getIntUnaligned(c, adr3 + 6*4) + 1); }
+ if (h3 >= 8) { UNSAFE.putIntUnaligned(c, adr3 + 7*4, UNSAFE.getIntUnaligned(c, adr3 + 7*4) + 1); }
+ if (h3 >= 9) { UNSAFE.putIntUnaligned(c, adr3 + 8*4, UNSAFE.getIntUnaligned(c, adr3 + 8*4) + 1); }
+ if (h3 >= 10) { UNSAFE.putIntUnaligned(c, adr3 + 9*4, UNSAFE.getIntUnaligned(c, adr3 + 9*4) + 1); }
+ if (h3 >= 11) { UNSAFE.putIntUnaligned(c, adr3 + 10*4, UNSAFE.getIntUnaligned(c, adr3 + 10*4) + 1); }
+ if (h3 >= 12) { UNSAFE.putIntUnaligned(c, adr3 + 11*4, UNSAFE.getIntUnaligned(c, adr3 + 11*4) + 1); }
+ if (h3 >= 13) { UNSAFE.putIntUnaligned(c, adr3 + 12*4, UNSAFE.getIntUnaligned(c, adr3 + 12*4) + 1); }
+ if (h3 >= 14) { UNSAFE.putIntUnaligned(c, adr3 + 13*4, UNSAFE.getIntUnaligned(c, adr3 + 13*4) + 1); }
+ if (h3 >= 15) { UNSAFE.putIntUnaligned(c, adr3 + 14*4, UNSAFE.getIntUnaligned(c, adr3 + 14*4) + 1); }
+ if (h3 >= 16) { UNSAFE.putIntUnaligned(c, adr3 + 15*4, UNSAFE.getIntUnaligned(c, adr3 + 15*4) + 1); }
+ }
+ return new Object[]{ a, b, c };
+ }
+
+ static byte[] generateB() {
+ byte[] a = new byte[RANGE_CON];
+ for (int i = 0; i < a.length; i++) {
+ a[i] = (byte)random.nextInt();
+ }
+ return a;
+ }
+
+ static char[] generateC() {
+ char[] a = new char[RANGE_CON];
+ for (int i = 0; i < a.length; i++) {
+ a[i] = (char)random.nextInt();
+ }
+ return a;
+ }
+
+ static short[] generateS() {
+ short[] a = new short[RANGE_CON];
+ for (int i = 0; i < a.length; i++) {
+ a[i] = (short)random.nextInt();
+ }
+ return a;
+ }
+
+ static int[] generateI() {
+ int[] a = new int[RANGE_CON];
+ for (int i = 0; i < a.length; i++) {
+ a[i] = random.nextInt();
+ }
+ return a;
+ }
+
+ static long[] generateL() {
+ long[] a = new long[RANGE_CON];
+ for (int i = 0; i < a.length; i++) {
+ a[i] = random.nextLong();
+ }
+ return a;
+ }
+
+ static float[] generateF() {
+ float[] a = new float[RANGE_CON];
+ for (int i = 0; i < a.length; i++) {
+ a[i] = Float.intBitsToFloat(random.nextInt());
+ }
+ return a;
+ }
+
+ static double[] generateD() {
+ double[] a = new double[RANGE_CON];
+ for (int i = 0; i < a.length; i++) {
+ a[i] = Double.longBitsToDouble(random.nextLong());
+ }
+ return a;
+ }
+
+ static void verify(String name, Object[] gold, Object[] result) {
+ if (gold.length != result.length) {
+ throw new RuntimeException("verify " + name + ": not the same number of outputs: gold.length = " +
+ gold.length + ", result.length = " + result.length);
+ }
+ for (int i = 0; i < gold.length; i++) {
+ Object g = gold[i];
+ Object r = result[i];
+ if (g.getClass() != r.getClass() || !g.getClass().isArray() || !r.getClass().isArray()) {
+ throw new RuntimeException("verify " + name + ": must both be array of same type:" +
+ " gold[" + i + "].getClass() = " + g.getClass().getSimpleName() +
+ " result[" + i + "].getClass() = " + r.getClass().getSimpleName());
+ }
+ if (g == r) {
+ throw new RuntimeException("verify " + name + ": should be two separate arrays (with identical content):" +
+ " gold[" + i + "] == result[" + i + "]");
+ }
+ if (Array.getLength(g) != Array.getLength(r)) {
+ throw new RuntimeException("verify " + name + ": arrays must have same length:" +
+ " gold[" + i + "].length = " + Array.getLength(g) +
+ " result[" + i + "].length = " + Array.getLength(r));
+ }
+ Class c = g.getClass().getComponentType();
+ if (c == byte.class) {
+ verifyB(name, i, (byte[])g, (byte[])r);
+ } else if (c == char.class) {
+ verifyC(name, i, (char[])g, (char[])r);
+ } else if (c == short.class) {
+ verifyS(name, i, (short[])g, (short[])r);
+ } else if (c == int.class) {
+ verifyI(name, i, (int[])g, (int[])r);
+ } else if (c == long.class) {
+ verifyL(name, i, (long[])g, (long[])r);
+ } else if (c == float.class) {
+ verifyF(name, i, (float[])g, (float[])r);
+ } else if (c == double.class) {
+ verifyD(name, i, (double[])g, (double[])r);
+ } else {
+ throw new RuntimeException("verify " + name + ": array type not supported for verify:" +
+ " gold[" + i + "].getClass() = " + g.getClass().getSimpleName() +
+ " result[" + i + "].getClass() = " + r.getClass().getSimpleName());
+ }
+ }
+ }
+
+ static void verifyB(String name, int i, byte[] g, byte[] r) {
+ for (int j = 0; j < g.length; j++) {
+ if (g[j] != r[j]) {
+ throw new RuntimeException("verifyB " + name + ": arrays must have same content:" +
+ " gold[" + i + "][" + j + "] = " + g[j] +
+ " result[" + i + "][" + j + "] = " + r[j]);
+ }
+ }
+ }
+
+ static void verifyC(String name, int i, char[] g, char[] r) {
+ for (int j = 0; j < g.length; j++) {
+ if (g[j] != r[j]) {
+ throw new RuntimeException("verifyC " + name + ": arrays must have same content:" +
+ " gold[" + i + "][" + j + "] = " + g[j] +
+ " result[" + i + "][" + j + "] = " + r[j]);
+ }
+ }
+ }
+
+ static void verifyS(String name, int i, short[] g, short[] r) {
+ for (int j = 0; j < g.length; j++) {
+ if (g[j] != r[j]) {
+ throw new RuntimeException("verifyS " + name + ": arrays must have same content:" +
+ " gold[" + i + "][" + j + "] = " + g[j] +
+ " result[" + i + "][" + j + "] = " + r[j]);
+ }
+ }
+ }
+
+ static void verifyI(String name, int i, int[] g, int[] r) {
+ for (int j = 0; j < g.length; j++) {
+ if (g[j] != r[j]) {
+ throw new RuntimeException("verifyI " + name + ": arrays must have same content:" +
+ " gold[" + i + "][" + j + "] = " + g[j] +
+ " result[" + i + "][" + j + "] = " + r[j]);
+ }
+ }
+ }
+
+ static void verifyL(String name, int i, long[] g, long[] r) {
+ for (int j = 0; j < g.length; j++) {
+ if (g[j] != r[j]) {
+ throw new RuntimeException("verifyL " + name + ": arrays must have same content:" +
+ " gold[" + i + "][" + j + "] = " + g[j] +
+ " result[" + i + "][" + j + "] = " + r[j]);
+ }
+ }
+ }
+
+ static void verifyF(String name, int i, float[] g, float[] r) {
+ for (int j = 0; j < g.length; j++) {
+ int gv = UNSAFE.getInt(g, UNSAFE.ARRAY_FLOAT_BASE_OFFSET + 4 * j);
+ int rv = UNSAFE.getInt(r, UNSAFE.ARRAY_FLOAT_BASE_OFFSET + 4 * j);
+ if (gv != rv) {
+ throw new RuntimeException("verifyF " + name + ": arrays must have same content:" +
+ " gold[" + i + "][" + j + "] = " + gv +
+ " result[" + i + "][" + j + "] = " + rv);
+ }
+ }
+ }
+
+ static void verifyD(String name, int i, double[] g, double[] r) {
+ for (int j = 0; j < g.length; j++) {
+ long gv = UNSAFE.getLong(g, UNSAFE.ARRAY_DOUBLE_BASE_OFFSET + 8 * j);
+ long rv = UNSAFE.getLong(r, UNSAFE.ARRAY_DOUBLE_BASE_OFFSET + 8 * j);
+ if (gv != rv) {
+ throw new RuntimeException("verifyF " + name + ": arrays must have same content:" +
+ " gold[" + i + "][" + j + "] = " + gv +
+ " result[" + i + "][" + j + "] = " + rv);
+ }
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestDependencyOffsets.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestDependencyOffsets.java
index 105b07b875874..1e48ae071069f 100644
--- a/test/hotspot/jtreg/compiler/loopopts/superword/TestDependencyOffsets.java
+++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestDependencyOffsets.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, 2024, 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
@@ -27,7 +27,7 @@
* and various MaxVectorSize values, and +- AlignVector.
*
* Note: this test is auto-generated. Please modify / generate with script:
- * https://bugs.openjdk.org/browse/JDK-8312570
+ * https://bugs.openjdk.org/browse/JDK-8310190
*
* Types: int, long, short, char, byte, float, double
* Offsets: 0, -1, 1, -2, 2, -3, 3, -4, 4, -7, 7, -8, 8, -14, 14, -16, 16, -18, 18, -20, 20, -31, 31, -32, 32, -63, 63, -64, 64, -65, 65, -128, 128, -129, 129, -192, 192
@@ -49,8 +49,7 @@
* Note: sizeofop(type) = sizeof(type), except sizeofop(char) = 2
*
* Different types can lead to different vector_width. This depends on
- * the CPU-features. Thus, we have a positive and negative IR rule per
- * CPU-feature for each test.
+ * the CPU-features.
*
* Definition:
* MaxVectorSize: limit through flag
@@ -66,31 +65,53 @@
* or some additional optimization collapses some Loads, and suddenly cyclic
* dependency disappears, and we can vectorize.
*
- * With '-XX:+AlignVector', we would like to check that we vectorize exactly iff:
- * byte_offset % actual_vector_width == 0
- * Because all vector_widths are powers of 2, this is equivalent to:
- * pow2_factor(byte_offset) >= actual_vector_width
- * where pow2_factor computes the largest power of 2 that is a factor of the number.
+ * With '-XX:+AlignVector' we do the following:
*
- * Under these assumptions, we know there must be vectorization:
- * pow2_factor(byte_offset) >= vector_width
+ * Must vectorize cleanly if:
+ * 1) guaranteed no misalignment AND
+ * 2) guaratneed no cyclic dependency
+ *
+ * Must not vectorize at all if:
+ * 1) guaranteed misalignment AND
+ * 2) guaranteed no cyclic dependency
+ *
+ * We could imagine a case with cyclic dependency, where C2 detects
+ * that only the first load is needed, and so no vectorization is
+ * required for it, and hence the store vector can be aligned.
+ *
+ * The alignment criteria is
+ * byte_offset % aw == 0
+ * where align width (aw) is
+ * aw = min(actual_vector_width, ObjectAlignmentInBytes)
+ * For simplicity, we assume that ObjectAlignmentInBytes == 8,
+ * which currently can only be changed manually and then no IR
+ * rule is run.
+ * This allows us to do the computation statically.
+ * Further, we define:
+ * aw_min = min(min_vector_width, ObjectAlignmentInBytes)
+ * aw_max = min(vector_width, ObjectAlignmentInBytes)
+ * aw_min <= aw <= aw_max
+ *
+ * Again, we have no cyclic dependency, except when:
+ * byte_offset > 0 and p.vector_width > byte_offset
+ * Here we must ensure that:
+ * byte_offset >= MaxVectorSize
+ *
+ * Guaranteed no misalignment:
+ * byte_offset % aw_max == 0
* implies
- * pow2_factor(byte_offset) >= actual_vector_width
- * MaxVectorSize >= min_vector_size
- * else any vectorization is impossible.
+ * byte_offset % aw == 0
*
- * And under the following conditions no vectorization is possible:
- * byte_offset < 0: No cyclic dependency.
- * Cyclic dependency could lead to Load removals, then only the store is vectorized.
- * byte_offset % min_vector_width != 0
+ * Guaranteed misalignment:
+ * byte_offset % aw_min != 0
* implies
- * byte_offset % actual_vector_width != 0
+ * byte_offset % aw != 0
*
*/
/*
* @test id=vanilla-A
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @library /test/lib /
@@ -99,7 +120,7 @@
/*
* @test id=vanilla-U
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @library /test/lib /
@@ -108,7 +129,7 @@
/*
* @test id=sse4-v016-A
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -119,7 +140,7 @@
/*
* @test id=sse4-v016-U
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -130,7 +151,7 @@
/*
* @test id=sse4-v008-A
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -141,7 +162,7 @@
/*
* @test id=sse4-v008-U
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -152,7 +173,7 @@
/*
* @test id=sse4-v004-A
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -163,7 +184,7 @@
/*
* @test id=sse4-v004-U
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -174,7 +195,7 @@
/*
* @test id=sse4-v002-A
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -185,7 +206,7 @@
/*
* @test id=sse4-v002-U
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -196,7 +217,7 @@
/*
* @test id=avx1-v032-A
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -207,7 +228,7 @@
/*
* @test id=avx1-v032-U
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -218,7 +239,7 @@
/*
* @test id=avx1-v016-A
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -229,7 +250,7 @@
/*
* @test id=avx1-v016-U
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -240,7 +261,7 @@
/*
* @test id=avx2-v032-A
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -251,7 +272,7 @@
/*
* @test id=avx2-v032-U
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -262,7 +283,7 @@
/*
* @test id=avx2-v016-A
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -273,7 +294,7 @@
/*
* @test id=avx2-v016-U
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -284,7 +305,7 @@
/*
* @test id=avx512-v064-A
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -295,7 +316,7 @@
/*
* @test id=avx512-v064-U
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -306,7 +327,7 @@
/*
* @test id=avx512-v032-A
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -317,7 +338,7 @@
/*
* @test id=avx512-v032-U
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -328,7 +349,7 @@
/*
* @test id=avx512bw-v064-A
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -339,7 +360,7 @@
/*
* @test id=avx512bw-v064-U
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -350,7 +371,7 @@
/*
* @test id=avx512bw-v032-A
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -361,7 +382,7 @@
/*
* @test id=avx512bw-v032-U
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64")
@@ -372,7 +393,7 @@
/*
* @test id=vec-v064-A
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch!="x86" & os.arch!="i386" & os.arch!="amd64" & os.arch!="x86_64")
@@ -382,7 +403,7 @@
/*
* @test id=vec-v064-U
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch!="x86" & os.arch!="i386" & os.arch!="amd64" & os.arch!="x86_64")
@@ -392,7 +413,7 @@
/*
* @test id=vec-v032-A
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch!="x86" & os.arch!="i386" & os.arch!="amd64" & os.arch!="x86_64")
@@ -402,7 +423,7 @@
/*
* @test id=vec-v032-U
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch!="x86" & os.arch!="i386" & os.arch!="amd64" & os.arch!="x86_64")
@@ -412,7 +433,7 @@
/*
* @test id=vec-v016-A
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch!="x86" & os.arch!="i386" & os.arch!="amd64" & os.arch!="x86_64")
@@ -422,7 +443,7 @@
/*
* @test id=vec-v016-U
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch!="x86" & os.arch!="i386" & os.arch!="amd64" & os.arch!="x86_64")
@@ -432,7 +453,7 @@
/*
* @test id=vec-v008-A
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch!="x86" & os.arch!="i386" & os.arch!="amd64" & os.arch!="x86_64")
@@ -442,7 +463,7 @@
/*
* @test id=vec-v008-U
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch!="x86" & os.arch!="i386" & os.arch!="amd64" & os.arch!="x86_64")
@@ -452,7 +473,7 @@
/*
* @test id=vec-v004-A
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch!="x86" & os.arch!="i386" & os.arch!="amd64" & os.arch!="x86_64")
@@ -462,7 +483,7 @@
/*
* @test id=vec-v004-U
- * @bug 8298935 8308606 8310308 8312570
+ * @bug 8298935 8308606 8310308 8312570 8310190
* @summary Test SuperWord: vector size, offsets, dependencies, alignment.
* @requires vm.compiler2.enabled
* @requires (os.arch!="x86" & os.arch!="i386" & os.arch!="amd64" & os.arch!="x86_64")
@@ -1392,22 +1413,42 @@ public static void main(String args[]) {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntP0(int[] data) {
for (int j = 0; j < RANGE; j++) {
data[j + 0] = (int)(data[j] * (int)-11);
@@ -1428,7 +1469,7 @@ public static void runIntP0() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -1436,7 +1477,7 @@ public static void runIntP0() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
@@ -1444,7 +1485,7 @@ public static void runIntP0() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512", "true"})
@@ -1452,7 +1493,7 @@ public static void runIntP0() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -1460,7 +1501,7 @@ public static void runIntP0() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -1483,18 +1524,38 @@ public static void runIntM1() {
// CPU: sse4.1 to avx -> vector_width: 16 -> elements in vector: 4
// positive byte_offset 4 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
// positive byte_offset 4 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
// positive byte_offset 4 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 4"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
// positive byte_offset 4 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
// positive byte_offset 4 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntP1(int[] data) {
for (int j = 0; j < RANGE - 1; j++) {
data[j + 1] = (int)(data[j] * (int)-11);
@@ -1515,22 +1576,42 @@ public static void runIntP1() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntM2(int[] data) {
for (int j = 2; j < RANGE; j++) {
data[j + -2] = (int)(data[j] * (int)-11);
@@ -1550,27 +1631,47 @@ public static void runIntM2() {
// CPU: sse4.1 to avx -> vector_width: 16 -> elements in vector: 4
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 8"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 8"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "8"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 8"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "8"},
+ applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "8"},
applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 8"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 8"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "8"},
+ applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "8"},
applyIfCPUFeature = {"sve", "true"})
public static void testIntP2(int[] data) {
for (int j = 0; j < RANGE - 2; j++) {
@@ -1592,7 +1693,7 @@ public static void runIntP2() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -1600,7 +1701,7 @@ public static void runIntP2() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
@@ -1608,7 +1709,7 @@ public static void runIntP2() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512", "true"})
@@ -1616,7 +1717,7 @@ public static void runIntP2() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -1624,7 +1725,7 @@ public static void runIntP2() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -1649,26 +1750,46 @@ public static void runIntM3() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 12"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 12"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
// positive byte_offset 12 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 12"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 12"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
// positive byte_offset 12 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 12"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 12"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
// positive byte_offset 12 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 12"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 12"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
// positive byte_offset 12 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 12"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 12"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntP3(int[] data) {
for (int j = 0; j < RANGE - 3; j++) {
data[j + 3] = (int)(data[j] * (int)-11);
@@ -1689,22 +1810,42 @@ public static void runIntP3() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntM4(int[] data) {
for (int j = 4; j < RANGE; j++) {
data[j + -4] = (int)(data[j] * (int)-11);
@@ -1725,7 +1866,7 @@ public static void runIntM4() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -1734,16 +1875,24 @@ public static void runIntM4() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
// positive byte_offset 16 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -1752,6 +1901,10 @@ public static void runIntM4() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntP4(int[] data) {
for (int j = 0; j < RANGE - 4; j++) {
data[j + 4] = (int)(data[j] * (int)-11);
@@ -1772,7 +1925,7 @@ public static void runIntP4() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -1780,7 +1933,7 @@ public static void runIntP4() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
@@ -1788,7 +1941,7 @@ public static void runIntP4() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512", "true"})
@@ -1796,7 +1949,7 @@ public static void runIntP4() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -1804,7 +1957,7 @@ public static void runIntP4() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -1828,25 +1981,45 @@ public static void runIntM7() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
// positive byte_offset 28 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 28"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 28"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
// positive byte_offset 28 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 28"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 28"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
// positive byte_offset 28 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 28"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 28"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntP7(int[] data) {
for (int j = 0; j < RANGE - 7; j++) {
data[j + 7] = (int)(data[j] * (int)-11);
@@ -1867,22 +2040,42 @@ public static void runIntP7() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntM8(int[] data) {
for (int j = 8; j < RANGE; j++) {
data[j + -8] = (int)(data[j] * (int)-11);
@@ -1903,7 +2096,7 @@ public static void runIntM8() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -1911,7 +2104,7 @@ public static void runIntM8() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
@@ -1920,11 +2113,15 @@ public static void runIntM8() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 32"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 32"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -1933,6 +2130,10 @@ public static void runIntM8() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 32"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 32"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntP8(int[] data) {
for (int j = 0; j < RANGE - 8; j++) {
data[j + 8] = (int)(data[j] * (int)-11);
@@ -1953,22 +2154,42 @@ public static void runIntP8() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntM14(int[] data) {
for (int j = 14; j < RANGE; j++) {
data[j + -14] = (int)(data[j] * (int)-11);
@@ -1989,24 +2210,44 @@ public static void runIntM14() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
// positive byte_offset 56 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 56"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 56"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
// positive byte_offset 56 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 56"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 56"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntP14(int[] data) {
for (int j = 0; j < RANGE - 14; j++) {
data[j + 14] = (int)(data[j] * (int)-11);
@@ -2027,22 +2268,42 @@ public static void runIntP14() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntM16(int[] data) {
for (int j = 16; j < RANGE; j++) {
data[j + -16] = (int)(data[j] * (int)-11);
@@ -2063,7 +2324,7 @@ public static void runIntM16() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -2071,7 +2332,7 @@ public static void runIntM16() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
@@ -2079,7 +2340,7 @@ public static void runIntM16() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
@@ -2087,7 +2348,7 @@ public static void runIntM16() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -2096,6 +2357,10 @@ public static void runIntM16() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 64"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 64"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntP16(int[] data) {
for (int j = 0; j < RANGE - 16; j++) {
data[j + 16] = (int)(data[j] * (int)-11);
@@ -2116,22 +2381,42 @@ public static void runIntP16() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntM18(int[] data) {
for (int j = 18; j < RANGE; j++) {
data[j + -18] = (int)(data[j] * (int)-11);
@@ -2152,23 +2437,43 @@ public static void runIntM18() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
// positive byte_offset 72 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 72"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 72"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntP18(int[] data) {
for (int j = 0; j < RANGE - 18; j++) {
data[j + 18] = (int)(data[j] * (int)-11);
@@ -2189,22 +2494,42 @@ public static void runIntP18() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntM20(int[] data) {
for (int j = 20; j < RANGE; j++) {
data[j + -20] = (int)(data[j] * (int)-11);
@@ -2225,7 +2550,7 @@ public static void runIntM20() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -2233,15 +2558,23 @@ public static void runIntM20() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -2250,6 +2583,10 @@ public static void runIntM20() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 80"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 80"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntP20(int[] data) {
for (int j = 0; j < RANGE - 20; j++) {
data[j + 20] = (int)(data[j] * (int)-11);
@@ -2270,7 +2607,7 @@ public static void runIntP20() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -2278,7 +2615,7 @@ public static void runIntP20() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
@@ -2286,7 +2623,7 @@ public static void runIntP20() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512", "true"})
@@ -2294,7 +2631,7 @@ public static void runIntP20() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -2302,7 +2639,7 @@ public static void runIntP20() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -2326,23 +2663,43 @@ public static void runIntM31() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
// positive byte_offset 124 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 124"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 124"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntP31(int[] data) {
for (int j = 0; j < RANGE - 31; j++) {
data[j + 31] = (int)(data[j] * (int)-11);
@@ -2363,22 +2720,42 @@ public static void runIntP31() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntM32(int[] data) {
for (int j = 32; j < RANGE; j++) {
data[j + -32] = (int)(data[j] * (int)-11);
@@ -2399,7 +2776,7 @@ public static void runIntM32() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -2407,7 +2784,7 @@ public static void runIntM32() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
@@ -2415,7 +2792,7 @@ public static void runIntM32() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
@@ -2423,7 +2800,7 @@ public static void runIntM32() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -2432,6 +2809,10 @@ public static void runIntM32() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 128"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 128"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntP32(int[] data) {
for (int j = 0; j < RANGE - 32; j++) {
data[j + 32] = (int)(data[j] * (int)-11);
@@ -2452,7 +2833,7 @@ public static void runIntP32() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -2460,7 +2841,7 @@ public static void runIntP32() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
@@ -2468,7 +2849,7 @@ public static void runIntP32() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512", "true"})
@@ -2476,7 +2857,7 @@ public static void runIntP32() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -2484,7 +2865,7 @@ public static void runIntP32() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -2508,23 +2889,43 @@ public static void runIntM63() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // CPU: sve -> max vector_width: 256 -> max elements in vector: 64
- // positive byte_offset 252 can lead to cyclic dependency
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // CPU: sve -> max vector_width: 256 -> max elements in vector: 64
+ // positive byte_offset 252 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 252"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 252"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntP63(int[] data) {
for (int j = 0; j < RANGE - 63; j++) {
data[j + 63] = (int)(data[j] * (int)-11);
@@ -2545,22 +2946,42 @@ public static void runIntP63() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntM64(int[] data) {
for (int j = 64; j < RANGE; j++) {
data[j + -64] = (int)(data[j] * (int)-11);
@@ -2581,7 +3002,7 @@ public static void runIntM64() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -2589,7 +3010,7 @@ public static void runIntM64() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
@@ -2597,7 +3018,7 @@ public static void runIntM64() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
@@ -2605,7 +3026,7 @@ public static void runIntM64() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -2613,7 +3034,7 @@ public static void runIntM64() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
@@ -2637,7 +3058,7 @@ public static void runIntP64() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -2645,7 +3066,7 @@ public static void runIntP64() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
@@ -2653,7 +3074,7 @@ public static void runIntP64() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512", "true"})
@@ -2661,7 +3082,7 @@ public static void runIntP64() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -2669,7 +3090,7 @@ public static void runIntP64() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -2693,22 +3114,42 @@ public static void runIntM65() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntP65(int[] data) {
for (int j = 0; j < RANGE - 65; j++) {
data[j + 65] = (int)(data[j] * (int)-11);
@@ -2729,22 +3170,42 @@ public static void runIntP65() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntM128(int[] data) {
for (int j = 128; j < RANGE; j++) {
data[j + -128] = (int)(data[j] * (int)-11);
@@ -2765,7 +3226,7 @@ public static void runIntM128() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -2773,7 +3234,7 @@ public static void runIntM128() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
@@ -2781,7 +3242,7 @@ public static void runIntM128() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
@@ -2789,7 +3250,7 @@ public static void runIntM128() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -2797,7 +3258,7 @@ public static void runIntM128() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
@@ -2821,7 +3282,7 @@ public static void runIntP128() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -2829,7 +3290,7 @@ public static void runIntP128() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
@@ -2837,7 +3298,7 @@ public static void runIntP128() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512", "true"})
@@ -2845,7 +3306,7 @@ public static void runIntP128() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -2853,7 +3314,7 @@ public static void runIntP128() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -2877,22 +3338,42 @@ public static void runIntM129() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_I, IRNode.MUL_VI, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntP129(int[] data) {
for (int j = 0; j < RANGE - 129; j++) {
data[j + 129] = (int)(data[j] * (int)-11);
@@ -2913,22 +3394,42 @@ public static void runIntP129() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testIntM192(int[] data) {
for (int j = 192; j < RANGE; j++) {
data[j + -192] = (int)(data[j] * (int)-11);
@@ -2949,7 +3450,7 @@ public static void runIntM192() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -2957,7 +3458,7 @@ public static void runIntM192() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
@@ -2965,7 +3466,7 @@ public static void runIntM192() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
@@ -2973,7 +3474,7 @@ public static void runIntM192() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -2981,7 +3482,7 @@ public static void runIntM192() {
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
@@ -3005,22 +3506,42 @@ public static void runIntP192() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongP0(long[] data) {
for (int j = 0; j < RANGE; j++) {
data[j + 0] = (long)(data[j] + (long)-11);
@@ -3041,41 +3562,41 @@ public static void runLongP0() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
public static void testLongM1(long[] data) {
for (int j = 1; j < RANGE; j++) {
@@ -3096,18 +3617,28 @@ public static void runLongM1() {
// CPU: sse4.1 to avx -> vector_width: 16 -> elements in vector: 2
// positive byte_offset 8 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect alignment.
+ // No positive IR rule: conditions impossible.
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
// positive byte_offset 8 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect alignment.
+ // No positive IR rule: conditions impossible.
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
// positive byte_offset 8 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect alignment.
+ // No positive IR rule: conditions impossible.
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
// positive byte_offset 8 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect alignment.
+ // No positive IR rule: conditions impossible.
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
// positive byte_offset 8 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect alignment.
+ // No positive IR rule: conditions impossible.
public static void testLongP1(long[] data) {
for (int j = 0; j < RANGE - 1; j++) {
data[j + 1] = (long)(data[j] + (long)-11);
@@ -3128,22 +3659,42 @@ public static void runLongP1() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongM2(long[] data) {
for (int j = 2; j < RANGE; j++) {
data[j + -2] = (long)(data[j] + (long)-11);
@@ -3164,32 +3715,44 @@ public static void runLongM2() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
// positive byte_offset 16 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 16"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
// positive byte_offset 16 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 16"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "16"},
+ applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "16"},
applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
// positive byte_offset 16 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 16"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "16"},
+ applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "16"},
applyIfCPUFeature = {"sve", "true"})
public static void testLongP2(long[] data) {
for (int j = 0; j < RANGE - 2; j++) {
@@ -3211,41 +3774,41 @@ public static void runLongP2() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
public static void testLongM3(long[] data) {
for (int j = 3; j < RANGE; j++) {
@@ -3267,25 +3830,45 @@ public static void runLongM3() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
// positive byte_offset 24 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 24"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 24"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
// positive byte_offset 24 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 24"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 24"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
// positive byte_offset 24 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 24"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 24"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongP3(long[] data) {
for (int j = 0; j < RANGE - 3; j++) {
data[j + 3] = (long)(data[j] + (long)-11);
@@ -3306,22 +3889,42 @@ public static void runLongP3() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongM4(long[] data) {
for (int j = 4; j < RANGE; j++) {
data[j + -4] = (long)(data[j] + (long)-11);
@@ -3342,7 +3945,7 @@ public static void runLongM4() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -3350,7 +3953,7 @@ public static void runLongM4() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
@@ -3359,11 +3962,15 @@ public static void runLongM4() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 32"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 32"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -3372,6 +3979,10 @@ public static void runLongM4() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 32"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 32"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongP4(long[] data) {
for (int j = 0; j < RANGE - 4; j++) {
data[j + 4] = (long)(data[j] + (long)-11);
@@ -3392,41 +4003,41 @@ public static void runLongP4() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
public static void testLongM7(long[] data) {
for (int j = 7; j < RANGE; j++) {
@@ -3448,24 +4059,44 @@ public static void runLongM7() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
// positive byte_offset 56 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 56"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 56"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
// positive byte_offset 56 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 56"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 56"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongP7(long[] data) {
for (int j = 0; j < RANGE - 7; j++) {
data[j + 7] = (long)(data[j] + (long)-11);
@@ -3486,22 +4117,42 @@ public static void runLongP7() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongM8(long[] data) {
for (int j = 8; j < RANGE; j++) {
data[j + -8] = (long)(data[j] + (long)-11);
@@ -3522,7 +4173,7 @@ public static void runLongM8() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -3530,7 +4181,7 @@ public static void runLongM8() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
@@ -3538,7 +4189,7 @@ public static void runLongM8() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
@@ -3546,7 +4197,7 @@ public static void runLongM8() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -3555,6 +4206,10 @@ public static void runLongM8() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 64"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 64"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongP8(long[] data) {
for (int j = 0; j < RANGE - 8; j++) {
data[j + 8] = (long)(data[j] + (long)-11);
@@ -3575,22 +4230,42 @@ public static void runLongP8() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongM14(long[] data) {
for (int j = 14; j < RANGE; j++) {
data[j + -14] = (long)(data[j] + (long)-11);
@@ -3611,7 +4286,7 @@ public static void runLongM14() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -3619,15 +4294,23 @@ public static void runLongM14() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -3636,6 +4319,10 @@ public static void runLongM14() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 112"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 112"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongP14(long[] data) {
for (int j = 0; j < RANGE - 14; j++) {
data[j + 14] = (long)(data[j] + (long)-11);
@@ -3656,22 +4343,42 @@ public static void runLongP14() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // CPU: avx512 -> vector_width: 64 -> elements in vector: 8
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongM16(long[] data) {
for (int j = 16; j < RANGE; j++) {
data[j + -16] = (long)(data[j] + (long)-11);
@@ -3692,7 +4399,7 @@ public static void runLongM16() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -3700,7 +4407,7 @@ public static void runLongM16() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
@@ -3708,7 +4415,7 @@ public static void runLongM16() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
@@ -3716,7 +4423,7 @@ public static void runLongM16() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -3725,6 +4432,10 @@ public static void runLongM16() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 128"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 128"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongP16(long[] data) {
for (int j = 0; j < RANGE - 16; j++) {
data[j + 16] = (long)(data[j] + (long)-11);
@@ -3745,22 +4456,42 @@ public static void runLongP16() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongM18(long[] data) {
for (int j = 18; j < RANGE; j++) {
data[j + -18] = (long)(data[j] + (long)-11);
@@ -3781,7 +4512,7 @@ public static void runLongM18() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -3789,15 +4520,23 @@ public static void runLongM18() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -3806,6 +4545,10 @@ public static void runLongM18() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 144"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 144"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongP18(long[] data) {
for (int j = 0; j < RANGE - 18; j++) {
data[j + 18] = (long)(data[j] + (long)-11);
@@ -3826,22 +4569,42 @@ public static void runLongP18() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongM20(long[] data) {
for (int j = 20; j < RANGE; j++) {
data[j + -20] = (long)(data[j] + (long)-11);
@@ -3862,7 +4625,7 @@ public static void runLongM20() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -3870,7 +4633,7 @@ public static void runLongM20() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
@@ -3878,11 +4641,15 @@ public static void runLongM20() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -3891,6 +4658,10 @@ public static void runLongM20() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 160"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 160"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongP20(long[] data) {
for (int j = 0; j < RANGE - 20; j++) {
data[j + 20] = (long)(data[j] + (long)-11);
@@ -3911,41 +4682,41 @@ public static void runLongP20() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
public static void testLongM31(long[] data) {
for (int j = 31; j < RANGE; j++) {
@@ -3967,23 +4738,43 @@ public static void runLongM31() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
// positive byte_offset 248 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 248"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 248"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongP31(long[] data) {
for (int j = 0; j < RANGE - 31; j++) {
data[j + 31] = (long)(data[j] + (long)-11);
@@ -4004,22 +4795,42 @@ public static void runLongP31() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongM32(long[] data) {
for (int j = 32; j < RANGE; j++) {
data[j + -32] = (long)(data[j] + (long)-11);
@@ -4040,7 +4851,7 @@ public static void runLongM32() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -4048,7 +4859,7 @@ public static void runLongM32() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
@@ -4056,7 +4867,7 @@ public static void runLongM32() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
@@ -4064,7 +4875,7 @@ public static void runLongM32() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -4072,7 +4883,7 @@ public static void runLongM32() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
@@ -4096,41 +4907,41 @@ public static void runLongP32() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
public static void testLongM63(long[] data) {
for (int j = 63; j < RANGE; j++) {
@@ -4152,22 +4963,42 @@ public static void runLongM63() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongP63(long[] data) {
for (int j = 0; j < RANGE - 63; j++) {
data[j + 63] = (long)(data[j] + (long)-11);
@@ -4188,22 +5019,42 @@ public static void runLongP63() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongM64(long[] data) {
for (int j = 64; j < RANGE; j++) {
data[j + -64] = (long)(data[j] + (long)-11);
@@ -4224,7 +5075,7 @@ public static void runLongM64() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -4232,7 +5083,7 @@ public static void runLongM64() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
@@ -4240,7 +5091,7 @@ public static void runLongM64() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
@@ -4248,7 +5099,7 @@ public static void runLongM64() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -4256,7 +5107,7 @@ public static void runLongM64() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
@@ -4280,41 +5131,41 @@ public static void runLongP64() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
public static void testLongM65(long[] data) {
for (int j = 65; j < RANGE; j++) {
@@ -4336,22 +5187,42 @@ public static void runLongM65() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongP65(long[] data) {
for (int j = 0; j < RANGE - 65; j++) {
data[j + 65] = (long)(data[j] + (long)-11);
@@ -4372,22 +5243,42 @@ public static void runLongP65() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongM128(long[] data) {
for (int j = 128; j < RANGE; j++) {
data[j + -128] = (long)(data[j] + (long)-11);
@@ -4408,7 +5299,7 @@ public static void runLongM128() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -4416,7 +5307,7 @@ public static void runLongM128() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
@@ -4424,7 +5315,7 @@ public static void runLongM128() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
@@ -4432,7 +5323,7 @@ public static void runLongM128() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -4440,7 +5331,7 @@ public static void runLongM128() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
@@ -4464,41 +5355,41 @@ public static void runLongP128() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_L, IRNode.ADD_VL, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
public static void testLongM129(long[] data) {
for (int j = 129; j < RANGE; j++) {
@@ -4520,22 +5411,42 @@ public static void runLongM129() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongP129(long[] data) {
for (int j = 0; j < RANGE - 129; j++) {
data[j + 129] = (long)(data[j] + (long)-11);
@@ -4556,22 +5467,42 @@ public static void runLongP129() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testLongM192(long[] data) {
for (int j = 192; j < RANGE; j++) {
data[j + -192] = (long)(data[j] + (long)-11);
@@ -4592,7 +5523,7 @@ public static void runLongM192() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -4600,7 +5531,7 @@ public static void runLongM192() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512", "false"})
@@ -4608,7 +5539,7 @@ public static void runLongM192() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
@@ -4616,7 +5547,7 @@ public static void runLongM192() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -4624,7 +5555,7 @@ public static void runLongM192() {
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
@@ -4648,22 +5579,42 @@ public static void runLongP192() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortP0(short[] data) {
for (int j = 0; j < RANGE; j++) {
data[j + 0] = (short)(data[j] * (short)-11);
@@ -4684,7 +5635,7 @@ public static void runShortP0() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -4692,7 +5643,7 @@ public static void runShortP0() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -4700,7 +5651,7 @@ public static void runShortP0() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -4708,7 +5659,7 @@ public static void runShortP0() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -4716,7 +5667,7 @@ public static void runShortP0() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -4739,18 +5690,38 @@ public static void runShortM1() {
// CPU: sse4.1 to avx -> vector_width: 16 -> elements in vector: 8
// positive byte_offset 2 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 2"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
// positive byte_offset 2 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 2"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
// positive byte_offset 2 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 2"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
// positive byte_offset 2 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 2"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 2 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 2"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortP1(short[] data) {
for (int j = 0; j < RANGE - 1; j++) {
data[j + 1] = (short)(data[j] * (short)-11);
@@ -4771,22 +5742,27 @@ public static void runShortP1() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
public static void testShortM2(short[] data) {
for (int j = 2; j < RANGE; j++) {
data[j + -2] = (short)(data[j] * (short)-11);
@@ -4806,28 +5782,33 @@ public static void runShortM2() {
// CPU: sse4.1 to avx -> vector_width: 16 -> elements in vector: 8
// positive byte_offset 4 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 4"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
// positive byte_offset 4 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 4"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
// positive byte_offset 4 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 4"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
// positive byte_offset 4 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 4"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 4 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 4"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "4"},
applyIfCPUFeature = {"sve", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
public static void testShortP2(short[] data) {
for (int j = 0; j < RANGE - 2; j++) {
data[j + 2] = (short)(data[j] * (short)-11);
@@ -4848,7 +5829,7 @@ public static void runShortP2() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -4856,7 +5837,7 @@ public static void runShortP2() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -4864,7 +5845,7 @@ public static void runShortP2() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -4872,7 +5853,7 @@ public static void runShortP2() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -4880,7 +5861,7 @@ public static void runShortP2() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -4905,26 +5886,46 @@ public static void runShortM3() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 6"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 6"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
// positive byte_offset 6 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 6"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 6"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
// positive byte_offset 6 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 6"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 6"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
// positive byte_offset 6 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 6"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 6"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 6 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 6"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 6"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortP3(short[] data) {
for (int j = 0; j < RANGE - 3; j++) {
data[j + 3] = (short)(data[j] * (short)-11);
@@ -4945,22 +5946,42 @@ public static void runShortP3() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortM4(short[] data) {
for (int j = 4; j < RANGE; j++) {
data[j + -4] = (short)(data[j] * (short)-11);
@@ -4982,26 +6003,46 @@ public static void runShortM4() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortP4(short[] data) {
for (int j = 0; j < RANGE - 4; j++) {
data[j + 4] = (short)(data[j] * (short)-11);
@@ -5022,7 +6063,7 @@ public static void runShortP4() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -5030,7 +6071,7 @@ public static void runShortP4() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -5038,7 +6079,7 @@ public static void runShortP4() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -5046,7 +6087,7 @@ public static void runShortP4() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -5054,7 +6095,7 @@ public static void runShortP4() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -5079,26 +6120,46 @@ public static void runShortM7() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 14"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 14"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
// positive byte_offset 14 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 14"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 14"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
// positive byte_offset 14 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 14"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 14"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
// positive byte_offset 14 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 14"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 14"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 14 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 14"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 14"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortP7(short[] data) {
for (int j = 0; j < RANGE - 7; j++) {
data[j + 7] = (short)(data[j] * (short)-11);
@@ -5119,22 +6180,42 @@ public static void runShortP7() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortM8(short[] data) {
for (int j = 8; j < RANGE; j++) {
data[j + -8] = (short)(data[j] * (short)-11);
@@ -5155,7 +6236,7 @@ public static void runShortM8() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -5164,16 +6245,24 @@ public static void runShortM8() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
// positive byte_offset 16 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 16"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 16"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -5182,6 +6271,10 @@ public static void runShortM8() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortP8(short[] data) {
for (int j = 0; j < RANGE - 8; j++) {
data[j + 8] = (short)(data[j] * (short)-11);
@@ -5202,22 +6295,27 @@ public static void runShortP8() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
public static void testShortM14(short[] data) {
for (int j = 14; j < RANGE; j++) {
data[j + -14] = (short)(data[j] * (short)-11);
@@ -5238,25 +6336,30 @@ public static void runShortM14() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
// positive byte_offset 28 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 28"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
// positive byte_offset 28 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 28"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 28 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 28"},
applyIfCPUFeature = {"sve", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
public static void testShortP14(short[] data) {
for (int j = 0; j < RANGE - 14; j++) {
data[j + 14] = (short)(data[j] * (short)-11);
@@ -5277,22 +6380,42 @@ public static void runShortP14() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortM16(short[] data) {
for (int j = 16; j < RANGE; j++) {
data[j + -16] = (short)(data[j] * (short)-11);
@@ -5313,7 +6436,7 @@ public static void runShortM16() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -5321,7 +6444,7 @@ public static void runShortM16() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -5330,11 +6453,15 @@ public static void runShortM16() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 32"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 32"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -5343,6 +6470,10 @@ public static void runShortM16() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 32"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 32"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortP16(short[] data) {
for (int j = 0; j < RANGE - 16; j++) {
data[j + 16] = (short)(data[j] * (short)-11);
@@ -5363,22 +6494,27 @@ public static void runShortP16() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
public static void testShortM18(short[] data) {
for (int j = 18; j < RANGE; j++) {
data[j + -18] = (short)(data[j] * (short)-11);
@@ -5399,24 +6535,29 @@ public static void runShortM18() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
// positive byte_offset 36 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 36"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 36 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 36"},
applyIfCPUFeature = {"sve", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
public static void testShortP18(short[] data) {
for (int j = 0; j < RANGE - 18; j++) {
data[j + 18] = (short)(data[j] * (short)-11);
@@ -5437,22 +6578,42 @@ public static void runShortP18() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortM20(short[] data) {
for (int j = 20; j < RANGE; j++) {
data[j + -20] = (short)(data[j] * (short)-11);
@@ -5473,24 +6634,44 @@ public static void runShortM20() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
// positive byte_offset 40 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 40"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 40"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 40 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 40"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 40"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortP20(short[] data) {
for (int j = 0; j < RANGE - 20; j++) {
data[j + 20] = (short)(data[j] * (short)-11);
@@ -5511,7 +6692,7 @@ public static void runShortP20() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -5519,7 +6700,7 @@ public static void runShortP20() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -5527,7 +6708,7 @@ public static void runShortP20() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -5535,7 +6716,7 @@ public static void runShortP20() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -5543,7 +6724,7 @@ public static void runShortP20() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -5567,24 +6748,44 @@ public static void runShortM31() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
// positive byte_offset 62 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 62"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 62"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 62 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 62"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 62"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortP31(short[] data) {
for (int j = 0; j < RANGE - 31; j++) {
data[j + 31] = (short)(data[j] * (short)-11);
@@ -5605,22 +6806,42 @@ public static void runShortP31() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortM32(short[] data) {
for (int j = 32; j < RANGE; j++) {
data[j + -32] = (short)(data[j] * (short)-11);
@@ -5641,7 +6862,7 @@ public static void runShortM32() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -5649,7 +6870,7 @@ public static void runShortM32() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -5657,7 +6878,7 @@ public static void runShortM32() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -5665,7 +6886,7 @@ public static void runShortM32() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -5674,6 +6895,10 @@ public static void runShortM32() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 64"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 64"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortP32(short[] data) {
for (int j = 0; j < RANGE - 32; j++) {
data[j + 32] = (short)(data[j] * (short)-11);
@@ -5694,7 +6919,7 @@ public static void runShortP32() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -5702,7 +6927,7 @@ public static void runShortP32() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -5710,7 +6935,7 @@ public static void runShortP32() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -5718,7 +6943,7 @@ public static void runShortP32() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -5726,7 +6951,7 @@ public static void runShortP32() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -5750,23 +6975,43 @@ public static void runShortM63() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 126 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 126"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 126"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortP63(short[] data) {
for (int j = 0; j < RANGE - 63; j++) {
data[j + 63] = (short)(data[j] * (short)-11);
@@ -5787,22 +7032,42 @@ public static void runShortP63() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortM64(short[] data) {
for (int j = 64; j < RANGE; j++) {
data[j + -64] = (short)(data[j] * (short)-11);
@@ -5823,7 +7088,7 @@ public static void runShortM64() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -5831,7 +7096,7 @@ public static void runShortM64() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -5839,7 +7104,7 @@ public static void runShortM64() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -5847,7 +7112,7 @@ public static void runShortM64() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -5856,6 +7121,10 @@ public static void runShortM64() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 128"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 128"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortP64(short[] data) {
for (int j = 0; j < RANGE - 64; j++) {
data[j + 64] = (short)(data[j] * (short)-11);
@@ -5876,7 +7145,7 @@ public static void runShortP64() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -5884,7 +7153,7 @@ public static void runShortP64() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -5892,7 +7161,7 @@ public static void runShortP64() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -5900,7 +7169,7 @@ public static void runShortP64() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -5908,7 +7177,7 @@ public static void runShortP64() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -5932,23 +7201,43 @@ public static void runShortM65() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 130 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 130"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 130"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortP65(short[] data) {
for (int j = 0; j < RANGE - 65; j++) {
data[j + 65] = (short)(data[j] * (short)-11);
@@ -5969,22 +7258,42 @@ public static void runShortP65() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortM128(short[] data) {
for (int j = 128; j < RANGE; j++) {
data[j + -128] = (short)(data[j] * (short)-11);
@@ -6005,7 +7314,7 @@ public static void runShortM128() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -6013,7 +7322,7 @@ public static void runShortM128() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -6021,7 +7330,7 @@ public static void runShortM128() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -6029,7 +7338,7 @@ public static void runShortM128() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -6037,7 +7346,7 @@ public static void runShortM128() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
@@ -6061,7 +7370,7 @@ public static void runShortP128() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -6069,7 +7378,7 @@ public static void runShortP128() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -6077,7 +7386,7 @@ public static void runShortP128() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -6085,7 +7394,7 @@ public static void runShortP128() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -6093,7 +7402,7 @@ public static void runShortP128() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -6117,22 +7426,42 @@ public static void runShortM129() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_S, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortP129(short[] data) {
for (int j = 0; j < RANGE - 129; j++) {
data[j + 129] = (short)(data[j] * (short)-11);
@@ -6153,22 +7482,42 @@ public static void runShortP129() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortM192(short[] data) {
for (int j = 192; j < RANGE; j++) {
data[j + -192] = (short)(data[j] * (short)-11);
@@ -6189,7 +7538,7 @@ public static void runShortM192() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -6197,7 +7546,7 @@ public static void runShortM192() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -6205,7 +7554,7 @@ public static void runShortM192() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -6213,7 +7562,7 @@ public static void runShortM192() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -6221,6 +7570,10 @@ public static void runShortM192() {
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testShortP192(short[] data) {
for (int j = 0; j < RANGE - 192; j++) {
data[j + 192] = (short)(data[j] * (short)-11);
@@ -6241,24 +7594,44 @@ public static void runShortP192() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- public static void testCharP0(char[] data) {
- for (int j = 0; j < RANGE; j++) {
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
+ public static void testCharP0(char[] data) {
+ for (int j = 0; j < RANGE; j++) {
data[j + 0] = (char)(data[j] * (char)-11);
}
}
@@ -6277,7 +7650,7 @@ public static void runCharP0() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -6285,7 +7658,7 @@ public static void runCharP0() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -6293,7 +7666,7 @@ public static void runCharP0() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -6301,7 +7674,7 @@ public static void runCharP0() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -6309,7 +7682,7 @@ public static void runCharP0() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -6332,18 +7705,38 @@ public static void runCharM1() {
// CPU: sse4.1 to avx -> vector_width: 16 -> elements in vector: 8
// positive byte_offset 2 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 2"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
// positive byte_offset 2 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 2"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
// positive byte_offset 2 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 2"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
// positive byte_offset 2 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 2"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 2 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 2"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharP1(char[] data) {
for (int j = 0; j < RANGE - 1; j++) {
data[j + 1] = (char)(data[j] * (char)-11);
@@ -6364,22 +7757,27 @@ public static void runCharP1() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
public static void testCharM2(char[] data) {
for (int j = 2; j < RANGE; j++) {
data[j + -2] = (char)(data[j] * (char)-11);
@@ -6399,28 +7797,33 @@ public static void runCharM2() {
// CPU: sse4.1 to avx -> vector_width: 16 -> elements in vector: 8
// positive byte_offset 4 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 4"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
// positive byte_offset 4 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 4"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
// positive byte_offset 4 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 4"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
// positive byte_offset 4 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 4"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 4 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 4"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "4"},
applyIfCPUFeature = {"sve", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
public static void testCharP2(char[] data) {
for (int j = 0; j < RANGE - 2; j++) {
data[j + 2] = (char)(data[j] * (char)-11);
@@ -6441,7 +7844,7 @@ public static void runCharP2() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -6449,7 +7852,7 @@ public static void runCharP2() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -6457,7 +7860,7 @@ public static void runCharP2() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -6465,7 +7868,7 @@ public static void runCharP2() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -6473,7 +7876,7 @@ public static void runCharP2() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -6498,26 +7901,46 @@ public static void runCharM3() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 6"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 6"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
// positive byte_offset 6 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 6"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 6"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
// positive byte_offset 6 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 6"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 6"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
// positive byte_offset 6 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 6"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 6"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 6 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 6"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 6"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharP3(char[] data) {
for (int j = 0; j < RANGE - 3; j++) {
data[j + 3] = (char)(data[j] * (char)-11);
@@ -6538,22 +7961,42 @@ public static void runCharP3() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharM4(char[] data) {
for (int j = 4; j < RANGE; j++) {
data[j + -4] = (char)(data[j] * (char)-11);
@@ -6575,26 +8018,46 @@ public static void runCharM4() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharP4(char[] data) {
for (int j = 0; j < RANGE - 4; j++) {
data[j + 4] = (char)(data[j] * (char)-11);
@@ -6615,7 +8078,7 @@ public static void runCharP4() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -6623,7 +8086,7 @@ public static void runCharP4() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -6631,7 +8094,7 @@ public static void runCharP4() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -6639,7 +8102,7 @@ public static void runCharP4() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -6647,7 +8110,7 @@ public static void runCharP4() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -6672,26 +8135,46 @@ public static void runCharM7() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 14"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 14"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
// positive byte_offset 14 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 14"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 14"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
// positive byte_offset 14 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 14"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 14"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
// positive byte_offset 14 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 14"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 14"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 14 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 14"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 14"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharP7(char[] data) {
for (int j = 0; j < RANGE - 7; j++) {
data[j + 7] = (char)(data[j] * (char)-11);
@@ -6712,22 +8195,42 @@ public static void runCharP7() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharM8(char[] data) {
for (int j = 8; j < RANGE; j++) {
data[j + -8] = (char)(data[j] * (char)-11);
@@ -6748,7 +8251,7 @@ public static void runCharM8() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -6757,16 +8260,24 @@ public static void runCharM8() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
// positive byte_offset 16 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 16"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 16"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -6775,6 +8286,10 @@ public static void runCharM8() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharP8(char[] data) {
for (int j = 0; j < RANGE - 8; j++) {
data[j + 8] = (char)(data[j] * (char)-11);
@@ -6795,22 +8310,27 @@ public static void runCharP8() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
public static void testCharM14(char[] data) {
for (int j = 14; j < RANGE; j++) {
data[j + -14] = (char)(data[j] * (char)-11);
@@ -6831,25 +8351,30 @@ public static void runCharM14() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
// positive byte_offset 28 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 28"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
// positive byte_offset 28 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 28"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 28 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 28"},
applyIfCPUFeature = {"sve", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
public static void testCharP14(char[] data) {
for (int j = 0; j < RANGE - 14; j++) {
data[j + 14] = (char)(data[j] * (char)-11);
@@ -6870,22 +8395,42 @@ public static void runCharP14() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharM16(char[] data) {
for (int j = 16; j < RANGE; j++) {
data[j + -16] = (char)(data[j] * (char)-11);
@@ -6906,7 +8451,7 @@ public static void runCharM16() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -6914,7 +8459,7 @@ public static void runCharM16() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -6923,11 +8468,15 @@ public static void runCharM16() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 32"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 32"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -6936,6 +8485,10 @@ public static void runCharM16() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 32"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 32"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharP16(char[] data) {
for (int j = 0; j < RANGE - 16; j++) {
data[j + 16] = (char)(data[j] * (char)-11);
@@ -6956,22 +8509,27 @@ public static void runCharP16() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
public static void testCharM18(char[] data) {
for (int j = 18; j < RANGE; j++) {
data[j + -18] = (char)(data[j] * (char)-11);
@@ -6992,24 +8550,29 @@ public static void runCharM18() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
// positive byte_offset 36 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 36"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 36 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 36"},
applyIfCPUFeature = {"sve", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
public static void testCharP18(char[] data) {
for (int j = 0; j < RANGE - 18; j++) {
data[j + 18] = (char)(data[j] * (char)-11);
@@ -7030,22 +8593,42 @@ public static void runCharP18() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharM20(char[] data) {
for (int j = 20; j < RANGE; j++) {
data[j + -20] = (char)(data[j] * (char)-11);
@@ -7066,24 +8649,44 @@ public static void runCharM20() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
// positive byte_offset 40 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 40"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 40"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 40 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 40"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 40"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharP20(char[] data) {
for (int j = 0; j < RANGE - 20; j++) {
data[j + 20] = (char)(data[j] * (char)-11);
@@ -7104,7 +8707,7 @@ public static void runCharP20() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -7112,7 +8715,7 @@ public static void runCharP20() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -7120,7 +8723,7 @@ public static void runCharP20() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -7128,7 +8731,7 @@ public static void runCharP20() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -7136,7 +8739,7 @@ public static void runCharP20() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -7160,24 +8763,44 @@ public static void runCharM31() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
// positive byte_offset 62 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 62"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 62"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 62 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 62"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 62"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharP31(char[] data) {
for (int j = 0; j < RANGE - 31; j++) {
data[j + 31] = (char)(data[j] * (char)-11);
@@ -7198,22 +8821,42 @@ public static void runCharP31() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharM32(char[] data) {
for (int j = 32; j < RANGE; j++) {
data[j + -32] = (char)(data[j] * (char)-11);
@@ -7234,7 +8877,7 @@ public static void runCharM32() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -7242,7 +8885,7 @@ public static void runCharM32() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -7250,7 +8893,7 @@ public static void runCharM32() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -7258,7 +8901,7 @@ public static void runCharM32() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -7267,6 +8910,10 @@ public static void runCharM32() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 64"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 64"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharP32(char[] data) {
for (int j = 0; j < RANGE - 32; j++) {
data[j + 32] = (char)(data[j] * (char)-11);
@@ -7287,7 +8934,7 @@ public static void runCharP32() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -7295,7 +8942,7 @@ public static void runCharP32() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -7303,7 +8950,7 @@ public static void runCharP32() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -7311,7 +8958,7 @@ public static void runCharP32() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -7319,7 +8966,7 @@ public static void runCharP32() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -7343,23 +8990,43 @@ public static void runCharM63() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 126 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 126"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 126"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharP63(char[] data) {
for (int j = 0; j < RANGE - 63; j++) {
data[j + 63] = (char)(data[j] * (char)-11);
@@ -7380,22 +9047,42 @@ public static void runCharP63() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharM64(char[] data) {
for (int j = 64; j < RANGE; j++) {
data[j + -64] = (char)(data[j] * (char)-11);
@@ -7416,7 +9103,7 @@ public static void runCharM64() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -7424,7 +9111,7 @@ public static void runCharM64() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -7432,7 +9119,7 @@ public static void runCharM64() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -7440,7 +9127,7 @@ public static void runCharM64() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -7449,6 +9136,10 @@ public static void runCharM64() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 128"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 128"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharP64(char[] data) {
for (int j = 0; j < RANGE - 64; j++) {
data[j + 64] = (char)(data[j] * (char)-11);
@@ -7469,7 +9160,7 @@ public static void runCharP64() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -7477,7 +9168,7 @@ public static void runCharP64() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -7485,7 +9176,7 @@ public static void runCharP64() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -7493,7 +9184,7 @@ public static void runCharP64() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -7501,7 +9192,7 @@ public static void runCharP64() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -7525,23 +9216,43 @@ public static void runCharM65() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
// positive byte_offset 130 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 130"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 130"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharP65(char[] data) {
for (int j = 0; j < RANGE - 65; j++) {
data[j + 65] = (char)(data[j] * (char)-11);
@@ -7562,22 +9273,42 @@ public static void runCharP65() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharM128(char[] data) {
for (int j = 128; j < RANGE; j++) {
data[j + -128] = (char)(data[j] * (char)-11);
@@ -7598,7 +9329,7 @@ public static void runCharM128() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -7606,7 +9337,7 @@ public static void runCharM128() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -7614,7 +9345,7 @@ public static void runCharM128() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -7622,7 +9353,7 @@ public static void runCharM128() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -7630,7 +9361,7 @@ public static void runCharM128() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
@@ -7654,7 +9385,7 @@ public static void runCharP128() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -7662,7 +9393,7 @@ public static void runCharP128() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -7670,7 +9401,7 @@ public static void runCharP128() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -7678,7 +9409,7 @@ public static void runCharP128() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -7686,7 +9417,7 @@ public static void runCharP128() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -7710,22 +9441,42 @@ public static void runCharM129() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_C, IRNode.MUL_VS, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharP129(char[] data) {
for (int j = 0; j < RANGE - 129; j++) {
data[j + 129] = (char)(data[j] * (char)-11);
@@ -7746,22 +9497,42 @@ public static void runCharP129() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 128
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharM192(char[] data) {
for (int j = 192; j < RANGE; j++) {
data[j + -192] = (char)(data[j] * (char)-11);
@@ -7782,7 +9553,7 @@ public static void runCharM192() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -7790,7 +9561,7 @@ public static void runCharM192() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -7798,7 +9569,7 @@ public static void runCharM192() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -7806,7 +9577,7 @@ public static void runCharM192() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -7814,6 +9585,10 @@ public static void runCharM192() {
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.MUL_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testCharP192(char[] data) {
for (int j = 0; j < RANGE - 192; j++) {
data[j + 192] = (char)(data[j] * (char)-11);
@@ -7834,22 +9609,42 @@ public static void runCharP192() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteP0(byte[] data) {
for (int j = 0; j < RANGE; j++) {
data[j + 0] = (byte)(data[j] * (byte)11);
@@ -7870,7 +9665,7 @@ public static void runByteP0() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -7878,7 +9673,7 @@ public static void runByteP0() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -7886,7 +9681,7 @@ public static void runByteP0() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -7894,7 +9689,7 @@ public static void runByteP0() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -7902,7 +9697,7 @@ public static void runByteP0() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -7925,18 +9720,38 @@ public static void runByteM1() {
// CPU: sse4.1 to avx -> vector_width: 16 -> elements in vector: 16
// positive byte_offset 1 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 1"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
// positive byte_offset 1 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 1"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
// positive byte_offset 1 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 1"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
// positive byte_offset 1 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 1"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
// positive byte_offset 1 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 1"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteP1(byte[] data) {
for (int j = 0; j < RANGE - 1; j++) {
data[j + 1] = (byte)(data[j] * (byte)11);
@@ -7957,7 +9772,7 @@ public static void runByteP1() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -7965,7 +9780,7 @@ public static void runByteP1() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -7973,7 +9788,7 @@ public static void runByteP1() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -7981,7 +9796,7 @@ public static void runByteP1() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -7989,7 +9804,7 @@ public static void runByteP1() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -8012,18 +9827,38 @@ public static void runByteM2() {
// CPU: sse4.1 to avx -> vector_width: 16 -> elements in vector: 16
// positive byte_offset 2 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 2"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
// positive byte_offset 2 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 2"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
// positive byte_offset 2 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 2"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
// positive byte_offset 2 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 2"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
// positive byte_offset 2 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 2"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteP2(byte[] data) {
for (int j = 0; j < RANGE - 2; j++) {
data[j + 2] = (byte)(data[j] * (byte)11);
@@ -8044,7 +9879,7 @@ public static void runByteP2() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -8052,7 +9887,7 @@ public static void runByteP2() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -8060,7 +9895,7 @@ public static void runByteP2() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -8068,7 +9903,7 @@ public static void runByteP2() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -8076,7 +9911,7 @@ public static void runByteP2() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -8099,18 +9934,38 @@ public static void runByteM3() {
// CPU: sse4.1 to avx -> vector_width: 16 -> elements in vector: 16
// positive byte_offset 3 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 3"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
// positive byte_offset 3 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 3"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
// positive byte_offset 3 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 3"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
// positive byte_offset 3 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 3"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
// positive byte_offset 3 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 3"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteP3(byte[] data) {
for (int j = 0; j < RANGE - 3; j++) {
data[j + 3] = (byte)(data[j] * (byte)11);
@@ -8131,22 +9986,27 @@ public static void runByteP3() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
public static void testByteM4(byte[] data) {
for (int j = 4; j < RANGE; j++) {
data[j + -4] = (byte)(data[j] * (byte)11);
@@ -8166,28 +10026,33 @@ public static void runByteM4() {
// CPU: sse4.1 to avx -> vector_width: 16 -> elements in vector: 16
// positive byte_offset 4 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 4"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
// positive byte_offset 4 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 4"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
// positive byte_offset 4 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 4"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
// positive byte_offset 4 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 4"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
// positive byte_offset 4 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 4"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "4"},
applyIfCPUFeature = {"sve", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
public static void testByteP4(byte[] data) {
for (int j = 0; j < RANGE - 4; j++) {
data[j + 4] = (byte)(data[j] * (byte)11);
@@ -8208,7 +10073,7 @@ public static void runByteP4() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -8216,7 +10081,7 @@ public static void runByteP4() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -8224,7 +10089,7 @@ public static void runByteP4() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -8232,7 +10097,7 @@ public static void runByteP4() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -8240,7 +10105,7 @@ public static void runByteP4() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -8265,26 +10130,46 @@ public static void runByteM7() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 7"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 7"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
// positive byte_offset 7 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 7"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 7"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
// positive byte_offset 7 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 7"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 7"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
// positive byte_offset 7 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 7"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 7"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
// positive byte_offset 7 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 7"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 7"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteP7(byte[] data) {
for (int j = 0; j < RANGE - 7; j++) {
data[j + 7] = (byte)(data[j] * (byte)11);
@@ -8305,22 +10190,42 @@ public static void runByteP7() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteM8(byte[] data) {
for (int j = 8; j < RANGE; j++) {
data[j + -8] = (byte)(data[j] * (byte)11);
@@ -8342,26 +10247,46 @@ public static void runByteM8() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteP8(byte[] data) {
for (int j = 0; j < RANGE - 8; j++) {
data[j + 8] = (byte)(data[j] * (byte)11);
@@ -8382,7 +10307,7 @@ public static void runByteP8() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -8390,7 +10315,7 @@ public static void runByteP8() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -8398,7 +10323,7 @@ public static void runByteP8() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -8406,7 +10331,7 @@ public static void runByteP8() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -8414,7 +10339,7 @@ public static void runByteP8() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -8439,26 +10364,46 @@ public static void runByteM14() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 14"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 14"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
// positive byte_offset 14 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 14"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 14"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
// positive byte_offset 14 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 14"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 14"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
// positive byte_offset 14 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 14"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 14"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
// positive byte_offset 14 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 14"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 14"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteP14(byte[] data) {
for (int j = 0; j < RANGE - 14; j++) {
data[j + 14] = (byte)(data[j] * (byte)11);
@@ -8479,22 +10424,42 @@ public static void runByteP14() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteM16(byte[] data) {
for (int j = 16; j < RANGE; j++) {
data[j + -16] = (byte)(data[j] * (byte)11);
@@ -8515,7 +10480,7 @@ public static void runByteM16() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -8524,16 +10489,24 @@ public static void runByteM16() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 16"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 16"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
// positive byte_offset 16 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 16"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 16"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -8542,6 +10515,10 @@ public static void runByteM16() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteP16(byte[] data) {
for (int j = 0; j < RANGE - 16; j++) {
data[j + 16] = (byte)(data[j] * (byte)11);
@@ -8562,7 +10539,7 @@ public static void runByteP16() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -8570,7 +10547,7 @@ public static void runByteP16() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -8578,7 +10555,7 @@ public static void runByteP16() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -8586,7 +10563,7 @@ public static void runByteP16() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -8594,7 +10571,7 @@ public static void runByteP16() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -8618,25 +10595,45 @@ public static void runByteM18() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
// positive byte_offset 18 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 18"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 18"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
// positive byte_offset 18 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 18"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 18"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
// positive byte_offset 18 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 18"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 18"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteP18(byte[] data) {
for (int j = 0; j < RANGE - 18; j++) {
data[j + 18] = (byte)(data[j] * (byte)11);
@@ -8657,22 +10654,27 @@ public static void runByteP18() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
public static void testByteM20(byte[] data) {
for (int j = 20; j < RANGE; j++) {
data[j + -20] = (byte)(data[j] * (byte)11);
@@ -8693,25 +10695,30 @@ public static void runByteM20() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
// positive byte_offset 20 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 20"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
// positive byte_offset 20 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 20"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
// positive byte_offset 20 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 20"},
applyIfCPUFeature = {"sve", "true"})
+ // Alignment unclear -> no IR rule for -XX:+AlignVector.
public static void testByteP20(byte[] data) {
for (int j = 0; j < RANGE - 20; j++) {
data[j + 20] = (byte)(data[j] * (byte)11);
@@ -8732,7 +10739,7 @@ public static void runByteP20() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -8740,7 +10747,7 @@ public static void runByteP20() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -8748,7 +10755,7 @@ public static void runByteP20() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -8756,7 +10763,7 @@ public static void runByteP20() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -8764,7 +10771,7 @@ public static void runByteP20() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -8788,25 +10795,45 @@ public static void runByteM31() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
// positive byte_offset 31 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 31"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 31"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
// positive byte_offset 31 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 31"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 31"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
// positive byte_offset 31 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 31"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 31"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteP31(byte[] data) {
for (int j = 0; j < RANGE - 31; j++) {
data[j + 31] = (byte)(data[j] * (byte)11);
@@ -8827,22 +10854,42 @@ public static void runByteP31() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteM32(byte[] data) {
for (int j = 32; j < RANGE; j++) {
data[j + -32] = (byte)(data[j] * (byte)11);
@@ -8863,7 +10910,7 @@ public static void runByteM32() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -8871,7 +10918,7 @@ public static void runByteM32() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -8880,11 +10927,15 @@ public static void runByteM32() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 32"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 32"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -8893,6 +10944,10 @@ public static void runByteM32() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 32"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 32"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteP32(byte[] data) {
for (int j = 0; j < RANGE - 32; j++) {
data[j + 32] = (byte)(data[j] * (byte)11);
@@ -8913,7 +10968,7 @@ public static void runByteP32() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -8921,7 +10976,7 @@ public static void runByteP32() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -8929,7 +10984,7 @@ public static void runByteP32() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -8937,7 +10992,7 @@ public static void runByteP32() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -8945,7 +11000,7 @@ public static void runByteP32() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -8969,24 +11024,44 @@ public static void runByteM63() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
// positive byte_offset 63 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 63"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 63"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
// positive byte_offset 63 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 63"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 63"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteP63(byte[] data) {
for (int j = 0; j < RANGE - 63; j++) {
data[j + 63] = (byte)(data[j] * (byte)11);
@@ -9007,22 +11082,42 @@ public static void runByteP63() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteM64(byte[] data) {
for (int j = 64; j < RANGE; j++) {
data[j + -64] = (byte)(data[j] * (byte)11);
@@ -9043,7 +11138,7 @@ public static void runByteM64() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -9051,7 +11146,7 @@ public static void runByteM64() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -9059,7 +11154,7 @@ public static void runByteM64() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -9067,7 +11162,7 @@ public static void runByteM64() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -9076,6 +11171,10 @@ public static void runByteM64() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 64"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 64"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteP64(byte[] data) {
for (int j = 0; j < RANGE - 64; j++) {
data[j + 64] = (byte)(data[j] * (byte)11);
@@ -9096,7 +11195,7 @@ public static void runByteP64() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -9104,7 +11203,7 @@ public static void runByteP64() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -9112,7 +11211,7 @@ public static void runByteP64() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -9120,7 +11219,7 @@ public static void runByteP64() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -9128,7 +11227,7 @@ public static void runByteP64() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -9152,23 +11251,43 @@ public static void runByteM65() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
// positive byte_offset 65 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 65"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 65"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteP65(byte[] data) {
for (int j = 0; j < RANGE - 65; j++) {
data[j + 65] = (byte)(data[j] * (byte)11);
@@ -9189,22 +11308,42 @@ public static void runByteP65() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteM128(byte[] data) {
for (int j = 128; j < RANGE; j++) {
data[j + -128] = (byte)(data[j] * (byte)11);
@@ -9225,7 +11364,7 @@ public static void runByteM128() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -9233,7 +11372,7 @@ public static void runByteM128() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -9241,7 +11380,7 @@ public static void runByteM128() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -9249,7 +11388,7 @@ public static void runByteM128() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -9258,6 +11397,10 @@ public static void runByteM128() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 128"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 128"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteP128(byte[] data) {
for (int j = 0; j < RANGE - 128; j++) {
data[j + 128] = (byte)(data[j] * (byte)11);
@@ -9278,7 +11421,7 @@ public static void runByteP128() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -9286,7 +11429,7 @@ public static void runByteP128() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -9294,7 +11437,7 @@ public static void runByteP128() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -9302,7 +11445,7 @@ public static void runByteP128() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -9310,7 +11453,7 @@ public static void runByteP128() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -9334,23 +11477,43 @@ public static void runByteM129() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
// positive byte_offset 129 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 129"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_B, IRNode.MUL_VB, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 129"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteP129(byte[] data) {
for (int j = 0; j < RANGE - 129; j++) {
data[j + 129] = (byte)(data[j] * (byte)11);
@@ -9371,22 +11534,42 @@ public static void runByteP129() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
// CPU: avx2 to avx512 without avx512bw -> vector_width: 32 -> elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
// CPU: avx512bw -> vector_width: 64 -> elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"avx512bw", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 256
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteM192(byte[] data) {
for (int j = 192; j < RANGE; j++) {
data[j + -192] = (byte)(data[j] * (byte)11);
@@ -9407,7 +11590,7 @@ public static void runByteM192() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "false"})
@@ -9415,7 +11598,7 @@ public static void runByteM192() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx512bw", "false"})
@@ -9423,7 +11606,7 @@ public static void runByteM192() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeature = {"avx512bw", "true"})
@@ -9431,7 +11614,7 @@ public static void runByteM192() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -9440,6 +11623,10 @@ public static void runByteM192() {
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 192"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.MUL_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 4", "MaxVectorSize", "<= 192"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testByteP192(byte[] data) {
for (int j = 0; j < RANGE - 192; j++) {
data[j + 192] = (byte)(data[j] * (byte)11);
@@ -9460,21 +11647,41 @@ public static void runByteP192() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // CPU: sve -> max vector_width: 256 -> max elements in vector: 64
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // CPU: sve -> max vector_width: 256 -> max elements in vector: 64
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
public static void testFloatP0(float[] data) {
for (int j = 0; j < RANGE; j++) {
@@ -9496,7 +11703,7 @@ public static void runFloatP0() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -9504,7 +11711,7 @@ public static void runFloatP0() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
@@ -9512,7 +11719,7 @@ public static void runFloatP0() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512", "true"})
@@ -9520,7 +11727,7 @@ public static void runFloatP0() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -9528,7 +11735,7 @@ public static void runFloatP0() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -9551,18 +11758,38 @@ public static void runFloatM1() {
// CPU: sse4.1 -> vector_width: 16 -> elements in vector: 4
// positive byte_offset 4 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 4"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
// positive byte_offset 4 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 4"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
// positive byte_offset 4 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 4"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
// positive byte_offset 4 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 4"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
// positive byte_offset 4 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 4"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatP1(float[] data) {
for (int j = 0; j < RANGE - 1; j++) {
data[j + 1] = (float)(data[j] * (float)1.001f);
@@ -9583,22 +11810,42 @@ public static void runFloatP1() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatM2(float[] data) {
for (int j = 2; j < RANGE; j++) {
data[j + -2] = (float)(data[j] * (float)1.001f);
@@ -9618,27 +11865,47 @@ public static void runFloatM2() {
// CPU: sse4.1 -> vector_width: 16 -> elements in vector: 4
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 8"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 8"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "8"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 8"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "8"},
+ applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "8"},
applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 8"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
// positive byte_offset 8 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 8"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "8"},
+ applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "8"},
applyIfCPUFeature = {"sve", "true"})
public static void testFloatP2(float[] data) {
for (int j = 0; j < RANGE - 2; j++) {
@@ -9660,7 +11927,7 @@ public static void runFloatP2() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -9668,7 +11935,7 @@ public static void runFloatP2() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
@@ -9676,7 +11943,7 @@ public static void runFloatP2() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512", "true"})
@@ -9684,7 +11951,7 @@ public static void runFloatP2() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -9692,7 +11959,7 @@ public static void runFloatP2() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -9717,26 +11984,46 @@ public static void runFloatM3() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 12"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 12"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
// positive byte_offset 12 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 12"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 12"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
// positive byte_offset 12 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 12"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 12"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
// positive byte_offset 12 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 12"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 12"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
// positive byte_offset 12 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 12"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 12"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatP3(float[] data) {
for (int j = 0; j < RANGE - 3; j++) {
data[j + 3] = (float)(data[j] * (float)1.001f);
@@ -9757,22 +12044,42 @@ public static void runFloatP3() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatM4(float[] data) {
for (int j = 4; j < RANGE; j++) {
data[j + -4] = (float)(data[j] * (float)1.001f);
@@ -9793,7 +12100,7 @@ public static void runFloatM4() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -9802,16 +12109,24 @@ public static void runFloatM4() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 16"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
// positive byte_offset 16 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -9820,6 +12135,10 @@ public static void runFloatM4() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatP4(float[] data) {
for (int j = 0; j < RANGE - 4; j++) {
data[j + 4] = (float)(data[j] * (float)1.001f);
@@ -9840,7 +12159,7 @@ public static void runFloatP4() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -9848,7 +12167,7 @@ public static void runFloatP4() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
@@ -9856,7 +12175,7 @@ public static void runFloatP4() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512", "true"})
@@ -9864,7 +12183,7 @@ public static void runFloatP4() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -9872,7 +12191,7 @@ public static void runFloatP4() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -9896,25 +12215,45 @@ public static void runFloatM7() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
// positive byte_offset 28 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 28"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 28"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
// positive byte_offset 28 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 28"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 28"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
// positive byte_offset 28 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 28"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 28"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatP7(float[] data) {
for (int j = 0; j < RANGE - 7; j++) {
data[j + 7] = (float)(data[j] * (float)1.001f);
@@ -9935,22 +12274,42 @@ public static void runFloatP7() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatM8(float[] data) {
for (int j = 8; j < RANGE; j++) {
data[j + -8] = (float)(data[j] * (float)1.001f);
@@ -9971,7 +12330,7 @@ public static void runFloatM8() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -9979,7 +12338,7 @@ public static void runFloatM8() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
@@ -9988,11 +12347,15 @@ public static void runFloatM8() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 32"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 32"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -10001,6 +12364,10 @@ public static void runFloatM8() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 32"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 32"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatP8(float[] data) {
for (int j = 0; j < RANGE - 8; j++) {
data[j + 8] = (float)(data[j] * (float)1.001f);
@@ -10021,22 +12388,42 @@ public static void runFloatP8() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatM14(float[] data) {
for (int j = 14; j < RANGE; j++) {
data[j + -14] = (float)(data[j] * (float)1.001f);
@@ -10057,24 +12444,44 @@ public static void runFloatM14() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
// positive byte_offset 56 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 56"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 56"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
// positive byte_offset 56 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 56"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 56"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatP14(float[] data) {
for (int j = 0; j < RANGE - 14; j++) {
data[j + 14] = (float)(data[j] * (float)1.001f);
@@ -10095,22 +12502,42 @@ public static void runFloatP14() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatM16(float[] data) {
for (int j = 16; j < RANGE; j++) {
data[j + -16] = (float)(data[j] * (float)1.001f);
@@ -10131,7 +12558,7 @@ public static void runFloatM16() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -10139,7 +12566,7 @@ public static void runFloatM16() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
@@ -10147,7 +12574,7 @@ public static void runFloatM16() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
@@ -10155,7 +12582,7 @@ public static void runFloatM16() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -10164,6 +12591,10 @@ public static void runFloatM16() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 64"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 64"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatP16(float[] data) {
for (int j = 0; j < RANGE - 16; j++) {
data[j + 16] = (float)(data[j] * (float)1.001f);
@@ -10184,22 +12615,42 @@ public static void runFloatP16() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatM18(float[] data) {
for (int j = 18; j < RANGE; j++) {
data[j + -18] = (float)(data[j] * (float)1.001f);
@@ -10220,23 +12671,43 @@ public static void runFloatM18() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
// positive byte_offset 72 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 72"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 72"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatP18(float[] data) {
for (int j = 0; j < RANGE - 18; j++) {
data[j + 18] = (float)(data[j] * (float)1.001f);
@@ -10257,22 +12728,42 @@ public static void runFloatP18() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatM20(float[] data) {
for (int j = 20; j < RANGE; j++) {
data[j + -20] = (float)(data[j] * (float)1.001f);
@@ -10293,7 +12784,7 @@ public static void runFloatM20() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -10301,15 +12792,23 @@ public static void runFloatM20() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -10318,6 +12817,10 @@ public static void runFloatM20() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 80"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 80"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatP20(float[] data) {
for (int j = 0; j < RANGE - 20; j++) {
data[j + 20] = (float)(data[j] * (float)1.001f);
@@ -10338,7 +12841,7 @@ public static void runFloatP20() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -10346,7 +12849,7 @@ public static void runFloatP20() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
@@ -10354,7 +12857,7 @@ public static void runFloatP20() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512", "true"})
@@ -10362,7 +12865,7 @@ public static void runFloatP20() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -10370,7 +12873,7 @@ public static void runFloatP20() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -10394,23 +12897,43 @@ public static void runFloatM31() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
// positive byte_offset 124 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 124"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 124"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatP31(float[] data) {
for (int j = 0; j < RANGE - 31; j++) {
data[j + 31] = (float)(data[j] * (float)1.001f);
@@ -10431,22 +12954,42 @@ public static void runFloatP31() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatM32(float[] data) {
for (int j = 32; j < RANGE; j++) {
data[j + -32] = (float)(data[j] * (float)1.001f);
@@ -10467,7 +13010,7 @@ public static void runFloatM32() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -10475,7 +13018,7 @@ public static void runFloatM32() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
@@ -10483,7 +13026,7 @@ public static void runFloatM32() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
@@ -10491,7 +13034,7 @@ public static void runFloatM32() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -10500,6 +13043,10 @@ public static void runFloatM32() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 128"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 128"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatP32(float[] data) {
for (int j = 0; j < RANGE - 32; j++) {
data[j + 32] = (float)(data[j] * (float)1.001f);
@@ -10520,7 +13067,7 @@ public static void runFloatP32() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -10528,7 +13075,7 @@ public static void runFloatP32() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
@@ -10536,7 +13083,7 @@ public static void runFloatP32() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512", "true"})
@@ -10544,7 +13091,7 @@ public static void runFloatP32() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -10552,7 +13099,7 @@ public static void runFloatP32() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -10576,23 +13123,43 @@ public static void runFloatM63() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
// positive byte_offset 252 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8", "MaxVectorSize", "<= 252"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "<= 252"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatP63(float[] data) {
for (int j = 0; j < RANGE - 63; j++) {
data[j + 63] = (float)(data[j] * (float)1.001f);
@@ -10613,22 +13180,42 @@ public static void runFloatP63() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatM64(float[] data) {
for (int j = 64; j < RANGE; j++) {
data[j + -64] = (float)(data[j] * (float)1.001f);
@@ -10649,7 +13236,7 @@ public static void runFloatM64() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -10657,7 +13244,7 @@ public static void runFloatM64() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
@@ -10665,7 +13252,7 @@ public static void runFloatM64() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
@@ -10673,7 +13260,7 @@ public static void runFloatM64() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -10681,7 +13268,7 @@ public static void runFloatM64() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
@@ -10705,7 +13292,7 @@ public static void runFloatP64() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -10713,7 +13300,7 @@ public static void runFloatP64() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
@@ -10721,7 +13308,7 @@ public static void runFloatP64() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512", "true"})
@@ -10729,7 +13316,7 @@ public static void runFloatP64() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -10737,7 +13324,7 @@ public static void runFloatP64() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -10761,22 +13348,42 @@ public static void runFloatM65() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatP65(float[] data) {
for (int j = 0; j < RANGE - 65; j++) {
data[j + 65] = (float)(data[j] * (float)1.001f);
@@ -10797,22 +13404,42 @@ public static void runFloatP65() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatM128(float[] data) {
for (int j = 128; j < RANGE; j++) {
data[j + -128] = (float)(data[j] * (float)1.001f);
@@ -10833,7 +13460,7 @@ public static void runFloatM128() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -10841,7 +13468,7 @@ public static void runFloatM128() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
@@ -10849,7 +13476,7 @@ public static void runFloatM128() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
@@ -10857,7 +13484,7 @@ public static void runFloatM128() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -10865,7 +13492,7 @@ public static void runFloatM128() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
@@ -10889,7 +13516,7 @@ public static void runFloatP128() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -10897,7 +13524,7 @@ public static void runFloatP128() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
@@ -10905,7 +13532,7 @@ public static void runFloatP128() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"avx512", "true"})
@@ -10913,7 +13540,7 @@ public static void runFloatP128() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -10921,7 +13548,7 @@ public static void runFloatP128() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
+ // Expect misalignment.
@IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
applyIf = {"AlignVector", "true"},
applyIfCPUFeature = {"sve", "true"})
@@ -10945,22 +13572,42 @@ public static void runFloatM129() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect misalignment.
+ @IR(failOn = {IRNode.LOAD_VECTOR_F, IRNode.MUL_VF, IRNode.STORE_VECTOR},
+ applyIf = {"AlignVector", "true"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatP129(float[] data) {
for (int j = 0; j < RANGE - 129; j++) {
data[j + 129] = (float)(data[j] * (float)1.001f);
@@ -10981,22 +13628,42 @@ public static void runFloatP129() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 16
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 64
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testFloatM192(float[] data) {
for (int j = 192; j < RANGE; j++) {
data[j + -192] = (float)(data[j] * (float)1.001f);
@@ -11017,7 +13684,7 @@ public static void runFloatM192() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -11025,7 +13692,7 @@ public static void runFloatM192() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
@@ -11033,7 +13700,7 @@ public static void runFloatM192() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"avx512", "true"})
@@ -11041,7 +13708,7 @@ public static void runFloatM192() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -11049,7 +13716,7 @@ public static void runFloatM192() {
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.MUL_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 8"},
applyIfCPUFeature = {"sve", "true"})
@@ -11073,22 +13740,42 @@ public static void runFloatP192() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleP0(double[] data) {
for (int j = 0; j < RANGE; j++) {
data[j + 0] = (double)(data[j] * (double)1.001);
@@ -11109,41 +13796,41 @@ public static void runDoubleP0() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
public static void testDoubleM1(double[] data) {
for (int j = 1; j < RANGE; j++) {
@@ -11164,18 +13851,28 @@ public static void runDoubleM1() {
// CPU: sse4.1 -> vector_width: 16 -> elements in vector: 2
// positive byte_offset 8 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect alignment.
+ // No positive IR rule: conditions impossible.
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
// positive byte_offset 8 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect alignment.
+ // No positive IR rule: conditions impossible.
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
// positive byte_offset 8 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect alignment.
+ // No positive IR rule: conditions impossible.
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
// positive byte_offset 8 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect alignment.
+ // No positive IR rule: conditions impossible.
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
// positive byte_offset 8 can lead to cyclic dependency
// No positive IR rule: conditions impossible.
+ // Expect alignment.
+ // No positive IR rule: conditions impossible.
public static void testDoubleP1(double[] data) {
for (int j = 0; j < RANGE - 1; j++) {
data[j + 1] = (double)(data[j] * (double)1.001);
@@ -11196,22 +13893,42 @@ public static void runDoubleP1() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleM2(double[] data) {
for (int j = 2; j < RANGE; j++) {
data[j + -2] = (double)(data[j] * (double)1.001);
@@ -11232,32 +13949,44 @@ public static void runDoubleM2() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
// positive byte_offset 16 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 16"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "16"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
// positive byte_offset 16 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 16"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "16"},
+ applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "16"},
applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
// positive byte_offset 16 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
- applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 16"},
+ applyIfAnd = {"AlignVector", "false", "MaxVectorSize", "16"},
+ applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", "16"},
applyIfCPUFeature = {"sve", "true"})
public static void testDoubleP2(double[] data) {
for (int j = 0; j < RANGE - 2; j++) {
@@ -11279,41 +14008,41 @@ public static void runDoubleP2() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
public static void testDoubleM3(double[] data) {
for (int j = 3; j < RANGE; j++) {
@@ -11335,25 +14064,45 @@ public static void runDoubleM3() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
// positive byte_offset 24 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 24"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 24"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
// positive byte_offset 24 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 24"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 24"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
// positive byte_offset 24 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 24"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 24"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleP3(double[] data) {
for (int j = 0; j < RANGE - 3; j++) {
data[j + 3] = (double)(data[j] * (double)1.001);
@@ -11374,22 +14123,42 @@ public static void runDoubleP3() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleM4(double[] data) {
for (int j = 4; j < RANGE; j++) {
data[j + -4] = (double)(data[j] * (double)1.001);
@@ -11410,7 +14179,7 @@ public static void runDoubleM4() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -11418,7 +14187,7 @@ public static void runDoubleM4() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
@@ -11427,11 +14196,15 @@ public static void runDoubleM4() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 32"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 32"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -11440,6 +14213,10 @@ public static void runDoubleM4() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 32"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 32"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleP4(double[] data) {
for (int j = 0; j < RANGE - 4; j++) {
data[j + 4] = (double)(data[j] * (double)1.001);
@@ -11460,41 +14237,41 @@ public static void runDoubleP4() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
public static void testDoubleM7(double[] data) {
for (int j = 7; j < RANGE; j++) {
@@ -11516,24 +14293,44 @@ public static void runDoubleM7() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
// positive byte_offset 56 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 56"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 56"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
// positive byte_offset 56 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 56"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 56"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleP7(double[] data) {
for (int j = 0; j < RANGE - 7; j++) {
data[j + 7] = (double)(data[j] * (double)1.001);
@@ -11554,22 +14351,42 @@ public static void runDoubleP7() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleM8(double[] data) {
for (int j = 8; j < RANGE; j++) {
data[j + -8] = (double)(data[j] * (double)1.001);
@@ -11590,7 +14407,7 @@ public static void runDoubleM8() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -11598,7 +14415,7 @@ public static void runDoubleM8() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
@@ -11606,7 +14423,7 @@ public static void runDoubleM8() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
@@ -11614,7 +14431,7 @@ public static void runDoubleM8() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -11623,6 +14440,10 @@ public static void runDoubleM8() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 64"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 64"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleP8(double[] data) {
for (int j = 0; j < RANGE - 8; j++) {
data[j + 8] = (double)(data[j] * (double)1.001);
@@ -11643,22 +14464,42 @@ public static void runDoubleP8() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleM14(double[] data) {
for (int j = 14; j < RANGE; j++) {
data[j + -14] = (double)(data[j] * (double)1.001);
@@ -11679,7 +14520,7 @@ public static void runDoubleM14() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -11687,15 +14528,23 @@ public static void runDoubleM14() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -11704,6 +14553,10 @@ public static void runDoubleM14() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 112"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 112"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleP14(double[] data) {
for (int j = 0; j < RANGE - 14; j++) {
data[j + 14] = (double)(data[j] * (double)1.001);
@@ -11724,22 +14577,42 @@ public static void runDoubleP14() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleM16(double[] data) {
for (int j = 16; j < RANGE; j++) {
data[j + -16] = (double)(data[j] * (double)1.001);
@@ -11760,7 +14633,7 @@ public static void runDoubleM16() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -11768,7 +14641,7 @@ public static void runDoubleM16() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
@@ -11776,7 +14649,7 @@ public static void runDoubleM16() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
@@ -11784,7 +14657,7 @@ public static void runDoubleM16() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -11793,6 +14666,10 @@ public static void runDoubleM16() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 128"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 128"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleP16(double[] data) {
for (int j = 0; j < RANGE - 16; j++) {
data[j + 16] = (double)(data[j] * (double)1.001);
@@ -11813,22 +14690,42 @@ public static void runDoubleP16() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleM18(double[] data) {
for (int j = 18; j < RANGE; j++) {
data[j + -18] = (double)(data[j] * (double)1.001);
@@ -11849,7 +14746,7 @@ public static void runDoubleM18() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -11857,15 +14754,23 @@ public static void runDoubleM18() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -11874,6 +14779,10 @@ public static void runDoubleM18() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 144"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 144"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleP18(double[] data) {
for (int j = 0; j < RANGE - 18; j++) {
data[j + 18] = (double)(data[j] * (double)1.001);
@@ -11894,22 +14803,42 @@ public static void runDoubleP18() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleM20(double[] data) {
for (int j = 20; j < RANGE; j++) {
data[j + -20] = (double)(data[j] * (double)1.001);
@@ -11930,7 +14859,7 @@ public static void runDoubleM20() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -11938,7 +14867,7 @@ public static void runDoubleM20() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
@@ -11946,11 +14875,15 @@ public static void runDoubleM20() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -11959,6 +14892,10 @@ public static void runDoubleM20() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 160"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 160"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleP20(double[] data) {
for (int j = 0; j < RANGE - 20; j++) {
data[j + 20] = (double)(data[j] * (double)1.001);
@@ -11979,41 +14916,41 @@ public static void runDoubleP20() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
public static void testDoubleM31(double[] data) {
for (int j = 31; j < RANGE; j++) {
@@ -12035,23 +14972,43 @@ public static void runDoubleM31() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
// positive byte_offset 248 can lead to cyclic dependency
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 248"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16", "MaxVectorSize", "<= 248"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleP31(double[] data) {
for (int j = 0; j < RANGE - 31; j++) {
data[j + 31] = (double)(data[j] * (double)1.001);
@@ -12072,22 +15029,42 @@ public static void runDoubleP31() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleM32(double[] data) {
for (int j = 32; j < RANGE; j++) {
data[j + -32] = (double)(data[j] * (double)1.001);
@@ -12108,7 +15085,7 @@ public static void runDoubleM32() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -12116,7 +15093,7 @@ public static void runDoubleM32() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
@@ -12124,7 +15101,7 @@ public static void runDoubleM32() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
@@ -12132,7 +15109,7 @@ public static void runDoubleM32() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -12140,7 +15117,7 @@ public static void runDoubleM32() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
@@ -12164,41 +15141,41 @@ public static void runDoubleP32() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
public static void testDoubleM63(double[] data) {
for (int j = 63; j < RANGE; j++) {
@@ -12220,22 +15197,42 @@ public static void runDoubleM63() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleP63(double[] data) {
for (int j = 0; j < RANGE - 63; j++) {
data[j + 63] = (double)(data[j] * (double)1.001);
@@ -12256,22 +15253,42 @@ public static void runDoubleP63() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleM64(double[] data) {
for (int j = 64; j < RANGE; j++) {
data[j + -64] = (double)(data[j] * (double)1.001);
@@ -12292,7 +15309,7 @@ public static void runDoubleM64() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -12300,7 +15317,7 @@ public static void runDoubleM64() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
@@ -12308,7 +15325,7 @@ public static void runDoubleM64() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
@@ -12316,7 +15333,7 @@ public static void runDoubleM64() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -12324,7 +15341,7 @@ public static void runDoubleM64() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
@@ -12348,41 +15365,41 @@ public static void runDoubleP64() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
public static void testDoubleM65(double[] data) {
for (int j = 65; j < RANGE; j++) {
@@ -12404,22 +15421,42 @@ public static void runDoubleM65() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleP65(double[] data) {
for (int j = 0; j < RANGE - 65; j++) {
data[j + 65] = (double)(data[j] * (double)1.001);
@@ -12440,22 +15477,42 @@ public static void runDoubleP65() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleM128(double[] data) {
for (int j = 128; j < RANGE; j++) {
data[j + -128] = (double)(data[j] * (double)1.001);
@@ -12476,7 +15533,7 @@ public static void runDoubleM128() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -12484,7 +15541,7 @@ public static void runDoubleM128() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
@@ -12492,7 +15549,7 @@ public static void runDoubleM128() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
@@ -12500,7 +15557,7 @@ public static void runDoubleM128() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -12508,7 +15565,7 @@ public static void runDoubleM128() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
@@ -12532,41 +15589,41 @@ public static void runDoubleP128() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Strict alignment not possible.
- @IR(failOn = {IRNode.LOAD_VECTOR_D, IRNode.MUL_VD, IRNode.STORE_VECTOR},
- applyIf = {"AlignVector", "true"},
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
public static void testDoubleM129(double[] data) {
for (int j = 129; j < RANGE; j++) {
@@ -12588,22 +15645,42 @@ public static void runDoubleM129() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleP129(double[] data) {
for (int j = 0; j < RANGE - 129; j++) {
data[j + 129] = (double)(data[j] * (double)1.001);
@@ -12624,22 +15701,42 @@ public static void runDoubleP129() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
// CPU: avx and avx2 -> vector_width: 32 -> elements in vector: 4
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
// CPU: avx512 -> vector_width: 64 -> elements in vector: 8
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"avx512", "true"})
// CPU: asimd -> vector_width: 16 -> elements in vector: 2
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
// CPU: sve -> max vector_width: 256 -> max elements in vector: 32
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
+ // Expect alignment.
+ @IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
+ applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
+ applyIfCPUFeature = {"sve", "true"})
public static void testDoubleM192(double[] data) {
for (int j = 192; j < RANGE; j++) {
data[j + -192] = (double)(data[j] * (double)1.001);
@@ -12660,7 +15757,7 @@ public static void runDoubleM192() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx", "false"})
@@ -12668,7 +15765,7 @@ public static void runDoubleM192() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx512", "false"})
@@ -12676,7 +15773,7 @@ public static void runDoubleM192() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"avx512", "true"})
@@ -12684,7 +15781,7 @@ public static void runDoubleM192() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
@@ -12692,7 +15789,7 @@ public static void runDoubleM192() {
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "false", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
- // Vectorize when strict alignment guaranteed.
+ // Expect alignment.
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.MUL_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
applyIfAnd = {"AlignVector", "true", "MaxVectorSize", ">= 16"},
applyIfCPUFeature = {"sve", "true"})
diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestMovingLoadBeforeStore.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestMovingLoadBeforeStore.java
index 80922aeffe9cd..752c8010468a3 100644
--- a/test/hotspot/jtreg/compiler/loopopts/superword/TestMovingLoadBeforeStore.java
+++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestMovingLoadBeforeStore.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, 2024, 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
@@ -25,7 +25,6 @@
/**
* @test
* @requires vm.compiler2.enabled
- * @requires vm.cpu.features ~= ".*avx2.*"
* @bug 8316679 8316594
* @summary In SuperWord::output, LoadVector can be moved before StoreVector, but only if it is proven to be safe.
* @key randomness
diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestMulAddS2I.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestMulAddS2I.java
index 78e97f26817f8..e32da89b8cd58 100644
--- a/test/hotspot/jtreg/compiler/loopopts/superword/TestMulAddS2I.java
+++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestMulAddS2I.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, 2024, 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
@@ -24,7 +24,6 @@
/**
* @test
* @bug 8310886
- * @requires os.arch == "x86_64" | os.arch == "aarch64"
* @summary Test MulAddS2I vectorization.
* @library /test/lib /
* @run driver compiler.loopopts.superword.TestMulAddS2I
@@ -75,15 +74,14 @@ public static void compare(int[] out) {
}
@Test
- @IR(applyIfCPUFeature = {"sse2", "true"}, applyIf = {"UseUnalignedLoadStores", "true"},
+ @IR(applyIfCPUFeature = {"sse2", "true"},
+ applyIfPlatform = {"64-bit", "true"},
counts = {IRNode.MUL_ADD_S2I, "> 0", IRNode.MUL_ADD_VS2VI, "> 0"})
- @IR(applyIfCPUFeature = {"sse2", "true"}, applyIf = {"UseUnalignedLoadStores", "false"},
- failOn = {IRNode.MUL_ADD_VS2VI}, // Can only pack LoadS if UseUnalignedLoadStores is true (default if sse4.2)
- counts = {IRNode.MUL_ADD_S2I, "> 0"})
- @IR(applyIfCPUFeature = {"asimd", "true"}, applyIf = {"MaxVectorSize", "16"}, // AD file requires vector_length = 16
- counts = {IRNode.MUL_ADD_S2I, "> 0", IRNode.MUL_ADD_VS2VI, "> 0"})
- @IR(applyIfCPUFeature = {"avx512_vnni", "true"}, applyIf = {"UseUnalignedLoadStores", "true"},
- counts = {IRNode.MUL_ADD_S2I, "> 0", IRNode.MUL_ADD_VS2VI_VNNI, "> 0"})
+ @IR(applyIfCPUFeature = {"asimd", "true"},
+ applyIf = {"MaxVectorSize", "16"}, // AD file requires vector_length = 16
+ counts = {IRNode.MUL_ADD_S2I, "> 0", IRNode.MUL_ADD_VS2VI, "> 0"})
+ @IR(applyIfCPUFeature = {"avx512_vnni", "true"},
+ counts = {IRNode.MUL_ADD_S2I, "> 0", IRNode.MUL_ADD_VS2VI_VNNI, "> 0"})
public static int[] test() {
int[] out = new int[ITER];
int[] out2 = new int[ITER];
diff --git a/test/hotspot/jtreg/compiler/vectorization/TestBufferVectorization.java b/test/hotspot/jtreg/compiler/vectorization/TestBufferVectorization.java
index 889cc68f876b6..76251ba99c8c3 100644
--- a/test/hotspot/jtreg/compiler/vectorization/TestBufferVectorization.java
+++ b/test/hotspot/jtreg/compiler/vectorization/TestBufferVectorization.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2024, 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
@@ -23,24 +23,17 @@
/**
* @test
- * @bug 8257531
+ * @bug 8257531 8310190
* @summary Test vectorization for Buffer operations.
* @library /test/lib /
- *
- * @requires vm.flagless
- * @requires vm.compiler2.enabled & vm.debug == true
- * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64"
- *
- * @run driver compiler.vectorization.TestBufferVectorization array
- * @run driver compiler.vectorization.TestBufferVectorization arrayOffset
- * @run driver compiler.vectorization.TestBufferVectorization buffer
- * @run driver compiler.vectorization.TestBufferVectorization bufferHeap
- * @run driver compiler.vectorization.TestBufferVectorization bufferDirect
- * @run driver compiler.vectorization.TestBufferVectorization arrayView
+ * @requires vm.compiler2.enabled
+ * @run driver compiler.vectorization.TestBufferVectorization
*/
package compiler.vectorization;
+import compiler.lib.ir_framework.*;
+
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
@@ -48,205 +41,196 @@
import java.nio.ByteOrder;
import java.nio.IntBuffer;
-import jdk.test.lib.Platform;
-import jdk.test.lib.process.ProcessTools;
-import jdk.test.lib.process.OutputAnalyzer;
-
public class TestBufferVectorization {
- final static int N = 500;
- final static int ITER = 1000;
- final static IntBuffer buffer = IntBuffer.allocate(N);
- final static int offset = buffer.arrayOffset();
- final static IntBuffer heap_buffer_byte_to_int = ByteBuffer.allocate(N * Integer.BYTES).order(ByteOrder.nativeOrder()).asIntBuffer();
- final static IntBuffer direct_buffer_byte_to_int = ByteBuffer.allocateDirect(N * Integer.BYTES).order(ByteOrder.nativeOrder()).asIntBuffer();
+ final static int N = 1024*16;
+ static int offset = 0;
final static VarHandle VH_arr_view = MethodHandles.byteArrayViewVarHandle(int[].class, ByteOrder.nativeOrder()).withInvokeExactBehavior();
- final static String arch = System.getProperty("os.arch");
- interface Test {
- void init();
- void run();
- void verify();
+ public static void main(String[] args) {
+ TestFramework.run();
}
- static class TestArray implements Test {
- final int[] array = new int[N];
+ @Run(test = "testArray")
+ public static void runArray() {
+ int[] array = new int[N];
- public void init() {
- for (int k = 0; k < array.length; k++) {
- array[k] = k;
- }
+ for (int k = 0; k < array.length; k++) {
+ array[k] = k;
}
- public void run() {
- for(int k = 0; k < array.length; k++) {
- array[k] += 1;
+ testArray(array);
+
+ for(int k = 0; k < array.length; k++) {
+ if (array[k] != (k + 1)) {
+ throw new RuntimeException(" Invalid result: array[" + k + "]: " + array[k] + " != " + (k + 1));
}
}
+ }
- public void verify() {
- init(); // reset
- run(); // run compiled code
- for(int k = 0; k < array.length; k++) {
- if (array[k] != (k + 1)) {
- throw new RuntimeException(" Invalid result: array[" + k + "]: " + array[k] + " != " + (k + 1));
- }
- }
+ @Test
+ @IR(counts = {IRNode.REPLICATE_I, ">0",
+ IRNode.LOAD_VECTOR_I, ">0",
+ IRNode.ADD_VI, ">0",
+ IRNode.STORE_VECTOR, ">0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ public static void testArray(int[] array) {
+ for(int k = 0; k < array.length; k++) {
+ array[k] += 1;
}
}
- static class TestArrayOffset implements Test {
- final int offset;
- final int[] array = new int[N];
+ @Run(test = "testArrayOffset")
+ public static void runArrayOffset() {
+ // Moving offset between 0..255
+ offset = (offset + 1) % 256;
- public TestArrayOffset(int off) {
- offset = off;
- }
+ int[] array = new int[N];
- public void init() {
- for (int k = 0; k < array.length; k++) {
- array[k] = k;
- }
+ for (int k = 0; k < array.length; k++) {
+ array[k] = k;
}
- public void run() {
- int l = array.length - offset;
- for(int k = 0; k < l; k++) {
- array[k + offset] += 1;
- }
- }
+ testArrayOffset(array, offset);
- public void verify() {
- init(); // reset
- run(); // run compiled code
- int l = array.length - offset;
- for(int k = 0; k < l; k++) {
- if (array[k] != (k + 1)) {
- throw new RuntimeException(" Invalid result: arrayOffset[" + k + "]: " + array[k] + " != " + (k + 1));
- }
+ int l = array.length - offset;
+ for(int k = 0; k < offset; k++) {
+ if (array[k] != k) {
+ throw new RuntimeException(" Invalid result: arrayOffset[" + k + "]: " + array[k] + " != " + (k + 1));
}
- for(int k = l; k < array.length; k++) {
- if (array[k] != k) {
- throw new RuntimeException(" Invalid result: arrayOffset[" + k + "]: " + array[k] + " != " + k);
- }
+ }
+ for(int k = offset; k < array.length; k++) {
+ if (array[k] != (k + 1)) {
+ throw new RuntimeException(" Invalid result: arrayOffset[" + k + "]: " + array[k] + " != " + k);
}
}
}
- static class TestBuffer implements Test {
- final IntBuffer buffer;
-
- public TestBuffer(IntBuffer buf) {
- buffer = buf;
- }
-
- public void init() {
- for (int k = 0; k < buffer.limit(); k++) {
- buffer.put(k, k);
- }
+ @Test
+ @IR(counts = {IRNode.REPLICATE_I, ">0",
+ IRNode.LOAD_VECTOR_I, ">0",
+ IRNode.ADD_VI, ">0",
+ IRNode.STORE_VECTOR, ">0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ public static void testArrayOffset(int[] array, int offset) {
+ int l = array.length - offset;
+ for(int k = 0; k < l; k++) {
+ array[k + offset] += 1;
}
+ }
- public void run() {
- for (int k = 0; k < buffer.limit(); k++) {
- buffer.put(k, buffer.get(k) + 1);
- }
- }
+ @Run(test = "testBuffer")
+ public static void runBuffer() {
+ IntBuffer buffer = IntBuffer.allocate(N);
+ initBuffer(buffer);
+ testBuffer(buffer);
+ verifyBuffer(buffer);
+ }
- public void verify() {
- init(); // reset
- run(); // run compiled code
- for(int k = 0; k < buffer.limit(); k++) {
- if (buffer.get(k) != (k + 1)) {
- throw new RuntimeException(" Invalid result: buffer.get(" + k + "): " + buffer.get(k) + " != " + (k + 1));
- }
- }
+ @Test
+ @IR(counts = {IRNode.REPLICATE_I, ">0",
+ IRNode.LOAD_VECTOR_I, ">0",
+ IRNode.ADD_VI, ">0",
+ IRNode.STORE_VECTOR, ">0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ public static void testBuffer(IntBuffer buffer) {
+ for (int k = 0; k < buffer.limit(); k++) {
+ buffer.put(k, buffer.get(k) + 1);
}
}
- static class TestArrayView implements Test {
- final byte[] b_arr = new byte[N * Integer.BYTES];
+ @Run(test = "testBufferHeap")
+ public static void runBufferHeap() {
+ IntBuffer buffer = ByteBuffer.allocate(N * Integer.BYTES).order(ByteOrder.nativeOrder()).asIntBuffer();
+ initBuffer(buffer);
+ testBufferHeap(buffer);
+ verifyBuffer(buffer);
+ }
- public void init() {
- for (int k = 0; k < N; k++) {
- VH_arr_view.set(b_arr, k, k);
- }
+ @Test
+ @IR(counts = {IRNode.REPLICATE_I, IRNode.VECTOR_SIZE_ANY, ">0",
+ IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE_ANY, ">0",
+ IRNode.ADD_VI, IRNode.VECTOR_SIZE_ANY, ">0",
+ IRNode.STORE_VECTOR, ">0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"},
+ applyIf = {"AlignVector", "false"},
+ applyIfPlatform = {"64-bit", "true"})
+ // VECTOR_SIZE_ANY: Unrolling does not always seem to go far enough to reach maximum vector size.
+ // This looks like a BUG.
+ // AlignVector: Buffer get/put have an invariant that is in bytes (LoadL in ByteBufferAsIntBufferL::byteOffset).
+ // This makes sense: we are accessing a byte buffer. But to be able to align the 4 byte ints,
+ // we would require to know that the invariant is a multiple of 4. Without that, we cannot
+ // guarantee alignment by adjusting the limit of the pre-loop with a stride of 4 bytes.
+ // 64-bit: bufferHeap uses Long type for memory accesses which are not vectorized in 32-bit VM
+ public static void testBufferHeap(IntBuffer buffer) {
+ for (int k = 0; k < buffer.limit(); k++) {
+ buffer.put(k, buffer.get(k) + 1);
}
+ }
- public void run() {
- for (int k = 0; k < b_arr.length; k += 4) {
- int v = (int) VH_arr_view.get(b_arr, k);
- VH_arr_view.set(b_arr, k, v + 1);
- }
+ @Run(test = "testBufferDirect")
+ public static void runBufferDirect() {
+ IntBuffer buffer = ByteBuffer.allocateDirect(N * Integer.BYTES).order(ByteOrder.nativeOrder()).asIntBuffer();
+ initBuffer(buffer);
+ testBufferDirect(buffer);
+ verifyBuffer(buffer);
+ }
+
+ @Test
+ // bufferDirect uses Unsafe memory accesses which are not vectorized currently
+ // We find a CastX2P in pointer analysis (VPointer)
+ public static void testBufferDirect(IntBuffer buffer) {
+ for (int k = 0; k < buffer.limit(); k++) {
+ buffer.put(k, buffer.get(k) + 1);
}
+ }
- public void verify() {
- init(); // reset
- // Save initial INT values
- final int[] i_arr = new int[N];
- for (int k = 0; k < i_arr.length; k++) {
- i_arr[k] = (int) VH_arr_view.get(b_arr, k * Integer.BYTES);
- }
- run(); // run compiled code
- for (int k = 0; k < i_arr.length; k++) {
- int v = (int) VH_arr_view.get(b_arr, k * Integer.BYTES);
- if (v != (i_arr[k] + 1)) {
- throw new RuntimeException(" Invalid result: VH_arr_view.get(b_arr, " + (k * Integer.BYTES) + "): " + v + " != " + (i_arr[k] + 1));
- }
- }
+ public static void initBuffer(IntBuffer buffer) {
+ for (int k = 0; k < buffer.limit(); k++) {
+ buffer.put(k, k);
}
}
- public static void main(String[] args) {
- if (args.length == 0) {
- throw new RuntimeException(" Missing test name: array, arrayOffset, buffer, bufferHeap, bufferDirect, arrayView");
- } else if (args.length == 1) {
- verify_vectors(args[0]);
- } else {
- Test te = switch (args[0]) {
- case "array" -> new TestArray();
- case "arrayOffset" -> new TestArrayOffset(offset);
- case "buffer" -> new TestBuffer(buffer);
- case "bufferHeap" -> new TestBuffer(heap_buffer_byte_to_int);
- case "bufferDirect" -> new TestBuffer(direct_buffer_byte_to_int);
- case "arrayView" -> new TestArrayView();
- default -> throw new RuntimeException(" Unknown test: " + args[0]);
- };
-
- te.init();
- for (int i = 0; i < ITER; i++) {
- te.run();
+ public static void verifyBuffer(IntBuffer buffer) {
+ for(int k = 0; k < buffer.limit(); k++) {
+ if (buffer.get(k) != (k + 1)) {
+ throw new RuntimeException(" Invalid result: buffer.get(" + k + "): " + buffer.get(k) + " != " + (k + 1));
}
- te.verify();
}
-
}
- static void verify_vectors(String testName) {
- ProcessBuilder pb;
- OutputAnalyzer out;
- try {
- pb = ProcessTools.createLimitedTestJavaProcessBuilder("-XX:-BackgroundCompilation",
- "-XX:+TraceNewVectors",
- "compiler.vectorization.TestBufferVectorization",
- testName,
- "run");
- out = new OutputAnalyzer(pb.start());
- } catch (Exception e) {
- throw new RuntimeException(" Exception launching Java process: " + e);
- }
+ @Run(test = "testArrayView")
+ public static void runArrayView() {
+ byte[] b_arr = new byte[N * Integer.BYTES];
- out.shouldHaveExitValue(0);
+ for (int k = 0; k < N; k++) {
+ VH_arr_view.set(b_arr, k, k);
+ }
- if (testName.equals("bufferDirect")) {
- return; // bufferDirect uses Unsafe memory accesses which are not vectorized currently
+ // Save initial INT values
+ int[] i_arr = new int[N];
+ for (int k = 0; k < i_arr.length; k++) {
+ i_arr[k] = (int) VH_arr_view.get(b_arr, k * Integer.BYTES);
}
+ testArrayView(b_arr);
- if (testName.equals("bufferHeap") && (Platform.is32bit())) {
- return; // bufferHeap uses Long type for memory accesses which are not vectorized in 32-bit VM
+ for (int k = 0; k < i_arr.length; k++) {
+ int v = (int) VH_arr_view.get(b_arr, k * Integer.BYTES);
+ if (v != (i_arr[k] + 1)) {
+ throw new RuntimeException(" Invalid result: VH_arr_view.get(b_arr, " + (k * Integer.BYTES) + "): " + v + " != " + (i_arr[k] + 1));
+ }
}
+ }
- out.shouldContain("Replicate");
- out.shouldContain("LoadVector");
- out.shouldContain("AddVI");
- out.shouldContain("StoreVector");
+ @Test
+ @IR(counts = {IRNode.REPLICATE_I, ">0",
+ IRNode.LOAD_VECTOR_I, ">0",
+ IRNode.ADD_VI, ">0",
+ IRNode.STORE_VECTOR, ">0"},
+ applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
+ public static void testArrayView(byte[] b_arr) {
+ for (int k = 0; k < b_arr.length; k += 4) {
+ int v = (int) VH_arr_view.get(b_arr, k);
+ VH_arr_view.set(b_arr, k, v + 1);
+ }
}
}
From c4a83bd6f6c45e72bd776e929005be0aa9408867 Mon Sep 17 00:00:00 2001
From: William Kemper
Date: Mon, 8 Jan 2024 16:44:28 +0000
Subject: [PATCH 015/153] 8323086: Shenandoah: Heap could be corrupted by oom
during evacuation
Reviewed-by: kdnilsen, shade
---
.../gc/shenandoah/shenandoahDegeneratedGC.cpp | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp
index d8398bb1ed8b3..e7cf402a52785 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp
@@ -131,6 +131,27 @@ void ShenandoahDegenGC::op_degenerated() {
// and we can do evacuation. Otherwise, it would be the shortcut cycle.
if (heap->is_evacuation_in_progress()) {
+ if (_degen_point == _degenerated_evac) {
+ // Degeneration under oom-evac protocol allows the mutator LRB to expose
+ // references to from-space objects. This is okay, in theory, because we
+ // will come to the safepoint here to complete the evacuations and update
+ // the references. However, if the from-space reference is written to a
+ // region that was EC during final mark or was recycled after final mark
+ // it will not have TAMS or UWM updated. Such a region is effectively
+ // skipped during update references which can lead to crashes and corruption
+ // if the from-space reference is accessed.
+ if (UseTLAB) {
+ heap->labs_make_parsable();
+ }
+
+ for (size_t i = 0; i < heap->num_regions(); i++) {
+ ShenandoahHeapRegion* r = heap->get_region(i);
+ if (r->is_active() && r->top() > r->get_update_watermark()) {
+ r->set_update_watermark_at_safepoint(r->top());
+ }
+ }
+ }
+
// Degeneration under oom-evac protocol might have left some objects in
// collection set un-evacuated. Restart evacuation from the beginning to
// capture all objects. For all the objects that are already evacuated,
From 387828a3f7e4ec5b26954747e756aac212d579ae Mon Sep 17 00:00:00 2001
From: Chris Plummer
Date: Mon, 8 Jan 2024 16:56:44 +0000
Subject: [PATCH 016/153] 8322980: Debug agent's dumpThread() API should update
thread's name before printing it
Reviewed-by: kevinw, sspitsyn
---
.../share/native/libjdwp/threadControl.c | 47 ++++++++++++++++++-
1 file changed, 45 insertions(+), 2 deletions(-)
diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/threadControl.c b/src/jdk.jdwp.agent/share/native/libjdwp/threadControl.c
index 581de4305713e..5628f8b44db43 100644
--- a/src/jdk.jdwp.agent/share/native/libjdwp/threadControl.c
+++ b/src/jdk.jdwp.agent/share/native/libjdwp/threadControl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2024, 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
@@ -2623,15 +2623,58 @@ dumpThreadList(ThreadList *list)
}
}
+#ifdef DEBUG_THREADNAME
+static void
+setThreadName(ThreadNode *node)
+{
+ /*
+ * Sometimes the debuggee changes the thread name, so we need to fetch
+ * and set it again.
+ */
+ jvmtiThreadInfo info;
+ jvmtiError error;
+
+ memset(&info, 0, sizeof(info));
+ error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadInfo)
+ (gdata->jvmti, node->thread, &info);
+ if (info.name != NULL) {
+ strncpy(node->name, info.name, sizeof(node->name) - 1);
+ jvmtiDeallocate(info.name);
+ }
+}
+#endif
+
+#if 0
+static jint
+getThreadState(ThreadNode *node)
+{
+ jint state = 0;
+ jvmtiError error = FUNC_PTR(gdata->jvmti,GetThreadState)
+ (gdata->jvmti, node->thread, &state);
+ return state;
+}
+#endif
+
static void
dumpThread(ThreadNode *node) {
- tty_message(" Thread: node = %p, jthread = %p", node, node->thread);
+ tty_message("Thread: node = %p, jthread = %p", node, node->thread);
#ifdef DEBUG_THREADNAME
+ setThreadName(node);
tty_message("\tname: %s", node->name);
#endif
// More fields can be printed here when needed. The amount of output is intentionally
// kept small so it doesn't generate too much output.
tty_message("\tsuspendCount: %d", node->suspendCount);
+#if 0
+ tty_message("\tsuspendAllCount: %d", suspendAllCount);
+ tty_message("\tthreadState: 0x%x", getThreadState(node));
+ tty_message("\ttoBeResumed: %d", node->toBeResumed);
+ tty_message("\tis_vthread: %d", node->is_vthread);
+ tty_message("\tcurrentInvoke.pending: %d", node->currentInvoke.pending);
+ tty_message("\tcurrentInvoke.started: %d", node->currentInvoke.started);
+ tty_message("\tcurrentInvoke.available: %d", node->currentInvoke.available);
+ tty_message("\tobjID: %d", commonRef_refToID(getEnv(), node->thread));
+#endif
}
#endif /* DEBUG */
From d47393bd8225e818f0f9cd45192a5e656018af11 Mon Sep 17 00:00:00 2001
From: Xin Liu
Date: Mon, 8 Jan 2024 18:53:41 +0000
Subject: [PATCH 017/153] 8320128: Clean up Parse constructor for OSR
Reviewed-by: thartmann, shade
---
src/hotspot/share/opto/parse.hpp | 7 +++--
src/hotspot/share/opto/parse1.cpp | 47 +++++++++++++++----------------
2 files changed, 28 insertions(+), 26 deletions(-)
diff --git a/src/hotspot/share/opto/parse.hpp b/src/hotspot/share/opto/parse.hpp
index 72929729812d1..40314ecc29d67 100644
--- a/src/hotspot/share/opto/parse.hpp
+++ b/src/hotspot/share/opto/parse.hpp
@@ -416,8 +416,11 @@ class Parse : public GraphKit {
void set_block(Block* b) { _block = b; }
// Derived accessors:
- bool is_normal_parse() const { return _entry_bci == InvocationEntryBci; }
- bool is_osr_parse() const { return _entry_bci != InvocationEntryBci; }
+ bool is_osr_parse() const {
+ assert(_entry_bci != UnknownBci, "uninitialized _entry_bci");
+ return _entry_bci != InvocationEntryBci;
+ }
+ bool is_normal_parse() const { return !is_osr_parse(); }
int osr_bci() const { assert(is_osr_parse(),""); return _entry_bci; }
void set_parse_bci(int bci);
diff --git a/src/hotspot/share/opto/parse1.cpp b/src/hotspot/share/opto/parse1.cpp
index 96db18f774fe7..c1fe7acaa75a3 100644
--- a/src/hotspot/share/opto/parse1.cpp
+++ b/src/hotspot/share/opto/parse1.cpp
@@ -401,19 +401,17 @@ Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses)
_wrote_stable = false;
_wrote_fields = false;
_alloc_with_final = nullptr;
- _entry_bci = InvocationEntryBci;
- _tf = nullptr;
_block = nullptr;
_first_return = true;
_replaced_nodes_for_exceptions = false;
_new_idx = C->unique();
- debug_only(_block_count = -1);
- debug_only(_blocks = (Block*)-1);
+ DEBUG_ONLY(_entry_bci = UnknownBci);
+ DEBUG_ONLY(_block_count = -1);
+ DEBUG_ONLY(_blocks = (Block*)-1);
#ifndef PRODUCT
if (PrintCompilation || PrintOpto) {
// Make sure I have an inline tree, so I can print messages about it.
- JVMState* ilt_caller = is_osr_parse() ? caller->caller() : caller;
- InlineTree::find_subtree_from_root(C->ilt(), ilt_caller, parse_method);
+ InlineTree::find_subtree_from_root(C->ilt(), caller, parse_method);
}
_max_switch_depth = 0;
_est_switch_depth = 0;
@@ -427,19 +425,7 @@ Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses)
C->set_has_monitors(true);
}
- _tf = TypeFunc::make(method());
_iter.reset_to_method(method());
- _flow = method()->get_flow_analysis();
- if (_flow->failing()) {
- assert(false, "type flow failed during parsing");
- C->record_method_not_compilable(_flow->failure_reason());
- }
-
-#ifndef PRODUCT
- if (_flow->has_irreducible_entry()) {
- C->set_parsed_irreducible_loop(true);
- }
-#endif
C->set_has_loops(C->has_loops() || method()->has_loops());
if (_expected_uses <= 0) {
@@ -507,14 +493,25 @@ Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses)
// Do some special top-level things.
if (depth() == 1 && C->is_osr_compilation()) {
+ _tf = C->tf(); // the OSR entry type is different
_entry_bci = C->entry_bci();
_flow = method()->get_osr_flow_analysis(osr_bci());
- if (_flow->failing()) {
- assert(false, "type flow analysis failed for OSR compilation");
- C->record_method_not_compilable(_flow->failure_reason());
+ } else {
+ _tf = TypeFunc::make(method());
+ _entry_bci = InvocationEntryBci;
+ _flow = method()->get_flow_analysis();
+ }
+
+ if (_flow->failing()) {
+ assert(false, "type flow analysis failed during parsing");
+ C->record_method_not_compilable(_flow->failure_reason());
#ifndef PRODUCT
if (PrintOpto && (Verbose || WizardMode)) {
- tty->print_cr("OSR @%d type flow bailout: %s", _entry_bci, _flow->failure_reason());
+ if (is_osr_parse()) {
+ tty->print_cr("OSR @%d type flow bailout: %s", _entry_bci, _flow->failure_reason());
+ } else {
+ tty->print_cr("type flow bailout: %s", _flow->failure_reason());
+ }
if (Verbose) {
method()->print();
method()->print_codes();
@@ -522,8 +519,6 @@ Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses)
}
}
#endif
- }
- _tf = C->tf(); // the OSR entry type is different
}
#ifdef ASSERT
@@ -535,6 +530,10 @@ Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses)
#endif
#ifndef PRODUCT
+ if (_flow->has_irreducible_entry()) {
+ C->set_parsed_irreducible_loop(true);
+ }
+
methods_parsed++;
// add method size here to guarantee that inlined methods are added too
if (CITime)
From 24823ba647d4bf412586372cd5076f35bbc131a5 Mon Sep 17 00:00:00 2001
From: Joshua Cao
Date: Mon, 8 Jan 2024 19:46:04 +0000
Subject: [PATCH 018/153] 8323095: Expand TraceOptoParse block output
abbreviations
Reviewed-by: thartmann, chagedorn, xliu
---
src/hotspot/share/opto/parse1.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/hotspot/share/opto/parse1.cpp b/src/hotspot/share/opto/parse1.cpp
index c1fe7acaa75a3..8ee99ae9a65e3 100644
--- a/src/hotspot/share/opto/parse1.cpp
+++ b/src/hotspot/share/opto/parse1.cpp
@@ -1511,13 +1511,13 @@ void Parse::do_one_block() {
int ns = b->num_successors();
int nt = b->all_successors();
- tty->print("Parsing block #%d at bci [%d,%d), successors: ",
+ tty->print("Parsing block #%d at bci [%d,%d), successors:",
block()->rpo(), block()->start(), block()->limit());
for (int i = 0; i < nt; i++) {
- tty->print((( i < ns) ? " %d" : " %d(e)"), b->successor_at(i)->rpo());
+ tty->print((( i < ns) ? " %d" : " %d(exception block)"), b->successor_at(i)->rpo());
}
if (b->is_loop_head()) {
- tty->print(" lphd");
+ tty->print(" loop head");
}
if (b->is_irreducible_loop_entry()) {
tty->print(" irreducible");
From d78e8dab93868c1212c95e165f556ad89a0b6920 Mon Sep 17 00:00:00 2001
From: Rajat Mahajan
Date: Mon, 8 Jan 2024 19:58:32 +0000
Subject: [PATCH 019/153] 8322545: Declare newInsets as static in
ThemeReader.cpp
Reviewed-by: serb, aivanov
---
.../windows/native/libawt/windows/ThemeReader.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp b/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp
index 12c2677e32a37..fad778dac4e0f 100644
--- a/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp
+++ b/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2024, 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
@@ -492,7 +492,7 @@ static void rescale(SIZE *size) {
}
}
-jobject newInsets(JNIEnv *env, jint top, jint left, jint bottom, jint right) {
+static jobject newInsets(JNIEnv *env, jint top, jint left, jint bottom, jint right) {
if (env->EnsureLocalCapacity(2) < 0) {
return NULL;
}
From 8a4dc79e1a40e7115e2971af81623b6b0368f41c Mon Sep 17 00:00:00 2001
From: Mikael Vidstedt
Date: Mon, 8 Jan 2024 20:17:29 +0000
Subject: [PATCH 020/153] 8274300: Address dsymutil warning by excluding
platform specific files
Reviewed-by: erikj
---
make/test/BuildTestLibNative.gmk | 6 +++++-
make/test/JtregNativeHotspot.gmk | 7 ++++++-
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/make/test/BuildTestLibNative.gmk b/make/test/BuildTestLibNative.gmk
index 00c7607913b1e..455936d163f3a 100644
--- a/make/test/BuildTestLibNative.gmk
+++ b/make/test/BuildTestLibNative.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2020, 2024, 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
@@ -45,6 +45,10 @@ BUILD_LIBTEST_OUTPUT_DIR := $(OUTPUTDIR)/support/test/lib/native
BUILD_LIBTEST_IMAGE_DIR := $(TEST_IMAGE_DIR)/lib
+ifeq ($(call isTargetOs, windows), false)
+ BUILD_LIBTEST_LIBRARIES_EXCLUDE += libFileUtils.c
+endif
+
# This evaluation is expensive and should only be done if this target was
# explicitly called.
ifneq ($(filter build-test-lib-native, $(MAKECMDGOALS)), )
diff --git a/make/test/JtregNativeHotspot.gmk b/make/test/JtregNativeHotspot.gmk
index 98101ee1e86bf..d8edb8743d7b5 100644
--- a/make/test/JtregNativeHotspot.gmk
+++ b/make/test/JtregNativeHotspot.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2024, 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
@@ -857,6 +857,11 @@ else
exeinvoke.c exestack-gap.c exestack-tls.c libAsyncGetCallTraceTest.cpp
endif
+ifeq ($(call And, $(call isTargetOs, linux) $(call isTargetCpu, aarch64)), false)
+ BUILD_HOTSPOT_JTREG_EXCLUDE += libTestSVEWithJNI.c
+endif
+
+
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exesigtest := -ljvm
ifeq ($(call isTargetOs, windows), true)
From ca9635df3357bf70b41645f619237b6d2068afb7 Mon Sep 17 00:00:00 2001
From: Kim Barrett
Date: Mon, 8 Jan 2024 21:26:18 +0000
Subject: [PATCH 021/153] 8322759: Eliminate -Wparentheses warnings in compiler
code
Reviewed-by: kvn, shade
---
src/hotspot/share/c1/c1_GraphBuilder.cpp | 10 +++++-----
src/hotspot/share/c1/c1_LinearScan.cpp | 6 +++---
src/hotspot/share/c1/c1_ValueStack.hpp | 4 ++--
src/hotspot/share/code/relocInfo.cpp | 6 +++---
.../share/compiler/compilerDefinitions.inline.hpp | 6 +++---
5 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/src/hotspot/share/c1/c1_GraphBuilder.cpp b/src/hotspot/share/c1/c1_GraphBuilder.cpp
index fe9a8a478365d..6e5fb99242c8c 100644
--- a/src/hotspot/share/c1/c1_GraphBuilder.cpp
+++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2024, 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
@@ -1315,8 +1315,8 @@ void GraphBuilder::if_node(Value x, If::Condition cond, Value y, ValueStack* sta
Instruction *i = append(new If(x, cond, false, y, tsux, fsux, (is_bb || compilation()->is_optimistic()) ? state_before : nullptr, is_bb));
assert(i->as_Goto() == nullptr ||
- (i->as_Goto()->sux_at(0) == tsux && i->as_Goto()->is_safepoint() == tsux->bci() < stream()->cur_bci()) ||
- (i->as_Goto()->sux_at(0) == fsux && i->as_Goto()->is_safepoint() == fsux->bci() < stream()->cur_bci()),
+ (i->as_Goto()->sux_at(0) == tsux && i->as_Goto()->is_safepoint() == (tsux->bci() < stream()->cur_bci())) ||
+ (i->as_Goto()->sux_at(0) == fsux && i->as_Goto()->is_safepoint() == (fsux->bci() < stream()->cur_bci())),
"safepoint state of Goto returned by canonicalizer incorrect");
if (is_profiling()) {
@@ -1451,7 +1451,7 @@ void GraphBuilder::table_switch() {
if (res->as_Goto()) {
for (i = 0; i < l; i++) {
if (sux->at(i) == res->as_Goto()->sux_at(0)) {
- assert(res->as_Goto()->is_safepoint() == sw.dest_offset_at(i) < 0, "safepoint state of Goto returned by canonicalizer incorrect");
+ assert(res->as_Goto()->is_safepoint() == (sw.dest_offset_at(i) < 0), "safepoint state of Goto returned by canonicalizer incorrect");
}
}
}
@@ -1500,7 +1500,7 @@ void GraphBuilder::lookup_switch() {
if (res->as_Goto()) {
for (i = 0; i < l; i++) {
if (sux->at(i) == res->as_Goto()->sux_at(0)) {
- assert(res->as_Goto()->is_safepoint() == sw.pair_at(i).offset() < 0, "safepoint state of Goto returned by canonicalizer incorrect");
+ assert(res->as_Goto()->is_safepoint() == (sw.pair_at(i).offset() < 0), "safepoint state of Goto returned by canonicalizer incorrect");
}
}
}
diff --git a/src/hotspot/share/c1/c1_LinearScan.cpp b/src/hotspot/share/c1/c1_LinearScan.cpp
index 7e46f9d56034b..9e9195a0d60d0 100644
--- a/src/hotspot/share/c1/c1_LinearScan.cpp
+++ b/src/hotspot/share/c1/c1_LinearScan.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2024, 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
@@ -4857,8 +4857,8 @@ void IntervalWalker::next_interval() {
// intervals may start at same position -> prefer fixed interval
kind = fixed != Interval::end() && fixed->from() <= any->from() ? fixedKind : anyKind;
- assert (kind == fixedKind && fixed->from() <= any->from() ||
- kind == anyKind && any->from() <= fixed->from(), "wrong interval!!!");
+ assert((kind == fixedKind && fixed->from() <= any->from()) ||
+ (kind == anyKind && any->from() <= fixed->from()), "wrong interval!!!");
assert(any == Interval::end() || fixed == Interval::end() || any->from() != fixed->from() || kind == fixedKind, "if fixed and any-Interval start at same position, fixed must be processed first");
} else if (fixed != Interval::end()) {
diff --git a/src/hotspot/share/c1/c1_ValueStack.hpp b/src/hotspot/share/c1/c1_ValueStack.hpp
index 74d5c2e3f3c65..0a75fa39bf607 100644
--- a/src/hotspot/share/c1/c1_ValueStack.hpp
+++ b/src/hotspot/share/c1/c1_ValueStack.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2024, 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
@@ -60,7 +60,7 @@ class ValueStack: public CompilationResourceObj {
Values* _locks; // the monitor stack (holding the locked values)
Value check(ValueTag tag, Value t) {
- assert(tag == t->type()->tag() || tag == objectTag && t->type()->tag() == addressTag, "types must correspond");
+ assert(tag == t->type()->tag() || (tag == objectTag && t->type()->tag() == addressTag), "types must correspond");
return t;
}
diff --git a/src/hotspot/share/code/relocInfo.cpp b/src/hotspot/share/code/relocInfo.cpp
index d2e70fbd6db02..bfb3db72d7265 100644
--- a/src/hotspot/share/code/relocInfo.cpp
+++ b/src/hotspot/share/code/relocInfo.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, 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
@@ -150,8 +150,8 @@ void RelocIterator::initialize(CompiledMethod* nm, address begin, address limit)
RelocIterator::RelocIterator(CodeSection* cs, address begin, address limit) {
initialize_misc();
- assert((cs->locs_start() != nullptr) && (cs->locs_end() != nullptr) ||
- (cs->locs_start() == nullptr) && (cs->locs_end() == nullptr), "valid start and end pointer");
+ assert(((cs->locs_start() != nullptr) && (cs->locs_end() != nullptr)) ||
+ ((cs->locs_start() == nullptr) && (cs->locs_end() == nullptr)), "valid start and end pointer");
_current = cs->locs_start()-1;
_end = cs->locs_end();
_addr = cs->start();
diff --git a/src/hotspot/share/compiler/compilerDefinitions.inline.hpp b/src/hotspot/share/compiler/compilerDefinitions.inline.hpp
index ed456a4215720..d490387672dad 100644
--- a/src/hotspot/share/compiler/compilerDefinitions.inline.hpp
+++ b/src/hotspot/share/compiler/compilerDefinitions.inline.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2024, 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
@@ -57,7 +57,7 @@ inline bool CompilerConfig::is_c1_only() {
}
inline bool CompilerConfig::is_c1_or_interpreter_only_no_jvmci() {
- assert(is_jvmci_compiler() && is_jvmci() || !is_jvmci_compiler(), "JVMCI compiler implies enabled JVMCI");
+ assert(!is_jvmci_compiler() || is_jvmci(), "JVMCI compiler implies enabled JVMCI");
return !is_jvmci() && (is_interpreter_only() || is_c1_only());
}
@@ -114,7 +114,7 @@ inline bool CompilerConfig::is_c2_or_jvmci_compiler_only() {
// Tiered is basically C1 & (C2 | JVMCI) minus all the odd cases with restrictions.
inline bool CompilerConfig::is_tiered() {
- assert(is_c1_simple_only() && is_c1_only() || !is_c1_simple_only(), "c1 simple mode must imply c1-only mode");
+ assert(!is_c1_simple_only() || is_c1_only(), "c1 simple mode must imply c1-only mode");
return has_tiered() && !is_interpreter_only() && !is_c1_only() && !is_c2_or_jvmci_compiler_only();
}
From 61ebe3b0c4afb6bfdadbf54d0e8a20347bea1975 Mon Sep 17 00:00:00 2001
From: Calvin Cheung
Date: Mon, 8 Jan 2024 22:41:07 +0000
Subject: [PATCH 022/153] 8323032: OptimizedModuleHandlingTest failed in
dynamic CDS archive mode
Reviewed-by: dholmes, matsaave
---
test/hotspot/jtreg/ProblemList.txt | 1 -
.../OptimizeModuleHandlingTest.java | 34 +++++++++++--------
2 files changed, 20 insertions(+), 15 deletions(-)
diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt
index f6913a0734ddc..d82f4a919fa81 100644
--- a/test/hotspot/jtreg/ProblemList.txt
+++ b/test/hotspot/jtreg/ProblemList.txt
@@ -113,7 +113,6 @@ runtime/StackGuardPages/TestStackGuardPagesNative.java 8303612 linux-all
runtime/ErrorHandling/TestDwarf.java#checkDecoder 8305489 linux-all
runtime/ErrorHandling/MachCodeFramesInErrorFile.java 8313315 linux-ppc64le
runtime/cds/appcds/customLoader/HelloCustom_JFR.java 8241075 linux-all,windows-x64
-runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java 8323032 generic-all
applications/jcstress/copy.java 8229852 linux-all
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java
index 53de474d9cd41..aeb5696830df4 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java
@@ -345,20 +345,26 @@ public static void runWithJarPath(String... extraRuntimeArgs) throws Exception {
.shouldNotContain(OPTIMIZE_ENABLED)
.shouldContain(MAP_FAILED);
});
- // Dump an archive with only -Xbootclasspath/a
- output = TestCommon.createArchive(
- null,
- appClasses,
- "-Xbootclasspath/a:" + mainJar.toString());
- TestCommon.checkDump(output);
- tty("13. run with CDS on, with the same -Xbootclasspath/a as dump time and adding a -cp with test.jar: should pass");
- TestCommon.run("-Xlog:cds,class+load",
- "-cp", testJar.toString(),
- "-Xbootclasspath/a:" + mainJar.toString(),
- MAIN_CLASS)
- .assertNormalExit(out -> {
- out.shouldMatch(MAIN_FROM_CDS)
- .shouldContain(OPTIMIZE_ENABLED);
+
+ // Skip the following test for dynamic CDS archive because the current
+ // dynamic dump test utililty does not support empty -cp with a classlist.
+ // (see createArchive(CDSOptions opts) in TestCommon.java)
+ if (!CDSTestUtils.isDynamicArchive()) {
+ // Dump an archive with only -Xbootclasspath/a
+ output = TestCommon.createArchive(
+ null,
+ appClasses,
+ "-Xbootclasspath/a:" + mainJar.toString());
+ TestCommon.checkDump(output);
+ tty("13. run with CDS on, with the same -Xbootclasspath/a as dump time and adding a -cp with test.jar: should pass");
+ TestCommon.run("-Xlog:cds,class+load",
+ "-cp", testJar.toString(),
+ "-Xbootclasspath/a:" + mainJar.toString(),
+ MAIN_CLASS)
+ .assertNormalExit(out -> {
+ out.shouldMatch(MAIN_FROM_CDS)
+ .shouldContain(OPTIMIZE_ENABLED);
});
+ }
}
}
From 841ab487f83d7e3639d352e796dc7131310c2390 Mon Sep 17 00:00:00 2001
From: Calvin Cheung
Date: Mon, 8 Jan 2024 23:53:06 +0000
Subject: [PATCH 023/153] 8322657: CDS filemap fastdebug assert while loading
Graal CE Polyglot in isolated classloader
Reviewed-by: matsaave, dholmes
---
src/hotspot/share/cds/filemap.cpp | 16 +--
src/hotspot/share/cds/filemap.hpp | 3 +-
.../jtreg/runtime/cds/appcds/JarBuilder.java | 19 +++-
.../ModularJarWithNonExistentJar.java | 105 ++++++++++++++++++
.../test-classes/DefineModuleApp.java | 51 +++++++++
.../manifest-with-non-existent-jar.txt | 3 +
6 files changed, 188 insertions(+), 9 deletions(-)
create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ModularJarWithNonExistentJar.java
create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/DefineModuleApp.java
create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/manifest-with-non-existent-jar.txt
diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp
index 3b50e01479718..c2bfec3dfeb18 100644
--- a/src/hotspot/share/cds/filemap.cpp
+++ b/src/hotspot/share/cds/filemap.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2024, 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
@@ -576,12 +576,14 @@ int FileMapInfo::get_module_shared_path_index(Symbol* location) {
const char* file = ClassLoader::skip_uri_protocol(location->as_C_string());
for (int i = ClassLoaderExt::app_module_paths_start_index(); i < get_number_of_shared_paths(); i++) {
SharedClassPathEntry* ent = shared_path(i);
- assert(ent->in_named_module(), "must be");
- bool cond = strcmp(file, ent->name()) == 0;
- log_debug(class, path)("get_module_shared_path_index (%d) %s : %s = %s", i,
- location->as_C_string(), ent->name(), cond ? "same" : "different");
- if (cond) {
- return i;
+ if (!ent->is_non_existent()) {
+ assert(ent->in_named_module(), "must be");
+ bool cond = strcmp(file, ent->name()) == 0;
+ log_debug(class, path)("get_module_shared_path_index (%d) %s : %s = %s", i,
+ location->as_C_string(), ent->name(), cond ? "same" : "different");
+ if (cond) {
+ return i;
+ }
}
}
diff --git a/src/hotspot/share/cds/filemap.hpp b/src/hotspot/share/cds/filemap.hpp
index 3d2062093c6b7..fd84563008ccf 100644
--- a/src/hotspot/share/cds/filemap.hpp
+++ b/src/hotspot/share/cds/filemap.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2024, 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
@@ -89,6 +89,7 @@ class SharedClassPathEntry : public MetaspaceObj {
bool is_dir() const { return _type == dir_entry; }
bool is_modules_image() const { return _type == modules_image_entry; }
bool is_jar() const { return _type == jar_entry; }
+ bool is_non_existent() const { return _type == non_existent_entry; }
bool from_class_path_attr() { return _from_class_path_attr; }
time_t timestamp() const { return _timestamp; }
const char* name() const;
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/JarBuilder.java b/test/hotspot/jtreg/runtime/cds/appcds/JarBuilder.java
index b9c2063f3e7e1..ef13a0a94141b 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/JarBuilder.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/JarBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2024, 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
@@ -199,6 +199,23 @@ public static void createModularJar(String jarPath,
createJar(argList);
}
+ public static void createModularJarWithManifest(String jarPath,
+ String classesDir,
+ String mainClass,
+ String manifest) throws Exception {
+ ArrayList argList = new ArrayList();
+ argList.add("--create");
+ argList.add("--file=" + jarPath);
+ if (mainClass != null) {
+ argList.add("--main-class=" + mainClass);
+ }
+ argList.add("--manifest=" + manifest);
+ argList.add("-C");
+ argList.add(classesDir);
+ argList.add(".");
+ createJar(argList);
+ }
+
private static void createJar(ArrayList args) {
if (DEBUG) printIterable("createJar args: ", args);
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ModularJarWithNonExistentJar.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ModularJarWithNonExistentJar.java
new file mode 100644
index 0000000000000..9e7579a34fd3e
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ModularJarWithNonExistentJar.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2024, 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 8322657
+ * @summary This test defines an application module using the DefineModuleApp.
+ * When performing dynamic dump, the modular jar containing the module
+ * is in the -cp. The jar listed in the "Class-Path" attribute of the modular
+ * jar doesn't exist. VM should not crash during dynamic dump under this scenario.
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds
+ * /test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes
+ * @build jdk.test.whitebox.WhiteBox DefineModuleApp
+ * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
+ * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar define_module_app.jar DefineModuleApp
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. ModularJarWithNonExistentJar
+ */
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import jdk.test.lib.cds.CDSTestUtils;
+import jdk.test.lib.helpers.ClassFileInstaller;
+
+public class ModularJarWithNonExistentJar extends DynamicArchiveTestBase {
+ private static final Path USER_DIR = Paths.get(CDSTestUtils.getOutputDir());
+
+ private static final String TEST_SRC = System.getProperty("test.src");
+
+ private static final Path SRC_DIR = Paths.get(TEST_SRC, "../jigsaw/modulepath/src");
+ private static final Path MODS_DIR = Paths.get("mods");
+ private static final Path MANIFEST_PATH = Paths.get(TEST_SRC, "test-classes/manifest-with-non-existent-jar.txt");
+
+ // the module name of the test module
+ private static final String TEST_MODULE = "com.simple";
+
+ // the module main class
+ private static final String MAIN_CLASS = "com.simple.Main";
+
+ private static Path moduleDir = null;
+ private static Path modularJar = null;
+
+ public static void buildTestModule() throws Exception {
+
+ // javac -d mods/$TESTMODULE --module-path MOD_DIR src/$TESTMODULE/**
+ JarBuilder.compileModule(SRC_DIR.resolve(TEST_MODULE),
+ MODS_DIR.resolve(TEST_MODULE),
+ MODS_DIR.toString());
+
+
+ moduleDir = Files.createTempDirectory(USER_DIR, "mlib");
+
+ modularJar = moduleDir.resolve(TEST_MODULE + ".jar");
+ String classes = MODS_DIR.resolve(TEST_MODULE).toString();
+ JarBuilder.createModularJarWithManifest(modularJar.toString(), classes,
+ MAIN_CLASS, MANIFEST_PATH.toString());
+ }
+
+ public static void main(String... args) throws Exception {
+ runTest(ModularJarWithNonExistentJar::testDefaultBase);
+ }
+
+ static void testDefaultBase() throws Exception {
+ String topArchiveName = getNewArchiveName("top");
+ doTest(topArchiveName);
+ }
+
+ private static void doTest(String topArchiveName) throws Exception {
+ // compile the module and create the modular jar file
+ buildTestModule();
+ String appJar = ClassFileInstaller.getJarPath("define_module_app.jar");
+ dump(topArchiveName,
+ "-Xlog:cds,class+path=info",
+ "-Xlog:cds+dynamic=debug",
+ "-cp", appJar + File.pathSeparator + modularJar.toString(),
+ "DefineModuleApp", moduleDir.toString(), TEST_MODULE)
+ .assertNormalExit(output -> {
+ output.shouldContain("Written dynamic archive 0x");
+ });
+ }
+}
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/DefineModuleApp.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/DefineModuleApp.java
new file mode 100644
index 0000000000000..fad62598cc73b
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/DefineModuleApp.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2024, 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.
+ *
+ */
+
+/**
+ * This app defines a module using the ModuleLayer.defineModulesWithOneLoader API
+ * which calls the JVM_DefineModule.
+ **/
+
+import java.nio.file.Path;
+import java.lang.ModuleLayer.Controller;
+import java.lang.module.*;
+import java.util.List;
+import java.util.Set;
+
+public class DefineModuleApp {
+ public static void main(String[] args) throws Throwable {
+ if (args.length != 2) {
+ throw new RuntimeException("DefineModuleApp expects 2 args but saw " + args.length);
+ }
+ final Path MODS = Path.of(args[0]);
+ final String MODULE_NAME = args[1];
+ Configuration cf = ModuleLayer.boot()
+ .configuration()
+ .resolve(ModuleFinder.of(), ModuleFinder.of(MODS), Set.of(MODULE_NAME));
+ ResolvedModule m = cf.findModule(MODULE_NAME).orElseThrow();
+ ModuleLayer bootLayer = ModuleLayer.boot();
+ ClassLoader scl = ClassLoader.getSystemClassLoader();
+ Controller controller = ModuleLayer.defineModulesWithOneLoader(cf, List.of(bootLayer), scl);
+ }
+}
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/manifest-with-non-existent-jar.txt b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/manifest-with-non-existent-jar.txt
new file mode 100644
index 0000000000000..7558b8b2c82a5
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/manifest-with-non-existent-jar.txt
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path: NonExistent.jar
+Created-By: 23-internal (Oracle Corporation)
From 8ae309ebacd6947bbad2ef168ca13702e1cba099 Mon Sep 17 00:00:00 2001
From: Weibing Xiao
Date: Tue, 9 Jan 2024 04:04:12 +0000
Subject: [PATCH 024/153] 8318971: Better Error Handling for Jar Tool When
Processing Non-existent Files
Reviewed-by: alanb, jpai
---
.../share/classes/sun/tools/jar/Main.java | 6 ++
test/jdk/tools/jar/InputFilesTest.java | 82 ++++++++++++++++++-
2 files changed, 86 insertions(+), 2 deletions(-)
diff --git a/src/jdk.jartool/share/classes/sun/tools/jar/Main.java b/src/jdk.jartool/share/classes/sun/tools/jar/Main.java
index fce80372b1e27..6163ef8264772 100644
--- a/src/jdk.jartool/share/classes/sun/tools/jar/Main.java
+++ b/src/jdk.jartool/share/classes/sun/tools/jar/Main.java
@@ -292,6 +292,9 @@ public synchronized boolean run(String args[]) {
}
}
expand();
+ if (!ok) {
+ return false;
+ }
if (!moduleInfos.isEmpty()) {
// All actual file entries (excl manifest and module-info.class)
Set jentries = new HashSet<>();
@@ -338,6 +341,9 @@ public synchronized boolean run(String args[]) {
tmpFile = createTemporaryFile("tmpjar", ".jar");
}
expand();
+ if (!ok) {
+ return false;
+ }
try (FileInputStream in = (fname != null) ? new FileInputStream(inputFile)
: new FileInputStream(FileDescriptor.in);
FileOutputStream out = new FileOutputStream(tmpFile);
diff --git a/test/jdk/tools/jar/InputFilesTest.java b/test/jdk/tools/jar/InputFilesTest.java
index 3dc08293a7677..6a0a7e2902188 100644
--- a/test/jdk/tools/jar/InputFilesTest.java
+++ b/test/jdk/tools/jar/InputFilesTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2023, 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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8165944
+ * @bug 8165944 8318971
* @summary test several jar tool input file scenarios with variations on -C
* options with/without a --release option. Some input files are
* duplicates that sometimes cause exceptions and other times do not,
@@ -153,6 +153,84 @@ public void test6() throws IOException {
jar("cf test.jar --release 9 -C test1 a -C test2 a");
}
+ /**
+ * Containing non-existent file in the file list
+ * The final jar should not be created and correct error message should be caught.
+ * IOException is triggered as expected.
+ */
+ @Test
+ public void testNonExistentFileInput() throws IOException {
+ touch("existingTestFile.txt");
+ onCompletion = () -> rm("existingTestFile.txt");
+ try {
+ jar("cf test.jar existingTestFile.txt nonExistentTestFile.txt");
+ Assert.fail("jar tool unexpectedly completed successfully");
+ } catch (IOException e) {
+ Assert.assertEquals(e.getMessage().trim(), "nonExistentTestFile.txt : no such file or directory");
+ Assert.assertTrue(Files.notExists(Path.of("test.jar")), "Jar file should not be created.");
+ }
+ }
+
+ /**
+ * With @File as a part of jar command line, where the File is containing one or more
+ * non-existent files or directories
+ * The final jar should not be created and correct error message should be caught.
+ * IOException is triggered as expected.
+ */
+ @Test
+ public void testNonExistentFileInputClassList() throws IOException {
+ touch("existingTestFile.txt");
+ touch("classes.list");
+ Files.writeString(Path.of("classes.list"), """
+ existingTestFile.txt
+ nonExistentTestFile.txt
+ nonExistentDirectory
+ """);
+ onCompletion = () -> rm("existingTestFile.txt classes.list");
+ try {
+ jar("cf test.jar @classes.list");
+ Assert.fail("jar tool unexpectedly completed successfully");
+ } catch (IOException e) {
+ String msg = e.getMessage().trim();
+ Assert.assertTrue(msg.contains("nonExistentTestFile.txt : no such file or directory"));
+ Assert.assertTrue(msg.trim().contains("nonExistentDirectory : no such file or directory"));
+ Assert.assertTrue(Files.notExists(Path.of("test.jar")), "Jar file should not be created.");
+ }
+
+ }
+
+ /**
+ * Create a jar file; then with @File as a part of jar command line, where the File is containing one or more
+ * non-existent files or directories
+ * The final jar should not be created and correct error message should be caught.
+ * IOException is triggered as expected.
+ */
+ @Test
+ public void testUpdateNonExistentFileInputClassList() throws IOException {
+ touch("existingTestFileUpdate.txt");
+ touch("existingTestFileUpdate2.txt");
+ touch("classesUpdate.list");
+ Files.writeString(Path.of("classesUpdate.list"), """
+ existingTestFileUpdate2.txt
+ nonExistentTestFileUpdate.txt
+ nonExistentDirectoryUpdate
+ """);
+ onCompletion = () -> rm("existingTestFileUpdate.txt existingTestFileUpdate2.txt " +
+ "classesUpdate.list testUpdate.jar");
+ try {
+ jar("cf testUpdate.jar existingTestFileUpdate.txt");
+ Assert.assertTrue(Files.exists(Path.of("testUpdate.jar")));
+ jar("uf testUpdate.jar @classesUpdate.list");
+ Assert.fail("jar tool unexpectedly completed successfully");
+ } catch (IOException e) {
+ String msg = e.getMessage().trim();
+ Assert.assertFalse(msg.contains("existingTestFileUpdate.txt : no such file or directory"));
+ Assert.assertTrue(msg.contains("nonExistentTestFileUpdate.txt : no such file or directory"));
+ Assert.assertTrue(msg.trim().contains("nonExistentDirectoryUpdate : no such file or directory"));
+ }
+
+ }
+
private Stream mkpath(String... args) {
return Arrays.stream(args).map(d -> Paths.get(".", d.split("/")));
}
From 176606d0cb9117ca9080261f898cd57339fa5a85 Mon Sep 17 00:00:00 2001
From: Athijegannathan Sundararajan
Date: Tue, 9 Jan 2024 04:36:30 +0000
Subject: [PATCH 025/153] 8310995: missing @since tags in 36 jdk.dynalink
classes
Reviewed-by: jlaskey, iris, attila
---
.../share/classes/jdk/dynalink/CallSiteDescriptor.java | 1 +
src/jdk.dynalink/share/classes/jdk/dynalink/DynamicLinker.java | 1 +
.../share/classes/jdk/dynalink/DynamicLinkerFactory.java | 1 +
src/jdk.dynalink/share/classes/jdk/dynalink/NamedOperation.java | 1 +
src/jdk.dynalink/share/classes/jdk/dynalink/Namespace.java | 1 +
.../share/classes/jdk/dynalink/NamespaceOperation.java | 1 +
.../classes/jdk/dynalink/NoSuchDynamicMethodException.java | 1 +
src/jdk.dynalink/share/classes/jdk/dynalink/Operation.java | 1 +
.../share/classes/jdk/dynalink/RelinkableCallSite.java | 1 +
.../share/classes/jdk/dynalink/SecureLookupSupplier.java | 1 +
.../share/classes/jdk/dynalink/StandardNamespace.java | 1 +
.../share/classes/jdk/dynalink/StandardOperation.java | 1 +
.../share/classes/jdk/dynalink/beans/BeansLinker.java | 1 +
.../classes/jdk/dynalink/beans/MissingMemberHandlerFactory.java | 1 +
.../share/classes/jdk/dynalink/beans/StaticClass.java | 1 +
.../share/classes/jdk/dynalink/linker/ConversionComparator.java | 2 ++
.../share/classes/jdk/dynalink/linker/GuardedInvocation.java | 1 +
.../jdk/dynalink/linker/GuardedInvocationTransformer.java | 1 +
.../classes/jdk/dynalink/linker/GuardingDynamicLinker.java | 1 +
.../jdk/dynalink/linker/GuardingDynamicLinkerExporter.java | 1 +
.../jdk/dynalink/linker/GuardingTypeConverterFactory.java | 1 +
.../share/classes/jdk/dynalink/linker/LinkRequest.java | 1 +
.../share/classes/jdk/dynalink/linker/LinkerServices.java | 1 +
.../classes/jdk/dynalink/linker/MethodHandleTransformer.java | 1 +
.../jdk/dynalink/linker/MethodTypeConversionStrategy.java | 1 +
.../jdk/dynalink/linker/TypeBasedGuardingDynamicLinker.java | 1 +
.../dynalink/linker/support/CompositeGuardingDynamicLinker.java | 1 +
.../linker/support/CompositeTypeBasedGuardingDynamicLinker.java | 1 +
.../dynalink/linker/support/DefaultInternalObjectFilter.java | 1 +
.../share/classes/jdk/dynalink/linker/support/Guards.java | 1 +
.../share/classes/jdk/dynalink/linker/support/Lookup.java | 1 +
.../classes/jdk/dynalink/linker/support/SimpleLinkRequest.java | 1 +
.../classes/jdk/dynalink/linker/support/TypeUtilities.java | 1 +
src/jdk.dynalink/share/classes/jdk/dynalink/package-info.java | 1 +
.../jdk/dynalink/support/AbstractRelinkableCallSite.java | 1 +
.../share/classes/jdk/dynalink/support/ChainedCallSite.java | 1 +
.../classes/jdk/dynalink/support/SimpleRelinkableCallSite.java | 1 +
37 files changed, 38 insertions(+)
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/CallSiteDescriptor.java b/src/jdk.dynalink/share/classes/jdk/dynalink/CallSiteDescriptor.java
index e1e49f22b4c45..e47625fb497d5 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/CallSiteDescriptor.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/CallSiteDescriptor.java
@@ -88,6 +88,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* the {@code MethodHandles.Lookup} object it carries. This lookup should be used
* to find method handles to set as targets of the call site described by this
* descriptor.
+ * @since 9
*/
public class CallSiteDescriptor extends SecureLookupSupplier {
private final Operation operation;
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/DynamicLinker.java b/src/jdk.dynalink/share/classes/jdk/dynalink/DynamicLinker.java
index eb7de0aba75a1..23f4f7a81227c 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/DynamicLinker.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/DynamicLinker.java
@@ -141,6 +141,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* in the above example the {@code parseOperation} method is left unimplemented.
*
*
+ * @since 9
*/
public final class DynamicLinker {
private static final String CLASS_NAME = DynamicLinker.class.getName();
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/DynamicLinkerFactory.java b/src/jdk.dynalink/share/classes/jdk/dynalink/DynamicLinkerFactory.java
index a34cff5ba12fe..ed2110085669f 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/DynamicLinkerFactory.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/DynamicLinkerFactory.java
@@ -105,6 +105,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* {@link #setClassLoader(ClassLoader) automatically discovered} ones, and
* finally the ones configured with {@link #setFallbackLinkers(List)}; this last
* category usually includes {@link BeansLinker}.
+ * @since 9
*/
public final class DynamicLinkerFactory {
@SuppressWarnings("removal")
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/NamedOperation.java b/src/jdk.dynalink/share/classes/jdk/dynalink/NamedOperation.java
index 7563e3946ad96..5fe3e96f43ec4 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/NamedOperation.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/NamedOperation.java
@@ -106,6 +106,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* usually containing the textual representation of the source expression that retrieved the
* callee, e.g. {@code StandardOperation.CALL.named("window.open")}.
*
+ * @since 9
*/
public final class NamedOperation implements Operation {
private final Operation baseOperation;
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/Namespace.java b/src/jdk.dynalink/share/classes/jdk/dynalink/Namespace.java
index 69b68d25ffc3a..8f5e7ede7f639 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/Namespace.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/Namespace.java
@@ -66,6 +66,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* set of standard namespaces with the {@link StandardNamespace} enum. Operations
* that need to specify a namespace they operate on can be expressed using
* {@link NamespaceOperation}.
+ * @since 9
*/
public interface Namespace {
}
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/NamespaceOperation.java b/src/jdk.dynalink/share/classes/jdk/dynalink/NamespaceOperation.java
index 322767de36463..0e047849c2c52 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/NamespaceOperation.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/NamespaceOperation.java
@@ -134,6 +134,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* StandardNamespace.PROPERTY)
* .named("empty");
*
+ * @since 9
*/
public final class NamespaceOperation implements Operation {
private final Operation baseOperation;
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/NoSuchDynamicMethodException.java b/src/jdk.dynalink/share/classes/jdk/dynalink/NoSuchDynamicMethodException.java
index bf20c23b7380d..8842c32c1befc 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/NoSuchDynamicMethodException.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/NoSuchDynamicMethodException.java
@@ -64,6 +64,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
/**
* Thrown at the invocation if the call site can not be linked by any available {@link GuardingDynamicLinker}.
+ * @since 9
*/
public class NoSuchDynamicMethodException extends RuntimeException {
private static final long serialVersionUID = 1L;
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/Operation.java b/src/jdk.dynalink/share/classes/jdk/dynalink/Operation.java
index ba22e32c54f3a..ef0acbc3b5741 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/Operation.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/Operation.java
@@ -74,6 +74,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* {@code GET:PROPERTY|ELEMENT}), and finally we will refer to named operations
* by separating the base operation and the name with the colon character (e.g.
* {@code GET:PROPERTY|ELEMENT:color}).
+ * @since 9
*/
public interface Operation {
/**
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/RelinkableCallSite.java b/src/jdk.dynalink/share/classes/jdk/dynalink/RelinkableCallSite.java
index 5f74edd700c48..e14cfdfebd3ed 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/RelinkableCallSite.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/RelinkableCallSite.java
@@ -76,6 +76,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* method handles. A relinkable call site will be managed by a
* {@link DynamicLinker} object after being associated with it using its
* {@link DynamicLinker#link(RelinkableCallSite)} method.
+ * @since 9
*/
public interface RelinkableCallSite {
/**
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/SecureLookupSupplier.java b/src/jdk.dynalink/share/classes/jdk/dynalink/SecureLookupSupplier.java
index 73ee39b9002c5..5ec1f2737fbdb 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/SecureLookupSupplier.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/SecureLookupSupplier.java
@@ -32,6 +32,7 @@
/**
* Provides security-checked access to a {@code MethodHandles.Lookup} object.
* See {@link #getLookup()} for details.
+ * @since 9
*/
public class SecureLookupSupplier {
/**
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/StandardNamespace.java b/src/jdk.dynalink/share/classes/jdk/dynalink/StandardNamespace.java
index 55b9acee7032e..b4c33250d38dd 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/StandardNamespace.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/StandardNamespace.java
@@ -62,6 +62,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
/**
* An enumeration of standard namespaces defined by Dynalink.
+ * @since 9
*/
public enum StandardNamespace implements Namespace {
/**
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/StandardOperation.java b/src/jdk.dynalink/share/classes/jdk/dynalink/StandardOperation.java
index e58bf4e78bf0a..176a87acd3621 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/StandardOperation.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/StandardOperation.java
@@ -67,6 +67,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* disappears from their type signature.
* {@link NamedOperation} can also be used to decorate {@link #CALL} and {@link #NEW} operations with a
* diagnostic name, and as such it does not affect their type signature.
+ * @since 9
*/
public enum StandardOperation implements Operation {
/**
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/BeansLinker.java b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/BeansLinker.java
index 386f386216ca8..ca09923292a77 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/BeansLinker.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/BeansLinker.java
@@ -135,6 +135,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* property and method names on classes and class instances, as well as access
* to per-class linkers using the {@link #getLinkerForClass(Class)}
* method.
+ * @since 9
*/
public class BeansLinker implements GuardingDynamicLinker {
private static final ClassValue linkers = new ClassValue<>() {
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/MissingMemberHandlerFactory.java b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/MissingMemberHandlerFactory.java
index 1fe50b916d9a1..c1e2f7eb71d15 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/MissingMemberHandlerFactory.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/MissingMemberHandlerFactory.java
@@ -67,6 +67,7 @@
* exception itself, as the linkage for the missing member is often conditional.
*
* @see BeansLinker#BeansLinker(MissingMemberHandlerFactory)
+ * @since 9
*/
@FunctionalInterface
public interface MissingMemberHandlerFactory {
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/StaticClass.java b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/StaticClass.java
index 62bb74cb29ea7..ebd6c7e55e2fb 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/StaticClass.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/StaticClass.java
@@ -102,6 +102,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* constructor. You might want to expose a mechanism in your language for
* selecting a constructor with an explicit signature through
* {@link BeansLinker#getConstructorMethod(Class, String)}.
+ * @since 9
*/
public final class StaticClass implements Serializable {
private static final ClassValue staticClasses = new ClassValue<>() {
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/ConversionComparator.java b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/ConversionComparator.java
index 6c0dd438bbb2a..267752b0a238d 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/ConversionComparator.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/ConversionComparator.java
@@ -70,10 +70,12 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* specific method with unrelated signatures. In these cases, language runtimes
* can be asked to resolve the ambiguity by expressing preferences for one
* conversion over the other.
+ * @since 9
*/
public interface ConversionComparator {
/**
* Enumeration of possible outcomes of comparing one conversion to another.
+ * @since 9
*/
enum Comparison {
/** The conversions cannot be compared. **/
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardedInvocation.java b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardedInvocation.java
index 1a1e23981c54a..174e63bff26ca 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardedInvocation.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardedInvocation.java
@@ -86,6 +86,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* throw an exception of the designated type. The guard, the switch points, and
* the exception type are all optional (a guarded invocation having none of them
* is unconditionally valid).
+ * @since 9
*/
public class GuardedInvocation {
private final MethodHandle invocation;
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardedInvocationTransformer.java b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardedInvocationTransformer.java
index 6c7750223620f..fa4f0cd454593 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardedInvocationTransformer.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardedInvocationTransformer.java
@@ -67,6 +67,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* another one. Typical usage is for implementing
* {@link DynamicLinkerFactory#setPrelinkTransformer(GuardedInvocationTransformer)
* pre-link transformers}.
+ * @since 9
*/
@FunctionalInterface
public interface GuardedInvocationTransformer {
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingDynamicLinker.java b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingDynamicLinker.java
index c604712ae43cf..e94cb7b912833 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingDynamicLinker.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingDynamicLinker.java
@@ -87,6 +87,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* Languages can export linkers to other language runtimes for
* {@link DynamicLinkerFactory#setClassLoader(ClassLoader) automatic discovery}
* using a {@link GuardingDynamicLinkerExporter}.
+ * @since 9
*/
public interface GuardingDynamicLinker {
/**
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingDynamicLinkerExporter.java b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingDynamicLinkerExporter.java
index 03be07cf45914..cd670a8fdbead 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingDynamicLinkerExporter.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingDynamicLinkerExporter.java
@@ -45,6 +45,7 @@
* security manager is present, to ensure that only trusted runtimes can
* automatically export their linkers into other runtimes.
* @see DynamicLinkerFactory#setClassLoader(ClassLoader)
+ * @since 9
*/
public abstract class GuardingDynamicLinkerExporter implements Supplier> {
/**
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingTypeConverterFactory.java b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingTypeConverterFactory.java
index 981a39059af5c..bbd327d5bbefd 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingTypeConverterFactory.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingTypeConverterFactory.java
@@ -75,6 +75,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* these conversions, will cause more ambiguity for {@link BeansLinker} in
* selecting the correct overload when trying to link to an overloaded Java
* method.
+ * @since 9
*/
public interface GuardingTypeConverterFactory {
/**
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/LinkRequest.java b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/LinkRequest.java
index 209c1920a3f8b..1feeed03d1560 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/LinkRequest.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/LinkRequest.java
@@ -69,6 +69,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* site. Instances of these requests will be constructed and passed to all
* {@link GuardingDynamicLinker} objects managed by the {@link DynamicLinker}
* that is trying to link the call site.
+ * @since 9
*/
public interface LinkRequest {
/**
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/LinkerServices.java b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/LinkerServices.java
index e66babebf33f5..5a028205676d1 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/LinkerServices.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/LinkerServices.java
@@ -73,6 +73,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
/**
* Interface for services provided to {@link GuardingDynamicLinker} instances by
* the {@link DynamicLinker} that owns them.
+ * @since 9
*/
public interface LinkerServices {
/**
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/MethodHandleTransformer.java b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/MethodHandleTransformer.java
index 2af6294c51740..e9ccd30ffed8d 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/MethodHandleTransformer.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/MethodHandleTransformer.java
@@ -68,6 +68,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* Typical usage is for implementing
* {@link DynamicLinkerFactory#setInternalObjectsFilter(MethodHandleTransformer)
* internal objects filters}.
+ * @since 9
*/
@FunctionalInterface
public interface MethodHandleTransformer {
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/MethodTypeConversionStrategy.java b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/MethodTypeConversionStrategy.java
index b830e375c12c2..394f81858ff35 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/MethodTypeConversionStrategy.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/MethodTypeConversionStrategy.java
@@ -70,6 +70,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* of
* {@link DynamicLinkerFactory#setAutoConversionStrategy(MethodTypeConversionStrategy)
* method invocation conversions}.
+ * @since 9
*/
@FunctionalInterface
public interface MethodTypeConversionStrategy {
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/TypeBasedGuardingDynamicLinker.java b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/TypeBasedGuardingDynamicLinker.java
index 53c1a66e86294..1565cfee552bd 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/TypeBasedGuardingDynamicLinker.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/TypeBasedGuardingDynamicLinker.java
@@ -68,6 +68,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* linkers will fall into this category, as they recognize their native objects as Java objects of classes implementing
* a specific language-native interface or superclass. The linker mechanism can optimize the dispatch for these linkers,
* see {@link CompositeTypeBasedGuardingDynamicLinker}.
+ * @since 9
*/
public interface TypeBasedGuardingDynamicLinker extends GuardingDynamicLinker {
/**
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/CompositeGuardingDynamicLinker.java b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/CompositeGuardingDynamicLinker.java
index 8ae1f4754cf4e..c226a9c0b178c 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/CompositeGuardingDynamicLinker.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/CompositeGuardingDynamicLinker.java
@@ -72,6 +72,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* A {@link GuardingDynamicLinker} that delegates sequentially to a list of
* other guarding dynamic linkers in its
* {@link #getGuardedInvocation(LinkRequest, LinkerServices)}.
+ * @since 9
*/
public class CompositeGuardingDynamicLinker implements GuardingDynamicLinker {
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/CompositeTypeBasedGuardingDynamicLinker.java b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/CompositeTypeBasedGuardingDynamicLinker.java
index 184cc8e0ab801..a0805ff57d651 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/CompositeTypeBasedGuardingDynamicLinker.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/CompositeTypeBasedGuardingDynamicLinker.java
@@ -77,6 +77,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* returning true are then bound to the class, and next time a receiver of same
* type is encountered, the linking is delegated to those linkers only, speeding
* up dispatch.
+ * @since 9
*/
public class CompositeTypeBasedGuardingDynamicLinker implements TypeBasedGuardingDynamicLinker {
// Using a separate static class instance so there's no strong reference from the class value back to the composite
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/DefaultInternalObjectFilter.java b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/DefaultInternalObjectFilter.java
index 9929eeb7e5009..7a43f7ebbc0d7 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/DefaultInternalObjectFilter.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/DefaultInternalObjectFilter.java
@@ -80,6 +80,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* the parameter filter as being a wrapping method for exposing internal runtime
* objects wrapped into an adapter with some public interface, and the return
* value filter as being its inverse unwrapping method.
+ * @since 9
*/
public class DefaultInternalObjectFilter implements MethodHandleTransformer {
private static final MethodHandle FILTER_VARARGS = new Lookup(MethodHandles.lookup()).findStatic(
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/Guards.java b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/Guards.java
index 9a456df5ebeab..7b0fd0e156b7c 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/Guards.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/Guards.java
@@ -72,6 +72,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* Utility methods for creating typical guards for
* {@link MethodHandles#guardWithTest(MethodHandle, MethodHandle, MethodHandle)}
* and for adjusting their method types.
+ * @since 9
*/
public final class Guards {
private static final Logger LOG = Logger
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/Lookup.java b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/Lookup.java
index ecf66e7d458a6..25792f0108b32 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/Lookup.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/Lookup.java
@@ -72,6 +72,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* checked exceptions. It is useful in those cases when you're looking up
* methods within your own codebase (therefore it is an error if they are not
* present).
+ * @since 9
*/
public final class Lookup {
private final MethodHandles.Lookup lookup;
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/SimpleLinkRequest.java b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/SimpleLinkRequest.java
index d8cfd8a9d9c2c..7a00b9fe3ea6d 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/SimpleLinkRequest.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/SimpleLinkRequest.java
@@ -66,6 +66,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
/**
* Default simple implementation of {@link LinkRequest}.
+ * @since 9
*/
public class SimpleLinkRequest implements LinkRequest {
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/TypeUtilities.java b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/TypeUtilities.java
index f5ee9e0909360..2a3d667d49a86 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/TypeUtilities.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/TypeUtilities.java
@@ -70,6 +70,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
/**
* Various static utility methods for working with Java types.
+ * @since 9
*/
public final class TypeUtilities {
private TypeUtilities() {
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/package-info.java b/src/jdk.dynalink/share/classes/jdk/dynalink/package-info.java
index 03c7b9603f6b4..1218885ae9afd 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/package-info.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/package-info.java
@@ -60,5 +60,6 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
/**
* Contains interfaces and classes that are used to link an {@code invokedynamic} call site.
+ * @since 9
*/
package jdk.dynalink;
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/support/AbstractRelinkableCallSite.java b/src/jdk.dynalink/share/classes/jdk/dynalink/support/AbstractRelinkableCallSite.java
index dbcf3ffd02153..84ecfa1db3887 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/support/AbstractRelinkableCallSite.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/support/AbstractRelinkableCallSite.java
@@ -75,6 +75,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* {@link #relink(GuardedInvocation, MethodHandle)} and
* {@link #resetAndRelink(GuardedInvocation, MethodHandle)}
* methods.
+ * @since 9
*/
public abstract class AbstractRelinkableCallSite extends MutableCallSite implements RelinkableCallSite {
private final CallSiteDescriptor descriptor;
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/support/ChainedCallSite.java b/src/jdk.dynalink/share/classes/jdk/dynalink/support/ChainedCallSite.java
index a026512242ab9..2f75b53fc3d93 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/support/ChainedCallSite.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/support/ChainedCallSite.java
@@ -84,6 +84,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* Race conditions in linking are resolved by throwing away the
* {@link GuardedInvocation} produced on the losing thread without incorporating
* it into the chain, so it can lead to repeated linking for the same arguments.
+ * @since 9
*/
public class ChainedCallSite extends AbstractRelinkableCallSite {
private static final MethodHandle PRUNE_CATCHES;
diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/support/SimpleRelinkableCallSite.java b/src/jdk.dynalink/share/classes/jdk/dynalink/support/SimpleRelinkableCallSite.java
index 06f50b4ff8079..022d6088d01f8 100644
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/support/SimpleRelinkableCallSite.java
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/support/SimpleRelinkableCallSite.java
@@ -71,6 +71,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* If the guard of that single invocation fails, or it has an invalidated
* switch point, or its invalidating exception triggered, then the call site
* will throw it away and ask its associated {@link DynamicLinker} to relink it.
+ * @since 9
*/
public class SimpleRelinkableCallSite extends AbstractRelinkableCallSite {
/**
From 07fce8eff207eedcbab29b52660f19333df7c574 Mon Sep 17 00:00:00 2001
From: Albert Mingkun Yang
Date: Tue, 9 Jan 2024 06:11:44 +0000
Subject: [PATCH 026/153] 8320864: Serial: Extract out Full GC related fields
from ContiguousSpace
Reviewed-by: kbarrett, sjohanss
---
src/hotspot/share/gc/serial/genMarkSweep.cpp | 452 ++++++++++++++----
src/hotspot/share/gc/serial/genMarkSweep.hpp | 9 +-
src/hotspot/share/gc/serial/generation.cpp | 31 --
src/hotspot/share/gc/serial/generation.hpp | 9 +-
.../share/gc/serial/tenuredGeneration.hpp | 4 +-
.../share/gc/shared/genCollectedHeap.cpp | 13 -
.../share/gc/shared/genCollectedHeap.hpp | 12 -
src/hotspot/share/gc/shared/space.cpp | 239 +--------
src/hotspot/share/gc/shared/space.hpp | 87 +---
src/hotspot/share/gc/shared/space.inline.hpp | 91 +---
src/hotspot/share/gc/shared/vmStructs_gc.hpp | 4 -
11 files changed, 363 insertions(+), 588 deletions(-)
diff --git a/src/hotspot/share/gc/serial/genMarkSweep.cpp b/src/hotspot/share/gc/serial/genMarkSweep.cpp
index fb55116ab816b..28ba4615f73a2 100644
--- a/src/hotspot/share/gc/serial/genMarkSweep.cpp
+++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp
@@ -36,6 +36,7 @@
#include "gc/serial/defNewGeneration.hpp"
#include "gc/serial/generation.hpp"
#include "gc/serial/genMarkSweep.hpp"
+#include "gc/serial/markSweep.inline.hpp"
#include "gc/serial/serialGcRefProcProxyTask.hpp"
#include "gc/serial/serialHeap.hpp"
#include "gc/shared/classUnloadingContext.hpp"
@@ -48,7 +49,7 @@
#include "gc/shared/preservedMarks.inline.hpp"
#include "gc/shared/referencePolicy.hpp"
#include "gc/shared/referenceProcessorPhaseTimes.hpp"
-#include "gc/shared/space.hpp"
+#include "gc/shared/space.inline.hpp"
#include "gc/shared/strongRootsScope.hpp"
#include "gc/shared/weakProcessor.hpp"
#include "memory/universe.hpp"
@@ -57,6 +58,7 @@
#include "prims/jvmtiExport.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/javaThread.hpp"
+#include "runtime/prefetch.inline.hpp"
#include "runtime/synchronizer.hpp"
#include "runtime/vmThread.hpp"
#include "utilities/copy.hpp"
@@ -66,98 +68,281 @@
#include "jvmci/jvmci.hpp"
#endif
-void GenMarkSweep::invoke_at_safepoint(bool clear_all_softrefs) {
- assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
+class DeadSpacer : StackObj {
+ size_t _allowed_deadspace_words;
+ bool _active;
+ ContiguousSpace* _space;
- SerialHeap* gch = SerialHeap::heap();
-#ifdef ASSERT
- if (gch->soft_ref_policy()->should_clear_all_soft_refs()) {
- assert(clear_all_softrefs, "Policy should have been checked earlier");
+public:
+ DeadSpacer(ContiguousSpace* space) : _allowed_deadspace_words(0), _space(space) {
+ size_t ratio = _space->allowed_dead_ratio();
+ _active = ratio > 0;
+
+ if (_active) {
+ // We allow some amount of garbage towards the bottom of the space, so
+ // we don't start compacting before there is a significant gain to be made.
+ // Occasionally, we want to ensure a full compaction, which is determined
+ // by the MarkSweepAlwaysCompactCount parameter.
+ if ((MarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0) {
+ _allowed_deadspace_words = (space->capacity() * ratio / 100) / HeapWordSize;
+ } else {
+ _active = false;
+ }
+ }
}
-#endif
- gch->trace_heap_before_gc(_gc_tracer);
-
- // Increment the invocation count
- _total_invocations++;
+ bool insert_deadspace(HeapWord* dead_start, HeapWord* dead_end) {
+ if (!_active) {
+ return false;
+ }
- // Capture used regions for each generation that will be
- // subject to collection, so that card table adjustments can
- // be made intelligently (see clear / invalidate further below).
- gch->save_used_regions();
+ size_t dead_length = pointer_delta(dead_end, dead_start);
+ if (_allowed_deadspace_words >= dead_length) {
+ _allowed_deadspace_words -= dead_length;
+ CollectedHeap::fill_with_object(dead_start, dead_length);
+ oop obj = cast_to_oop(dead_start);
+ // obj->set_mark(obj->mark().set_marked());
+
+ assert(dead_length == obj->size(), "bad filler object size");
+ log_develop_trace(gc, compaction)("Inserting object to dead space: " PTR_FORMAT ", " PTR_FORMAT ", " SIZE_FORMAT "b",
+ p2i(dead_start), p2i(dead_end), dead_length * HeapWordSize);
+
+ return true;
+ } else {
+ _active = false;
+ return false;
+ }
+ }
+};
- allocate_stacks();
+// Implement the "compaction" part of the mark-compact GC algorithm.
+class Compacter {
+ // There are four spaces in total, but only the first three can be used after
+ // compact. IOW, old and eden/from must be enough for all live objs
+ static constexpr uint max_num_spaces = 4;
+
+ struct CompactionSpace {
+ ContiguousSpace* _space;
+ // Will be the new top after compaction is complete.
+ HeapWord* _compaction_top;
+ // The first dead word in this contiguous space. It's an optimization to
+ // skip large chunk of live objects at the beginning.
+ HeapWord* _first_dead;
+
+ void init(ContiguousSpace* space) {
+ _space = space;
+ _compaction_top = space->bottom();
+ _first_dead = nullptr;
+ }
+ };
- mark_sweep_phase1(clear_all_softrefs);
+ CompactionSpace _spaces[max_num_spaces];
+ // The num of spaces to be compacted, i.e. containing live objs.
+ uint _num_spaces;
- mark_sweep_phase2();
+ uint _index;
- // Don't add any more derived pointers during phase3
-#if COMPILER2_OR_JVMCI
- assert(DerivedPointerTable::is_active(), "Sanity");
- DerivedPointerTable::set_active(false);
-#endif
+ HeapWord* get_compaction_top(uint index) const {
+ return _spaces[index]._compaction_top;
+ }
- mark_sweep_phase3();
+ HeapWord* get_first_dead(uint index) const {
+ return _spaces[index]._first_dead;
+ }
- mark_sweep_phase4();
+ ContiguousSpace* get_space(uint index) const {
+ return _spaces[index]._space;
+ }
- restore_marks();
+ void record_first_dead(uint index, HeapWord* first_dead) {
+ assert(_spaces[index]._first_dead == nullptr, "should write only once");
+ _spaces[index]._first_dead = first_dead;
+ }
- // Set saved marks for allocation profiler (and other things? -- dld)
- // (Should this be in general part?)
- gch->save_marks();
+ HeapWord* alloc(size_t words) {
+ while (true) {
+ if (words <= pointer_delta(_spaces[_index]._space->end(),
+ _spaces[_index]._compaction_top)) {
+ HeapWord* result = _spaces[_index]._compaction_top;
+ _spaces[_index]._compaction_top += words;
+ if (_index == 0) {
+ // old-gen requires BOT update
+ static_cast(_spaces[0]._space)->update_for_block(result, result + words);
+ }
+ return result;
+ }
+
+ // out-of-memory in this space
+ _index++;
+ assert(_index < max_num_spaces - 1, "the last space should not be used");
+ }
+ }
- deallocate_stacks();
+ static void prefetch_read_scan(void* p) {
+ if (PrefetchScanIntervalInBytes >= 0) {
+ Prefetch::read(p, PrefetchScanIntervalInBytes);
+ }
+ }
- MarkSweep::_string_dedup_requests->flush();
+ static void prefetch_write_scan(void* p) {
+ if (PrefetchScanIntervalInBytes >= 0) {
+ Prefetch::write(p, PrefetchScanIntervalInBytes);
+ }
+ }
- bool is_young_gen_empty = (gch->young_gen()->used() == 0);
- gch->rem_set()->maintain_old_to_young_invariant(gch->old_gen(), is_young_gen_empty);
+ static void prefetch_write_copy(void* p) {
+ if (PrefetchCopyIntervalInBytes >= 0) {
+ Prefetch::write(p, PrefetchCopyIntervalInBytes);
+ }
+ }
- gch->prune_scavengable_nmethods();
+ static void forward_obj(oop obj, HeapWord* new_addr) {
+ prefetch_write_scan(obj);
+ if (cast_from_oop(obj) != new_addr) {
+ obj->forward_to(cast_to_oop(new_addr));
+ } else {
+ assert(obj->is_gc_marked(), "inv");
+ // This obj will stay in-place. Fix the markword.
+ obj->init_mark();
+ }
+ }
- // Update heap occupancy information which is used as
- // input to soft ref clearing policy at the next gc.
- Universe::heap()->update_capacity_and_used_at_gc();
+ static HeapWord* find_next_live_addr(HeapWord* start, HeapWord* end) {
+ for (HeapWord* i_addr = start; i_addr < end; /* empty */) {
+ prefetch_read_scan(i_addr);
+ oop obj = cast_to_oop(i_addr);
+ if (obj->is_gc_marked()) {
+ return i_addr;
+ }
+ i_addr += obj->size();
+ }
+ return end;
+ };
- // Signal that we have completed a visit to all live objects.
- Universe::heap()->record_whole_heap_examined_timestamp();
+ static size_t relocate(HeapWord* addr) {
+ // Prefetch source and destination
+ prefetch_read_scan(addr);
- gch->trace_heap_after_gc(_gc_tracer);
-}
+ oop obj = cast_to_oop(addr);
+ oop new_obj = obj->forwardee();
+ HeapWord* new_addr = cast_from_oop(new_obj);
+ assert(addr != new_addr, "inv");
+ prefetch_write_copy(new_addr);
-void GenMarkSweep::allocate_stacks() {
- void* scratch = nullptr;
- size_t num_words;
- DefNewGeneration* young_gen = (DefNewGeneration*)SerialHeap::heap()->young_gen();
- young_gen->contribute_scratch(scratch, num_words);
+ size_t obj_size = obj->size();
+ Copy::aligned_conjoint_words(addr, new_addr, obj_size);
+ new_obj->init_mark();
- if (scratch != nullptr) {
- _preserved_count_max = num_words * HeapWordSize / sizeof(PreservedMark);
- } else {
- _preserved_count_max = 0;
+ return obj_size;
}
- _preserved_marks = (PreservedMark*)scratch;
- _preserved_count = 0;
-
- _preserved_overflow_stack_set.init(1);
-}
+public:
+ explicit Compacter(SerialHeap* heap) {
+ // In this order so that heap is compacted towards old-gen.
+ _spaces[0].init(heap->old_gen()->space());
+ _spaces[1].init(heap->young_gen()->eden());
+ _spaces[2].init(heap->young_gen()->from());
+
+ bool is_promotion_failed = (heap->young_gen()->from()->next_compaction_space() != nullptr);
+ if (is_promotion_failed) {
+ _spaces[3].init(heap->young_gen()->to());
+ _num_spaces = 4;
+ } else {
+ _num_spaces = 3;
+ }
+ _index = 0;
+ }
+ void phase2_calculate_new_addr() {
+ for (uint i = 0; i < _num_spaces; ++i) {
+ ContiguousSpace* space = get_space(i);
+ HeapWord* cur_addr = space->bottom();
+ HeapWord* top = space->top();
+
+ bool record_first_dead_done = false;
+
+ DeadSpacer dead_spacer(space);
+
+ while (cur_addr < top) {
+ oop obj = cast_to_oop(cur_addr);
+ size_t obj_size = obj->size();
+ if (obj->is_gc_marked()) {
+ HeapWord* new_addr = alloc(obj_size);
+ forward_obj(obj, new_addr);
+ cur_addr += obj_size;
+ } else {
+ // Skipping the current known-unmarked obj
+ HeapWord* next_live_addr = find_next_live_addr(cur_addr + obj_size, top);
+ if (dead_spacer.insert_deadspace(cur_addr, next_live_addr)) {
+ // Register space for the filler obj
+ alloc(pointer_delta(next_live_addr, cur_addr));
+ } else {
+ if (!record_first_dead_done) {
+ record_first_dead(i, cur_addr);
+ record_first_dead_done = true;
+ }
+ *(HeapWord**)cur_addr = next_live_addr;
+ }
+ cur_addr = next_live_addr;
+ }
+ }
+
+ if (!record_first_dead_done) {
+ record_first_dead(i, top);
+ }
+ }
+ }
-void GenMarkSweep::deallocate_stacks() {
- if (_preserved_count_max != 0) {
- DefNewGeneration* young_gen = (DefNewGeneration*)SerialHeap::heap()->young_gen();
- young_gen->reset_scratch();
+ void phase3_adjust_pointers() {
+ for (uint i = 0; i < _num_spaces; ++i) {
+ ContiguousSpace* space = get_space(i);
+ HeapWord* cur_addr = space->bottom();
+ HeapWord* const top = space->top();
+ HeapWord* const first_dead = get_first_dead(i);
+
+ while (cur_addr < top) {
+ prefetch_write_scan(cur_addr);
+ if (cur_addr < first_dead || cast_to_oop(cur_addr)->is_gc_marked()) {
+ size_t size = MarkSweep::adjust_pointers(cast_to_oop(cur_addr));
+ cur_addr += size;
+ } else {
+ assert(*(HeapWord**)cur_addr > cur_addr, "forward progress");
+ cur_addr = *(HeapWord**)cur_addr;
+ }
+ }
+ }
}
- _preserved_overflow_stack_set.reclaim();
- _marking_stack.clear();
- _objarray_stack.clear(true);
-}
+ void phase4_compact() {
+ for (uint i = 0; i < _num_spaces; ++i) {
+ ContiguousSpace* space = get_space(i);
+ HeapWord* cur_addr = space->bottom();
+ HeapWord* top = space->top();
+
+ // Check if the first obj inside this space is forwarded.
+ if (!cast_to_oop(cur_addr)->is_forwarded()) {
+ // Jump over consecutive (in-place) live-objs-chunk
+ cur_addr = get_first_dead(i);
+ }
+
+ while (cur_addr < top) {
+ if (!cast_to_oop(cur_addr)->is_forwarded()) {
+ cur_addr = *(HeapWord**) cur_addr;
+ continue;
+ }
+ cur_addr += relocate(cur_addr);
+ }
+
+ // Reset top and unused memory
+ space->set_top(get_compaction_top(i));
+ if (ZapUnusedHeapArea) {
+ space->mangle_unused_area();
+ }
+ }
+ }
+};
-void GenMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
+void GenMarkSweep::phase1_mark(bool clear_all_softrefs) {
// Recursively traverse all live objects and mark them
GCTraceTime(Info, gc, phases) tm("Phase 1: Mark live objects", _gc_timer);
@@ -241,54 +426,121 @@ void GenMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
}
}
+void GenMarkSweep::invoke_at_safepoint(bool clear_all_softrefs) {
+ assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
-void GenMarkSweep::mark_sweep_phase2() {
- // Now all live objects are marked, compute the new object addresses.
- GCTraceTime(Info, gc, phases) tm("Phase 2: Compute new object addresses", _gc_timer);
+ SerialHeap* gch = SerialHeap::heap();
+#ifdef ASSERT
+ if (gch->soft_ref_policy()->should_clear_all_soft_refs()) {
+ assert(clear_all_softrefs, "Policy should have been checked earlier");
+ }
+#endif
- SerialHeap::heap()->prepare_for_compaction();
-}
+ gch->trace_heap_before_gc(_gc_tracer);
-class GenAdjustPointersClosure: public SerialHeap::GenClosure {
-public:
- void do_generation(Generation* gen) {
- gen->adjust_pointers();
+ // Increment the invocation count
+ _total_invocations++;
+
+ // Capture used regions for each generation that will be
+ // subject to collection, so that card table adjustments can
+ // be made intelligently (see clear / invalidate further below).
+ gch->save_used_regions();
+
+ allocate_stacks();
+
+ phase1_mark(clear_all_softrefs);
+
+ Compacter compacter{gch};
+
+ {
+ // Now all live objects are marked, compute the new object addresses.
+ GCTraceTime(Info, gc, phases) tm("Phase 2: Compute new object addresses", _gc_timer);
+
+ compacter.phase2_calculate_new_addr();
}
-};
-void GenMarkSweep::mark_sweep_phase3() {
- SerialHeap* gch = SerialHeap::heap();
+ // Don't add any more derived pointers during phase3
+#if COMPILER2_OR_JVMCI
+ assert(DerivedPointerTable::is_active(), "Sanity");
+ DerivedPointerTable::set_active(false);
+#endif
+
+ {
+ // Adjust the pointers to reflect the new locations
+ GCTraceTime(Info, gc, phases) tm("Phase 3: Adjust pointers", gc_timer());
+
+ ClassLoaderDataGraph::verify_claimed_marks_cleared(ClassLoaderData::_claim_stw_fullgc_adjust);
+
+ CodeBlobToOopClosure code_closure(&adjust_pointer_closure, CodeBlobToOopClosure::FixRelocations);
+ gch->process_roots(SerialHeap::SO_AllCodeCache,
+ &adjust_pointer_closure,
+ &adjust_cld_closure,
+ &adjust_cld_closure,
+ &code_closure);
- // Adjust the pointers to reflect the new locations
- GCTraceTime(Info, gc, phases) tm("Phase 3: Adjust pointers", gc_timer());
+ WeakProcessor::oops_do(&adjust_pointer_closure);
- ClassLoaderDataGraph::verify_claimed_marks_cleared(ClassLoaderData::_claim_stw_fullgc_adjust);
+ adjust_marks();
+ compacter.phase3_adjust_pointers();
+ }
- CodeBlobToOopClosure code_closure(&adjust_pointer_closure, CodeBlobToOopClosure::FixRelocations);
- gch->process_roots(SerialHeap::SO_AllCodeCache,
- &adjust_pointer_closure,
- &adjust_cld_closure,
- &adjust_cld_closure,
- &code_closure);
+ {
+ // All pointers are now adjusted, move objects accordingly
+ GCTraceTime(Info, gc, phases) tm("Phase 4: Move objects", _gc_timer);
- gch->gen_process_weak_roots(&adjust_pointer_closure);
+ compacter.phase4_compact();
+ }
- adjust_marks();
- GenAdjustPointersClosure blk;
- gch->generation_iterate(&blk, true);
+ restore_marks();
+
+ // Set saved marks for allocation profiler (and other things? -- dld)
+ // (Should this be in general part?)
+ gch->save_marks();
+
+ deallocate_stacks();
+
+ MarkSweep::_string_dedup_requests->flush();
+
+ bool is_young_gen_empty = (gch->young_gen()->used() == 0);
+ gch->rem_set()->maintain_old_to_young_invariant(gch->old_gen(), is_young_gen_empty);
+
+ gch->prune_scavengable_nmethods();
+
+ // Update heap occupancy information which is used as
+ // input to soft ref clearing policy at the next gc.
+ Universe::heap()->update_capacity_and_used_at_gc();
+
+ // Signal that we have completed a visit to all live objects.
+ Universe::heap()->record_whole_heap_examined_timestamp();
+
+ gch->trace_heap_after_gc(_gc_tracer);
}
-class GenCompactClosure: public SerialHeap::GenClosure {
-public:
- void do_generation(Generation* gen) {
- gen->compact();
+void GenMarkSweep::allocate_stacks() {
+ void* scratch = nullptr;
+ size_t num_words;
+ DefNewGeneration* young_gen = (DefNewGeneration*)SerialHeap::heap()->young_gen();
+ young_gen->contribute_scratch(scratch, num_words);
+
+ if (scratch != nullptr) {
+ _preserved_count_max = num_words * HeapWordSize / sizeof(PreservedMark);
+ } else {
+ _preserved_count_max = 0;
}
-};
-void GenMarkSweep::mark_sweep_phase4() {
- // All pointers are now adjusted, move objects accordingly
- GCTraceTime(Info, gc, phases) tm("Phase 4: Move objects", _gc_timer);
+ _preserved_marks = (PreservedMark*)scratch;
+ _preserved_count = 0;
+
+ _preserved_overflow_stack_set.init(1);
+}
- GenCompactClosure blk;
- SerialHeap::heap()->generation_iterate(&blk, true);
+void GenMarkSweep::deallocate_stacks() {
+ if (_preserved_count_max != 0) {
+ DefNewGeneration* young_gen = (DefNewGeneration*)SerialHeap::heap()->young_gen();
+ young_gen->reset_scratch();
+ }
+
+ _preserved_overflow_stack_set.reclaim();
+ _marking_stack.clear();
+ _objarray_stack.clear(true);
}
diff --git a/src/hotspot/share/gc/serial/genMarkSweep.hpp b/src/hotspot/share/gc/serial/genMarkSweep.hpp
index be830318bd0d9..520e801057389 100644
--- a/src/hotspot/share/gc/serial/genMarkSweep.hpp
+++ b/src/hotspot/share/gc/serial/genMarkSweep.hpp
@@ -32,15 +32,8 @@ class GenMarkSweep : public MarkSweep {
static void invoke_at_safepoint(bool clear_all_softrefs);
private:
-
// Mark live objects
- static void mark_sweep_phase1(bool clear_all_softrefs);
- // Calculate new addresses
- static void mark_sweep_phase2();
- // Update pointers
- static void mark_sweep_phase3();
- // Move objects to new positions
- static void mark_sweep_phase4();
+ static void phase1_mark(bool clear_all_softrefs);
// Temporary data structures for traversal and storing/restoring marks
static void allocate_stacks();
diff --git a/src/hotspot/share/gc/serial/generation.cpp b/src/hotspot/share/gc/serial/generation.cpp
index aa3c804ba3c20..30f1429fd40f2 100644
--- a/src/hotspot/share/gc/serial/generation.cpp
+++ b/src/hotspot/share/gc/serial/generation.cpp
@@ -218,34 +218,3 @@ void Generation::object_iterate(ObjectClosure* cl) {
GenerationObjIterateClosure blk(cl);
space_iterate(&blk);
}
-
-void Generation::prepare_for_compaction(CompactPoint* cp) {
- // Generic implementation, can be specialized
- ContiguousSpace* space = first_compaction_space();
- while (space != nullptr) {
- space->prepare_for_compaction(cp);
- space = space->next_compaction_space();
- }
-}
-
-class AdjustPointersClosure: public SpaceClosure {
- public:
- void do_space(Space* sp) {
- sp->adjust_pointers();
- }
-};
-
-void Generation::adjust_pointers() {
- // Note that this is done over all spaces, not just the compactible
- // ones.
- AdjustPointersClosure blk;
- space_iterate(&blk, true);
-}
-
-void Generation::compact() {
- ContiguousSpace* sp = first_compaction_space();
- while (sp != nullptr) {
- sp->compact();
- sp = sp->next_compaction_space();
- }
-}
diff --git a/src/hotspot/share/gc/serial/generation.hpp b/src/hotspot/share/gc/serial/generation.hpp
index 63eefae720bbb..d93c2b66df717 100644
--- a/src/hotspot/share/gc/serial/generation.hpp
+++ b/src/hotspot/share/gc/serial/generation.hpp
@@ -51,7 +51,7 @@
class DefNewGeneration;
class GCMemoryManager;
class ContiguousSpace;
-class CompactPoint;
+
class OopClosure;
class GCStats;
@@ -286,13 +286,6 @@ class Generation: public CHeapObj {
GCStats* gc_stats() const { return _gc_stats; }
virtual void update_gc_stats(Generation* current_generation, bool full) {}
- // Mark sweep support phase2
- virtual void prepare_for_compaction(CompactPoint* cp);
- // Mark sweep support phase3
- virtual void adjust_pointers();
- // Mark sweep support phase4
- virtual void compact();
-
// Accessing "marks".
// This function gives a generation a chance to note a point between
diff --git a/src/hotspot/share/gc/serial/tenuredGeneration.hpp b/src/hotspot/share/gc/serial/tenuredGeneration.hpp
index 75e8bf8486051..6b2a5891c64cd 100644
--- a/src/hotspot/share/gc/serial/tenuredGeneration.hpp
+++ b/src/hotspot/share/gc/serial/tenuredGeneration.hpp
@@ -70,8 +70,6 @@ class TenuredGeneration: public Generation {
GenerationCounters* _gen_counters;
CSpaceCounters* _space_counters;
- // Accessing spaces
- TenuredSpace* space() const { return _the_space; }
// Attempt to expand the generation by "bytes". Expand by at a
// minimum "expand_bytes". Return true if some amount (not
@@ -85,6 +83,8 @@ class TenuredGeneration: public Generation {
public:
virtual void compute_new_size();
+ TenuredSpace* space() const { return _the_space; }
+
// Grow generation with specified size (returns false if unable to grow)
bool grow_by(size_t bytes);
// Grow generation to reserved size.
diff --git a/src/hotspot/share/gc/shared/genCollectedHeap.cpp b/src/hotspot/share/gc/shared/genCollectedHeap.cpp
index f4c21cce6dcda..cf101caae38b3 100644
--- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp
@@ -713,10 +713,6 @@ void GenCollectedHeap::process_roots(ScanningOption so,
DEBUG_ONLY(ScavengableNMethods::asserted_non_scavengable_nmethods_do(&assert_code_is_non_scavengable));
}
-void GenCollectedHeap::gen_process_weak_roots(OopClosure* root_closure) {
- WeakProcessor::oops_do(root_closure);
-}
-
bool GenCollectedHeap::no_allocs_since_save_marks() {
return _young_gen->no_allocs_since_save_marks() &&
_old_gen->no_allocs_since_save_marks();
@@ -911,15 +907,6 @@ GenCollectedHeap* GenCollectedHeap::heap() {
return named_heap(CollectedHeap::Serial);
}
-#if INCLUDE_SERIALGC
-void GenCollectedHeap::prepare_for_compaction() {
- // Start by compacting into same gen.
- CompactPoint cp(_old_gen);
- _old_gen->prepare_for_compaction(&cp);
- _young_gen->prepare_for_compaction(&cp);
-}
-#endif // INCLUDE_SERIALGC
-
void GenCollectedHeap::verify(VerifyOption option /* ignored */) {
log_debug(gc, verify)("%s", _old_gen->name());
_old_gen->verify();
diff --git a/src/hotspot/share/gc/shared/genCollectedHeap.hpp b/src/hotspot/share/gc/shared/genCollectedHeap.hpp
index 72548f6e2f54a..1c1759f1422be 100644
--- a/src/hotspot/share/gc/shared/genCollectedHeap.hpp
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.hpp
@@ -292,11 +292,6 @@ class GenCollectedHeap : public CollectedHeap {
CLDClosure* weak_cld_closure,
CodeBlobToOopClosure* code_roots);
- // Apply "root_closure" to all the weak roots of the system.
- // These include JNI weak roots, string table,
- // and referents of reachable weak refs.
- void gen_process_weak_roots(OopClosure* root_closure);
-
// Set the saved marks of generations, if that makes sense.
// In particular, if any generation might iterate over the oops
// in other generations, it should call this method.
@@ -340,13 +335,6 @@ class GenCollectedHeap : public CollectedHeap {
HeapWord* mem_allocate_work(size_t size,
bool is_tlab);
-#if INCLUDE_SERIALGC
- // For use by mark-sweep. As implemented, mark-sweep-compact is global
- // in an essential way: compaction is performed across generations, by
- // iterating over spaces.
- void prepare_for_compaction();
-#endif
-
// Save the tops of the spaces in all generations
void record_gen_tops_before_GC() PRODUCT_RETURN;
diff --git a/src/hotspot/share/gc/shared/space.cpp b/src/hotspot/share/gc/shared/space.cpp
index 1c2afaa8b70ea..b6dc4e1e7d8f2 100644
--- a/src/hotspot/share/gc/shared/space.cpp
+++ b/src/hotspot/share/gc/shared/space.cpp
@@ -35,19 +35,13 @@
#include "oops/oop.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/java.hpp"
-#include "runtime/prefetch.inline.hpp"
#include "runtime/safepoint.hpp"
#include "utilities/align.hpp"
#include "utilities/copy.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
-#if INCLUDE_SERIALGC
-#include "gc/serial/serialBlockOffsetTable.inline.hpp"
-#include "gc/serial/defNewGeneration.hpp"
-#endif
ContiguousSpace::ContiguousSpace(): Space(),
- _compaction_top(nullptr),
_next_compaction_space(nullptr),
_top(nullptr) {
_mangler = new GenSpaceMangler(this);
@@ -59,8 +53,7 @@ ContiguousSpace::~ContiguousSpace() {
void ContiguousSpace::initialize(MemRegion mr,
bool clear_space,
- bool mangle_space)
-{
+ bool mangle_space) {
HeapWord* bottom = mr.start();
HeapWord* end = mr.end();
assert(Universe::on_page_boundary(bottom) && Universe::on_page_boundary(end),
@@ -70,7 +63,6 @@ void ContiguousSpace::initialize(MemRegion mr,
if (clear_space) {
clear(mangle_space);
}
- set_compaction_top(bottom);
_next_compaction_space = nullptr;
}
@@ -80,7 +72,6 @@ void ContiguousSpace::clear(bool mangle_space) {
if (ZapUnusedHeapArea && mangle_space) {
mangle_unused_area();
}
- _compaction_top = bottom();
}
bool ContiguousSpace::is_free_block(const HeapWord* p) const {
@@ -115,230 +106,6 @@ void ContiguousSpace::mangle_unused_area_complete() {
#endif // NOT_PRODUCT
-HeapWord* ContiguousSpace::forward(oop q, size_t size,
- CompactPoint* cp, HeapWord* compact_top) {
- // q is alive
- // First check if we should switch compaction space
- assert(this == cp->space, "'this' should be current compaction space.");
- size_t compaction_max_size = pointer_delta(end(), compact_top);
- while (size > compaction_max_size) {
- // switch to next compaction space
- cp->space->set_compaction_top(compact_top);
- cp->space = cp->space->next_compaction_space();
- if (cp->space == nullptr) {
- cp->gen = GenCollectedHeap::heap()->young_gen();
- assert(cp->gen != nullptr, "compaction must succeed");
- cp->space = cp->gen->first_compaction_space();
- assert(cp->space != nullptr, "generation must have a first compaction space");
- }
- compact_top = cp->space->bottom();
- cp->space->set_compaction_top(compact_top);
- compaction_max_size = pointer_delta(cp->space->end(), compact_top);
- }
-
- // store the forwarding pointer into the mark word
- if (cast_from_oop(q) != compact_top) {
- q->forward_to(cast_to_oop(compact_top));
- assert(q->is_gc_marked(), "encoding the pointer should preserve the mark");
- } else {
- // if the object isn't moving we can just set the mark to the default
- // mark and handle it specially later on.
- q->init_mark();
- assert(!q->is_forwarded(), "should not be forwarded");
- }
-
- compact_top += size;
-
- // We need to update the offset table so that the beginnings of objects can be
- // found during scavenge. Note that we are updating the offset table based on
- // where the object will be once the compaction phase finishes.
- cp->space->update_for_block(compact_top - size, compact_top);
- return compact_top;
-}
-
-#if INCLUDE_SERIALGC
-
-void ContiguousSpace::prepare_for_compaction(CompactPoint* cp) {
- // Compute the new addresses for the live objects and store it in the mark
- // Used by universe::mark_sweep_phase2()
-
- // We're sure to be here before any objects are compacted into this
- // space, so this is a good time to initialize this:
- set_compaction_top(bottom());
-
- if (cp->space == nullptr) {
- assert(cp->gen != nullptr, "need a generation");
- assert(cp->gen->first_compaction_space() == this, "just checking");
- cp->space = cp->gen->first_compaction_space();
- cp->space->set_compaction_top(cp->space->bottom());
- }
-
- HeapWord* compact_top = cp->space->compaction_top(); // This is where we are currently compacting to.
-
- DeadSpacer dead_spacer(this);
-
- HeapWord* end_of_live = bottom(); // One byte beyond the last byte of the last live object.
- HeapWord* first_dead = nullptr; // The first dead object.
-
- const intx interval = PrefetchScanIntervalInBytes;
-
- HeapWord* cur_obj = bottom();
- HeapWord* scan_limit = top();
-
- while (cur_obj < scan_limit) {
- if (cast_to_oop(cur_obj)->is_gc_marked()) {
- // prefetch beyond cur_obj
- Prefetch::write(cur_obj, interval);
- size_t size = cast_to_oop(cur_obj)->size();
- compact_top = cp->space->forward(cast_to_oop(cur_obj), size, cp, compact_top);
- cur_obj += size;
- end_of_live = cur_obj;
- } else {
- // run over all the contiguous dead objects
- HeapWord* end = cur_obj;
- do {
- // prefetch beyond end
- Prefetch::write(end, interval);
- end += cast_to_oop(end)->size();
- } while (end < scan_limit && !cast_to_oop(end)->is_gc_marked());
-
- // see if we might want to pretend this object is alive so that
- // we don't have to compact quite as often.
- if (cur_obj == compact_top && dead_spacer.insert_deadspace(cur_obj, end)) {
- oop obj = cast_to_oop(cur_obj);
- compact_top = cp->space->forward(obj, obj->size(), cp, compact_top);
- end_of_live = end;
- } else {
- // otherwise, it really is a free region.
-
- // cur_obj is a pointer to a dead object. Use this dead memory to store a pointer to the next live object.
- *(HeapWord**)cur_obj = end;
-
- // see if this is the first dead region.
- if (first_dead == nullptr) {
- first_dead = cur_obj;
- }
- }
-
- // move on to the next object
- cur_obj = end;
- }
- }
-
- assert(cur_obj == scan_limit, "just checking");
- _end_of_live = end_of_live;
- if (first_dead != nullptr) {
- _first_dead = first_dead;
- } else {
- _first_dead = end_of_live;
- }
-
- // save the compaction_top of the compaction space.
- cp->space->set_compaction_top(compact_top);
-}
-
-void ContiguousSpace::adjust_pointers() {
- // Check first is there is any work to do.
- if (used() == 0) {
- return; // Nothing to do.
- }
-
- // adjust all the interior pointers to point at the new locations of objects
- // Used by MarkSweep::mark_sweep_phase3()
-
- HeapWord* cur_obj = bottom();
- HeapWord* const end_of_live = _end_of_live; // Established by prepare_for_compaction().
- HeapWord* const first_dead = _first_dead; // Established by prepare_for_compaction().
-
- assert(first_dead <= end_of_live, "Stands to reason, no?");
-
- const intx interval = PrefetchScanIntervalInBytes;
-
- debug_only(HeapWord* prev_obj = nullptr);
- while (cur_obj < end_of_live) {
- Prefetch::write(cur_obj, interval);
- if (cur_obj < first_dead || cast_to_oop(cur_obj)->is_gc_marked()) {
- // cur_obj is alive
- // point all the oops to the new location
- size_t size = MarkSweep::adjust_pointers(cast_to_oop(cur_obj));
- debug_only(prev_obj = cur_obj);
- cur_obj += size;
- } else {
- debug_only(prev_obj = cur_obj);
- // cur_obj is not a live object, instead it points at the next live object
- cur_obj = *(HeapWord**)cur_obj;
- assert(cur_obj > prev_obj, "we should be moving forward through memory, cur_obj: " PTR_FORMAT ", prev_obj: " PTR_FORMAT, p2i(cur_obj), p2i(prev_obj));
- }
- }
-
- assert(cur_obj == end_of_live, "just checking");
-}
-
-void ContiguousSpace::compact() {
- // Copy all live objects to their new location
- // Used by MarkSweep::mark_sweep_phase4()
-
- verify_up_to_first_dead(this);
-
- HeapWord* const start = bottom();
- HeapWord* const end_of_live = _end_of_live;
-
- assert(_first_dead <= end_of_live, "Invariant. _first_dead: " PTR_FORMAT " <= end_of_live: " PTR_FORMAT, p2i(_first_dead), p2i(end_of_live));
- if (_first_dead == end_of_live && (start == end_of_live || !cast_to_oop(start)->is_gc_marked())) {
- // Nothing to compact. The space is either empty or all live object should be left in place.
- clear_empty_region(this);
- return;
- }
-
- const intx scan_interval = PrefetchScanIntervalInBytes;
- const intx copy_interval = PrefetchCopyIntervalInBytes;
-
- assert(start < end_of_live, "bottom: " PTR_FORMAT " should be < end_of_live: " PTR_FORMAT, p2i(start), p2i(end_of_live));
- HeapWord* cur_obj = start;
- if (_first_dead > cur_obj && !cast_to_oop(cur_obj)->is_gc_marked()) {
- // All object before _first_dead can be skipped. They should not be moved.
- // A pointer to the first live object is stored at the memory location for _first_dead.
- cur_obj = *(HeapWord**)(_first_dead);
- }
-
- debug_only(HeapWord* prev_obj = nullptr);
- while (cur_obj < end_of_live) {
- if (!cast_to_oop(cur_obj)->is_forwarded()) {
- debug_only(prev_obj = cur_obj);
- // The first word of the dead object contains a pointer to the next live object or end of space.
- cur_obj = *(HeapWord**)cur_obj;
- assert(cur_obj > prev_obj, "we should be moving forward through memory");
- } else {
- // prefetch beyond q
- Prefetch::read(cur_obj, scan_interval);
-
- // size and destination
- size_t size = cast_to_oop(cur_obj)->size();
- HeapWord* compaction_top = cast_from_oop(cast_to_oop(cur_obj)->forwardee());
-
- // prefetch beyond compaction_top
- Prefetch::write(compaction_top, copy_interval);
-
- // copy object and reinit its mark
- assert(cur_obj != compaction_top, "everything in this pass should be moving");
- Copy::aligned_conjoint_words(cur_obj, compaction_top, size);
- oop new_obj = cast_to_oop(compaction_top);
-
- ContinuationGCSupport::transform_stack_chunk(new_obj);
-
- new_obj->init_mark();
- assert(new_obj->klass() != nullptr, "should have a class");
-
- debug_only(prev_obj = cur_obj);
- cur_obj += size;
- }
- }
-
- clear_empty_region(this);
-}
-
-#endif // INCLUDE_SERIALGC
-
void Space::print_short() const { print_short_on(tty); }
void Space::print_short_on(outputStream* st) const {
@@ -481,10 +248,6 @@ HeapWord* ContiguousSpace::par_allocate(size_t size) {
}
#if INCLUDE_SERIALGC
-void TenuredSpace::update_for_block(HeapWord* start, HeapWord* end) {
- _offsets.update_for_block(start, end);
-}
-
HeapWord* TenuredSpace::block_start_const(const void* addr) const {
HeapWord* cur_block = _offsets.block_start_reaching_into_card(addr);
diff --git a/src/hotspot/share/gc/shared/space.hpp b/src/hotspot/share/gc/shared/space.hpp
index 5d559f74f5eef..6b8279ec8bd05 100644
--- a/src/hotspot/share/gc/shared/space.hpp
+++ b/src/hotspot/share/gc/shared/space.hpp
@@ -184,29 +184,12 @@ class Space: public CHeapObj {
// Allocation (return null if full). Enforces mutual exclusion internally.
virtual HeapWord* par_allocate(size_t word_size) = 0;
-#if INCLUDE_SERIALGC
- // Mark-sweep-compact support: all spaces can update pointers to objects
- // moving as a part of compaction.
- virtual void adjust_pointers() = 0;
-#endif
-
void print() const;
virtual void print_on(outputStream* st) const;
void print_short() const;
void print_short_on(outputStream* st) const;
};
-// A structure to represent a point at which objects are being copied
-// during compaction.
-class CompactPoint : public StackObj {
-public:
- Generation* gen;
- ContiguousSpace* space;
-
- CompactPoint(Generation* g = nullptr) :
- gen(g), space(nullptr) {}
-};
-
class GenSpaceMangler;
// A space in which the free area is contiguous. It therefore supports
@@ -215,26 +198,13 @@ class ContiguousSpace: public Space {
friend class VMStructs;
private:
- HeapWord* _compaction_top;
ContiguousSpace* _next_compaction_space;
- static inline void verify_up_to_first_dead(ContiguousSpace* space) NOT_DEBUG_RETURN;
-
- static inline void clear_empty_region(ContiguousSpace* space);
-
- protected:
+protected:
HeapWord* _top;
// A helper for mangling the unused area of the space in debug builds.
GenSpaceMangler* _mangler;
- // Used during compaction.
- HeapWord* _first_dead;
- HeapWord* _end_of_live;
-
- // This the function to invoke when an allocation of an object covering
- // "start" to "end" occurs to update other internal data structures.
- virtual void update_for_block(HeapWord* start, HeapWord* the_end) { }
-
GenSpaceMangler* mangler() { return _mangler; }
// Allocation helpers (return null if full).
@@ -254,23 +224,13 @@ class ContiguousSpace: public Space {
// The "clear" method must be called on a region that may have
// had allocation performed in it, but is now to be considered empty.
- virtual void clear(bool mangle_space);
-
- // Used temporarily during a compaction phase to hold the value
- // top should have when compaction is complete.
- HeapWord* compaction_top() const { return _compaction_top; }
-
- void set_compaction_top(HeapWord* value) {
- assert(value == nullptr || (value >= bottom() && value <= end()),
- "should point inside space");
- _compaction_top = value;
- }
+ void clear(bool mangle_space);
// Returns the next space (in the current generation) to be compacted in
// the global compaction order. Also is used to select the next
// space into which to compact.
- virtual ContiguousSpace* next_compaction_space() const {
+ ContiguousSpace* next_compaction_space() const {
return _next_compaction_space;
}
@@ -278,42 +238,10 @@ class ContiguousSpace: public Space {
_next_compaction_space = csp;
}
-#if INCLUDE_SERIALGC
- // MarkSweep support phase2
-
- // Start the process of compaction of the current space: compute
- // post-compaction addresses, and insert forwarding pointers. The fields
- // "cp->gen" and "cp->compaction_space" are the generation and space into
- // which we are currently compacting. This call updates "cp" as necessary,
- // and leaves the "compaction_top" of the final value of
- // "cp->compaction_space" up-to-date. Offset tables may be updated in
- // this phase as if the final copy had occurred; if so, "cp->threshold"
- // indicates when the next such action should be taken.
- void prepare_for_compaction(CompactPoint* cp);
- // MarkSweep support phase3
- void adjust_pointers() override;
- // MarkSweep support phase4
- virtual void compact();
-#endif // INCLUDE_SERIALGC
-
// The maximum percentage of objects that can be dead in the compacted
// live part of a compacted space ("deadwood" support.)
virtual size_t allowed_dead_ratio() const { return 0; };
- // "q" is an object of the given "size" that should be forwarded;
- // "cp" names the generation ("gen") and containing "this" (which must
- // also equal "cp->space"). "compact_top" is where in "this" the
- // next object should be forwarded to. If there is room in "this" for
- // the object, insert an appropriate forwarding pointer in "q".
- // If not, go to the next compaction space (there must
- // be one, since compaction must succeed -- we go to the first space of
- // the previous generation if necessary, updating "cp"), reset compact_top
- // and then forward. In either case, returns the new value of "compact_top".
- // Invokes the "update_for_block" function of the then-current compaction
- // space.
- virtual HeapWord* forward(oop q, size_t size, CompactPoint* cp,
- HeapWord* compact_top);
-
// Accessors
HeapWord* top() const { return _top; }
void set_top(HeapWord* value) { _top = value; }
@@ -359,12 +287,6 @@ class ContiguousSpace: public Space {
// Iteration
void object_iterate(ObjectClosure* blk) override;
- // Compaction support
- void reset_after_compaction() {
- assert(compaction_top() >= bottom() && compaction_top() <= end(), "should point inside space");
- set_top(compaction_top());
- }
-
// Apply "blk->do_oop" to the addresses of all reference fields in objects
// starting with the _saved_mark_word, which was noted during a generation's
// save_marks and is required to denote the head of an object.
@@ -419,8 +341,7 @@ class TenuredSpace: public ContiguousSpace {
inline HeapWord* allocate(size_t word_size) override;
inline HeapWord* par_allocate(size_t word_size) override;
- // MarkSweep support phase3
- void update_for_block(HeapWord* start, HeapWord* end) override;
+ inline void update_for_block(HeapWord* start, HeapWord* end);
void print_on(outputStream* st) const override;
};
diff --git a/src/hotspot/share/gc/shared/space.inline.hpp b/src/hotspot/share/gc/shared/space.inline.hpp
index 9c4c2864cedb6..bfaf84e8fac01 100644
--- a/src/hotspot/share/gc/shared/space.inline.hpp
+++ b/src/hotspot/share/gc/shared/space.inline.hpp
@@ -27,17 +27,12 @@
#include "gc/shared/space.hpp"
-#include "gc/serial/generation.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/spaceDecorator.hpp"
#include "oops/oop.inline.hpp"
#include "oops/oopsHierarchy.hpp"
#include "runtime/prefetch.inline.hpp"
#include "runtime/safepoint.hpp"
-#if INCLUDE_SERIALGC
-#include "gc/serial/serialBlockOffsetTable.inline.hpp"
-#include "gc/serial/markSweep.inline.hpp"
-#endif
inline HeapWord* Space::block_start(const void* p) {
return block_start_const(p);
@@ -60,90 +55,8 @@ inline HeapWord* TenuredSpace::par_allocate(size_t size) {
return res;
}
-class DeadSpacer : StackObj {
- size_t _allowed_deadspace_words;
- bool _active;
- ContiguousSpace* _space;
-
-public:
- DeadSpacer(ContiguousSpace* space) : _allowed_deadspace_words(0), _space(space) {
- size_t ratio = _space->allowed_dead_ratio();
- _active = ratio > 0;
-
- if (_active) {
- assert(!UseG1GC, "G1 should not be using dead space");
-
- // We allow some amount of garbage towards the bottom of the space, so
- // we don't start compacting before there is a significant gain to be made.
- // Occasionally, we want to ensure a full compaction, which is determined
- // by the MarkSweepAlwaysCompactCount parameter.
- if ((MarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0) {
- _allowed_deadspace_words = (space->capacity() * ratio / 100) / HeapWordSize;
- } else {
- _active = false;
- }
- }
- }
-
- bool insert_deadspace(HeapWord* dead_start, HeapWord* dead_end) {
- if (!_active) {
- return false;
- }
-
- size_t dead_length = pointer_delta(dead_end, dead_start);
- if (_allowed_deadspace_words >= dead_length) {
- _allowed_deadspace_words -= dead_length;
- CollectedHeap::fill_with_object(dead_start, dead_length);
- oop obj = cast_to_oop(dead_start);
- obj->set_mark(obj->mark().set_marked());
-
- assert(dead_length == obj->size(), "bad filler object size");
- log_develop_trace(gc, compaction)("Inserting object to dead space: " PTR_FORMAT ", " PTR_FORMAT ", " SIZE_FORMAT "b",
- p2i(dead_start), p2i(dead_end), dead_length * HeapWordSize);
-
- return true;
- } else {
- _active = false;
- return false;
- }
- }
-};
-
-#ifdef ASSERT
-inline void ContiguousSpace::verify_up_to_first_dead(ContiguousSpace* space) {
- HeapWord* cur_obj = space->bottom();
-
- if (cur_obj < space->_end_of_live && space->_first_dead > cur_obj && !cast_to_oop(cur_obj)->is_gc_marked()) {
- // we have a chunk of the space which hasn't moved and we've reinitialized
- // the mark word during the previous pass, so we can't use is_gc_marked for
- // the traversal.
- HeapWord* prev_obj = nullptr;
-
- while (cur_obj < space->_first_dead) {
- size_t size = cast_to_oop(cur_obj)->size();
- assert(!cast_to_oop(cur_obj)->is_gc_marked(), "should be unmarked (special dense prefix handling)");
- prev_obj = cur_obj;
- cur_obj += size;
- }
- }
-}
-#endif
-
-inline void ContiguousSpace::clear_empty_region(ContiguousSpace* space) {
- // Let's remember if we were empty before we did the compaction.
- bool was_empty = space->used_region().is_empty();
- // Reset space after compaction is complete
- space->reset_after_compaction();
- // We do this clear, below, since it has overloaded meanings for some
- // space subtypes. For example, TenuredSpace's that were
- // compacted into will have had their offset table thresholds updated
- // continuously, but those that weren't need to have their thresholds
- // re-initialized. Also mangles unused area for debugging.
- if (space->used_region().is_empty()) {
- if (!was_empty) space->clear(SpaceDecorator::Mangle);
- } else {
- if (ZapUnusedHeapArea) space->mangle_unused_area();
- }
+inline void TenuredSpace::update_for_block(HeapWord* start, HeapWord* end) {
+ _offsets.update_for_block(start, end);
}
#endif // INCLUDE_SERIALGC
diff --git a/src/hotspot/share/gc/shared/vmStructs_gc.hpp b/src/hotspot/share/gc/shared/vmStructs_gc.hpp
index 696cdc00dc520..a5d671a3b9295 100644
--- a/src/hotspot/share/gc/shared/vmStructs_gc.hpp
+++ b/src/hotspot/share/gc/shared/vmStructs_gc.hpp
@@ -99,10 +99,6 @@
nonstatic_field(CollectedHeap, _is_gc_active, bool) \
nonstatic_field(CollectedHeap, _total_collections, unsigned int) \
\
- nonstatic_field(ContiguousSpace, _compaction_top, HeapWord*) \
- nonstatic_field(ContiguousSpace, _first_dead, HeapWord*) \
- nonstatic_field(ContiguousSpace, _end_of_live, HeapWord*) \
- \
nonstatic_field(ContiguousSpace, _top, HeapWord*) \
nonstatic_field(ContiguousSpace, _saved_mark_word, HeapWord*) \
\
From 7286f5291d6aad290fda778668eeb3a7cbfd8a55 Mon Sep 17 00:00:00 2001
From: Alan Bateman
Date: Tue, 9 Jan 2024 07:05:27 +0000
Subject: [PATCH 027/153] 8322829: Refactor nioBlocker to avoid blocking while
holding Thread's interrupt lock
Reviewed-by: jpai
---
.../share/classes/java/lang/System.java | 4 +-
.../share/classes/java/lang/Thread.java | 29 ++++++---
.../classes/java/lang/VirtualThread.java | 27 ++++++--
.../spi/AbstractInterruptibleChannel.java | 63 ++++++++++++-------
.../nio/channels/spi/AbstractSelector.java | 28 +++++----
.../classes/sun/nio/ch/Interruptible.java | 21 ++++++-
6 files changed, 118 insertions(+), 54 deletions(-)
diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java
index 0c10079316722..227982af9eaf6 100644
--- a/src/java.base/share/classes/java/lang/System.java
+++ b/src/java.base/share/classes/java/lang/System.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2024, 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
@@ -2374,7 +2374,7 @@ E[] getEnumConstantsShared(Class klass) {
return klass.getEnumConstantsShared();
}
public void blockedOn(Interruptible b) {
- Thread.blockedOn(b);
+ Thread.currentThread().blockedOn(b);
}
public void registerShutdownHook(int slot, boolean registerShutdownInProgress, Runnable hook) {
Shutdown.add(slot, registerShutdownInProgress, hook);
diff --git a/src/java.base/share/classes/java/lang/Thread.java b/src/java.base/share/classes/java/lang/Thread.java
index 4236368d28743..c3a6a3de5bc0f 100644
--- a/src/java.base/share/classes/java/lang/Thread.java
+++ b/src/java.base/share/classes/java/lang/Thread.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2024, 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
@@ -345,15 +345,20 @@ void inheritScopedValueBindings(ThreadContainer container) {
* operation, if any. The blocker's interrupt method should be invoked
* after setting this thread's interrupt status.
*/
- volatile Interruptible nioBlocker;
+ private Interruptible nioBlocker;
+
+ Interruptible nioBlocker() {
+ //assert Thread.holdsLock(interruptLock);
+ return nioBlocker;
+ }
/* Set the blocker field; invoked via jdk.internal.access.SharedSecrets
* from java.nio code
*/
- static void blockedOn(Interruptible b) {
- Thread me = Thread.currentThread();
- synchronized (me.interruptLock) {
- me.nioBlocker = b;
+ void blockedOn(Interruptible b) {
+ //assert Thread.currentThread() == this;
+ synchronized (interruptLock) {
+ nioBlocker = b;
}
}
@@ -1699,15 +1704,19 @@ public void interrupt() {
checkAccess();
// thread may be blocked in an I/O operation
+ Interruptible blocker;
synchronized (interruptLock) {
- Interruptible b = nioBlocker;
- if (b != null) {
+ blocker = nioBlocker;
+ if (blocker != null) {
interrupted = true;
interrupt0(); // inform VM of interrupt
- b.interrupt(this);
- return;
+ blocker.interrupt(this);
}
}
+ if (blocker != null) {
+ blocker.postInterrupt();
+ return;
+ }
}
interrupted = true;
interrupt0(); // inform VM of interrupt
diff --git a/src/java.base/share/classes/java/lang/VirtualThread.java b/src/java.base/share/classes/java/lang/VirtualThread.java
index 6f82516d86452..72ae1070242e8 100644
--- a/src/java.base/share/classes/java/lang/VirtualThread.java
+++ b/src/java.base/share/classes/java/lang/VirtualThread.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2024, 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
@@ -852,18 +852,32 @@ boolean joinNanos(long nanos) throws InterruptedException {
return true;
}
+ @Override
+ void blockedOn(Interruptible b) {
+ notifyJvmtiDisableSuspend(true);
+ try {
+ super.blockedOn(b);
+ } finally {
+ notifyJvmtiDisableSuspend(false);
+ }
+ }
+
@Override
@SuppressWarnings("removal")
public void interrupt() {
if (Thread.currentThread() != this) {
checkAccess();
+
+ // if current thread is a virtual thread then prevent it from being
+ // suspended when entering or holding interruptLock
+ Interruptible blocker;
notifyJvmtiDisableSuspend(true);
try {
synchronized (interruptLock) {
interrupted = true;
- Interruptible b = nioBlocker;
- if (b != null) {
- b.interrupt(this);
+ blocker = nioBlocker();
+ if (blocker != null) {
+ blocker.interrupt(this);
}
// interrupt carrier thread if mounted
@@ -873,6 +887,11 @@ public void interrupt() {
} finally {
notifyJvmtiDisableSuspend(false);
}
+
+ // notify blocker after releasing interruptLock
+ if (blocker != null) {
+ blocker.postInterrupt();
+ }
} else {
interrupted = true;
carrierThread.setInterrupt();
diff --git a/src/java.base/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java b/src/java.base/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java
index 26dfc5ebca5e1..6adf2eb227634 100644
--- a/src/java.base/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java
+++ b/src/java.base/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2024, 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
@@ -32,9 +32,9 @@
import java.nio.channels.InterruptibleChannel;
import jdk.internal.access.SharedSecrets;
+import jdk.internal.misc.Unsafe;
import sun.nio.ch.Interruptible;
-
/**
* Base implementation class for interruptible channels.
*
@@ -89,10 +89,26 @@ public abstract class AbstractInterruptibleChannel
private final Object closeLock = new Object();
private volatile boolean closed;
+ // invoked if a Thread is interrupted when blocked in an I/O op
+ private final Interruptible interruptor;
+
/**
* Initializes a new instance of this class.
*/
- protected AbstractInterruptibleChannel() { }
+ protected AbstractInterruptibleChannel() {
+ this.interruptor = new Interruptible() {
+ @Override
+ public void interrupt(Thread target) {
+ AbstractInterruptibleChannel.this.trySetTarget(target);
+ }
+ @Override
+ public void postInterrupt() {
+ try {
+ AbstractInterruptibleChannel.this.close();
+ } catch (IOException x) { }
+ }
+ };
+ }
/**
* Closes this channel.
@@ -139,8 +155,15 @@ public final boolean isOpen() {
// -- Interruption machinery --
- private Interruptible interruptor;
- private volatile Thread interrupted;
+ private static final Unsafe U = Unsafe.getUnsafe();
+ private static final long INTERRUPTED_TARGET =
+ U.objectFieldOffset(AbstractInterruptibleChannel.class, "interruptedTarget");
+ private volatile Object interruptedTarget; // Thread or placeholder object
+
+ private void trySetTarget(Thread target) {
+ // can't use VarHandle here as CAS may park on first usage
+ U.compareAndSetReference(this, INTERRUPTED_TARGET, null, target);
+ }
/**
* Marks the beginning of an I/O operation that might block indefinitely.
@@ -151,24 +174,12 @@ public final boolean isOpen() {
* closing and interruption for this channel.
*/
protected final void begin() {
- if (interruptor == null) {
- interruptor = new Interruptible() {
- public void interrupt(Thread target) {
- synchronized (closeLock) {
- if (closed)
- return;
- closed = true;
- interrupted = target;
- try {
- AbstractInterruptibleChannel.this.implCloseChannel();
- } catch (IOException x) { }
- }
- }};
- }
blockedOn(interruptor);
Thread me = Thread.currentThread();
- if (me.isInterrupted())
+ if (me.isInterrupted()) {
interruptor.interrupt(me);
+ interruptor.postInterrupt();
+ }
}
/**
@@ -194,10 +205,14 @@ protected final void end(boolean completed)
throws AsynchronousCloseException
{
blockedOn(null);
- Thread interrupted = this.interrupted;
- if (interrupted != null && interrupted == Thread.currentThread()) {
- this.interrupted = null;
- throw new ClosedByInterruptException();
+ Object interruptedTarget = this.interruptedTarget;
+ if (interruptedTarget != null) {
+ interruptor.postInterrupt();
+ if (interruptedTarget == Thread.currentThread()) {
+ // replace with dummy object to avoid retaining reference to this thread
+ this.interruptedTarget = new Object();
+ throw new ClosedByInterruptException();
+ }
}
if (!completed && closed)
throw new AsynchronousCloseException();
diff --git a/src/java.base/share/classes/java/nio/channels/spi/AbstractSelector.java b/src/java.base/share/classes/java/nio/channels/spi/AbstractSelector.java
index d04485471cc68..7ea5f89221834 100644
--- a/src/java.base/share/classes/java/nio/channels/spi/AbstractSelector.java
+++ b/src/java.base/share/classes/java/nio/channels/spi/AbstractSelector.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2024, 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
@@ -89,6 +89,9 @@ public abstract class AbstractSelector
// cancelled-key, not used by the JDK Selector implementations
private final Set cancelledKeys;
+ // invoked if a Thread is interrupted when blocked on a selection op
+ private final Interruptible interruptor;
+
/**
* Initializes a new instance of this class.
*
@@ -103,6 +106,15 @@ protected AbstractSelector(SelectorProvider provider) {
} else {
this.cancelledKeys = new HashSet<>();
}
+ this.interruptor = new Interruptible() {
+ @Override
+ public void interrupt(Thread ignore) {
+ }
+ @Override
+ public void postInterrupt() {
+ AbstractSelector.this.wakeup();
+ }
+ };
}
void cancel(SelectionKey k) { // package-private
@@ -209,8 +221,6 @@ protected final void deregister(AbstractSelectionKey key) {
// -- Interruption machinery --
- private Interruptible interruptor = null;
-
/**
* Marks the beginning of an I/O operation that might block indefinitely.
*
@@ -225,16 +235,11 @@ protected final void deregister(AbstractSelectionKey key) {
* blocked in an I/O operation upon the selector.
*/
protected final void begin() {
- if (interruptor == null) {
- interruptor = new Interruptible() {
- public void interrupt(Thread ignore) {
- AbstractSelector.this.wakeup();
- }};
- }
AbstractInterruptibleChannel.blockedOn(interruptor);
Thread me = Thread.currentThread();
- if (me.isInterrupted())
- interruptor.interrupt(me);
+ if (me.isInterrupted()) {
+ interruptor.postInterrupt();
+ }
}
/**
@@ -248,5 +253,4 @@ public void interrupt(Thread ignore) {
protected final void end() {
AbstractInterruptibleChannel.blockedOn(null);
}
-
}
diff --git a/src/java.base/share/classes/sun/nio/ch/Interruptible.java b/src/java.base/share/classes/sun/nio/ch/Interruptible.java
index 8445e35f05095..5785ba52e24d6 100644
--- a/src/java.base/share/classes/sun/nio/ch/Interruptible.java
+++ b/src/java.base/share/classes/sun/nio/ch/Interruptible.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2024, 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
@@ -31,6 +31,23 @@
public interface Interruptible {
- public void interrupt(Thread t);
+ /**
+ * Invoked by Thread.interrupt when the given Thread is interrupted. Thread.interrupt
+ * invokes this method while holding the given Thread's interrupt lock. This method
+ * is also invoked by AbstractInterruptibleChannel when beginning an I/O operation
+ * with the current thread's interrupt status set. This method must not block.
+ */
+ void interrupt(Thread target);
+
+ /**
+ * Invoked by Thread.interrupt after releasing the Thread's interrupt lock.
+ * It may also be invoked by AbstractInterruptibleChannel or AbstractSelector when
+ * beginning an I/O operation with the current thread's interrupt status set, or at
+ * the end of an I/O operation when any thread doing I/O on the channel (or selector)
+ * has been interrupted. This method closes the channel (or wakes up the Selector) to
+ * ensure that AsynchronousCloseException or ClosedByInterruptException is thrown.
+ * This method is required to be idempotent.
+ */
+ void postInterrupt();
}
From 4cf131a101d13699b1bf017895798c9bda87f551 Mon Sep 17 00:00:00 2001
From: Ludovic Henry
Date: Tue, 9 Jan 2024 07:26:35 +0000
Subject: [PATCH 028/153] 8319716: RISC-V: Add SHA-2
Co-authored-by: Robbin Ehn
Reviewed-by: fyang, mli, luhenry
---
src/hotspot/cpu/riscv/assembler_riscv.hpp | 77 +++-
src/hotspot/cpu/riscv/globals_riscv.hpp | 2 +
.../cpu/riscv/macroAssembler_riscv.hpp | 14 +
src/hotspot/cpu/riscv/stubGenerator_riscv.cpp | 398 ++++++++++++++++++
src/hotspot/cpu/riscv/vm_version_riscv.cpp | 44 +-
5 files changed, 516 insertions(+), 19 deletions(-)
diff --git a/src/hotspot/cpu/riscv/assembler_riscv.hpp b/src/hotspot/cpu/riscv/assembler_riscv.hpp
index 22554972583e3..ffe6dcf07ecd7 100644
--- a/src/hotspot/cpu/riscv/assembler_riscv.hpp
+++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp
@@ -1334,6 +1334,7 @@ enum VectorMask {
INSN(vsll_vi, 0b1010111, 0b011, 0b100101);
// Vector Slide Instructions
+ INSN(vslideup_vi, 0b1010111, 0b011, 0b001110);
INSN(vslidedown_vi, 0b1010111, 0b011, 0b001111);
#undef INSN
@@ -1689,7 +1690,6 @@ enum VectorMask {
INSN(vmv_v_x, 0b1010111, 0b100, v0, 0b1, 0b010111);
#undef INSN
-#undef patch_VArith
#define INSN(NAME, op, funct13, funct6) \
void NAME(VectorRegister Vd, VectorMask vm = unmasked) { \
@@ -1731,14 +1731,29 @@ enum Nf {
patch_reg((address)&insn, 15, Rs1); \
emit(insn)
-#define INSN(NAME, op, lumop, vm, mop, nf) \
- void NAME(VectorRegister Vd, Register Rs1, uint32_t width = 0, bool mew = false) { \
+#define INSN(NAME, op, width, lumop, vm, mop, mew, nf) \
+ void NAME(VectorRegister Vd, Register Rs1) { \
guarantee(is_uimm3(width), "width is invalid"); \
patch_VLdSt(op, Vd, width, Rs1, lumop, vm, mop, mew, nf); \
}
// Vector Load/Store Instructions
- INSN(vl1re8_v, 0b0000111, 0b01000, 0b1, 0b00, g1);
+ INSN(vl1re8_v, 0b0000111, 0b000, 0b01000, 0b1, 0b00, 0b0, g1);
+ INSN(vl1re16_v, 0b0000111, 0b101, 0b01000, 0b1, 0b00, 0b0, g1);
+ INSN(vl1re32_v, 0b0000111, 0b110, 0b01000, 0b1, 0b00, 0b0, g1);
+ INSN(vl1re64_v, 0b0000111, 0b111, 0b01000, 0b1, 0b00, 0b0, g1);
+ INSN(vl2re8_v, 0b0000111, 0b000, 0b01000, 0b1, 0b00, 0b0, g2);
+ INSN(vl2re16_v, 0b0000111, 0b101, 0b01000, 0b1, 0b00, 0b0, g2);
+ INSN(vl2re32_v, 0b0000111, 0b110, 0b01000, 0b1, 0b00, 0b0, g2);
+ INSN(vl2re64_v, 0b0000111, 0b111, 0b01000, 0b1, 0b00, 0b0, g2);
+ INSN(vl4re8_v, 0b0000111, 0b000, 0b01000, 0b1, 0b00, 0b0, g4);
+ INSN(vl4re16_v, 0b0000111, 0b101, 0b01000, 0b1, 0b00, 0b0, g4);
+ INSN(vl4re32_v, 0b0000111, 0b110, 0b01000, 0b1, 0b00, 0b0, g4);
+ INSN(vl4re64_v, 0b0000111, 0b111, 0b01000, 0b1, 0b00, 0b0, g4);
+ INSN(vl8re8_v, 0b0000111, 0b000, 0b01000, 0b1, 0b00, 0b0, g8);
+ INSN(vl8re16_v, 0b0000111, 0b101, 0b01000, 0b1, 0b00, 0b0, g8);
+ INSN(vl8re32_v, 0b0000111, 0b110, 0b01000, 0b1, 0b00, 0b0, g8);
+ INSN(vl8re64_v, 0b0000111, 0b111, 0b01000, 0b1, 0b00, 0b0, g8);
#undef INSN
@@ -1749,6 +1764,9 @@ enum Nf {
// Vector Load/Store Instructions
INSN(vs1r_v, 0b0100111, 0b000, 0b01000, 0b1, 0b00, 0b0, g1);
+ INSN(vs2r_v, 0b0100111, 0b000, 0b01000, 0b1, 0b00, 0b0, g2);
+ INSN(vs4r_v, 0b0100111, 0b000, 0b01000, 0b1, 0b00, 0b0, g4);
+ INSN(vs8r_v, 0b0100111, 0b000, 0b01000, 0b1, 0b00, 0b0, g8);
#undef INSN
@@ -1794,9 +1812,11 @@ enum Nf {
}
// Vector unordered indexed load instructions
+ INSN( vluxei8_v, 0b0000111, 0b000, 0b01, 0b0);
INSN(vluxei32_v, 0b0000111, 0b110, 0b01, 0b0);
// Vector unordered indexed store instructions
+ INSN( vsuxei8_v, 0b0100111, 0b000, 0b01, 0b0);
INSN(vsuxei32_v, 0b0100111, 0b110, 0b01, 0b0);
#undef INSN
@@ -1820,6 +1840,55 @@ enum Nf {
#undef INSN
#undef patch_VLdSt
+// ====================================
+// RISC-V Vector Crypto Extension
+// ====================================
+
+#define INSN(NAME, op, funct3, funct6) \
+ void NAME(VectorRegister Vd, VectorRegister Vs2, VectorRegister Vs1, VectorMask vm = unmasked) { \
+ patch_VArith(op, Vd, funct3, Vs1->raw_encoding(), Vs2, vm, funct6); \
+ }
+
+ // Vector Bit-manipulation used in Cryptography (Zvkb) Extension
+ INSN(vandn_vv, 0b1010111, 0b000, 0b000001);
+ INSN(vandn_vx, 0b1010111, 0b100, 0b000001);
+ INSN(vandn_vi, 0b1010111, 0b011, 0b000001);
+ INSN(vclmul_vv, 0b1010111, 0b010, 0b001100);
+ INSN(vclmul_vx, 0b1010111, 0b110, 0b001100);
+ INSN(vclmulh_vv, 0b1010111, 0b010, 0b001101);
+ INSN(vclmulh_vx, 0b1010111, 0b110, 0b001101);
+ INSN(vror_vv, 0b1010111, 0b000, 0b010100);
+ INSN(vror_vx, 0b1010111, 0b100, 0b010100);
+ INSN(vrol_vv, 0b1010111, 0b000, 0b010101);
+ INSN(vrol_vx, 0b1010111, 0b100, 0b010101);
+
+#undef INSN
+
+#define INSN(NAME, op, funct3, Vs1, funct6) \
+ void NAME(VectorRegister Vd, VectorRegister Vs2, VectorMask vm = unmasked) { \
+ patch_VArith(op, Vd, funct3, Vs1, Vs2, vm, funct6); \
+ }
+
+ // Vector Bit-manipulation used in Cryptography (Zvkb) Extension
+ INSN(vbrev8_v, 0b1010111, 0b010, 0b01000, 0b010010);
+ INSN(vrev8_v, 0b1010111, 0b010, 0b01001, 0b010010);
+
+#undef INSN
+
+#define INSN(NAME, op, funct3, vm, funct6) \
+ void NAME(VectorRegister Vd, VectorRegister Vs2, VectorRegister Vs1) { \
+ patch_VArith(op, Vd, funct3, Vs1->raw_encoding(), Vs2, vm, funct6); \
+ }
+
+ // Vector SHA-2 Secure Hash (Zvknh[ab]) Extension
+ INSN(vsha2ms_vv, 0b1110111, 0b010, 0b1, 0b101101);
+ INSN(vsha2ch_vv, 0b1110111, 0b010, 0b1, 0b101110);
+ INSN(vsha2cl_vv, 0b1110111, 0b010, 0b1, 0b101111);
+
+#undef INSN
+
+#undef patch_VArith
+
// ====================================
// RISC-V Bit-Manipulation Extension
// Currently only support Zba, Zbb and Zbs bitmanip extensions.
diff --git a/src/hotspot/cpu/riscv/globals_riscv.hpp b/src/hotspot/cpu/riscv/globals_riscv.hpp
index 60456c37ffe75..aa95cebec14cd 100644
--- a/src/hotspot/cpu/riscv/globals_riscv.hpp
+++ b/src/hotspot/cpu/riscv/globals_riscv.hpp
@@ -113,6 +113,8 @@ define_pd_global(intx, InlineSmallCode, 1000);
product(bool, UseZtso, false, EXPERIMENTAL, "Assume Ztso memory model") \
product(bool, UseZihintpause, false, EXPERIMENTAL, \
"Use Zihintpause instructions") \
+ product(bool, UseZvkn, false, EXPERIMENTAL, \
+ "Use Zvkn group extension, Zvkned, Zvknhb, Zvkb, Zvkt") \
product(bool, UseRVVForBigIntegerShiftIntrinsics, true, \
"Use RVV instructions for left/right shift of BigInteger")
diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
index 3e0206746242c..4724dd85e7801 100644
--- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
+++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
@@ -1361,6 +1361,16 @@ class MacroAssembler: public Assembler {
vmfle_vv(vd, vs1, vs2, vm);
}
+ inline void vmsltu_vi(VectorRegister Vd, VectorRegister Vs2, uint32_t imm, VectorMask vm = unmasked) {
+ guarantee(imm >= 1 && imm <= 16, "imm is invalid");
+ vmsleu_vi(Vd, Vs2, imm-1, vm);
+ }
+
+ inline void vmsgeu_vi(VectorRegister Vd, VectorRegister Vs2, uint32_t imm, VectorMask vm = unmasked) {
+ guarantee(imm >= 1 && imm <= 16, "imm is invalid");
+ vmsgtu_vi(Vd, Vs2, imm-1, vm);
+ }
+
// Copy mask register
inline void vmmv_m(VectorRegister vd, VectorRegister vs) {
vmand_mm(vd, vs, vs);
@@ -1376,6 +1386,10 @@ class MacroAssembler: public Assembler {
vmxnor_mm(vd, vd, vd);
}
+ inline void vnot_v(VectorRegister Vd, VectorRegister Vs, VectorMask vm = unmasked) {
+ vxor_vi(Vd, Vs, -1, vm);
+ }
+
static const int zero_words_block_size;
void cast_primitive_type(BasicType type, Register Rt) {
diff --git a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp
index be5fd98335329..4bd33d08f8928 100644
--- a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp
+++ b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp
@@ -3659,8 +3659,394 @@ class StubGenerator: public StubCodeGenerator {
return entry;
}
};
+
#endif // COMPILER2
+#undef __
+#define __ this->
+ class Sha2Generator : public MacroAssembler {
+ StubCodeGenerator* _cgen;
+ public:
+ Sha2Generator(MacroAssembler* masm, StubCodeGenerator* cgen) : MacroAssembler(masm->code()), _cgen(cgen) {}
+ address generate_sha256_implCompress(bool multi_block) {
+ return generate_sha2_implCompress(Assembler::e32, multi_block);
+ }
+ address generate_sha512_implCompress(bool multi_block) {
+ return generate_sha2_implCompress(Assembler::e64, multi_block);
+ }
+ private:
+
+ void vleXX_v(Assembler::SEW vset_sew, VectorRegister vr, Register sr) {
+ if (vset_sew == Assembler::e32) __ vle32_v(vr, sr);
+ else __ vle64_v(vr, sr);
+ }
+
+ void vseXX_v(Assembler::SEW vset_sew, VectorRegister vr, Register sr) {
+ if (vset_sew == Assembler::e32) __ vse32_v(vr, sr);
+ else __ vse64_v(vr, sr);
+ }
+
+ // Overview of the logic in each "quad round".
+ //
+ // The code below repeats 16/20 times the logic implementing four rounds
+ // of the SHA-256/512 core loop as documented by NIST. 16/20 "quad rounds"
+ // to implementing the 64/80 single rounds.
+ //
+ // // Load four word (u32/64) constants (K[t+3], K[t+2], K[t+1], K[t+0])
+ // // Output:
+ // // vTmp1 = {K[t+3], K[t+2], K[t+1], K[t+0]}
+ // vl1reXX.v vTmp1, ofs
+ //
+ // // Increment word constant address by stride (16/32 bytes, 4*4B/8B, 128b/256b)
+ // addi ofs, ofs, 16/32
+ //
+ // // Add constants to message schedule words:
+ // // Input
+ // // vTmp1 = {K[t+3], K[t+2], K[t+1], K[t+0]}
+ // // vW0 = {W[t+3], W[t+2], W[t+1], W[t+0]}; // Vt0 = W[3:0];
+ // // Output
+ // // vTmp0 = {W[t+3]+K[t+3], W[t+2]+K[t+2], W[t+1]+K[t+1], W[t+0]+K[t+0]}
+ // vadd.vv vTmp0, vTmp1, vW0
+ //
+ // // 2 rounds of working variables updates.
+ // // vState1[t+4] <- vState1[t], vState0[t], vTmp0[t]
+ // // Input:
+ // // vState1 = {c[t],d[t],g[t],h[t]} " = vState1[t] "
+ // // vState0 = {a[t],b[t],e[t],f[t]}
+ // // vTmp0 = {W[t+3]+K[t+3], W[t+2]+K[t+2], W[t+1]+K[t+1], W[t+0]+K[t+0]}
+ // // Output:
+ // // vState1 = {f[t+2],e[t+2],b[t+2],a[t+2]} " = vState0[t+2] "
+ // // = {h[t+4],g[t+4],d[t+4],c[t+4]} " = vState1[t+4] "
+ // vsha2cl.vv vState1, vState0, vTmp0
+ //
+ // // 2 rounds of working variables updates.
+ // // vState0[t+4] <- vState0[t], vState0[t+2], vTmp0[t]
+ // // Input
+ // // vState0 = {a[t],b[t],e[t],f[t]} " = vState0[t] "
+ // // = {h[t+2],g[t+2],d[t+2],c[t+2]} " = vState1[t+2] "
+ // // vState1 = {f[t+2],e[t+2],b[t+2],a[t+2]} " = vState0[t+2] "
+ // // vTmp0 = {W[t+3]+K[t+3], W[t+2]+K[t+2], W[t+1]+K[t+1], W[t+0]+K[t+0]}
+ // // Output:
+ // // vState0 = {f[t+4],e[t+4],b[t+4],a[t+4]} " = vState0[t+4] "
+ // vsha2ch.vv vState0, vState1, vTmp0
+ //
+ // // Combine 2QW into 1QW
+ // //
+ // // To generate the next 4 words, "new_vW0"/"vTmp0" from vW0-vW3, vsha2ms needs
+ // // vW0[0..3], vW1[0], vW2[1..3], vW3[0, 2..3]
+ // // and it can only take 3 vectors as inputs. Hence we need to combine
+ // // vW1[0] and vW2[1..3] in a single vector.
+ // //
+ // // vmerge Vt4, Vt1, Vt2, V0
+ // // Input
+ // // V0 = mask // first word from vW2, 1..3 words from vW1
+ // // vW2 = {Wt-8, Wt-7, Wt-6, Wt-5}
+ // // vW1 = {Wt-12, Wt-11, Wt-10, Wt-9}
+ // // Output
+ // // Vt4 = {Wt-12, Wt-7, Wt-6, Wt-5}
+ // vmerge.vvm vTmp0, vW2, vW1, v0
+ //
+ // // Generate next Four Message Schedule Words (hence allowing for 4 more rounds)
+ // // Input
+ // // vW0 = {W[t+ 3], W[t+ 2], W[t+ 1], W[t+ 0]} W[ 3: 0]
+ // // vW3 = {W[t+15], W[t+14], W[t+13], W[t+12]} W[15:12]
+ // // vTmp0 = {W[t+11], W[t+10], W[t+ 9], W[t+ 4]} W[11: 9,4]
+ // // Output (next four message schedule words)
+ // // vW0 = {W[t+19], W[t+18], W[t+17], W[t+16]} W[19:16]
+ // vsha2ms.vv vW0, vTmp0, vW3
+ //
+ // BEFORE
+ // vW0 - vW3 hold the message schedule words (initially the block words)
+ // vW0 = W[ 3: 0] "oldest"
+ // vW1 = W[ 7: 4]
+ // vW2 = W[11: 8]
+ // vW3 = W[15:12] "newest"
+ //
+ // vt6 - vt7 hold the working state variables
+ // vState0 = {a[t],b[t],e[t],f[t]} // initially {H5,H4,H1,H0}
+ // vState1 = {c[t],d[t],g[t],h[t]} // initially {H7,H6,H3,H2}
+ //
+ // AFTER
+ // vW0 - vW3 hold the message schedule words (initially the block words)
+ // vW1 = W[ 7: 4] "oldest"
+ // vW2 = W[11: 8]
+ // vW3 = W[15:12]
+ // vW0 = W[19:16] "newest"
+ //
+ // vState0 and vState1 hold the working state variables
+ // vState0 = {a[t+4],b[t+4],e[t+4],f[t+4]}
+ // vState1 = {c[t+4],d[t+4],g[t+4],h[t+4]}
+ //
+ // The group of vectors vW0,vW1,vW2,vW3 is "rotated" by one in each quad-round,
+ // hence the uses of those vectors rotate in each round, and we get back to the
+ // initial configuration every 4 quad-rounds. We could avoid those changes at
+ // the cost of moving those vectors at the end of each quad-rounds.
+ void sha2_quad_round(Assembler::SEW vset_sew, VectorRegister rot1, VectorRegister rot2, VectorRegister rot3, VectorRegister rot4,
+ Register scalarconst, VectorRegister vtemp, VectorRegister vtemp2, VectorRegister v_abef, VectorRegister v_cdgh,
+ bool gen_words = true, bool step_const = true) {
+ __ vleXX_v(vset_sew, vtemp, scalarconst);
+ if (step_const) {
+ __ addi(scalarconst, scalarconst, vset_sew == Assembler::e32 ? 16 : 32);
+ }
+ __ vadd_vv(vtemp2, vtemp, rot1);
+ __ vsha2cl_vv(v_cdgh, v_abef, vtemp2);
+ __ vsha2ch_vv(v_abef, v_cdgh, vtemp2);
+ if (gen_words) {
+ __ vmerge_vvm(vtemp2, rot3, rot2);
+ __ vsha2ms_vv(rot1, vtemp2, rot4);
+ }
+ }
+
+ const char* stub_name(Assembler::SEW vset_sew, bool multi_block) {
+ if (vset_sew == Assembler::e32 && !multi_block) return "sha256_implCompress";
+ if (vset_sew == Assembler::e32 && multi_block) return "sha256_implCompressMB";
+ if (vset_sew == Assembler::e64 && !multi_block) return "sha512_implCompress";
+ if (vset_sew == Assembler::e64 && multi_block) return "sha512_implCompressMB";
+ ShouldNotReachHere();
+ return "bad name lookup";
+ }
+
+ // Arguments:
+ //
+ // Inputs:
+ // c_rarg0 - byte[] source+offset
+ // c_rarg1 - int[] SHA.state
+ // c_rarg2 - int offset
+ // c_rarg3 - int limit
+ //
+ address generate_sha2_implCompress(Assembler::SEW vset_sew, bool multi_block) {
+ alignas(64) static const uint32_t round_consts_256[64] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
+ };
+ alignas(64) static const uint64_t round_consts_512[80] = {
+ 0x428a2f98d728ae22l, 0x7137449123ef65cdl, 0xb5c0fbcfec4d3b2fl,
+ 0xe9b5dba58189dbbcl, 0x3956c25bf348b538l, 0x59f111f1b605d019l,
+ 0x923f82a4af194f9bl, 0xab1c5ed5da6d8118l, 0xd807aa98a3030242l,
+ 0x12835b0145706fbel, 0x243185be4ee4b28cl, 0x550c7dc3d5ffb4e2l,
+ 0x72be5d74f27b896fl, 0x80deb1fe3b1696b1l, 0x9bdc06a725c71235l,
+ 0xc19bf174cf692694l, 0xe49b69c19ef14ad2l, 0xefbe4786384f25e3l,
+ 0x0fc19dc68b8cd5b5l, 0x240ca1cc77ac9c65l, 0x2de92c6f592b0275l,
+ 0x4a7484aa6ea6e483l, 0x5cb0a9dcbd41fbd4l, 0x76f988da831153b5l,
+ 0x983e5152ee66dfabl, 0xa831c66d2db43210l, 0xb00327c898fb213fl,
+ 0xbf597fc7beef0ee4l, 0xc6e00bf33da88fc2l, 0xd5a79147930aa725l,
+ 0x06ca6351e003826fl, 0x142929670a0e6e70l, 0x27b70a8546d22ffcl,
+ 0x2e1b21385c26c926l, 0x4d2c6dfc5ac42aedl, 0x53380d139d95b3dfl,
+ 0x650a73548baf63del, 0x766a0abb3c77b2a8l, 0x81c2c92e47edaee6l,
+ 0x92722c851482353bl, 0xa2bfe8a14cf10364l, 0xa81a664bbc423001l,
+ 0xc24b8b70d0f89791l, 0xc76c51a30654be30l, 0xd192e819d6ef5218l,
+ 0xd69906245565a910l, 0xf40e35855771202al, 0x106aa07032bbd1b8l,
+ 0x19a4c116b8d2d0c8l, 0x1e376c085141ab53l, 0x2748774cdf8eeb99l,
+ 0x34b0bcb5e19b48a8l, 0x391c0cb3c5c95a63l, 0x4ed8aa4ae3418acbl,
+ 0x5b9cca4f7763e373l, 0x682e6ff3d6b2b8a3l, 0x748f82ee5defb2fcl,
+ 0x78a5636f43172f60l, 0x84c87814a1f0ab72l, 0x8cc702081a6439ecl,
+ 0x90befffa23631e28l, 0xa4506cebde82bde9l, 0xbef9a3f7b2c67915l,
+ 0xc67178f2e372532bl, 0xca273eceea26619cl, 0xd186b8c721c0c207l,
+ 0xeada7dd6cde0eb1el, 0xf57d4f7fee6ed178l, 0x06f067aa72176fbal,
+ 0x0a637dc5a2c898a6l, 0x113f9804bef90dael, 0x1b710b35131c471bl,
+ 0x28db77f523047d84l, 0x32caab7b40c72493l, 0x3c9ebe0a15c9bebcl,
+ 0x431d67c49c100d4cl, 0x4cc5d4becb3e42b6l, 0x597f299cfc657e2al,
+ 0x5fcb6fab3ad6faecl, 0x6c44198c4a475817l
+ };
+ const int const_add = vset_sew == Assembler::e32 ? 16 : 32;
+
+ __ align(CodeEntryAlignment);
+ StubCodeMark mark(_cgen, "StubRoutines", stub_name(vset_sew, multi_block));
+ address start = __ pc();
+
+ Register buf = c_rarg0;
+ Register state = c_rarg1;
+ Register ofs = c_rarg2;
+ Register limit = c_rarg3;
+ Register consts = t2; // caller saved
+ Register state_c = x28; // caller saved
+ VectorRegister vindex = v2;
+ VectorRegister vW0 = v4;
+ VectorRegister vW1 = v6;
+ VectorRegister vW2 = v8;
+ VectorRegister vW3 = v10;
+ VectorRegister vState0 = v12;
+ VectorRegister vState1 = v14;
+ VectorRegister vHash0 = v16;
+ VectorRegister vHash1 = v18;
+ VectorRegister vTmp0 = v20;
+ VectorRegister vTmp1 = v22;
+
+ Label multi_block_loop;
+
+ __ enter();
+
+ address constant_table = vset_sew == Assembler::e32 ? (address)round_consts_256 : (address)round_consts_512;
+ la(consts, ExternalAddress(constant_table));
+
+ // Register use in this function:
+ //
+ // VECTORS
+ // vW0 - vW3 (512/1024-bits / 4*128/256 bits / 4*4*32/65 bits), hold the message
+ // schedule words (Wt). They start with the message block
+ // content (W0 to W15), then further words in the message
+ // schedule generated via vsha2ms from previous Wt.
+ // Initially:
+ // vW0 = W[ 3:0] = { W3, W2, W1, W0}
+ // vW1 = W[ 7:4] = { W7, W6, W5, W4}
+ // vW2 = W[ 11:8] = {W11, W10, W9, W8}
+ // vW3 = W[15:12] = {W15, W14, W13, W12}
+ //
+ // vState0 - vState1 hold the working state variables (a, b, ..., h)
+ // vState0 = {f[t],e[t],b[t],a[t]}
+ // vState1 = {h[t],g[t],d[t],c[t]}
+ // Initially:
+ // vState0 = {H5i-1, H4i-1, H1i-1 , H0i-1}
+ // vState1 = {H7i-i, H6i-1, H3i-1 , H2i-1}
+ //
+ // v0 = masks for vrgather/vmerge. Single value during the 16 rounds.
+ //
+ // vTmp0 = temporary, Wt+Kt
+ // vTmp1 = temporary, Kt
+ //
+ // vHash0/vHash1 = hold the initial values of the hash, byte-swapped.
+ //
+ // During most of the function the vector state is configured so that each
+ // vector is interpreted as containing four 32/64 bits (e32/e64) elements (128/256 bits).
+
+ // vsha2ch/vsha2cl uses EGW of 4*SEW.
+ // SHA256 SEW = e32, EGW = 128-bits
+ // SHA512 SEW = e64, EGW = 256-bits
+ //
+ // VLEN is required to be at least 128.
+ // For the case of VLEN=128 and SHA512 we need LMUL=2 to work with 4*e64 (EGW = 256)
+ //
+ // m1: LMUL=1/2
+ // ta: tail agnostic (don't care about those lanes)
+ // ma: mask agnostic (don't care about those lanes)
+ // x0 is not written, we known the number of vector elements.
+
+ if (vset_sew == Assembler::e64 && MaxVectorSize == 16) { // SHA512 and VLEN = 128
+ __ vsetivli(x0, 4, vset_sew, Assembler::m2, Assembler::ma, Assembler::ta);
+ } else {
+ __ vsetivli(x0, 4, vset_sew, Assembler::m1, Assembler::ma, Assembler::ta);
+ }
+
+ int64_t indexes = vset_sew == Assembler::e32 ? 0x00041014ul : 0x00082028ul;
+ __ li(t0, indexes);
+ __ vmv_v_x(vindex, t0);
+
+ // Step-over a,b, so we are pointing to c.
+ // const_add is equal to 4x state variable, div by 2 is thus 2, a,b
+ __ addi(state_c, state, const_add/2);
+
+ // Use index-load to get {f,e,b,a},{h,g,d,c}
+ __ vluxei8_v(vState0, state, vindex);
+ __ vluxei8_v(vState1, state_c, vindex);
+
+ __ bind(multi_block_loop);
+
+ // Capture the initial H values in vHash0 and vHash1 to allow for computing
+ // the resulting H', since H' = H+{a',b',c',...,h'}.
+ __ vmv_v_v(vHash0, vState0);
+ __ vmv_v_v(vHash1, vState1);
+
+ // Load the 512/1024-bits of the message block in vW0-vW3 and perform
+ // an endian swap on each 4/8 bytes element.
+ //
+ // If Zvkb is not implemented one can use vrgather
+ // with an index sequence to byte-swap.
+ // sequence = [3 2 1 0 7 6 5 4 11 10 9 8 15 14 13 12]
+ // gives us "N ^ 3" as a nice formula to generate
+ // this sequence. 'vid' gives us the N.
+ __ vleXX_v(vset_sew, vW0, buf);
+ __ vrev8_v(vW0, vW0);
+ __ addi(buf, buf, const_add);
+ __ vleXX_v(vset_sew, vW1, buf);
+ __ vrev8_v(vW1, vW1);
+ __ addi(buf, buf, const_add);
+ __ vleXX_v(vset_sew, vW2, buf);
+ __ vrev8_v(vW2, vW2);
+ __ addi(buf, buf, const_add);
+ __ vleXX_v(vset_sew, vW3, buf);
+ __ vrev8_v(vW3, vW3);
+ __ addi(buf, buf, const_add);
+
+ // Set v0 up for the vmerge that replaces the first word (idx==0)
+ __ vid_v(v0);
+ __ vmseq_vi(v0, v0, 0x0); // v0.mask[i] = (i == 0 ? 1 : 0)
+
+ VectorRegister rotation_regs[] = {vW0, vW1, vW2, vW3};
+ int rot_pos = 0;
+ // Quad-round #0 (+0, vW0->vW1->vW2->vW3) ... #11 (+3, vW3->vW0->vW1->vW2)
+ const int qr_end = vset_sew == Assembler::e32 ? 12 : 16;
+ for (int i = 0; i < qr_end; i++) {
+ sha2_quad_round(vset_sew,
+ rotation_regs[(rot_pos + 0) & 0x3],
+ rotation_regs[(rot_pos + 1) & 0x3],
+ rotation_regs[(rot_pos + 2) & 0x3],
+ rotation_regs[(rot_pos + 3) & 0x3],
+ consts,
+ vTmp1, vTmp0, vState0, vState1);
+ ++rot_pos;
+ }
+ // Quad-round #12 (+0, vW0->vW1->vW2->vW3) ... #15 (+3, vW3->vW0->vW1->vW2)
+ // Note that we stop generating new message schedule words (Wt, vW0-13)
+ // as we already generated all the words we end up consuming (i.e., W[63:60]).
+ const int qr_c_end = qr_end + 4;
+ for (int i = qr_end; i < qr_c_end; i++) {
+ sha2_quad_round(vset_sew,
+ rotation_regs[(rot_pos + 0) & 0x3],
+ rotation_regs[(rot_pos + 1) & 0x3],
+ rotation_regs[(rot_pos + 2) & 0x3],
+ rotation_regs[(rot_pos + 3) & 0x3],
+ consts,
+ vTmp1, vTmp0, vState0, vState1, false, i < (qr_c_end-1));
+ ++rot_pos;
+ }
+
+ //--------------------------------------------------------------------------------
+ // Compute the updated hash value H'
+ // H' = H + {h',g',...,b',a'}
+ // = {h,g,...,b,a} + {h',g',...,b',a'}
+ // = {h+h',g+g',...,b+b',a+a'}
+
+ // H' = H+{a',b',c',...,h'}
+ __ vadd_vv(vState0, vHash0, vState0);
+ __ vadd_vv(vState1, vHash1, vState1);
+
+ if (multi_block) {
+ int total_adds = vset_sew == Assembler::e32 ? 240 : 608;
+ __ addi(consts, consts, -total_adds);
+ __ add(ofs, ofs, vset_sew == Assembler::e32 ? 64 : 128);
+ __ ble(ofs, limit, multi_block_loop);
+ __ mv(c_rarg0, ofs); // return ofs
+ }
+
+ // Store H[0..8] = {a,b,c,d,e,f,g,h} from
+ // vState0 = {f,e,b,a}
+ // vState1 = {h,g,d,c}
+ __ vsuxei8_v(vState0, state, vindex);
+ __ vsuxei8_v(vState1, state_c, vindex);
+
+ __ leave();
+ __ ret();
+
+ return start;
+ }
+ };
+#undef __
+#define __ masm->
+
// Continuation point for throwing of implicit exceptions that are
// not handled in the current activation. Fabricates an exception
// oop and initiates normal exception dispatching in this
@@ -4862,6 +5248,18 @@ static const int64_t right_3_bits = right_n_bits(3);
}
#endif // COMPILER2
+ if (UseSHA256Intrinsics) {
+ Sha2Generator sha2(_masm, this);
+ StubRoutines::_sha256_implCompress = sha2.generate_sha256_implCompress(false);
+ StubRoutines::_sha256_implCompressMB = sha2.generate_sha256_implCompress(true);
+ }
+
+ if (UseSHA512Intrinsics) {
+ Sha2Generator sha2(_masm, this);
+ StubRoutines::_sha512_implCompress = sha2.generate_sha512_implCompress(false);
+ StubRoutines::_sha512_implCompressMB = sha2.generate_sha512_implCompress(true);
+ }
+
generate_compare_long_strings();
generate_string_indexof_stubs();
diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.cpp b/src/hotspot/cpu/riscv/vm_version_riscv.cpp
index 41ec15a8634b2..9a72b8d75a136 100644
--- a/src/hotspot/cpu/riscv/vm_version_riscv.cpp
+++ b/src/hotspot/cpu/riscv/vm_version_riscv.cpp
@@ -146,26 +146,11 @@ void VM_Version::initialize() {
FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false);
}
- if (UseSHA) {
- warning("SHA instructions are not available on this CPU");
- FLAG_SET_DEFAULT(UseSHA, false);
- }
-
if (UseSHA1Intrinsics) {
warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU.");
FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
}
- if (UseSHA256Intrinsics) {
- warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU.");
- FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
- }
-
- if (UseSHA512Intrinsics) {
- warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU.");
- FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
- }
-
if (UseSHA3Intrinsics) {
warning("Intrinsics for SHA3-224, SHA3-256, SHA3-384 and SHA3-512 crypto hash functions not available on this CPU.");
FLAG_SET_DEFAULT(UseSHA3Intrinsics, false);
@@ -272,6 +257,10 @@ void VM_Version::initialize() {
// NOTE: Make sure codes dependent on UseRVV are put after c2_initialize(),
// as there are extra checks inside it which could disable UseRVV
// in some situations.
+ if (UseZvkn && !UseRVV) {
+ FLAG_SET_DEFAULT(UseZvkn, false);
+ warning("Cannot enable Zvkn on cpu without RVV support.");
+ }
if (UseRVV) {
if (FLAG_IS_DEFAULT(UseChaCha20Intrinsics)) {
@@ -283,6 +272,31 @@ void VM_Version::initialize() {
}
FLAG_SET_DEFAULT(UseChaCha20Intrinsics, false);
}
+
+ if (!UseZvkn && UseSHA) {
+ warning("SHA instructions are not available on this CPU");
+ FLAG_SET_DEFAULT(UseSHA, false);
+ } else if (UseZvkn && FLAG_IS_DEFAULT(UseSHA)) {
+ FLAG_SET_DEFAULT(UseSHA, true);
+ }
+
+ if (!UseSHA) {
+ if (UseSHA256Intrinsics) {
+ warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU, UseZvkn needed.");
+ FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
+ }
+ if (UseSHA512Intrinsics) {
+ warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU, UseZvkn needed.");
+ FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
+ }
+ } else {
+ if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
+ FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
+ }
+ if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) {
+ FLAG_SET_DEFAULT(UseSHA512Intrinsics, true);
+ }
+ }
}
#ifdef COMPILER2
From 30f93a29c2f677d0279176b89edf2ecdc06b42ca Mon Sep 17 00:00:00 2001
From: Robbin Ehn
Date: Tue, 9 Jan 2024 07:34:50 +0000
Subject: [PATCH 029/153] 8320069: RISC-V: Add Zcb instructions
Reviewed-by: fyang, vkempik
---
src/hotspot/cpu/riscv/assembler_riscv.hpp | 259 +++++++++++++++++-
.../cpu/riscv/macroAssembler_riscv.cpp | 71 +++--
.../cpu/riscv/macroAssembler_riscv.hpp | 19 +-
src/hotspot/cpu/riscv/vm_version_riscv.hpp | 6 +
.../linux_riscv/vm_version_linux_riscv.cpp | 2 +
5 files changed, 316 insertions(+), 41 deletions(-)
diff --git a/src/hotspot/cpu/riscv/assembler_riscv.hpp b/src/hotspot/cpu/riscv/assembler_riscv.hpp
index ffe6dcf07ecd7..55c3e755c48eb 100644
--- a/src/hotspot/cpu/riscv/assembler_riscv.hpp
+++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp
@@ -506,7 +506,7 @@ class Assembler : public AbstractAssembler {
INSN(sllw, 0b0111011, 0b001, 0b0000000);
INSN(sraw, 0b0111011, 0b101, 0b0100000);
INSN(srlw, 0b0111011, 0b101, 0b0000000);
- INSN(mul, 0b0110011, 0b000, 0b0000001);
+ INSN(_mul, 0b0110011, 0b000, 0b0000001);
INSN(mulh, 0b0110011, 0b001, 0b0000001);
INSN(mulhsu,0b0110011, 0b010, 0b0000001);
INSN(mulhu, 0b0110011, 0b011, 0b0000001);
@@ -537,9 +537,9 @@ class Assembler : public AbstractAssembler {
}
INSN(lb, 0b0000011, 0b000);
- INSN(lbu, 0b0000011, 0b100);
- INSN(lh, 0b0000011, 0b001);
- INSN(lhu, 0b0000011, 0b101);
+ INSN(_lbu, 0b0000011, 0b100);
+ INSN(_lh, 0b0000011, 0b001);
+ INSN(_lhu, 0b0000011, 0b101);
INSN(_lw, 0b0000011, 0b010);
INSN(lwu, 0b0000011, 0b110);
INSN(_ld, 0b0000011, 0b011);
@@ -609,8 +609,8 @@ class Assembler : public AbstractAssembler {
emit(insn); \
} \
- INSN(sb, Register, 0b0100011, 0b000);
- INSN(sh, Register, 0b0100011, 0b001);
+ INSN(_sb, Register, 0b0100011, 0b000);
+ INSN(_sh, Register, 0b0100011, 0b001);
INSN(_sw, Register, 0b0100011, 0b010);
INSN(_sd, Register, 0b0100011, 0b011);
INSN(fsw, FloatRegister, 0b0100111, 0b010);
@@ -1938,9 +1938,9 @@ enum Nf {
}
INSN(rev8, 0b0010011, 0b101, 0b011010111000);
- INSN(sext_b, 0b0010011, 0b001, 0b011000000100);
- INSN(sext_h, 0b0010011, 0b001, 0b011000000101);
- INSN(zext_h, 0b0111011, 0b100, 0b000010000000);
+ INSN(_sext_b, 0b0010011, 0b001, 0b011000000100);
+ INSN(_sext_h, 0b0010011, 0b001, 0b011000000101);
+ INSN(_zext_h, 0b0111011, 0b100, 0b000010000000);
INSN(clz, 0b0010011, 0b001, 0b011000000000);
INSN(clzw, 0b0011011, 0b001, 0b011000000000);
INSN(ctz, 0b0010011, 0b001, 0b011000000001);
@@ -2652,6 +2652,15 @@ enum Nf {
return UseRVC && in_compressible_region();
}
+ bool do_compress_zcb(Register reg1 = noreg, Register reg2 = noreg) const {
+ return do_compress() && VM_Version::ext_Zcb.enabled() &&
+ (reg1 == noreg || reg1->is_compressed_valid()) && (reg2 == noreg || reg2->is_compressed_valid());
+ }
+
+ bool do_compress_zcb_zbb(Register reg1 = noreg, Register reg2 = noreg) const {
+ return do_compress_zcb(reg1, reg2) && UseZbb;
+ }
+
// --------------------------
// Load/store register
// --------------------------
@@ -2986,6 +2995,238 @@ enum Nf {
#undef INSN
+// -------------- ZCB Instruction Definitions --------------
+// Zcb additional C instructions
+ private:
+ // Format CLH, c.lh/c.lhu
+ template
+ void c_lh_if(Register Rd_Rs2, Register Rs1, uint32_t uimm) {
+ assert_cond(uimm == 0 || uimm == 2);
+ assert_cond(do_compress_zcb(Rd_Rs2, Rs1));
+ uint16_t insn = 0;
+ c_patch((address)&insn, 1, 0, 0b00);
+ c_patch_compressed_reg((address)&insn, 2, Rd_Rs2);
+ c_patch((address)&insn, 5, 5, (uimm & nth_bit(1)) >> 1);
+ c_patch((address)&insn, 6, 6, Unsigned ? 0 : 1);
+ c_patch_compressed_reg((address)&insn, 7, Rs1);
+ c_patch((address)&insn, 12, 10, 0b001);
+ c_patch((address)&insn, 15, 13, 0b100);
+ emit_int16(insn);
+ }
+
+ template
+ void lh_c_mux(Register Rd_Rs2, Register Rs1, const int32_t uimm) {
+ if (do_compress_zcb(Rd_Rs2, Rs1) &&
+ (uimm == 0 || uimm == 2)) {
+ c_lh_if(Rd_Rs2, Rs1, uimm);
+ } else {
+ if (Unsigned) {
+ _lhu(Rd_Rs2, Rs1, uimm);
+ } else {
+ _lh(Rd_Rs2, Rs1, uimm);
+ }
+ }
+ }
+
+ // Format CU, c.[sz]ext.*, c.not
+ template
+ void c_u_if(Register Rs1) {
+ assert_cond(do_compress_zcb(Rs1));
+ uint16_t insn = 0;
+ c_patch((address)&insn, 1, 0, 0b01);
+ c_patch((address)&insn, 4, 2, InstructionType);
+ c_patch((address)&insn, 6, 5, 0b11);
+ c_patch_compressed_reg((address)&insn, 7, Rs1);
+ c_patch((address)&insn, 12, 10, 0b111);
+ c_patch((address)&insn, 15, 13, 0b100);
+ emit_int16(insn);
+ }
+
+ public:
+
+ // Prerequisites: Zcb
+ void c_lh(Register Rd_Rs2, Register Rs1, const int32_t uimm) { c_lh_if(Rd_Rs2, Rs1, uimm); }
+ void lh(Register Rd_Rs2, Register Rs1, const int32_t uimm) { lh_c_mux(Rd_Rs2, Rs1, uimm); }
+
+ // Prerequisites: Zcb
+ void c_lhu(Register Rd_Rs2, Register Rs1, const int32_t uimm) { c_lh_if(Rd_Rs2, Rs1, uimm); }
+ void lhu(Register Rd_Rs2, Register Rs1, const int32_t uimm) { lh_c_mux(Rd_Rs2, Rs1, uimm); }
+
+ // Prerequisites: Zcb
+ // Format CLB, single instruction
+ void c_lbu(Register Rd_Rs2, Register Rs1, uint32_t uimm) {
+ assert_cond(uimm <= 3);
+ assert_cond(do_compress_zcb(Rd_Rs2, Rs1));
+ uint16_t insn = 0;
+ c_patch((address)&insn, 1, 0, 0b00);
+ c_patch_compressed_reg((address)&insn, 2, Rd_Rs2);
+ c_patch((address)&insn, 5, 5, (uimm & nth_bit(1)) >> 1);
+ c_patch((address)&insn, 6, 6, (uimm & nth_bit(0)) >> 0);
+ c_patch_compressed_reg((address)&insn, 7, Rs1);
+ c_patch((address)&insn, 12, 10, 0b000);
+ c_patch((address)&insn, 15, 13, 0b100);
+ emit_int16(insn);
+ }
+
+ void lbu(Register Rd_Rs2, Register Rs1, const int32_t uimm) {
+ if (do_compress_zcb(Rd_Rs2, Rs1) &&
+ uimm >= 0 && uimm <= 3) {
+ c_lbu(Rd_Rs2, Rs1, uimm);
+ } else {
+ _lbu(Rd_Rs2, Rs1, uimm);
+ }
+ }
+
+ // Prerequisites: Zcb
+ // Format CSB, single instruction
+ void c_sb(Register Rd_Rs2, Register Rs1, uint32_t uimm) {
+ assert_cond(uimm <= 3);
+ assert_cond(do_compress_zcb(Rd_Rs2, Rs1));
+ uint16_t insn = 0;
+ c_patch((address)&insn, 1, 0, 0b00);
+ c_patch_compressed_reg((address)&insn, 2, Rd_Rs2);
+ c_patch((address)&insn, 5, 5, (uimm & nth_bit(1)) >> 1);
+ c_patch((address)&insn, 6, 6, (uimm & nth_bit(0)) >> 0);
+ c_patch_compressed_reg((address)&insn, 7, Rs1);
+ c_patch((address)&insn, 12, 10, 0b010);
+ c_patch((address)&insn, 15, 13, 0b100);
+ emit_int16(insn);
+ }
+
+ void sb(Register Rd_Rs2, Register Rs1, const int32_t uimm) {
+ if (do_compress_zcb(Rd_Rs2, Rs1) &&
+ uimm >= 0 && uimm <= 3) {
+ c_sb(Rd_Rs2, Rs1, uimm);
+ } else {
+ _sb(Rd_Rs2, Rs1, uimm);
+ }
+ }
+
+ // Prerequisites: Zcb
+ // Format CSH, single instruction
+ void c_sh(Register Rd_Rs2, Register Rs1, uint32_t uimm) {
+ assert_cond(uimm == 0 || uimm == 2);
+ assert_cond(do_compress_zcb(Rd_Rs2, Rs1));
+ uint16_t insn = 0;
+ c_patch((address)&insn, 1, 0, 0b00);
+ c_patch_compressed_reg((address)&insn, 2, Rd_Rs2);
+ c_patch((address)&insn, 5, 5, (uimm & nth_bit(1)) >> 1);
+ c_patch((address)&insn, 6, 6, 0);
+ c_patch_compressed_reg((address)&insn, 7, Rs1);
+ c_patch((address)&insn, 12, 10, 0b011);
+ c_patch((address)&insn, 15, 13, 0b100);
+ emit_int16(insn);
+ }
+
+ void sh(Register Rd_Rs2, Register Rs1, const int32_t uimm) {
+ if (do_compress_zcb(Rd_Rs2, Rs1) &&
+ (uimm == 0 || uimm == 2)) {
+ c_sh(Rd_Rs2, Rs1, uimm);
+ } else {
+ _sh(Rd_Rs2, Rs1, uimm);
+ }
+ }
+
+ // Prerequisites: Zcb
+ // Format CS
+ void c_zext_b(Register Rs1) {
+ assert_cond(do_compress_zcb(Rs1));
+ c_u_if<0b000>(Rs1);
+ }
+
+ // Prerequisites: Zbb
+ void sext_b(Register Rd_Rs2, Register Rs1) {
+ assert_cond(UseZbb);
+ if (do_compress_zcb_zbb(Rd_Rs2, Rs1) && (Rd_Rs2 == Rs1)) {
+ c_sext_b(Rd_Rs2);
+ } else {
+ _sext_b(Rd_Rs2, Rs1);
+ }
+ }
+
+ // Prerequisites: Zcb, Zbb
+ // Format CS
+ void c_sext_b(Register Rs1) {
+ c_u_if<0b001>(Rs1);
+ }
+
+ // Prerequisites: Zbb
+ void zext_h(Register Rd_Rs2, Register Rs1) {
+ assert_cond(UseZbb);
+ if (do_compress_zcb_zbb(Rd_Rs2, Rs1) && (Rd_Rs2 == Rs1)) {
+ c_zext_h(Rd_Rs2);
+ } else {
+ _zext_h(Rd_Rs2, Rs1);
+ }
+ }
+
+ // Prerequisites: Zcb, Zbb
+ // Format CS
+ void c_zext_h(Register Rs1) {
+ c_u_if<0b010>(Rs1);
+ }
+
+ // Prerequisites: Zbb
+ void sext_h(Register Rd_Rs2, Register Rs1) {
+ assert_cond(UseZbb);
+ if (do_compress_zcb_zbb(Rd_Rs2, Rs1) && (Rd_Rs2 == Rs1)) {
+ c_sext_h(Rd_Rs2);
+ } else {
+ _sext_h(Rd_Rs2, Rs1);
+ }
+ }
+
+ // Prerequisites: Zcb, Zbb
+ // Format CS
+ void c_sext_h(Register Rs1) {
+ c_u_if<0b011>(Rs1);
+ }
+
+ // Prerequisites: Zcb, Zba
+ // Format CS
+ void c_zext_w(Register Rs1) {
+ c_u_if<0b100>(Rs1);
+ }
+
+ // Prerequisites: Zcb
+ // Format CS
+ void c_not(Register Rs1) {
+ c_u_if<0b101>(Rs1);
+ }
+
+ // Prerequisites: Zcb (M or Zmmul)
+ // Format CA, c.mul
+ void c_mul(Register Rd_Rs1, Register Rs2) {
+ uint16_t insn = 0;
+ c_patch((address)&insn, 1, 0, 0b01);
+ c_patch_compressed_reg((address)&insn, 2, Rs2);
+ c_patch((address)&insn, 6, 5, 0b10);
+ c_patch_compressed_reg((address)&insn, 7, Rd_Rs1);
+ c_patch((address)&insn, 12, 10, 0b111);
+ c_patch((address)&insn, 15, 13, 0b100);
+ emit_int16(insn);
+ }
+
+ void mul(Register Rd, Register Rs1, Register Rs2) {
+ if (Rd != Rs1 && Rd != Rs2) {
+ // Three registers needed without a mv, emit uncompressed
+ _mul(Rd, Rs1, Rs2);
+ return;
+ }
+
+ // Rd is either Rs1 or Rs2
+ if (!do_compress_zcb(Rs2, Rs1)) {
+ _mul(Rd, Rs1, Rs2);
+ } else {
+ if (Rd == Rs2) {
+ Rs2 = Rs1;
+ } else {
+ assert(Rd == Rs1, "must be");
+ }
+ c_mul(Rd, Rs2);
+ }
+ }
+
// Stack overflow checking
virtual void bang_stack_with_offset(int offset) { Unimplemented(); }
diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
index 50ad3efbdb450..5008a0c08c219 100644
--- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
+++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
@@ -4678,41 +4678,54 @@ void MacroAssembler::shadd(Register Rd, Register Rs1, Register Rs2, Register tmp
}
void MacroAssembler::zero_extend(Register dst, Register src, int bits) {
- if (UseZba && bits == 32) {
- zext_w(dst, src);
- return;
- }
-
- if (UseZbb && bits == 16) {
- zext_h(dst, src);
- return;
- }
-
- if (bits == 8) {
- zext_b(dst, src);
- } else {
- slli(dst, src, XLEN - bits);
- srli(dst, dst, XLEN - bits);
+ switch (bits) {
+ case 32:
+ if (UseZba) {
+ zext_w(dst, src);
+ return;
+ }
+ break;
+ case 16:
+ if (UseZbb) {
+ zext_h(dst, src);
+ return;
+ }
+ break;
+ case 8:
+ if (UseZbb) {
+ zext_b(dst, src);
+ return;
+ }
+ break;
+ default:
+ break;
}
+ slli(dst, src, XLEN - bits);
+ srli(dst, dst, XLEN - bits);
}
void MacroAssembler::sign_extend(Register dst, Register src, int bits) {
- if (UseZbb) {
- if (bits == 8) {
- sext_b(dst, src);
+ switch (bits) {
+ case 32:
+ sext_w(dst, src);
return;
- } else if (bits == 16) {
- sext_h(dst, src);
- return;
- }
- }
-
- if (bits == 32) {
- sext_w(dst, src);
- } else {
- slli(dst, src, XLEN - bits);
- srai(dst, dst, XLEN - bits);
+ case 16:
+ if (UseZbb) {
+ sext_h(dst, src);
+ return;
+ }
+ break;
+ case 8:
+ if (UseZbb) {
+ sext_b(dst, src);
+ return;
+ }
+ break;
+ default:
+ break;
}
+ slli(dst, src, XLEN - bits);
+ srai(dst, dst, XLEN - bits);
}
void MacroAssembler::cmp_x2i(Register dst, Register src1, Register src2,
diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
index 4724dd85e7801..d283654e6e179 100644
--- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
+++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
@@ -473,7 +473,11 @@ class MacroAssembler: public Assembler {
}
inline void notr(Register Rd, Register Rs) {
- xori(Rd, Rs, -1);
+ if (do_compress_zcb(Rd, Rs) && (Rd == Rs)) {
+ c_not(Rd);
+ } else {
+ xori(Rd, Rs, -1);
+ }
}
inline void neg(Register Rd, Register Rs) {
@@ -489,7 +493,11 @@ class MacroAssembler: public Assembler {
}
inline void zext_b(Register Rd, Register Rs) {
- andi(Rd, Rs, 0xFF);
+ if (do_compress_zcb(Rd, Rs) && (Rd == Rs)) {
+ c_zext_b(Rd);
+ } else {
+ andi(Rd, Rs, 0xFF);
+ }
}
inline void seqz(Register Rd, Register Rs) {
@@ -511,7 +519,12 @@ class MacroAssembler: public Assembler {
// Bit-manipulation extension pseudo instructions
// zero extend word
inline void zext_w(Register Rd, Register Rs) {
- add_uw(Rd, Rs, zr);
+ assert(UseZba, "must be");
+ if (do_compress_zcb(Rd, Rs) && (Rd == Rs)) {
+ c_zext_w(Rd);
+ } else {
+ add_uw(Rd, Rs, zr);
+ }
}
// Floating-point data-processing pseudo instructions
diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp
index 290b44eb0efe9..1ea853284ff15 100644
--- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp
+++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp
@@ -110,6 +110,9 @@ class VM_Version : public Abstract_VM_Version {
// Zic64b Cache blocks must be 64 bytes in size, naturally aligned in the address space.
// Zihintpause Pause instruction HINT
//
+ // Zc Code Size Reduction - Additional compressed instructions.
+ // Zcb Simple code-size saving instructions
+ //
// Other features and settings
// mvendorid Manufactory JEDEC id encoded, ISA vol 2 3.1.2..
// marchid Id for microarch. Mvendorid plus marchid uniquely identify the microarch.
@@ -117,6 +120,8 @@ class VM_Version : public Abstract_VM_Version {
// unaligned_access Unaligned memory accesses (unknown, unspported, emulated, slow, firmware, fast)
// satp mode SATP bits (number of virtual addr bits) mbare, sv39, sv48, sv57, sv64
+ public:
+
#define RV_NO_FLAG_BIT (BitsPerWord+1) // nth_bit will return 0 on values larger than BitsPerWord
// declaration name , extension name, bit pos ,in str, mapped flag)
@@ -137,6 +142,7 @@ class VM_Version : public Abstract_VM_Version {
decl(ext_Zbb , "Zbb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbb)) \
decl(ext_Zbc , "Zbc" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zbs , "Zbs" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbs)) \
+ decl(ext_Zcb , "Zcb" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zicsr , "Zicsr" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zifencei , "Zifencei" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zic64b , "Zic64b" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZic64b)) \
diff --git a/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp b/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp
index 6e93406b1a353..354dbd70bb4e1 100644
--- a/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp
+++ b/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp
@@ -240,6 +240,8 @@ void VM_Version::rivos_features() {
ext_Zbb.enable_feature();
ext_Zbs.enable_feature();
+ ext_Zcb.enable_feature();
+
ext_Zicsr.enable_feature();
ext_Zifencei.enable_feature();
ext_Zic64b.enable_feature();
From 075fed91bd144d94328e198b41ea2946961940e9 Mon Sep 17 00:00:00 2001
From: David Holmes
Date: Tue, 9 Jan 2024 08:19:57 +0000
Subject: [PATCH 030/153] 8323241: jcmd manpage should use lists for argument
lists
Reviewed-by: alanb
---
src/jdk.jcmd/share/man/jcmd.1 | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/jdk.jcmd/share/man/jcmd.1 b/src/jdk.jcmd/share/man/jcmd.1
index f0e14a9dbd2e5..0da1ee6912777 100644
--- a/src/jdk.jcmd/share/man/jcmd.1
+++ b/src/jdk.jcmd/share/man/jcmd.1
@@ -172,11 +172,11 @@ Impact: Low: Depends on code heap size and content.
Holds CodeCache_lock during analysis step, usually sub-second duration.
.PP
\f[I]arguments\f[R]:
-.PP
+.IP \[bu] 2
\f[I]function\f[R]: (Optional) Function to be performed (aggregate,
UsedSpace, FreeSpace, MethodCount, MethodSpace, MethodAge, MethodNames,
discard (STRING, all)
-.PP
+.IP \[bu] 2
\f[I]granularity\f[R]: (Optional) Detail level - smaller value -> more
detail (INT, 4096)
.RE
@@ -202,7 +202,7 @@ Adds compiler directives from a file.
Impact: Low
.PP
\f[I]arguments\f[R]:
-.PP
+.IP \[bu] 2
\f[I]filename\f[R]: The name of the directives file (STRING, no default
value)
.RE
@@ -253,7 +253,7 @@ Write map file for Linux perf tool.
Impact: Low
.PP
\f[I]arguments\f[R]:
-.PP
+.IP \[bu] 2
\f[I]filename\f[R]: (Optional) The name of the map file (STRING, no
default value)
.RE
From 52a6c37558fa970f595067bc1bb5bc2b710c3876 Mon Sep 17 00:00:00 2001
From: Boris Ulasevich
Date: Tue, 9 Jan 2024 10:33:52 +0000
Subject: [PATCH 031/153] 8322858: compiler/c2/aarch64/TestFarJump.java fails
on AArch64 due to unexpected PrintAssembly output
Reviewed-by: aph, thartmann
---
test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java b/test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java
index d461d56d8a390..3fe213122bda6 100644
--- a/test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java
+++ b/test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, BELLSOFT. All rights reserved.
+ * Copyright (c) 2024, BELLSOFT. 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
@@ -89,10 +89,9 @@ static void runVM(boolean bigCodeHeap) throws Exception {
"-Xbatch",
"-XX:+TieredCompilation",
"-XX:+SegmentedCodeCache",
- "-XX:CompileOnly=" + className + "::main",
"-XX:ReservedCodeCacheSize=" + (bigCodeHeap ? "256M" : "200M"),
"-XX:+UnlockDiagnosticVMOptions",
- "-XX:+PrintAssembly",
+ "-XX:CompileCommand=option," + className + "::main,bool,PrintAssembly,true",
className};
ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(procArgs);
From 6e9671a8a87a369c6986854a2c3c32cc9d7027ba Mon Sep 17 00:00:00 2001
From: Albert Mingkun Yang
Date: Tue, 9 Jan 2024 10:37:02 +0000
Subject: [PATCH 032/153] 8323264: Serial: Remove unused
GenerationBlockSizeClosure
Reviewed-by: stefank
---
src/hotspot/share/gc/serial/generation.cpp | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/src/hotspot/share/gc/serial/generation.cpp b/src/hotspot/share/gc/serial/generation.cpp
index 30f1429fd40f2..302f8f231e7be 100644
--- a/src/hotspot/share/gc/serial/generation.cpp
+++ b/src/hotspot/share/gc/serial/generation.cpp
@@ -173,18 +173,6 @@ HeapWord* Generation::block_start(const void* p) const {
return blk._start;
}
-class GenerationBlockSizeClosure : public SpaceClosure {
- public:
- const HeapWord* _p;
- size_t size;
- virtual void do_space(Space* s) {
- if (size == 0 && s->is_in_reserved(_p)) {
- size = s->block_size(_p);
- }
- }
- GenerationBlockSizeClosure(const HeapWord* p) { _p = p; size = 0; }
-};
-
class GenerationBlockIsObjClosure : public SpaceClosure {
public:
const HeapWord* _p;
From 7d42aa15137814761ff314112a055e835a659cf1 Mon Sep 17 00:00:00 2001
From: Pavel Rappo
Date: Tue, 9 Jan 2024 11:31:50 +0000
Subject: [PATCH 033/153] 8310277:
jdk/javadoc/doclet/testMethodCommentAlgorithm/TestMethodCommentsAlgorithm.java
fails with IllegalStateException
Reviewed-by: jjg
---
.../TestMethodCommentsAlgorithm.java | 155 +++++++++---------
1 file changed, 77 insertions(+), 78 deletions(-)
diff --git a/test/langtools/jdk/javadoc/doclet/testMethodCommentAlgorithm/TestMethodCommentsAlgorithm.java b/test/langtools/jdk/javadoc/doclet/testMethodCommentAlgorithm/TestMethodCommentsAlgorithm.java
index 2931ae40f9d7e..3e5d978cc8f7d 100644
--- a/test/langtools/jdk/javadoc/doclet/testMethodCommentAlgorithm/TestMethodCommentsAlgorithm.java
+++ b/test/langtools/jdk/javadoc/doclet/testMethodCommentAlgorithm/TestMethodCommentsAlgorithm.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2024, 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
@@ -31,13 +31,15 @@
* @run main TestMethodCommentsAlgorithm
*/
+import java.io.IOError;
import java.io.IOException;
import java.nio.file.Files;
+import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
-import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
+import java.util.Optional;
import java.util.Set;
import javax.lang.model.element.Modifier;
import javax.lang.model.type.TypeKind;
@@ -109,6 +111,12 @@
* 3. While documentation for java.lang.Object is currently inaccessible outside
* of the JDK, these test mimic what happens when the JDK documentation is
* built.
+ *
+ * Note
+ * ====
+ *
+ * If any of these tests cannot find a valid Object.java file in the test
+ * environment, they will throw jtreg.SkippedException.
*/
public class TestMethodCommentsAlgorithm extends JavadocTester {
@@ -136,20 +144,7 @@ public static void main(String... args) throws Exception {
*/
@Test
public void testMixedHierarchyEquals(Path base) throws Exception {
- Path p = Path.of(System.getProperty("test.src", ".")).toAbsolutePath();
- while (!Files.exists(p.resolve("TEST.ROOT"))) {
- p = p.getParent();
- if (p == null) {
- throw new SkippedException("can't find TEST.ROOT");
- }
- }
- out.println("Test suite root: " + p);
- Path javaBase = p.resolve("../../src/java.base").normalize();
- if (!Files.exists(javaBase)) {
- throw new SkippedException("can't find java.base");
- }
- out.println("java.base: " + javaBase);
-
+ var javaBase = findJavaBase();
for (int i = 1; i < 7; i++) {
mixedHierarchyI(base, javaBase, i);
new OutputChecker("mymodule/x/T1.html").check("""
@@ -265,20 +260,7 @@ private static String generateDocComment(int index, int run, boolean includeComm
*/
@Test
public void testInterfaceHierarchy(Path base) throws Exception {
- Path p = Path.of(System.getProperty("test.src", ".")).toAbsolutePath();
- while (!Files.exists(p.resolve("TEST.ROOT"))) {
- p = p.getParent();
- if (p == null) {
- throw new SkippedException("can't find TEST.ROOT");
- }
- }
- System.err.println("Test suite root: " + p);
- Path javaBase = p.resolve("../../src/java.base").normalize();
- if (!Files.exists(javaBase)) {
- throw new SkippedException("can't find java.base");
- }
- System.err.println("java.base: " + javaBase);
-
+ var javaBase = findJavaBase();
for (int i = 1; i < 6; i++) {
interfaceHierarchyI(base, javaBase, i);
new OutputChecker("mymodule/x/T1.html").check("""
@@ -306,20 +288,7 @@ public void testInterfaceHierarchy(Path base) throws Exception {
*/
@Test
public void testRecursiveInheritDocTagsAreProcessedFirst(Path base) throws Exception {
- Path p = Path.of(System.getProperty("test.src", ".")).toAbsolutePath();
- while (!Files.exists(p.resolve("TEST.ROOT"))) {
- p = p.getParent();
- if (p == null) {
- throw new SkippedException("can't find TEST.ROOT");
- }
- }
- System.err.println("Test suite root: " + p);
- Path javaBase = p.resolve("../../src/java.base").normalize();
- if (!Files.exists(javaBase)) {
- throw new SkippedException("can't find java.base");
- }
- System.err.println("java.base: " + javaBase);
-
+ var javaBase = findJavaBase();
Path src = base.resolve("src");
tb.writeJavaFiles(src.resolve("mymodule"), """
package x;
@@ -418,41 +387,67 @@ public interface T5 {
}
/*
- * Takes a path to the java.base module, finds the Object.java file in
- * there, creates a copy of that file _with the modified doc comment_
- * for Object.equals in the provided destination directory and returns
- * the path to that created copy.
+ * Locates source of the java.base module.
*/
- private Path createPatchedJavaLangObject(Path src, Path dst, String newComment)
- throws IOException {
- if (!Files.isDirectory(src) || !Files.isDirectory(dst)) {
- throw new IllegalArgumentException();
+ private Path findJavaBase() {
+ String testSrc = System.getProperty("test.src");
+ if (testSrc == null) {
+ // shouldn't happen
+ throw new SkippedException("test.src is not set");
}
- var obj = Path.of("java/lang/Object.java");
- List files;
- // ensure Object.java is found and unique
- try (var s = Files.find(src, Integer.MAX_VALUE,
- (p, attr) -> attr.isRegularFile() && p.endsWith(obj))) {
- files = s.limit(2).toList(); // 2 is enough to deduce non-uniqueness
+ Path start;
+ try {
+ start = Path.of(testSrc).toAbsolutePath();
+ } catch (InvalidPathException | IOError e) {
+ throw new SkippedException("Couldn't make sense of '" + testSrc + "'", e);
}
- if (files.size() != 1) {
- throw new IllegalStateException(Arrays.toString(files.toArray()));
+ Path p = start;
+ while (!Files.exists(p.resolve("TEST.ROOT"))) {
+ p = p.getParent();
+ if (p == null) {
+ // shouldn't happen as jtreg won't even run a test without TEST.ROOT
+ throw new SkippedException("Couldn't find TEST.ROOT above '" + start + "'");
+ }
}
- var original = files.get(0);
- out.println("found " + original.toAbsolutePath());
- var source = Files.readString(original);
- var region = findDocCommentRegion(original);
- var newSource = source.substring(0, region.start)
- + newComment
- + source.substring(region.end);
- // create intermediate directories in the destination first, otherwise
- // writeString will throw java.nio.file.NoSuchFileException
- var copy = dst.resolve(src.relativize(original));
- out.println("to be copied to " + copy);
- if (Files.notExists(copy.getParent())) {
- Files.createDirectories(copy.getParent());
+ Path javaBase = p.resolve("../../src/java.base").normalize();
+ out.println("Source for java.base is found at: " + javaBase);
+ return javaBase;
+ }
+
+ /*
+ * Finds java/lang/Object.java rooted at src, creates a copy of that file
+ * _with the modified doc comment_ for Object.equals in dst, and returns
+ * the path to that copy.
+ */
+ private Path createPatchedJavaLangObject(Path src, Path dst, String newComment) {
+ var obj = Path.of("java/lang/Object.java");
+ try {
+ Optional files;
+ try (var s = Files.find(src, Integer.MAX_VALUE,
+ (p, attr) -> attr.isRegularFile() && p.endsWith(obj))) {
+ files = s.findAny();
+ }
+ if (files.isEmpty()) {
+ throw new SkippedException("Couldn't find '" + obj + "' at '" + src + "'");
+ }
+ var original = files.get();
+ out.println("Found '" + obj + "' at " + original.toAbsolutePath());
+ var source = Files.readString(original);
+ var region = findDocCommentRegion(original);
+ var newSource = source.substring(0, region.start)
+ + newComment
+ + source.substring(region.end);
+ // create intermediate directories in the destination first, otherwise
+ // writeString will throw java.nio.file.NoSuchFileException
+ var copy = dst.resolve(src.relativize(original));
+ out.println("To be copied to '" + copy + "'");
+ if (Files.notExists(copy.getParent())) {
+ Files.createDirectories(copy.getParent());
+ }
+ return Files.writeString(copy, newSource, StandardOpenOption.CREATE);
+ } catch (IOException e) {
+ throw new SkippedException("Couldn't create patched '" + obj + "'", e);
}
- return Files.writeString(copy, newSource, StandardOpenOption.CREATE);
}
private static SourceRegion findDocCommentRegion(Path src) throws IOException {
@@ -464,14 +459,18 @@ private static SourceRegion findDocCommentRegion(Path src) throws IOException {
var task = (JavacTask) compiler.getTask(null, null, null, null, null, List.of(fileObject));
Iterator extends CompilationUnitTree> iterator = task.parse().iterator();
if (!iterator.hasNext()) {
- throw new AssertionError();
+ throw new SkippedException("Couldn't parse '" + src + "'");
}
var tree = iterator.next();
var pathToEqualsMethod = findMethod(tree);
+ if (pathToEqualsMethod == null) {
+ throw new SkippedException("Couldn't find the equals method in '" + src + "'");
+ }
var trees = DocTrees.instance(task);
DocCommentTree docCommentTree = trees.getDocCommentTree(pathToEqualsMethod);
- if (docCommentTree == null)
- throw new AssertionError("cannot find the doc comment for java.lang.Object#equals");
+ if (docCommentTree == null) {
+ throw new SkippedException("Couldn't find documentation for the equals method at '" + src + "'");
+ }
var positions = trees.getSourcePositions();
long start = positions.getStartPosition(null, docCommentTree, docCommentTree);
long end = positions.getEndPosition(null, docCommentTree, docCommentTree);
@@ -510,7 +509,7 @@ public Void visitMethod(MethodTree m, Void unused) {
List extends VariableTree> params = m.getParameters();
if (params.size() != 1)
return null;
- var parameterType = params.get(0).getType();
+ var parameterType = params.getFirst().getType();
if (parameterType.getKind() == Tree.Kind.IDENTIFIER &&
((IdentifierTree) parameterType).getName().toString().equals("Object")) {
throw new Result(getCurrentPath());
From 37a61720b60a503a958b35c422ca4f2eb06d62fb Mon Sep 17 00:00:00 2001
From: Pavel Rappo
Date: Tue, 9 Jan 2024 11:36:36 +0000
Subject: [PATCH 034/153] 8322936: Update blessed-modifier-order.sh for
default, sealed, and non-sealed
Reviewed-by: erikj, rriggs, martin
---
bin/blessed-modifier-order.sh | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/bin/blessed-modifier-order.sh b/bin/blessed-modifier-order.sh
index 4e999e02506ca..548a89dbe14b8 100644
--- a/bin/blessed-modifier-order.sh
+++ b/bin/blessed-modifier-order.sh
@@ -1,5 +1,6 @@
#!/bin/bash
#
+# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
# Copyright 2015 Google, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
@@ -26,12 +27,17 @@ usage() {
echo "$0 DIR ..."
echo "Modifies in place all the java source files found"
echo "in the given directories so that all java language modifiers"
- echo "are in the canonical order given by Modifier#toString()."
+ echo "are in the canonical order."
echo "Tries to get it right even within javadoc comments,"
echo "and even if the list of modifiers spans 2 lines."
echo
echo "See:"
- echo "https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Modifier.html#toString-int-"
+ echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.1.1"
+ echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.3.1"
+ echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.4.3"
+ echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.8.3"
+ echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-9.html#jls-9.1.1"
+ echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-9.html#jls-9.4"
echo
echo "Example:"
echo "$0 jdk/src/java.base jdk/test/java/{util,io,lang}"
@@ -46,7 +52,7 @@ for dir in "${dirs[@]}"; do [[ -d "$dir" ]] || usage; done
declare -ar modifiers=(
public protected private
- abstract static final transient
+ abstract default static final sealed non-sealed transient
volatile synchronized native strictfp
)
declare -r SAVE_IFS="$IFS"
From ff499ef79f6bffe95afa17a9aa312ac9f67fba18 Mon Sep 17 00:00:00 2001
From: Lei Zaakjyu
Date: Tue, 9 Jan 2024 13:26:38 +0000
Subject: [PATCH 035/153] 8233443: G1 DetailedUsage class names overly generic
for global namespace
Reviewed-by: ayang, gli, tschatzl
---
src/hotspot/share/gc/g1/g1HeapTransition.cpp | 4 ++--
src/hotspot/share/gc/g1/g1HeapTransition.hpp | 3 +++
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/hotspot/share/gc/g1/g1HeapTransition.cpp b/src/hotspot/share/gc/g1/g1HeapTransition.cpp
index a2097041b2093..4f759b4a6069e 100644
--- a/src/hotspot/share/gc/g1/g1HeapTransition.cpp
+++ b/src/hotspot/share/gc/g1/g1HeapTransition.cpp
@@ -62,7 +62,7 @@ G1HeapTransition::Data::~Data() {
G1HeapTransition::G1HeapTransition(G1CollectedHeap* g1_heap) : _g1_heap(g1_heap), _before(g1_heap) { }
-struct DetailedUsage : public StackObj {
+struct G1HeapTransition::DetailedUsage : public StackObj {
size_t _eden_used;
size_t _survivor_used;
size_t _old_used;
@@ -79,7 +79,7 @@ struct DetailedUsage : public StackObj {
_humongous_region_count(0) {}
};
-class DetailedUsageClosure: public HeapRegionClosure {
+class G1HeapTransition::DetailedUsageClosure: public HeapRegionClosure {
public:
DetailedUsage _usage;
bool do_heap_region(HeapRegion* r) {
diff --git a/src/hotspot/share/gc/g1/g1HeapTransition.hpp b/src/hotspot/share/gc/g1/g1HeapTransition.hpp
index 09d901f283c70..54f87fd3b71dd 100644
--- a/src/hotspot/share/gc/g1/g1HeapTransition.hpp
+++ b/src/hotspot/share/gc/g1/g1HeapTransition.hpp
@@ -31,6 +31,9 @@
class G1CollectedHeap;
class G1HeapTransition {
+ struct DetailedUsage;
+ class DetailedUsageClosure;
+
struct Data {
size_t _eden_length;
size_t _survivor_length;
From 52c7ff1d81940d6d0d1e3dd7ad0447c80708161c Mon Sep 17 00:00:00 2001
From: Thomas Schatzl
Date: Tue, 9 Jan 2024 13:47:32 +0000
Subject: [PATCH 036/153] 8322330: JavadocHelperTest.java OOMEs with Parallel
GC and ZGC
Reviewed-by: ayang, aboldtch
---
.../jdk/internal/shellsupport/doc/JavadocHelperTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/langtools/jdk/internal/shellsupport/doc/JavadocHelperTest.java b/test/langtools/jdk/internal/shellsupport/doc/JavadocHelperTest.java
index 48106face35aa..d8539b8c656c7 100644
--- a/test/langtools/jdk/internal/shellsupport/doc/JavadocHelperTest.java
+++ b/test/langtools/jdk/internal/shellsupport/doc/JavadocHelperTest.java
@@ -30,7 +30,7 @@
* jdk.compiler/com.sun.tools.javac.main
* jdk.compiler/jdk.internal.shellsupport.doc
* @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask
- * @run testng/timeout=900/othervm JavadocHelperTest
+ * @run testng/timeout=900/othervm -Xmx1024m JavadocHelperTest
*/
import java.io.IOException;
From 438ab7c115249d7501edfbb2d3c62e96ae824181 Mon Sep 17 00:00:00 2001
From: Albert Mingkun Yang
Date: Tue, 9 Jan 2024 14:23:42 +0000
Subject: [PATCH 037/153] 8323284: Remove unused FilteringClosure declaration
Reviewed-by: stefank, tschatzl
---
src/hotspot/share/gc/shared/space.hpp | 1 -
src/hotspot/share/oops/oop.hpp | 2 --
2 files changed, 3 deletions(-)
diff --git a/src/hotspot/share/gc/shared/space.hpp b/src/hotspot/share/gc/shared/space.hpp
index 6b8279ec8bd05..541747e38f838 100644
--- a/src/hotspot/share/gc/shared/space.hpp
+++ b/src/hotspot/share/gc/shared/space.hpp
@@ -51,7 +51,6 @@ class Generation;
class ContiguousSpace;
class CardTableRS;
class DirtyCardToOopClosure;
-class FilteringClosure;
// A Space describes a heap area. Class Space is an abstract
// base class.
diff --git a/src/hotspot/share/oops/oop.hpp b/src/hotspot/share/oops/oop.hpp
index 50d8b6041b674..75bc3d9af7216 100644
--- a/src/hotspot/share/oops/oop.hpp
+++ b/src/hotspot/share/oops/oop.hpp
@@ -45,8 +45,6 @@
// Forward declarations.
class OopClosure;
-class FilteringClosure;
-
class PSPromotionManager;
class ParCompactionManager;
From 886386c0396d4cd4f1be24906a77c9dbfc8626e6 Mon Sep 17 00:00:00 2001
From: Lei Zaakjyu
Date: Tue, 9 Jan 2024 15:52:39 +0000
Subject: [PATCH 038/153] 8322890: Directly return in OldPLABSizeConstraintFunc
Reviewed-by: ayang, tschatzl
---
src/hotspot/share/gc/shared/jvmFlagConstraintsGC.cpp | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.cpp b/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.cpp
index 8ac9a3fc783d7..6c6f83177d204 100644
--- a/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.cpp
+++ b/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.cpp
@@ -93,13 +93,7 @@ JVMFlag::Error YoungPLABSizeConstraintFunc(size_t value, bool verbose) {
}
JVMFlag::Error OldPLABSizeConstraintFunc(size_t value, bool verbose) {
- JVMFlag::Error status = JVMFlag::SUCCESS;
-
- {
- status = MinMaxPLABSizeBounds("OldPLABSize", value, verbose);
- }
-
- return status;
+ return MinMaxPLABSizeBounds("OldPLABSize", value, verbose);
}
JVMFlag::Error MinHeapFreeRatioConstraintFunc(uintx value, bool verbose) {
From ee98d262181f5822609674c71c85ad4576ac1632 Mon Sep 17 00:00:00 2001
From: Thomas Schatzl
Date: Tue, 9 Jan 2024 17:03:28 +0000
Subject: [PATCH 039/153] 8323066: gc/g1/TestSkipRebuildRemsetPhase.java fails
with 'Skipping Remembered Set Rebuild.' missing
Reviewed-by: ayang, iwalulya
---
test/hotspot/jtreg/ProblemList.txt | 1 -
.../gc/g1/TestSkipRebuildRemsetPhase.java | 24 ++++++++-----------
2 files changed, 10 insertions(+), 15 deletions(-)
diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt
index d82f4a919fa81..754cf68ba591f 100644
--- a/test/hotspot/jtreg/ProblemList.txt
+++ b/test/hotspot/jtreg/ProblemList.txt
@@ -93,7 +93,6 @@ gc/stress/gclocker/TestGCLockerWithParallel.java 8180622 generic-all
gc/stress/gclocker/TestGCLockerWithSerial.java 8180622 generic-all
gc/stress/gclocker/TestGCLockerWithShenandoah.java 8180622 generic-all
gc/stress/TestStressG1Humongous.java 8286554 windows-x64
-gc/g1/TestSkipRebuildRemsetPhase.java 8323066 linux-aarch64
#############################################################################
diff --git a/test/hotspot/jtreg/gc/g1/TestSkipRebuildRemsetPhase.java b/test/hotspot/jtreg/gc/g1/TestSkipRebuildRemsetPhase.java
index f7f768c9d7dfd..1dc64bf625510 100644
--- a/test/hotspot/jtreg/gc/g1/TestSkipRebuildRemsetPhase.java
+++ b/test/hotspot/jtreg/gc/g1/TestSkipRebuildRemsetPhase.java
@@ -45,7 +45,7 @@ public static void main(String[] args) throws Exception {
"-XX:+UnlockExperimentalVMOptions",
"-XX:+UnlockDiagnosticVMOptions",
"-XX:+WhiteBoxAPI",
- "-XX:G1MixedGCLiveThresholdPercent=20",
+ "-XX:G1MixedGCLiveThresholdPercent=0",
"-Xlog:gc+marking=debug,gc+phases=debug,gc+remset+tracking=trace",
"-Xms10M",
"-Xmx10M",
@@ -58,24 +58,20 @@ public static void main(String[] args) throws Exception {
public static class GCTest {
public static void main(String args[]) throws Exception {
WhiteBox wb = WhiteBox.getWhiteBox();
- // Allocate some memory less than region size.
- Object used = alloc();
+ // Allocate some memory less than region size. Any object is just fine as we set
+ // G1MixedGCLiveThresholdPercent to zero (and no region should be selected).
+ Object used = new byte[2000];
- // Trigger the full GC using the WhiteBox API.
- wb.fullGC(); // full
+ // Trigger the full GC using the WhiteBox API to make sure that at least "used"
+ // has been promoted to old gen.
+ wb.fullGC();
// Memory objects have been promoted to old by full GC.
- // Concurrent cycle should not select any regions for rebuilding
+ // Concurrent cycle should not select any regions for rebuilding and print the
+ // appropriate message.
wb.g1RunConcurrentGC();
System.out.println(used);
}
-
- private static Object alloc() {
- // Since G1MixedGCLiveThresholdPercent is 20%, make sure to allocate object larger than that
- // so that it will not be collected and the expected message printed.
- final int objectSize = WhiteBox.getWhiteBox().g1RegionSize() / 3;
- Object ret = new byte[objectSize];
- return ret;
- }
}
}
+
From dd8ae616437398f957f9b4f09cf2c7f1d0bd0938 Mon Sep 17 00:00:00 2001
From: Alex Menkov
Date: Tue, 9 Jan 2024 19:31:03 +0000
Subject: [PATCH 040/153] 8322237: Heap dump contains duplicate thread records
for mounted virtual threads
Reviewed-by: dholmes, sspitsyn
---
src/hotspot/share/services/heapDumper.cpp | 18 +++++++++++++++++-
.../vthread/HeapDump/VThreadInHeapDump.java | 19 ++++++++++++++++++-
2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/src/hotspot/share/services/heapDumper.cpp b/src/hotspot/share/services/heapDumper.cpp
index a46101f6d8d1d..add86b338deef 100644
--- a/src/hotspot/share/services/heapDumper.cpp
+++ b/src/hotspot/share/services/heapDumper.cpp
@@ -1641,6 +1641,19 @@ class ThreadDumper : public CHeapObj {
&& java_lang_VirtualThread::state(vt) != java_lang_VirtualThread::TERMINATED;
}
+ static bool is_vthread_mounted(oop vt) {
+ // The code should be consistent with the "mounted virtual thread" case
+ // (VM_HeapDumper::dump_stack_traces(), ThreadDumper::get_top_frame()).
+ // I.e. virtual thread is mounted if its carrierThread is not null
+ // and is_vthread_mounted() for the carrier thread returns true.
+ oop carrier_thread = java_lang_VirtualThread::carrier_thread(vt);
+ if (carrier_thread == nullptr) {
+ return false;
+ }
+ JavaThread* java_thread = java_lang_Thread::thread(carrier_thread);
+ return java_thread->is_vthread_mounted();
+ }
+
ThreadDumper(ThreadType thread_type, JavaThread* java_thread, oop thread_oop);
// affects frame_count
@@ -1918,7 +1931,10 @@ void HeapObjectDumper::do_object(oop o) {
if (o->is_instance()) {
// create a HPROF_GC_INSTANCE record for each object
DumperSupport::dump_instance(writer(), o, &_class_cache);
- if (java_lang_VirtualThread::is_instance(o) && ThreadDumper::should_dump_vthread(o)) {
+ // If we encounter an unmounted virtual thread it needs to be dumped explicitly
+ // (mounted virtual threads are dumped with their carriers).
+ if (java_lang_VirtualThread::is_instance(o)
+ && ThreadDumper::should_dump_vthread(o) && !ThreadDumper::is_vthread_mounted(o)) {
_vthread_dumper->dump_vthread(o, writer());
}
} else if (o->is_objArray()) {
diff --git a/test/hotspot/jtreg/serviceability/jvmti/vthread/HeapDump/VThreadInHeapDump.java b/test/hotspot/jtreg/serviceability/jvmti/vthread/HeapDump/VThreadInHeapDump.java
index 7fe5abb800fd2..2243a1d37b6ba 100644
--- a/test/hotspot/jtreg/serviceability/jvmti/vthread/HeapDump/VThreadInHeapDump.java
+++ b/test/hotspot/jtreg/serviceability/jvmti/vthread/HeapDump/VThreadInHeapDump.java
@@ -26,7 +26,9 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -223,11 +225,22 @@ private static void verifyDump(File dumpFile) throws Exception {
// Log all threads with stack traces and stack references.
List threads = snapshot.getThreads();
List roots = Collections.list(snapshot.getRoots());
+ // And detect thread object duplicates.
+ Set uniqueThreads = new HashSet<>();
+
log("Threads:");
for (ThreadObject thread: threads) {
+ JavaHeapObject threadObj = snapshot.findThing(thread.getId());
+ JavaClass threadClass = threadObj.getClazz();
StackTrace st = thread.getStackTrace();
StackFrame[] frames = st.getFrames();
- log("thread " + thread.getIdString() + ", " + frames.length + " frames");
+ log("thread " + thread.getIdString() + " (" + threadClass.getName() + "), " + frames.length + " frames");
+
+ if (uniqueThreads.contains(thread.getId())) {
+ log(" - ERROR: duplicate");
+ } else {
+ uniqueThreads.add(thread.getId());
+ }
List stackRoots = findStackRoot(roots, thread);
for (int i = 0; i < frames.length; i++) {
@@ -250,6 +263,10 @@ private static void verifyDump(File dumpFile) throws Exception {
}
}
+ if (threads.size() != uniqueThreads.size()) {
+ throw new RuntimeException("Thread duplicates detected (" + (threads.size() - uniqueThreads.size()) + ")");
+ }
+
// Verify objects from thread stacks are dumped.
test(snapshot, VThreadInHeapDumpTarg.VThreadMountedReferenced.class);
test(snapshot, VThreadInHeapDumpTarg.PThreadReferenced.class);
From bc05893f820ff8158897f84b9d2fdaed2cd1661b Mon Sep 17 00:00:00 2001
From: Albert Mingkun Yang
Date: Tue, 9 Jan 2024 19:37:28 +0000
Subject: [PATCH 041/153] 8323318: Remove unused Space::is_free_block
Reviewed-by: tschatzl
---
src/hotspot/share/gc/shared/space.cpp | 4 ----
src/hotspot/share/gc/shared/space.hpp | 5 -----
2 files changed, 9 deletions(-)
diff --git a/src/hotspot/share/gc/shared/space.cpp b/src/hotspot/share/gc/shared/space.cpp
index b6dc4e1e7d8f2..67d3ad5338388 100644
--- a/src/hotspot/share/gc/shared/space.cpp
+++ b/src/hotspot/share/gc/shared/space.cpp
@@ -74,10 +74,6 @@ void ContiguousSpace::clear(bool mangle_space) {
}
}
-bool ContiguousSpace::is_free_block(const HeapWord* p) const {
- return p >= _top;
-}
-
#ifndef PRODUCT
void ContiguousSpace::set_top_for_allocations(HeapWord* v) {
diff --git a/src/hotspot/share/gc/shared/space.hpp b/src/hotspot/share/gc/shared/space.hpp
index 541747e38f838..8299a7e628913 100644
--- a/src/hotspot/share/gc/shared/space.hpp
+++ b/src/hotspot/share/gc/shared/space.hpp
@@ -133,9 +133,6 @@ class Space: public CHeapObj {
// given address.
bool is_in_reserved(const void* p) const { return _bottom <= p && p < _end; }
- // Returns true iff the given block is not allocated.
- virtual bool is_free_block(const HeapWord* p) const = 0;
-
// Test whether p is double-aligned
static bool is_aligned(void* p) {
return ::is_aligned(p, sizeof(double));
@@ -273,8 +270,6 @@ class ContiguousSpace: public Space {
size_t used() const override { return byte_size(bottom(), top()); }
size_t free() const override { return byte_size(top(), end()); }
- bool is_free_block(const HeapWord* p) const override;
-
// In a contiguous space we have a more obvious bound on what parts
// contain objects.
MemRegion used_region() const override { return MemRegion(bottom(), top()); }
From f3be138eb80c9e7f6cc21afb75cda9e49b667c8a Mon Sep 17 00:00:00 2001
From: Mandy Chung
Date: Tue, 9 Jan 2024 22:04:02 +0000
Subject: [PATCH 042/153] 8322809: SystemModulesMap::classNames and moduleNames
arrays do not match the order
Reviewed-by: alanb
---
.../internal/plugins/SystemModulesPlugin.java | 13 +-
.../ModuleMainClassTest.java | 145 ++++++++++++++++++
.../src/com.foo/com/foo/Main.java | 53 +++++++
.../src/com.foo/module-info.java | 27 ++++
.../src/net.foo/module-info.java | 26 ++++
.../src/net.foo/net/foo/Main.java | 54 +++++++
6 files changed, 313 insertions(+), 5 deletions(-)
create mode 100644 test/jdk/tools/jlink/plugins/SystemModuleDescriptors/ModuleMainClassTest.java
create mode 100644 test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/com.foo/com/foo/Main.java
create mode 100644 test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/com.foo/module-info.java
create mode 100644 test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/net.foo/module-info.java
create mode 100644 test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/net.foo/net/foo/Main.java
diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java
index 735c969a88603..40693b33d6db2 100644
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2024, 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
@@ -1827,6 +1827,9 @@ private String genSystemModulesMapClass(ClassDesc allSystemModules,
// write the class file to the pool as a resource
String rn = "/java.base/" + SYSTEM_MODULES_MAP_CLASSNAME + ".class";
+ // sort the map of module name to the class name of the generated SystemModules class
+ List> systemModulesMap = map.entrySet()
+ .stream().sorted(Map.Entry.comparingByKey()).toList();
ResourcePoolEntry e = ResourcePoolEntry.create(rn, ClassFile.of().build(
CD_SYSTEM_MODULES_MAP,
clb -> clb.withFlags(ACC_FINAL + ACC_SUPER)
@@ -1877,10 +1880,10 @@ private String genSystemModulesMapClass(ClassDesc allSystemModules,
cob.anewarray(CD_String);
int index = 0;
- for (String moduleName : sorted(map.keySet())) {
+ for (Map.Entry entry : systemModulesMap) {
cob.dup() // arrayref
.constantInstruction(index)
- .constantInstruction(moduleName)
+ .constantInstruction(entry.getKey())
.aastore();
index++;
}
@@ -1898,10 +1901,10 @@ private String genSystemModulesMapClass(ClassDesc allSystemModules,
.anewarray(CD_String);
int index = 0;
- for (String className : sorted(map.values())) {
+ for (Map.Entry entry : systemModulesMap) {
cob.dup() // arrayref
.constantInstruction(index)
- .constantInstruction(className.replace('/', '.'))
+ .constantInstruction(entry.getValue().replace('/', '.'))
.aastore();
index++;
}
diff --git a/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/ModuleMainClassTest.java b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/ModuleMainClassTest.java
new file mode 100644
index 0000000000000..ca7e2bc5f3009
--- /dev/null
+++ b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/ModuleMainClassTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2024, 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.
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.spi.ToolProvider;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import jdk.test.lib.compiler.CompilerUtils;
+import jdk.test.lib.util.FileUtils;
+
+import static jdk.test.lib.process.ProcessTools.*;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.BeforeAll;
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @test
+ * @bug 8322809
+ * @library /test/lib
+ * @modules jdk.compiler jdk.jlink
+ * @build jdk.test.lib.compiler.CompilerUtils
+ * jdk.test.lib.process.ProcessTools
+ * jdk.test.lib.util.FileUtils
+ * ModuleMainClassTest
+ * @run junit ModuleMainClassTest
+ */
+
+public class ModuleMainClassTest {
+ private static final String JAVA_HOME = System.getProperty("java.home");
+ private static final String TEST_SRC = System.getProperty("test.src");
+
+ private static final Path SRC_DIR = Path.of(TEST_SRC, "src");
+ private static final Path MODS_DIR = Path.of("mods");
+ private static final Path JMODS_DIR = Path.of("jmods");
+
+ private static final Path IMAGE = Path.of("image");
+
+ // the module names are sorted by the plugin and so these names cover
+ // the cases that are before and after the elements of `jdk.*` modules
+ // with main classes
+ private static String[] modules = new String[] {"com.foo", "net.foo"};
+
+ private static boolean hasJmods() {
+ if (!Files.exists(Paths.get(JAVA_HOME, "jmods"))) {
+ System.err.println("Test skipped. NO jmods directory");
+ return false;
+ }
+ return true;
+ }
+
+ @BeforeAll
+ public static void compileAll() throws Throwable {
+ if (!hasJmods()) return;
+
+ for (String mn : modules) {
+ Path msrc = SRC_DIR.resolve(mn);
+ assertTrue(CompilerUtils.compile(msrc, MODS_DIR,
+ "--module-source-path", SRC_DIR.toString(),
+ "--add-exports", "java.base/jdk.internal.module=" + mn));
+ }
+
+ if (Files.exists(IMAGE)) {
+ FileUtils.deleteFileTreeUnchecked(IMAGE);
+ }
+
+ // create JMOD files
+ Files.createDirectories(JMODS_DIR);
+ Stream.of(modules).forEach(mn ->
+ assertTrue(jmod("create",
+ "--class-path", MODS_DIR.resolve(mn).toString(),
+ "--main-class", mn + ".Main",
+ JMODS_DIR.resolve(mn + ".jmod").toString()) == 0)
+ );
+
+ // the run-time image created will have 4 modules with main classes
+ createImage(IMAGE, "com.foo");
+ }
+
+ @Test
+ public void testComFoo() throws Exception {
+ if (!hasJmods()) return;
+
+ Path java = IMAGE.resolve("bin").resolve("java");
+ assertTrue(executeProcess(java.toString(),
+ "-m", "com.foo")
+ .outputTo(System.out)
+ .errorTo(System.out)
+ .getExitValue() == 0);
+ }
+
+ @Test
+ public void testNetFoo() throws Exception {
+ if (!hasJmods()) return;
+
+ Path java = IMAGE.resolve("bin").resolve("java");
+ assertTrue(executeProcess(java.toString(),
+ "-m", "net.foo")
+ .outputTo(System.out)
+ .errorTo(System.out)
+ .getExitValue() == 0);
+ }
+
+ static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink")
+ .orElseThrow(() -> new RuntimeException("jlink tool not found"));
+
+ static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod")
+ .orElseThrow(() -> new RuntimeException("jmod tool not found"));
+
+ private static void createImage(Path outputDir, String... modules) throws Throwable {
+ assertTrue(JLINK_TOOL.run(System.out, System.out,
+ "--output", outputDir.toString(),
+ "--add-modules", Arrays.stream(modules).collect(Collectors.joining(",")),
+ "--module-path", JMODS_DIR.toString()) == 0);
+ }
+
+ private static int jmod(String... options) {
+ System.out.println("jmod " + Arrays.asList(options));
+ return JMOD_TOOL.run(System.out, System.out, options);
+ }
+}
diff --git a/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/com.foo/com/foo/Main.java b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/com.foo/com/foo/Main.java
new file mode 100644
index 0000000000000..f8b230647fabe
--- /dev/null
+++ b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/com.foo/com/foo/Main.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2024, 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 com.foo;
+
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleFinder;
+import java.util.stream.Stream;
+
+/**
+ * Sanity test if SystemModules pre-resolved at link-time for com.foo
+ * with main class is loaded properly.
+ */
+public class Main {
+ public static void main(String... args) throws Exception {
+ ModuleDescriptor md = Main.class.getModule().getDescriptor();
+ System.out.println(md);
+
+ checkMainClass("com.foo", "com.foo.Main");
+ checkMainClass("net.foo", "net.foo.Main");
+ Stream.of("jdk.httpserver", "jdk.jfr").forEach(mn ->
+ ModuleFinder.ofSystem().find(mn).get().descriptor().mainClass()
+ .orElseThrow(() -> new RuntimeException(mn + " no main class"))
+ );
+ }
+
+ static void checkMainClass(String mn, String mainClass) {
+ String cn = ModuleFinder.ofSystem().find(mn).get().descriptor().mainClass().get();
+ if (!cn.equals(mainClass)) {
+ throw new RuntimeException("Mismatched main class of module " + mn + ": " + cn + " expected: " + mainClass);
+ }
+ }
+}
diff --git a/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/com.foo/module-info.java b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/com.foo/module-info.java
new file mode 100644
index 0000000000000..99107602506c7
--- /dev/null
+++ b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/com.foo/module-info.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2024, 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.
+ */
+
+module com.foo {
+ requires jdk.httpserver;
+ requires net.foo;
+}
diff --git a/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/net.foo/module-info.java b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/net.foo/module-info.java
new file mode 100644
index 0000000000000..360a989d9b339
--- /dev/null
+++ b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/net.foo/module-info.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2024, 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.
+ */
+
+module net.foo {
+ requires jdk.jfr;
+}
diff --git a/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/net.foo/net/foo/Main.java b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/net.foo/net/foo/Main.java
new file mode 100644
index 0000000000000..c147923e75a0d
--- /dev/null
+++ b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/net.foo/net/foo/Main.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2024, 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 net.foo;
+
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleFinder;
+import java.util.stream.Stream;
+
+/**
+ * Sanity test if SystemModules pre-resolved at link-time for net.foo
+ * with main class is loaded properly.
+ */
+public class Main {
+ public static void main(String... args) throws Exception {
+ ModuleDescriptor md = Main.class.getModule().getDescriptor();
+ System.out.println(md);
+
+ checkMainClass("com.foo", "com.foo.Main");
+ checkMainClass("net.foo", "net.foo.Main");
+ Stream.of("jdk.httpserver", "jdk.jfr").forEach(mn ->
+ ModuleFinder.ofSystem().find(mn).get().descriptor().mainClass()
+ .orElseThrow(() -> new RuntimeException(mn + " no main class"))
+ );
+ }
+
+ static void checkMainClass(String mn, String mainClass) {
+ String cn = ModuleFinder.ofSystem().find(mn).get().descriptor().mainClass().get();
+ if (!cn.equals(mainClass)) {
+ throw new RuntimeException("Mismatched main class of module " + mn + ": " + cn + " expected: " + mainClass);
+ }
+ }
+
+}
From aba19334eaeb46d37169cddeef929b13e050a60e Mon Sep 17 00:00:00 2001
From: Sergey Bylokhov
Date: Tue, 9 Jan 2024 22:05:37 +0000
Subject: [PATCH 043/153] 8323210: Update the usage of cmsFLAGS_COPY_ALPHA
Reviewed-by: prr
---
src/java.desktop/share/native/liblcms/LCMS.c | 9 +++++++--
.../cmm/ColorConvertOp/ColCvtAlphaDifferentSrcDst.java | 2 +-
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/src/java.desktop/share/native/liblcms/LCMS.c b/src/java.desktop/share/native/liblcms/LCMS.c
index 1295d6df356d4..5cf7ee6c43629 100644
--- a/src/java.desktop/share/native/liblcms/LCMS.c
+++ b/src/java.desktop/share/native/liblcms/LCMS.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2024, 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
@@ -177,8 +177,13 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
}
}
+ cmsUInt32Number dwFlags = 0;
+ if (T_EXTRA(inFormatter) > 0 && T_EXTRA(outFormatter) > 0) {
+ dwFlags |= cmsFLAGS_COPY_ALPHA;
+ }
+
sTrans = cmsCreateMultiprofileTransform(iccArray, j,
- inFormatter, outFormatter, renderingIntent, cmsFLAGS_COPY_ALPHA);
+ inFormatter, outFormatter, renderingIntent, dwFlags);
(*env)->ReleaseLongArrayElements(env, profileIDs, ids, 0);
diff --git a/test/jdk/sun/java2d/cmm/ColorConvertOp/ColCvtAlphaDifferentSrcDst.java b/test/jdk/sun/java2d/cmm/ColorConvertOp/ColCvtAlphaDifferentSrcDst.java
index 31db9d1a38083..22868ffaf3c11 100644
--- a/test/jdk/sun/java2d/cmm/ColorConvertOp/ColCvtAlphaDifferentSrcDst.java
+++ b/test/jdk/sun/java2d/cmm/ColorConvertOp/ColCvtAlphaDifferentSrcDst.java
@@ -52,7 +52,7 @@
/*
* @test
- * @bug 8012229 8300725 8279216
+ * @bug 8012229 8300725 8279216 8323210
* @summary one more test to check the alpha channel
*/
public final class ColCvtAlphaDifferentSrcDst {
From e9f7db304559cbc8e2b46ea30496d3c570569f4c Mon Sep 17 00:00:00 2001
From: Kim Barrett
Date: Tue, 9 Jan 2024 22:26:17 +0000
Subject: [PATCH 044/153] 8322880: Eliminate -Wparentheses warnings in arm32
code
Reviewed-by: shade, dholmes
---
src/hotspot/cpu/arm/arm.ad | 4 ++--
src/hotspot/cpu/arm/assembler_arm.hpp | 4 ++--
src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp | 6 +++---
src/hotspot/cpu/arm/frame_arm.inline.hpp | 4 ++--
src/hotspot/cpu/arm/nativeInst_arm_32.cpp | 4 ++--
src/hotspot/cpu/arm/nativeInst_arm_32.hpp | 4 ++--
6 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/src/hotspot/cpu/arm/arm.ad b/src/hotspot/cpu/arm/arm.ad
index c4197235987d5..e31ad91613a1a 100644
--- a/src/hotspot/cpu/arm/arm.ad
+++ b/src/hotspot/cpu/arm/arm.ad
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2008, 2024, 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
@@ -9193,7 +9193,7 @@ instruct clear_array(iRegX cnt, iRegP base, iRegI temp, iRegX zero, Universe dum
ins_encode %{
__ mov($zero$$Register, 0);
__ mov($temp$$Register, $cnt$$Register);
- Label(loop);
+ Label loop;
__ bind(loop);
__ subs($temp$$Register, $temp$$Register, 4);
__ str($zero$$Register, Address($base$$Register, $temp$$Register), ge);
diff --git a/src/hotspot/cpu/arm/assembler_arm.hpp b/src/hotspot/cpu/arm/assembler_arm.hpp
index b1b4199e88de0..6a3092f7b3b91 100644
--- a/src/hotspot/cpu/arm/assembler_arm.hpp
+++ b/src/hotspot/cpu/arm/assembler_arm.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, 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
@@ -175,7 +175,7 @@ class Address {
if (_index == noreg) {
assert(-256 < _disp && _disp < 256, "encoding constraint");
return _mode | up(_disp) << 23 | 1 << 22 | _base->encoding() << 16 |
- (abs(_disp) & 0xf0) << 4 | abs(_disp) & 0x0f;
+ (abs(_disp) & 0xf0) << 4 | (abs(_disp) & 0x0f);
} else {
assert(_index != PC && (_mode == basic_offset || _index != _base), "unpredictable instruction");
assert(_disp == 0 && _shift == lsl && _shift_imm == 0, "encoding constraint");
diff --git a/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp b/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp
index 72993b3211f9d..999309c02258d 100644
--- a/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp
+++ b/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, 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
@@ -2640,8 +2640,8 @@ void LIR_Assembler::rt_call(LIR_Opr result, address dest, const LIR_OprList* arg
void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info) {
- assert(src->is_double_cpu() && dest->is_address() ||
- src->is_address() && dest->is_double_cpu(),
+ assert((src->is_double_cpu() && dest->is_address()) ||
+ (src->is_address() && dest->is_double_cpu()),
"Simple move_op is called for all other cases");
int null_check_offset;
diff --git a/src/hotspot/cpu/arm/frame_arm.inline.hpp b/src/hotspot/cpu/arm/frame_arm.inline.hpp
index 9191d03baf0ec..43cc523658b5a 100644
--- a/src/hotspot/cpu/arm/frame_arm.inline.hpp
+++ b/src/hotspot/cpu/arm/frame_arm.inline.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, 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
@@ -93,7 +93,7 @@ inline bool frame::equal(frame other) const {
&& unextended_sp() == other.unextended_sp()
&& fp() == other.fp()
&& pc() == other.pc();
- assert(!ret || ret && cb() == other.cb() && _deopt_state == other._deopt_state, "inconsistent construction");
+ assert(!ret || (cb() == other.cb() && _deopt_state == other._deopt_state), "inconsistent construction");
return ret;
}
diff --git a/src/hotspot/cpu/arm/nativeInst_arm_32.cpp b/src/hotspot/cpu/arm/nativeInst_arm_32.cpp
index e5e5e89c2002b..429a0c000f637 100644
--- a/src/hotspot/cpu/arm/nativeInst_arm_32.cpp
+++ b/src/hotspot/cpu/arm/nativeInst_arm_32.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, 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
@@ -162,7 +162,7 @@ void NativeMovConstReg::set_data(intptr_t x, address pc) {
unsigned int hi = (unsigned int)(x >> 16);
this->set_encoding((this->encoding() & 0xfff0f000) | (lo & 0xf000) << 4 | (lo & 0xfff));
next->set_encoding((next->encoding() & 0xfff0f000) | (hi & 0xf000) << 4 | (hi & 0xfff));
- } else if (oop_addr == nullptr & metadata_addr == nullptr) {
+ } else if (oop_addr == nullptr && metadata_addr == nullptr) {
// A static ldr_literal (without oop or metadata relocation)
assert(is_ldr_literal(), "must be");
int offset = ldr_offset();
diff --git a/src/hotspot/cpu/arm/nativeInst_arm_32.hpp b/src/hotspot/cpu/arm/nativeInst_arm_32.hpp
index 804292c24b086..a7a51f017d22d 100644
--- a/src/hotspot/cpu/arm/nativeInst_arm_32.hpp
+++ b/src/hotspot/cpu/arm/nativeInst_arm_32.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, 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
@@ -396,7 +396,7 @@ class NativeMovConstReg: public NativeInstruction {
inline NativeMovConstReg* nativeMovConstReg_at(address address) {
NativeInstruction* ni = nativeInstruction_at(address);
assert(ni->is_ldr_literal() || ni->is_pc_rel() ||
- ni->is_movw() && VM_Version::supports_movw(), "must be");
+ (ni->is_movw() && VM_Version::supports_movw()), "must be");
return (NativeMovConstReg*)address;
}
From 28d8149c693a9470bbde4b1a27c4b9be6c5f365c Mon Sep 17 00:00:00 2001
From: Kim Barrett
Date: Tue, 9 Jan 2024 22:33:13 +0000
Subject: [PATCH 045/153] 8323115: x86-32: Incorrect predicates for cmov
instruct transforms with UseSSE
Reviewed-by: shade, thartmann
---
src/hotspot/cpu/x86/x86_32.ad | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/src/hotspot/cpu/x86/x86_32.ad b/src/hotspot/cpu/x86/x86_32.ad
index 45cc785a5394d..f2e9c042b244f 100644
--- a/src/hotspot/cpu/x86/x86_32.ad
+++ b/src/hotspot/cpu/x86/x86_32.ad
@@ -1,5 +1,5 @@
//
-// Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 1997, 2024, 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
@@ -13161,7 +13161,7 @@ instruct cmovPP_reg_LTGE_U(cmpOpU cmp, flagsReg_ulong_LTGE flags, eRegP dst, eRe
// Compare 2 longs and CMOVE doubles
instruct cmovDDPR_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regDPR dst, regDPR src) %{
- predicate( UseSSE<=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
+ predicate( UseSSE<=1 && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ));
match(Set dst (CMoveD (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
@@ -13171,7 +13171,7 @@ instruct cmovDDPR_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regDPR dst, regD
// Compare 2 longs and CMOVE doubles
instruct cmovDD_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regD dst, regD src) %{
- predicate( UseSSE>=2 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
+ predicate( UseSSE>=2 && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ));
match(Set dst (CMoveD (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
@@ -13180,7 +13180,7 @@ instruct cmovDD_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regD dst, regD src
%}
instruct cmovFFPR_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regFPR dst, regFPR src) %{
- predicate( UseSSE==0 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
+ predicate( UseSSE==0 && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ));
match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
@@ -13189,7 +13189,7 @@ instruct cmovFFPR_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regFPR dst, regF
%}
instruct cmovFF_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regF dst, regF src) %{
- predicate( UseSSE>=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
+ predicate( UseSSE>=1 && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ));
match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
@@ -13352,7 +13352,7 @@ instruct cmovPP_reg_EQNE_U(cmpOpU cmp, flagsReg_ulong_EQNE flags, eRegP dst, eRe
// Compare 2 longs and CMOVE doubles
instruct cmovDDPR_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regDPR dst, regDPR src) %{
- predicate( UseSSE<=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
+ predicate( UseSSE<=1 && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ));
match(Set dst (CMoveD (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
@@ -13362,7 +13362,7 @@ instruct cmovDDPR_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regDPR dst, regD
// Compare 2 longs and CMOVE doubles
instruct cmovDD_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regD dst, regD src) %{
- predicate( UseSSE>=2 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
+ predicate( UseSSE>=2 && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ));
match(Set dst (CMoveD (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
@@ -13371,7 +13371,7 @@ instruct cmovDD_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regD dst, regD src
%}
instruct cmovFFPR_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regFPR dst, regFPR src) %{
- predicate( UseSSE==0 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
+ predicate( UseSSE==0 && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ));
match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
@@ -13380,7 +13380,7 @@ instruct cmovFFPR_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regFPR dst, regF
%}
instruct cmovFF_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regF dst, regF src) %{
- predicate( UseSSE>=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
+ predicate( UseSSE>=1 && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ));
match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
@@ -13571,7 +13571,7 @@ instruct cmovPP_reg_LEGT_U(cmpOpU_commute cmp, flagsReg_ulong_LEGT flags, eRegP
// Compare 2 longs and CMOVE doubles
instruct cmovDDPR_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regDPR dst, regDPR src) %{
- predicate( UseSSE<=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
+ predicate( UseSSE<=1 && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ));
match(Set dst (CMoveD (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
@@ -13581,7 +13581,7 @@ instruct cmovDDPR_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regDPR d
// Compare 2 longs and CMOVE doubles
instruct cmovDD_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regD dst, regD src) %{
- predicate( UseSSE>=2 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
+ predicate( UseSSE>=2 && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ));
match(Set dst (CMoveD (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
@@ -13590,7 +13590,7 @@ instruct cmovDD_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regD dst,
%}
instruct cmovFFPR_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regFPR dst, regFPR src) %{
- predicate( UseSSE==0 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
+ predicate( UseSSE==0 && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ));
match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
@@ -13600,7 +13600,7 @@ instruct cmovFFPR_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regFPR d
instruct cmovFF_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regF dst, regF src) %{
- predicate( UseSSE>=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt );
+ predicate( UseSSE>=1 && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ));
match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
ins_cost(200);
expand %{
From a5071e010be8c79f1a3cd96f7325d04bac8f7ae0 Mon Sep 17 00:00:00 2001
From: Kim Barrett
Date: Tue, 9 Jan 2024 22:47:36 +0000
Subject: [PATCH 046/153] 8322817: RISC-V: Eliminate -Wparentheses warnings in
riscv code
Reviewed-by: fyang, luhenry
---
src/hotspot/cpu/riscv/frame_riscv.inline.hpp | 4 ++--
src/hotspot/cpu/riscv/macroAssembler_riscv.cpp | 14 +++++++-------
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/hotspot/cpu/riscv/frame_riscv.inline.hpp b/src/hotspot/cpu/riscv/frame_riscv.inline.hpp
index dfec388019216..37f273be6c19b 100644
--- a/src/hotspot/cpu/riscv/frame_riscv.inline.hpp
+++ b/src/hotspot/cpu/riscv/frame_riscv.inline.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -186,7 +186,7 @@ inline bool frame::equal(frame other) const {
unextended_sp() == other.unextended_sp() &&
fp() == other.fp() &&
pc() == other.pc();
- assert(!ret || ret && cb() == other.cb() && _deopt_state == other._deopt_state, "inconsistent construction");
+ assert(!ret || (cb() == other.cb() && _deopt_state == other._deopt_state), "inconsistent construction");
return ret;
}
diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
index 5008a0c08c219..ce336c16aa718 100644
--- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
+++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -4904,9 +4904,9 @@ void MacroAssembler::object_move(OopMap* map,
// A float arg may have to do float reg int reg conversion
void MacroAssembler::float_move(VMRegPair src, VMRegPair dst, Register tmp) {
- assert(src.first()->is_stack() && dst.first()->is_stack() ||
- src.first()->is_reg() && dst.first()->is_reg() ||
- src.first()->is_stack() && dst.first()->is_reg(), "Unexpected error");
+ assert((src.first()->is_stack() && dst.first()->is_stack()) ||
+ (src.first()->is_reg() && dst.first()->is_reg()) ||
+ (src.first()->is_stack() && dst.first()->is_reg()), "Unexpected error");
if (src.first()->is_stack()) {
if (dst.first()->is_stack()) {
lwu(tmp, Address(fp, reg2offset_in(src.first())));
@@ -4948,9 +4948,9 @@ void MacroAssembler::long_move(VMRegPair src, VMRegPair dst, Register tmp) {
// A double move
void MacroAssembler::double_move(VMRegPair src, VMRegPair dst, Register tmp) {
- assert(src.first()->is_stack() && dst.first()->is_stack() ||
- src.first()->is_reg() && dst.first()->is_reg() ||
- src.first()->is_stack() && dst.first()->is_reg(), "Unexpected error");
+ assert((src.first()->is_stack() && dst.first()->is_stack()) ||
+ (src.first()->is_reg() && dst.first()->is_reg()) ||
+ (src.first()->is_stack() && dst.first()->is_reg()), "Unexpected error");
if (src.first()->is_stack()) {
if (dst.first()->is_stack()) {
ld(tmp, Address(fp, reg2offset_in(src.first())));
From 376051a9be95e0e4acf3c59d0eba3e9ef8727d79 Mon Sep 17 00:00:00 2001
From: Naoto Sato
Date: Tue, 9 Jan 2024 23:11:21 +0000
Subject: [PATCH 047/153] 8320919: Clarify Locale related system properties
Reviewed-by: smarks, rriggs
---
.../share/classes/java/util/Locale.java | 91 +++++++++++++++++--
1 file changed, 81 insertions(+), 10 deletions(-)
diff --git a/src/java.base/share/classes/java/util/Locale.java b/src/java.base/share/classes/java/util/Locale.java
index 02f556489e641..88a49a94f9be5 100644
--- a/src/java.base/share/classes/java/util/Locale.java
+++ b/src/java.base/share/classes/java/util/Locale.java
@@ -45,6 +45,7 @@
import java.io.ObjectOutputStream;
import java.io.ObjectStreamField;
import java.io.Serializable;
+import java.text.DateFormat;
import java.text.MessageFormat;
import java.util.concurrent.ConcurrentHashMap;
import java.util.spi.LocaleNameProvider;
@@ -258,6 +259,74 @@
* locales. For example, {@code Locale.US} is the {@code Locale} object
* for the United States.
*
+ *
+ *
+ * The default Locale is provided for any locale-sensitive methods if no
+ * {@code Locale} is explicitly specified as an argument, such as
+ * {@link DateFormat#getInstance()}. The default Locale is determined at startup
+ * of the Java runtime and established in the following three phases:
+ *
+ * - The locale-related system properties listed below are established from the
+ * host environment. Some system properties (except for {@code user.language}) may
+ * not have values from the host environment.
+ *
+ * Shows property keys and associated values
+ *
+ * Locale-related System Properties Key |
+ * Description |
+ *
+ *
+ * {@systemProperty user.language} |
+ * {@link ##def_language language} for the default Locale,
+ * such as "en" (English) |
+ * {@systemProperty user.script} |
+ * {@link ##def_script script} for the default Locale,
+ * such as "Latn" (Latin) |
+ * {@systemProperty user.country} |
+ * {@link ##def_region country} for the default Locale,
+ * such as "US" (United States) |
+ * {@systemProperty user.variant} |
+ * {@link ##def_variant variant} for the default Locale,
+ * such as "POSIX" |
+ * {@systemProperty user.extensions} |
+ * {@link ##def_extensions extensions} for the default Locale,
+ * such as "u-ca-japanese" (Japanese Calendar) |
+ *
+ *
+ *
+ * - The values of these system properties can be overridden by values designated
+ * at startup time. If the overriding value of the {@code user.extensions} property
+ * is unparsable, it is ignored. The overriding values of other properties are not
+ * checked for syntax or validity and are used directly in the default Locale.
+ * (Typically, system property values can be provided using the {@code -D} command-line
+ * option of a launcher. For example, specifying {@code -Duser.extensions=foobarbaz}
+ * results in a default Locale with no extensions, while specifying
+ * {@code -Duser.language=foobarbaz} results in a default Locale whose language is
+ * "foobarbaz".)
+ *
+ * - The default {@code Locale} instance is constructed from the values of these
+ * system properties.
+ *
+ *
+ * Altering the system property values with {@link System#setProperties(Properties)}/
+ * {@link System#setProperty(String, String)} has no effect on the default Locale.
+ *
Once the default Locale is established, applications can query the default
+ * Locale with {@link #getDefault()} and change it with {@link #setDefault(Locale)}.
+ * If the default Locale is changed with {@link #setDefault(Locale)}, the corresponding
+ * system properties are not altered. It is not recommended that applications read
+ * these system properties and parse or interpret them as their values may be out of date.
+ *
+ *
There are finer-grained default Locales specific for each {@link Locale.Category}.
+ * These category specific default Locales can be queried by {@link #getDefault(Category)},
+ * and set by {@link #setDefault(Category, Locale)}. Construction of these category
+ * specific default Locales are determined by the corresponding system properties,
+ * which consist of the base system properties as listed above, suffixed by either
+ * {@code ".display"} or {@code ".format"} depending on the category. For example,
+ * the value of the {@code user.language.display} system property will be used in the
+ * {@code language} part of the default Locale for the {@link Locale.Category#DISPLAY}
+ * category. In the absence of category specific system properties, the "category-less"
+ * system properties are used, such as {@code user.language} in the previous example.
+ *
*
*
* If an application or a system is internationalized and provides localized
@@ -984,14 +1053,14 @@ public int hashCode() {
}
/**
- * Gets the current value of the default locale for this instance
- * of the Java Virtual Machine.
+ * Gets the current value of the {@link ##default_locale default locale} for
+ * this instance of the Java Virtual Machine.
*
* The Java Virtual Machine sets the default locale during startup
* based on the host environment. It is used by many locale-sensitive
* methods if no locale is explicitly specified.
* It can be changed using the
- * {@link #setDefault(java.util.Locale) setDefault} method.
+ * {@link #setDefault(Locale)} method.
*
* @return the default locale for this instance of the Java Virtual Machine
*/
@@ -1001,13 +1070,13 @@ public static Locale getDefault() {
}
/**
- * Gets the current value of the default locale for the specified Category
- * for this instance of the Java Virtual Machine.
+ * Gets the current value of the {@link ##default_locale default locale} for
+ * the specified Category for this instance of the Java Virtual Machine.
*
* The Java Virtual Machine sets the default locale during startup based
* on the host environment. It is used by many locale-sensitive methods
* if no locale is explicitly specified. It can be changed using the
- * setDefault(Locale.Category, Locale) method.
+ * {@link #setDefault(Locale.Category, Locale)} method.
*
* @param category the specified category to get the default locale
* @throws NullPointerException if category is null
@@ -1108,8 +1177,9 @@ private static Optional getDefaultExtensions(String extensions
}
/**
- * Sets the default locale for this instance of the Java Virtual Machine.
- * This does not affect the host locale.
+ * Sets the {@link ##default_locale default locale} for
+ * this instance of the Java Virtual Machine. This does not affect the
+ * host locale.
*
* If there is a security manager, its {@code checkPermission}
* method is called with a {@code PropertyPermission("user.language", "write")}
@@ -1142,8 +1212,9 @@ public static synchronized void setDefault(Locale newLocale) {
}
/**
- * Sets the default locale for the specified Category for this instance
- * of the Java Virtual Machine. This does not affect the host locale.
+ * Sets the {@link ##default_locale default locale} for the specified
+ * Category for this instance of the Java Virtual Machine. This does
+ * not affect the host locale.
*
* If there is a security manager, its checkPermission method is called
* with a PropertyPermission("user.language", "write") permission before
From f4ca41ad75fa78a08ff069ba0b6ac3596e35c23d Mon Sep 17 00:00:00 2001
From: Kim Barrett
Date: Wed, 10 Jan 2024 00:19:05 +0000
Subject: [PATCH 048/153] 8322816: RISC-V: Incorrect guarantee in patch_vtype
Reviewed-by: fyang, luhenry
---
src/hotspot/cpu/riscv/assembler_riscv.hpp | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/src/hotspot/cpu/riscv/assembler_riscv.hpp b/src/hotspot/cpu/riscv/assembler_riscv.hpp
index 55c3e755c48eb..f44840d9f8cc7 100644
--- a/src/hotspot/cpu/riscv/assembler_riscv.hpp
+++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -1156,10 +1156,8 @@ static Assembler::SEW elemtype_to_sew(BasicType etype) {
}
#define patch_vtype(hsb, lsb, vlmul, vsew, vta, vma, vill) \
- if (vill == 1) { \
- guarantee((vlmul | vsew | vta | vma == 0), \
- "the other bits in vtype shall be zero"); \
- } \
+ /* If vill then other bits of vtype must be zero. */ \
+ guarantee(!vill, "vill not supported"); \
patch((address)&insn, lsb + 2, lsb, vlmul); \
patch((address)&insn, lsb + 5, lsb + 3, vsew); \
patch((address)&insn, lsb + 6, vta); \
From 856922747358291ed2e112c328fb776a7be2567d Mon Sep 17 00:00:00 2001
From: Zhiqiang Zang
Date: Wed, 10 Jan 2024 07:31:56 +0000
Subject: [PATCH 049/153] 8322589: Add Ideal transformation: (~a) & (~b) => ~(a
| b)
Reviewed-by: thartmann, epeter
---
src/hotspot/share/opto/addnode.cpp | 18 ++++-
src/hotspot/share/opto/addnode.hpp | 9 ++-
src/hotspot/share/opto/mulnode.cpp | 16 ++++-
.../c2/irTests/AndINodeIdealizationTests.java | 25 +++++--
.../c2/irTests/AndLNodeIdealizationTests.java | 68 +++++++++++++++++++
.../compiler/lib/ir_framework/IRNode.java | 7 +-
6 files changed, 132 insertions(+), 11 deletions(-)
create mode 100644 test/hotspot/jtreg/compiler/c2/irTests/AndLNodeIdealizationTests.java
diff --git a/src/hotspot/share/opto/addnode.cpp b/src/hotspot/share/opto/addnode.cpp
index 305501bfb1467..49d17d84fc91c 100644
--- a/src/hotspot/share/opto/addnode.cpp
+++ b/src/hotspot/share/opto/addnode.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, 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
@@ -253,6 +253,22 @@ AddNode* AddNode::make(Node* in1, Node* in2, BasicType bt) {
return nullptr;
}
+bool AddNode::is_not(PhaseGVN* phase, Node* n, BasicType bt) {
+ return n->Opcode() == Op_Xor(bt) && phase->type(n->in(2)) == TypeInteger::minus_1(bt);
+}
+
+AddNode* AddNode::make_not(PhaseGVN* phase, Node* n, BasicType bt) {
+ switch (bt) {
+ case T_INT:
+ return new XorINode(n, phase->intcon(-1));
+ case T_LONG:
+ return new XorLNode(n, phase->longcon(-1L));
+ default:
+ fatal("Not implemented for %s", type2name(bt));
+ }
+ return nullptr;
+}
+
//=============================================================================
//------------------------------Idealize---------------------------------------
Node* AddNode::IdealIL(PhaseGVN* phase, bool can_reshape, BasicType bt) {
diff --git a/src/hotspot/share/opto/addnode.hpp b/src/hotspot/share/opto/addnode.hpp
index 709958b6abf25..577dd6ba29588 100644
--- a/src/hotspot/share/opto/addnode.hpp
+++ b/src/hotspot/share/opto/addnode.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, 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
@@ -78,6 +78,13 @@ class AddNode : public Node {
virtual int min_opcode() const = 0;
static AddNode* make(Node* in1, Node* in2, BasicType bt);
+
+ // Utility function to check if the given node is a NOT operation,
+ // i.e., n == m ^ (-1).
+ static bool is_not(PhaseGVN* phase, Node* n, BasicType bt);
+
+ // Utility function to make a NOT operation, i.e., returning n ^ (-1).
+ static AddNode* make_not(PhaseGVN* phase, Node* n, BasicType bt);
};
//------------------------------AddINode---------------------------------------
diff --git a/src/hotspot/share/opto/mulnode.cpp b/src/hotspot/share/opto/mulnode.cpp
index 3b493b5efa277..8b7fa22af55a7 100644
--- a/src/hotspot/share/opto/mulnode.cpp
+++ b/src/hotspot/share/opto/mulnode.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2024, 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
@@ -610,6 +610,13 @@ Node *AndINode::Ideal(PhaseGVN *phase, bool can_reshape) {
return progress;
}
+ // Convert "(~a) & (~b)" into "~(a | b)"
+ if (AddNode::is_not(phase, in(1), T_INT) && AddNode::is_not(phase, in(2), T_INT)) {
+ Node* or_a_b = new OrINode(in(1)->in(1), in(2)->in(1));
+ Node* tn = phase->transform(or_a_b);
+ return AddNode::make_not(phase, tn, T_INT);
+ }
+
// Special case constant AND mask
const TypeInt *t2 = phase->type( in(2) )->isa_int();
if( !t2 || !t2->is_con() ) return MulNode::Ideal(phase, can_reshape);
@@ -750,6 +757,13 @@ Node *AndLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
return progress;
}
+ // Convert "(~a) & (~b)" into "~(a | b)"
+ if (AddNode::is_not(phase, in(1), T_LONG) && AddNode::is_not(phase, in(2), T_LONG)) {
+ Node* or_a_b = new OrLNode(in(1)->in(1), in(2)->in(1));
+ Node* tn = phase->transform(or_a_b);
+ return AddNode::make_not(phase, tn, T_LONG);
+ }
+
// Special case constant AND mask
const TypeLong *t2 = phase->type( in(2) )->isa_long();
if( !t2 || !t2->is_con() ) return MulNode::Ideal(phase, can_reshape);
diff --git a/test/hotspot/jtreg/compiler/c2/irTests/AndINodeIdealizationTests.java b/test/hotspot/jtreg/compiler/c2/irTests/AndINodeIdealizationTests.java
index ad2b52392b6c3..f20c28e321db1 100644
--- a/test/hotspot/jtreg/compiler/c2/irTests/AndINodeIdealizationTests.java
+++ b/test/hotspot/jtreg/compiler/c2/irTests/AndINodeIdealizationTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2024, 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
@@ -38,22 +38,24 @@ public static void main(String[] args) {
TestFramework.run();
}
- @Run(test = { "test1" })
+ @Run(test = { "test1", "test2" })
public void runMethod() {
int a = RunInfo.getRandom().nextInt();
+ int b = RunInfo.getRandom().nextInt();
int min = Integer.MIN_VALUE;
int max = Integer.MAX_VALUE;
- assertResult(0);
- assertResult(a);
- assertResult(min);
- assertResult(max);
+ assertResult(0, 0);
+ assertResult(a, b);
+ assertResult(min, min);
+ assertResult(max, max);
}
@DontCompile
- public void assertResult(int a) {
+ public void assertResult(int a, int b) {
Asserts.assertEQ((0 - a) & 1, test1(a));
+ Asserts.assertEQ((~a) & (~b), test2(a, b));
}
@Test
@@ -63,4 +65,13 @@ public void assertResult(int a) {
public int test1(int x) {
return (0 - x) & 1;
}
+
+ @Test
+ @IR(failOn = { IRNode.AND })
+ @IR(counts = { IRNode.OR, "1",
+ IRNode.XOR, "1" })
+ // Checks (~a) & (~b) => ~(a | b)
+ public int test2(int a, int b) {
+ return (~a) & (~b);
+ }
}
diff --git a/test/hotspot/jtreg/compiler/c2/irTests/AndLNodeIdealizationTests.java b/test/hotspot/jtreg/compiler/c2/irTests/AndLNodeIdealizationTests.java
new file mode 100644
index 0000000000000..9aa1b62be9743
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/c2/irTests/AndLNodeIdealizationTests.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2024, 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.c2.irTests;
+
+import jdk.test.lib.Asserts;
+import compiler.lib.ir_framework.*;
+
+/*
+ * @test
+ * @bug 8322589
+ * @summary Test that Ideal transformations of AndLNode* are being performed as expected.
+ * @library /test/lib /
+ * @run driver compiler.c2.irTests.AndLNodeIdealizationTests
+ */
+public class AndLNodeIdealizationTests {
+
+ public static void main(String[] args) {
+ TestFramework.run();
+ }
+
+ @Run(test = { "test1" })
+ public void runMethod() {
+ long a = RunInfo.getRandom().nextLong();
+ long b = RunInfo.getRandom().nextLong();
+
+ long min = Long.MIN_VALUE;
+ long max = Long.MAX_VALUE;
+
+ assertResult(0, 0);
+ assertResult(a, b);
+ assertResult(min, min);
+ assertResult(max, max);
+ }
+
+ @DontCompile
+ public void assertResult(long a, long b) {
+ Asserts.assertEQ((~a) & (~b), test1(a, b));
+ }
+
+ @Test
+ @IR(failOn = { IRNode.AND })
+ @IR(counts = { IRNode.OR, "1",
+ IRNode.XOR, "1" })
+ // Checks (~a) & (~b) => ~(a | b)
+ public long test1(long a, long b) {
+ return (~a) & (~b);
+ }
+}
diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java
index 9e91268edffc3..040fe5d0222c7 100644
--- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java
+++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024, 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
@@ -298,6 +298,11 @@ public class IRNode {
optoOnly(ALLOC_ARRAY_OF, regex);
}
+ public static final String OR = PREFIX + "OR" + POSTFIX;
+ static {
+ beforeMatchingNameRegex(OR, "Or(I|L)");
+ }
+
public static final String AND = PREFIX + "AND" + POSTFIX;
static {
beforeMatchingNameRegex(AND, "And(I|L)");
From 88378ed0584c7eb0849b6fc1e361fd8ea0698caf Mon Sep 17 00:00:00 2001
From: Tobias Holenstein
Date: Wed, 10 Jan 2024 08:30:47 +0000
Subject: [PATCH 050/153] 8277869: Maven POMs are using HTTP links where HTTPS
is available
Reviewed-by: kvn, thartmann
---
src/utils/IdealGraphVisualizer/Bytecodes/pom.xml | 2 +-
.../igv/bytecodes/BytecodeViewTopComponentSettings.xml | 2 +-
.../igv/bytecodes/BytecodeViewTopComponentWstcref.xml | 2 +-
.../main/resources/com/sun/hotspot/igv/bytecodes/layer.xml | 2 +-
src/utils/IdealGraphVisualizer/ControlFlow/pom.xml | 2 +-
.../igv/controlflow/ControlFlowTopComponentSettings.xml | 2 +-
.../igv/controlflow/ControlFlowTopComponentWstcref.xml | 2 +-
.../resources/com/sun/hotspot/igv/controlflow/layer.xml | 2 +-
src/utils/IdealGraphVisualizer/Coordinator/pom.xml | 2 +-
.../hotspot/igv/coordinator/OutlineTopComponentSettings.xml | 2 +-
.../hotspot/igv/coordinator/OutlineTopComponentWstcref.xml | 2 +-
.../sun/hotspot/igv/coordinator/StandardConfiguration.xml | 2 +-
.../resources/com/sun/hotspot/igv/coordinator/layer.xml | 2 +-
src/utils/IdealGraphVisualizer/Data/pom.xml | 2 +-
.../sun/hotspot/igv/data/serialization/graphdocument.xsd | 2 +-
src/utils/IdealGraphVisualizer/Difference/pom.xml | 2 +-
src/utils/IdealGraphVisualizer/Filter/pom.xml | 2 +-
.../src/main/resources/com/sun/hotspot/igv/filter/layer.xml | 2 +-
src/utils/IdealGraphVisualizer/FilterWindow/pom.xml | 2 +-
.../hotspot/igv/filterwindow/FilterTopComponentSettings.xml | 2 +-
.../hotspot/igv/filterwindow/FilterTopComponentWstcref.xml | 2 +-
.../resources/com/sun/hotspot/igv/filterwindow/layer.xml | 2 +-
src/utils/IdealGraphVisualizer/Graph/pom.xml | 2 +-
src/utils/IdealGraphVisualizer/HierarchicalLayout/pom.xml | 2 +-
src/utils/IdealGraphVisualizer/Layout/pom.xml | 2 +-
src/utils/IdealGraphVisualizer/NetworkConnection/pom.xml | 2 +-
src/utils/IdealGraphVisualizer/SelectionCoordinator/pom.xml | 2 +-
src/utils/IdealGraphVisualizer/ServerCompiler/pom.xml | 2 +-
.../resources/com/sun/hotspot/igv/servercompiler/layer.xml | 2 +-
src/utils/IdealGraphVisualizer/Settings/pom.xml | 2 +-
.../main/resources/com/sun/hotspot/igv/settings/layer.xml | 2 +-
src/utils/IdealGraphVisualizer/Util/pom.xml | 2 +-
src/utils/IdealGraphVisualizer/View/pom.xml | 2 +-
.../src/main/resources/com/sun/hotspot/igv/view/layer.xml | 2 +-
.../resources/com/sun/hotspot/igv/view/propertiesWsmode.xml | 2 +-
.../com/sun/hotspot/igv/view/propertiesWstcref.xml | 2 +-
src/utils/IdealGraphVisualizer/application/pom.xml | 2 +-
src/utils/IdealGraphVisualizer/branding/pom.xml | 2 +-
src/utils/IdealGraphVisualizer/pom.xml | 2 +-
src/utils/LogCompilation/pom.xml | 6 +++---
40 files changed, 42 insertions(+), 42 deletions(-)
diff --git a/src/utils/IdealGraphVisualizer/Bytecodes/pom.xml b/src/utils/IdealGraphVisualizer/Bytecodes/pom.xml
index e87ad7fb50998..0a4f81d4d4ad9 100644
--- a/src/utils/IdealGraphVisualizer/Bytecodes/pom.xml
+++ b/src/utils/IdealGraphVisualizer/Bytecodes/pom.xml
@@ -30,7 +30,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-
+
4.0.0
IdealGraphVisualizer-parent
diff --git a/src/utils/IdealGraphVisualizer/Bytecodes/src/main/resources/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponentSettings.xml b/src/utils/IdealGraphVisualizer/Bytecodes/src/main/resources/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponentSettings.xml
index d9469aba6b11c..50a58be99cd6c 100644
--- a/src/utils/IdealGraphVisualizer/Bytecodes/src/main/resources/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponentSettings.xml
+++ b/src/utils/IdealGraphVisualizer/Bytecodes/src/main/resources/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponentSettings.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/src/utils/IdealGraphVisualizer/Bytecodes/src/main/resources/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponentWstcref.xml b/src/utils/IdealGraphVisualizer/Bytecodes/src/main/resources/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponentWstcref.xml
index a680c8f02fe72..3e0a7c7db2e30 100644
--- a/src/utils/IdealGraphVisualizer/Bytecodes/src/main/resources/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponentWstcref.xml
+++ b/src/utils/IdealGraphVisualizer/Bytecodes/src/main/resources/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponentWstcref.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/src/utils/IdealGraphVisualizer/Bytecodes/src/main/resources/com/sun/hotspot/igv/bytecodes/layer.xml b/src/utils/IdealGraphVisualizer/Bytecodes/src/main/resources/com/sun/hotspot/igv/bytecodes/layer.xml
index c864c8d9269dd..ae88bac2414ae 100644
--- a/src/utils/IdealGraphVisualizer/Bytecodes/src/main/resources/com/sun/hotspot/igv/bytecodes/layer.xml
+++ b/src/utils/IdealGraphVisualizer/Bytecodes/src/main/resources/com/sun/hotspot/igv/bytecodes/layer.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/src/utils/IdealGraphVisualizer/ControlFlow/pom.xml b/src/utils/IdealGraphVisualizer/ControlFlow/pom.xml
index 9b77a418dd205..a75a439c011d1 100644
--- a/src/utils/IdealGraphVisualizer/ControlFlow/pom.xml
+++ b/src/utils/IdealGraphVisualizer/ControlFlow/pom.xml
@@ -30,7 +30,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-
+
4.0.0
IdealGraphVisualizer-parent
diff --git a/src/utils/IdealGraphVisualizer/ControlFlow/src/main/resources/com/sun/hotspot/igv/controlflow/ControlFlowTopComponentSettings.xml b/src/utils/IdealGraphVisualizer/ControlFlow/src/main/resources/com/sun/hotspot/igv/controlflow/ControlFlowTopComponentSettings.xml
index e226cd5ece9ec..5ffb8213fbc5c 100644
--- a/src/utils/IdealGraphVisualizer/ControlFlow/src/main/resources/com/sun/hotspot/igv/controlflow/ControlFlowTopComponentSettings.xml
+++ b/src/utils/IdealGraphVisualizer/ControlFlow/src/main/resources/com/sun/hotspot/igv/controlflow/ControlFlowTopComponentSettings.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/src/utils/IdealGraphVisualizer/ControlFlow/src/main/resources/com/sun/hotspot/igv/controlflow/ControlFlowTopComponentWstcref.xml b/src/utils/IdealGraphVisualizer/ControlFlow/src/main/resources/com/sun/hotspot/igv/controlflow/ControlFlowTopComponentWstcref.xml
index 07bbb1f52fb3b..66bc3093c7ea6 100644
--- a/src/utils/IdealGraphVisualizer/ControlFlow/src/main/resources/com/sun/hotspot/igv/controlflow/ControlFlowTopComponentWstcref.xml
+++ b/src/utils/IdealGraphVisualizer/ControlFlow/src/main/resources/com/sun/hotspot/igv/controlflow/ControlFlowTopComponentWstcref.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/src/utils/IdealGraphVisualizer/ControlFlow/src/main/resources/com/sun/hotspot/igv/controlflow/layer.xml b/src/utils/IdealGraphVisualizer/ControlFlow/src/main/resources/com/sun/hotspot/igv/controlflow/layer.xml
index 176712f1595e2..5e79cc22ee712 100644
--- a/src/utils/IdealGraphVisualizer/ControlFlow/src/main/resources/com/sun/hotspot/igv/controlflow/layer.xml
+++ b/src/utils/IdealGraphVisualizer/ControlFlow/src/main/resources/com/sun/hotspot/igv/controlflow/layer.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/src/utils/IdealGraphVisualizer/Coordinator/pom.xml b/src/utils/IdealGraphVisualizer/Coordinator/pom.xml
index e93c6d20a40e1..718ef67044e5c 100644
--- a/src/utils/IdealGraphVisualizer/Coordinator/pom.xml
+++ b/src/utils/IdealGraphVisualizer/Coordinator/pom.xml
@@ -30,7 +30,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-
+
4.0.0
IdealGraphVisualizer-parent
diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/OutlineTopComponentSettings.xml b/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/OutlineTopComponentSettings.xml
index 1acdbcbe986e7..7f2a5a45a0f42 100644
--- a/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/OutlineTopComponentSettings.xml
+++ b/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/OutlineTopComponentSettings.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/OutlineTopComponentWstcref.xml b/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/OutlineTopComponentWstcref.xml
index 329140ea6bd6f..e0d1d62766cda 100644
--- a/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/OutlineTopComponentWstcref.xml
+++ b/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/OutlineTopComponentWstcref.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/StandardConfiguration.xml b/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/StandardConfiguration.xml
index ada940d0094ac..2412c5fed215a 100644
--- a/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/StandardConfiguration.xml
+++ b/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/StandardConfiguration.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/layer.xml b/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/layer.xml
index c4759676284c7..60e73788c952a 100644
--- a/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/layer.xml
+++ b/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/layer.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/src/utils/IdealGraphVisualizer/Data/pom.xml b/src/utils/IdealGraphVisualizer/Data/pom.xml
index 832be674e9885..90010dd700112 100644
--- a/src/utils/IdealGraphVisualizer/Data/pom.xml
+++ b/src/utils/IdealGraphVisualizer/Data/pom.xml
@@ -30,7 +30,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-
+
4.0.0
IdealGraphVisualizer-parent
diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/resources/com/sun/hotspot/igv/data/serialization/graphdocument.xsd b/src/utils/IdealGraphVisualizer/Data/src/main/resources/com/sun/hotspot/igv/data/serialization/graphdocument.xsd
index be576142ed45c..4e02fb64bb911 100644
--- a/src/utils/IdealGraphVisualizer/Data/src/main/resources/com/sun/hotspot/igv/data/serialization/graphdocument.xsd
+++ b/src/utils/IdealGraphVisualizer/Data/src/main/resources/com/sun/hotspot/igv/data/serialization/graphdocument.xsd
@@ -1,6 +1,6 @@
-
+
diff --git a/src/utils/IdealGraphVisualizer/Difference/pom.xml b/src/utils/IdealGraphVisualizer/Difference/pom.xml
index d4605c6072722..d51896a5d969d 100644
--- a/src/utils/IdealGraphVisualizer/Difference/pom.xml
+++ b/src/utils/IdealGraphVisualizer/Difference/pom.xml
@@ -30,7 +30,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-
+
4.0.0
IdealGraphVisualizer-parent
diff --git a/src/utils/IdealGraphVisualizer/Filter/pom.xml b/src/utils/IdealGraphVisualizer/Filter/pom.xml
index fa5089c8e65f8..e000c824f4f40 100644
--- a/src/utils/IdealGraphVisualizer/Filter/pom.xml
+++ b/src/utils/IdealGraphVisualizer/Filter/pom.xml
@@ -30,7 +30,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-
+
4.0.0
IdealGraphVisualizer-parent
diff --git a/src/utils/IdealGraphVisualizer/Filter/src/main/resources/com/sun/hotspot/igv/filter/layer.xml b/src/utils/IdealGraphVisualizer/Filter/src/main/resources/com/sun/hotspot/igv/filter/layer.xml
index 32fe79fc1a8e2..0cd6bc645b6bd 100644
--- a/src/utils/IdealGraphVisualizer/Filter/src/main/resources/com/sun/hotspot/igv/filter/layer.xml
+++ b/src/utils/IdealGraphVisualizer/Filter/src/main/resources/com/sun/hotspot/igv/filter/layer.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/src/utils/IdealGraphVisualizer/FilterWindow/pom.xml b/src/utils/IdealGraphVisualizer/FilterWindow/pom.xml
index 1617e1a5fa7db..4a4034c864f0a 100644
--- a/src/utils/IdealGraphVisualizer/FilterWindow/pom.xml
+++ b/src/utils/IdealGraphVisualizer/FilterWindow/pom.xml
@@ -30,7 +30,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-
+
4.0.0
IdealGraphVisualizer-parent
diff --git a/src/utils/IdealGraphVisualizer/FilterWindow/src/main/resources/com/sun/hotspot/igv/filterwindow/FilterTopComponentSettings.xml b/src/utils/IdealGraphVisualizer/FilterWindow/src/main/resources/com/sun/hotspot/igv/filterwindow/FilterTopComponentSettings.xml
index 6ae22f0fcd8e5..516361b0e88ce 100644
--- a/src/utils/IdealGraphVisualizer/FilterWindow/src/main/resources/com/sun/hotspot/igv/filterwindow/FilterTopComponentSettings.xml
+++ b/src/utils/IdealGraphVisualizer/FilterWindow/src/main/resources/com/sun/hotspot/igv/filterwindow/FilterTopComponentSettings.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/src/utils/IdealGraphVisualizer/FilterWindow/src/main/resources/com/sun/hotspot/igv/filterwindow/FilterTopComponentWstcref.xml b/src/utils/IdealGraphVisualizer/FilterWindow/src/main/resources/com/sun/hotspot/igv/filterwindow/FilterTopComponentWstcref.xml
index cc493bc5d6df7..29efbd5705d04 100644
--- a/src/utils/IdealGraphVisualizer/FilterWindow/src/main/resources/com/sun/hotspot/igv/filterwindow/FilterTopComponentWstcref.xml
+++ b/src/utils/IdealGraphVisualizer/FilterWindow/src/main/resources/com/sun/hotspot/igv/filterwindow/FilterTopComponentWstcref.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/src/utils/IdealGraphVisualizer/FilterWindow/src/main/resources/com/sun/hotspot/igv/filterwindow/layer.xml b/src/utils/IdealGraphVisualizer/FilterWindow/src/main/resources/com/sun/hotspot/igv/filterwindow/layer.xml
index aabc0e3829cac..72802a59b8a16 100644
--- a/src/utils/IdealGraphVisualizer/FilterWindow/src/main/resources/com/sun/hotspot/igv/filterwindow/layer.xml
+++ b/src/utils/IdealGraphVisualizer/FilterWindow/src/main/resources/com/sun/hotspot/igv/filterwindow/layer.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/src/utils/IdealGraphVisualizer/Graph/pom.xml b/src/utils/IdealGraphVisualizer/Graph/pom.xml
index 3dba21fa7a048..d828c9140abe0 100644
--- a/src/utils/IdealGraphVisualizer/Graph/pom.xml
+++ b/src/utils/IdealGraphVisualizer/Graph/pom.xml
@@ -30,7 +30,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-
+
4.0.0
IdealGraphVisualizer-parent
diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/pom.xml b/src/utils/IdealGraphVisualizer/HierarchicalLayout/pom.xml
index 4a99ff829d5ad..64d1f8f58dc72 100644
--- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/pom.xml
+++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/pom.xml
@@ -30,7 +30,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-
+
4.0.0
IdealGraphVisualizer-parent
diff --git a/src/utils/IdealGraphVisualizer/Layout/pom.xml b/src/utils/IdealGraphVisualizer/Layout/pom.xml
index 6a046b5e6b871..42975afd54d65 100644
--- a/src/utils/IdealGraphVisualizer/Layout/pom.xml
+++ b/src/utils/IdealGraphVisualizer/Layout/pom.xml
@@ -30,7 +30,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-
+
4.0.0
IdealGraphVisualizer-parent
diff --git a/src/utils/IdealGraphVisualizer/NetworkConnection/pom.xml b/src/utils/IdealGraphVisualizer/NetworkConnection/pom.xml
index 93ffbcee64be6..b755fec8fc6c6 100644
--- a/src/utils/IdealGraphVisualizer/NetworkConnection/pom.xml
+++ b/src/utils/IdealGraphVisualizer/NetworkConnection/pom.xml
@@ -30,7 +30,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-
+
4.0.0
IdealGraphVisualizer-parent
diff --git a/src/utils/IdealGraphVisualizer/SelectionCoordinator/pom.xml b/src/utils/IdealGraphVisualizer/SelectionCoordinator/pom.xml
index cf813426bdea3..8dd8dda05af6b 100644
--- a/src/utils/IdealGraphVisualizer/SelectionCoordinator/pom.xml
+++ b/src/utils/IdealGraphVisualizer/SelectionCoordinator/pom.xml
@@ -30,7 +30,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-
+
4.0.0
IdealGraphVisualizer-parent
diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/pom.xml b/src/utils/IdealGraphVisualizer/ServerCompiler/pom.xml
index 86980e79c50fc..59d4cce7a465a 100644
--- a/src/utils/IdealGraphVisualizer/ServerCompiler/pom.xml
+++ b/src/utils/IdealGraphVisualizer/ServerCompiler/pom.xml
@@ -30,7 +30,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-
+
4.0.0
IdealGraphVisualizer-parent
diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml
index 24533b75af02f..808a281fee4e1 100644
--- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml
+++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/src/utils/IdealGraphVisualizer/Settings/pom.xml b/src/utils/IdealGraphVisualizer/Settings/pom.xml
index 4003013bfa6eb..21f92b3001d9a 100644
--- a/src/utils/IdealGraphVisualizer/Settings/pom.xml
+++ b/src/utils/IdealGraphVisualizer/Settings/pom.xml
@@ -30,7 +30,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-
+
4.0.0
IdealGraphVisualizer-parent
diff --git a/src/utils/IdealGraphVisualizer/Settings/src/main/resources/com/sun/hotspot/igv/settings/layer.xml b/src/utils/IdealGraphVisualizer/Settings/src/main/resources/com/sun/hotspot/igv/settings/layer.xml
index 789b0ee8fd8a1..3573869405708 100644
--- a/src/utils/IdealGraphVisualizer/Settings/src/main/resources/com/sun/hotspot/igv/settings/layer.xml
+++ b/src/utils/IdealGraphVisualizer/Settings/src/main/resources/com/sun/hotspot/igv/settings/layer.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/src/utils/IdealGraphVisualizer/Util/pom.xml b/src/utils/IdealGraphVisualizer/Util/pom.xml
index bc27c79d17532..664ad35ef770b 100644
--- a/src/utils/IdealGraphVisualizer/Util/pom.xml
+++ b/src/utils/IdealGraphVisualizer/Util/pom.xml
@@ -30,7 +30,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-
+
4.0.0
IdealGraphVisualizer-parent
diff --git a/src/utils/IdealGraphVisualizer/View/pom.xml b/src/utils/IdealGraphVisualizer/View/pom.xml
index c66cb8c9a2430..2ffb98774cf8c 100644
--- a/src/utils/IdealGraphVisualizer/View/pom.xml
+++ b/src/utils/IdealGraphVisualizer/View/pom.xml
@@ -30,7 +30,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-
+
4.0.0
IdealGraphVisualizer-parent
diff --git a/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/layer.xml b/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/layer.xml
index 4e0417884a2b5..d50f7c914ccfe 100644
--- a/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/layer.xml
+++ b/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/layer.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/propertiesWsmode.xml b/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/propertiesWsmode.xml
index 22540d0628be0..d5ba5b18fc143 100644
--- a/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/propertiesWsmode.xml
+++ b/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/propertiesWsmode.xml
@@ -2,7 +2,7 @@
+ "https://www.netbeans.org/dtds/mode-properties2_0.dtd">
diff --git a/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/propertiesWstcref.xml b/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/propertiesWstcref.xml
index a706bb6e26591..cfba9aebfce4c 100644
--- a/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/propertiesWstcref.xml
+++ b/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/propertiesWstcref.xml
@@ -2,7 +2,7 @@
+ "https://www.netbeans.org/dtds/tc-ref2_0.dtd">
diff --git a/src/utils/IdealGraphVisualizer/application/pom.xml b/src/utils/IdealGraphVisualizer/application/pom.xml
index d202691a4ab1a..8266f2cf9e1b2 100644
--- a/src/utils/IdealGraphVisualizer/application/pom.xml
+++ b/src/utils/IdealGraphVisualizer/application/pom.xml
@@ -30,7 +30,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-
+
4.0.0
com.sun.hotspot.igv
diff --git a/src/utils/IdealGraphVisualizer/branding/pom.xml b/src/utils/IdealGraphVisualizer/branding/pom.xml
index ed33298d3e4c5..522445d897823 100644
--- a/src/utils/IdealGraphVisualizer/branding/pom.xml
+++ b/src/utils/IdealGraphVisualizer/branding/pom.xml
@@ -30,7 +30,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-
+
4.0.0
com.sun.hotspot.igv
diff --git a/src/utils/IdealGraphVisualizer/pom.xml b/src/utils/IdealGraphVisualizer/pom.xml
index 9363b05ae1f7f..772916540ff72 100644
--- a/src/utils/IdealGraphVisualizer/pom.xml
+++ b/src/utils/IdealGraphVisualizer/pom.xml
@@ -30,7 +30,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-
+
4.0.0
com.sun.hotspot.igv
IdealGraphVisualizer-parent
diff --git a/src/utils/LogCompilation/pom.xml b/src/utils/LogCompilation/pom.xml
index 1d8e0ffa1bda8..e033a3fbc073f 100644
--- a/src/utils/LogCompilation/pom.xml
+++ b/src/utils/LogCompilation/pom.xml
@@ -29,15 +29,15 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-
+
4.0.0
com.sun.hotspot.tools.compiler
LogCompilation
jar
1.0-SNAPSHOT
LogCompilation
- http://maven.apache.org
+ https://maven.apache.org
junit
From 40861761c2b0bb5ae548afc4752dc7cee3bf506a Mon Sep 17 00:00:00 2001
From: Thomas Schatzl
Date: Wed, 10 Jan 2024 09:57:16 +0000
Subject: [PATCH 051/153] 8322987: Remove gc/stress/gclocker/TestGCLocker*
since they always fail with OOME
Reviewed-by: ayang, lmesnik
---
test/hotspot/jtreg/ProblemList.txt | 3 -
.../gc/stress/gclocker/TestGCLocker.java | 228 ------------------
.../stress/gclocker/TestGCLockerWithG1.java | 39 ---
.../gclocker/TestGCLockerWithParallel.java | 39 ---
.../gclocker/TestGCLockerWithSerial.java | 40 ---
.../gclocker/TestGCLockerWithShenandoah.java | 64 -----
.../gc/stress/gclocker/libTestGCLocker.c | 35 ---
7 files changed, 448 deletions(-)
delete mode 100644 test/hotspot/jtreg/gc/stress/gclocker/TestGCLocker.java
delete mode 100644 test/hotspot/jtreg/gc/stress/gclocker/TestGCLockerWithG1.java
delete mode 100644 test/hotspot/jtreg/gc/stress/gclocker/TestGCLockerWithParallel.java
delete mode 100644 test/hotspot/jtreg/gc/stress/gclocker/TestGCLockerWithSerial.java
delete mode 100644 test/hotspot/jtreg/gc/stress/gclocker/TestGCLockerWithShenandoah.java
delete mode 100644 test/hotspot/jtreg/gc/stress/gclocker/libTestGCLocker.c
diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt
index 754cf68ba591f..4cb1ec5489880 100644
--- a/test/hotspot/jtreg/ProblemList.txt
+++ b/test/hotspot/jtreg/ProblemList.txt
@@ -89,9 +89,6 @@ gc/TestAllocHumongousFragment.java#iu-aggressive 8298781 generic-all
gc/TestAllocHumongousFragment.java#g1 8298781 generic-all
gc/TestAllocHumongousFragment.java#static 8298781 generic-all
gc/stress/gclocker/TestExcessGCLockerCollections.java 8229120 generic-all
-gc/stress/gclocker/TestGCLockerWithParallel.java 8180622 generic-all
-gc/stress/gclocker/TestGCLockerWithSerial.java 8180622 generic-all
-gc/stress/gclocker/TestGCLockerWithShenandoah.java 8180622 generic-all
gc/stress/TestStressG1Humongous.java 8286554 windows-x64
#############################################################################
diff --git a/test/hotspot/jtreg/gc/stress/gclocker/TestGCLocker.java b/test/hotspot/jtreg/gc/stress/gclocker/TestGCLocker.java
deleted file mode 100644
index 36b9a59fde66a..0000000000000
--- a/test/hotspot/jtreg/gc/stress/gclocker/TestGCLocker.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (c) 2017, 2023, 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 gc.stress.gclocker;
-
-// Stress the GC locker by calling GetPrimitiveArrayCritical while
-// concurrently filling up old gen.
-
-import java.lang.management.MemoryPoolMXBean;
-import java.lang.management.ManagementFactory;
-import java.lang.management.MemoryUsage;
-import java.util.ArrayDeque;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Queue;
-
-final class ThreadUtils {
- public static void sleep(long durationMS) {
- try {
- Thread.sleep(durationMS);
- } catch (Exception e) {
- }
- }
-}
-
-class Filler {
- private static final int SIZE = 250000;
-
- private int[] i1 = new int[SIZE];
- private int[] i2 = new int[SIZE];
- private short[] s1 = new short[SIZE];
- private short[] s2 = new short[SIZE];
-
- private Map