[PATCH] D84835: [APFloat] Fix incorrect fptrunc rouning when from semantics exp lower than minimal exp of target semantics

Kirill via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 29 04:04:57 PDT 2020


kpolushin created this revision.
kpolushin added reviewers: chandlerc, uweigand, lattner, rriddle, stuij.
kpolushin added a project: LLVM.
Herald added subscribers: llvm-commits, hiraditya.
kpolushin requested review of this revision.

Incorrect calculation of the exponentChange in the case when the exponent
of the original semantics is lower than the minimum exponent of the target semantics,
led to an incorrect shift and an incorrect value of the lost fraction.

For example:

  fptrunc double 0x10000001 to float

Round to the minimum positive float 0x36A0000000000000 (denorm),
although in the case of rounding to the nearest, this should have reduced to 0.
Since the lost fraction was calculated incorrectly, the function IEEEFloat::roundAwayFromZero,
called from IEEEFloat::normalize returned true (ignoring differences in changed exponent semantics),
which resulted in rounding up.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84835

Files:
  llvm/lib/Support/APFloat.cpp
  llvm/test/Transforms/InstCombine/fpcast.ll


Index: llvm/test/Transforms/InstCombine/fpcast.ll
===================================================================
--- llvm/test/Transforms/InstCombine/fpcast.ll
+++ llvm/test/Transforms/InstCombine/fpcast.ll
@@ -156,3 +156,55 @@
   ret half %t2
 }
 
+define float @fptrunc_double_to_float_rounding_to_zero0() {
+; CHECK-LABEL: @fptrunc_double_to_float_rounding_to_zero0(
+; CHECK-NEXT:    ret float 0.000000e+00
+;
+  %trunc = fptrunc double 0x10000001 to float
+  ret float %trunc
+}
+
+define float @fptrunc_double_to_float_rounding_to_zero1() {
+; CHECK-LABEL: @fptrunc_double_to_float_rounding_to_zero1(
+; CHECK-NEXT:    ret float 0.000000e+00
+;
+  %trunc = fptrunc double 0x11111111 to float
+  ret float %trunc
+}
+
+define float @fptrunc_double_to_float_rounding_to_zero2() {
+; CHECK-LABEL: @fptrunc_double_to_float_rounding_to_zero2(
+; CHECK-NEXT:    ret float 0.000000e+00
+;
+  %trunc = fptrunc double 0x10000000 to float
+  ret float %trunc
+}
+
+define float @fptrunc_double_to_float_rounding_lower() {
+; CHECK-LABEL: @fptrunc_double_to_float_rounding_lower(
+; CHECK-NEXT:    ret float 0.000000e+00
+;
+  %den_f = bitcast i32 1 to float
+  %den_d = fpext float %den_f to double
+  %div = fdiv double %den_d, 2.0
+  %bits = bitcast double %div to i64
+  %add = add i64 %bits, 0
+  %cast = bitcast i64 %add to double
+  %trunc = fptrunc double %cast to float
+  ret float %trunc
+}
+
+define float @fptrunc_double_to_float_rounding_upper() {
+; CHECK-LABEL: @fptrunc_double_to_float_rounding_upper(
+; CHECK-NEXT:    ret float 0x36A0000000000000
+;
+  %den_f = bitcast i32 1 to float
+  %den_d = fpext float %den_f to double
+  %div = fdiv double %den_d, 2.0
+  %bits = bitcast double %div to i64
+  %add = add i64 %bits, 1
+  %cast = bitcast i64 %add to double
+  %trunc = fptrunc double %cast to float
+  ret float %trunc
+}
+
Index: llvm/lib/Support/APFloat.cpp
===================================================================
--- llvm/lib/Support/APFloat.cpp
+++ llvm/lib/Support/APFloat.cpp
@@ -2191,7 +2191,7 @@
   if (shift < 0 && isFiniteNonZero()) {
     int exponentChange = significandMSB() + 1 - fromSemantics.precision;
     if (exponent + exponentChange < toSemantics.minExponent)
-      exponentChange = toSemantics.minExponent - exponent;
+      exponentChange = exponent - toSemantics.minExponent;
     if (exponentChange < shift)
       exponentChange = shift;
     if (exponentChange < 0) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D84835.281487.patch
Type: text/x-patch
Size: 2433 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200729/72f570b3/attachment.bin>


More information about the llvm-commits mailing list