1 /*
  2  * Copyright (c) 2023, Red Hat, Inc. All rights reserved.
  3  * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
  4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  5  *
  6  * This code is free software; you can redistribute it and/or modify it
  7  * under the terms of the GNU General Public License version 2 only, as
  8  * published by the Free Software Foundation.
  9  *
 10  * This code is distributed in the hope that it will be useful, but WITHOUT
 11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 13  * version 2 for more details (a copy is included in the LICENSE file that
 14  * accompanied this code).
 15  *
 16  * You should have received a copy of the GNU General Public License version
 17  * 2 along with this work; if not, write to the Free Software Foundation,
 18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 19  *
 20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 21  * or visit www.oracle.com if you need additional information or have any
 22  * questions.
 23  */
 24 
 25 package compiler.c2.irTests;
 26 
 27 import compiler.lib.ir_framework.*;
 28 import jdk.test.lib.Utils;
 29 import jdk.test.whitebox.WhiteBox;
 30 import jdk.internal.misc.Unsafe;
 31 import java.util.Random;
 32 import java.util.Arrays;
 33 import java.nio.ByteOrder;
 34 
 35 /*
 36  * @test
 37  * @bug 8300258
 38  * @key randomness
 39  * @summary C2: vectorization fails on simple ByteBuffer loop
 40  * @modules java.base/jdk.internal.misc
 41  * @library /test/lib /
 42  * @build jdk.test.whitebox.WhiteBox
 43  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 44  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI compiler.c2.irTests.TestVectorizationMismatchedAccess
 45  */
 46 
 47 public class TestVectorizationMismatchedAccess {
 48     private static final Unsafe UNSAFE = Unsafe.getUnsafe();
 49     private static final Random RANDOM = Utils.getRandomInstance();
 50     private final static WhiteBox wb = WhiteBox.getWhiteBox();
 51 
 52     public static void main(String[] args) {
 53         Object alignVector = wb.getVMFlag("AlignVector");
 54         if (alignVector != null && !((Boolean)alignVector)) {
 55             if (ByteOrder.nativeOrder() != ByteOrder.LITTLE_ENDIAN) {
 56                 throw new RuntimeException("fix test that was written for a little endian platform");
 57             }
 58             TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED");
 59         }
 60     }
 61 
 62     static int size = 1024;
 63     static byte[] byteArray = new byte[size * 8];
 64     static long[] longArray = new long[size];
 65     static byte[] verifyByteArray = new byte[size * 8];
 66     static long[] verifyLongArray = new long[size];
 67     static long baseOffset = 0;
 68     static long baseOffHeap = UNSAFE.allocateMemory(size * 8);
 69 
 70 
 71     static {
 72         for (int i = 0; i < verifyByteArray.length; i++) {
 73             verifyByteArray[i] = (byte)RANDOM.nextInt(Byte.MAX_VALUE);
 74         }
 75         for (int i = 0; i < verifyLongArray.length; i++) {
 76             verifyLongArray[i] = 0;
 77             for (int j = 0; j < 8; j++) {
 78                 verifyLongArray[i] = verifyLongArray[i] | (((long)verifyByteArray[8 * i + j]) << 8 * j);
 79             }
 80         }
 81     }
 82 
 83     static private void runAndVerify(Runnable test, int offset) {
 84         System.arraycopy(verifyLongArray, 0, longArray, 0, longArray.length);
 85         Arrays.fill(byteArray, (byte)0);
 86         test.run();
 87         int i;
 88         for (i = 0; i < Math.max(offset, 0); i++) {
 89             if (byteArray[i] != 0) {
 90                 throw new RuntimeException("Incorrect result at " + i + " " + byteArray[i] + " != 0");
 91             }
 92         }
 93         for (; i < Math.min(byteArray.length + offset, byteArray.length); i++) {
 94             if (byteArray[i] != verifyByteArray[i - offset]) {
 95                 throw new RuntimeException("Incorrect result at " + i + " " + byteArray[i] + " != " + verifyByteArray[i-offset]);
 96             }
 97         }
 98         for (; i < byteArray.length; i++) {
 99             if (byteArray[i] != 0) {
100                 throw new RuntimeException("Incorrect result at " + i + " " + byteArray[i] + " != 0");
101             }
102         }
103     }
104 
105     static private void runAndVerify2(Runnable test, int offset) {
106         System.arraycopy(verifyByteArray, 0, byteArray, 0, byteArray.length);
107         test.run();
108         int i;
109         for (i = 0; i < Math.max(offset, 0); i++) {
110             if (byteArray[i] != verifyByteArray[i]) {
111                 throw new RuntimeException("Incorrect result at " + i + " " + byteArray[i] + " != " + verifyByteArray[i]);
112             }
113         }
114         for (; i < Math.min(byteArray.length + offset, byteArray.length); i++) {
115             int val = offset > 0 ? verifyByteArray[(i-offset) % 8] : verifyByteArray[i-offset];
116             if (byteArray[i] != val) {
117                 throw new RuntimeException("Incorrect result at " + i + " " + byteArray[i] + " != " + verifyByteArray[i-offset]);
118             }
119         }
120         for (; i < byteArray.length; i++) {
121             if (byteArray[i] != verifyByteArray[i]) {
122                 throw new RuntimeException("Incorrect result at " + i + " " + byteArray[i] + " != " + verifyByteArray[i]);
123             }
124         }
125     }
126 
127 
128     static private void runAndVerify3(Runnable test, int offset) {
129         System.arraycopy(verifyLongArray, 0, longArray, 0, longArray.length);
130         for (int i = 0; i < size * 8; i++) {
131             UNSAFE.putByte(null, baseOffHeap + i, (byte)0);
132         }
133         test.run();
134         int i;
135         for (i = 0; i < Math.max(offset, 0); i++) {
136             if (UNSAFE.getByte(null, baseOffHeap + i) != 0) {
137                 throw new RuntimeException("Incorrect result at " + i + " " + byteArray[i] + " != 0");
138             }
139         }
140         for (; i < Math.min(size * 8 + offset, size * 8); i++) {
141             if (UNSAFE.getByte(null, baseOffHeap + i) != verifyByteArray[i - offset]) {
142                 throw new RuntimeException("Incorrect result at " + i + " " + byteArray[i] + " != " + verifyByteArray[i-offset]);
143             }
144         }
145         for (; i < byteArray.length; i++) {
146             if (UNSAFE.getByte(null, baseOffHeap + i) != 0) {
147                 throw new RuntimeException("Incorrect result at " + i + " " + byteArray[i] + " != 0");
148             }
149         }
150     }
151 
152     @Test
153     @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" },
154         applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"},
155         applyIfPlatform = {"64-bit", "true"})
156     // 32-bit: offsets are badly aligned (UNSAFE.ARRAY_BYTE_BASE_OFFSET is 4 byte aligned, but not 8 byte aligned).
157     //         might get fixed with JDK-8325155.
158     public static void testByteLong1a(byte[] dest, long[] src) {
159         for (int i = 0; i < src.length; i++) {
160             UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8 * i, src[i]);
161         }
162     }
163 
164     @Test
165     @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" },
166         applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"},
167         applyIfPlatform = {"64-bit", "true"})
168     // 32-bit: address has ConvL2I for cast of long to address, not supported.
169     public static void testByteLong1b(byte[] dest, long[] src) {
170         for (int i = 0; i < src.length; i++) {
171             UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8L * i, src[i]);
172         }
173     }
174 
175     @Test
176     @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" },
177         applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"})
178     public static void testByteLong1c(byte[] dest, long[] src) {
179         long base = 64; // make sure it is big enough and 8 byte aligned (required for 32-bit)
180         for (int i = 0; i < src.length - 8; i++) {
181             UNSAFE.putLongUnaligned(dest, base + 8 * i, src[i]);
182         }
183     }
184 
185     @Test
186     @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" },
187         applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"},
188         applyIfPlatform = {"64-bit", "true"})
189     // 32-bit: address has ConvL2I for cast of long to address, not supported.
190     public static void testByteLong1d(byte[] dest, long[] src) {
191         long base = 64; // make sure it is big enough and 8 byte aligned (required for 32-bit)
192         for (int i = 0; i < src.length - 8; i++) {
193             UNSAFE.putLongUnaligned(dest, base + 8L * i, src[i]);
194         }
195     }
196 
197     @Run(test = {"testByteLong1a", "testByteLong1b", "testByteLong1c", "testByteLong1d"})
198     public static void testByteLong1_runner() {
199         runAndVerify(() -> testByteLong1a(byteArray, longArray), 0);
200         runAndVerify(() -> testByteLong1b(byteArray, longArray), 0);
201         testByteLong1c(byteArray, longArray);
202         testByteLong1d(byteArray, longArray);
203     }
204 
205     @Test
206     @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" },
207         applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"},
208         applyIfPlatform = {"64-bit", "true"})
209     // 32-bit: offsets are badly aligned (UNSAFE.ARRAY_BYTE_BASE_OFFSET is 4 byte aligned, but not 8 byte aligned).
210     //         might get fixed with JDK-8325155.
211     public static void testByteLong2a(byte[] dest, long[] src) {
212         for (int i = 1; i < src.length; i++) {
213             UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8 * (i - 1), src[i]);
214         }
215     }
216 
217     @Test
218     @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" },
219         applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"},
220         applyIfPlatform = {"64-bit", "true"})
221     // 32-bit: address has ConvL2I for cast of long to address, not supported.
222     public static void testByteLong2b(byte[] dest, long[] src) {
223         for (int i = 1; i < src.length; i++) {
224             UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8L * (i - 1), src[i]);
225         }
226     }
227 
228     @Run(test = {"testByteLong2a", "testByteLong2b"})
229     public static void testByteLong2_runner() {
230         runAndVerify(() -> testByteLong2a(byteArray, longArray), -8);
231         runAndVerify(() -> testByteLong2b(byteArray, longArray), -8);
232     }
233 
234     @Test
235     @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" },
236         applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"},
237         applyIfPlatform = {"64-bit", "true"})
238     // 32-bit: offsets are badly aligned (UNSAFE.ARRAY_BYTE_BASE_OFFSET is 4 byte aligned, but not 8 byte aligned).
239     //         might get fixed with JDK-8325155.
240     public static void testByteLong3a(byte[] dest, long[] src) {
241         for (int i = 0; i < src.length - 1; i++) {
242             UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8 * (i + 1), src[i]);
243         }
244     }
245 
246     @Test
247     @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" },
248         applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"},
249         applyIfPlatform = {"64-bit", "true"})
250     // 32-bit: address has ConvL2I for cast of long to address, not supported.
251     public static void testByteLong3b(byte[] dest, long[] src) {
252         for (int i = 0; i < src.length - 1; i++) {
253             UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8L * (i + 1), src[i]);
254         }
255     }
256 
257     @Run(test = {"testByteLong3a", "testByteLong3b"})
258     public static void testByteLong3_runner() {
259         runAndVerify(() -> testByteLong3a(byteArray, longArray), 8);
260         runAndVerify(() -> testByteLong3b(byteArray, longArray), 8);
261     }
262 
263     @Test
264     @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" },
265         applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"},
266         applyIfPlatform = {"64-bit", "true"})
267     // 32-bit: offsets are badly aligned (UNSAFE.ARRAY_BYTE_BASE_OFFSET is 4 byte aligned, but not 8 byte aligned).
268     //         might get fixed with JDK-8325155.
269     public static void testByteLong4a(byte[] dest, long[] src, int start, int stop) {
270         for (int i = start; i < stop; i++) {
271             UNSAFE.putLongUnaligned(dest, 8 * i + baseOffset, src[i]);
272         }
273     }
274 
275     @Test
276     @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" },
277         applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"},
278         applyIfPlatform = {"64-bit", "true"})
279     // 32-bit: address has ConvL2I for cast of long to address, not supported.
280     public static void testByteLong4b(byte[] dest, long[] src, int start, int stop) {
281         for (int i = start; i < stop; i++) {
282             UNSAFE.putLongUnaligned(dest, 8L * i + baseOffset, src[i]);
283         }
284     }
285 
286     @Run(test = {"testByteLong4a", "testByteLong4b"})
287     public static void testByteLong4_runner() {
288         baseOffset = UNSAFE.ARRAY_BYTE_BASE_OFFSET;
289         runAndVerify(() -> testByteLong4a(byteArray, longArray, 0, size), 0);
290         runAndVerify(() -> testByteLong4b(byteArray, longArray, 0, size), 0);
291     }
292 
293     @Test
294     @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" },
295         applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"},
296         applyIfPlatform = {"64-bit", "true"})
297     // 32-bit: offsets are badly aligned (UNSAFE.ARRAY_BYTE_BASE_OFFSET is 4 byte aligned, but not 8 byte aligned).
298     //         might get fixed with JDK-8325155.
299     public static void testByteLong5a(byte[] dest, long[] src, int start, int stop) {
300         for (int i = start; i < stop; i++) {
301             UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8 * (i + baseOffset), src[i]);
302         }
303     }
304 
305     @Test
306     @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" },
307         applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"},
308         applyIfPlatform = {"64-bit", "true"})
309     // 32-bit: address has ConvL2I for cast of long to address, not supported.
310     public static void testByteLong5b(byte[] dest, long[] src, int start, int stop) {
311         for (int i = start; i < stop; i++) {
312             UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8L * (i + baseOffset), src[i]);
313         }
314     }
315 
316     @Run(test = {"testByteLong5a", "testByteLong5b"})
317     public static void testByteLong5_runner() {
318         baseOffset = 1;
319         runAndVerify(() -> testByteLong5a(byteArray, longArray, 0, size-1), 8);
320         runAndVerify(() -> testByteLong5b(byteArray, longArray, 0, size-1), 8);
321     }
322 
323     @Test
324     @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" },
325         applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"},
326         applyIfPlatform = {"64-bit", "true"})
327     // 32-bit: offsets are badly aligned (UNSAFE.ARRAY_BYTE_BASE_OFFSET is 4 byte aligned, but not 8 byte aligned).
328     //         might get fixed with JDK-8325155.
329     public static void testByteByte1a(byte[] dest, byte[] src) {
330         for (int i = 0; i < src.length / 8; i++) {
331             UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8 * i, UNSAFE.getLongUnaligned(src, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8 * i));
332         }
333     }
334 
335     @Test
336     @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" },
337         applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"},
338         applyIfPlatform = {"64-bit", "true"})
339     // 32-bit: address has ConvL2I for cast of long to address, not supported.
340     public static void testByteByte1b(byte[] dest, byte[] src) {
341         for (int i = 0; i < src.length / 8; i++) {
342             UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8L * i, UNSAFE.getLongUnaligned(src, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8L * i));
343         }
344     }
345 
346     @Run(test = {"testByteByte1a", "testByteByte1b"})
347     public static void testByteByte1_runner() {
348         runAndVerify2(() -> testByteByte1a(byteArray, byteArray), 0);
349         runAndVerify2(() -> testByteByte1b(byteArray, byteArray), 0);
350     }
351 
352     @Test
353     // It would be legal to vectorize this one but it's not currently
354     //@IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" },
355     //    applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"},
356     //    applyIfPlatform = {"64-bit", "true"})
357     // 32-bit: offsets are badly aligned (UNSAFE.ARRAY_BYTE_BASE_OFFSET is 4 byte aligned, but not 8 byte aligned).
358     //         might get fixed with JDK-8325155.
359     public static void testByteByte2a(byte[] dest, byte[] src) {
360         for (int i = 1; i < src.length / 8; i++) {
361             UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8 * (i - 1), UNSAFE.getLongUnaligned(src, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8 * i));
362         }
363     }
364 
365     @Test
366     // It would be legal to vectorize this one but it's not currently
367     //@IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" },
368     //    applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"},
369     //    applyIfPlatform = {"64-bit", "true"})
370     // 32-bit: address has ConvL2I for cast of long to address, not supported.
371     public static void testByteByte2b(byte[] dest, byte[] src) {
372         for (int i = 1; i < src.length / 8; i++) {
373             UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8L * (i - 1), UNSAFE.getLongUnaligned(src, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8L * i));
374         }
375     }
376 
377     @Run(test = {"testByteByte2a", "testByteByte2b"})
378     public static void testByteByte2_runner() {
379         runAndVerify2(() -> testByteByte2a(byteArray, byteArray), -8);
380         runAndVerify2(() -> testByteByte2b(byteArray, byteArray), -8);
381     }
382 
383     @Test
384     @IR(failOn = { IRNode.LOAD_VECTOR_L, IRNode.STORE_VECTOR })
385     public static void testByteByte3a(byte[] dest, byte[] src) {
386         for (int i = 0; i < src.length / 8 - 1; i++) {
387             UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8 * (i + 1), UNSAFE.getLongUnaligned(src, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8 * i));
388         }
389     }
390 
391     @Test
392     @IR(failOn = { IRNode.LOAD_VECTOR_L, IRNode.STORE_VECTOR })
393     public static void testByteByte3b(byte[] dest, byte[] src) {
394         for (int i = 0; i < src.length / 8 - 1; i++) {
395             UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8L * (i + 1), UNSAFE.getLongUnaligned(src, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8L * i));
396         }
397     }
398 
399     @Run(test = {"testByteByte3a", "testByteByte3b"})
400     public static void testByteByte3_runner() {
401         runAndVerify2(() -> testByteByte3a(byteArray, byteArray), 8);
402         runAndVerify2(() -> testByteByte3b(byteArray, byteArray), 8);
403     }
404 
405     @Test
406     @IR(failOn = { IRNode.LOAD_VECTOR_L, IRNode.STORE_VECTOR })
407     public static void testByteByte4a(byte[] dest, byte[] src, int start, int stop) {
408         for (int i = start; i < stop; i++) {
409             UNSAFE.putLongUnaligned(dest, 8 * i + baseOffset, UNSAFE.getLongUnaligned(src, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8 * i));
410         }
411     }
412 
413     @Test
414     @IR(failOn = { IRNode.LOAD_VECTOR_L, IRNode.STORE_VECTOR })
415     public static void testByteByte4b(byte[] dest, byte[] src, int start, int stop) {
416         for (int i = start; i < stop; i++) {
417             UNSAFE.putLongUnaligned(dest, 8L * i + baseOffset, UNSAFE.getLongUnaligned(src, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8L * i));
418         }
419     }
420 
421     @Run(test = {"testByteByte4a", "testByteByte4b"})
422     public static void testByteByte4_runner() {
423         baseOffset = UNSAFE.ARRAY_BYTE_BASE_OFFSET;
424         runAndVerify2(() -> testByteByte4a(byteArray, byteArray, 0, size), 0);
425         runAndVerify2(() -> testByteByte4b(byteArray, byteArray, 0, size), 0);
426     }
427 
428     @Test
429     @IR(failOn = { IRNode.LOAD_VECTOR_L, IRNode.STORE_VECTOR })
430     public static void testByteByte5a(byte[] dest, byte[] src, int start, int stop) {
431         for (int i = start; i < stop; i++) {
432             UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8 * (i + baseOffset), UNSAFE.getLongUnaligned(src, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8 * i));
433         }
434     }
435 
436     @Test
437     @IR(failOn = { IRNode.LOAD_VECTOR_L, IRNode.STORE_VECTOR })
438     public static void testByteByte5b(byte[] dest, byte[] src, int start, int stop) {
439         for (int i = start; i < stop; i++) {
440             UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8L * (i + baseOffset), UNSAFE.getLongUnaligned(src, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8L * i));
441         }
442     }
443 
444     @Run(test = {"testByteByte5a", "testByteByte5b"})
445     public static void testByteByte5_runner() {
446         baseOffset = 1;
447         runAndVerify2(() -> testByteByte5a(byteArray, byteArray, 0, size-1), 8);
448         runAndVerify2(() -> testByteByte5b(byteArray, byteArray, 0, size-1), 8);
449     }
450 
451     @Test
452     @IR(counts = { IRNode.LOAD_VECTOR_L, "=0", IRNode.STORE_VECTOR, "=0" }) // temporary
453     // @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" })
454     // FAILS: adr is CastX2P(dest + 8 * (i + int_con))
455     // See: JDK-8331576
456     public static void testOffHeapLong1a(long dest, long[] src) {
457         for (int i = 0; i < src.length; i++) {
458             UNSAFE.putLongUnaligned(null, dest + 8 * i, src[i]);
459         }
460     }
461 
462     @Test
463     @IR(counts = { IRNode.LOAD_VECTOR_L, "=0", IRNode.STORE_VECTOR, "=0" }) // temporary
464     // @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" })
465     // FAILS: adr is CastX2P(dest + 8L * (i + int_con))
466     // See: JDK-8331576
467     public static void testOffHeapLong1b(long dest, long[] src) {
468         for (int i = 0; i < src.length; i++) {
469             UNSAFE.putLongUnaligned(null, dest + 8L * i, src[i]);
470         }
471     }
472 
473     @Run(test = {"testOffHeapLong1a", "testOffHeapLong1b"})
474     public static void testOffHeapLong1_runner() {
475         runAndVerify3(() -> testOffHeapLong1a(baseOffHeap, longArray), 0);
476         runAndVerify3(() -> testOffHeapLong1b(baseOffHeap, longArray), 0);
477     }
478 
479     @Test
480     @IR(counts = { IRNode.LOAD_VECTOR_L, "=0", IRNode.STORE_VECTOR, "=0" }) // temporary
481     // @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" })
482     // FAILS: adr is CastX2P
483     // See: JDK-8331576
484     public static void testOffHeapLong2a(long dest, long[] src) {
485         for (int i = 1; i < src.length; i++) {
486             UNSAFE.putLongUnaligned(null, dest + 8 * (i - 1), src[i]);
487         }
488     }
489 
490     @Test
491     @IR(counts = { IRNode.LOAD_VECTOR_L, "=0", IRNode.STORE_VECTOR, "=0" }) // temporary
492     // @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" })
493     // FAILS: adr is CastX2P
494     // See: JDK-8331576
495     public static void testOffHeapLong2b(long dest, long[] src) {
496         for (int i = 1; i < src.length; i++) {
497             UNSAFE.putLongUnaligned(null, dest + 8L * (i - 1), src[i]);
498         }
499     }
500 
501     @Run(test = {"testOffHeapLong2a", "testOffHeapLong2b"})
502     public static void testOffHeapLong2_runner() {
503         runAndVerify3(() -> testOffHeapLong2a(baseOffHeap, longArray), -8);
504         runAndVerify3(() -> testOffHeapLong2b(baseOffHeap, longArray), -8);
505     }
506 
507     @Test
508     @IR(counts = { IRNode.LOAD_VECTOR_L, "=0", IRNode.STORE_VECTOR, "=0" }) // temporary
509     // @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" })
510     // FAILS: adr is CastX2P
511     // See: JDK-8331576
512     public static void testOffHeapLong3a(long dest, long[] src) {
513         for (int i = 0; i < src.length - 1; i++) {
514             UNSAFE.putLongUnaligned(null, dest + 8 * (i + 1), src[i]);
515         }
516     }
517 
518     @Test
519     @IR(counts = { IRNode.LOAD_VECTOR_L, "=0", IRNode.STORE_VECTOR, "=0" }) // temporary
520     // @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" })
521     // FAILS: adr is CastX2P
522     // See: JDK-8331576
523     public static void testOffHeapLong3b(long dest, long[] src) {
524         for (int i = 0; i < src.length - 1; i++) {
525             UNSAFE.putLongUnaligned(null, dest + 8L * (i + 1), src[i]);
526         }
527     }
528 
529     @Run(test = {"testOffHeapLong3a", "testOffHeapLong3b"})
530     public static void testOffHeapLong3_runner() {
531         runAndVerify3(() -> testOffHeapLong3a(baseOffHeap, longArray), 8);
532         runAndVerify3(() -> testOffHeapLong3b(baseOffHeap, longArray), 8);
533     }
534 
535     @Test
536     @IR(counts = { IRNode.LOAD_VECTOR_L, "=0", IRNode.STORE_VECTOR, "=0" }) // temporary
537     // @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" })
538     // FAILS: adr is CastX2P
539     // See: JDK-8331576
540     public static void testOffHeapLong4a(long dest, long[] src, int start, int stop) {
541         for (int i = start; i < stop; i++) {
542             UNSAFE.putLongUnaligned(null, dest + 8 * i + baseOffset, src[i]);
543         }
544     }
545 
546     @Test
547     @IR(counts = { IRNode.LOAD_VECTOR_L, "=0", IRNode.STORE_VECTOR, "=0" }) // temporary
548     // @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" })
549     // FAILS: adr is CastX2P
550     // See: JDK-8331576
551     public static void testOffHeapLong4b(long dest, long[] src, int start, int stop) {
552         for (int i = start; i < stop; i++) {
553             UNSAFE.putLongUnaligned(null, dest + 8L * i + baseOffset, src[i]);
554         }
555     }
556 
557     @Run(test = {"testOffHeapLong4a", "testOffHeapLong4b"})
558     public static void testOffHeapLong4_runner() {
559         baseOffset = 8;
560         runAndVerify3(() -> testOffHeapLong4a(baseOffHeap, longArray, 0, size-1), 8);
561         runAndVerify3(() -> testOffHeapLong4b(baseOffHeap, longArray, 0, size-1), 8);
562     }
563 }