[aarch64][Linux] m_allowScratchRegister assert hit in MacroAssemblerARM64 under B3...
authorzandobersek@gmail.com <zandobersek@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 2 May 2017 04:32:08 +0000 (04:32 +0000)
committerzandobersek@gmail.com <zandobersek@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 2 May 2017 04:32:08 +0000 (04:32 +0000)
https://bugs.webkit.org/show_bug.cgi?id=170672

Reviewed by Filip Pizlo.

In Air::CCallSpecial::admitsStack() we reject admitting the callee argument on
the stack for ARM64 because that can lead to disallowed usage of the scratch
register in MacroAssemblerARM64 when generating a call with an address Arg
in Air::CCallSpecial::generate().

The testLinearScanWithCalleeOnStack test is added to testb3. It reproduces the
original issue by force-spilling everything on the stack and enforcing the use
of the linear scan register allocation by using an optimization level of 1.

* b3/air/AirCCallSpecial.cpp:
(JSC::B3::Air::CCallSpecial::admitsStack):
* b3/testb3.cpp:
(JSC::B3::testLinearScanWithCalleeOnStack):
(JSC::B3::run):

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

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/b3/air/AirCCallSpecial.cpp
Source/JavaScriptCore/b3/testb3.cpp

index 8f9885b..c304696 100644 (file)
@@ -1,3 +1,25 @@
+2017-05-01  Zan Dobersek  <zdobersek@igalia.com>
+
+        [aarch64][Linux] m_allowScratchRegister assert hit in MacroAssemblerARM64 under B3::Air::CCallSpecial::generate()
+        https://bugs.webkit.org/show_bug.cgi?id=170672
+
+        Reviewed by Filip Pizlo.
+
+        In Air::CCallSpecial::admitsStack() we reject admitting the callee argument on
+        the stack for ARM64 because that can lead to disallowed usage of the scratch
+        register in MacroAssemblerARM64 when generating a call with an address Arg
+        in Air::CCallSpecial::generate().
+
+        The testLinearScanWithCalleeOnStack test is added to testb3. It reproduces the
+        original issue by force-spilling everything on the stack and enforcing the use
+        of the linear scan register allocation by using an optimization level of 1.
+
+        * b3/air/AirCCallSpecial.cpp:
+        (JSC::B3::Air::CCallSpecial::admitsStack):
+        * b3/testb3.cpp:
+        (JSC::B3::testLinearScanWithCalleeOnStack):
+        (JSC::B3::run):
+
 2017-05-01  David Kilzer  <ddkilzer@apple.com>
 
         Stop using sprintf() in JavaScriptCore debugger
index 0c803cd..2471fbb 100644 (file)
@@ -110,9 +110,10 @@ bool CCallSpecial::isValid(Inst& inst)
 
 bool CCallSpecial::admitsStack(Inst&, unsigned argIndex)
 {
-    // The callee can be on the stack.
+    // The callee can be on the stack unless targeting ARM64, where we can't later properly
+    // handle an Addr callee argument in generate() due to disallowed scratch register usage.
     if (argIndex == calleeArgOffset)
-        return true;
+        return !isARM64();
     
     return false;
 }
index 077dc0d..d023800 100644 (file)
@@ -10427,6 +10427,37 @@ void testCallFunctionWithHellaFloatArguments()
     CHECK(compileAndRun<float>(proc) == functionWithHellaFloatArguments(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26));
 }
 
+void testLinearScanWithCalleeOnStack()
+{
+    // This tests proper CCall generation when compiling with a lower optimization
+    // level and operating with a callee argument that's spilt on the stack.
+    // On ARM64, this caused an assert in MacroAssemblerARM64 because of disallowed
+    // use of the scratch register.
+    // https://bugs.webkit.org/show_bug.cgi?id=170672
+
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+
+    root->appendNewControlValue(
+        proc, Return, Origin(),
+        root->appendNew<CCallValue>(
+            proc, Int32, Origin(),
+            root->appendNew<ConstPtrValue>(proc, Origin(), bitwise_cast<void*>(simpleFunction)),
+            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
+            root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
+
+    // Force the linear scan algorithm to spill everything.
+    auto original = Options::airLinearScanSpillsEverything();
+    Options::airLinearScanSpillsEverything() = true;
+
+    // Compiling with 1 as the optimization level enforces the use of linear scan
+    // for register allocation.
+    auto code = compileProc(proc, 1);
+    CHECK_EQ(invoke<int>(*code, 41, 1), 42);
+
+    Options::airLinearScanSpillsEverything() = original;
+}
+
 void testChillDiv(int num, int den, int res)
 {
     // Test non-constant.
@@ -16319,6 +16350,8 @@ void run(const char* filter)
     RUN_BINARY(testCallSimpleFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
     RUN(testCallFunctionWithHellaFloatArguments());
 
+    RUN(testLinearScanWithCalleeOnStack());
+
     RUN(testChillDiv(4, 2, 2));
     RUN(testChillDiv(1, 0, 0));
     RUN(testChillDiv(0, 0, 0));