@@ -4575,6 +4575,35 @@ void IEEEFloat::toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision,
45754575
45764576}
45774577
4578+ bool  IEEEFloat::getExactInverse (APFloat *inv) const  {
4579+   //  Special floats and denormals have no exact inverse.
4580+   if  (!isFiniteNonZero ())
4581+     return  false ;
4582+ 
4583+   //  Check that the number is a power of two by making sure that only the
4584+   //  integer bit is set in the significand.
4585+   if  (significandLSB () != semantics->precision  - 1 )
4586+     return  false ;
4587+ 
4588+   //  Get the inverse.
4589+   IEEEFloat reciprocal (*semantics, 1ULL );
4590+   if  (reciprocal.divide (*this , rmNearestTiesToEven) != opOK)
4591+     return  false ;
4592+ 
4593+   //  Avoid multiplication with a denormal, it is not safe on all platforms and
4594+   //  may be slower than a normal division.
4595+   if  (reciprocal.isDenormal ())
4596+     return  false ;
4597+ 
4598+   assert (reciprocal.isFiniteNonZero () &&
4599+          reciprocal.significandLSB () == reciprocal.semantics ->precision  - 1 );
4600+ 
4601+   if  (inv)
4602+     *inv = APFloat (reciprocal, *semantics);
4603+ 
4604+   return  true ;
4605+ }
4606+ 
45784607int  IEEEFloat::getExactLog2Abs () const  {
45794608  if  (!isFinite () || isZero ())
45804609    return  INT_MIN;
@@ -5702,6 +5731,17 @@ void DoubleAPFloat::toString(SmallVectorImpl<char> &Str,
57025731      .toString (Str, FormatPrecision, FormatMaxPadding, TruncateZero);
57035732}
57045733
5734+ bool  DoubleAPFloat::getExactInverse (APFloat *inv) const  {
5735+   assert (Semantics == &semPPCDoubleDouble && " Unexpected Semantics"  );
5736+   APFloat Tmp (semPPCDoubleDoubleLegacy, bitcastToAPInt ());
5737+   if  (!inv)
5738+     return  Tmp.getExactInverse (nullptr );
5739+   APFloat Inv (semPPCDoubleDoubleLegacy);
5740+   auto  Ret = Tmp.getExactInverse (&Inv);
5741+   *inv = APFloat (semPPCDoubleDouble, Inv.bitcastToAPInt ());
5742+   return  Ret;
5743+ }
5744+ 
57055745int  DoubleAPFloat::getExactLog2Abs () const  {
57065746  //  In order for Hi + Lo to be a power of two, the following must be true:
57075747  //  1. Hi must be a power of two.
@@ -5886,58 +5926,6 @@ FPClassTest APFloat::classify() const {
58865926  return  isSignaling () ? fcSNan : fcQNan;
58875927}
58885928
5889- bool  APFloat::getExactInverse (APFloat *Inv) const  {
5890-   //  Only finite, non-zero numbers can have a useful, representable inverse.
5891-   //  This check filters out +/- zero, +/- infinity, and NaN.
5892-   if  (!isFiniteNonZero ())
5893-     return  false ;
5894- 
5895-   //  A number has an exact, representable inverse if and only if it is a power
5896-   //  of two.
5897-   // 
5898-   //  Mathematical Rationale:
5899-   //  1. A binary floating-point number x is a dyadic rational, meaning it can
5900-   //     be written as x = M / 2^k for integers M (the significand) and k.
5901-   //  2. The inverse is 1/x = 2^k / M.
5902-   //  3. For 1/x to also be a dyadic rational (and thus exactly representable
5903-   //     in binary), its denominator M must also be a power of two.
5904-   //     Let's say M = 2^m.
5905-   //  4. Substituting this back into the formula for x, we get
5906-   //     x = (2^m) / (2^k) = 2^(m-k).
5907-   // 
5908-   //  This proves that x must be a power of two.
5909- 
5910-   //  getExactLog2Abs() returns the integer exponent if the number is a power of
5911-   //  two or INT_MIN if it is not.
5912-   const  int  Exp = getExactLog2Abs ();
5913-   if  (Exp == INT_MIN)
5914-     return  false ;
5915- 
5916-   //  The inverse of +/- 2^Exp is +/- 2^(-Exp). We can compute this by
5917-   //  scaling 1.0 by the negated exponent.
5918-   APFloat Reciprocal =
5919-       scalbn (APFloat::getOne (getSemantics (), /* Negative=*/ isNegative ()), -Exp,
5920-              rmTowardZero);
5921- 
5922-   //  scalbn might round if the resulting exponent -Exp is outside the
5923-   //  representable range, causing overflow (to infinity) or underflow. We
5924-   //  must verify that the result is still the exact power of two we expect.
5925-   if  (Reciprocal.getExactLog2Abs () != -Exp)
5926-     return  false ;
5927- 
5928-   //  Avoid multiplication with a subnormal, it is not safe on all platforms and
5929-   //  may be slower than a normal division.
5930-   if  (Reciprocal.isDenormal ())
5931-     return  false ;
5932- 
5933-   assert (Reciprocal.isFiniteNonZero ());
5934- 
5935-   if  (Inv)
5936-     *Inv = std::move (Reciprocal);
5937- 
5938-   return  true ;
5939- }
5940- 
59415929APFloat::opStatus APFloat::convert (const  fltSemantics &ToSemantics,
59425930                                   roundingMode RM, bool  *losesInfo) {
59435931  if  (&getSemantics () == &ToSemantics) {
0 commit comments