This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
incorrect simplifications for fixed-point rtl expressions
- From: "Stefan M. Freudenberger" <stefan at reservoir dot com>
- To: <gcc-bugs at gcc dot gnu dot org>
- Date: Wed, 1 Apr 2009 18:38:28 +0200
- Subject: incorrect simplifications for fixed-point rtl expressions
Hello,
I am working with the current distribution of gcc 4.3.3.
The following two transformations are unsafe for (signed) fixed-point
numbers. In both cases, a NEG operation is moved to the input of the MULT
(say, A). However, if A is -1.0, then NEG A overflows, and the MULT yields
the wrong result. Note that if the result of (-1.0 * B) is between -1.0 and
+1.0 than the NEG doesn't overflow (1st case); otherwise, it would be a user
error (undefined overflow behavior).
I didn't find this bug mentioned in the archives. If it has been reported
before, please accept my apologies for sending a duplicate report.
Best regards,
Stefan Freudenberger
PS. I don't subscribe to gcc-bugs: please include me in replies. Thank you.
$ LC_ALL=C TZ=UTC0 diff -Naur gcc-4.3.3-{ORIG,smf}/gcc/simplify-rtx.c
--- gcc-4.3.3-ORIG/gcc/simplify-rtx.c 2008-05-09 17:13:30.000000000 +0000
+++ gcc-4.3.3-smf/gcc/simplify-rtx.c 2009-03-27 09:52:38.712334115 +0000
@@ -542,7 +542,8 @@
/* (neg (mult A B)) becomes (mult (neg A) B).
This works even for floating-point values. */
if (GET_CODE (op) == MULT
- && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
+ && !HONOR_SIGN_DEPENDENT_ROUNDING (mode)
+ && !SIGNED_FIXED_POINT_MODE_P (mode))
{
temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
return simplify_gen_binary (MULT, mode, temp, XEXP (op, 1));
@@ -1933,6 +1934,7 @@
/* Canonicalize (minus (neg A) (mult B C)) to
(minus (mult (neg B) C) A). */
if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
+ && !SIGNED_FIXED_POINT_MODE_P (mode)
&& GET_CODE (op1) == MULT
&& GET_CODE (op0) == NEG)
{
$