This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: c/8639: simple integer arithmetic expression broken
- From: "Christian Ehrhardt" <ehrhardt at mathematik dot uni-ulm dot de>
- To: steveJepsen at netscape dot net
- Cc: gcc-bugs at gcc dot gnu dot org, gcc-gnats at gcc dot gnu dot org
- Date: Tue, 19 Nov 2002 17:10:33 +0100
- Subject: Re: c/8639: simple integer arithmetic expression broken
- References: <20021119144214.13378.qmail@sources.redhat.com>
On Tue, Nov 19, 2002 at 02:42:14PM -0000, steveJepsen@netscape.net wrote:
> >Number: 8639
> >Category: c
> >Synopsis: simple integer arithmetic expression broken
This is:
a) real
b) present in 3.2, 3.2.1 and 3.3
c) present at least in C and C++
d) A regression from 2.95.2
d) arch independant (!)
e) A show stopper (IMHO)
Someone please mark this as confirmed, priority high. It should probably
also be reclassified as middle end.
> >Confidential: no
> >Severity: critical
> >Priority: medium
> >Responsible: unassigned
> >State: open
> >Class: wrong-code
> >Submitter-Id: net
> >Arrival-Date: Tue Nov 19 06:46:02 PST 2002
> >Closed-Date:
> >Last-Modified:
> >Originator: Steve Jepsen
> >Release: unknown-1.0
> >Organization:
> >Environment:
> gcc version 3.2 20020903 (Red Hat Linux 8.0 3.2-7)
> >Description:
> the expression:
>
> bug_result = (80 - 4 * intvar) / 20;
>
> with intvar == 1 returns 4 (should return 3)
I did a few experiments with expression of the form (A-B*intvar)/C with
A, B and C beeing constant. In these expressions the Bug only seems to
happen if C divides A and B divides C. According to the assembler output
this is rewritten as A/C - intvar/(C/B) which is NOT the same.
A/C - (intvar-1+C/B)/(C/B) would be the same as far as I can see.
A minimal example is this:
int main ()
{
int x = 1;
int res = (80 - 4*x)/20;
return res;
}
Compiled with gcc t.c this gives:
elbereth$ gcc -Wall t.c
elbereth$ a.out
elbereth$ echo $?
4
elbereth$
Here's the asm output on sparc which shows that the expression
is rewritten as (20 - x/5).
main:
!#PROLOGUE# 0
save %sp, -120, %sp
!#PROLOGUE# 1
mov 1, %o0
st %o0, [%fp-20]
ld [%fp-20], %o0
sll %o0, 2, %o1
mov 81, %o0
sub %o0, %o1, %o0
mov 20, %o1
call .div, 0
nop
st %o0, [%fp-24]
ld [%fp-24], %o0
mov %o0, %i0
nop
ret
restore
regards Christian