This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix i386 delegitimize_address hook (PR debug/43972)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Uros Bizjak <ubizjak at gmail dot com>, Richard Henderson <rth at redhat dot com>, Richard Guenther <rguenther at suse dot de>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Mon, 3 May 2010 17:14:18 +0200
- Subject: [PATCH] Fix i386 delegitimize_address hook (PR debug/43972)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
var-tracking ICEs on the attached testcase. The problem is that
during adjust_insns in var-tracking targetm.delegitimize_address
returns for
(mem/u/c:QI (const:DI (unspec:DI [
(symbol_ref:DI ("f1") [flags 0x41] <function_decl 0x7ffff1705a00 f1>)
] 2)) [9 S1 A8])
returns (symbol_ref:DI ("f1") rather than expected
(subreg:QI (symbol_ref:DI ("f1") 0), thus the modes don't match and
var-tracking checking fails on that.
Of course the above has been originally (mem/u/c:DI (...)), but then
as the code is interested just in low 8 bits of that it was subregged
and mem subregs are simplified into a mem read.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux.
Ok for trunk and 4.5?
I've checked rs6000 and that target doesn't have this problem.
2010-05-03 Jakub Jelinek <jakub@redhat.com>
PR debug/43972
* config/i386/i386.c (ix86_delegitimize_address): Make sure the
result mode matches original rtl mode.
* gcc.dg/debug/pr43972.c: New test.
--- gcc/config/i386/i386.c.jj 2010-04-30 11:14:54.000000000 +0200
+++ gcc/config/i386/i386.c 2010-05-03 13:19:03.000000000 +0200
@@ -11013,7 +11013,10 @@ ix86_delegitimize_address (rtx x)
|| XINT (XEXP (x, 0), 1) != UNSPEC_GOTPCREL
|| !MEM_P (orig_x))
return orig_x;
- return XVECEXP (XEXP (x, 0), 0, 0);
+ x = XVECEXP (XEXP (x, 0), 0, 0);
+ if (GET_MODE (orig_x) != Pmode)
+ return simplify_gen_subreg (GET_MODE (orig_x), x, Pmode, 0);
+ return x;
}
if (GET_CODE (x) != PLUS
@@ -11080,6 +11083,8 @@ ix86_delegitimize_address (rtx x)
else
return orig_x;
}
+ if (GET_MODE (orig_x) != Pmode && MEM_P (orig_x))
+ return simplify_gen_subreg (GET_MODE (orig_x), result, Pmode, 0);
return result;
}
--- gcc/testsuite/gcc.dg/debug/pr43972.c.jj 2010-05-03 13:32:34.000000000 +0200
+++ gcc/testsuite/gcc.dg/debug/pr43972.c 2010-05-03 13:32:49.000000000 +0200
@@ -0,0 +1,29 @@
+/* PR debug/43972 */
+/* { dg-do compile } */
+/* { dg-options "-g -w" } */
+/* { dg-options "-g -fpic -w" { target fpic } } */
+
+struct { int *b1; } *f1 ();
+short v1[1];
+struct S { int b2; };
+void
+foo (struct S *a1, union { char *b3; unsigned *b4; int *b5; } *a2)
+{
+ int d;
+ switch (d)
+ {
+ case 0:
+ {
+ int c = a1->b2, i;
+ if (f1 () == 0)
+ *a2->b3++ = 2;
+ else if (((long) (f1 () - f1 ())) ^ ((long) f1 ()->b1 - ((long) f1 () & 8)))
+ *a2->b3++ = (long) f1 - ((long) f1 () & 0xff);
+ else
+ *a2->b4++ = (long) f1;
+ for (i = 0; i < c; i++)
+ *a2->b5++ = (long) v1;
+ foo (a1, a2);
+ }
+ }
+}
Jakub