@@ -326,6 +326,8 @@ std::optional<bool> ConstantFPRange::getSignBit() const {
326326}
327327
328328bool ConstantFPRange::operator ==(const ConstantFPRange &CR) const {
329+ assert (&getSemantics () == &CR.getSemantics () &&
330+ " Should only use the same semantics" );
329331 if (MayBeSNaN != CR.MayBeSNaN || MayBeQNaN != CR.MayBeQNaN )
330332 return false ;
331333 return Lower.bitwiseIsEqual (CR.Lower ) && Upper.bitwiseIsEqual (CR.Upper );
@@ -426,17 +428,50 @@ ConstantFPRange ConstantFPRange::getWithoutInf() const {
426428 MayBeSNaN);
427429}
428430
429- ConstantFPRange ConstantFPRange::cast (const fltSemantics &DstSem) const {
431+ ConstantFPRange ConstantFPRange::abs () const {
432+ if (isNaNOnly ())
433+ return *this ;
434+ // Check if the range is all non-negative or all non-positive.
435+ if (Lower.isNegative () == Upper.isNegative ()) {
436+ if (Lower.isNegative ())
437+ return negate ();
438+ return *this ;
439+ }
440+ // The range contains both positive and negative values.
441+ APFloat NewLower = APFloat::getZero (getSemantics ());
442+ APFloat NewUpper = maxnum (-Lower, Upper);
443+ return ConstantFPRange (std::move (NewLower), std::move (NewUpper), MayBeQNaN,
444+ MayBeSNaN);
445+ }
446+
447+ ConstantFPRange ConstantFPRange::negate () const {
448+ return ConstantFPRange (-Upper, -Lower, MayBeQNaN, MayBeSNaN);
449+ }
450+
451+ ConstantFPRange ConstantFPRange::getWithoutInf () const {
452+ if (isNaNOnly ())
453+ return *this ;
454+ APFloat NewLower = Lower;
455+ APFloat NewUpper = Upper;
456+ if (Lower.isNegInfinity ())
457+ NewLower = APFloat::getLargest (getSemantics (), /* Negative=*/ true );
458+ if (Upper.isPosInfinity ())
459+ NewUpper = APFloat::getLargest (getSemantics (), /* Negative=*/ false );
460+ canonicalizeRange (NewLower, NewUpper);
461+ return ConstantFPRange (std::move (NewLower), std::move (NewUpper), MayBeQNaN,
462+ MayBeSNaN);
463+ }
464+
465+ ConstantFPRange ConstantFPRange::cast (const fltSemantics &DstSem,
466+ APFloat::roundingMode RM) const {
430467 bool LosesInfo;
431468 APFloat NewLower = Lower;
432469 APFloat NewUpper = Upper;
433470 // For conservative, return full range if conversion is invalid.
434- if (NewLower.convert (DstSem, APFloat::rmNearestTiesToEven, &LosesInfo) ==
435- APFloat::opInvalidOp ||
471+ if (NewLower.convert (DstSem, RM, &LosesInfo) == APFloat::opInvalidOp ||
436472 NewLower.isNaN ())
437473 return getFull (DstSem);
438- if (NewUpper.convert (DstSem, APFloat::rmNearestTiesToEven, &LosesInfo) ==
439- APFloat::opInvalidOp ||
474+ if (NewUpper.convert (DstSem, RM, &LosesInfo) == APFloat::opInvalidOp ||
440475 NewUpper.isNaN ())
441476 return getFull (DstSem);
442477 return ConstantFPRange (std::move (NewLower), std::move (NewUpper),
0 commit comments