diff --git a/llvm/include/llvm/ADT/APFixedPoint.h b/llvm/include/llvm/ADT/APFixedPoint.h index e151089b75bbf0..0b72fcc76e1212 100644 --- a/llvm/include/llvm/ADT/APFixedPoint.h +++ b/llvm/include/llvm/ADT/APFixedPoint.h @@ -214,7 +214,7 @@ class APFixedPoint { APSInt ExtVal = (getLsbWeight() > 0) ? Val.extend(getWidth() + getLsbWeight()) : Val; if (Val < 0 && Val != -Val) // Cover the case when we have the min val - return -(-ExtVal.relativeShl(getLsbWeight())); + return -((-ExtVal).relativeShl(getLsbWeight())); return ExtVal.relativeShl(getLsbWeight()); } diff --git a/llvm/unittests/ADT/APFixedPointTest.cpp b/llvm/unittests/ADT/APFixedPointTest.cpp index 0b85db531f7399..3a197639f2ea01 100644 --- a/llvm/unittests/ADT/APFixedPointTest.cpp +++ b/llvm/unittests/ADT/APFixedPointTest.cpp @@ -276,6 +276,11 @@ void CheckIntPartMax(const FixedPointSemantics &Sema, uint64_t Expected) { APSInt::getUnsigned(Expected)) == 0); } +void CheckIntPartRes(const FixedPointSemantics &Sema, int64_t Representation, int64_t Result) { + APFixedPoint Val(Representation, Sema); + ASSERT_EQ(Val.getIntPart().getZExtValue(), Result) ; +} + TEST(FixedPoint, getIntPart) { // Normal values CheckIntPart(getSAccumSema(), 2); @@ -359,6 +364,12 @@ TEST(FixedPoint, getIntPart) { CheckIntPartMax(getPadUSFractSema(), 0); CheckIntPartMax(getPadUFractSema(), 0); CheckIntPartMax(getPadULFractSema(), 0); + + // Rounded Towards Zero + CheckIntPartRes(getSFractSema(), -127, 0); + CheckIntPartRes(getFractSema(), -32767, 0); + CheckIntPartRes(getLFractSema(), -2147483647, 0); + CheckIntPartRes(getS16Neg18(), -32768, 0); } TEST(FixedPoint, compare) {