The previous implementation of getExactInverse used the following check
to identify powers of two:
// Check that the number is a power of two by making sure that only the
// integer bit is set in the significand.
if (significandLSB() != semantics->precision - 1)
return false;
This condition verifies that the only set bit in the significand is the
integer bit, which is correct for normal numbers. However, this logic is
not correct for subnormal values.
APFloat represents subnormal numbers by shifting the significand right
while holding the exponent at its minimum value. For a power of two in
the subnormal range, its single set bit will therefore be at a position
lower than precision - 1. The original check would consequently fail,
causing the function to determine that these numbers do not have an
exact multiplicative inverse.
The new logic calculated this correctly but it seems that
test/CodeGen/Thumb2/mve-vcvt-fixed-to-float.ll expected the old
behavior.
Seeing as how getExactInverse does not have tests or documentation, we
conservatively maintain (and document) this behavior.
This reverts commit 47e62e846beb267aad50eb9195dfd855e160483e.
This reverts commit f4941319cba19d7691baa6ec783c84be4d847637.
This broke llvm/test/CodeGen/Thumb2/mve-vcvt-fixed-to-float.ll which
took out a ton of buildbots and also broke premerge.
Some background: getExactInverse()'s callers expect that
the result is not subnormal.
DoubleAPFloat implemented getExactInverse() by going through
semPPCDoubleDoubleLegacy.
This means that numbers like 0x1p1022 which would have a normal inverse
in semPPCDoubleDouble would not in semPPCDoubleDoubleLegacy.
This commit refactors the logic into a single method on APFloat which
uses getExactLog2Abs() and scalbn() to calculate the inverse without
having to compute a reciprocal and test if it is inexact.
This approach works for both IEEEFloat and DoubleAPFloat.
An earlier draft of DoubleAPFloat::convertToSignExtendedInteger had
arranged for overflow to be handled in a different way. However, these
assertions are now possible if Hi+Lo are out of range and Lo != 0.
A test has been added to defend against a regression.
The prior implementation did not consider that the Lo component may
underflow when it undergoes scaling. This means that we need to
carefully handle things like binade crossings or how to handle
roundTowardZero when Hi and Lo have different signs.
Particularly annoying is roundTiesToAway when Hi and Lo have different
signs. It basically requires us to implement roundTiesTowardZero.
Previously, reserve() allocated double the required number of buckets.
For example, for NumEntries in the range [49, 96], it would reserve
256 buckets when only 128 are needed to maintain the load factor.
This patch removes "+ 1" in the NewSize calculation.
Use DoubleAPFloat::roundToIntegral to get a pair of APFloat values which
hold integral values. Then we sum the pair, taking care to make sure
that we handle edge cases like (hi=2^128, lo=-1) and ensuring that they
fit in an unsigned i128.
The previous implementation did not correctly handle double-doubles like
0x1p100 + 0x1p1 as the low order component would need more than a
106-bit significand to represent.
Rather than converting to the legacy 106-bit format, perform next() on the
low APFloat. Of course, we need to renormalize the two APFloats if
either of the two constraints are violated:
1. abs(low) <= ulp(high)/2
2. high = rtne(high + low)
Should renormalization be needed, it will increment the high component
and set low to the smallest value which obeys these rules.
The old version would prefer the "const &" overload over the "&&" one
unless the former was not allowed in the given situation. In particular,
if the function passed was "[](auto &&)" the argument would be "const &"
even if the value passed to transformOptional was an rvalue reference.
This version improves the handling of expression categories, and the
lambda argument category will reflect the argument category in the above
scenario.
Add `consume_front` that returns the first element and drops it from the
current ArrayRef, and `consume_back` that returns the last element and
drops it from the current ArrayRef.
The assumption here is that if data() returns a pointer and size()
exists it's something representing contiguous storage.
Modeled after the behavior of C++20 std::span and enables two-way
conversion between std::span (or really any span-like type) and
ArrayRef. Add a unit test that verifies this if std::span is around.
This also means we can get rid of specific conversions for std::vector
and SmallVector.
None of the constructors touched in this patch has a corresponding
definition. This patch explicitly deletes them with "= delete" while
moving them to the public section of respective classes. Note that "=
delete" itself serves as documentation.
Identified with modernize-use-equals-delete.
Added APInt::clearBits(unsigned loBit, unsigned hiBit) that clears bits within a certain range.
Fixes#136550
---------
Co-authored-by: Simon Pilgrim <llvm-dev@redking.me.uk>
std::array<> doesn't seem to decay to plain pointers on some MSVC
versions, causing windows build failures after 101fd87f98c9.
Use plain arrays to fix windows builds, including
https://lab.llvm.org/buildbot/#/builders/2/builds/22803
Introduce 'erase(const ElemTy &V)' member function to allow the deletion
of a certain value from EquivClasses. This is essential for certain
scenarios that require modifying the contents of EquivClasses.
---------
Co-authored-by: Florian Hahn <flo@fhahn.com>
Introduce members() iterator-helper to shorten the members_{begin,end}
idiom. A previous attempt of this patch was #130319, which had to be
reverted due to unit-test failures when attempting to call members() on
the end iterator. In this patch, members() accepts either an ECValue or
an ElemTy, which is more intuitive and doesn't suffer from the same
issue.
This PR add `DenseMap::insert_range` to `DenseMap` for consistency with
existing `DenseSet::insert_range`, `SmallSet::insert_range` and
`std::map::insert_range`.
This patch removes the old range constructors of SmallSet and
StringSet that do not take the llvm::from_range tag. Since there are
so few uses, this patch directly removes them without going through
the deprecation process.
DenseSet recently gained a range constructor:
DenseSet<T> Dest(llvm::from_range, Src);
This patch adds the same signature to SmallSetVector for consistency.
DenseSet recently gained a range constructor:
DenseSet<T> Dest(llvm::from_range, Src);
This patch adds the same signature to SetVector, SmallPtrSet,
SmallSet, and StringSet for consistency.
This pach adds StringSet::insert_range for consistency with
DenseSet::insert_range and std::set::insert_range from C++23.
In the unit test, I'm using contains instead of
testing::UnorderedElementsAre because the latter doesn't seem to work
with char *.