c/593: invalid signed multiplication/division optimization
gustav@virtutech.se
gustav@virtutech.se
Tue Oct 3 05:26:00 GMT 2000
>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:
More information about the Gcc-bugs
mailing list