⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 194372 in webkit


Ignore:
Timestamp:
Dec 22, 2015, 1:59:59 PM (11 years ago)
Author:
fpizlo@apple.com
Message:

FTL B3 does not logicalNot correctly
https://bugs.webkit.org/show_bug.cgi?id=152512

Reviewed by Saam Barati.

Source/JavaScriptCore:

I'm working on a bug where V8/richards does not run correctly. I noticed that the codegen was
doing a log of Not32's followed by branches, which smelled like badness. To debug this, I
needed B3's origins to dump as something other than a hexed pointer to a node. The node index
would be better. So, I added the notion of an origin printer to Procedure.

The bug was easy enough to fix. This introduces Output::logicalNot(). In LLVM, it's the same
as bitNot(). In B3, it's compiled to Equal(value, 0). We could have also compiled it to
BitXor(value, 1), except that B3 will strength-reduce to that anyway whenever it's safe. It's
sort of nice that right now, you could use logicalNot() on non-bool values and get C-like
behavior.

Richards still doesn't run, though. There are more bugs!

(JSC::B3::BasicBlock::dump):
(JSC::B3::BasicBlock::deepDump):

  • b3/B3BasicBlock.h:

(JSC::B3::BasicBlock::frequency):
(JSC::B3::DeepBasicBlockDump::DeepBasicBlockDump):
(JSC::B3::DeepBasicBlockDump::dump):
(JSC::B3::deepDump):

  • b3/B3LowerToAir.cpp:

(JSC::B3::Air::LowerToAir::run):
(JSC::B3::Air::LowerToAir::lower):

  • b3/B3Origin.h:

(JSC::B3::Origin::data):

  • b3/B3OriginDump.h: Added.

(JSC::B3::OriginDump::OriginDump):
(JSC::B3::OriginDump::dump):

  • b3/B3Procedure.cpp:

(JSC::B3::Procedure::~Procedure):
(JSC::B3::Procedure::printOrigin):
(JSC::B3::Procedure::addBlock):
(JSC::B3::Procedure::dump):

  • b3/B3Procedure.h:

(JSC::B3::Procedure::setOriginPrinter):

  • b3/B3Value.cpp:

(JSC::B3::Value::dumpChildren):
(JSC::B3::Value::deepDump):

  • b3/B3Value.h:

(JSC::B3::DeepValueDump::DeepValueDump):
(JSC::B3::DeepValueDump::dump):
(JSC::B3::deepDump):

  • ftl/FTLB3Output.cpp:

(JSC::FTL::Output::lockedStackSlot):
(JSC::FTL::Output::bitNot):
(JSC::FTL::Output::logicalNot):
(JSC::FTL::Output::load):

  • ftl/FTLB3Output.h:

(JSC::FTL::Output::aShr):
(JSC::FTL::Output::lShr):
(JSC::FTL::Output::ctlz32):
(JSC::FTL::Output::addWithOverflow32):
(JSC::FTL::Output::lessThanOrEqual):
(JSC::FTL::Output::doubleEqual):
(JSC::FTL::Output::doubleEqualOrUnordered):
(JSC::FTL::Output::doubleNotEqualOrUnordered):
(JSC::FTL::Output::doubleLessThan):
(JSC::FTL::Output::doubleLessThanOrEqual):
(JSC::FTL::Output::doubleGreaterThan):
(JSC::FTL::Output::doubleGreaterThanOrEqual):
(JSC::FTL::Output::doubleNotEqualAndOrdered):
(JSC::FTL::Output::doubleLessThanOrUnordered):
(JSC::FTL::Output::doubleLessThanOrEqualOrUnordered):
(JSC::FTL::Output::doubleGreaterThanOrUnordered):
(JSC::FTL::Output::doubleGreaterThanOrEqualOrUnordered):
(JSC::FTL::Output::isZero32):
(JSC::FTL::Output::notZero32):
(JSC::FTL::Output::addIncomingToPhi):
(JSC::FTL::Output::bitCast):
(JSC::FTL::Output::bitNot): Deleted.

  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::DFG::LowerDFGToLLVM::compileCheckArray):
(JSC::FTL::DFG::LowerDFGToLLVM::compileGetTypedArrayByteOffset):
(JSC::FTL::DFG::LowerDFGToLLVM::compileLogicalNot):
(JSC::FTL::DFG::LowerDFGToLLVM::compileCallOrConstruct):
(JSC::FTL::DFG::LowerDFGToLLVM::compileInstanceOfCustom):
(JSC::FTL::DFG::LowerDFGToLLVM::compileCountExecution):
(JSC::FTL::DFG::LowerDFGToLLVM::boolify):
(JSC::FTL::DFG::LowerDFGToLLVM::isMisc):
(JSC::FTL::DFG::LowerDFGToLLVM::isNotBoolean):
(JSC::FTL::DFG::LowerDFGToLLVM::isBoolean):
(JSC::FTL::DFG::LowerDFGToLLVM::unboxBoolean):
(JSC::FTL::DFG::LowerDFGToLLVM::isNotType):
(JSC::FTL::DFG::LowerDFGToLLVM::speculateObject):

  • ftl/FTLOutput.h:

(JSC::FTL::Output::aShr):
(JSC::FTL::Output::lShr):
(JSC::FTL::Output::bitNot):
(JSC::FTL::Output::logicalNot):
(JSC::FTL::Output::insertElement):

  • ftl/FTLState.cpp:

(JSC::FTL::State::State):

Source/WTF:

This change introduces yet another use of SharedTask in JSC. While doing this, I noticed that
SharedTask::run() always demands that whatever arguments the callback takes, they must be
passed as rvalue references. This was a clear misuse of perfect forwarding. This change makes
SharedTask's approach to forwarding match what we were already doing in ScopedLambda.

  • wtf/SharedTask.h:
Location:
trunk/Source
Files:
1 added
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r194369 r194372  
     12015-12-22  Filip Pizlo  <fpizlo@apple.com>
     2
     3        FTL B3 does not logicalNot correctly
     4        https://bugs.webkit.org/show_bug.cgi?id=152512
     5
     6        Reviewed by Saam Barati.
     7
     8        I'm working on a bug where V8/richards does not run correctly. I noticed that the codegen was
     9        doing a log of Not32's followed by branches, which smelled like badness. To debug this, I
     10        needed B3's origins to dump as something other than a hexed pointer to a node. The node index
     11        would be better. So, I added the notion of an origin printer to Procedure.
     12
     13        The bug was easy enough to fix. This introduces Output::logicalNot(). In LLVM, it's the same
     14        as bitNot(). In B3, it's compiled to Equal(value, 0). We could have also compiled it to
     15        BitXor(value, 1), except that B3 will strength-reduce to that anyway whenever it's safe. It's
     16        sort of nice that right now, you could use logicalNot() on non-bool values and get C-like
     17        behavior.
     18
     19        Richards still doesn't run, though. There are more bugs!
     20
     21        * JavaScriptCore.xcodeproj/project.pbxproj:
     22        * b3/B3BasicBlock.cpp:
     23        (JSC::B3::BasicBlock::dump):
     24        (JSC::B3::BasicBlock::deepDump):
     25        * b3/B3BasicBlock.h:
     26        (JSC::B3::BasicBlock::frequency):
     27        (JSC::B3::DeepBasicBlockDump::DeepBasicBlockDump):
     28        (JSC::B3::DeepBasicBlockDump::dump):
     29        (JSC::B3::deepDump):
     30        * b3/B3LowerToAir.cpp:
     31        (JSC::B3::Air::LowerToAir::run):
     32        (JSC::B3::Air::LowerToAir::lower):
     33        * b3/B3Origin.h:
     34        (JSC::B3::Origin::data):
     35        * b3/B3OriginDump.h: Added.
     36        (JSC::B3::OriginDump::OriginDump):
     37        (JSC::B3::OriginDump::dump):
     38        * b3/B3Procedure.cpp:
     39        (JSC::B3::Procedure::~Procedure):
     40        (JSC::B3::Procedure::printOrigin):
     41        (JSC::B3::Procedure::addBlock):
     42        (JSC::B3::Procedure::dump):
     43        * b3/B3Procedure.h:
     44        (JSC::B3::Procedure::setOriginPrinter):
     45        * b3/B3Value.cpp:
     46        (JSC::B3::Value::dumpChildren):
     47        (JSC::B3::Value::deepDump):
     48        * b3/B3Value.h:
     49        (JSC::B3::DeepValueDump::DeepValueDump):
     50        (JSC::B3::DeepValueDump::dump):
     51        (JSC::B3::deepDump):
     52        * ftl/FTLB3Output.cpp:
     53        (JSC::FTL::Output::lockedStackSlot):
     54        (JSC::FTL::Output::bitNot):
     55        (JSC::FTL::Output::logicalNot):
     56        (JSC::FTL::Output::load):
     57        * ftl/FTLB3Output.h:
     58        (JSC::FTL::Output::aShr):
     59        (JSC::FTL::Output::lShr):
     60        (JSC::FTL::Output::ctlz32):
     61        (JSC::FTL::Output::addWithOverflow32):
     62        (JSC::FTL::Output::lessThanOrEqual):
     63        (JSC::FTL::Output::doubleEqual):
     64        (JSC::FTL::Output::doubleEqualOrUnordered):
     65        (JSC::FTL::Output::doubleNotEqualOrUnordered):
     66        (JSC::FTL::Output::doubleLessThan):
     67        (JSC::FTL::Output::doubleLessThanOrEqual):
     68        (JSC::FTL::Output::doubleGreaterThan):
     69        (JSC::FTL::Output::doubleGreaterThanOrEqual):
     70        (JSC::FTL::Output::doubleNotEqualAndOrdered):
     71        (JSC::FTL::Output::doubleLessThanOrUnordered):
     72        (JSC::FTL::Output::doubleLessThanOrEqualOrUnordered):
     73        (JSC::FTL::Output::doubleGreaterThanOrUnordered):
     74        (JSC::FTL::Output::doubleGreaterThanOrEqualOrUnordered):
     75        (JSC::FTL::Output::isZero32):
     76        (JSC::FTL::Output::notZero32):
     77        (JSC::FTL::Output::addIncomingToPhi):
     78        (JSC::FTL::Output::bitCast):
     79        (JSC::FTL::Output::bitNot): Deleted.
     80        * ftl/FTLLowerDFGToLLVM.cpp:
     81        (JSC::FTL::DFG::LowerDFGToLLVM::compileCheckArray):
     82        (JSC::FTL::DFG::LowerDFGToLLVM::compileGetTypedArrayByteOffset):
     83        (JSC::FTL::DFG::LowerDFGToLLVM::compileLogicalNot):
     84        (JSC::FTL::DFG::LowerDFGToLLVM::compileCallOrConstruct):
     85        (JSC::FTL::DFG::LowerDFGToLLVM::compileInstanceOfCustom):
     86        (JSC::FTL::DFG::LowerDFGToLLVM::compileCountExecution):
     87        (JSC::FTL::DFG::LowerDFGToLLVM::boolify):
     88        (JSC::FTL::DFG::LowerDFGToLLVM::isMisc):
     89        (JSC::FTL::DFG::LowerDFGToLLVM::isNotBoolean):
     90        (JSC::FTL::DFG::LowerDFGToLLVM::isBoolean):
     91        (JSC::FTL::DFG::LowerDFGToLLVM::unboxBoolean):
     92        (JSC::FTL::DFG::LowerDFGToLLVM::isNotType):
     93        (JSC::FTL::DFG::LowerDFGToLLVM::speculateObject):
     94        * ftl/FTLOutput.h:
     95        (JSC::FTL::Output::aShr):
     96        (JSC::FTL::Output::lShr):
     97        (JSC::FTL::Output::bitNot):
     98        (JSC::FTL::Output::logicalNot):
     99        (JSC::FTL::Output::insertElement):
     100        * ftl/FTLState.cpp:
     101        (JSC::FTL::State::State):
     102
    11032015-12-22  Keith Miller  <keith_miller@apple.com>
    2104
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r194363 r194372  
    374374                0F493AFA16D0CAD30084508B /* SourceProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F493AF816D0CAD10084508B /* SourceProvider.cpp */; };
    375375                0F4B94DC17B9F07500DD03A4 /* TypedArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
     376                0F4C91661C29F4F2004341A6 /* B3OriginDump.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4C91651C29F4F2004341A6 /* B3OriginDump.h */; };
    376377                0F4F29DF18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */; };
    377378                0F4F29E018B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */; };
     
    25072508                0F493AF816D0CAD10084508B /* SourceProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SourceProvider.cpp; sourceTree = "<group>"; };
    25082509                0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrayInlines.h; sourceTree = "<group>"; };
     2510                0F4C91651C29F4F2004341A6 /* B3OriginDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3OriginDump.h; path = b3/B3OriginDump.h; sourceTree = "<group>"; };
    25092511                0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStaticExecutionCountEstimationPhase.cpp; path = dfg/DFGStaticExecutionCountEstimationPhase.cpp; sourceTree = "<group>"; };
    25102512                0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStaticExecutionCountEstimationPhase.h; path = dfg/DFGStaticExecutionCountEstimationPhase.h; sourceTree = "<group>"; };
     
    47024704                                0FEC84D91BDACDAC0080FF74 /* B3Origin.cpp */,
    47034705                                0FEC84DA1BDACDAC0080FF74 /* B3Origin.h */,
     4706                                0F4C91651C29F4F2004341A6 /* B3OriginDump.h */,
    47044707                                0FEC84DB1BDACDAC0080FF74 /* B3PatchpointSpecial.cpp */,
    47054708                                0FEC84DC1BDACDAC0080FF74 /* B3PatchpointSpecial.h */,
     
    69876990                                7094C4DF1AE439530041A2EE /* BytecodeIntrinsicRegistry.h in Headers */,
    69886991                                0F2DD80B1AB3D85800BBB8E8 /* BytecodeKills.h in Headers */,
     6992                                0F4C91661C29F4F2004341A6 /* B3OriginDump.h in Headers */,
    69896993                                C2FCAE1317A9C24E0034C735 /* BytecodeLivenessAnalysis.h in Headers */,
    69906994                                0F666EC0183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h in Headers */,
  • trunk/Source/JavaScriptCore/b3/B3BasicBlock.cpp

    r192346 r194372  
    109109}
    110110
    111 void BasicBlock::deepDump(PrintStream& out) const
     111void BasicBlock::deepDump(const Procedure& proc, PrintStream& out) const
    112112{
    113113    out.print("BB", *this, ": ; frequency = ", m_frequency, "\n");
     
    115115        out.print("  Predecessors: ", pointerListDump(predecessors()), "\n");
    116116    for (Value* value : *this)
    117         out.print("    ", B3::deepDump(value), "\n");
     117        out.print("    ", B3::deepDump(proc, value), "\n");
    118118}
    119119
  • trunk/Source/JavaScriptCore/b3/B3BasicBlock.h

    r192346 r194372  
    115115
    116116    void dump(PrintStream&) const;
    117     void deepDump(PrintStream&) const;
     117    void deepDump(const Procedure&, PrintStream&) const;
    118118
    119119private:
     
    133133class DeepBasicBlockDump {
    134134public:
    135     DeepBasicBlockDump(const BasicBlock* block)
    136         : m_block(block)
     135    DeepBasicBlockDump(const Procedure& proc, const BasicBlock* block)
     136        : m_proc(proc)
     137        , m_block(block)
    137138    {
    138139    }
     
    141142    {
    142143        if (m_block)
    143             m_block->deepDump(out);
     144            m_block->deepDump(m_proc, out);
    144145        else
    145146            out.print("<null>");
     
    147148
    148149private:
     150    const Procedure& m_proc;
    149151    const BasicBlock* m_block;
    150152};
    151153
    152 inline DeepBasicBlockDump deepDump(const BasicBlock* block)
     154inline DeepBasicBlockDump deepDump(const Procedure& proc, const BasicBlock* block)
    153155{
    154     return DeepBasicBlockDump(block);
     156    return DeepBasicBlockDump(proc, block);
    155157}
    156158
  • trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp

    r194354 r194372  
    103103                m_insts.append(Vector<Inst>());
    104104                if (verbose)
    105                     dataLog("Lowering ", deepDump(m_value), ":\n");
     105                    dataLog("Lowering ", deepDump(m_procedure, m_value), ":\n");
    106106                lower();
    107107                if (verbose) {
     
    21482148        }
    21492149
    2150         dataLog("FATAL: could not lower ", deepDump(m_value), "\n");
     2150        dataLog("FATAL: could not lower ", deepDump(m_procedure, m_value), "\n");
    21512151        RELEASE_ASSERT_NOT_REACHED();
    21522152    }
  • trunk/Source/JavaScriptCore/b3/B3Origin.h

    r191705 r194372  
    4848    const void* data() const { return m_data; }
    4949
     50    // You should avoid using this. Use OriginDump instead.
    5051    void dump(PrintStream&) const;
    5152   
  • trunk/Source/JavaScriptCore/b3/B3Procedure.cpp

    r193683 r194372  
    5353}
    5454
     55void Procedure::printOrigin(PrintStream& out, Origin origin) const
     56{
     57    if (m_originPrinter)
     58        m_originPrinter->run(out, origin);
     59    else
     60        out.print(origin);
     61}
     62
    5563BasicBlock* Procedure::addBlock(double frequency)
    5664{
     
    127135{
    128136    for (BasicBlock* block : *this)
    129         out.print(deepDump(block));
     137        out.print(deepDump(*this, block));
    130138    if (m_byproducts->count())
    131139        out.print(*m_byproducts);
  • trunk/Source/JavaScriptCore/b3/B3Procedure.h

    r193682 r194372  
    4040#include <wtf/Noncopyable.h>
    4141#include <wtf/PrintStream.h>
     42#include <wtf/SharedTask.h>
    4243#include <wtf/TriState.h>
    4344#include <wtf/Vector.h>
     
    6061    JS_EXPORT_PRIVATE Procedure();
    6162    JS_EXPORT_PRIVATE ~Procedure();
     63
     64    template<typename Callback>
     65    void setOriginPrinter(Callback&& callback)
     66    {
     67        m_originPrinter = createSharedTask<void(PrintStream&, Origin)>(
     68            std::forward<Callback>(callback));
     69    }
     70
     71    // Usually you use this via OriginDump, though it's cool to use it directly.
     72    void printOrigin(PrintStream& out, Origin origin) const;
    6273
    6374    JS_EXPORT_PRIVATE BasicBlock* addBlock(double frequency = 1);
     
    262273    std::unique_ptr<OpaqueByproducts> m_byproducts;
    263274    std::unique_ptr<Air::Code> m_code;
     275    RefPtr<SharedTask<void(PrintStream&, Origin)>> m_originPrinter;
    264276};
    265277
  • trunk/Source/JavaScriptCore/b3/B3Value.cpp

    r194341 r194372  
    3333#include "B3ControlValue.h"
    3434#include "B3MemoryValue.h"
     35#include "B3OriginDump.h"
    3536#include "B3ProcedureInlines.h"
    3637#include "B3StackSlotValue.h"
     
    100101}
    101102
    102 void Value::deepDump(PrintStream& out) const
     103void Value::deepDump(const Procedure& proc, PrintStream& out) const
    103104{
    104105    out.print(m_type, " ", *this, " = ", m_opcode);
     
    109110
    110111    if (m_origin)
    111         out.print(comma, m_origin);
     112        out.print(comma, OriginDump(proc, m_origin));
    112113
    113114    dumpMeta(comma, out);
  • trunk/Source/JavaScriptCore/b3/B3Value.h

    r194331 r194372  
    8686
    8787    void dump(PrintStream&) const;
    88     void deepDump(PrintStream&) const;
     88    void deepDump(const Procedure&, PrintStream&) const;
    8989
    9090    // This is how you cast Values. For example, if you want to do something provided that we have a
     
    315315class DeepValueDump {
    316316public:
    317     DeepValueDump(const Value* value)
    318         : m_value(value)
     317    DeepValueDump(const Procedure& proc, const Value* value)
     318        : m_proc(proc)
     319        , m_value(value)
    319320    {
    320321    }
     
    323324    {
    324325        if (m_value)
    325             m_value->deepDump(out);
     326            m_value->deepDump(m_proc, out);
    326327        else
    327328            out.print("<null>");
     
    329330
    330331private:
     332    const Procedure& m_proc;
    331333    const Value* m_value;
    332334};
    333335
    334 inline DeepValueDump deepDump(const Value* value)
     336inline DeepValueDump deepDump(const Procedure& proc, const Value* value)
    335337{
    336     return DeepValueDump(value);
     338    return DeepValueDump(proc, value);
    337339}
    338340
  • trunk/Source/JavaScriptCore/ftl/FTLB3Output.cpp

    r194341 r194372  
    6868}
    6969
     70LValue Output::bitNot(LValue value)
     71{
     72    return m_block->appendNew<B3::Value>(m_proc, B3::BitXor, origin(),
     73        value,
     74        m_block->appendIntConstant(m_proc, origin(), value->type(), -1));
     75}
     76
     77LValue Output::logicalNot(LValue value)
     78{
     79    return m_block->appendNew<B3::Value>(m_proc, B3::Equal, origin(), value, int32Zero);
     80}
     81
    7082LValue Output::load(TypedPointer pointer, LType type)
    7183{
  • trunk/Source/JavaScriptCore/ftl/FTLB3Output.h

    r194341 r194372  
    154154    LValue lShr(LValue left, LValue right) { return m_block->appendNew<B3::Value>(m_proc, B3::ZShr, origin(), left, castToInt32(right)); }
    155155    LValue bitNot(LValue);
     156    LValue logicalNot(LValue);
    156157
    157158    LValue ctlz32(LValue operand) { return m_block->appendNew<B3::Value>(m_proc, B3::Clz, origin(), operand); }
     
    336337
    337338    LValue doubleEqual(LValue left, LValue right) { return m_block->appendNew<B3::Value>(m_proc, B3::Equal, origin(), left, right); }
     339    LValue doubleEqualOrUnordered(LValue left, LValue right) { return m_block->appendNew<B3::Value>(m_proc, B3::EqualOrUnordered, origin(), left, right); }
    338340    LValue doubleNotEqualOrUnordered(LValue left, LValue right) { return m_block->appendNew<B3::Value>(m_proc, B3::NotEqual, origin(), left, right); }
    339341    LValue doubleLessThan(LValue left, LValue right) { return m_block->appendNew<B3::Value>(m_proc, B3::LessThan, origin(), left, right); }
     
    341343    LValue doubleGreaterThan(LValue left, LValue right) { return m_block->appendNew<B3::Value>(m_proc, B3::GreaterThan, origin(), left, right); }
    342344    LValue doubleGreaterThanOrEqual(LValue left, LValue right) { return m_block->appendNew<B3::Value>(m_proc, B3::GreaterEqual, origin(), left, right); }
    343     LValue doubleNotEqualAndOrdered(LValue left, LValue right)
    344     {
    345         LValue equalOrUnordered = m_block->appendNew<B3::Value>(m_proc, B3::EqualOrUnordered, origin(), left, right);
    346         return bitXor(equalOrUnordered, int32One);
    347     }
    348     LValue doubleLessThanOrUnordered(LValue left, LValue right)
    349     {
    350         return m_block->appendNew<B3::Value>(
    351             m_proc, B3::Equal, origin(),
    352             m_block->appendNew<B3::Value>(m_proc, B3::GreaterEqual, origin(), left, right),
    353             int32Zero);
    354     }
    355     LValue doubleLessThanOrEqualOrUnordered(LValue left, LValue right)
    356     {
    357         return m_block->appendNew<B3::Value>(
    358             m_proc, B3::Equal, origin(),
    359             m_block->appendNew<B3::Value>(m_proc, B3::GreaterThan, origin(), left, right),
    360             int32Zero);
    361     }
    362     LValue doubleGreaterThanOrUnordered(LValue left, LValue right)
    363     {
    364         return m_block->appendNew<B3::Value>(
    365             m_proc, B3::Equal, origin(),
    366             m_block->appendNew<B3::Value>(m_proc, B3::LessEqual, origin(), left, right),
    367             int32Zero);
    368     }
    369     LValue doubleGreaterThanOrEqualOrUnordered(LValue left, LValue right)
    370     {
    371         return m_block->appendNew<B3::Value>(
    372             m_proc, B3::Equal, origin(),
    373             m_block->appendNew<B3::Value>(m_proc, B3::LessThan, origin(), left, right),
    374             int32Zero);
    375     }
     345    LValue doubleNotEqualAndOrdered(LValue left, LValue right) { return logicalNot(doubleEqualOrUnordered(left, right)); }
     346    LValue doubleLessThanOrUnordered(LValue left, LValue right) { return logicalNot(doubleGreaterThanOrEqual(left, right)); }
     347    LValue doubleLessThanOrEqualOrUnordered(LValue left, LValue right) { return logicalNot(doubleGreaterThan(left, right)); }
     348    LValue doubleGreaterThanOrUnordered(LValue left, LValue right) { return logicalNot(doubleLessThanOrEqual(left, right)); }
     349    LValue doubleGreaterThanOrEqualOrUnordered(LValue left, LValue right) { return logicalNot(doubleLessThan(left, right)); }
    376350
    377351    LValue isZero32(LValue value) { return m_block->appendNew<B3::Value>(m_proc, B3::Equal, origin(), value, int32Zero); }
     
    541515}
    542516
    543 inline LValue Output::bitNot(LValue value)
    544 {
    545     return m_block->appendNew<B3::Value>(m_proc, B3::BitXor, origin(),
    546         value,
    547         m_block->appendIntConstant(m_proc, origin(), value->type(), -1));
    548 }
    549 
    550517inline LValue Output::bitCast(LValue value, LType type)
    551518{
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

    r194368 r194372  
    27012701        speculate(
    27022702            BadIndexingType, jsValueValue(cell), 0,
    2703             m_out.bitNot(isArrayType(cell, m_node->arrayMode())));
     2703            m_out.logicalNot(isArrayType(cell, m_node->arrayMode())));
    27042704    }
    27052705
     
    49004900    void compileLogicalNot()
    49014901    {
    4902         setBoolean(m_out.bitNot(boolify(m_node->child1())));
     4902        setBoolean(m_out.logicalNot(boolify(m_node->child1())));
    49034903    }
    49044904
     
    61696169        LValue hasInstance = lowJSValue(m_node->child3());
    61706170
    6171         setBoolean(m_out.bitNot(m_out.equal(m_out.constInt32(0), vmCall(m_out.int32, m_out.operation(operationInstanceOfCustom), m_callFrame, value, constructor, hasInstance))));
     6171        setBoolean(m_out.logicalNot(m_out.equal(m_out.constInt32(0), vmCall(m_out.int32, m_out.operation(operationInstanceOfCustom), m_callFrame, value, constructor, hasInstance))));
    61726172    }
    61736173   
     
    76327632            return m_out.doubleNotEqualAndOrdered(lowDouble(edge), m_out.doubleZero);
    76337633        case ObjectOrOtherUse:
    7634             return m_out.bitNot(
     7634            return m_out.logicalNot(
    76357635                equalNullOrUndefined(
    76367636                    edge, CellCaseSpeculatesObject, SpeculateNullOrUndefined,
     
    91059105        if (LValue proven = isProvenValue(type, SpecMisc))
    91069106            return proven;
    9107         return m_out.bitNot(isNotMisc(value));
     9107        return m_out.logicalNot(isNotMisc(value));
    91089108    }
    91099109   
     
    91209120        if (LValue proven = isProvenValue(type, SpecBoolean))
    91219121            return proven;
    9122         return m_out.bitNot(isNotBoolean(jsValue));
     9122        return m_out.logicalNot(isNotBoolean(jsValue));
    91239123    }
    91249124    LValue unboxBoolean(LValue jsValue)
     
    94119411    LValue isNotType(LValue cell, JSType type)
    94129412    {
    9413         return m_out.bitNot(isType(cell, type));
     9413        return m_out.logicalNot(isType(cell, type));
    94149414    }
    94159415   
  • trunk/Source/JavaScriptCore/ftl/FTLOutput.h

    r194341 r194372  
    145145    LValue lShr(LValue left, LValue right) { return buildLShr(m_builder, left, right); } // logical = unsigned
    146146    LValue bitNot(LValue value) { return buildNot(m_builder, value); }
     147    LValue logicalNot(LValue value) { return bitNot(value); }
    147148   
    148149    LValue insertElement(LValue vector, LValue element, LValue index) { return buildInsertElement(m_builder, vector, element, index); }
  • trunk/Source/JavaScriptCore/ftl/FTLState.cpp

    r193362 r194372  
    7373#if FTL_USES_B3
    7474    proc = std::make_unique<Procedure>();
     75
     76    proc->setOriginPrinter(
     77        [this] (PrintStream& out, B3::Origin origin) {
     78            out.print("DFG:", bitwise_cast<Node*>(origin.data()));
     79        });
    7580#endif // FTL_USES_B3
    7681}
  • trunk/Source/WTF/ChangeLog

    r194323 r194372  
     12015-12-22  Filip Pizlo  <fpizlo@apple.com>
     2
     3        FTL B3 does not logicalNot correctly
     4        https://bugs.webkit.org/show_bug.cgi?id=152512
     5
     6        Reviewed by Saam Barati.
     7
     8        This change introduces yet another use of SharedTask in JSC. While doing this, I noticed that
     9        SharedTask::run() always demands that whatever arguments the callback takes, they must be
     10        passed as rvalue references. This was a clear misuse of perfect forwarding. This change makes
     11        SharedTask's approach to forwarding match what we were already doing in ScopedLambda.
     12
     13        * wtf/SharedTask.h:
     14
    1152015-12-20  Michael Catanzaro  <mcatanzaro@igalia.com>
    216
  • trunk/Source/WTF/wtf/SharedTask.h

    r191705 r194372  
    6666    virtual ~SharedTask() { }
    6767
    68     virtual ResultType run(ArgumentTypes&&...) = 0;
     68    virtual ResultType run(ArgumentTypes...) = 0;
    6969};
    7070
     
    8686
    8787private:
    88     ResultType run(ArgumentTypes&&... arguments) override
     88    ResultType run(ArgumentTypes... arguments) override
    8989    {
    90         return m_functor(std::forward<ArgumentTypes>(arguments)...);
     90        return m_functor(arguments...);
    9191    }
    9292
Note: See TracChangeset for help on using the changeset viewer.