[ADT] Fix Incorrect rounding for APFixedPoint::getIntPart
authorTyker <tyker1@outlook.com>
Mon, 10 Oct 2022 08:35:47 +0000 (10:35 +0200)
committerTyker <tyker1@outlook.com>
Fri, 14 Oct 2022 18:01:20 +0000 (11:01 -0700)
llvm/include/llvm/ADT/APFixedPoint.h
llvm/unittests/ADT/APFixedPointTest.cpp

index e151089..0b72fcc 100644 (file)
@@ -214,7 +214,7 @@ public:
     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());
   }
 
index 0b85db5..3a19763 100644 (file)
@@ -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) {