Make sure that the address matcher correctly handles Shl(x, 1)
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 Nov 2015 19:29:34 +0000 (19:29 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 Nov 2015 19:29:34 +0000 (19:29 +0000)
https://bugs.webkit.org/show_bug.cgi?id=151316

Reviewed by Geoffrey Garen.

This optimization isn't really that awesome, but the nicest part of the change is just the
testing. If we ever do more cleverness with shifts, these tests will come in handy.

* b3/B3LowerToAir.cpp:
(JSC::B3::Air::LowerToAir::effectiveAddr):
* b3/testb3.cpp:
(JSC::B3::testLoadOffsetUsingAddNotConstant):
(JSC::B3::testLoadAddrShift):
(JSC::B3::testFramePointer):
(JSC::B3::run):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@192478 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/b3/B3LowerToAir.cpp
Source/JavaScriptCore/b3/testb3.cpp

index 4d47fbb..f9ba49a 100644 (file)
@@ -1,3 +1,21 @@
+2015-11-16  Filip Pizlo  <fpizlo@apple.com>
+
+        Make sure that the address matcher correctly handles Shl(x, 1)
+        https://bugs.webkit.org/show_bug.cgi?id=151316
+
+        Reviewed by Geoffrey Garen.
+
+        This optimization isn't really that awesome, but the nicest part of the change is just the
+        testing. If we ever do more cleverness with shifts, these tests will come in handy.
+
+        * b3/B3LowerToAir.cpp:
+        (JSC::B3::Air::LowerToAir::effectiveAddr):
+        * b3/testb3.cpp:
+        (JSC::B3::testLoadOffsetUsingAddNotConstant):
+        (JSC::B3::testLoadAddrShift):
+        (JSC::B3::testFramePointer):
+        (JSC::B3::run):
+
 2015-11-16  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [GTK] Use FTL by default when LLVM 3.7 is available
index 110c657..0e265f8 100644 (file)
@@ -395,6 +395,18 @@ private:
             return Arg::index(tmp(left), tmp(right));
         }
 
+        case Shl: {
+            Value* left = address->child(0);
+
+            // We'll never see child(1)->isInt32(0), since that would have been reduced. If the shift
+            // amount is greater than 1, then there isn't really anything smart that we could do here.
+            // We avoid using baseless indexes because their encoding isn't particularly efficient.
+            if (m_locked.contains(left) || !address->child(1)->isInt32(1))
+                return Arg::addr(tmp(address));
+
+            return Arg::index(tmp(left), tmp(left));
+        }
+
         case FramePointer:
             return Arg::addr(Tmp(GPRInfo::callFrameRegister));
 
index de7d6ab..ae69ec9 100644 (file)
@@ -1889,6 +1889,36 @@ void testLoadOffsetUsingAddNotConstant()
     CHECK(compileAndRun<int>(proc, &array[0]) == array[0] + array[1]);
 }
 
+void testLoadAddrShift(unsigned shift)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    int slots[2];
+
+    // Figure out which slot to use while having proper alignment for the shift.
+    int* slot;
+    uintptr_t arg;
+    for (unsigned i = sizeof(slots)/sizeof(slots[0]); i--;) {
+        slot = slots + i;
+        arg = bitwise_cast<uintptr_t>(slot) >> shift;
+        if (bitwise_cast<int*>(arg << shift) == slot)
+            break;
+    }
+
+    *slot = 8675309;
+    
+    root->appendNew<ControlValue>(
+        proc, Return, Origin(),
+        root->appendNew<MemoryValue>(
+            proc, Load, Int32, Origin(),
+            root->appendNew<Value>(
+                proc, Shl, Origin(),
+                root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
+                root->appendNew<Const32Value>(proc, Origin(), shift))));
+
+    CHECK(compileAndRun<int>(proc, arg) == 8675309);
+}
+
 void testFramePointer()
 {
     Procedure proc;
@@ -4362,6 +4392,10 @@ void run(const char* filter)
     RUN(testLoadOffsetUsingAdd());
     RUN(testLoadOffsetUsingAddInterference());
     RUN(testLoadOffsetUsingAddNotConstant());
+    RUN(testLoadAddrShift(0));
+    RUN(testLoadAddrShift(1));
+    RUN(testLoadAddrShift(2));
+    RUN(testLoadAddrShift(3));
     RUN(testFramePointer());
     RUN(testStackSlot());
     RUN(testLoadFromFramePointer());