/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class Main {
public static void assertIntEquals(int expected, int result) {
if (expected != result) {
throw new Error("Expected: " + expected + ", found: " + result);
}
}
/// CHECK-START-ARM64: void Main.checkIntCase(int[]) instruction_simplifier_arm64 (before)
/// CHECK-DAG: <<Array:l\d+>> ParameterValue
/// CHECK-DAG: <<Const5:i\d+>> IntConstant 5
/// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const5>>]
// -------------- Loop
/// CHECK-DAG: <<Index:i\d+>> Phi
/// CHECK-DAG: If
/// CHECK-DAG: <<Load:d\d+>> VecLoad [<<Array>>,<<Index>>]
/// CHECK-DAG: <<Add:d\d+>> VecAdd [<<Load>>,<<Repl>>]
/// CHECK-DAG: VecStore [<<Array>>,<<Index>>,<<Add>>]
/// CHECK-START-ARM64: void Main.checkIntCase(int[]) instruction_simplifier_arm64 (after)
/// CHECK-DAG: <<Array:l\d+>> ParameterValue
/// CHECK-DAG: <<Const5:i\d+>> IntConstant 5
/// CHECK-DAG: <<DataOffset:i\d+>> IntConstant 12
/// CHECK-DAG: <<Const2:i\d+>> IntConstant 2
/// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const5>>]
// -------------- Loop
/// CHECK-DAG: <<Index:i\d+>> Phi
/// CHECK-DAG: If
/// CHECK-DAG: <<Address1:i\d+>> IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const2>>]
/// CHECK-DAG: <<Load:d\d+>> VecLoad [<<Array>>,<<Address1>>]
/// CHECK-DAG: <<Add:d\d+>> VecAdd [<<Load>>,<<Repl>>]
/// CHECK-DAG: <<Address2:i\d+>> IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const2>>]
/// CHECK-DAG: VecStore [<<Array>>,<<Address2>>,<<Add>>]
/// CHECK-START-ARM64: void Main.checkIntCase(int[]) GVN$after_arch (after)
/// CHECK-DAG: <<Array:l\d+>> ParameterValue
/// CHECK-DAG: <<Const5:i\d+>> IntConstant 5
/// CHECK-DAG: <<DataOffset:i\d+>> IntConstant 12
/// CHECK-DAG: <<Const2:i\d+>> IntConstant 2
/// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const5>>]
// -------------- Loop
/// CHECK-DAG: <<Index:i\d+>> Phi
/// CHECK-DAG: If
/// CHECK-DAG: <<Address1:i\d+>> IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const2>>]
/// CHECK-DAG: <<Load:d\d+>> VecLoad [<<Array>>,<<Address1>>]
/// CHECK-DAG: <<Add:d\d+>> VecAdd [<<Load>>,<<Repl>>]
/// CHECK-NOT: IntermediateAddress
/// CHECK-DAG: VecStore [<<Array>>,<<Address1>>,<<Add>>]
/// CHECK-START-ARM64: void Main.checkIntCase(int[]) disassembly (after)
/// CHECK: IntermediateAddressIndex
/// CHECK-NEXT: add w{{[0-9]+}}, w{{[0-9]+}}, w{{[0-9]+}}, lsl #2
public static void checkIntCase(int[] a) {
for (int i = 0; i < 128; i++) {
a[i] += 5;
}
}
/// CHECK-START-ARM64: void Main.checkByteCase(byte[]) instruction_simplifier_arm64 (before)
/// CHECK-DAG: <<Array:l\d+>> ParameterValue
/// CHECK-DAG: <<Const5:i\d+>> IntConstant 5
/// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const5>>]
// -------------- Loop
/// CHECK-DAG: <<Index:i\d+>> Phi
/// CHECK-DAG: If
/// CHECK-DAG: <<Load:d\d+>> VecLoad [<<Array>>,<<Index>>]
/// CHECK-DAG: <<Add:d\d+>> VecAdd [<<Load>>,<<Repl>>]
/// CHECK-DAG: VecStore [<<Array>>,<<Index>>,<<Add>>]
/// CHECK-START-ARM64: void Main.checkByteCase(byte[]) instruction_simplifier_arm64 (after)
/// CHECK-DAG: <<Array:l\d+>> ParameterValue
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
/// CHECK-DAG: <<Const5:i\d+>> IntConstant 5
/// CHECK-DAG: <<DataOffset:i\d+>> IntConstant 12
/// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const5>>]
// -------------- Loop
/// CHECK-DAG: <<Index:i\d+>> Phi
/// CHECK-DAG: If
/// CHECK-DAG: <<Address1:i\d+>> IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const0>>]
/// CHECK-DAG: <<Load:d\d+>> VecLoad [<<Array>>,<<Address1>>]
/// CHECK-DAG: <<Add:d\d+>> VecAdd [<<Load>>,<<Repl>>]
/// CHECK-DAG: <<Address2:i\d+>> IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const0>>]
/// CHECK-DAG: VecStore [<<Array>>,<<Address2>>,<<Add>>]
/// CHECK-START-ARM64: void Main.checkByteCase(byte[]) GVN$after_arch (after)
/// CHECK-DAG: <<Array:l\d+>> ParameterValue
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
/// CHECK-DAG: <<Const5:i\d+>> IntConstant 5
/// CHECK-DAG: <<DataOffset:i\d+>> IntConstant 12
/// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const5>>]
// -------------- Loop
/// CHECK-DAG: <<Index:i\d+>> Phi
/// CHECK-DAG: If
/// CHECK-DAG: <<Address1:i\d+>> IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const0>>]
/// CHECK-DAG: <<Load:d\d+>> VecLoad [<<Array>>,<<Address1>>]
/// CHECK-DAG: <<Add:d\d+>> VecAdd [<<Load>>,<<Repl>>]
/// CHECK-NOT: IntermediateAddress
/// CHECK-DAG: VecStore [<<Array>>,<<Address1>>,<<Add>>]
/// CHECK-START-ARM64: void Main.checkByteCase(byte[]) disassembly (after)
/// CHECK: IntermediateAddressIndex
/// CHECK-NEXT: add w{{[0-9]+}}, w{{[0-9]+}}, #0x{{[0-9a-fA-F]+}}
/// CHECK: VecLoad
/// CHECK-NEXT: ldr q{{[0-9]+}}, [x{{[0-9]+}}, x{{[0-9]+}}]
/// CHECK: VecStore
/// CHECK-NEXT: str q{{[0-9]+}}, [x{{[0-9]+}}, x{{[0-9]+}}]
public static void checkByteCase(byte[] a) {
for (int i = 0; i < 128; i++) {
a[i] += 5;
}
}
/// CHECK-START-ARM64: void Main.checkSingleAccess(int[]) instruction_simplifier_arm64 (before)
/// CHECK-DAG: <<Array:l\d+>> ParameterValue
/// CHECK-DAG: <<Const5:i\d+>> IntConstant 5
/// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const5>>]
// -------------- Loop
/// CHECK-DAG: <<Index:i\d+>> Phi
/// CHECK-DAG: If
/// CHECK-DAG: VecStore [<<Array>>,<<Index>>,<<Repl>>]
/// CHECK-START-ARM64: void Main.checkSingleAccess(int[]) instruction_simplifier_arm64 (after)
/// CHECK-DAG: <<Array:l\d+>> ParameterValue
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
/// CHECK-DAG: <<Const5:i\d+>> IntConstant 5
/// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const5>>]
// -------------- Loop
/// CHECK-DAG: <<Index:i\d+>> Phi
/// CHECK-DAG: If
/// CHECK-DAG: VecStore [<<Array>>,<<Index>>,<<Repl>>]
/// CHECK-NOT: IntermediateAddress
public static void checkSingleAccess(int[] a) {
for (int i = 0; i < 128; i++) {
a[i] = 5;
}
}
/// CHECK-START-ARM64: void Main.checkInt2Float(int[], float[]) instruction_simplifier_arm64 (before)
/// CHECK-DAG: <<Array1:l\d+>> ParameterValue
/// CHECK-DAG: <<Array2:l\d+>> ParameterValue
// -------------- Loop
/// CHECK-DAG: <<Index:i\d+>> Phi
/// CHECK-DAG: If
/// CHECK-DAG: <<Load:d\d+>> VecLoad [<<Array1>>,<<Index>>]
/// CHECK-DAG: <<Cnv:d\d+>> VecCnv [<<Load>>]
/// CHECK-DAG: VecStore [<<Array2>>,<<Index>>,<<Cnv>>]
/// CHECK-START-ARM64: void Main.checkInt2Float(int[], float[]) instruction_simplifier_arm64 (after)
/// CHECK-DAG: <<Array1:l\d+>> ParameterValue
/// CHECK-DAG: <<Array2:l\d+>> ParameterValue
/// CHECK-DAG: <<DataOffset:i\d+>> IntConstant 12
/// CHECK-DAG: <<Const2:i\d+>> IntConstant 2
// -------------- Loop
/// CHECK-DAG: <<Index:i\d+>> Phi
/// CHECK-DAG: If
/// CHECK-DAG: <<Address1:i\d+>> IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const2>>]
/// CHECK-DAG: <<Load:d\d+>> VecLoad [<<Array1>>,<<Address1>>]
/// CHECK-DAG: <<Cnv:d\d+>> VecCnv [<<Load>>]
/// CHECK-DAG: <<Address2:i\d+>> IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const2>>]
/// CHECK-DAG: VecStore [<<Array2>>,<<Address2>>,<<Cnv>>]
/// CHECK-START-ARM64: void Main.checkInt2Float(int[], float[]) GVN$after_arch (after)
/// CHECK-DAG: <<Array1:l\d+>> ParameterValue
/// CHECK-DAG: <<Array2:l\d+>> ParameterValue
/// CHECK-DAG: <<DataOffset:i\d+>> IntConstant 12
/// CHECK-DAG: <<Const2:i\d+>> IntConstant 2
// -------------- Loop
/// CHECK-DAG: <<Index:i\d+>> Phi
/// CHECK-DAG: If
/// CHECK-DAG: <<Address1:i\d+>> IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const2>>]
/// CHECK-DAG: <<Load:d\d+>> VecLoad [<<Array1>>,<<Address1>>]
/// CHECK-DAG: <<Cnv:d\d+>> VecCnv [<<Load>>]
/// CHECK-NOT: IntermediateAddress
/// CHECK-DAG: VecStore [<<Array2>>,<<Address1>>,<<Cnv>>]
/// CHECK-START-ARM64: void Main.checkInt2Float(int[], float[]) disassembly (after)
/// CHECK: IntermediateAddressIndex
/// CHECK-NEXT: add w{{[0-9]+}}, w{{[0-9]+}}, w{{[0-9]+}}, lsl #2
public static void checkInt2Float(int[] a, float[] b) {
for (int i = 0; i < 128; i++) {
b[i] = (float) a[i];
}
}
public static final int ARRAY_SIZE = 1024;
public static int calcArraySum(int[] a, byte[] b, float[] c) {
int sum = 0;
for (int i = 0; i < 128; i++) {
sum += a[i] + b[i] + (int) c[i];
}
return sum;
}
public static void main(String[] args) {
byte[] ba = new byte[ARRAY_SIZE];
int[] ia = new int[ARRAY_SIZE];
float[] fa = new float[ARRAY_SIZE];
checkSingleAccess(ia);
checkIntCase(ia);
checkByteCase(ba);
checkInt2Float(ia, fa);
assertIntEquals(3200, calcArraySum(ia, ba, fa));
}
}