1 /*
  2  * Copyright (c) 2022, Arm Limited. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 /*
 25  * @test
 26  * @bug 8289996
 27  * @summary Test range check hoisting for some scaled iv at array index
 28  * @library /test/lib /
 29  * @requires vm.debug & vm.compiler2.enabled & (os.simpleArch == "x64" | os.arch == "aarch64")
 30  * @modules jdk.incubator.vector
 31  * @compile -source ${jdk.version} TestRangeCheckHoistingScaledIV.java
 32  * @run main/othervm compiler.rangechecks.TestRangeCheckHoistingScaledIV
 33  */
 34 
 35 package compiler.rangechecks;
 36 
 37 import java.lang.foreign.MemorySegment;
 38 import java.nio.ByteOrder;
 39 
 40 import jdk.incubator.vector.ByteVector;
 41 import jdk.incubator.vector.VectorSpecies;
 42 import jdk.test.lib.process.OutputAnalyzer;
 43 import jdk.test.lib.process.ProcessTools;
 44 
 45 public class TestRangeCheckHoistingScaledIV {
 46 
 47     // Inner class for test loops
 48     class Launcher {
 49         private static final int SIZE = 16000;
 50         private static final VectorSpecies<Byte> SPECIES = ByteVector.SPECIES_64;
 51         private static final ByteOrder ORDER = ByteOrder.nativeOrder();
 52 
 53         private static byte[] ta = new byte[SIZE];
 54         private static byte[] tb = new byte[SIZE];
 55 
 56         private static MemorySegment sa = MemorySegment.ofArray(ta);
 57         private static MemorySegment sb = MemorySegment.ofArray(tb);
 58 
 59         private static int count = 789;
 60 
 61         // Normal array accesses with int range checks
 62         public static void scaledIntIV() {
 63             for (int i = 0; i < count; i += 2) {
 64                 tb[7 * i] = ta[3 * i];
 65             }
 66         }
 67 
 68         // Memory segment accesses with long range checks
 69         public static void scaledLongIV() {
 70             for (long l = 0; l < count; l += 64) {
 71                 ByteVector v = ByteVector.fromMemorySegment(SPECIES, sa, l * 6, ORDER);
 72                 v.intoMemorySegment(sb, l * 15, ORDER);
 73             }
 74         }
 75 
 76         public static void main(String[] args) {
 77             for (int i = 0; i < 20000; i++) {
 78                 scaledIntIV();
 79                 scaledLongIV();
 80             }
 81         }
 82     }
 83 
 84     public static void main(String[] args) throws Exception {
 85         ProcessBuilder pb = ProcessTools.createTestJvm(
 86                 "--add-modules", "jdk.incubator.vector",
 87                 "-Xbatch", "-XX:+TraceLoopPredicate", Launcher.class.getName());
 88         OutputAnalyzer analyzer = new OutputAnalyzer(pb.start());
 89         analyzer.shouldHaveExitValue(0);
 90         analyzer.outputTo(System.out);
 91 
 92         // Check if int range checks are hoisted
 93         analyzer.stdoutShouldContain("rc_predicate init * 3");
 94         analyzer.stdoutShouldContain("rc_predicate init * 7");
 95 
 96         // Check if long range checks are hoisted
 97         analyzer.stdoutShouldContain("rc_predicate init * 6");
 98         analyzer.stdoutShouldContain("rc_predicate init * 15");
 99     }
100 }