B3::LowerToAir should recognize Neg (i.e. Sub($0, value))
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Nov 2015 00:41:14 +0000 (00:41 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Nov 2015 00:41:14 +0000 (00:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=150759

Reviewed by Benjamin Poulain.

Adds various forms of Sub(0, value) and compiles them as Neg. Also fixes a bug in
StoreSubLoad. This bug was correctness-benign, so I couldn't add a test for it.

* b3/B3LowerToAir.cpp:
(JSC::B3::Air::LowerToAir::immOrTmp):
(JSC::B3::Air::LowerToAir::appendUnOp):
(JSC::B3::Air::LowerToAir::appendBinOp):
(JSC::B3::Air::LowerToAir::tryAppendStoreUnOp):
(JSC::B3::Air::LowerToAir::tryAppendStoreBinOp):
(JSC::B3::Air::LowerToAir::trySub):
(JSC::B3::Air::LowerToAir::tryStoreSubLoad):
* b3/B3LoweringMatcher.patterns:
* b3/air/AirOpcode.opcodes:
* b3/testb3.cpp:
(JSC::B3::testAdd1Ptr):
(JSC::B3::testNeg32):
(JSC::B3::testNegPtr):
(JSC::B3::testStoreAddLoad):
(JSC::B3::testStoreAddAndLoad):
(JSC::B3::testStoreNegLoad32):
(JSC::B3::testStoreNegLoadPtr):
(JSC::B3::testAdd1Uncommuted):
(JSC::B3::run):

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

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/b3/B3LowerToAir.cpp
Source/JavaScriptCore/b3/B3LoweringMatcher.patterns
Source/JavaScriptCore/b3/air/AirOpcode.opcodes
Source/JavaScriptCore/b3/testb3.cpp

index c036054..90af471 100644 (file)
@@ -1,5 +1,36 @@
 2015-11-03  Filip Pizlo  <fpizlo@apple.com>
 
+        B3::LowerToAir should recognize Neg (i.e. Sub($0, value))
+        https://bugs.webkit.org/show_bug.cgi?id=150759
+
+        Reviewed by Benjamin Poulain.
+
+        Adds various forms of Sub(0, value) and compiles them as Neg. Also fixes a bug in
+        StoreSubLoad. This bug was correctness-benign, so I couldn't add a test for it.
+
+        * b3/B3LowerToAir.cpp:
+        (JSC::B3::Air::LowerToAir::immOrTmp):
+        (JSC::B3::Air::LowerToAir::appendUnOp):
+        (JSC::B3::Air::LowerToAir::appendBinOp):
+        (JSC::B3::Air::LowerToAir::tryAppendStoreUnOp):
+        (JSC::B3::Air::LowerToAir::tryAppendStoreBinOp):
+        (JSC::B3::Air::LowerToAir::trySub):
+        (JSC::B3::Air::LowerToAir::tryStoreSubLoad):
+        * b3/B3LoweringMatcher.patterns:
+        * b3/air/AirOpcode.opcodes:
+        * b3/testb3.cpp:
+        (JSC::B3::testAdd1Ptr):
+        (JSC::B3::testNeg32):
+        (JSC::B3::testNegPtr):
+        (JSC::B3::testStoreAddLoad):
+        (JSC::B3::testStoreAddAndLoad):
+        (JSC::B3::testStoreNegLoad32):
+        (JSC::B3::testStoreNegLoadPtr):
+        (JSC::B3::testAdd1Uncommuted):
+        (JSC::B3::run):
+
+2015-11-03  Filip Pizlo  <fpizlo@apple.com>
+
         B3::Values that have effects should allow specification of custom HeapRanges
         https://bugs.webkit.org/show_bug.cgi?id=150535
 
index ea0de49..09387b8 100644 (file)
@@ -277,6 +277,25 @@ public:
         return tmp(value);
     }
 
+    template<Air::Opcode opcode>
+    void appendUnOp(Value* value)
+    {
+        Tmp result = tmp(currentValue);
+
+        // Two operand forms like:
+        //     Op a, b
+        // mean something like:
+        //     b = Op a
+
+        if (isValidForm(opcode, Arg::Tmp, Arg::Tmp)) {
+            append(opcode, tmp(value), result);
+            return;
+        }
+
+        append(relaxedMoveForType(currentValue->type()), tmp(value), result);
+        append(opcode, result);
+    }
+
     template<Air::Opcode opcode, Commutativity commutativity = NotCommutative>
     void appendBinOp(Value* left, Value* right)
     {
@@ -352,6 +371,20 @@ public:
         append(opcode, tmp(right), result);
     }
 
+    template<Air::Opcode opcode>
+    bool tryAppendStoreUnOp(Value* value)
+    {
+        Arg storeAddr = addr(currentValue);
+        ASSERT(storeAddr);
+
+        if (loadAddr(value) != storeAddr)
+            return false;
+
+        commitInternal(value);
+        append(opcode, storeAddr);
+        return true;
+    }
+
     template<Air::Opcode opcode, Commutativity commutativity = NotCommutative>
     bool tryAppendStoreBinOp(Value* left, Value* right)
     {
@@ -628,10 +661,16 @@ public:
     {
         switch (left->type()) {
         case Int32:
-            appendBinOp<Sub32>(left, right);
+            if (left->isInt32(0))
+                appendUnOp<Neg32>(right);
+            else
+                appendBinOp<Sub32>(left, right);
             return true;
         case Int64:
-            appendBinOp<Sub64>(left, right);
+            if (left->isInt64(0))
+                appendUnOp<Neg64>(right);
+            else
+                appendBinOp<Sub64>(left, right);
             return true;
         default:
             // FIXME: Implement more types!
@@ -700,6 +739,8 @@ public:
     {
         switch (left->type()) {
         case Int32:
+            if (left->isInt32(0))
+                return tryAppendStoreUnOp<Neg32>(right);
             return tryAppendStoreBinOp<Sub32, NotCommutative>(left, right);
         default:
             // FIXME: Implement more types!
index 7ccfde6..fc63225 100644 (file)
@@ -38,7 +38,7 @@ Or = BitOr(left, right)
 Shl = Shl(value, amount)
 
 StoreAddLoad = Store(Add(left, right), address)
-StoreSubLoad = Store(Add(left, right), address)
+StoreSubLoad = Store(Sub(left, right), address)
 StoreAndLoad = Store(BitAnd(left, right), address)
 Store = Store(value, address)
 
index 3d02502..04b5011 100644 (file)
@@ -89,6 +89,13 @@ Sub64 U:G, UD:G
     Tmp, Tmp
     Imm, Tmp
 
+Neg32 UD:G
+    Tmp
+    Addr
+
+Neg64 UD:G
+    Tmp
+
 Lea UA:G, D:G
     Addr, Tmp
 
index 0adc8fc..f603d7b 100644 (file)
@@ -835,6 +835,36 @@ void testAdd1Ptr(intptr_t value)
     CHECK(compileAndRun<intptr_t>(proc, value) == value + 1);
 }
 
+void testNeg32(int32_t value)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    root->appendNew<ControlValue>(
+        proc, Return, Origin(),
+        root->appendNew<Value>(
+            proc, Sub, Origin(),
+            root->appendNew<Const32Value>(proc, Origin(), 0),
+            root->appendNew<Value>(
+                proc, Trunc, Origin(),
+                root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
+
+    CHECK(compileAndRun<int32_t>(proc, value) == -value);
+}
+
+void testNegPtr(intptr_t value)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    root->appendNew<ControlValue>(
+        proc, Return, Origin(),
+        root->appendNew<Value>(
+            proc, Sub, Origin(),
+            root->appendNew<ConstPtrValue>(proc, Origin(), 0),
+            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
+
+    CHECK(compileAndRun<intptr_t>(proc, value) == -value);
+}
+
 void testStoreAddLoad(int amount)
 {
     Procedure proc;
@@ -931,6 +961,54 @@ void testStoreAddAndLoad(int amount, int mask)
     CHECK(slot == ((37 + amount) & mask));
 }
 
+void testStoreNegLoad32(int32_t value)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+
+    int32_t slot = value;
+
+    ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
+    
+    root->appendNew<MemoryValue>(
+        proc, Store, Origin(),
+        root->appendNew<Value>(
+            proc, Sub, Origin(),
+            root->appendNew<Const32Value>(proc, Origin(), 0),
+            root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr)),
+        slotPtr);
+    
+    root->appendNew<ControlValue>(
+        proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
+
+    CHECK(!compileAndRun<int32_t>(proc));
+    CHECK(slot == -value);
+}
+
+void testStoreNegLoadPtr(intptr_t value)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+
+    intptr_t slot = value;
+
+    ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
+    
+    root->appendNew<MemoryValue>(
+        proc, Store, Origin(),
+        root->appendNew<Value>(
+            proc, Sub, Origin(),
+            root->appendNew<ConstPtrValue>(proc, Origin(), 0),
+            root->appendNew<MemoryValue>(proc, Load, pointerType(), Origin(), slotPtr)),
+        slotPtr);
+    
+    root->appendNew<ControlValue>(
+        proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
+
+    CHECK(!compileAndRun<int32_t>(proc));
+    CHECK(slot == -value);
+}
+
 void testAdd1Uncommuted(int value)
 {
     Procedure proc;
@@ -1866,11 +1944,15 @@ void run(const char* filter)
     RUN(testAdd1(45));
     RUN(testAdd1Ptr(51));
     RUN(testAdd1Ptr(bitwise_cast<intptr_t>(vm)));
+    RUN(testNeg32(52));
+    RUN(testNegPtr(53));
     RUN(testStoreAddLoad(46));
     RUN(testStoreSubLoad(46));
     RUN(testStoreAddLoadInterference(52));
     RUN(testStoreAddAndLoad(47, 0xffff));
     RUN(testStoreAddAndLoad(470000, 0xffff));
+    RUN(testStoreNegLoad32(54));
+    RUN(testStoreNegLoadPtr(55));
     RUN(testAdd1Uncommuted(48));
     RUN(testLoadOffset());
     RUN(testLoadOffsetNotConstant());