This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: PR middle-end/43671: [4.4/4.5/4.6 Regression] -fsched2-use-superblocks -m32 produces wrong code with vectorization
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 2 May 2010 15:20:22 -0700
- Subject: PATCH: PR middle-end/43671: [4.4/4.5/4.6 Regression] -fsched2-use-superblocks -m32 produces wrong code with vectorization
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
Hi,
When several optimizations are turned on at the same time, get_addr
may return an address containing VALUE as shown in the testcase. This
patch changes get_addr not to return an address containing VALUE. OK
for trunk, 4.4 and 4.5?
Thanks.
H.J.
----
gcc/
2010-05-02 H.J. Lu <hongjiu.lu@intel.com>
PR middle-end/43671
* alias.c (value_address_p): New.
(get_addr): Use it.
gcc/testsuite/
2010-05-02 H.J. Lu <hongjiu.lu@intel.com>
PR middle-end/43671
* gcc.target/i386/pr43671.c: New.
diff --git a/gcc/alias.c b/gcc/alias.c
index baf0a62..45d7f6f 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -1693,6 +1693,40 @@ base_alias_check (rtx x, rtx y, enum machine_mode x_mode,
return 1;
}
+/* Return TRUE if X refers to a memory location whose address contains
+ VALUE rtx. */
+
+static bool
+value_address_p (const_rtx x)
+{
+ enum rtx_code code;
+ int i, j;
+ const char *fmt;
+
+ if (x == NULL_RTX)
+ return false;
+
+ code = GET_CODE (x);
+ if (code == VALUE)
+ return true;
+
+ fmt = GET_RTX_FORMAT (code);
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ if (fmt[i] == 'e')
+ {
+ if (value_address_p (XEXP (x, i)))
+ return true;
+ }
+ else if (fmt[i] == 'E')
+ {
+ for (j = 0; j < XVECLEN (x, i); j++)
+ if (value_address_p (XVECEXP (x, i, j)))
+ return true;
+ }
+
+ return false;
+}
+
/* Convert the address X into something we can use. This is done by returning
it unchanged unless it is a value; in the latter case we call cselib to get
a more useful rtx. */
@@ -1713,7 +1747,11 @@ get_addr (rtx x)
return l->loc;
for (l = v->locs; l; l = l->next)
if (!REG_P (l->loc) && !MEM_P (l->loc))
- return l->loc;
+ {
+ /* Don't return an expression with VALUE. */
+ if (!value_address_p (l->loc))
+ return l->loc;
+ }
if (v->locs)
return v->locs->loc;
}
--- /dev/null 2010-04-26 09:25:52.584800265 -0700
+++ gcc/gcc/testsuite/gcc.target/i386/pr43671.c 2010-05-02 15:11:28.000000000 -0700
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-mtune=i686 -O1 -fpeel-loops -fschedule-insns2 -ftree-vectorize -fsched2-use-superblocks" } */
+
+extern void abort ();
+
+int main ()
+{
+ struct {
+ char ca[16];
+ } s;
+ int i;
+
+ for (i = 0; i < 16; i++)
+ {
+ s.ca[i] = 5;
+ }
+
+
+ for (i = 0; i < 16; i++)
+ {
+ if (s.ca[i] != 5)
+ abort ();
+ }
+
+ return 0;
+}