Ignore:
Timestamp:
Jun 30, 2017, 4:37:01 PM (8 years ago)
Author:
[email protected]
Message:

B3ReduceDoubleToFloat incorrectly reduces operations over two double constants
https://bugs.webkit.org/show_bug.cgi?id=174034
<rdar://problem/30793007>

Reviewed by Filip Pizlo.

B3ReduceDoubleToFloat had a bug in it where it would incorrectly
reduce binary operations over double constants into the same binary
operation over the double constants casted to floats. This is clearly
incorrect as these two things will produce different values. For example:

a = DoubleConst(bitwise_cast<double>(0x8000000000000001ull))
b = DoubleConst(bitwise_cast<double>(0x0000000000000000ull))
c = EqualOrUnordered(@a, @b) produces 0

into:

a = FloatConst(static_cast<float>(bitwise_cast<double>(0x8000000000000001ull)))
b = FloatConst(static_cast<float>(bitwise_cast<double>(0x0000000000000000ull)))
c = EqualOrUnordered(@a, @b) produces 1

Which produces a different value for @c.

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

(JSC::B3::doubleEq):
(JSC::B3::doubleNeq):
(JSC::B3::doubleGt):
(JSC::B3::doubleGte):
(JSC::B3::doubleLt):
(JSC::B3::doubleLte):
(JSC::B3::testDoubleLiteralComparison):
(JSC::B3::run):

File:
1 edited

Legend:

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

    r217127 r219026  
    6868#include "PureNaN.h"
    6969#include <cmath>
     70#include <list>
    7071#include <string>
    7172#include <wtf/FastTLS.h>
     
    1543115432    CHECK_EQ(bitwise_cast<uintptr_t>(_pthread_getspecific_direct(WTF_TESTING_KEY)), static_cast<uintptr_t>(0xdead));
    1543215433#endif
     15434}
     15435
     15436NEVER_INLINE bool doubleEq(double a, double b) { return a == b; }
     15437NEVER_INLINE bool doubleNeq(double a, double b) { return a != b; }
     15438NEVER_INLINE bool doubleGt(double a, double b) { return a > b; }
     15439NEVER_INLINE bool doubleGte(double a, double b) { return a >= b; }
     15440NEVER_INLINE bool doubleLt(double a, double b) { return a < b; }
     15441NEVER_INLINE bool doubleLte(double a, double b) { return a <= b; }
     15442
     15443void testDoubleLiteralComparison(double a, double b)
     15444{
     15445    using Test = std::tuple<B3::Opcode, bool (*)(double, double)>;
     15446    std::list<Test> tests = {
     15447        { NotEqual, doubleNeq },
     15448        { Equal, doubleEq },
     15449        { EqualOrUnordered, doubleEq },
     15450        { GreaterThan, doubleGt },
     15451        { GreaterEqual, doubleGte },
     15452        { LessThan, doubleLt },
     15453        { LessEqual, doubleLte },
     15454    };
     15455
     15456    for (const Test& test : tests) {
     15457        Procedure proc;
     15458        BasicBlock* root = proc.addBlock();
     15459        Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
     15460        Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
     15461
     15462        // This is here just to make reduceDoubleToFloat do things.
     15463        Value* valueC = root->appendNew<ConstDoubleValue>(proc, Origin(), 0.0);
     15464        Value* valueAsFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), valueC);
     15465
     15466        root->appendNewControlValue(
     15467            proc, Return, Origin(),
     15468                root->appendNew<Value>(proc, BitAnd, Origin(),
     15469                    root->appendNew<Value>(proc, std::get<0>(test), Origin(), valueA, valueB),
     15470                    root->appendNew<Value>(proc, Equal, Origin(), valueAsFloat, valueAsFloat)));
     15471
     15472        CHECK(!!compileAndRun<int32_t>(proc) == std::get<1>(test)(a, b));
     15473    }
    1543315474}
    1543415475
     
    1696717008    RUN(testFastTLSStore());
    1696817009
     17010    RUN(testDoubleLiteralComparison(bitwise_cast<double>(0x8000000000000001ull), bitwise_cast<double>(0x0000000000000000ull)));
     17011    RUN(testDoubleLiteralComparison(bitwise_cast<double>(0x0000000000000000ull), bitwise_cast<double>(0x8000000000000001ull)));
     17012    RUN(testDoubleLiteralComparison(125.3144446948241, 125.3144446948242));
     17013    RUN(testDoubleLiteralComparison(125.3144446948242, 125.3144446948241));
     17014
    1696917015    if (isX86()) {
    1697017016        RUN(testBranchBitAndImmFusion(Identity, Int64, 1, Air::BranchTest32, Air::Arg::Tmp));
Note: See TracChangeset for help on using the changeset viewer.