Ignore:
Timestamp:
Apr 27, 2017, 4:52:41 PM (8 years ago)
Author:
[email protected]
Message:

B3::FoldPathConstants does not consider the fall through case for Switch
https://bugs.webkit.org/show_bug.cgi?id=171390

Reviewed by Filip Pizlo.

foldPathConstants was not taking into account a Switch's default
case when it tried to constant propagate the switch's operand value.
e.g, we incorrectly transformed this code:

`
x = argumentGPR0;
switch (x) {
case 10: return 20;

case 0:
default: return x == 0;
}
`

into:
`
x = argumentGPR0;
switch (x) {
case 10: return 20;

case 0:
default: return 1;
}
`

Because we didn't take into account the default case, we incorrectly
optimized the code as if case 0's block was only reachable if x is
equal to zero. This is obviously not true, since it's the same block
as the default case.

This fix ensures that we can run the WebAssembly Tanks demo even when
we set webAssemblyBBQOptimizationLevel=2.

  • b3/B3FoldPathConstants.cpp:
  • b3/B3SwitchValue.cpp:

(JSC::B3::SwitchValue::fallThrough):
(JSC::B3::SwitchValue::removeCase): Deleted.

  • b3/B3SwitchValue.h:
  • b3/testb3.cpp:

(JSC::B3::testCallFunctionWithHellaArguments):
(JSC::B3::testSwitchSameCaseAsDefault):
(JSC::B3::testWasmBoundsCheck):
(JSC::B3::run):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/b3/testb3.cpp

    r215533 r215908  
    1029210292void testCallFunctionWithHellaArguments()
    1029310293{
     10294    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=171392
     10295    return;
     10296
    1029410297    Procedure proc;
    1029510298    BasicBlock* root = proc.addBlock();
     
    1074710750    CHECK(!invoke<int32_t>(*code, degree * gap, 42, 11));
    1074810751    CHECK(!invoke<int32_t>(*code, degree * gap + 1, 42, 11));
     10752}
     10753
     10754void testSwitchSameCaseAsDefault()
     10755{
     10756    Procedure proc;
     10757    BasicBlock* root = proc.addBlock();
     10758
     10759    BasicBlock* return10 = proc.addBlock();
     10760    return10->appendNewControlValue(
     10761        proc, Return, Origin(),
     10762        return10->appendNew<Const32Value>(proc, Origin(), 10));
     10763
     10764    Value* switchOperand = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
     10765
     10766    BasicBlock* caseAndDefault = proc.addBlock();
     10767    caseAndDefault->appendNewControlValue(
     10768        proc, Return, Origin(),
     10769            caseAndDefault->appendNew<Value>(
     10770                proc, Equal, Origin(),
     10771                switchOperand, caseAndDefault->appendNew<ConstPtrValue>(proc, Origin(), 0)));
     10772
     10773    SwitchValue* switchValue = root->appendNew<SwitchValue>(proc, Origin(), switchOperand);
     10774
     10775    switchValue->appendCase(SwitchCase(100, FrequentedBlock(return10)));
     10776
     10777    // Because caseAndDefault is reached both as default case, and when it's 0,
     10778    // we should not incorrectly optimize and assume that switchOperand==0.
     10779    switchValue->appendCase(SwitchCase(0, FrequentedBlock(caseAndDefault)));
     10780    switchValue->setFallThrough(FrequentedBlock(caseAndDefault));
     10781
     10782    auto code = compileProc(proc);
     10783
     10784    CHECK(invoke<int32_t>(*code, 100) == 10);
     10785    CHECK(invoke<int32_t>(*code, 0) == 1);
     10786    CHECK(invoke<int32_t>(*code, 1) == 0);
     10787    CHECK(invoke<int32_t>(*code, 2) == 0);
     10788    CHECK(invoke<int32_t>(*code, 99) == 0);
     10789    CHECK(invoke<int32_t>(*code, 0xbaadbeef) == 0);
    1074910790}
    1075010791
     
    1516715208void testWasmBoundsCheck(unsigned offset)
    1516815209{
     15210    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=171392
     15211    return;
     15212
    1516915213    Procedure proc;
    1517015214    GPRReg pinned = GPRInfo::argumentGPR1;
     
    1631716361    RUN(testSwitch(100, 1));
    1631816362    RUN(testSwitch(100, 100));
     16363
     16364    RUN(testSwitchSameCaseAsDefault());
    1631916365
    1632016366    RUN(testSwitchChillDiv(0, 1));
Note: See TracChangeset for help on using the changeset viewer.