Changeset 229517 in webkit


Ignore:
Timestamp:
Mar 11, 2018 12:52:24 PM (6 years ago)
Author:
Yusuke Suzuki
Message:

[B3] Above/Below should be strength-reduced for comparison with 0
https://bugs.webkit.org/show_bug.cgi?id=183543

Reviewed by Filip Pizlo.

Above(0, x) and BelowEqual(0, x) can be converted to constants false and true respectively.
This can be seen in ArraySlice(0) case: Select(Above(0, length), length, 0) this should
be converted to 0. This patch adds such a folding to comparisons.

We also fix B3ReduceStrength issue creating an orphan value. If a flipped value is folded to
a constant, we do not insert flipped value and make it an orphan. This issue causes JSC test
failure with this B3Const32/64Value change. With this patch, we create a flipped value only
when we fail to fold it to a constant.

  • b3/B3Const32Value.cpp:

(JSC::B3::Const32Value::lessThanConstant const):
(JSC::B3::Const32Value::greaterThanConstant const):
(JSC::B3::Const32Value::lessEqualConstant const):
(JSC::B3::Const32Value::greaterEqualConstant const):
(JSC::B3::Const32Value::aboveConstant const):
(JSC::B3::Const32Value::belowConstant const):
(JSC::B3::Const32Value::aboveEqualConstant const):
(JSC::B3::Const32Value::belowEqualConstant const):

  • b3/B3Const64Value.cpp:

(JSC::B3::Const64Value::lessThanConstant const):
(JSC::B3::Const64Value::greaterThanConstant const):
(JSC::B3::Const64Value::lessEqualConstant const):
(JSC::B3::Const64Value::greaterEqualConstant const):
(JSC::B3::Const64Value::aboveConstant const):
(JSC::B3::Const64Value::belowConstant const):
(JSC::B3::Const64Value::aboveEqualConstant const):
(JSC::B3::Const64Value::belowEqualConstant const):

  • b3/B3ReduceStrength.cpp:
  • b3/testb3.cpp:

(JSC::B3::int64Operands):
(JSC::B3::int32Operands):

Location:
trunk/Source/JavaScriptCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r229514 r229517  
     12018-03-11  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        [B3] Above/Below should be strength-reduced for comparison with 0
     4        https://bugs.webkit.org/show_bug.cgi?id=183543
     5
     6        Reviewed by Filip Pizlo.
     7
     8        Above(0, x) and BelowEqual(0, x) can be converted to constants false and true respectively.
     9        This can be seen in ArraySlice(0) case: `Select(Above(0, length), length, 0)` this should
     10        be converted to `0`. This patch adds such a folding to comparisons.
     11
     12        We also fix B3ReduceStrength issue creating an orphan value. If a flipped value is folded to
     13        a constant, we do not insert flipped value and make it an orphan. This issue causes JSC test
     14        failure with this B3Const32/64Value change. With this patch, we create a flipped value only
     15        when we fail to fold it to a constant.
     16
     17        * b3/B3Const32Value.cpp:
     18        (JSC::B3::Const32Value::lessThanConstant const):
     19        (JSC::B3::Const32Value::greaterThanConstant const):
     20        (JSC::B3::Const32Value::lessEqualConstant const):
     21        (JSC::B3::Const32Value::greaterEqualConstant const):
     22        (JSC::B3::Const32Value::aboveConstant const):
     23        (JSC::B3::Const32Value::belowConstant const):
     24        (JSC::B3::Const32Value::aboveEqualConstant const):
     25        (JSC::B3::Const32Value::belowEqualConstant const):
     26        * b3/B3Const64Value.cpp:
     27        (JSC::B3::Const64Value::lessThanConstant const):
     28        (JSC::B3::Const64Value::greaterThanConstant const):
     29        (JSC::B3::Const64Value::lessEqualConstant const):
     30        (JSC::B3::Const64Value::greaterEqualConstant const):
     31        (JSC::B3::Const64Value::aboveConstant const):
     32        (JSC::B3::Const64Value::belowConstant const):
     33        (JSC::B3::Const64Value::aboveEqualConstant const):
     34        (JSC::B3::Const64Value::belowEqualConstant const):
     35        * b3/B3ReduceStrength.cpp:
     36        * b3/testb3.cpp:
     37        (JSC::B3::int64Operands):
     38        (JSC::B3::int32Operands):
     39
    1402018-03-10  Yusuke Suzuki  <utatane.tea@gmail.com>
    241
  • trunk/Source/JavaScriptCore/b3/B3Const32Value.cpp

    r208848 r229517  
    221221TriState Const32Value::lessThanConstant(const Value* other) const
    222222{
     223    // INT32_MAX < x is always false.
     224    if (static_cast<int32_t>(m_value) == std::numeric_limits<int32_t>::max())
     225        return FalseTriState;
    223226    if (!other->hasInt32())
    224227        return MixedTriState;
     
    228231TriState Const32Value::greaterThanConstant(const Value* other) const
    229232{
     233    // INT32_MIN > x is always false.
     234    if (static_cast<int32_t>(m_value) == std::numeric_limits<int32_t>::min())
     235        return FalseTriState;
    230236    if (!other->hasInt32())
    231237        return MixedTriState;
     
    235241TriState Const32Value::lessEqualConstant(const Value* other) const
    236242{
     243    // INT32_MIN <= x is always true.
     244    if (static_cast<int32_t>(m_value) == std::numeric_limits<int32_t>::min())
     245        return TrueTriState;
    237246    if (!other->hasInt32())
    238247        return MixedTriState;
     
    242251TriState Const32Value::greaterEqualConstant(const Value* other) const
    243252{
     253    // INT32_MAX >= x is always true.
     254    if (static_cast<int32_t>(m_value) == std::numeric_limits<int32_t>::max())
     255        return TrueTriState;
    244256    if (!other->hasInt32())
    245257        return MixedTriState;
     
    249261TriState Const32Value::aboveConstant(const Value* other) const
    250262{
     263    // UINT32_MIN > x is always false.
     264    if (static_cast<uint32_t>(m_value) == std::numeric_limits<uint32_t>::min())
     265        return FalseTriState;
    251266    if (!other->hasInt32())
    252267        return MixedTriState;
     
    256271TriState Const32Value::belowConstant(const Value* other) const
    257272{
     273    // UINT32_MAX < x is always false.
     274    if (static_cast<uint32_t>(m_value) == std::numeric_limits<uint32_t>::max())
     275        return FalseTriState;
    258276    if (!other->hasInt32())
    259277        return MixedTriState;
     
    263281TriState Const32Value::aboveEqualConstant(const Value* other) const
    264282{
     283    // UINT32_MAX >= x is always true.
     284    if (static_cast<uint32_t>(m_value) == std::numeric_limits<uint32_t>::max())
     285        return TrueTriState;
    265286    if (!other->hasInt32())
    266287        return MixedTriState;
     
    270291TriState Const32Value::belowEqualConstant(const Value* other) const
    271292{
     293    // UINT32_MIN <= x is always true.
     294    if (static_cast<uint32_t>(m_value) == std::numeric_limits<uint32_t>::min())
     295        return TrueTriState;
    272296    if (!other->hasInt32())
    273297        return MixedTriState;
  • trunk/Source/JavaScriptCore/b3/B3Const64Value.cpp

    r208848 r229517  
    221221TriState Const64Value::lessThanConstant(const Value* other) const
    222222{
     223    // INT64_MAX < x is always false.
     224    if (static_cast<int64_t>(m_value) == std::numeric_limits<int64_t>::max())
     225        return FalseTriState;
    223226    if (!other->hasInt64())
    224227        return MixedTriState;
     
    228231TriState Const64Value::greaterThanConstant(const Value* other) const
    229232{
     233    // INT64_MIN > x is always false.
     234    if (static_cast<int64_t>(m_value) == std::numeric_limits<int64_t>::min())
     235        return FalseTriState;
    230236    if (!other->hasInt64())
    231237        return MixedTriState;
     
    235241TriState Const64Value::lessEqualConstant(const Value* other) const
    236242{
     243    // INT64_MIN <= x is always true.
     244    if (static_cast<int64_t>(m_value) == std::numeric_limits<int64_t>::min())
     245        return TrueTriState;
    237246    if (!other->hasInt64())
    238247        return MixedTriState;
     
    242251TriState Const64Value::greaterEqualConstant(const Value* other) const
    243252{
     253    // INT64_MAX >= x is always true.
     254    if (static_cast<int64_t>(m_value) == std::numeric_limits<int64_t>::max())
     255        return TrueTriState;
    244256    if (!other->hasInt64())
    245257        return MixedTriState;
     
    249261TriState Const64Value::aboveConstant(const Value* other) const
    250262{
     263    // UINT64_MIN > x is always false.
     264    if (static_cast<uint64_t>(m_value) == std::numeric_limits<uint64_t>::min())
     265        return FalseTriState;
    251266    if (!other->hasInt64())
    252267        return MixedTriState;
     
    256271TriState Const64Value::belowConstant(const Value* other) const
    257272{
     273    // UINT64_MAX < x is always false.
     274    if (static_cast<uint64_t>(m_value) == std::numeric_limits<uint64_t>::max())
     275        return FalseTriState;
    258276    if (!other->hasInt64())
    259277        return MixedTriState;
     
    263281TriState Const64Value::aboveEqualConstant(const Value* other) const
    264282{
     283    // UINT64_MAX >= x is always true.
     284    if (static_cast<uint64_t>(m_value) == std::numeric_limits<uint64_t>::max())
     285        return TrueTriState;
    265286    if (!other->hasInt64())
    266287        return MixedTriState;
     
    270291TriState Const64Value::belowEqualConstant(const Value* other) const
    271292{
     293    // UINT64_MIN <= x is always true.
     294    if (static_cast<uint64_t>(m_value) == std::numeric_limits<uint64_t>::min())
     295        return TrueTriState;
    272296    if (!other->hasInt64())
    273297        return MixedTriState;
  • trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp

    r229513 r229517  
    16741674        case AboveEqual:
    16751675        case BelowEqual: {
    1676             auto* value = newComparisonVaueIfNecessary();
     1676            CanonicalizedComparison comparison = canonicalizeComparison(m_value);
    16771677            TriState result = MixedTriState;
    1678             switch (value->opcode()) {
     1678            switch (comparison.opcode) {
    16791679            case LessThan:
    1680                 result = value->child(1)->greaterThanConstant(value->child(0));
     1680                result = comparison.operands[1]->greaterThanConstant(comparison.operands[0]);
    16811681                break;
    16821682            case GreaterThan:
    1683                 result = value->child(1)->lessThanConstant(value->child(0));
     1683                result = comparison.operands[1]->lessThanConstant(comparison.operands[0]);
    16841684                break;
    16851685            case LessEqual:
    1686                 result = value->child(1)->greaterEqualConstant(value->child(0));
     1686                result = comparison.operands[1]->greaterEqualConstant(comparison.operands[0]);
    16871687                break;
    16881688            case GreaterEqual:
    1689                 result = value->child(1)->lessEqualConstant(value->child(0));
     1689                result = comparison.operands[1]->lessEqualConstant(comparison.operands[0]);
    16901690                break;
    16911691            case Above:
    1692                 result = value->child(1)->belowConstant(value->child(0));
     1692                result = comparison.operands[1]->belowConstant(comparison.operands[0]);
    16931693                break;
    16941694            case Below:
    1695                 result = value->child(1)->aboveConstant(value->child(0));
     1695                result = comparison.operands[1]->aboveConstant(comparison.operands[0]);
    16961696                break;
    16971697            case AboveEqual:
    1698                 result = value->child(1)->belowEqualConstant(value->child(0));
     1698                result = comparison.operands[1]->belowEqualConstant(comparison.operands[0]);
    16991699                break;
    17001700            case BelowEqual:
    1701                 result = value->child(1)->aboveEqualConstant(value->child(0));
     1701                result = comparison.operands[1]->aboveEqualConstant(comparison.operands[0]);
    17021702                break;
    17031703            default:
     
    17061706            }
    17071707
    1708             if (auto* constant = m_proc.addBoolConstant(value->origin(), result)) {
     1708            if (auto* constant = m_proc.addBoolConstant(m_value->origin(), result)) {
    17091709                replaceWithNewValue(constant);
    17101710                break;
    17111711            }
    1712 
    1713             // Replace with newly created "value". Its opcode is flipped and operands are swapped from m_value.
    1714             if (m_value != value)
    1715                 replaceWithNewValue(value);
     1712            if (comparison.opcode != m_value->opcode()) {
     1713                replaceWithNew<Value>(comparison.opcode, m_value->origin(), comparison.operands[0], comparison.operands[1]);
     1714                break;
     1715            }
    17161716            break;
    17171717        }
     
    21672167    }
    21682168
    2169     Value* newComparisonVaueIfNecessary()
     2169    struct CanonicalizedComparison {
     2170        Opcode opcode;
     2171        Value* operands[2];
     2172    };
     2173    static CanonicalizedComparison canonicalizeComparison(Value* value)
    21702174    {
    21712175        auto flip = [] (Opcode opcode) {
     
    21912195            }
    21922196        };
    2193         if (shouldSwapBinaryOperands(m_value)) {
    2194             m_changed = true;
    2195             return m_proc.add<Value>(flip(m_value->opcode()), m_value->origin(), m_value->child(1), m_value->child(0));
    2196         }
    2197         return m_value;
     2197        if (shouldSwapBinaryOperands(value))
     2198            return { flip(value->opcode()), { value->child(1), value->child(0) } };
     2199        return { value->opcode(), { value->child(0), value->child(1) } };
    21982200    }
    21992201
  • trunk/Source/JavaScriptCore/b3/testb3.cpp

    r229054 r229517  
    248248    operands.append({ "int32-max", std::numeric_limits<int32_t>::max() });
    249249    operands.append({ "int32-min", std::numeric_limits<int32_t>::min() });
     250    operands.append({ "uint64-max", static_cast<int64_t>(std::numeric_limits<uint64_t>::max()) });
     251    operands.append({ "uint64-min", static_cast<int64_t>(std::numeric_limits<uint64_t>::min()) });
     252    operands.append({ "uint32-max", static_cast<int64_t>(std::numeric_limits<uint32_t>::max()) });
     253    operands.append({ "uint32-min", static_cast<int64_t>(std::numeric_limits<uint32_t>::min()) });
    250254
    251255    return operands;
     
    261265        { "-42", -42 },
    262266        { "int32-max", std::numeric_limits<int32_t>::max() },
    263         { "int32-min", std::numeric_limits<int32_t>::min() }
     267        { "int32-min", std::numeric_limits<int32_t>::min() },
     268        { "uint32-max", static_cast<int32_t>(std::numeric_limits<uint32_t>::max()) },
     269        { "uint32-min", static_cast<int32_t>(std::numeric_limits<uint32_t>::min()) }
    264270    });
    265271    return operands;
Note: See TracChangeset for help on using the changeset viewer.