1//===- llvm/ADT/APFloat.h - Arbitrary Precision Floating Point ---*- C++ -*-==//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file declares a class to represent arbitrary precision floating point
11/// values and provide a variety of arithmetic operations on them.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_ADT_APFLOAT_H
16#define LLVM_ADT_APFLOAT_H
17
18#include "llvm/ADT/APInt.h"
19#include "llvm/ADT/ArrayRef.h"
20#include "llvm/ADT/FloatingPointMode.h"
21#include "llvm/Support/ErrorHandling.h"
22#include "llvm/Support/float128.h"
23#include <memory>
24
25#define APFLOAT_DISPATCH_ON_SEMANTICS(METHOD_CALL) \
26 do { \
27 if (usesLayout<IEEEFloat>(getSemantics())) \
28 return U.IEEE.METHOD_CALL; \
29 if (usesLayout<DoubleAPFloat>(getSemantics())) \
30 return U.Double.METHOD_CALL; \
31 llvm_unreachable("Unexpected semantics"); \
32 } while (false)
33
34namespace llvm {
35
36struct fltSemantics;
37class APSInt;
38class StringRef;
39class APFloat;
40class raw_ostream;
41
42template <typename T> class Expected;
43template <typename T> class SmallVectorImpl;
44
45/// Enum that represents what fraction of the LSB truncated bits of an fp number
46/// represent.
47///
48/// This essentially combines the roles of guard and sticky bits.
49enum lostFraction { // Example of truncated bits:
50 lfExactlyZero, // 000000
51 lfLessThanHalf, // 0xxxxx x's not all zero
52 lfExactlyHalf, // 100000
53 lfMoreThanHalf // 1xxxxx x's not all zero
54};
55
56/// A self-contained host- and target-independent arbitrary-precision
57/// floating-point software implementation.
58///
59/// APFloat uses bignum integer arithmetic as provided by static functions in
60/// the APInt class. The library will work with bignum integers whose parts are
61/// any unsigned type at least 16 bits wide, but 64 bits is recommended.
62///
63/// Written for clarity rather than speed, in particular with a view to use in
64/// the front-end of a cross compiler so that target arithmetic can be correctly
65/// performed on the host. Performance should nonetheless be reasonable,
66/// particularly for its intended use. It may be useful as a base
67/// implementation for a run-time library during development of a faster
68/// target-specific one.
69///
70/// All 5 rounding modes in the IEEE-754R draft are handled correctly for all
71/// implemented operations. Currently implemented operations are add, subtract,
72/// multiply, divide, fused-multiply-add, conversion-to-float,
73/// conversion-to-integer and conversion-from-integer. New rounding modes
74/// (e.g. away from zero) can be added with three or four lines of code.
75///
76/// Four formats are built-in: IEEE single precision, double precision,
77/// quadruple precision, and x87 80-bit extended double (when operating with
78/// full extended precision). Adding a new format that obeys IEEE semantics
79/// only requires adding two lines of code: a declaration and definition of the
80/// format.
81///
82/// All operations return the status of that operation as an exception bit-mask,
83/// so multiple operations can be done consecutively with their results or-ed
84/// together. The returned status can be useful for compiler diagnostics; e.g.,
85/// inexact, underflow and overflow can be easily diagnosed on constant folding,
86/// and compiler optimizers can determine what exceptions would be raised by
87/// folding operations and optimize, or perhaps not optimize, accordingly.
88///
89/// At present, underflow tininess is detected after rounding; it should be
90/// straight forward to add support for the before-rounding case too.
91///
92/// The library reads hexadecimal floating point numbers as per C99, and
93/// correctly rounds if necessary according to the specified rounding mode.
94/// Syntax is required to have been validated by the caller. It also converts
95/// floating point numbers to hexadecimal text as per the C99 %a and %A
96/// conversions. The output precision (or alternatively the natural minimal
97/// precision) can be specified; if the requested precision is less than the
98/// natural precision the output is correctly rounded for the specified rounding
99/// mode.
100///
101/// It also reads decimal floating point numbers and correctly rounds according
102/// to the specified rounding mode.
103///
104/// Conversion to decimal text is not currently implemented.
105///
106/// Non-zero finite numbers are represented internally as a sign bit, a 16-bit
107/// signed exponent, and the significand as an array of integer parts. After
108/// normalization of a number of precision P the exponent is within the range of
109/// the format, and if the number is not denormal the P-th bit of the
110/// significand is set as an explicit integer bit. For denormals the most
111/// significant bit is shifted right so that the exponent is maintained at the
112/// format's minimum, so that the smallest denormal has just the least
113/// significant bit of the significand set. The sign of zeroes and infinities
114/// is significant; the exponent and significand of such numbers is not stored,
115/// but has a known implicit (deterministic) value: 0 for the significands, 0
116/// for zero exponent, all 1 bits for infinity exponent. For NaNs the sign and
117/// significand are deterministic, although not really meaningful, and preserved
118/// in non-conversion operations. The exponent is implicitly all 1 bits.
119///
120/// APFloat does not provide any exception handling beyond default exception
121/// handling. We represent Signaling NaNs via IEEE-754R 2008 6.2.1 should clause
122/// by encoding Signaling NaNs with the first bit of its trailing significand as
123/// 0.
124///
125/// TODO
126/// ====
127///
128/// Some features that may or may not be worth adding:
129///
130/// Binary to decimal conversion (hard).
131///
132/// Optional ability to detect underflow tininess before rounding.
133///
134/// New formats: x87 in single and double precision mode (IEEE apart from
135/// extended exponent range) (hard).
136///
137/// New operations: sqrt, IEEE remainder, C90 fmod, nexttoward.
138///
139
140// This is the common type definitions shared by APFloat and its internal
141// implementation classes. This struct should not define any non-static data
142// members.
143struct APFloatBase {
144 typedef APInt::WordType integerPart;
145 static constexpr unsigned integerPartWidth = APInt::APINT_BITS_PER_WORD;
146
147 /// A signed type to represent a floating point numbers unbiased exponent.
148 typedef int32_t ExponentType;
149
150 /// \name Floating Point Semantics.
151 /// @{
152 enum Semantics {
153 S_IEEEhalf,
154 S_BFloat,
155 S_IEEEsingle,
156 S_IEEEdouble,
157 S_IEEEquad,
158 // The IBM double-double semantics. Such a number consists of a pair of
159 // IEEE 64-bit doubles (Hi, Lo), where |Hi| > |Lo|, and if normal,
160 // (double)(Hi + Lo) == Hi. The numeric value it's modeling is Hi + Lo.
161 // Therefore it has two 53-bit mantissa parts that aren't necessarily
162 // adjacent to each other, and two 11-bit exponents.
163 //
164 // Note: we need to make the value different from semBogus as otherwise
165 // an unsafe optimization may collapse both values to a single address,
166 // and we heavily rely on them having distinct addresses.
167 S_PPCDoubleDouble,
168 // These are legacy semantics for the fallback, inaccurate implementation
169 // of IBM double-double, if the accurate semPPCDoubleDouble doesn't handle
170 // the operation. It's equivalent to having an IEEE number with consecutive
171 // 106 bits of mantissa and 11 bits of exponent.
172 //
173 // It's not equivalent to IBM double-double. For example, a legit IBM
174 // double-double, 1 + epsilon:
175 //
176 // 1 + epsilon = 1 + (1 >> 1076)
177 //
178 // is not representable by a consecutive 106 bits of mantissa.
179 //
180 // Currently, these semantics are used in the following way:
181 //
182 // semPPCDoubleDouble -> (IEEEdouble, IEEEdouble) ->
183 // (64-bit APInt, 64-bit APInt) -> (128-bit APInt) ->
184 // semPPCDoubleDoubleLegacy -> IEEE operations
185 //
186 // We use bitcastToAPInt() to get the bit representation (in APInt) of the
187 // underlying IEEEdouble, then use the APInt constructor to construct the
188 // legacy IEEE float.
189 //
190 // TODO: Implement all operations in semPPCDoubleDouble, and delete these
191 // semantics.
192 S_PPCDoubleDoubleLegacy,
193 // 8-bit floating point number following IEEE-754 conventions with bit
194 // layout S1E5M2 as described in https://arxiv.org/abs/2209.05433.
195 S_Float8E5M2,
196 // 8-bit floating point number mostly following IEEE-754 conventions
197 // and bit layout S1E5M2 described in https://arxiv.org/abs/2206.02915,
198 // with expanded range and with no infinity or signed zero.
199 // NaN is represented as negative zero. (FN -> Finite, UZ -> unsigned zero).
200 // This format's exponent bias is 16, instead of the 15 (2 ** (5 - 1) - 1)
201 // that IEEE precedent would imply.
202 S_Float8E5M2FNUZ,
203 // 8-bit floating point number following IEEE-754 conventions with bit
204 // layout S1E4M3.
205 S_Float8E4M3,
206 // 8-bit floating point number mostly following IEEE-754 conventions with
207 // bit layout S1E4M3 as described in https://arxiv.org/abs/2209.05433.
208 // Unlike IEEE-754 types, there are no infinity values, and NaN is
209 // represented with the exponent and mantissa bits set to all 1s.
210 S_Float8E4M3FN,
211 // 8-bit floating point number mostly following IEEE-754 conventions
212 // and bit layout S1E4M3 described in https://arxiv.org/abs/2206.02915,
213 // with expanded range and with no infinity or signed zero.
214 // NaN is represented as negative zero. (FN -> Finite, UZ -> unsigned zero).
215 // This format's exponent bias is 8, instead of the 7 (2 ** (4 - 1) - 1)
216 // that IEEE precedent would imply.
217 S_Float8E4M3FNUZ,
218 // 8-bit floating point number mostly following IEEE-754 conventions
219 // and bit layout S1E4M3 with expanded range and with no infinity or signed
220 // zero.
221 // NaN is represented as negative zero. (FN -> Finite, UZ -> unsigned zero).
222 // This format's exponent bias is 11, instead of the 7 (2 ** (4 - 1) - 1)
223 // that IEEE precedent would imply.
224 S_Float8E4M3B11FNUZ,
225 // 8-bit floating point number following IEEE-754 conventions with bit
226 // layout S1E3M4.
227 S_Float8E3M4,
228 // Floating point number that occupies 32 bits or less of storage, providing
229 // improved range compared to half (16-bit) formats, at (potentially)
230 // greater throughput than single precision (32-bit) formats.
231 S_FloatTF32,
232 // 8-bit floating point number with (all the) 8 bits for the exponent
233 // like in FP32. There are no zeroes, no infinities, and no denormal values.
234 // This format has unsigned representation only. (U -> Unsigned only).
235 // NaN is represented with all bits set to 1. Bias is 127.
236 // This format represents the scale data type in the MX specification from:
237 // https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf
238 S_Float8E8M0FNU,
239 // 6-bit floating point number with bit layout S1E3M2. Unlike IEEE-754
240 // types, there are no infinity or NaN values. The format is detailed in
241 // https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf
242 S_Float6E3M2FN,
243 // 6-bit floating point number with bit layout S1E2M3. Unlike IEEE-754
244 // types, there are no infinity or NaN values. The format is detailed in
245 // https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf
246 S_Float6E2M3FN,
247 // 4-bit floating point number with bit layout S1E2M1. Unlike IEEE-754
248 // types, there are no infinity or NaN values. The format is detailed in
249 // https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf
250 S_Float4E2M1FN,
251 // TODO: Documentation is missing.
252 S_x87DoubleExtended,
253 S_MaxSemantics = S_x87DoubleExtended,
254 };
255
256 static const llvm::fltSemantics &EnumToSemantics(Semantics S);
257 static Semantics SemanticsToEnum(const llvm::fltSemantics &Sem);
258
259 static const fltSemantics &IEEEhalf() LLVM_READNONE;
260 static const fltSemantics &BFloat() LLVM_READNONE;
261 static const fltSemantics &IEEEsingle() LLVM_READNONE;
262 static const fltSemantics &IEEEdouble() LLVM_READNONE;
263 static const fltSemantics &IEEEquad() LLVM_READNONE;
264 static const fltSemantics &PPCDoubleDouble() LLVM_READNONE;
265 static const fltSemantics &PPCDoubleDoubleLegacy() LLVM_READNONE;
266 static const fltSemantics &Float8E5M2() LLVM_READNONE;
267 static const fltSemantics &Float8E5M2FNUZ() LLVM_READNONE;
268 static const fltSemantics &Float8E4M3() LLVM_READNONE;
269 static const fltSemantics &Float8E4M3FN() LLVM_READNONE;
270 static const fltSemantics &Float8E4M3FNUZ() LLVM_READNONE;
271 static const fltSemantics &Float8E4M3B11FNUZ() LLVM_READNONE;
272 static const fltSemantics &Float8E3M4() LLVM_READNONE;
273 static const fltSemantics &FloatTF32() LLVM_READNONE;
274 static const fltSemantics &Float8E8M0FNU() LLVM_READNONE;
275 static const fltSemantics &Float6E3M2FN() LLVM_READNONE;
276 static const fltSemantics &Float6E2M3FN() LLVM_READNONE;
277 static const fltSemantics &Float4E2M1FN() LLVM_READNONE;
278 static const fltSemantics &x87DoubleExtended() LLVM_READNONE;
279
280 /// A Pseudo fltsemantic used to construct APFloats that cannot conflict with
281 /// anything real.
282 static const fltSemantics &Bogus() LLVM_READNONE;
283
284 // Returns true if any number described by this semantics can be precisely
285 // represented by the specified semantics. Does not take into account
286 // the value of fltNonfiniteBehavior, hasZero, hasSignedRepr.
287 static bool isRepresentableBy(const fltSemantics &A, const fltSemantics &B);
288
289 /// @}
290
291 /// IEEE-754R 5.11: Floating Point Comparison Relations.
292 enum cmpResult {
293 cmpLessThan,
294 cmpEqual,
295 cmpGreaterThan,
296 cmpUnordered
297 };
298
299 /// IEEE-754R 4.3: Rounding-direction attributes.
300 using roundingMode = llvm::RoundingMode;
301
302 static constexpr roundingMode rmNearestTiesToEven =
303 RoundingMode::NearestTiesToEven;
304 static constexpr roundingMode rmTowardPositive = RoundingMode::TowardPositive;
305 static constexpr roundingMode rmTowardNegative = RoundingMode::TowardNegative;
306 static constexpr roundingMode rmTowardZero = RoundingMode::TowardZero;
307 static constexpr roundingMode rmNearestTiesToAway =
308 RoundingMode::NearestTiesToAway;
309
310 /// IEEE-754R 7: Default exception handling.
311 ///
312 /// opUnderflow or opOverflow are always returned or-ed with opInexact.
313 ///
314 /// APFloat models this behavior specified by IEEE-754:
315 /// "For operations producing results in floating-point format, the default
316 /// result of an operation that signals the invalid operation exception
317 /// shall be a quiet NaN."
318 enum opStatus {
319 opOK = 0x00,
320 opInvalidOp = 0x01,
321 opDivByZero = 0x02,
322 opOverflow = 0x04,
323 opUnderflow = 0x08,
324 opInexact = 0x10
325 };
326
327 /// Category of internally-represented number.
328 enum fltCategory {
329 fcInfinity,
330 fcNaN,
331 fcNormal,
332 fcZero
333 };
334
335 /// Convenience enum used to construct an uninitialized APFloat.
336 enum uninitializedTag {
337 uninitialized
338 };
339
340 /// Enumeration of \c ilogb error results.
341 enum IlogbErrorKinds {
342 IEK_Zero = INT_MIN + 1,
343 IEK_NaN = INT_MIN,
344 IEK_Inf = INT_MAX
345 };
346
347 static unsigned int semanticsPrecision(const fltSemantics &);
348 static ExponentType semanticsMinExponent(const fltSemantics &);
349 static ExponentType semanticsMaxExponent(const fltSemantics &);
350 static unsigned int semanticsSizeInBits(const fltSemantics &);
351 static unsigned int semanticsIntSizeInBits(const fltSemantics&, bool);
352 static bool semanticsHasZero(const fltSemantics &);
353 static bool semanticsHasSignedRepr(const fltSemantics &);
354 static bool semanticsHasInf(const fltSemantics &);
355 static bool semanticsHasNaN(const fltSemantics &);
356 static bool isIEEELikeFP(const fltSemantics &);
357
358 // Returns true if any number described by \p Src can be precisely represented
359 // by a normal (not subnormal) value in \p Dst.
360 static bool isRepresentableAsNormalIn(const fltSemantics &Src,
361 const fltSemantics &Dst);
362
363 /// Returns the size of the floating point number (in bits) in the given
364 /// semantics.
365 static unsigned getSizeInBits(const fltSemantics &Sem);
366};
367
368namespace detail {
369
370using integerPart = APFloatBase::integerPart;
371using uninitializedTag = APFloatBase::uninitializedTag;
372using roundingMode = APFloatBase::roundingMode;
373using opStatus = APFloatBase::opStatus;
374using cmpResult = APFloatBase::cmpResult;
375using fltCategory = APFloatBase::fltCategory;
376using ExponentType = APFloatBase::ExponentType;
377static constexpr uninitializedTag uninitialized = APFloatBase::uninitialized;
378static constexpr roundingMode rmNearestTiesToEven =
379 APFloatBase::rmNearestTiesToEven;
380static constexpr roundingMode rmNearestTiesToAway =
381 APFloatBase::rmNearestTiesToAway;
382static constexpr roundingMode rmTowardNegative = APFloatBase::rmTowardNegative;
383static constexpr roundingMode rmTowardPositive = APFloatBase::rmTowardPositive;
384static constexpr roundingMode rmTowardZero = APFloatBase::rmTowardZero;
385static constexpr unsigned integerPartWidth = APFloatBase::integerPartWidth;
386static constexpr cmpResult cmpEqual = APFloatBase::cmpEqual;
387static constexpr cmpResult cmpLessThan = APFloatBase::cmpLessThan;
388static constexpr cmpResult cmpGreaterThan = APFloatBase::cmpGreaterThan;
389static constexpr cmpResult cmpUnordered = APFloatBase::cmpUnordered;
390static constexpr opStatus opOK = APFloatBase::opOK;
391static constexpr opStatus opInvalidOp = APFloatBase::opInvalidOp;
392static constexpr opStatus opDivByZero = APFloatBase::opDivByZero;
393static constexpr opStatus opOverflow = APFloatBase::opOverflow;
394static constexpr opStatus opUnderflow = APFloatBase::opUnderflow;
395static constexpr opStatus opInexact = APFloatBase::opInexact;
396static constexpr fltCategory fcInfinity = APFloatBase::fcInfinity;
397static constexpr fltCategory fcNaN = APFloatBase::fcNaN;
398static constexpr fltCategory fcNormal = APFloatBase::fcNormal;
399static constexpr fltCategory fcZero = APFloatBase::fcZero;
400
401class IEEEFloat final {
402public:
403 /// \name Constructors
404 /// @{
405
406 IEEEFloat(const fltSemantics &); // Default construct to +0.0
407 IEEEFloat(const fltSemantics &, integerPart);
408 IEEEFloat(const fltSemantics &, uninitializedTag);
409 IEEEFloat(const fltSemantics &, const APInt &);
410 explicit IEEEFloat(double d);
411 explicit IEEEFloat(float f);
412 IEEEFloat(const IEEEFloat &);
413 IEEEFloat(IEEEFloat &&);
414 ~IEEEFloat();
415
416 /// @}
417
418 /// Returns whether this instance allocated memory.
419 bool needsCleanup() const { return partCount() > 1; }
420
421 /// \name Convenience "constructors"
422 /// @{
423
424 /// @}
425
426 /// \name Arithmetic
427 /// @{
428
429 opStatus add(const IEEEFloat &, roundingMode);
430 opStatus subtract(const IEEEFloat &, roundingMode);
431 opStatus multiply(const IEEEFloat &, roundingMode);
432 opStatus divide(const IEEEFloat &, roundingMode);
433 /// IEEE remainder.
434 opStatus remainder(const IEEEFloat &);
435 /// C fmod, or llvm frem.
436 opStatus mod(const IEEEFloat &);
437 opStatus fusedMultiplyAdd(const IEEEFloat &, const IEEEFloat &, roundingMode);
438 opStatus roundToIntegral(roundingMode);
439 /// IEEE-754R 5.3.1: nextUp/nextDown.
440 opStatus next(bool nextDown);
441
442 /// @}
443
444 /// \name Sign operations.
445 /// @{
446
447 void changeSign();
448
449 /// @}
450
451 /// \name Conversions
452 /// @{
453
454 opStatus convert(const fltSemantics &, roundingMode, bool *);
455 opStatus convertToInteger(MutableArrayRef<integerPart>, unsigned int, bool,
456 roundingMode, bool *) const;
457 opStatus convertFromAPInt(const APInt &, bool, roundingMode);
458 opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int,
459 bool, roundingMode);
460 opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned int,
461 bool, roundingMode);
462 Expected<opStatus> convertFromString(StringRef, roundingMode);
463 APInt bitcastToAPInt() const;
464 double convertToDouble() const;
465#ifdef HAS_IEE754_FLOAT128
466 float128 convertToQuad() const;
467#endif
468 float convertToFloat() const;
469
470 /// @}
471
472 /// The definition of equality is not straightforward for floating point, so
473 /// we won't use operator==. Use one of the following, or write whatever it
474 /// is you really mean.
475 bool operator==(const IEEEFloat &) const = delete;
476
477 /// IEEE comparison with another floating point number (NaNs compare
478 /// unordered, 0==-0).
479 cmpResult compare(const IEEEFloat &) const;
480
481 /// Bitwise comparison for equality (QNaNs compare equal, 0!=-0).
482 bool bitwiseIsEqual(const IEEEFloat &) const;
483
484 /// Write out a hexadecimal representation of the floating point value to DST,
485 /// which must be of sufficient size, in the C99 form [-]0xh.hhhhp[+-]d.
486 /// Return the number of characters written, excluding the terminating NUL.
487 unsigned int convertToHexString(char *dst, unsigned int hexDigits,
488 bool upperCase, roundingMode) const;
489
490 /// \name IEEE-754R 5.7.2 General operations.
491 /// @{
492
493 /// IEEE-754R isSignMinus: Returns true if and only if the current value is
494 /// negative.
495 ///
496 /// This applies to zeros and NaNs as well.
497 bool isNegative() const { return sign; }
498
499 /// IEEE-754R isNormal: Returns true if and only if the current value is normal.
500 ///
501 /// This implies that the current value of the float is not zero, subnormal,
502 /// infinite, or NaN following the definition of normality from IEEE-754R.
503 bool isNormal() const { return !isDenormal() && isFiniteNonZero(); }
504
505 /// Returns true if and only if the current value is zero, subnormal, or
506 /// normal.
507 ///
508 /// This means that the value is not infinite or NaN.
509 bool isFinite() const { return !isNaN() && !isInfinity(); }
510
511 /// Returns true if and only if the float is plus or minus zero.
512 bool isZero() const { return category == fltCategory::fcZero; }
513
514 /// IEEE-754R isSubnormal(): Returns true if and only if the float is a
515 /// denormal.
516 bool isDenormal() const;
517
518 /// IEEE-754R isInfinite(): Returns true if and only if the float is infinity.
519 bool isInfinity() const { return category == fcInfinity; }
520
521 /// Returns true if and only if the float is a quiet or signaling NaN.
522 bool isNaN() const { return category == fcNaN; }
523
524 /// Returns true if and only if the float is a signaling NaN.
525 bool isSignaling() const;
526
527 /// @}
528
529 /// \name Simple Queries
530 /// @{
531
532 fltCategory getCategory() const { return category; }
533 const fltSemantics &getSemantics() const { return *semantics; }
534 bool isNonZero() const { return category != fltCategory::fcZero; }
535 bool isFiniteNonZero() const { return isFinite() && !isZero(); }
536 bool isPosZero() const { return isZero() && !isNegative(); }
537 bool isNegZero() const { return isZero() && isNegative(); }
538
539 /// Returns true if and only if the number has the smallest possible non-zero
540 /// magnitude in the current semantics.
541 bool isSmallest() const;
542
543 /// Returns true if this is the smallest (by magnitude) normalized finite
544 /// number in the given semantics.
545 bool isSmallestNormalized() const;
546
547 /// Returns true if and only if the number has the largest possible finite
548 /// magnitude in the current semantics.
549 bool isLargest() const;
550
551 /// Returns true if and only if the number is an exact integer.
552 bool isInteger() const;
553
554 /// @}
555
556 IEEEFloat &operator=(const IEEEFloat &);
557 IEEEFloat &operator=(IEEEFloat &&);
558
559 /// Overload to compute a hash code for an APFloat value.
560 ///
561 /// Note that the use of hash codes for floating point values is in general
562 /// frought with peril. Equality is hard to define for these values. For
563 /// example, should negative and positive zero hash to different codes? Are
564 /// they equal or not? This hash value implementation specifically
565 /// emphasizes producing different codes for different inputs in order to
566 /// be used in canonicalization and memoization. As such, equality is
567 /// bitwiseIsEqual, and 0 != -0.
568 friend hash_code hash_value(const IEEEFloat &Arg);
569
570 /// Converts this value into a decimal string.
571 ///
572 /// \param FormatPrecision The maximum number of digits of
573 /// precision to output. If there are fewer digits available,
574 /// zero padding will not be used unless the value is
575 /// integral and small enough to be expressed in
576 /// FormatPrecision digits. 0 means to use the natural
577 /// precision of the number.
578 /// \param FormatMaxPadding The maximum number of zeros to
579 /// consider inserting before falling back to scientific
580 /// notation. 0 means to always use scientific notation.
581 ///
582 /// \param TruncateZero Indicate whether to remove the trailing zero in
583 /// fraction part or not. Also setting this parameter to false forcing
584 /// producing of output more similar to default printf behavior.
585 /// Specifically the lower e is used as exponent delimiter and exponent
586 /// always contains no less than two digits.
587 ///
588 /// Number Precision MaxPadding Result
589 /// ------ --------- ---------- ------
590 /// 1.01E+4 5 2 10100
591 /// 1.01E+4 4 2 1.01E+4
592 /// 1.01E+4 5 1 1.01E+4
593 /// 1.01E-2 5 2 0.0101
594 /// 1.01E-2 4 2 0.0101
595 /// 1.01E-2 4 1 1.01E-2
596 void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision = 0,
597 unsigned FormatMaxPadding = 3, bool TruncateZero = true) const;
598
599 /// If this value has an exact multiplicative inverse, store it in inv and
600 /// return true.
601 bool getExactInverse(APFloat *inv) const;
602
603 // If this is an exact power of two, return the exponent while ignoring the
604 // sign bit. If it's not an exact power of 2, return INT_MIN
605 LLVM_READONLY
606 int getExactLog2Abs() const;
607
608 // If this is an exact power of two, return the exponent. If it's not an exact
609 // power of 2, return INT_MIN
610 LLVM_READONLY
611 int getExactLog2() const {
612 return isNegative() ? INT_MIN : getExactLog2Abs();
613 }
614
615 /// Returns the exponent of the internal representation of the APFloat.
616 ///
617 /// Because the radix of APFloat is 2, this is equivalent to floor(log2(x)).
618 /// For special APFloat values, this returns special error codes:
619 ///
620 /// NaN -> \c IEK_NaN
621 /// 0 -> \c IEK_Zero
622 /// Inf -> \c IEK_Inf
623 ///
624 friend int ilogb(const IEEEFloat &Arg);
625
626 /// Returns: X * 2^Exp for integral exponents.
627 friend IEEEFloat scalbn(IEEEFloat X, int Exp, roundingMode);
628
629 friend IEEEFloat frexp(const IEEEFloat &X, int &Exp, roundingMode);
630
631 /// \name Special value setters.
632 /// @{
633
634 void makeLargest(bool Neg = false);
635 void makeSmallest(bool Neg = false);
636 void makeNaN(bool SNaN = false, bool Neg = false,
637 const APInt *fill = nullptr);
638 void makeInf(bool Neg = false);
639 void makeZero(bool Neg = false);
640 void makeQuiet();
641
642 /// Returns the smallest (by magnitude) normalized finite number in the given
643 /// semantics.
644 ///
645 /// \param Negative - True iff the number should be negative
646 void makeSmallestNormalized(bool Negative = false);
647
648 /// @}
649
650 cmpResult compareAbsoluteValue(const IEEEFloat &) const;
651
652private:
653 /// \name Simple Queries
654 /// @{
655
656 integerPart *significandParts();
657 const integerPart *significandParts() const;
658 unsigned int partCount() const;
659
660 /// @}
661
662 /// \name Significand operations.
663 /// @{
664
665 integerPart addSignificand(const IEEEFloat &);
666 integerPart subtractSignificand(const IEEEFloat &, integerPart);
667 lostFraction addOrSubtractSignificand(const IEEEFloat &, bool subtract);
668 lostFraction multiplySignificand(const IEEEFloat &, IEEEFloat,
669 bool ignoreAddend = false);
670 lostFraction multiplySignificand(const IEEEFloat&);
671 lostFraction divideSignificand(const IEEEFloat &);
672 void incrementSignificand();
673 void initialize(const fltSemantics *);
674 void shiftSignificandLeft(unsigned int);
675 lostFraction shiftSignificandRight(unsigned int);
676 unsigned int significandLSB() const;
677 unsigned int significandMSB() const;
678 void zeroSignificand();
679 unsigned int getNumHighBits() const;
680 /// Return true if the significand excluding the integral bit is all ones.
681 bool isSignificandAllOnes() const;
682 bool isSignificandAllOnesExceptLSB() const;
683 /// Return true if the significand excluding the integral bit is all zeros.
684 bool isSignificandAllZeros() const;
685 bool isSignificandAllZerosExceptMSB() const;
686
687 /// @}
688
689 /// \name Arithmetic on special values.
690 /// @{
691
692 opStatus addOrSubtractSpecials(const IEEEFloat &, bool subtract);
693 opStatus divideSpecials(const IEEEFloat &);
694 opStatus multiplySpecials(const IEEEFloat &);
695 opStatus modSpecials(const IEEEFloat &);
696 opStatus remainderSpecials(const IEEEFloat&);
697
698 /// @}
699
700 /// \name Miscellany
701 /// @{
702
703 bool convertFromStringSpecials(StringRef str);
704 opStatus normalize(roundingMode, lostFraction);
705 opStatus addOrSubtract(const IEEEFloat &, roundingMode, bool subtract);
706 opStatus handleOverflow(roundingMode);
707 bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const;
708 opStatus convertToSignExtendedInteger(MutableArrayRef<integerPart>,
709 unsigned int, bool, roundingMode,
710 bool *) const;
711 opStatus convertFromUnsignedParts(const integerPart *, unsigned int,
712 roundingMode);
713 Expected<opStatus> convertFromHexadecimalString(StringRef, roundingMode);
714 Expected<opStatus> convertFromDecimalString(StringRef, roundingMode);
715 char *convertNormalToHexString(char *, unsigned int, bool,
716 roundingMode) const;
717 opStatus roundSignificandWithExponent(const integerPart *, unsigned int, int,
718 roundingMode);
719 ExponentType exponentNaN() const;
720 ExponentType exponentInf() const;
721 ExponentType exponentZero() const;
722
723 /// @}
724
725 template <const fltSemantics &S> APInt convertIEEEFloatToAPInt() const;
726 APInt convertHalfAPFloatToAPInt() const;
727 APInt convertBFloatAPFloatToAPInt() const;
728 APInt convertFloatAPFloatToAPInt() const;
729 APInt convertDoubleAPFloatToAPInt() const;
730 APInt convertQuadrupleAPFloatToAPInt() const;
731 APInt convertF80LongDoubleAPFloatToAPInt() const;
732 APInt convertPPCDoubleDoubleLegacyAPFloatToAPInt() const;
733 APInt convertFloat8E5M2APFloatToAPInt() const;
734 APInt convertFloat8E5M2FNUZAPFloatToAPInt() const;
735 APInt convertFloat8E4M3APFloatToAPInt() const;
736 APInt convertFloat8E4M3FNAPFloatToAPInt() const;
737 APInt convertFloat8E4M3FNUZAPFloatToAPInt() const;
738 APInt convertFloat8E4M3B11FNUZAPFloatToAPInt() const;
739 APInt convertFloat8E3M4APFloatToAPInt() const;
740 APInt convertFloatTF32APFloatToAPInt() const;
741 APInt convertFloat8E8M0FNUAPFloatToAPInt() const;
742 APInt convertFloat6E3M2FNAPFloatToAPInt() const;
743 APInt convertFloat6E2M3FNAPFloatToAPInt() const;
744 APInt convertFloat4E2M1FNAPFloatToAPInt() const;
745 void initFromAPInt(const fltSemantics *Sem, const APInt &api);
746 template <const fltSemantics &S> void initFromIEEEAPInt(const APInt &api);
747 void initFromHalfAPInt(const APInt &api);
748 void initFromBFloatAPInt(const APInt &api);
749 void initFromFloatAPInt(const APInt &api);
750 void initFromDoubleAPInt(const APInt &api);
751 void initFromQuadrupleAPInt(const APInt &api);
752 void initFromF80LongDoubleAPInt(const APInt &api);
753 void initFromPPCDoubleDoubleLegacyAPInt(const APInt &api);
754 void initFromFloat8E5M2APInt(const APInt &api);
755 void initFromFloat8E5M2FNUZAPInt(const APInt &api);
756 void initFromFloat8E4M3APInt(const APInt &api);
757 void initFromFloat8E4M3FNAPInt(const APInt &api);
758 void initFromFloat8E4M3FNUZAPInt(const APInt &api);
759 void initFromFloat8E4M3B11FNUZAPInt(const APInt &api);
760 void initFromFloat8E3M4APInt(const APInt &api);
761 void initFromFloatTF32APInt(const APInt &api);
762 void initFromFloat8E8M0FNUAPInt(const APInt &api);
763 void initFromFloat6E3M2FNAPInt(const APInt &api);
764 void initFromFloat6E2M3FNAPInt(const APInt &api);
765 void initFromFloat4E2M1FNAPInt(const APInt &api);
766
767 void assign(const IEEEFloat &);
768 void copySignificand(const IEEEFloat &);
769 void freeSignificand();
770
771 /// Note: this must be the first data member.
772 /// The semantics that this value obeys.
773 const fltSemantics *semantics;
774
775 /// A binary fraction with an explicit integer bit.
776 ///
777 /// The significand must be at least one bit wider than the target precision.
778 union Significand {
779 integerPart part;
780 integerPart *parts;
781 } significand;
782
783 /// The signed unbiased exponent of the value.
784 ExponentType exponent;
785
786 /// What kind of floating point number this is.
787 ///
788 /// Only 2 bits are required, but VisualStudio incorrectly sign extends it.
789 /// Using the extra bit keeps it from failing under VisualStudio.
790 fltCategory category : 3;
791
792 /// Sign bit of the number.
793 unsigned int sign : 1;
794};
795
796hash_code hash_value(const IEEEFloat &Arg);
797int ilogb(const IEEEFloat &Arg);
798IEEEFloat scalbn(IEEEFloat X, int Exp, roundingMode);
799IEEEFloat frexp(const IEEEFloat &Val, int &Exp, roundingMode RM);
800
801// This mode implements more precise float in terms of two APFloats.
802// The interface and layout is designed for arbitrary underlying semantics,
803// though currently only PPCDoubleDouble semantics are supported, whose
804// corresponding underlying semantics are IEEEdouble.
805class DoubleAPFloat final {
806 // Note: this must be the first data member.
807 const fltSemantics *Semantics;
808 std::unique_ptr<APFloat[]> Floats;
809
810 opStatus addImpl(const APFloat &a, const APFloat &aa, const APFloat &c,
811 const APFloat &cc, roundingMode RM);
812
813 opStatus addWithSpecial(const DoubleAPFloat &LHS, const DoubleAPFloat &RHS,
814 DoubleAPFloat &Out, roundingMode RM);
815
816public:
817 DoubleAPFloat(const fltSemantics &S);
818 DoubleAPFloat(const fltSemantics &S, uninitializedTag);
819 DoubleAPFloat(const fltSemantics &S, integerPart);
820 DoubleAPFloat(const fltSemantics &S, const APInt &I);
821 DoubleAPFloat(const fltSemantics &S, APFloat &&First, APFloat &&Second);
822 DoubleAPFloat(const DoubleAPFloat &RHS);
823 DoubleAPFloat(DoubleAPFloat &&RHS);
824
825 DoubleAPFloat &operator=(const DoubleAPFloat &RHS);
826 inline DoubleAPFloat &operator=(DoubleAPFloat &&RHS);
827
828 bool needsCleanup() const { return Floats != nullptr; }
829
830 inline APFloat &getFirst();
831 inline const APFloat &getFirst() const;
832 inline APFloat &getSecond();
833 inline const APFloat &getSecond() const;
834
835 opStatus add(const DoubleAPFloat &RHS, roundingMode RM);
836 opStatus subtract(const DoubleAPFloat &RHS, roundingMode RM);
837 opStatus multiply(const DoubleAPFloat &RHS, roundingMode RM);
838 opStatus divide(const DoubleAPFloat &RHS, roundingMode RM);
839 opStatus remainder(const DoubleAPFloat &RHS);
840 opStatus mod(const DoubleAPFloat &RHS);
841 opStatus fusedMultiplyAdd(const DoubleAPFloat &Multiplicand,
842 const DoubleAPFloat &Addend, roundingMode RM);
843 opStatus roundToIntegral(roundingMode RM);
844 void changeSign();
845 cmpResult compareAbsoluteValue(const DoubleAPFloat &RHS) const;
846
847 fltCategory getCategory() const;
848 bool isNegative() const;
849
850 void makeInf(bool Neg);
851 void makeZero(bool Neg);
852 void makeLargest(bool Neg);
853 void makeSmallest(bool Neg);
854 void makeSmallestNormalized(bool Neg);
855 void makeNaN(bool SNaN, bool Neg, const APInt *fill);
856
857 cmpResult compare(const DoubleAPFloat &RHS) const;
858 bool bitwiseIsEqual(const DoubleAPFloat &RHS) const;
859 APInt bitcastToAPInt() const;
860 Expected<opStatus> convertFromString(StringRef, roundingMode);
861 opStatus next(bool nextDown);
862
863 opStatus convertToInteger(MutableArrayRef<integerPart> Input,
864 unsigned int Width, bool IsSigned, roundingMode RM,
865 bool *IsExact) const;
866 opStatus convertFromAPInt(const APInt &Input, bool IsSigned, roundingMode RM);
867 opStatus convertFromSignExtendedInteger(const integerPart *Input,
868 unsigned int InputSize, bool IsSigned,
869 roundingMode RM);
870 opStatus convertFromZeroExtendedInteger(const integerPart *Input,
871 unsigned int InputSize, bool IsSigned,
872 roundingMode RM);
873 unsigned int convertToHexString(char *DST, unsigned int HexDigits,
874 bool UpperCase, roundingMode RM) const;
875
876 bool isDenormal() const;
877 bool isSmallest() const;
878 bool isSmallestNormalized() const;
879 bool isLargest() const;
880 bool isInteger() const;
881
882 void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision,
883 unsigned FormatMaxPadding, bool TruncateZero = true) const;
884
885 bool getExactInverse(APFloat *inv) const;
886
887 LLVM_READONLY
888 int getExactLog2() const;
889 LLVM_READONLY
890 int getExactLog2Abs() const;
891
892 friend DoubleAPFloat scalbn(const DoubleAPFloat &X, int Exp, roundingMode);
893 friend DoubleAPFloat frexp(const DoubleAPFloat &X, int &Exp, roundingMode);
894 friend hash_code hash_value(const DoubleAPFloat &Arg);
895};
896
897hash_code hash_value(const DoubleAPFloat &Arg);
898DoubleAPFloat scalbn(const DoubleAPFloat &Arg, int Exp, roundingMode RM);
899DoubleAPFloat frexp(const DoubleAPFloat &X, int &Exp, roundingMode);
900
901} // End detail namespace
902
903// This is a interface class that is currently forwarding functionalities from
904// detail::IEEEFloat.
905class APFloat : public APFloatBase {
906 typedef detail::IEEEFloat IEEEFloat;
907 typedef detail::DoubleAPFloat DoubleAPFloat;
908
909 static_assert(std::is_standard_layout<IEEEFloat>::value);
910
911 union Storage {
912 const fltSemantics *semantics;
913 IEEEFloat IEEE;
914 DoubleAPFloat Double;
915
916 explicit Storage(IEEEFloat F, const fltSemantics &S);
917 explicit Storage(DoubleAPFloat F, const fltSemantics &S)
918 : Double(std::move(F)) {
919 assert(&S == &PPCDoubleDouble());
920 }
921
922 template <typename... ArgTypes>
923 Storage(const fltSemantics &Semantics, ArgTypes &&... Args) {
924 if (usesLayout<IEEEFloat>(Semantics)) {
925 new (&IEEE) IEEEFloat(Semantics, std::forward<ArgTypes>(Args)...);
926 return;
927 }
928 if (usesLayout<DoubleAPFloat>(Semantics)) {
929 new (&Double) DoubleAPFloat(Semantics, std::forward<ArgTypes>(Args)...);
930 return;
931 }
932 llvm_unreachable("Unexpected semantics");
933 }
934
935 ~Storage() {
936 if (usesLayout<IEEEFloat>(Semantics: *semantics)) {
937 IEEE.~IEEEFloat();
938 return;
939 }
940 if (usesLayout<DoubleAPFloat>(Semantics: *semantics)) {
941 Double.~DoubleAPFloat();
942 return;
943 }
944 llvm_unreachable("Unexpected semantics");
945 }
946
947 Storage(const Storage &RHS) {
948 if (usesLayout<IEEEFloat>(Semantics: *RHS.semantics)) {
949 new (this) IEEEFloat(RHS.IEEE);
950 return;
951 }
952 if (usesLayout<DoubleAPFloat>(Semantics: *RHS.semantics)) {
953 new (this) DoubleAPFloat(RHS.Double);
954 return;
955 }
956 llvm_unreachable("Unexpected semantics");
957 }
958
959 Storage(Storage &&RHS) {
960 if (usesLayout<IEEEFloat>(Semantics: *RHS.semantics)) {
961 new (this) IEEEFloat(std::move(RHS.IEEE));
962 return;
963 }
964 if (usesLayout<DoubleAPFloat>(Semantics: *RHS.semantics)) {
965 new (this) DoubleAPFloat(std::move(RHS.Double));
966 return;
967 }
968 llvm_unreachable("Unexpected semantics");
969 }
970
971 Storage &operator=(const Storage &RHS) {
972 if (usesLayout<IEEEFloat>(Semantics: *semantics) &&
973 usesLayout<IEEEFloat>(Semantics: *RHS.semantics)) {
974 IEEE = RHS.IEEE;
975 } else if (usesLayout<DoubleAPFloat>(Semantics: *semantics) &&
976 usesLayout<DoubleAPFloat>(Semantics: *RHS.semantics)) {
977 Double = RHS.Double;
978 } else if (this != &RHS) {
979 this->~Storage();
980 new (this) Storage(RHS);
981 }
982 return *this;
983 }
984
985 Storage &operator=(Storage &&RHS) {
986 if (usesLayout<IEEEFloat>(Semantics: *semantics) &&
987 usesLayout<IEEEFloat>(Semantics: *RHS.semantics)) {
988 IEEE = std::move(RHS.IEEE);
989 } else if (usesLayout<DoubleAPFloat>(Semantics: *semantics) &&
990 usesLayout<DoubleAPFloat>(Semantics: *RHS.semantics)) {
991 Double = std::move(RHS.Double);
992 } else if (this != &RHS) {
993 this->~Storage();
994 new (this) Storage(std::move(RHS));
995 }
996 return *this;
997 }
998 } U;
999
1000 template <typename T> static bool usesLayout(const fltSemantics &Semantics) {
1001 static_assert(std::is_same<T, IEEEFloat>::value ||
1002 std::is_same<T, DoubleAPFloat>::value);
1003 if (std::is_same<T, DoubleAPFloat>::value) {
1004 return &Semantics == &PPCDoubleDouble();
1005 }
1006 return &Semantics != &PPCDoubleDouble();
1007 }
1008
1009 IEEEFloat &getIEEE() {
1010 if (usesLayout<IEEEFloat>(Semantics: *U.semantics))
1011 return U.IEEE;
1012 if (usesLayout<DoubleAPFloat>(Semantics: *U.semantics))
1013 return U.Double.getFirst().U.IEEE;
1014 llvm_unreachable("Unexpected semantics");
1015 }
1016
1017 const IEEEFloat &getIEEE() const {
1018 if (usesLayout<IEEEFloat>(Semantics: *U.semantics))
1019 return U.IEEE;
1020 if (usesLayout<DoubleAPFloat>(Semantics: *U.semantics))
1021 return U.Double.getFirst().U.IEEE;
1022 llvm_unreachable("Unexpected semantics");
1023 }
1024
1025 void makeZero(bool Neg) { APFLOAT_DISPATCH_ON_SEMANTICS(makeZero(Neg)); }
1026
1027 void makeInf(bool Neg) { APFLOAT_DISPATCH_ON_SEMANTICS(makeInf(Neg)); }
1028
1029 void makeNaN(bool SNaN, bool Neg, const APInt *fill) {
1030 APFLOAT_DISPATCH_ON_SEMANTICS(makeNaN(SNaN, Neg, fill));
1031 }
1032
1033 void makeLargest(bool Neg) {
1034 APFLOAT_DISPATCH_ON_SEMANTICS(makeLargest(Neg));
1035 }
1036
1037 void makeSmallest(bool Neg) {
1038 APFLOAT_DISPATCH_ON_SEMANTICS(makeSmallest(Neg));
1039 }
1040
1041 void makeSmallestNormalized(bool Neg) {
1042 APFLOAT_DISPATCH_ON_SEMANTICS(makeSmallestNormalized(Neg));
1043 }
1044
1045 explicit APFloat(IEEEFloat F, const fltSemantics &S) : U(std::move(F), S) {}
1046 explicit APFloat(DoubleAPFloat F, const fltSemantics &S)
1047 : U(std::move(F), S) {}
1048
1049 cmpResult compareAbsoluteValue(const APFloat &RHS) const {
1050 assert(&getSemantics() == &RHS.getSemantics() &&
1051 "Should only compare APFloats with the same semantics");
1052 if (usesLayout<IEEEFloat>(Semantics: getSemantics()))
1053 return U.IEEE.compareAbsoluteValue(RHS.U.IEEE);
1054 if (usesLayout<DoubleAPFloat>(Semantics: getSemantics()))
1055 return U.Double.compareAbsoluteValue(RHS: RHS.U.Double);
1056 llvm_unreachable("Unexpected semantics");
1057 }
1058
1059public:
1060 APFloat(const fltSemantics &Semantics) : U(Semantics) {}
1061 APFloat(const fltSemantics &Semantics, StringRef S);
1062 APFloat(const fltSemantics &Semantics, integerPart I) : U(Semantics, I) {}
1063 template <typename T,
1064 typename = std::enable_if_t<std::is_floating_point<T>::value>>
1065 APFloat(const fltSemantics &Semantics, T V) = delete;
1066 // TODO: Remove this constructor. This isn't faster than the first one.
1067 APFloat(const fltSemantics &Semantics, uninitializedTag)
1068 : U(Semantics, uninitialized) {}
1069 APFloat(const fltSemantics &Semantics, const APInt &I) : U(Semantics, I) {}
1070 explicit APFloat(double d) : U(IEEEFloat(d), IEEEdouble()) {}
1071 explicit APFloat(float f) : U(IEEEFloat(f), IEEEsingle()) {}
1072 APFloat(const APFloat &RHS) = default;
1073 APFloat(APFloat &&RHS) = default;
1074
1075 ~APFloat() = default;
1076
1077 bool needsCleanup() const { APFLOAT_DISPATCH_ON_SEMANTICS(needsCleanup()); }
1078
1079 /// Factory for Positive and Negative Zero.
1080 ///
1081 /// \param Negative True iff the number should be negative.
1082 static APFloat getZero(const fltSemantics &Sem, bool Negative = false) {
1083 APFloat Val(Sem, uninitialized);
1084 Val.makeZero(Neg: Negative);
1085 return Val;
1086 }
1087
1088 /// Factory for Positive and Negative One.
1089 ///
1090 /// \param Negative True iff the number should be negative.
1091 static APFloat getOne(const fltSemantics &Sem, bool Negative = false) {
1092 APFloat Val(Sem, 1U);
1093 if (Negative)
1094 Val.changeSign();
1095 return Val;
1096 }
1097
1098 /// Factory for Positive and Negative Infinity.
1099 ///
1100 /// \param Negative True iff the number should be negative.
1101 static APFloat getInf(const fltSemantics &Sem, bool Negative = false) {
1102 APFloat Val(Sem, uninitialized);
1103 Val.makeInf(Neg: Negative);
1104 return Val;
1105 }
1106
1107 /// Factory for NaN values.
1108 ///
1109 /// \param Negative - True iff the NaN generated should be negative.
1110 /// \param payload - The unspecified fill bits for creating the NaN, 0 by
1111 /// default. The value is truncated as necessary.
1112 static APFloat getNaN(const fltSemantics &Sem, bool Negative = false,
1113 uint64_t payload = 0) {
1114 if (payload) {
1115 APInt intPayload(64, payload);
1116 return getQNaN(Sem, Negative, payload: &intPayload);
1117 } else {
1118 return getQNaN(Sem, Negative, payload: nullptr);
1119 }
1120 }
1121
1122 /// Factory for QNaN values.
1123 static APFloat getQNaN(const fltSemantics &Sem, bool Negative = false,
1124 const APInt *payload = nullptr) {
1125 APFloat Val(Sem, uninitialized);
1126 Val.makeNaN(SNaN: false, Neg: Negative, fill: payload);
1127 return Val;
1128 }
1129
1130 /// Factory for SNaN values.
1131 static APFloat getSNaN(const fltSemantics &Sem, bool Negative = false,
1132 const APInt *payload = nullptr) {
1133 APFloat Val(Sem, uninitialized);
1134 Val.makeNaN(SNaN: true, Neg: Negative, fill: payload);
1135 return Val;
1136 }
1137
1138 /// Returns the largest finite number in the given semantics.
1139 ///
1140 /// \param Negative - True iff the number should be negative
1141 static APFloat getLargest(const fltSemantics &Sem, bool Negative = false) {
1142 APFloat Val(Sem, uninitialized);
1143 Val.makeLargest(Neg: Negative);
1144 return Val;
1145 }
1146
1147 /// Returns the smallest (by magnitude) finite number in the given semantics.
1148 /// Might be denormalized, which implies a relative loss of precision.
1149 ///
1150 /// \param Negative - True iff the number should be negative
1151 static APFloat getSmallest(const fltSemantics &Sem, bool Negative = false) {
1152 APFloat Val(Sem, uninitialized);
1153 Val.makeSmallest(Neg: Negative);
1154 return Val;
1155 }
1156
1157 /// Returns the smallest (by magnitude) normalized finite number in the given
1158 /// semantics.
1159 ///
1160 /// \param Negative - True iff the number should be negative
1161 static APFloat getSmallestNormalized(const fltSemantics &Sem,
1162 bool Negative = false) {
1163 APFloat Val(Sem, uninitialized);
1164 Val.makeSmallestNormalized(Neg: Negative);
1165 return Val;
1166 }
1167
1168 /// Returns a float which is bitcasted from an all one value int.
1169 ///
1170 /// \param Semantics - type float semantics
1171 static APFloat getAllOnesValue(const fltSemantics &Semantics);
1172
1173 /// Returns true if the given semantics has actual significand.
1174 ///
1175 /// \param Sem - type float semantics
1176 static bool hasSignificand(const fltSemantics &Sem) {
1177 return &Sem != &Float8E8M0FNU();
1178 }
1179
1180 /// Used to insert APFloat objects, or objects that contain APFloat objects,
1181 /// into FoldingSets.
1182 void Profile(FoldingSetNodeID &NID) const;
1183
1184 opStatus add(const APFloat &RHS, roundingMode RM) {
1185 assert(&getSemantics() == &RHS.getSemantics() &&
1186 "Should only call on two APFloats with the same semantics");
1187 if (usesLayout<IEEEFloat>(Semantics: getSemantics()))
1188 return U.IEEE.add(RHS.U.IEEE, RM);
1189 if (usesLayout<DoubleAPFloat>(Semantics: getSemantics()))
1190 return U.Double.add(RHS: RHS.U.Double, RM);
1191 llvm_unreachable("Unexpected semantics");
1192 }
1193 opStatus subtract(const APFloat &RHS, roundingMode RM) {
1194 assert(&getSemantics() == &RHS.getSemantics() &&
1195 "Should only call on two APFloats with the same semantics");
1196 if (usesLayout<IEEEFloat>(Semantics: getSemantics()))
1197 return U.IEEE.subtract(RHS.U.IEEE, RM);
1198 if (usesLayout<DoubleAPFloat>(Semantics: getSemantics()))
1199 return U.Double.subtract(RHS: RHS.U.Double, RM);
1200 llvm_unreachable("Unexpected semantics");
1201 }
1202 opStatus multiply(const APFloat &RHS, roundingMode RM) {
1203 assert(&getSemantics() == &RHS.getSemantics() &&
1204 "Should only call on two APFloats with the same semantics");
1205 if (usesLayout<IEEEFloat>(Semantics: getSemantics()))
1206 return U.IEEE.multiply(RHS.U.IEEE, RM);
1207 if (usesLayout<DoubleAPFloat>(Semantics: getSemantics()))
1208 return U.Double.multiply(RHS: RHS.U.Double, RM);
1209 llvm_unreachable("Unexpected semantics");
1210 }
1211 opStatus divide(const APFloat &RHS, roundingMode RM) {
1212 assert(&getSemantics() == &RHS.getSemantics() &&
1213 "Should only call on two APFloats with the same semantics");
1214 if (usesLayout<IEEEFloat>(Semantics: getSemantics()))
1215 return U.IEEE.divide(RHS.U.IEEE, RM);
1216 if (usesLayout<DoubleAPFloat>(Semantics: getSemantics()))
1217 return U.Double.divide(RHS: RHS.U.Double, RM);
1218 llvm_unreachable("Unexpected semantics");
1219 }
1220 opStatus remainder(const APFloat &RHS) {
1221 assert(&getSemantics() == &RHS.getSemantics() &&
1222 "Should only call on two APFloats with the same semantics");
1223 if (usesLayout<IEEEFloat>(Semantics: getSemantics()))
1224 return U.IEEE.remainder(RHS.U.IEEE);
1225 if (usesLayout<DoubleAPFloat>(Semantics: getSemantics()))
1226 return U.Double.remainder(RHS: RHS.U.Double);
1227 llvm_unreachable("Unexpected semantics");
1228 }
1229 opStatus mod(const APFloat &RHS) {
1230 assert(&getSemantics() == &RHS.getSemantics() &&
1231 "Should only call on two APFloats with the same semantics");
1232 if (usesLayout<IEEEFloat>(Semantics: getSemantics()))
1233 return U.IEEE.mod(RHS.U.IEEE);
1234 if (usesLayout<DoubleAPFloat>(Semantics: getSemantics()))
1235 return U.Double.mod(RHS: RHS.U.Double);
1236 llvm_unreachable("Unexpected semantics");
1237 }
1238 opStatus fusedMultiplyAdd(const APFloat &Multiplicand, const APFloat &Addend,
1239 roundingMode RM) {
1240 assert(&getSemantics() == &Multiplicand.getSemantics() &&
1241 "Should only call on APFloats with the same semantics");
1242 assert(&getSemantics() == &Addend.getSemantics() &&
1243 "Should only call on APFloats with the same semantics");
1244 if (usesLayout<IEEEFloat>(Semantics: getSemantics()))
1245 return U.IEEE.fusedMultiplyAdd(Multiplicand.U.IEEE, Addend.U.IEEE, RM);
1246 if (usesLayout<DoubleAPFloat>(Semantics: getSemantics()))
1247 return U.Double.fusedMultiplyAdd(Multiplicand: Multiplicand.U.Double, Addend: Addend.U.Double,
1248 RM);
1249 llvm_unreachable("Unexpected semantics");
1250 }
1251 opStatus roundToIntegral(roundingMode RM) {
1252 APFLOAT_DISPATCH_ON_SEMANTICS(roundToIntegral(RM));
1253 }
1254
1255 // TODO: bool parameters are not readable and a source of bugs.
1256 // Do something.
1257 opStatus next(bool nextDown) {
1258 APFLOAT_DISPATCH_ON_SEMANTICS(next(nextDown));
1259 }
1260
1261 /// Negate an APFloat.
1262 APFloat operator-() const {
1263 APFloat Result(*this);
1264 Result.changeSign();
1265 return Result;
1266 }
1267
1268 /// Add two APFloats, rounding ties to the nearest even.
1269 /// No error checking.
1270 APFloat operator+(const APFloat &RHS) const {
1271 APFloat Result(*this);
1272 (void)Result.add(RHS, RM: rmNearestTiesToEven);
1273 return Result;
1274 }
1275
1276 /// Subtract two APFloats, rounding ties to the nearest even.
1277 /// No error checking.
1278 APFloat operator-(const APFloat &RHS) const {
1279 APFloat Result(*this);
1280 (void)Result.subtract(RHS, RM: rmNearestTiesToEven);
1281 return Result;
1282 }
1283
1284 /// Multiply two APFloats, rounding ties to the nearest even.
1285 /// No error checking.
1286 APFloat operator*(const APFloat &RHS) const {
1287 APFloat Result(*this);
1288 (void)Result.multiply(RHS, RM: rmNearestTiesToEven);
1289 return Result;
1290 }
1291
1292 /// Divide the first APFloat by the second, rounding ties to the nearest even.
1293 /// No error checking.
1294 APFloat operator/(const APFloat &RHS) const {
1295 APFloat Result(*this);
1296 (void)Result.divide(RHS, RM: rmNearestTiesToEven);
1297 return Result;
1298 }
1299
1300 void changeSign() { APFLOAT_DISPATCH_ON_SEMANTICS(changeSign()); }
1301 void clearSign() {
1302 if (isNegative())
1303 changeSign();
1304 }
1305 void copySign(const APFloat &RHS) {
1306 if (isNegative() != RHS.isNegative())
1307 changeSign();
1308 }
1309
1310 /// A static helper to produce a copy of an APFloat value with its sign
1311 /// copied from some other APFloat.
1312 static APFloat copySign(APFloat Value, const APFloat &Sign) {
1313 Value.copySign(RHS: Sign);
1314 return Value;
1315 }
1316
1317 /// Assuming this is an IEEE-754 NaN value, quiet its signaling bit.
1318 /// This preserves the sign and payload bits.
1319 APFloat makeQuiet() const {
1320 APFloat Result(*this);
1321 Result.getIEEE().makeQuiet();
1322 return Result;
1323 }
1324
1325 opStatus convert(const fltSemantics &ToSemantics, roundingMode RM,
1326 bool *losesInfo);
1327 opStatus convertToInteger(MutableArrayRef<integerPart> Input,
1328 unsigned int Width, bool IsSigned, roundingMode RM,
1329 bool *IsExact) const {
1330 APFLOAT_DISPATCH_ON_SEMANTICS(
1331 convertToInteger(Input, Width, IsSigned, RM, IsExact));
1332 }
1333 opStatus convertToInteger(APSInt &Result, roundingMode RM,
1334 bool *IsExact) const;
1335 opStatus convertFromAPInt(const APInt &Input, bool IsSigned,
1336 roundingMode RM) {
1337 APFLOAT_DISPATCH_ON_SEMANTICS(convertFromAPInt(Input, IsSigned, RM));
1338 }
1339 opStatus convertFromSignExtendedInteger(const integerPart *Input,
1340 unsigned int InputSize, bool IsSigned,
1341 roundingMode RM) {
1342 APFLOAT_DISPATCH_ON_SEMANTICS(
1343 convertFromSignExtendedInteger(Input, InputSize, IsSigned, RM));
1344 }
1345 opStatus convertFromZeroExtendedInteger(const integerPart *Input,
1346 unsigned int InputSize, bool IsSigned,
1347 roundingMode RM) {
1348 APFLOAT_DISPATCH_ON_SEMANTICS(
1349 convertFromZeroExtendedInteger(Input, InputSize, IsSigned, RM));
1350 }
1351 Expected<opStatus> convertFromString(StringRef, roundingMode);
1352 APInt bitcastToAPInt() const {
1353 APFLOAT_DISPATCH_ON_SEMANTICS(bitcastToAPInt());
1354 }
1355
1356 /// Converts this APFloat to host double value.
1357 ///
1358 /// \pre The APFloat must be built using semantics, that can be represented by
1359 /// the host double type without loss of precision. It can be IEEEdouble and
1360 /// shorter semantics, like IEEEsingle and others.
1361 double convertToDouble() const;
1362
1363 /// Converts this APFloat to host float value.
1364 ///
1365 /// \pre The APFloat must be built using semantics, that can be represented by
1366 /// the host float type without loss of precision. It can be IEEEquad and
1367 /// shorter semantics, like IEEEdouble and others.
1368#ifdef HAS_IEE754_FLOAT128
1369 float128 convertToQuad() const;
1370#endif
1371
1372 /// Converts this APFloat to host float value.
1373 ///
1374 /// \pre The APFloat must be built using semantics, that can be represented by
1375 /// the host float type without loss of precision. It can be IEEEsingle and
1376 /// shorter semantics, like IEEEhalf.
1377 float convertToFloat() const;
1378
1379 bool operator==(const APFloat &RHS) const { return compare(RHS) == cmpEqual; }
1380
1381 bool operator!=(const APFloat &RHS) const { return compare(RHS) != cmpEqual; }
1382
1383 bool operator<(const APFloat &RHS) const {
1384 return compare(RHS) == cmpLessThan;
1385 }
1386
1387 bool operator>(const APFloat &RHS) const {
1388 return compare(RHS) == cmpGreaterThan;
1389 }
1390
1391 bool operator<=(const APFloat &RHS) const {
1392 cmpResult Res = compare(RHS);
1393 return Res == cmpLessThan || Res == cmpEqual;
1394 }
1395
1396 bool operator>=(const APFloat &RHS) const {
1397 cmpResult Res = compare(RHS);
1398 return Res == cmpGreaterThan || Res == cmpEqual;
1399 }
1400
1401 cmpResult compare(const APFloat &RHS) const {
1402 assert(&getSemantics() == &RHS.getSemantics() &&
1403 "Should only compare APFloats with the same semantics");
1404 if (usesLayout<IEEEFloat>(Semantics: getSemantics()))
1405 return U.IEEE.compare(RHS.U.IEEE);
1406 if (usesLayout<DoubleAPFloat>(Semantics: getSemantics()))
1407 return U.Double.compare(RHS: RHS.U.Double);
1408 llvm_unreachable("Unexpected semantics");
1409 }
1410
1411 bool bitwiseIsEqual(const APFloat &RHS) const {
1412 if (&getSemantics() != &RHS.getSemantics())
1413 return false;
1414 if (usesLayout<IEEEFloat>(Semantics: getSemantics()))
1415 return U.IEEE.bitwiseIsEqual(RHS.U.IEEE);
1416 if (usesLayout<DoubleAPFloat>(Semantics: getSemantics()))
1417 return U.Double.bitwiseIsEqual(RHS: RHS.U.Double);
1418 llvm_unreachable("Unexpected semantics");
1419 }
1420
1421 /// We don't rely on operator== working on double values, as
1422 /// it returns true for things that are clearly not equal, like -0.0 and 0.0.
1423 /// As such, this method can be used to do an exact bit-for-bit comparison of
1424 /// two floating point values.
1425 ///
1426 /// We leave the version with the double argument here because it's just so
1427 /// convenient to write "2.0" and the like. Without this function we'd
1428 /// have to duplicate its logic everywhere it's called.
1429 bool isExactlyValue(double V) const {
1430 bool ignored;
1431 APFloat Tmp(V);
1432 Tmp.convert(ToSemantics: getSemantics(), RM: APFloat::rmNearestTiesToEven, losesInfo: &ignored);
1433 return bitwiseIsEqual(RHS: Tmp);
1434 }
1435
1436 unsigned int convertToHexString(char *DST, unsigned int HexDigits,
1437 bool UpperCase, roundingMode RM) const {
1438 APFLOAT_DISPATCH_ON_SEMANTICS(
1439 convertToHexString(DST, HexDigits, UpperCase, RM));
1440 }
1441
1442 bool isZero() const { return getCategory() == fcZero; }
1443 bool isInfinity() const { return getCategory() == fcInfinity; }
1444 bool isNaN() const { return getCategory() == fcNaN; }
1445
1446 bool isNegative() const { return getIEEE().isNegative(); }
1447 bool isDenormal() const { APFLOAT_DISPATCH_ON_SEMANTICS(isDenormal()); }
1448 bool isSignaling() const { return getIEEE().isSignaling(); }
1449
1450 bool isNormal() const { return !isDenormal() && isFiniteNonZero(); }
1451 bool isFinite() const { return !isNaN() && !isInfinity(); }
1452
1453 fltCategory getCategory() const { return getIEEE().getCategory(); }
1454 const fltSemantics &getSemantics() const { return *U.semantics; }
1455 bool isNonZero() const { return !isZero(); }
1456 bool isFiniteNonZero() const { return isFinite() && !isZero(); }
1457 bool isPosZero() const { return isZero() && !isNegative(); }
1458 bool isNegZero() const { return isZero() && isNegative(); }
1459 bool isPosInfinity() const { return isInfinity() && !isNegative(); }
1460 bool isNegInfinity() const { return isInfinity() && isNegative(); }
1461 bool isSmallest() const { APFLOAT_DISPATCH_ON_SEMANTICS(isSmallest()); }
1462 bool isLargest() const { APFLOAT_DISPATCH_ON_SEMANTICS(isLargest()); }
1463 bool isInteger() const { APFLOAT_DISPATCH_ON_SEMANTICS(isInteger()); }
1464 bool isIEEE() const { return usesLayout<IEEEFloat>(Semantics: getSemantics()); }
1465
1466 bool isSmallestNormalized() const {
1467 APFLOAT_DISPATCH_ON_SEMANTICS(isSmallestNormalized());
1468 }
1469
1470 /// Return the FPClassTest which will return true for the value.
1471 FPClassTest classify() const;
1472
1473 APFloat &operator=(const APFloat &RHS) = default;
1474 APFloat &operator=(APFloat &&RHS) = default;
1475
1476 void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision = 0,
1477 unsigned FormatMaxPadding = 3, bool TruncateZero = true) const {
1478 APFLOAT_DISPATCH_ON_SEMANTICS(
1479 toString(Str, FormatPrecision, FormatMaxPadding, TruncateZero));
1480 }
1481
1482 void print(raw_ostream &) const;
1483 void dump() const;
1484
1485 bool getExactInverse(APFloat *inv) const {
1486 APFLOAT_DISPATCH_ON_SEMANTICS(getExactInverse(inv));
1487 }
1488
1489 LLVM_READONLY
1490 int getExactLog2Abs() const {
1491 APFLOAT_DISPATCH_ON_SEMANTICS(getExactLog2Abs());
1492 }
1493
1494 LLVM_READONLY
1495 int getExactLog2() const {
1496 APFLOAT_DISPATCH_ON_SEMANTICS(getExactLog2());
1497 }
1498
1499 friend hash_code hash_value(const APFloat &Arg);
1500 friend int ilogb(const APFloat &Arg) { return ilogb(Arg: Arg.getIEEE()); }
1501 friend APFloat scalbn(APFloat X, int Exp, roundingMode RM);
1502 friend APFloat frexp(const APFloat &X, int &Exp, roundingMode RM);
1503 friend IEEEFloat;
1504 friend DoubleAPFloat;
1505};
1506
1507static_assert(sizeof(APFloat) == sizeof(detail::IEEEFloat),
1508 "Empty base class optimization is not performed.");
1509
1510/// See friend declarations above.
1511///
1512/// These additional declarations are required in order to compile LLVM with IBM
1513/// xlC compiler.
1514hash_code hash_value(const APFloat &Arg);
1515inline APFloat scalbn(APFloat X, int Exp, APFloat::roundingMode RM) {
1516 if (APFloat::usesLayout<detail::IEEEFloat>(Semantics: X.getSemantics()))
1517 return APFloat(scalbn(X: X.U.IEEE, Exp, RM), X.getSemantics());
1518 if (APFloat::usesLayout<detail::DoubleAPFloat>(Semantics: X.getSemantics()))
1519 return APFloat(scalbn(Arg: X.U.Double, Exp, RM), X.getSemantics());
1520 llvm_unreachable("Unexpected semantics");
1521}
1522
1523/// Equivalent of C standard library function.
1524///
1525/// While the C standard says Exp is an unspecified value for infinity and nan,
1526/// this returns INT_MAX for infinities, and INT_MIN for NaNs.
1527inline APFloat frexp(const APFloat &X, int &Exp, APFloat::roundingMode RM) {
1528 if (APFloat::usesLayout<detail::IEEEFloat>(Semantics: X.getSemantics()))
1529 return APFloat(frexp(Val: X.U.IEEE, Exp, RM), X.getSemantics());
1530 if (APFloat::usesLayout<detail::DoubleAPFloat>(Semantics: X.getSemantics()))
1531 return APFloat(frexp(X: X.U.Double, Exp, RM), X.getSemantics());
1532 llvm_unreachable("Unexpected semantics");
1533}
1534/// Returns the absolute value of the argument.
1535inline APFloat abs(APFloat X) {
1536 X.clearSign();
1537 return X;
1538}
1539
1540/// Returns the negated value of the argument.
1541inline APFloat neg(APFloat X) {
1542 X.changeSign();
1543 return X;
1544}
1545
1546/// Implements IEEE-754 2019 minimumNumber semantics. Returns the smaller of the
1547/// 2 arguments if both are not NaN. If either argument is a NaN, returns the
1548/// other argument. -0 is treated as ordered less than +0.
1549LLVM_READONLY
1550inline APFloat minnum(const APFloat &A, const APFloat &B) {
1551 if (A.isNaN())
1552 return B;
1553 if (B.isNaN())
1554 return A;
1555 if (A.isZero() && B.isZero() && (A.isNegative() != B.isNegative()))
1556 return A.isNegative() ? A : B;
1557 return B < A ? B : A;
1558}
1559
1560/// Implements IEEE-754 2019 maximumNumber semantics. Returns the larger of the
1561/// 2 arguments if both are not NaN. If either argument is a NaN, returns the
1562/// other argument. +0 is treated as ordered greater than -0.
1563LLVM_READONLY
1564inline APFloat maxnum(const APFloat &A, const APFloat &B) {
1565 if (A.isNaN())
1566 return B;
1567 if (B.isNaN())
1568 return A;
1569 if (A.isZero() && B.isZero() && (A.isNegative() != B.isNegative()))
1570 return A.isNegative() ? B : A;
1571 return A < B ? B : A;
1572}
1573
1574/// Implements IEEE 754-2019 minimum semantics. Returns the smaller of 2
1575/// arguments, returning a quiet NaN if an argument is a NaN and treating -0
1576/// as less than +0.
1577LLVM_READONLY
1578inline APFloat minimum(const APFloat &A, const APFloat &B) {
1579 if (A.isNaN())
1580 return A.makeQuiet();
1581 if (B.isNaN())
1582 return B.makeQuiet();
1583 if (A.isZero() && B.isZero() && (A.isNegative() != B.isNegative()))
1584 return A.isNegative() ? A : B;
1585 return B < A ? B : A;
1586}
1587
1588/// Implements IEEE 754-2019 minimumNumber semantics. Returns the smaller
1589/// of 2 arguments, not propagating NaNs and treating -0 as less than +0.
1590LLVM_READONLY
1591inline APFloat minimumnum(const APFloat &A, const APFloat &B) {
1592 if (A.isNaN())
1593 return B.isNaN() ? B.makeQuiet() : B;
1594 if (B.isNaN())
1595 return A;
1596 if (A.isZero() && B.isZero() && (A.isNegative() != B.isNegative()))
1597 return A.isNegative() ? A : B;
1598 return B < A ? B : A;
1599}
1600
1601/// Implements IEEE 754-2019 maximum semantics. Returns the larger of 2
1602/// arguments, returning a quiet NaN if an argument is a NaN and treating -0
1603/// as less than +0.
1604LLVM_READONLY
1605inline APFloat maximum(const APFloat &A, const APFloat &B) {
1606 if (A.isNaN())
1607 return A.makeQuiet();
1608 if (B.isNaN())
1609 return B.makeQuiet();
1610 if (A.isZero() && B.isZero() && (A.isNegative() != B.isNegative()))
1611 return A.isNegative() ? B : A;
1612 return A < B ? B : A;
1613}
1614
1615/// Implements IEEE 754-2019 maximumNumber semantics. Returns the larger
1616/// of 2 arguments, not propagating NaNs and treating -0 as less than +0.
1617LLVM_READONLY
1618inline APFloat maximumnum(const APFloat &A, const APFloat &B) {
1619 if (A.isNaN())
1620 return B.isNaN() ? B.makeQuiet() : B;
1621 if (B.isNaN())
1622 return A;
1623 if (A.isZero() && B.isZero() && (A.isNegative() != B.isNegative()))
1624 return A.isNegative() ? B : A;
1625 return A < B ? B : A;
1626}
1627
1628inline raw_ostream &operator<<(raw_ostream &OS, const APFloat &V) {
1629 V.print(OS);
1630 return OS;
1631}
1632
1633// We want the following functions to be available in the header for inlining.
1634// We cannot define them inline in the class definition of `DoubleAPFloat`
1635// because doing so would instantiate `std::unique_ptr<APFloat[]>` before
1636// `APFloat` is defined, and that would be undefined behavior.
1637namespace detail {
1638
1639DoubleAPFloat &DoubleAPFloat::operator=(DoubleAPFloat &&RHS) {
1640 if (this != &RHS) {
1641 this->~DoubleAPFloat();
1642 new (this) DoubleAPFloat(std::move(RHS));
1643 }
1644 return *this;
1645}
1646
1647APFloat &DoubleAPFloat::getFirst() { return Floats[0]; }
1648const APFloat &DoubleAPFloat::getFirst() const { return Floats[0]; }
1649APFloat &DoubleAPFloat::getSecond() { return Floats[1]; }
1650const APFloat &DoubleAPFloat::getSecond() const { return Floats[1]; }
1651
1652} // namespace detail
1653
1654} // namespace llvm
1655
1656#undef APFLOAT_DISPATCH_ON_SEMANTICS
1657#endif // LLVM_ADT_APFLOAT_H
1658

source code of include/llvm-20/llvm/ADT/APFloat.h