ARM: Optimize Div/Rem by positive const for non-negative dividends

When a constant divisor is positive and it can be proved that dividends
are non-negative, there is no need to generate instructions correcting
the result.

The CL implements this optimization for ARM32/ARM64.

Test: 411-checker-hdiv-hrem-const
Test: test.py --host --optimizing --jit --gtest --interpreter
Test: test.py -target --optimizing --jit --interpreter
Test: run-gtests.sh
Change-Id: Idf9aa740f14700000948b5ca58311be403a269ee
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index ba5b1b7..7d1af05 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -3242,13 +3242,23 @@
 
   // Extract the result from the high 32 bits and apply the final right shift.
   DCHECK_LT(shift, 32);
-  __ Asr(temp.X(), temp.X(), 32 + shift);
-
-  if (instruction->IsRem()) {
-    GenerateIncrementNegativeByOne(temp, temp, use_cond_inc);
-    GenerateResultRemWithAnyConstant(out, dividend, temp, imm, &temps);
+  if (imm > 0 && IsGEZero(instruction->GetLeft())) {
+    // No need to adjust the result for a non-negative dividend and a positive divisor.
+    if (instruction->IsDiv()) {
+      __ Lsr(out.X(), temp.X(), 32 + shift);
+    } else {
+      __ Lsr(temp.X(), temp.X(), 32 + shift);
+      GenerateResultRemWithAnyConstant(out, dividend, temp, imm, &temps);
+    }
   } else {
-    GenerateIncrementNegativeByOne(out, temp, use_cond_inc);
+    __ Asr(temp.X(), temp.X(), 32 + shift);
+
+    if (instruction->IsRem()) {
+      GenerateIncrementNegativeByOne(temp, temp, use_cond_inc);
+      GenerateResultRemWithAnyConstant(out, dividend, temp, imm, &temps);
+    } else {
+      GenerateIncrementNegativeByOne(out, temp, use_cond_inc);
+    }
   }
 }