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

Changeset 294847 in webkit


Ignore:
Timestamp:
May 25, 2022, 4:50:04 PM (4 years ago)
Author:
Alan Coon
Message:

Cherry-pick 6983e76741a1. rdar://problem/93536782

Refine B3ReduceStrength's range for sign extension operations.
​https://bugs.webkit.org/show_bug.cgi?id=240720
<rdar://problem/93536782>

Reviewed by Yusuke Suzuki and Keith Miller.

  • Source/JavaScriptCore/b3/B3ReduceStrength.cpp:

Canonical link: ​https://commits.webkit.org/250808@main
git-svn-id: ​https://svn.webkit.org/repository/webkit/trunk@294563 268f45cc-cd09-0410-ab3c-d52691b4dbfc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/safari-613-branch/Source/JavaScriptCore/b3/B3ReduceStrength.cpp

    r287160 r294847  
    11/*
    2  * Copyright (C) 2015-2020 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2022 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
    … …  
    387387            return IntRange();
    388388        }
     389    }
     390
     391    template<typename T>
     392    IntRange sExt()
     393    {
     394        ASSERT(m_min >= INT32_MIN);
     395        ASSERT(m_max <= INT32_MAX);
     396        int64_t typeMin = std::numeric_limits<T>::min();
     397        int64_t typeMax = std::numeric_limits<T>::max();
     398        auto min = m_min;
     399        auto max = m_max;
     400
     401        if (typeMin <= min && min <= typeMax
     402            && typeMin <= max && max <= typeMax)
     403            return IntRange(min, max);
     404
     405        // Given type T with N bits, signed extension will turn bit N-1 as
     406        // a sign bit. If bits N-1 upwards are identical for both min and max,
     407        // then we're guaranteed that even after the sign extension, min and
     408        // max will still be in increasing order.
     409        //
     410        // For example, when T is int8_t, the space of numbers from highest to
     411        // lowest are as follows (in binary bits):
     412        //
     413        //      highest     0 111 1111  ^
     414        //                    ...       |
     415        //            1     0 000 0001  |   top segment
     416        //            0     0 000 0000  v
     417        //
     418        //           -1     1 111 1111  ^
     419        //           -2     1 111 1110  |   bottom segment
     420        //                    ...       |
     421        //       lowest     1 000 0000  v
     422        //
     423        // Note that if we exclude the sign bit, the range is made up of 2 segments
     424        // of contiguous increasing numbers. If min and max are both in the same
     425        // segment before the sign extension, then min and max will continue to be
     426        // in a contiguous segment after the sign extension. Only when min and max
     427        // spans across more than 1 of these segments, will min and max no longer
     428        // be guaranteed to be in a contiguous range after the sign extension.
     429        //
     430        // Hence, we can check if bits N-1 and up are identical for the range min
     431        // and max. If so, then the new min and max can be be computed by simply
     432        // applying sign extension to their original values.
     433
     434        constexpr unsigned numberOfBits = countOfBits<T>;
     435        constexpr int64_t segmentMask = (1ll << (numberOfBits - 1)) - 1;
     436        constexpr int64_t topBitsMask = ~segmentMask;
     437        int64_t minTopBits = topBitsMask & min;
     438        int64_t maxTopBits = topBitsMask & max;
     439
     440        if (minTopBits == maxTopBits)
     441            return IntRange(static_cast<int64_t>(static_cast<T>(min)), static_cast<int64_t>(static_cast<T>(max)));
     442
     443        return top<T>();
    389444    }
    390445
    … …  
    27662821
    27672822        case SExt8:
     2823            return rangeFor(value->child(0), timeToLive - 1).sExt<int8_t>();
    27682824        case SExt16:
     2825            return rangeFor(value->child(0), timeToLive - 1).sExt<int16_t>();
    27692826        case SExt32:
    2770             return rangeFor(value->child(0), timeToLive - 1);
     2827            return rangeFor(value->child(0), timeToLive - 1).sExt<int32_t>();
    27712828
    27722829        case ZExt32:
Note: See TracChangeset for help on using the changeset viewer.