Title: [289354] trunk/Source/_javascript_Core
Revision
289354
Author
sbar...@apple.com
Date
2022-02-07 19:00:28 -0800 (Mon, 07 Feb 2022)

Log Message

Wasm crash on https://copy.sh/v86/?profile=""
https://bugs.webkit.org/show_bug.cgi?id=236037
rdar://88358719

Reviewed by Mark Lam.

Lower stack args in Air had a bug where it was emitting a constant
materialization at the wrong instruction offset for certain types
of spill instructions. This happens when we have a stack slot that
is 8 bytes wide, but we're emitting a zero def Move32. We need to
zero the upper 4 bytes. However, there is also code inside lower
stack args that uses the temp register when encountering offsets
that are too large to encode in a single instruction. However,
this offset materialization code for the second Move32 to zero
the upper bytes was happening before the actual store. For example,
we'd end up with:
movz x16, #k
movz x16, #k2
stur x1, [x16]
stur zr, [x16]

instead of
movz x16, #k
stur x1, [x16]
movz x16, #k2
stur zr, [x16]

* b3/air/AirLowerStackArgs.cpp:
(JSC::B3::Air::lowerStackArgs):
* b3/air/testair.cpp:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (289353 => 289354)


--- trunk/Source/_javascript_Core/ChangeLog	2022-02-08 02:58:30 UTC (rev 289353)
+++ trunk/Source/_javascript_Core/ChangeLog	2022-02-08 03:00:28 UTC (rev 289354)
@@ -1,3 +1,36 @@
+2022-02-07  Saam Barati  <sbar...@apple.com>
+
+        Wasm crash on https://copy.sh/v86/?profile=""
+        https://bugs.webkit.org/show_bug.cgi?id=236037
+        rdar://88358719
+
+        Reviewed by Mark Lam.
+
+        Lower stack args in Air had a bug where it was emitting a constant
+        materialization at the wrong instruction offset for certain types
+        of spill instructions. This happens when we have a stack slot that
+        is 8 bytes wide, but we're emitting a zero def Move32. We need to
+        zero the upper 4 bytes. However, there is also code inside lower
+        stack args that uses the temp register when encountering offsets
+        that are too large to encode in a single instruction. However,
+        this offset materialization code for the second Move32 to zero
+        the upper bytes was happening before the actual store. For example,
+        we'd end up with:
+        movz x16, #k
+        movz x16, #k2
+        stur x1, [x16]
+        stur zr, [x16]
+        
+        instead of
+        movz x16, #k
+        stur x1, [x16]
+        movz x16, #k2
+        stur zr, [x16]
+
+        * b3/air/AirLowerStackArgs.cpp:
+        (JSC::B3::Air::lowerStackArgs):
+        * b3/air/testair.cpp:
+
 2022-02-06  Lauro Moura  <lmo...@igalia.com>
 
         Unreviewed, non-unified build fixes

Modified: trunk/Source/_javascript_Core/b3/air/AirLowerStackArgs.cpp (289353 => 289354)


--- trunk/Source/_javascript_Core/b3/air/AirLowerStackArgs.cpp	2022-02-08 02:58:30 UTC (rev 289353)
+++ trunk/Source/_javascript_Core/b3/air/AirLowerStackArgs.cpp	2022-02-08 03:00:28 UTC (rev 289354)
@@ -110,7 +110,7 @@
 
             inst.forEachArg(
                 [&] (Arg& arg, Arg::Role role, Bank, Width width) {
-                    auto stackAddr = [&] (Value::OffsetType offsetFromFP) -> Arg {
+                    auto stackAddr = [&] (unsigned instIndex, Value::OffsetType offsetFromFP) -> Arg {
                         int32_t offsetFromSP = offsetFromFP + code.frameSize();
 
                         if (inst.admitsExtendedOffsetAddr(arg)) {
@@ -137,6 +137,7 @@
                         result = Arg::addr(tmp, 0);
                         return result;
 #elif CPU(X86_64)
+                        UNUSED_PARAM(instIndex);
                         // Can't happen on x86: immediates are always big enough for frame size.
                         RELEASE_ASSERT_NOT_REACHED();
 #else
@@ -171,13 +172,13 @@
                             RELEASE_ASSERT(isValidForm(storeOpcode, operandKind, Arg::Stack));
                             insertionSet.insert(
                                 instIndex + 1, storeOpcode, inst.origin, operand,
-                                stackAddr(arg.offset() + 4 + slot->offsetFromFP()));
+                                stackAddr(instIndex + 1, arg.offset() + 4 + slot->offsetFromFP()));
                         }
-                        arg = stackAddr(arg.offset() + slot->offsetFromFP());
+                        arg = stackAddr(instIndex, arg.offset() + slot->offsetFromFP());
                         break;
                     }
                     case Arg::CallArg:
-                        arg = stackAddr(arg.offset() - code.frameSize());
+                        arg = stackAddr(instIndex, arg.offset() - code.frameSize());
                         break;
                     default:
                         break;

Modified: trunk/Source/_javascript_Core/b3/air/testair.cpp (289353 => 289354)


--- trunk/Source/_javascript_Core/b3/air/testair.cpp	2022-02-08 02:58:30 UTC (rev 289353)
+++ trunk/Source/_javascript_Core/b3/air/testair.cpp	2022-02-08 03:00:28 UTC (rev 289354)
@@ -2360,6 +2360,37 @@
     CHECK(runResult == 99);
 }
 
+void testZDefOfSpillSlotWithOffsetNeedingToBeMaterializedInARegister()
+{
+    if (Options::defaultB3OptLevel() == 2)
+        return;
+
+    B3::Procedure proc;
+    Code& code = proc.code();
+
+    BasicBlock* root = code.addBlock();
+
+    Vector<StackSlot*> slots;
+    for (unsigned i = 0; i < 10000; ++i)
+        slots.append(code.addStackSlot(8, StackSlotKind::Spill));
+
+    for (auto* slot : slots)
+        root->append(Move32, nullptr, Tmp(GPRInfo::argumentGPR0), Arg::stack(slot));
+
+    Tmp loadResult = code.newTmp(GP);
+    Tmp sum = code.newTmp(GP);
+    root->append(Move, nullptr, Arg::imm(0), sum);
+    for (auto* slot : slots) {
+        root->append(Move, nullptr, Arg::stack(slot), loadResult);
+        root->append(Add64, nullptr, loadResult, sum);
+    }
+    root->append(Move, nullptr, sum, Tmp(GPRInfo::returnValueGPR));
+    root->append(Ret64, nullptr, Tmp(GPRInfo::returnValueGPR));
+
+    int32_t result = compileAndRun<int>(proc, 1);
+    CHECK(result == 10000);
+}
+
 #define PREFIX "O", Options::defaultB3OptLevel(), ": "
 
 #define RUN(test) do {                                 \
@@ -2455,6 +2486,8 @@
     RUN(testLinearScanSpillRangesLateUse());
     RUN(testLinearScanSpillRangesEarlyDef());
 
+    RUN(testZDefOfSpillSlotWithOffsetNeedingToBeMaterializedInARegister());
+
     if (tasks.isEmpty())
         usage();
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to