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