* src/SDCCloop.c (loopInvariants): applied fix for bug 1717943, thanks
authorMaartenBrock <MaartenBrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 30 Mar 2008 19:38:18 +0000 (19:38 +0000)
committerMaartenBrock <MaartenBrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 30 Mar 2008 19:38:18 +0000 (19:38 +0000)
  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

ChangeLog
src/SDCCloop.c
support/regression/tests/bug1717943.c [new file with mode: 0644]

index b59e62bf6e4b36ad06ddafec3d75afb830fea348..b2fa61b3b278cd034f3236f4bf31fd773494e5ed 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,16 @@
+2008-03-30 Maarten Brock <sourceforge.brock AT dse.nl>
+
+       * 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 <pkk AT spth.de>
-       * 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 <pkk AT spth.de>
-       * 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.
 
index 07d20ecae821e0470fc3c6e40044dc187f63fc3a..6400d1a4f411f7b92dae13451ab6cf31d93bb52a 100644 (file)
@@ -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 (file)
index 0000000..af653be
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+   bug1717943c.c
+     an error in the detection of loopinvariants,
+      will move the foo=0 initialisation out of the loops.
+ */
+
+#include <testfwk.h>
+
+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);
+}