From: MaartenBrock Date: Sun, 30 Mar 2008 19:38:18 +0000 (+0000) Subject: * src/SDCCloop.c (loopInvariants): applied fix for bug 1717943, thanks X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=b17bba4e10285e6cf6b34dfd5677710b2ba70822;p=fw%2Fsdcc * src/SDCCloop.c (loopInvariants): applied fix for bug 1717943, thanks Robert Larice * support/regression/tests/bug1717943.c: new, added git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@5129 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index b59e62bf..b2fa61b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,16 @@ +2008-03-30 Maarten Brock + + * src/SDCCloop.c (loopInvariants): applied fix for bug 1717943, thanks + Robert Larice + * support/regression/tests/bug1717943.c: new, added + 2008-03-30 Philipp Klaus Krause - * src/z80/gen.c (assignResultValue): - Reverted reversal of order of bytewise return value assignments introduced in last commit. + * src/z80/gen.c (assignResultValue): Reverted reversal of order of bytewise + return value assignments introduced in last commit. 2008-03-30 Philipp Klaus Krause - * src/z80/gen.c (emitDebug, assignResultValue, genPlus, genMinus, genMult, genJumpTab): + * src/z80/gen.c (emitDebug, assignResultValue, genPlus, genMinus, genMult, + genJumpTab): Use 16-bit instructions for addition in some additional cases, implemented RFEs #1914251, #1914245, #1922090, #1921382, #1918323. diff --git a/src/SDCCloop.c b/src/SDCCloop.c index 07d20eca..6400d1a4 100644 --- a/src/SDCCloop.c +++ b/src/SDCCloop.c @@ -459,11 +459,13 @@ loopInvariants (region * theLoop, ebbIndex * ebbi) elementsInSet (theLoop->exits)); /* find out if we have a function call in this block */ - for (ic = lBlock->sch, fCallsInBlock=0; ic; ic = ic->next) { - if (SKIP_IC(ic)) { - fCallsInBlock++; + for (ic = lBlock->sch, fCallsInBlock=0; ic; ic = ic->next) + { + if (SKIP_IC(ic)) + { + fCallsInBlock++; + } } - } /* now we go thru the instructions of this block and */ /* collect those instructions with invariant operands */ @@ -477,18 +479,27 @@ loopInvariants (region * theLoop, ebbIndex * ebbi) here and the definition, but I am too lazy to do that now */ /* if there are function calls in this block */ - if (fCallsInBlock) { + if (fCallsInBlock) + { + /* if this is a pointer get */ + if (POINTER_GET(ic)) + { + continue; + } - /* if this is a pointer get */ - if (POINTER_GET(ic)) { - continue; - } + /* if this is an assignment from a global */ + if (ic->op=='=' && isOperandGlobal(IC_RIGHT(ic))) + { + continue; + } - /* if this is an assignment from a global */ - if (ic->op=='=' && isOperandGlobal(IC_RIGHT(ic))) { - continue; + /* Bug 1717943, + * if this is an assignment to a global */ + if (ic->op=='=' && isOperandGlobal(IC_RESULT(ic))) + { + continue; + } } - } if (SKIP_IC (ic) || POINTER_SET (ic) || ic->op == IFX) continue; @@ -518,18 +529,22 @@ loopInvariants (region * theLoop, ebbIndex * ebbi) if (ic->op == ADDRESS_OF && IS_SYMOP (IC_LEFT (ic)) && IS_AGGREGATE (operandType (IC_LEFT (ic)))) - lin++; - else { - /* check if left operand is an invariant */ - if ((lin = isOperandInvariant (IC_LEFT (ic), theLoop, lInvars))) - /* if this is a pointer get then make sure - that the pointer set does not exist in - any of the blocks */ - if (POINTER_GET (ic) && - (applyToSet (theLoop->regBlocks, - pointerAssigned, IC_LEFT (ic)))) - lin = 0; - } + { + lin++; + } + else + { + /* check if left operand is an invariant */ + if ((lin = isOperandInvariant (IC_LEFT (ic), theLoop, lInvars)) && + /* if this is a pointer get then make sure + that the pointer set does not exist in + any of the blocks */ + POINTER_GET (ic) && + applyToSet (theLoop->regBlocks, pointerAssigned, IC_LEFT (ic))) + { + lin = 0; + } + } /* do the same for right */ rin = isOperandInvariant (IC_RIGHT (ic), theLoop, lInvars); diff --git a/support/regression/tests/bug1717943.c b/support/regression/tests/bug1717943.c new file mode 100644 index 00000000..af653be0 --- /dev/null +++ b/support/regression/tests/bug1717943.c @@ -0,0 +1,38 @@ +/* + bug1717943c.c + an error in the detection of loopinvariants, + will move the foo=0 initialisation out of the loops. + */ + +#include + +char foo, firstcall; + +char check(void) +{ + if(!firstcall) + return 1; + + firstcall=0; + foo = 42; + return 0; +} + +void bug(void) +{ + while(1) { + foo = 0; + while(check()) + if(check()) + return; + } +} + + +void +testBug(void) +{ + firstcall = 1; + bug(); + ASSERT(foo == 0); +}