|
|
6fdc0f |
2007-04-21 Alexandre Oliva <aoliva@redhat.com>
|
|
|
6fdc0f |
|
|
|
6fdc0f |
* gcse.c (store_killed_in_insn): Handle PARALLELs.
|
|
|
6fdc0f |
(store_killed_in_pat): New.
|
|
|
6fdc0f |
|
|
|
6fdc0f |
* gcc.dg/movsi-sm-1.c: New.
|
|
|
6fdc0f |
|
|
|
6fdc0f |
--- gcc/gcse.c.jj 2007-02-23 21:29:12.000000000 +0100
|
|
|
6fdc0f |
+++ gcc/gcse.c 2007-07-18 20:41:08.000000000 +0200
|
|
|
6fdc0f |
@@ -7427,6 +7427,40 @@ find_loads (rtx x, rtx store_pattern, in
|
|
|
6fdc0f |
return ret;
|
|
|
6fdc0f |
}
|
|
|
6fdc0f |
|
|
|
6fdc0f |
+static inline bool
|
|
|
6fdc0f |
+store_killed_in_pat (rtx x, rtx pat, int after)
|
|
|
6fdc0f |
+{
|
|
|
6fdc0f |
+ if (GET_CODE (pat) == SET)
|
|
|
6fdc0f |
+ {
|
|
|
6fdc0f |
+ rtx dest = SET_DEST (pat);
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ if (GET_CODE (dest) == SIGN_EXTRACT
|
|
|
6fdc0f |
+ || GET_CODE (dest) == ZERO_EXTRACT)
|
|
|
6fdc0f |
+ dest = XEXP (dest, 0);
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ /* Check for memory stores to aliased objects. */
|
|
|
6fdc0f |
+ if (GET_CODE (dest) == MEM
|
|
|
6fdc0f |
+ && !expr_equiv_p (dest, x))
|
|
|
6fdc0f |
+ {
|
|
|
6fdc0f |
+ if (after)
|
|
|
6fdc0f |
+ {
|
|
|
6fdc0f |
+ if (output_dependence (dest, x))
|
|
|
6fdc0f |
+ return true;
|
|
|
6fdc0f |
+ }
|
|
|
6fdc0f |
+ else
|
|
|
6fdc0f |
+ {
|
|
|
6fdc0f |
+ if (output_dependence (x, dest))
|
|
|
6fdc0f |
+ return true;
|
|
|
6fdc0f |
+ }
|
|
|
6fdc0f |
+ }
|
|
|
6fdc0f |
+ }
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ if (find_loads (pat, x, after))
|
|
|
6fdc0f |
+ return true;
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ return false;
|
|
|
6fdc0f |
+}
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
/* Check if INSN kills the store pattern X (is aliased with it).
|
|
|
6fdc0f |
AFTER is true if we are checking the case when store X occurs
|
|
|
6fdc0f |
after the insn. Return true if it it does. */
|
|
|
6fdc0f |
@@ -7434,7 +7468,7 @@ find_loads (rtx x, rtx store_pattern, in
|
|
|
6fdc0f |
static bool
|
|
|
6fdc0f |
store_killed_in_insn (rtx x, rtx x_regs, rtx insn, int after)
|
|
|
6fdc0f |
{
|
|
|
6fdc0f |
- rtx reg, base, note;
|
|
|
6fdc0f |
+ rtx reg, base, note, pat;
|
|
|
6fdc0f |
|
|
|
6fdc0f |
if (!INSN_P (insn))
|
|
|
6fdc0f |
return false;
|
|
|
6fdc0f |
@@ -7461,33 +7495,20 @@ store_killed_in_insn (rtx x, rtx x_regs,
|
|
|
6fdc0f |
return false;
|
|
|
6fdc0f |
}
|
|
|
6fdc0f |
|
|
|
6fdc0f |
- if (GET_CODE (PATTERN (insn)) == SET)
|
|
|
6fdc0f |
+ pat = PATTERN (insn);
|
|
|
6fdc0f |
+ if (GET_CODE (pat) == SET)
|
|
|
6fdc0f |
{
|
|
|
6fdc0f |
- rtx pat = PATTERN (insn);
|
|
|
6fdc0f |
- rtx dest = SET_DEST (pat);
|
|
|
6fdc0f |
-
|
|
|
6fdc0f |
- if (GET_CODE (dest) == SIGN_EXTRACT
|
|
|
6fdc0f |
- || GET_CODE (dest) == ZERO_EXTRACT)
|
|
|
6fdc0f |
- dest = XEXP (dest, 0);
|
|
|
6fdc0f |
-
|
|
|
6fdc0f |
- /* Check for memory stores to aliased objects. */
|
|
|
6fdc0f |
- if (GET_CODE (dest) == MEM
|
|
|
6fdc0f |
- && !expr_equiv_p (dest, x))
|
|
|
6fdc0f |
- {
|
|
|
6fdc0f |
- if (after)
|
|
|
6fdc0f |
- {
|
|
|
6fdc0f |
- if (output_dependence (dest, x))
|
|
|
6fdc0f |
- return true;
|
|
|
6fdc0f |
- }
|
|
|
6fdc0f |
- else
|
|
|
6fdc0f |
- {
|
|
|
6fdc0f |
- if (output_dependence (x, dest))
|
|
|
6fdc0f |
- return true;
|
|
|
6fdc0f |
- }
|
|
|
6fdc0f |
- }
|
|
|
6fdc0f |
- if (find_loads (SET_SRC (pat), x, after))
|
|
|
6fdc0f |
+ if (store_killed_in_pat (x, pat, after))
|
|
|
6fdc0f |
return true;
|
|
|
6fdc0f |
}
|
|
|
6fdc0f |
+ else if (GET_CODE (pat) == PARALLEL)
|
|
|
6fdc0f |
+ {
|
|
|
6fdc0f |
+ int i;
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ for (i = 0; i < XVECLEN (pat, 0); i++)
|
|
|
6fdc0f |
+ if (store_killed_in_pat (x, XVECEXP (pat, 0, i), after))
|
|
|
6fdc0f |
+ return true;
|
|
|
6fdc0f |
+ }
|
|
|
6fdc0f |
else if (find_loads (PATTERN (insn), x, after))
|
|
|
6fdc0f |
return true;
|
|
|
6fdc0f |
|
|
|
6fdc0f |
--- gcc/testsuite/gcc.dg/movsi-sm-1.c.jj 2007-07-18 20:58:08.000000000 +0200
|
|
|
6fdc0f |
+++ gcc/testsuite/gcc.dg/movsi-sm-1.c 2007-07-18 21:01:52.000000000 +0200
|
|
|
6fdc0f |
@@ -0,0 +1,35 @@
|
|
|
6fdc0f |
+/* { dg-do run } */
|
|
|
6fdc0f |
+/* { dg-options "-O2" } */
|
|
|
6fdc0f |
+/* { dg-options "-O2 -mtune=i386" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+int ret = 1;
|
|
|
6fdc0f |
+char buf[128];
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+void
|
|
|
6fdc0f |
+__attribute__((noinline))
|
|
|
6fdc0f |
+bug (int arg)
|
|
|
6fdc0f |
+{
|
|
|
6fdc0f |
+ char str[28];
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ __builtin_memcpy (str, "Bugged!", 8);
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ if (arg & 0200)
|
|
|
6fdc0f |
+ {
|
|
|
6fdc0f |
+ __builtin_memcpy (str, "This is what we should get!", 28);
|
|
|
6fdc0f |
+ ret = 0;
|
|
|
6fdc0f |
+ }
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ if (arg & 0100)
|
|
|
6fdc0f |
+ __builtin_memcpy (str, "Broken!", 8);
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ __builtin_sprintf (buf, "%s\n", str);
|
|
|
6fdc0f |
+}
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+int
|
|
|
6fdc0f |
+main ()
|
|
|
6fdc0f |
+{
|
|
|
6fdc0f |
+ bug (0200);
|
|
|
6fdc0f |
+ if (ret)
|
|
|
6fdc0f |
+ return ret;
|
|
|
6fdc0f |
+ return __builtin_strcmp (buf, "This is what we should get!\n") != 0;
|
|
|
6fdc0f |
+}
|