Changeset 289354 in webkit for trunk/Source/JavaScriptCore/b3


Ignore:
Timestamp:
Feb 7, 2022, 7:00:28 PM (3 years ago)
Author:
[email protected]
Message:

Wasm crash on https://copy.sh/v86/?profile=dsl
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:
Location:
trunk/Source/JavaScriptCore/b3/air
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/b3/air/AirLowerStackArgs.cpp

    r287513 r289354  
    111111            inst.forEachArg(
    112112                [&] (Arg& arg, Arg::Role role, Bank, Width width) {
    113                     auto stackAddr = [&] (Value::OffsetType offsetFromFP) -> Arg {
     113                    auto stackAddr = [&] (unsigned instIndex, Value::OffsetType offsetFromFP) -> Arg {
    114114                        int32_t offsetFromSP = offsetFromFP + code.frameSize();
    115115
     
    138138                        return result;
    139139#elif CPU(X86_64)
     140                        UNUSED_PARAM(instIndex);
    140141                        // Can't happen on x86: immediates are always big enough for frame size.
    141142                        RELEASE_ASSERT_NOT_REACHED();
     
    172173                            insertionSet.insert(
    173174                                instIndex + 1, storeOpcode, inst.origin, operand,
    174                                 stackAddr(arg.offset() + 4 + slot->offsetFromFP()));
     175                                stackAddr(instIndex + 1, arg.offset() + 4 + slot->offsetFromFP()));
    175176                        }
    176                         arg = stackAddr(arg.offset() + slot->offsetFromFP());
     177                        arg = stackAddr(instIndex, arg.offset() + slot->offsetFromFP());
    177178                        break;
    178179                    }
    179180                    case Arg::CallArg:
    180                         arg = stackAddr(arg.offset() - code.frameSize());
     181                        arg = stackAddr(instIndex, arg.offset() - code.frameSize());
    181182                        break;
    182183                    default:
  • trunk/Source/JavaScriptCore/b3/air/testair.cpp

    r277920 r289354  
    23592359    auto runResult = compileAndRun<uint32_t>(proc);
    23602360    CHECK(runResult == 99);
     2361}
     2362
     2363void testZDefOfSpillSlotWithOffsetNeedingToBeMaterializedInARegister()
     2364{
     2365    if (Options::defaultB3OptLevel() == 2)
     2366        return;
     2367
     2368    B3::Procedure proc;
     2369    Code& code = proc.code();
     2370
     2371    BasicBlock* root = code.addBlock();
     2372
     2373    Vector<StackSlot*> slots;
     2374    for (unsigned i = 0; i < 10000; ++i)
     2375        slots.append(code.addStackSlot(8, StackSlotKind::Spill));
     2376
     2377    for (auto* slot : slots)
     2378        root->append(Move32, nullptr, Tmp(GPRInfo::argumentGPR0), Arg::stack(slot));
     2379
     2380    Tmp loadResult = code.newTmp(GP);
     2381    Tmp sum = code.newTmp(GP);
     2382    root->append(Move, nullptr, Arg::imm(0), sum);
     2383    for (auto* slot : slots) {
     2384        root->append(Move, nullptr, Arg::stack(slot), loadResult);
     2385        root->append(Add64, nullptr, loadResult, sum);
     2386    }
     2387    root->append(Move, nullptr, sum, Tmp(GPRInfo::returnValueGPR));
     2388    root->append(Ret64, nullptr, Tmp(GPRInfo::returnValueGPR));
     2389
     2390    int32_t result = compileAndRun<int>(proc, 1);
     2391    CHECK(result == 10000);
    23612392}
    23622393
     
    24562487    RUN(testLinearScanSpillRangesEarlyDef());
    24572488
     2489    RUN(testZDefOfSpillSlotWithOffsetNeedingToBeMaterializedInARegister());
     2490
    24582491    if (tasks.isEmpty())
    24592492        usage();
Note: See TracChangeset for help on using the changeset viewer.