summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Evgeny Astigeevich <evgeny.astigeevich@linaro.org> 2018-06-25 17:54:07 +0100
committer Evgeny Astigeevich <evgeny.astigeevich@linaro.org> 2018-07-13 16:30:32 +0100
commitf58dc65c52f5e3f15eaaa1e25d7259e64649ade3 (patch)
tree4485299d9959a658909879b5a234fd807d7627ff
parent0b4a439f808f4602c7b97364e49c5546f5100d51 (diff)
ART: Delete code optimizing a%1 and a%-1 from InstructionCodeGeneratorARM64
In InstructionWithAbsorbingInputSimplifier there is code optimizing a%1 and a%-1. So the code in InstructionCodeGeneratorARM64 optimizing such cases can be deleted. This patch deletes the code from InstructionCodeGeneratorARM64 and adds additional tests. Test: 012-math, 014-math3, 411-optimizing-arith, 411-checker-hdiv-hrem-pow2 Test: 701-easy-div-rem, 442-checker-constant-folding Test: test-art-host, test-art-target Change-Id: Ib80c0aa4c3e28b07fa79bb43783274c9d7fc456a
-rw-r--r--compiler/optimizing/code_generator_arm64.cc18
-rw-r--r--compiler/optimizing/code_generator_arm64.h1
-rw-r--r--test/411-optimizing-arith/src/RemTest.java48
-rw-r--r--test/442-checker-constant-folding/src/Main.java54
4 files changed, 108 insertions, 13 deletions
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index d1c83ce625..02c995a833 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -5678,14 +5678,6 @@ void InstructionCodeGeneratorARM64::GenerateIntRemForPower2Denom(HRem *instructi
}
}
-void InstructionCodeGeneratorARM64::GenerateIntRemForOneOrMinusOneDenom(HRem *instruction) {
- int64_t imm = Int64FromLocation(instruction->GetLocations()->InAt(1));
- DCHECK(imm == 1 || imm == -1) << imm;
-
- Register out = OutputRegister(instruction);
- __ Mov(out, 0);
-}
-
void InstructionCodeGeneratorARM64::GenerateIntRemForConstDenom(HRem *instruction) {
int64_t imm = Int64FromLocation(instruction->GetLocations()->InAt(1));
@@ -5695,10 +5687,12 @@ void InstructionCodeGeneratorARM64::GenerateIntRemForConstDenom(HRem *instructio
return;
}
- if (imm == 1 || imm == -1) {
- // TODO: These cases need to be optimized in InstructionSimplifier
- GenerateIntRemForOneOrMinusOneDenom(instruction);
- } else if (IsPowerOfTwo(AbsOrMin(imm))) {
+ if (IsPowerOfTwo(AbsOrMin(imm))) {
+ // Cases imm == -1 or imm == 1 are handled in constant folding by
+ // InstructionWithAbsorbingInputSimplifier.
+ // If the cases have survided till code generation they are handled in
+ // GenerateIntRemForPower2Denom becauses -1 and 1 are the power of 2 (2^0).
+ // The correct code is generated for them, just more instructions.
GenerateIntRemForPower2Denom(instruction);
} else {
DCHECK(imm < -2 || imm > 2) << imm;
diff --git a/compiler/optimizing/code_generator_arm64.h b/compiler/optimizing/code_generator_arm64.h
index c44fa48066..93bab3180c 100644
--- a/compiler/optimizing/code_generator_arm64.h
+++ b/compiler/optimizing/code_generator_arm64.h
@@ -327,7 +327,6 @@ class InstructionCodeGeneratorARM64 : public InstructionCodeGenerator {
void GenerateIntDivForPower2Denom(HDiv *instruction);
void GenerateIntRem(HRem* instruction);
void GenerateIntRemForConstDenom(HRem *instruction);
- void GenerateIntRemForOneOrMinusOneDenom(HRem *instruction);
void GenerateIntRemForPower2Denom(HRem *instruction);
void HandleGoto(HInstruction* got, HBasicBlock* successor);
diff --git a/test/411-optimizing-arith/src/RemTest.java b/test/411-optimizing-arith/src/RemTest.java
index 1b31f63569..287f5d8799 100644
--- a/test/411-optimizing-arith/src/RemTest.java
+++ b/test/411-optimizing-arith/src/RemTest.java
@@ -89,6 +89,34 @@ public class RemTest {
expectDivisionByZero(5L);
expectDivisionByZero(Long.MAX_VALUE);
expectDivisionByZero(Long.MIN_VALUE);
+
+ expectEquals(0, $noinline$RemLoaded1(0));
+ expectEquals(0, $noinline$RemLoaded1(1));
+ expectEquals(0, $noinline$RemLoaded1(-1));
+ expectEquals(0, $noinline$RemLoaded1(12345));
+ expectEquals(0, $noinline$RemLoaded1(Integer.MAX_VALUE));
+ expectEquals(0, $noinline$RemLoaded1(Integer.MIN_VALUE));
+
+ expectEquals(0, $noinline$RemLoadedN1(0));
+ expectEquals(0, $noinline$RemLoadedN1(1));
+ expectEquals(0, $noinline$RemLoadedN1(-1));
+ expectEquals(0, $noinline$RemLoadedN1(12345));
+ expectEquals(0, $noinline$RemLoadedN1(Integer.MAX_VALUE));
+ expectEquals(0, $noinline$RemLoadedN1(Integer.MIN_VALUE));
+
+ expectEquals(0L, $noinline$RemLoaded1(0L));
+ expectEquals(0L, $noinline$RemLoaded1(1L));
+ expectEquals(0L, $noinline$RemLoaded1(-1L));
+ expectEquals(0L, $noinline$RemLoaded1(12345L));
+ expectEquals(0L, $noinline$RemLoaded1(Long.MAX_VALUE));
+ expectEquals(0L, $noinline$RemLoaded1(Long.MIN_VALUE));
+
+ expectEquals(0L, $noinline$RemLoadedN1(0L));
+ expectEquals(0L, $noinline$RemLoadedN1(1L));
+ expectEquals(0L, $noinline$RemLoadedN1(-1L));
+ expectEquals(0L, $noinline$RemLoadedN1(12345L));
+ expectEquals(0L, $noinline$RemLoadedN1(Long.MAX_VALUE));
+ expectEquals(0L, $noinline$RemLoadedN1(Long.MIN_VALUE));
}
static int $opt$Rem(int a, int b) {
@@ -99,6 +127,26 @@ public class RemTest {
return a % 0;
}
+ static int $noinline$RemLoaded1(int a) {
+ int[] v = {25, 1};
+ return a % v[1];
+ }
+
+ static int $noinline$RemLoadedN1(int a) {
+ int [] v = {25, -1};
+ return a % v[1];
+ }
+
+ static long $noinline$RemLoaded1(long a) {
+ long[] v = {25, 1};
+ return a % v[1];
+ }
+
+ static long $noinline$RemLoadedN1(long a) {
+ long [] v = {25, -1};
+ return a % v[1];
+ }
+
// Modulo by literals != 0 should not generate checks.
static int $opt$RemConst(int a) {
return a % 4;
diff --git a/test/442-checker-constant-folding/src/Main.java b/test/442-checker-constant-folding/src/Main.java
index fcc3c1a852..3d9294304d 100644
--- a/test/442-checker-constant-folding/src/Main.java
+++ b/test/442-checker-constant-folding/src/Main.java
@@ -1150,6 +1150,41 @@ public class Main {
return arg % 1;
}
+ /// CHECK-START: int Main.RemN1(int) constant_folding (before)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<ConstN1:i\d+>> IntConstant -1
+ /// CHECK-DAG: <<Rem:i\d+>> Rem [<<Arg>>,<<ConstN1>>]
+ /// CHECK-DAG: Return [<<Rem>>]
+
+ /// CHECK-START: int Main.RemN1(int) constant_folding (after)
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: Return [<<Const0>>]
+
+ /// CHECK-START: int Main.RemN1(int) constant_folding (after)
+ /// CHECK-NOT: Rem
+
+ public static int RemN1(int arg) {
+ return arg % -1;
+ }
+
+ /// CHECK-START: long Main.Rem1(long) constant_folding (before)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Const1:j\d+>> LongConstant 1
+ /// CHECK-DAG: <<DivZeroCheck:j\d+>> DivZeroCheck [<<Const1>>]
+ /// CHECK-DAG: <<Rem:j\d+>> Rem [<<Arg>>,<<DivZeroCheck>>]
+ /// CHECK-DAG: Return [<<Rem>>]
+
+ /// CHECK-START: long Main.Rem1(long) constant_folding (after)
+ /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0
+ /// CHECK-DAG: Return [<<Const0>>]
+
+ /// CHECK-START: long Main.Rem1(long) constant_folding (after)
+ /// CHECK-NOT: Rem
+
+ public static long Rem1(long arg) {
+ return arg % 1;
+ }
+
/// CHECK-START: long Main.RemN1(long) constant_folding (before)
/// CHECK-DAG: <<Arg:j\d+>> ParameterValue
/// CHECK-DAG: <<ConstN1:j\d+>> LongConstant -1
@@ -1597,7 +1632,26 @@ public class Main {
assertIntEquals(-1, OrAllOnes(arbitrary));
assertLongEquals(0, Rem0(arbitrary));
assertIntEquals(0, Rem1(arbitrary));
+ assertIntEquals(0, Rem1(0));
+ assertIntEquals(0, Rem1(-1));
+ assertIntEquals(0, Rem1(Integer.MAX_VALUE));
+ assertIntEquals(0, Rem1(Integer.MIN_VALUE));
+ assertIntEquals(0, RemN1(arbitrary));
+ assertIntEquals(0, RemN1(0));
+ assertIntEquals(0, RemN1(-1));
+ assertIntEquals(0, RemN1(Integer.MAX_VALUE));
+ assertIntEquals(0, RemN1(Integer.MIN_VALUE));
+ assertIntEquals(0, RemN1(arbitrary));
+ assertLongEquals(0, Rem1((long)arbitrary));
+ assertLongEquals(0, Rem1(0L));
+ assertLongEquals(0, Rem1(-1L));
+ assertLongEquals(0, Rem1(Long.MAX_VALUE));
+ assertLongEquals(0, Rem1(Long.MIN_VALUE));
assertLongEquals(0, RemN1(arbitrary));
+ assertLongEquals(0, RemN1(0L));
+ assertLongEquals(0, RemN1(-1L));
+ assertLongEquals(0, RemN1(Long.MAX_VALUE));
+ assertLongEquals(0, RemN1(Long.MIN_VALUE));
assertIntEquals(0, Shl0(arbitrary));
assertLongEquals(0, ShlLong0WithInt(arbitrary));
assertLongEquals(0, Shr0(arbitrary));