Changeset 195422 in webkit


Ignore:
Timestamp:
Jan 21, 2016 2:56:21 PM (8 years ago)
Author:
benjamin@webkit.org
Message:

[JSC] foldPathConstants() makes invalid assumptions with Switch
https://bugs.webkit.org/show_bug.cgi?id=153324

Reviewed by Filip Pizlo.

If a Switch() has two cases pointing to the same basic block, foldPathConstants()
was adding two override for that block with two different constants.
If the block with the Switch dominates the target, both override were equally valid
and we were assuming any of the constants as the value in the target block.

See testSwitchTargettingSameBlockFoldPathConstant() for an example that breaks.

This patch adds checks to ignore any block that is reached more than
once by the control value.

  • b3/B3FoldPathConstants.cpp:
  • b3/B3Generate.cpp:

(JSC::B3::generateToAir):

  • b3/testb3.cpp:

(JSC::B3::testSwitchTargettingSameBlock):
(JSC::B3::testSwitchTargettingSameBlockFoldPathConstant):
(JSC::B3::run):

Location:
trunk/Source/JavaScriptCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r195419 r195422  
     12016-01-21  Benjamin Poulain  <benjamin@webkit.org>
     2
     3        [JSC] foldPathConstants() makes invalid assumptions with Switch
     4        https://bugs.webkit.org/show_bug.cgi?id=153324
     5
     6        Reviewed by Filip Pizlo.
     7
     8        If a Switch() has two cases pointing to the same basic block, foldPathConstants()
     9        was adding two override for that block with two different constants.
     10        If the block with the Switch dominates the target, both override were equally valid
     11        and we were assuming any of the constants as the value in the target block.
     12
     13        See testSwitchTargettingSameBlockFoldPathConstant() for an example that breaks.
     14
     15        This patch adds checks to ignore any block that is reached more than
     16        once by the control value.
     17
     18        * b3/B3FoldPathConstants.cpp:
     19        * b3/B3Generate.cpp:
     20        (JSC::B3::generateToAir):
     21        * b3/testb3.cpp:
     22        (JSC::B3::testSwitchTargettingSameBlock):
     23        (JSC::B3::testSwitchTargettingSameBlockFoldPathConstant):
     24        (JSC::B3::run):
     25
    1262016-01-21  Filip Pizlo  <fpizlo@apple.com>
    227
  • trunk/Source/JavaScriptCore/b3/B3FoldPathConstants.cpp

    r195395 r195422  
    9191            switch (branch->opcode()) {
    9292            case Branch:
     93                if (branch->successorBlock(0) == branch->successorBlock(1))
     94                    continue;
    9395                addOverride(
    9496                    block, branch->child(0),
     
    98100                    Override::constant(branch->successorBlock(1), 0));
    99101                break;
    100             case Switch:
     102            case Switch: {
     103                HashMap<BasicBlock*, unsigned> targetUses;
     104                for (const SwitchCase& switchCase : *branch->as<SwitchValue>())
     105                    targetUses.add(switchCase.targetBlock(), 0).iterator->value++;
     106
    101107                for (const SwitchCase& switchCase : *branch->as<SwitchValue>()) {
     108                    if (targetUses.find(switchCase.targetBlock())->value != 1)
     109                        continue;
     110
    102111                    addOverride(
    103112                        block, branch->child(0),
     
    105114                }
    106115                break;
     116            }
    107117            default:
    108118                break;
  • trunk/Source/JavaScriptCore/b3/B3Generate.cpp

    r195417 r195422  
    9292    if (optLevel >= 1) {
    9393        reduceStrength(procedure);
    94        
     94
    9595        // FIXME: Add more optimizations here.
    9696        // https://bugs.webkit.org/show_bug.cgi?id=150507
  • trunk/Source/JavaScriptCore/b3/testb3.cpp

    r195395 r195422  
    84288428    CHECK(!invoke<int32_t>(*code, degree * gap, 42, 11));
    84298429    CHECK(!invoke<int32_t>(*code, degree * gap + 1, 42, 11));
     8430}
     8431
     8432void testSwitchTargettingSameBlock()
     8433{
     8434    Procedure proc;
     8435    BasicBlock* root = proc.addBlock();
     8436
     8437    BasicBlock* terminate = proc.addBlock();
     8438    terminate->appendNew<ControlValue>(
     8439        proc, Return, Origin(),
     8440        terminate->appendNew<Const32Value>(proc, Origin(), 5));
     8441
     8442    SwitchValue* switchValue = root->appendNew<SwitchValue>(
     8443        proc, Origin(),
     8444        root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
     8445        FrequentedBlock(terminate));
     8446
     8447    BasicBlock* otherTarget = proc.addBlock();
     8448    otherTarget->appendNew<ControlValue>(
     8449        proc, Return, Origin(),
     8450        otherTarget->appendNew<Const32Value>(proc, Origin(), 42));
     8451    switchValue->appendCase(SwitchCase(3, FrequentedBlock(otherTarget)));
     8452    switchValue->appendCase(SwitchCase(13, FrequentedBlock(otherTarget)));
     8453
     8454    auto code = compile(proc);
     8455
     8456    for (unsigned i = 0; i < 20; ++i) {
     8457        int32_t expected = (i == 3 || i == 13) ? 42 : 5;
     8458        CHECK(invoke<int32_t>(*code, i) == expected);
     8459    }
     8460}
     8461
     8462void testSwitchTargettingSameBlockFoldPathConstant()
     8463{
     8464    Procedure proc;
     8465    BasicBlock* root = proc.addBlock();
     8466
     8467    BasicBlock* terminate = proc.addBlock();
     8468    terminate->appendNew<ControlValue>(
     8469        proc, Return, Origin(),
     8470        terminate->appendNew<Const32Value>(proc, Origin(), 42));
     8471
     8472    Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
     8473    SwitchValue* switchValue = root->appendNew<SwitchValue>(
     8474        proc, Origin(),
     8475        argument,
     8476        FrequentedBlock(terminate));
     8477
     8478    BasicBlock* otherTarget = proc.addBlock();
     8479    otherTarget->appendNew<ControlValue>(
     8480        proc, Return, Origin(), argument);
     8481    switchValue->appendCase(SwitchCase(3, FrequentedBlock(otherTarget)));
     8482    switchValue->appendCase(SwitchCase(13, FrequentedBlock(otherTarget)));
     8483
     8484    auto code = compile(proc);
     8485
     8486    for (unsigned i = 0; i < 20; ++i) {
     8487        int32_t expected = (i == 3 || i == 13) ? i : 42;
     8488        CHECK(invoke<int32_t>(*code, i) == expected);
     8489    }
    84308490}
    84318491
     
    1038510445    RUN(testSwitchChillDiv(100, 1));
    1038610446    RUN(testSwitchChillDiv(100, 100));
     10447
     10448    RUN(testSwitchTargettingSameBlock());
     10449    RUN(testSwitchTargettingSameBlockFoldPathConstant());
    1038710450
    1038810451    RUN(testTrunc(0));
Note: See TracChangeset for help on using the changeset viewer.