[turbofan] Bug fix in arm64 ubfx selection.
authorbaptiste.afsa@arm.com <baptiste.afsa@arm.com>
Wed, 29 Oct 2014 16:47:10 +0000 (16:47 +0000)
committerbaptiste.afsa@arm.com <baptiste.afsa@arm.com>
Wed, 29 Oct 2014 16:47:45 +0000 (16:47 +0000)
R=bmeurer@chromium.org

Review URL: https://codereview.chromium.org/687193002

Cr-Commit-Position: refs/heads/master@{#24989}
git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24989 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/compiler/arm64/instruction-selector-arm64.cc
test/mjsunit/mjsunit.status
test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc

index 014525f..40cb207 100644 (file)
@@ -438,6 +438,13 @@ void InstructionSelector::VisitWord32And(Node* node) {
       // significant bits.
       Int32BinopMatcher mleft(m.left().node());
       if (mleft.right().IsInRange(0, 31)) {
+        // Ubfx cannot extract bits past the register size, however since
+        // shifting the original value would have introduced some zeros we can
+        // still use ubfx with a smaller mask and the remaining bits will be
+        // zeros.
+        uint32_t lsb = mleft.right().Value();
+        if (lsb + mask_width > 32) mask_width = 32 - lsb;
+
         Emit(kArm64Ubfx32, g.DefineAsRegister(node),
              g.UseRegister(mleft.left().node()),
              g.UseImmediate(mleft.right().node()), g.TempImmediate(mask_width));
@@ -468,6 +475,13 @@ void InstructionSelector::VisitWord64And(Node* node) {
       // significant bits.
       Int64BinopMatcher mleft(m.left().node());
       if (mleft.right().IsInRange(0, 63)) {
+        // Ubfx cannot extract bits past the register size, however since
+        // shifting the original value would have introduced some zeros we can
+        // still use ubfx with a smaller mask and the remaining bits will be
+        // zeros.
+        uint64_t lsb = mleft.right().Value();
+        if (lsb + mask_width > 64) mask_width = 64 - lsb;
+
         Emit(kArm64Ubfx, g.DefineAsRegister(node),
              g.UseRegister(mleft.left().node()),
              g.UseImmediate(mleft.right().node()), g.TempImmediate(mask_width));
index 1eefecd..aa263aa 100644 (file)
   'unicodelctest-no-optimization': [PASS, SLOW],
   'unicodelctest': [PASS, SLOW],
   'unicode-test': [PASS, SLOW],
-
-  # TODO(bmeurer, Rodolph.Perfetta@arm.com): Fails with turbo fan.
-  'numops-fuzz-part1': [PASS, NO_VARIANTS],
-  'numops-fuzz-part2': [PASS, NO_VARIANTS],
 }],  # 'arch == arm64'
 
 ['arch == arm64 and mode == debug and simulator_run == True', {
index 8a6384d..ad9d607 100644 (file)
@@ -1779,7 +1779,8 @@ TEST_F(InstructionSelectorTest, Word32AndWithImmediateWithWord32Shr) {
       EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode());
       ASSERT_EQ(3U, s[0]->InputCount());
       EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
-      EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
+      int32_t actual_width = (lsb + width > 32) ? (32 - lsb) : width;
+      EXPECT_EQ(actual_width, s.ToInt32(s[0]->InputAt(2)));
     }
   }
   TRACED_FORRANGE(int32_t, lsb, 1, 31) {
@@ -1793,15 +1794,16 @@ TEST_F(InstructionSelectorTest, Word32AndWithImmediateWithWord32Shr) {
       EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode());
       ASSERT_EQ(3U, s[0]->InputCount());
       EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
-      EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
+      int32_t actual_width = (lsb + width > 32) ? (32 - lsb) : width;
+      EXPECT_EQ(actual_width, s.ToInt32(s[0]->InputAt(2)));
     }
   }
 }
 
 
 TEST_F(InstructionSelectorTest, Word64AndWithImmediateWithWord64Shr) {
-  TRACED_FORRANGE(int32_t, lsb, 1, 31) {
-    TRACED_FORRANGE(int32_t, width, 1, 31) {
+  TRACED_FORRANGE(int64_t, lsb, 1, 63) {
+    TRACED_FORRANGE(int64_t, width, 1, 63) {
       uint64_t msk = (V8_UINT64_C(1) << width) - 1;
       StreamBuilder m(this, kMachInt64, kMachInt64);
       m.Return(m.Word64And(m.Word64Shr(m.Parameter(0), m.Int64Constant(lsb)),
@@ -1811,11 +1813,12 @@ TEST_F(InstructionSelectorTest, Word64AndWithImmediateWithWord64Shr) {
       EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode());
       ASSERT_EQ(3U, s[0]->InputCount());
       EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1)));
-      EXPECT_EQ(width, s.ToInt64(s[0]->InputAt(2)));
+      int64_t actual_width = (lsb + width > 64) ? (64 - lsb) : width;
+      EXPECT_EQ(actual_width, s.ToInt64(s[0]->InputAt(2)));
     }
   }
-  TRACED_FORRANGE(int32_t, lsb, 1, 31) {
-    TRACED_FORRANGE(int32_t, width, 1, 31) {
+  TRACED_FORRANGE(int64_t, lsb, 1, 63) {
+    TRACED_FORRANGE(int64_t, width, 1, 63) {
       uint64_t msk = (V8_UINT64_C(1) << width) - 1;
       StreamBuilder m(this, kMachInt64, kMachInt64);
       m.Return(m.Word64And(m.Int64Constant(msk),
@@ -1825,7 +1828,8 @@ TEST_F(InstructionSelectorTest, Word64AndWithImmediateWithWord64Shr) {
       EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode());
       ASSERT_EQ(3U, s[0]->InputCount());
       EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1)));
-      EXPECT_EQ(width, s.ToInt64(s[0]->InputAt(2)));
+      int64_t actual_width = (lsb + width > 64) ? (64 - lsb) : width;
+      EXPECT_EQ(actual_width, s.ToInt64(s[0]->InputAt(2)));
     }
   }
 }