This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: gcc optimizer bug in 2.95.2
- To: Bob Peterson <bob at acdstar dot com>
- Subject: Re: gcc optimizer bug in 2.95.2
- From: Bernd Schmidt <bernds at redhat dot co dot uk>
- Date: Fri, 27 Oct 2000 15:19:41 +0100 (BST)
- cc: gcc-bugs at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org, Franz dot Sirl-kernel at lauterbach dot com
On Thu, 26 Oct 2000, Bob Peterson wrote:
> I don't know if this optimizer bug has been reported already, but here goes.
> The following extremely simple C program below will produce incorrect
> output when compiled with -O2. The output is correct if compiled with -O.
> I'm running Redhat 6.2, with GCC 2.95.2.
It appears this was fixed in current CVS by the patch below. Another candidate
for backporting to the 2.95 branch.
Bernd
2000-09-01 Jim Wilson <wilson@cygnus.com>
* loop.c (check_final_value): Check for biv use before checking for
giv use. Check for both biv and giv uses. Always set last_giv_use
if there is a giv use.
Index: loop.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/loop.c,v
retrieving revision 1.277
retrieving revision 1.278
diff -u -p -r1.277 -r1.278
--- loop.c 2000/08/29 19:15:26 1.277
+++ loop.c 2000/09/01 22:01:43 1.278
@@ -5677,19 +5677,25 @@ check_final_value (loop, v)
if (GET_CODE (p) == INSN || GET_CODE (p) == JUMP_INSN
|| GET_CODE (p) == CALL_INSN)
{
- if (biv_increment_seen)
+ /* It is possible for the BIV increment to use the GIV if we
+ have a cycle. Thus we must be sure to check each insn for
+ both BIV and GIV uses, and we must check for BIV uses
+ first. */
+
+ if (! biv_increment_seen
+ && reg_set_p (v->src_reg, PATTERN (p)))
+ biv_increment_seen = 1;
+
+ if (reg_mentioned_p (v->dest_reg, PATTERN (p)))
{
- if (reg_mentioned_p (v->dest_reg, PATTERN (p)))
+ if (biv_increment_seen)
{
v->replaceable = 0;
v->not_replaceable = 1;
break;
}
+ last_giv_use = p;
}
- else if (reg_set_p (v->src_reg, PATTERN (p)))
- biv_increment_seen = 1;
- else if (reg_mentioned_p (v->dest_reg, PATTERN (p)))
- last_giv_use = p;
}
}
> ----------------------------------------------------------------------------
> /* program gronk2 */
> #include <stdio.h>
> #include <stdlib.h>
> #include <errno.h>
> #include <errno.h>
> #include <fcntl.h>
> #include <string.h>
> #include <ctype.h>
> #include <unistd.h>
>
> int main()
> {
> char upc1[15],upc2[15];
> int i;
>
> memset(upc1,0,sizeof(upc1));
> memset(upc2,0,sizeof(upc2));
> strcpy(upc1,"0074646561225");
> for (i=0; i<12; i++) {
> upc2[i]=upc1[i+1];
> }
> upc2[i]='\0';
> printf("upc1=%s upc2=%s i=%d\n",upc1,upc2,i);
> }
> ----------------------------------------------------------------------------
> When it is compiled with -O2 it produces this bad output:
> upc1=0074646561225 upc2=07464656122 i=12
>
> When it is compiled with -O it produces the correct output:
> upc1=0074646561225 upc2=074646561225 i=12