Changeset 209953 in webkit


Ignore:
Timestamp:
Dec 16, 2016 5:07:38 PM (7 years ago)
Author:
sbarati@apple.com
Message:

B3::DoubleToFloatReduction will accidentally convince itself it converted a Phi from Double to Float and then convert uses of that Phi into a use of FloatToDouble(@Phi)
https://bugs.webkit.org/show_bug.cgi?id=165946

Reviewed by Keith Miller.

This was happening because the phase will convert some Phi nodes
from Double to Float. However, one place that did this conversion
forgot to first check if the Phi was already a Float. If it's already
a Float, a later part of the phase will be buggy if the phase claims that it has
converted it from Double->Float. The reason is that at the end of the
phase, we'll look for all uses of former Double Phi nodes and make them
be a use of ConvertFloatToDouble on the Phi, instead of a use of the Phi itself.
This is clearly wrong if the Phi were Float to begin with (and
therefore, the uses were Float uses to begin with).

  • b3/B3ReduceDoubleToFloat.cpp:
  • b3/testb3.cpp:

(JSC::B3::testReduceFloatToDoubleValidates):
(JSC::B3::run):

Location:
trunk/Source/JavaScriptCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r209952 r209953  
     12016-12-16  Saam Barati  <sbarati@apple.com>
     2
     3        B3::DoubleToFloatReduction will accidentally convince itself it converted a Phi from Double to Float and then convert uses of that Phi into a use of FloatToDouble(@Phi)
     4        https://bugs.webkit.org/show_bug.cgi?id=165946
     5
     6        Reviewed by Keith Miller.
     7
     8        This was happening because the phase will convert some Phi nodes
     9        from Double to Float. However, one place that did this conversion
     10        forgot to first check if the Phi was already a Float. If it's already
     11        a Float, a later part of the phase will be buggy if the phase claims that it has
     12        converted it from Double->Float. The reason is that at the end of the
     13        phase, we'll look for all uses of former Double Phi nodes and make them
     14        be a use of ConvertFloatToDouble on the Phi, instead of a use of the Phi itself.
     15        This is clearly wrong if the Phi were Float to begin with (and
     16        therefore, the uses were Float uses to begin with).
     17
     18        * b3/B3ReduceDoubleToFloat.cpp:
     19        * b3/testb3.cpp:
     20        (JSC::B3::testReduceFloatToDoubleValidates):
     21        (JSC::B3::run):
     22
    1232016-12-16  Mark Lam  <mark.lam@apple.com>
    224
  • trunk/Source/JavaScriptCore/b3/B3ReduceDoubleToFloat.cpp

    r204920 r209953  
    232232
    233233        if (value->opcode() == Phi) {
    234             convertPhi(value);
     234            ASSERT(value->type() == Double || value->type() == Float);
     235            if (value->type() == Double)
     236                convertPhi(value);
    235237            return value;
    236238        }
     
    242244    {
    243245        ASSERT(phi->opcode() == Phi);
     246        ASSERT(phi->type() == Double);
    244247        phi->setType(Float);
    245248        m_convertedPhis.add(phi);
  • trunk/Source/JavaScriptCore/b3/testb3.cpp

    r209928 r209953  
    45344534    CHECK(isIdentical(invoke<float>(*code, 1, bitwise_cast<int32_t>(value)), value + 42.5f));
    45354535    CHECK(isIdentical(invoke<float>(*code, 0, bitwise_cast<int32_t>(value)), static_cast<float>(M_PI)));
     4536}
     4537
     4538void testReduceFloatToDoubleValidates()
     4539{
     4540    // Simple case of:
     4541    //     f = DoubleToFloat(Bitcast(argGPR0))
     4542    //     if (a) {
     4543    //         x = FloatConst()
     4544    //     else
     4545    //         x = FloatConst()
     4546    //     p = Phi(x)
     4547    //     a = Mul(p, p)
     4548    //     b = Add(a, f)
     4549    //     c = Add(p, b)
     4550    //     Return(c)
     4551    //
     4552    // This should not crash in the validator after ReduceFloatToDouble.
     4553    Procedure proc;
     4554    BasicBlock* root = proc.addBlock();
     4555    BasicBlock* thenCase = proc.addBlock();
     4556    BasicBlock* elseCase = proc.addBlock();
     4557    BasicBlock* tail = proc.addBlock();
     4558
     4559    Value* condition = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
     4560    Value* thingy = root->appendNew<Value>(proc, BitwiseCast, Origin(), condition);
     4561    thingy = root->appendNew<Value>(proc, DoubleToFloat, Origin(), thingy); // Make the phase think it has work to do.
     4562    root->appendNewControlValue(
     4563        proc, Branch, Origin(),
     4564        condition,
     4565        FrequentedBlock(thenCase), FrequentedBlock(elseCase));
     4566
     4567    UpsilonValue* thenValue = thenCase->appendNew<UpsilonValue>(proc, Origin(),
     4568        thenCase->appendNew<ConstFloatValue>(proc, Origin(), 11.5));
     4569    thenCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
     4570
     4571    UpsilonValue* elseValue = elseCase->appendNew<UpsilonValue>(proc, Origin(),
     4572        elseCase->appendNew<ConstFloatValue>(proc, Origin(), 10.5));
     4573    elseCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
     4574
     4575    Value* phi =  tail->appendNew<Value>(proc, Phi, Float, Origin());
     4576    thenValue->setPhi(phi);
     4577    elseValue->setPhi(phi);
     4578    Value* result = tail->appendNew<Value>(proc, Mul, Origin(),
     4579            phi, phi);
     4580    result = tail->appendNew<Value>(proc, Add, Origin(),
     4581            result,
     4582            thingy);
     4583    result = tail->appendNew<Value>(proc, Add, Origin(),
     4584            phi,
     4585            result);
     4586    tail->appendNewControlValue(proc, Return, Origin(), result);
     4587
     4588    auto code = compile(proc);
     4589    CHECK(isIdentical(invoke<float>(*code, 1), 11.5f * 11.5f + static_cast<float>(bitwise_cast<double>(static_cast<uint64_t>(1))) + 11.5f));
     4590    CHECK(isIdentical(invoke<float>(*code, 0), 10.5f * 10.5f + static_cast<float>(bitwise_cast<double>(static_cast<uint64_t>(0))) + 10.5f));
    45364591}
    45374592
     
    1462914684    RUN_BINARY(testCompareFloatToDoubleThroughPhi, floatingPointOperands<float>(), floatingPointOperands<float>());
    1463014685    RUN_UNARY(testDoubleToFloatThroughPhi, floatingPointOperands<float>());
     14686    RUN(testReduceFloatToDoubleValidates());
    1463114687    RUN_UNARY(testDoubleProducerPhiToFloatConversion, floatingPointOperands<float>());
    1463214688    RUN_UNARY(testDoubleProducerPhiToFloatConversionWithDoubleConsumer, floatingPointOperands<float>());
Note: See TracChangeset for help on using the changeset viewer.