1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 public class Main {
main(String[] args)18     public static void main(String[] args) {
19         $noinline$testVectorAndNonVector();
20     }
21 
22     // Before loop optimization we only had an array get. After it, we optimized to also have
23     // VecLoad operations. This happens consistently only for Arm64 when using traditional
24     // vectorization (NEON). Arm32 vectorizes consistently but it also removes the ArrayGet, as does
25     // Arm64 predicated vectorization (SVE) because the scalar tail loop is eliminated. X86/X86_64
26     // doesn't vectorize consistently (other vectorization tests also ignore x86/x86_64).
27     // TODO: Create equivalent ArrayGet-replacement regression test for SVE, when SVE supports LSE.
28 
29     /// CHECK-START-ARM64: void Main.$noinline$testVectorAndNonVector() loop_optimization (before)
30     /// CHECK-IF:      not (hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true')
31     ///   CHECK-DAG:     ArrayGet
32     ///   CHECK-NOT:     VecLoad
33     /// CHECK-FI:
34 
35     /// CHECK-START-ARM64: void Main.$noinline$testVectorAndNonVector() loop_optimization (after)
36     /// CHECK-IF:      not (hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true')
37     ///   CHECK-DAG:     ArrayGet
38     ///   CHECK-DAG:     VecLoad
39     /// CHECK-FI:
40 
41     // In LoadStoreElimination both ArrayGet and VecLoad have the same heap location. We will try to
42     // replace the ArrayGet with the constant 0. The crash happens when we want to do the same with
43     // the vector operation, changing the vector operation to a scalar.
44 
45     /// CHECK-START-ARM64: void Main.$noinline$testVectorAndNonVector() load_store_elimination (before)
46     /// CHECK-IF:      not (hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true')
47     ///   CHECK-DAG:     VecLoad outer_loop:<<VecBlock:B\d+>>
48     ///   CHECK-DAG:     ArrayGet outer_loop:<<ScalarBlock:B\d+>>
49     ///   CHECK-EVAL:    "<<VecBlock>>" == "<<ScalarBlock>>"
50     /// CHECK-FI:
51 
$noinline$testVectorAndNonVector()52     private static void $noinline$testVectorAndNonVector() {
53         int[] result = new int[2];
54         int[] source = new int[12];
55 
56         // This will get vectorized.
57         for (int i = 0; i < result.length; ++i) {
58             int value = 0;
59             // Always true but needed to repro a crash since we need Phis.
60             if (i + 10 < source.length) {
61                 for (int j = 0; j < 10; j++) {
62                     value += Math.abs(source[i + j]);
63                 }
64             }
65             result[i] = value;
66         }
67     }
68 }
69