Add numerator check for integer divide and modulo

Implemented numerator == 0 optimization for integer divide and modulo

Change-Id: I6e3bff4a9f68d2790394f7df6106a948003a04c4
Signed-off-by: Yixin Shou <yixin.shou@intel.com>
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc
index cc51538..3463c54 100755
--- a/compiler/dex/quick/x86/int_x86.cc
+++ b/compiler/dex/quick/x86/int_x86.cc
@@ -607,6 +607,12 @@
     rl_result = EvalLoc(rl_dest, kCoreReg, true);
     if (is_div) {
       LoadValueDirectFixed(rl_src, rl_result.reg);
+
+      // Check if numerator is 0
+      OpRegImm(kOpCmp, rl_result.reg, 0);
+      LIR* branch = NewLIR2(kX86Jcc8, 0, kX86CondEq);
+
+      // handle 0x80000000 / -1
       OpRegImm(kOpCmp, rl_result.reg, 0x80000000);
       LIR *minint_branch = NewLIR2(kX86Jcc8, 0, kX86CondEq);
 
@@ -615,6 +621,7 @@
 
       // EAX already contains the right value (0x80000000),
       minint_branch->target = NewLIR0(kPseudoTargetLabel);
+      branch->target = NewLIR0(kPseudoTargetLabel);
     } else {
       // x % -1 == 0.
       LoadConstantNoClobber(rl_result.reg, 0);
@@ -627,6 +634,14 @@
       RegStorage rs_temp = AllocTypedTemp(false, kCoreReg);
       rl_result.reg.SetReg(rs_temp.GetReg());
     }
+
+    // Check if numerator is 0
+    OpRegImm(kOpCmp, rl_src.reg, 0);
+    LIR* branch = NewLIR2(kX86Jcc8, 0, kX86CondNe);
+    LoadConstantNoClobber(rl_result.reg, 0);
+    LIR* done = NewLIR1(kX86Jmp8, 0);
+    branch->target = NewLIR0(kPseudoTargetLabel);
+
     NewLIR3(kX86Lea32RM, rl_result.reg.GetReg(), rl_src.reg.GetReg(), std::abs(imm) - 1);
     NewLIR2(kX86Test32RR, rl_src.reg.GetReg(), rl_src.reg.GetReg());
     OpCondRegReg(kOpCmov, kCondPl, rl_result.reg, rl_src.reg);
@@ -635,6 +650,7 @@
     if (imm < 0) {
       OpReg(kOpNeg, rl_result.reg);
     }
+    done->target = NewLIR0(kPseudoTargetLabel);
   } else {
     CHECK(imm <= -2 || imm >= 2);
 
@@ -682,6 +698,13 @@
       LoadValueDirectFixed(rl_src, rs_r0);
     }
 
+    // Check if numerator is 0
+    OpRegImm(kOpCmp, rs_r0, 0);
+    LIR* branch = NewLIR2(kX86Jcc8, 0, kX86CondNe);
+    LoadConstantNoClobber(rs_r2, 0);
+    LIR* done = NewLIR1(kX86Jmp8, 0);
+    branch->target = NewLIR0(kPseudoTargetLabel);
+
     // EDX = magic.
     LoadConstantNoClobber(rs_r2, magic);
 
@@ -730,6 +753,7 @@
       // For this case, return the result in EAX.
       rl_result.reg.SetReg(r0);
     }
+    done->target = NewLIR0(kPseudoTargetLabel);
   }
 
   return rl_result;
@@ -761,6 +785,10 @@
     GenDivZeroCheck(rs_r1);
   }
 
+  // Check if numerator is 0
+  OpRegImm(kOpCmp, rs_r0, 0);
+  LIR* branch = NewLIR2(kX86Jcc8, 0, kX86CondEq);
+
   // Have to catch 0x80000000/-1 case, or we will get an exception!
   OpRegImm(kOpCmp, rs_r1, -1);
   LIR *minus_one_branch = NewLIR2(kX86Jcc8, 0, kX86CondNe);
@@ -769,6 +797,8 @@
   OpRegImm(kOpCmp, rs_r0, 0x80000000);
   LIR * minint_branch = NewLIR2(kX86Jcc8, 0, kX86CondNe);
 
+  branch->target = NewLIR0(kPseudoTargetLabel);
+
   // In 0x80000000/-1 case.
   if (!is_div) {
     // For DIV, EAX is already right. For REM, we need EDX 0.
diff --git a/test/012-math/expected.txt b/test/012-math/expected.txt
index af9708e..75a559e 100644
--- a/test/012-math/expected.txt
+++ b/test/012-math/expected.txt
@@ -30,3 +30,11 @@
 f:21.0
 f:3.0
 f:3.0
+0
+0
+0
+0
+0
+0
+0
+0
diff --git a/test/012-math/src/Main.java b/test/012-math/src/Main.java
index a4a8c71..07b7540 100644
--- a/test/012-math/src/Main.java
+++ b/test/012-math/src/Main.java
@@ -99,7 +99,27 @@
         f %= g;
         System.out.println("f:" +f);
     }
+    public static void math_012_numerator(int a, int b, int d, int e, int f) {
+        int c = 0;
+        c /= b;
+        System.out.println(c);
+        c %= b;
+        System.out.println(c);
+        c = a / b;
+        System.out.println(c);
+        c = a % b;
+        System.out.println(c);
+        c = c / d;
+        System.out.println(c);
+        c = c / e;
+        System.out.println(c);
+        c = c / f;
+        System.out.println(c);
+        c = c % f;
+        System.out.println(c);
+    }
     public static void main(String args[]) {
       math_012();
+      math_012_numerator(0, 3, -1, 4, 5);
     }
 }