Hi!

As the following testcase shows, we store decimal REAL_CSTs always in
_Decimal128 internal form and perform all the arithmetics on that, but while
for arithmetics we then ensure rounding to the actual type (_Decimal{32,64}
or for _Decimal128 no further rounding), e.g. const_binop calls
      inexact = real_arithmetic (&value, code, &d1, &d2);
      real_convert (&result, mode, &value);
when converting integers to _Decimal{32,64} we do nothing like that.
We do that only for non-decimal conversions from INTEGER_CSTs to REAL_CSTs.

The following patch fixes that.  Bootstrapped/regtested on x86_64-linux
(i686-linux fails to bootstrap for other reason), and on 6.x branch on
x86_64-linux and i686-linux.  Dominik has kindly tested it on s390x (where
the bug has been originally reported on the float-cast-overflow-10.c test).

Ok for trunk?

2017-02-15  Jakub Jelinek  <ja...@redhat.com>

        PR target/79487
        * real.c (real_from_integer): Call real_convert even for decimal.

        * gcc.dg/dfp/pr79487.c: New test.
        * c-c++-common/ubsan/float-cast-overflow-8.c (TEST): Revert
        2017-02-13 change.

--- gcc/real.c.jj       2017-01-01 12:45:37.000000000 +0100
+++ gcc/real.c  2017-02-14 21:35:35.868906203 +0100
@@ -2266,7 +2266,7 @@ real_from_integer (REAL_VALUE_TYPE *r, f
 
   if (fmt.decimal_p ())
     decimal_from_integer (r);
-  else if (fmt)
+  if (fmt)
     real_convert (r, fmt, r);
 }
 
--- gcc/testsuite/gcc.dg/dfp/pr79487.c.jj       2017-02-14 22:42:33.137938789 
+0100
+++ gcc/testsuite/gcc.dg/dfp/pr79487.c  2017-02-14 22:42:22.000000000 +0100
@@ -0,0 +1,16 @@
+/* PR target/79487 */
+/* { dg-options "-O2" } */
+
+int
+main ()
+{
+  _Decimal32 a = (-9223372036854775807LL - 1LL); 
+  _Decimal32 b = -9.223372E+18DF;
+  if (b - a != 0.0DF)
+    __builtin_abort ();
+  _Decimal64 c = (-9223372036854775807LL - 1LL); 
+  _Decimal64 d = -9.223372036854776E+18DD;
+  if (d - c != 0.0DD)
+    __builtin_abort ();
+  return 0;
+}
--- gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-8.c.jj 2017-02-14 
00:08:33.000000000 +0100
+++ gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-8.c    2017-02-15 
07:46:46.780778627 +0100
@@ -8,7 +8,7 @@
 #define TEST(type1, type2) \
   if (type1##_MIN)                                             \
     {                                                          \
-      volatile type2 min = type1##_MIN;                                \
+      type2 min = type1##_MIN;                                 \
       type2 add = -1.0;                                                \
       while (1)                                                        \
        {                                                       \
@@ -28,7 +28,7 @@
       volatile type1 tem3 = cvt_##type1##_##type2 (-1.0f);     \
     }                                                          \
   {                                                            \
-    volatile type2 max = type1##_MAX;                          \
+    type2 max = type1##_MAX;                                   \
     type2 add = 1.0;                                           \
     while (1)                                                  \
       {                                                                \

        Jakub

Reply via email to