Missed optimization gcc version 4.0.0 20041205 (experimental) 4.0.0/cc1.exe -quiet -v looprv.c -quiet -dumpbase looprv.c -mmcu=atmega169 -auxbase looprv -Os -Wall -version -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -o looprv.s Down counting loop, uses expensive compare EQ (-n) instead of compare >=0. Testcase as follows: volatile char value6; extern void foo6(char); void testloop6(void) { int i; for (i=100;i>= 0;i-=10) { if (!value6) { foo6(i); } } Loop test in RTL is compare NE -10. It should be compare GE 0 - which is(generally) free. First dump of Expanded RTL show the compare.
Hmm, on most targets it is true that != is the same case as >=.
(In reply to comment #1) > Hmm, on most targets it is true that != is the same case as >=. s/case/cost/.
Subject: Re: Poor optimisation of loop test I am not sure what makes you think that. Compare with ZERO is invariabley cheaper than compare with "n". The former is "free" sign status following any conditioning setting instruction - like subtract! Its even the sign bit of the result! subi r28,10 cpi r28, -10 brpl looptop subi r28,10 brpl looptop or did I miss something? pinskia at gcc dot gnu dot org wrote: >------- Additional Comments From pinskia at gcc dot gnu dot org 2005-01-30 03:17 ------- >Hmm, on most targets it is true that != is the same case as >=. > > >
Confirmed (sorry about that I was thinking of something different at the time). Here is a better example for normal targets (PPC and x86 too): extern void foo6(int); void testloop6 (void) { int i; i = 100; do { foo6 ( i); i-=10; } while (i != 0); } The tree dump for the loop on x86: <L0>:; foo6 (i); D.1592 = (unsigned int) i + 0fffffff6; i = (int) D.1592; if (D.1592 != 0) goto <L0>; else goto <L1>; Note this is not IV-OPTS messing up but DOM changing the if statement.
Even though DOM is the problem, IV-OPTS can be improved so we don't create the casts in the first place, patch here to do that: <http://gcc.gnu.org/ml/gcc-patches/2005-01/msg02209.html>. I will try get a testcase where DOM messes up even without IV-OPTs doing anything. And here is that testcase, yes it is werid for someone to do this but ...: extern void foo6(int); void testloop6 (void) { unsigned int D1133; int i; i = 100; do { foo6 (i); i = ((unsigned int) i) + 4294967286U; }while (i != 0); }
Lowering the priority as IV-OPTs has worked around DOM's problems.
This has been fixed on the mainline now.
Since this is only a missed optimization, closing as fixed for 4.1.0.