This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Bug target/20126] [3.3/3.4/4.0 Regression] Inlined memcmp makes one argument null on entry
- From: Jakub Jelinek <jakub at redhat dot com>
- To: mark at codesourcery dot com, aoliva at redhat dot com, roger at eyesopen dot com
- Cc: gcc-patches at gcc dot gnu dot org, gcc-bugzilla at gcc dot gnu dot org
- Date: Wed, 13 Apr 2005 05:45:01 -0400
- Subject: Re: [Bug target/20126] [3.3/3.4/4.0 Regression] Inlined memcmp makes one argument null on entry
- References: <20050221214433.20126.jkohen@users.sourceforge.net> <20050412175458.14371.qmail@sourceware.org>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Tue, Apr 12, 2005 at 05:54:58PM -0000, mmitchel at gcc dot gnu dot org wrote:
>
> ------- Additional Comments From mmitchel at gcc dot gnu dot org 2005-04-12 17:54 -------
> I like the simpler approach. If someone would test that for 4.0, I'd be ecstatic.
Here is what I have bootstrapped/regtested on
{i386,x86_64,ia64,ppc,ppc64,s390,s390x}-linux.
2005-04-13 Alexandre Oliva <aoliva@redhat.com>
Roger Sayle <roger@eyesopen.com>
PR target/20126
* loop.c (loop_givs_rescan): If replacement of DEST_ADDR failed,
set the original address pseudo to the correct value before the
original insn, if possible, and leave the insn alone, otherwise
create a new pseudo, set it and replace it in the insn.
* recog.c (validate_change_maybe_volatile): New.
* recog.h (validate_change_maybe_volatile): Declare.
* gcc.dg/pr20126.c: New.
--- gcc/loop.c.jj 2005-04-03 10:33:24.000000000 +0200
+++ gcc/loop.c 2005-04-12 23:22:06.000000000 +0200
@@ -5478,9 +5478,20 @@ loop_givs_rescan (struct loop *loop, str
mark_reg_pointer (v->new_reg, 0);
if (v->giv_type == DEST_ADDR)
- /* Store reduced reg as the address in the memref where we found
- this giv. */
- validate_change (v->insn, v->location, v->new_reg, 0);
+ {
+ /* Store reduced reg as the address in the memref where we found
+ this giv. */
+ if (!validate_change (v->insn, v->location, v->new_reg, 0))
+ {
+ if (loop_dump_stream)
+ fprintf (loop_dump_stream,
+ "unable to reduce iv to register in insn %d\n",
+ INSN_UID (v->insn));
+ bl->all_reduced = 0;
+ v->ignore = 1;
+ continue;
+ }
+ }
else if (v->replaceable)
{
reg_map[REGNO (v->dest_reg)] = v->new_reg;
--- gcc/testsuite/gcc.dg/pr20126.c 1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/gcc.dg/pr20126.c 10 Mar 2005 11:24:16 -0000
@@ -0,0 +1,50 @@
+/* dg-do run */
+/* dg-options "-O2" */
+
+/* PR target/20126 was not really target-specific, but rather a loop's
+ failure to take into account the possibility that a DEST_ADDR giv
+ replacement might fail, such as when you attempt to replace a REG
+ with a PLUS in one of the register_operands of cmpstrqi_rex_1. */
+
+extern void abort (void);
+
+typedef struct { int a; char b[3]; } S;
+S c = { 2, "aa" }, d = { 2, "aa" };
+
+void *
+bar (const void *x, int y, int z)
+{
+ return (void *) 0;
+}
+
+int
+foo (S *x, S *y)
+{
+ const char *e, *f, *g;
+ int h;
+
+ h = y->a;
+ f = y->b;
+ e = x->b;
+
+ if (h == 1)
+ return bar (e, *f, x->a) != 0;
+
+ g = e + x->a - h;
+ while (e <= g)
+ {
+ const char *t = e + 1;
+ if (__builtin_memcmp (e, f, h) == 0)
+ return 1;
+ e = t;
+ }
+ return 0;
+}
+
+int
+main (void)
+{
+ if (foo (&c, &d) != 1)
+ abort ();
+ return 0;
+}
Jakub