Path: meolyon!mwhh!news.Hanse.DE!news.rrz.uni-hamburg.de!news.dkrz.de!news.tu-harburg.de!news.dfn.de!Germany.EU.net!howland.reston.ans.net!tank.news.pipex.net!pipex!news.mathworks.com!newshost.marcam.com!usc!math.ohio-state.edu!magnus.acs.ohio-state.edu!cis.ohio-state.edu!meolyon.hanse.DE!amylaar From: amylaar@meolyon.hanse.DE (Joern Rennecke) Newsgroups: gnu.gcc.bug Subject: strength reduce fix (Was: Serious math bug with -O2 compiles) Date: 7 Sep 1995 06:41:37 -0400 Organization: GNUs Not Usenet Lines: 102 Sender: daemon@cis.ohio-state.edu Approved: bug-gcc@prep.ai.mit.edu Distribution: gnu Message-ID: <m0sqcnA-000D3sC@meolyon> ~Newsgroups: gnu.gcc.bug Path: amylaar ~From: amylaar@meolyon.hanse.de (Joern Rennecke) ~Subject: strength reduce fix (Was: Serious math bug with -O2 compiles) Distribution: gnu Organization: Private site running Linux Message-ID: <1995Sep7.085837.1720@meolyon.hanse.de> ~References: <425612$9ri@iii2.iii.net> ~Date: Thu, 7 Sep 1995 08:58:37 GMT craigs@iii.net (Craig Shrimpton) writes: >Greetings, >I have been informed of a possible serious compile bug when using -O2 >optimization. The program will produce two different results depending >on how the -O2 optimization is invoked. >Compile first as so: gcc -O2 -o test test.c >and then as: gcc -O2 -fno-strength-reduce -o test test.c >The first compile does not produce the expected result. I have tried >this with -O and it compiles correctly. The bug seems to be related to >-O2 without -fno-strength-reduce. The errors this could produce for >engineering, math, statistic and financial applications is mind-boggling. >If this is already known, please let me know if a patch exists. I'm >running gcc 2.7.0 and libc-5.0.9 >Cheers, >Craig >------------------------ Try Me ----------------------------- >#include <stdio.h> >int A[3]; >unsigned int B = 3; >void printit(void) >{ >int i; >for(i = 0; i < B; i++) >fprintf(stdout, "A[%d] = %d\n", i, A[i]); >} >int main() >{ >int i; >for(i = 0; i < B; i++) >A[i] = i - 3; >printit(); >return 0; >} There have also been different reports of the same bug, and it can also be shown for pure unsigned and and for pure signed comparisons. The fix is simply to disable an invalid optimization (diff appended) . I think the basic problem is that C lacks subrange types with which the programmer can give direct hint what data to expect where. Any attempt to implement optimizations in a C compiler that rely on having only a subrange in certain data is bound to introduce a bug. I know that pascal and Modula-II have these, but they are messy in different ways for low-level programming. Are there any attempts to extend C in this direction? It would also be nice to be able to supply *likely* values for data values, iteration counts and conditional branch taken frequencies. Joern Rennecke *** gcc-2.7.0/loop.c Thu Sep 7 10:35:36 1995 --- gcc-2.7.0-x/loop.c Thu Sep 7 10:32:38 1995 *************** maybe_eliminate_biv_1 (x, insn, bl, elim *** 6130,6135 **** --- 6130,6140 ---- { if (invariant_p (arg) == 1) { + #if 0 /* Linear transformations of the compared values + are incorrect unless it can be verified that + overflow behaviour stays the same for all possible + values of the loop bound, for all iterations. */ + /* Look for giv with constant positive mult_val and nonconst add_val. Insert insns to compute new compare value. */ *************** maybe_eliminate_biv_1 (x, insn, bl, elim *** 6156,6161 **** --- 6161,6167 ---- if (apply_change_group ()) return 1; } + #endif } /* This code has problems. Basically, you can't know when