diff options
author | 2018-06-25 17:54:07 +0100 | |
---|---|---|
committer | 2018-07-13 16:30:32 +0100 | |
commit | f58dc65c52f5e3f15eaaa1e25d7259e64649ade3 (patch) | |
tree | 4485299d9959a658909879b5a234fd807d7627ff | |
parent | 0b4a439f808f4602c7b97364e49c5546f5100d51 (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.cc | 18 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm64.h | 1 | ||||
-rw-r--r-- | test/411-optimizing-arith/src/RemTest.java | 48 | ||||
-rw-r--r-- | test/442-checker-constant-folding/src/Main.java | 54 |
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)); |