Reviewers: Jakob,

Description:
Fix a bug in Div when all uses are truncating

Refine the related test cases to cover truncating cases

BUG=

Please review this at https://codereview.chromium.org/22964004/

SVN Base: https://github.com/v8/v8.git@master

Affected files:
  M src/arm/lithium-codegen-arm.cc
  M src/ia32/lithium-codegen-ia32.cc
  M src/x64/lithium-codegen-x64.cc
  M test/mjsunit/shift-for-integer-div.js


Index: src/arm/lithium-codegen-arm.cc
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 9ec80f819a062dbf3078fc4a0487b765177a19cb..d090f9203f66046ff8f4eecba405867802e3da87 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -1394,10 +1394,18 @@ void LCodeGen::DoDivI(LDivI* instr) {
     if (test_value != 0) {
       if (instr->hydrogen()->CheckFlag(
           HInstruction::kAllUsesTruncatingToInt32)) {
+        Label negative, done;
         __ cmp(dividend, Operand(0));
+        __ b(lt, &negative);
+        __ mov(dividend, Operand(dividend, ASR, power));
+        if (divisor < 0) __ rsb(dividend, dividend, Operand(0));
+        __ jmp(&done);
+
+        __ bind(&negative);
         __ rsb(dividend, dividend, Operand(0), LeaveCC, lt);
         __ mov(dividend, Operand(dividend, ASR, power));
- if (divisor > 0) __ rsb(dividend, dividend, Operand(0), LeaveCC, lt);
+        if (divisor > 0) __ rsb(dividend, dividend, Operand(0));
+        __ bind(&done);
         return;  // Don't fall through to "__ rsb" below.
       } else {
         // Deoptimize if remainder is not 0.
Index: src/ia32/lithium-codegen-ia32.cc
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 19c553bfa517a7b47bf462e7e8affae561830095..a6c1f5a7ed4975481f7709a96246aaa0ade2b8e4 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -1441,6 +1441,7 @@ void LCodeGen::DoDivI(LDivI* instr) {
         __ cmp(dividend, 0);
         __ j(less, &negative, Label::kNear);
         __ sar(dividend, power);
+        if (divisor < 0) __ neg(dividend);
         __ jmp(&done, Label::kNear);

         __ bind(&negative);
Index: src/x64/lithium-codegen-x64.cc
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index abb8c77b5b772cd0440251034944771b8277abd9..16478b287f6dfb99bfcf966c3f94243456c28d2c 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -1216,6 +1216,7 @@ void LCodeGen::DoDivI(LDivI* instr) {
         __ cmpl(dividend, Immediate(0));
         __ j(less, &negative, Label::kNear);
         __ sarl(dividend, Immediate(power));
+        if (divisor < 0) __ negl(dividend);
         __ jmp(&done, Label::kNear);

         __ bind(&negative);
Index: test/mjsunit/shift-for-integer-div.js
diff --git a/test/mjsunit/shift-for-integer-div.js b/test/mjsunit/shift-for-integer-div.js index 0fe1262292137e4146d5054bde05537a75e32032..ac8d90682d930541f061b81be66710d9b6803f07 100644
--- a/test/mjsunit/shift-for-integer-div.js
+++ b/test/mjsunit/shift-for-integer-div.js
@@ -1,4 +1,4 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -25,35 +25,63 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+// Flags: --allow-natives-syntax
+
 function divp4(x) {
   return x / 4;
 }

-for (var i = 0; i < 10000; i+=4) {
-  assertEquals(i >> 2, divp4(i));
-}
-
+divp4(8);
+divp4(8);
+%OptimizeFunctionOnNextCall(divp4);
+assertEquals(2, divp4(8));
 assertEquals(0.5, divp4(2));

+
 function divn4(x) {
   return x / (-4);
 }

-for (var i = 0; i < 10000; i+=4) {
-  assertEquals(-(i >> 2), divn4(i));
-}
-
+divn4(8);
+divn4(8);
+%OptimizeFunctionOnNextCall(divn4);
+assertEquals(-2, divn4(8));
+// Check for (0 / -x)
 assertEquals(-0, divn4(0));


+// Check for (kMinInt / -1)
 function divn1(x) {
   return x / (-1);
 }

-for (var i = 0; i < 10000; i++) {
-  assertEquals(-i, divn1(i));
+var two_31 = 1 << 31;
+divn1(2);
+divn1(2);
+%OptimizeFunctionOnNextCall(divn1);
+assertEquals(-2, divn1(2));
+assertEquals(two_31, divn1(-two_31));
+
+
+//Check for truncating to int32 case
+function divp4t(x) {
+  return (x / 4) | 0;
 }

-var min_int = -(0x7FFFFFFF)-1;
-assertEquals(-min_int, divn1(min_int));
+divp4t(8);
+divp4t(8);
+%OptimizeFunctionOnNextCall(divp4t);
+assertEquals(-1, divp4t(-5));
+assertEquals(1, divp4t(5));
+assertOptimized(divp4t);
+
+function divn4t(x) {
+  return (x / -4) | 0;
+}

+divn4t(8);
+divn4t(8);
+%OptimizeFunctionOnNextCall(divn4t);
+assertEquals(1, divn4t(-5));
+assertEquals(-1, divn4t(5));
+assertOptimized(divn4t);


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to