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