Thread view

Hi,
the bug is in file SDCCast.c function reverseLoop, I prupose the correction
below, can somebody validate and integrate this change in sdcc tree ??
C:\sdcc\src\SDCCast.c(1478): <sym> = end; */ //SUPP <sym> = end -
1; */
C:\sdcc\src\SDCCast.c(1488)://SUPP newNode('-', end,
C:\sdcc\src\SDCCast.c(1489): end));//ADD SUPP
newAst_VALUE(constVal("1")))));
Regards
BESSIERE Jerome
FROM: Scott Dattalo
DATE: 12/06/2000 21:57:37
SUBJECT: RE: [sdcc-devel] for loop bug?
On Wed, 6 Dec 2000, Karl Bongers wrote:
> Silly me, I should have tried changing it to:
> if (i < 9)
> which I did now and it does make the problem go away,
> so it is probably a < versus <= kinda problem in the compiler.
>
> The .dumpraw1 show the bit of code for "if (i < 10)"
> but the .dumpcse file does not. I think the .dumpcse stuff is the
> next optimization done. You can look at SDCCopt.c to get an idea
> of the sequence of compiler optimization passes.
> It looks like cseAllBlocks(common sub-expression ellimination)
> is called between these and is probably the culprit.
>
> Thats about as far as I go now into SDCC(some of the source code
> is greek to me).
I tracked it down some more - but I know nothing about the innards of
SDCC. Here's the bt when the EVELYN warning is printed.
#0 werror (errNum=110) at SDCCerr.c:180
#1 0x806619f in ifxOptimize (ic=0x817ddc0, cseSet=0x8173000, computeOnly=0,
ebb=0x8168a50, change=0xbff36750, ebbs=0x817eea0, count=6) at SDCCcse.c:948
#2 0x8066e4a in cseBBlock (ebb=0x8168a50, computeOnly=0, ebbs=0x817eea0,
count=6) at SDCCcse.c:1285
#3 0x8067823 in cseAllBlocks (ebbs=0x817eea0, count=6) at SDCCcse.c:1548
#4 0x8052f0d in eBBlockFromiCode (ic=0x0) at SDCCopt.c:699
#5 0x80589b9 in createFunction (name=0x8178c60, body=0x817af78) at
SDCCast.c:3658
#6 0x80497c7 in yyparse () at SDCC.y:161
#7 0x804edb0 in main (argc=4, argv=0xbffffb84, envp=0xbffffb98) at
SDCCmain.c:1398
The culprit is manifested here (in ifxOptimize)
/* if the conditional is a literal then */
if (IS_OP_LITERAL(IC_COND(ic))) {
if ( (operandLitValue(IC_COND(ic)) != 0.0) && IC_TRUE(ic)) {
/* change to a goto */
ic->op = GOTO ;
IC_LABEL(ic) = IC_TRUE(ic);
(*change)++;
} else {
if (!operandLitValue(IC_COND(ic)) && IC_FALSE(ic)) {
ic->op = GOTO ;
IC_LABEL(ic) = IC_FALSE(ic);
(*change)++;
} else {
/* then kill this if condition */
---> remiCodeFromeBBlock (ebb,ic);
}
}
/* now we need to recompute the control flow */
/* since the control flow has changed */
/* this is very expensive but it does not happen */
/* too often, if it does happen then the user pays */
/* the price */
computeControlFlow (ebbs,count,1);
werror (W_CONTROL_FLOW,ic->filename,ic->lineno);
return ;
}
Just to confim Karl's observation, I changed the code to:
void for2(void)
{
unsigned char i=0;
for(i=0; i<10; i++)
achar0++;
if(i == 9)
failures++;
}
And sure enough, the code will increment `failures'. Changing the 9 to anything
else will not increment failures. So clearly the compiler believes that i is
equal to 9 upon exiting the for loop.
Scott
PS.
Just to check my sanity (or verify as the case may be) I wrote this simple test
program:
#include <stdio.h>
int main(void)
{
int i,j=0;
for(i=0; i<10; i++) {
j++;
printf("j=%d\n");
}
printf("i=%d\n",i);
return 0;
}
Which will print:
j=1
j=2
j=3
j=4
j=5
j=6
j=7
j=8
j=9
j=10
i=10
So according to my beliefs and gcc, i is 10 and not 9.