[llvm] [APFloat] Fix literals with long significands. (PR #102051)
Krzysztof Drewniak via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 3 12:08:53 PDT 2024
================
@@ -761,27 +745,45 @@ ulpsFromBoundary(const APFloatBase::integerPart *parts, unsigned int bits,
return ~(APFloatBase::integerPart) 0; /* A lot. */
}
-/* Place pow(5, power) in DST, and return the number of parts used.
- DST must be at least one part larger than size of the answer. */
-static unsigned int
-powerOf5(APFloatBase::integerPart *dst, unsigned int power) {
+/* Calculate and return pow(5, power). */
+static SmallVector<APFloatBase::integerPart, 0> powerOf5(unsigned int power) {
static const APFloatBase::integerPart firstEightPowers[] = { 1, 5, 25, 125, 625, 3125, 15625, 78125 };
- APFloatBase::integerPart pow5s[maxPowerOfFiveParts * 2 + 5];
+
+ // Make sure that the following expression does not overflow.
+ assert(power <= UINT_MAX / 815);
+
+ // A tight upper bound on number of parts required to hold the value
+ // pow(5, power) is
+ //
+ // power * 815 / (351 * integerPartWidth) + 1
+ //
+ // However, whilst the result may require only this many parts,
+ // because we are multiplying two values to get it, the
+ // multiplication may require an extra part with the excess part
+ // being zero (consider the trivial case of 1 * 1, tcFullMultiply
+ // requires two parts to hold the single-part result). So we add an
+ // extra one to guarantee enough space whilst multiplying.
+ const unsigned int maxPowerOfFiveParts =
+ 2 + ((power * 815) / (351 * APFloatBase::integerPartWidth));
+
+ SmallVector<APFloatBase::integerPart, 0> pow5s(maxPowerOfFiveParts * 2 + 5);
----------------
krzysz00 wrote:
`, 0>` is a heap allocation, I don't think that's what you want?
Either `, 1>` or just not specifying it
https://github.com/llvm/llvm-project/pull/102051
More information about the llvm-commits
mailing list