blob: a644df921f96718a488ed83b4cfd595a660e23cc [file] [log] [blame]
// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.analysis.type;
import static com.android.tools.r8.ir.analysis.type.TypeElement.getFloat;
import static com.android.tools.r8.ir.analysis.type.TypeElement.getInt;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ir.analysis.AnalysisTestBase;
import com.android.tools.r8.ir.code.ArrayGet;
import com.android.tools.r8.ir.code.ArrayPut;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.ConstNumber;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.Phi;
import com.android.tools.r8.ir.code.Value;
import java.util.function.Consumer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class ArrayTypeTest extends AnalysisTestBase {
@Parameterized.Parameters(name = "{0}")
public static TestParametersCollection data() {
return getTestParameters().withAllRuntimes().build();
}
public ArrayTypeTest(TestParameters parameters) throws Exception {
super(parameters, TestClass.class);
}
@Test
public void testArray() throws Exception {
buildAndCheckIR("arrayTest", arrayTestInspector());
}
@Test
public void testNestedArray() throws Exception {
buildAndCheckIR("nestedArrayTest", nestedArrayTestInspector());
}
@Test
public void testJoinOfArraysForPrimitivesSmallerThanInt() throws Exception {
buildAndCheckIR(
"joinOfArraysForPrimitivesSmallerThanInt",
joinOfArraysForPrimitivesSmallerThanInt());
}
private static Consumer<IRCode> arrayTestInspector() {
return code -> {
for (Instruction instruction : code.instructions()) {
if (instruction.isArrayGet() || instruction.isArrayPut()) {
Value array, value;
if (instruction.isArrayGet()) {
ArrayGet arrayGetInstruction = instruction.asArrayGet();
array = arrayGetInstruction.array();
value = arrayGetInstruction.outValue();
} else {
ArrayPut arrayPutInstruction = instruction.asArrayPut();
array = arrayPutInstruction.array();
value = arrayPutInstruction.value();
}
assertTrue(array.getType().isArrayType());
ArrayTypeElement arrayType = array.getType().asArrayType();
TypeElement elementType = arrayType.getMemberType();
assertEquals(getFloat(), elementType);
assertEquals(getFloat(), value.getType());
}
}
};
}
private static Consumer<IRCode> nestedArrayTestInspector() {
return code -> {
{
ArrayPut arrayPutInstruction = getMatchingInstruction(code, Instruction::isArrayPut);
Value array = arrayPutInstruction.array();
Value value = arrayPutInstruction.value();
assertTrue(array.getType().isArrayType());
ArrayTypeElement arrayType = array.getType().asArrayType();
TypeElement elementType = arrayType.getMemberType();
assertEquals(getFloat(), elementType);
assertEquals(getFloat(), value.getType());
}
{
ConstNumber constNumberInstruction =
getMatchingInstruction(
code,
instruction ->
instruction.isConstNumber() && instruction.asConstNumber().getRawValue() != 0);
assertEquals(getFloat(), constNumberInstruction.outValue().getType());
}
};
}
private static Consumer<IRCode> joinOfArraysForPrimitivesSmallerThanInt() {
return code -> {
int phiCount = 0;
for (BasicBlock block : code.blocks) {
for (Phi phi : block.getPhis()) {
phiCount++;
assertEquals(getInt(), phi.getType());
}
}
assertEquals(2, phiCount);
};
}
static class TestClass {
public static void arrayTest() {
float nans[] = {
Float.NaN,
Float.intBitsToFloat(0x7f800001),
Float.intBitsToFloat(0x7fC00000),
Float.intBitsToFloat(0x7fffffff),
Float.intBitsToFloat(0xff800001),
Float.intBitsToFloat(0x7fC00000),
Float.intBitsToFloat(0xffffffff),
};
nans[0] = nans[0];
nans[1] = nans[1];
nans[2] = nans[2];
nans[3] = nans[3];
nans[4] = nans[4];
nans[5] = nans[5];
nans[6] = nans[6];
}
public static void nestedArrayTest(float[][] array) {
float x = 1f;
array[0][0] = x;
}
public static void joinOfArraysForPrimitivesSmallerThanInt(
boolean predicate, byte[] bs, char[] cs) {
char s = (char) (predicate ? bs[0] : cs[0]);
byte b = (predicate ? bs[0] : bs[0]);
if (s == b) {
System.out.println("Meh, just to use variables.");
}
}
}
}