This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
c/593: invalid signed multiplication/division optimization
- To: gcc-gnats at gcc dot gnu dot org
- Subject: c/593: invalid signed multiplication/division optimization
- From: gustav at virtutech dot se
- Date: 3 Oct 2000 12:20:01 -0000
- Cc: mattias at virtutech dot se
- Reply-To: gustav at virtutech dot se
- Resent-Cc: gcc-prs at gcc dot gnu dot org, gcc-bugs at gcc dot gnu dot org, mattias at virtutech dot se
- Resent-Reply-To: gcc-gnats@gcc.gnu.org, gustav@virtutech.se
>Number: 593
>Category: c
>Synopsis: invalid signed multiplication/division optimization
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: wrong-code
>Submitter-Id: net
>Arrival-Date: Tue Oct 03 05:26:01 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator: gustav@virtutech.se
>Release: gcc version 2.96 20000921 (experimental)
>Organization:
>Environment:
Linux hal.hq.vtech 2.2.14-6.1.1smp #1 SMP Thu Apr 13 19:55:55 EDT 2000 i686 unknown
>Description:
There's some really strange optimizations with a
multiplication (that may cause overflow) and a following
division on signed integers.
The compiler doesn't check if a multiplication followed
by a division causes overflow, and ignores the fact that
some bits should be cleared/set.
Example: x = (x << 16) / (1 << 16) is treated as a nop
(but I really think it should sign extend the low
(bits-in-x - 16) bits of x. In fact, if you split the
expression into two statements (x <<= 16; x /= 1 << 16;)
the (in my eyes) "correct" operation is done.
I guess this could be percieved as an ok optimization, but
it's very weird that it behaves differently if you split
an expression into two lines, and it's very strange that
it behaves differently for signed and unsigned.
I've tested it on different gcc versions and the behaviour
seems to be somedwhat different...
>How-To-Repeat:
#include <stdio.h>
#define M (1 << 22)
int main(int argc, char **argv)
{
int x = 0xc001babe, y;
x = (x * M) / M;
y = x * M;
y /= M;
printf("x = %#x y = %#x\n", x, y);
return 0;
}
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted: