On February 15, 2017 7:53:58 AM GMT+01:00, Jakub Jelinek <ja...@redhat.com> wrote: >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?
OK. Richard. >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