middle-end/105376 - invalid REAL_CST for DFP constant
Commit Message
We are eventually ICEing in decimal_to_decnumber on non-decimal
REAL_VALUE_TYPE that creep in from uses of build_real (..., dconst*)
for DFP types. The following fixes the single occurance that matters
for the testcase in the PR by instead using build_real_truncate.
Bootstrapped and tested on x86_64-unknown-linux-gnu.
OK for trunk?
Is this the correct strathegy to deal with this problem? Would
it be valid to just set ->is_decimal in build_real based on
DECIMAL_FLOAT_TYPE_P for the dconst* cases we "support" (not
checking for them but instead declaring others invalid)?
Richard.
2022-04-27 Richard Biener <rguenther@suse.de>
PR middle-end/105376
* match.pd (x + x -> 2.*x): Use build_real_truncate.
* gcc.dg/pr105376.c: New testcase.
---
gcc/match.pd | 2 +-
gcc/testsuite/gcc.dg/pr105376.c | 9 +++++++++
2 files changed, 10 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.dg/pr105376.c
Comments
On Wed, 27 Apr 2022, Richard Biener via Gcc-patches wrote:
> Is this the correct strathegy to deal with this problem? Would
> it be valid to just set ->is_decimal in build_real based on
Just setting ->decimal isn't correct; that signifies that ->sig stores the
number in decimal128 format (host-endian DPD), so it's only correct for a
REAL_VALUE_TYPE that actually is encoded in decimal128 format, not one
copied from dconst*.
I think build_real is a reasonable place to handle the dconst* special
cases, but it would need to have an explicit mapping from the binary
dconst* to corresponding constants using the decimal128 format, in the
case where the REAL_VALUE_TYPE passed in is binary but the requested type
is decimal.
@@ -3865,7 +3865,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(simplify
(plus @0 @0)
(if (SCALAR_FLOAT_TYPE_P (type))
- (mult @0 { build_real (type, dconst2); })
+ (mult @0 { build_real_truncate (type, dconst2); })
(if (INTEGRAL_TYPE_P (type))
(mult @0 { build_int_cst (type, 2); }))))
new file mode 100644
@@ -0,0 +1,9 @@
+/* { dg-do compile { target dfp } } */
+/* { dg-options "-O -g" } */
+
+void
+foo (_Decimal64 d, _Decimal64 e)
+{
+ d -= -d;
+ d *= -e;
+}