From ff166363f049bd9cc57358cff2d5537470718b20 Mon Sep 17 00:00:00 2001 From: uz Date: Sun, 28 Oct 2012 19:04:09 +0000 Subject: [PATCH] OptCmp3 removed a compare to zero instruction preceeded by a load despite the fact that the carry flag (which is set by the compare but not by the load) had been used later. git-svn-id: svn://svn.cc65.org/cc65/trunk@5885 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/coptcmp.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/cc65/coptcmp.c b/src/cc65/coptcmp.c index b99c1a69a..25e1a8982 100644 --- a/src/cc65/coptcmp.c +++ b/src/cc65/coptcmp.c @@ -432,8 +432,8 @@ unsigned OptCmp3 (CodeSeg* S) int Delete = 0; /* Check for the call to boolxx. We only remove the compare if - * the carry flag is evaluated later, because the load will not - * set the carry flag. + * the carry flag is not evaluated later, because the load will + * not set the carry flag. */ if (L[2]->OPC == OP65_JSR) { switch (FindBoolCmpCond (L[2]->Arg)) { @@ -458,12 +458,29 @@ unsigned OptCmp3 (CodeSeg* S) } } else if ((L[2]->Info & OF_FBRA) != 0) { - - /* The following insn branches on the condition of a load, so - * the compare instruction can be removed. + /* The following insn branches on the condition of the load, + * so the compare instruction might be removed. For safety, + * do some more checks if the carry isn't used later, since + * the compare does set the carry, but the load does not. */ - Delete = 1; - + CodeEntry* E; + CodeEntry* N; + if ((E = CS_GetNextEntry (S, I+2)) != 0 && + L[2]->JumpTo != 0 && + (N = L[2]->JumpTo->Owner) != 0 && + N->OPC != OP65_BCC && + N->OPC != OP65_BCS && + N->OPC != OP65_JCC && + N->OPC != OP65_JCS && + (N->OPC != OP65_JSR || + FindBoolCmpCond (N->Arg) == CMP_INV)) { + + /* The following insn branches on the condition of a load, + * and there's no use of the carry flag in sight, so the + * compare instruction can be removed. + */ + Delete = 1; + } } /* Delete the compare if we can */ -- 2.39.5