From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5728 invoked by alias); 19 Nov 2002 16:16:07 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 5682 invoked by uid 71); 19 Nov 2002 16:16:04 -0000 Date: Tue, 26 Nov 2002 06:56:00 -0000 Message-ID: <20021119161604.5677.qmail@sources.redhat.com> To: nobody@gcc.gnu.org Cc: gcc-prs@gcc.gnu.org, From: "Christian Ehrhardt" Subject: Re: c/8639: simple integer arithmetic expression broken Reply-To: "Christian Ehrhardt" X-SW-Source: 2002-11/txt/msg00974.txt.bz2 List-Id: The following reply was made to PR c/8639; it has been noted by GNATS. From: "Christian Ehrhardt" To: steveJepsen@netscape.net Cc: gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org Subject: Re: c/8639: simple integer arithmetic expression broken Date: Tue, 19 Nov 2002 17:10:33 +0100 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