PR target/37382
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 11 Sep 2008 07:33:23 +0000 (07:33 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 11 Sep 2008 07:33:23 +0000 (07:33 +0000)
* expmed.c (extract_low_bits): Avoid creating invalid subregs.
* dse.c (find_shift_sequence): Use extract_low_bits instead of
simplify_gen_subreg.

* gcc.c-torture/compile/pr37382.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@140265 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/dse.c
gcc/expmed.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr37382.c [new file with mode: 0644]

index 3be4d03..5cf27d0 100644 (file)
@@ -1,3 +1,10 @@
+2008-09-11  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/37382
+       * expmed.c (extract_low_bits): Avoid creating invalid subregs.
+       * dse.c (find_shift_sequence): Use extract_low_bits instead of
+       simplify_gen_subreg.
+
 2008-09-11  Ira Rosen  <irar@il.ibm.com>
 
        * tree-vect-transform.c (vectorizable_store): Use the rhs vector type
index 7283bbe..0a3ebb4 100644 (file)
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -1445,7 +1445,7 @@ find_shift_sequence (int access_size,
        new_mode = GET_MODE_WIDER_MODE (new_mode))
     {
       rtx target, new_reg, shift_seq, insn, new_lhs;
-      int cost, offset;
+      int cost;
 
       /* Try a wider mode if truncating the store mode to NEW_MODE
         requires a real instruction.  */
@@ -1459,11 +1459,6 @@ find_shift_sequence (int access_size,
       if (!CONSTANT_P (store_info->rhs)
          && !MODES_TIEABLE_P (new_mode, store_mode))
        continue;
-      offset = subreg_lowpart_offset (new_mode, store_mode);
-      new_lhs = simplify_gen_subreg (new_mode, copy_rtx (store_info->rhs),
-                                    store_mode, offset);
-      if (new_lhs == NULL_RTX)
-       continue;
 
       new_reg = gen_reg_rtx (new_mode);
 
@@ -1496,6 +1491,11 @@ find_shift_sequence (int access_size,
       if (cost > COSTS_N_INSNS (1))
        continue;
 
+      new_lhs = extract_low_bits (new_mode, store_mode,
+                                 copy_rtx (store_info->rhs));
+      if (new_lhs == NULL_RTX)
+       continue;
+
       /* We found an acceptable shift.  Generate a move to
         take the value from the store and put it into the
         shift pseudo, then shift it, then generate another
index 0daf7fa..6099c4b 100644 (file)
@@ -1991,8 +1991,22 @@ extract_low_bits (enum machine_mode mode, enum machine_mode src_mode, rtx src)
     return src;
 
   if (CONSTANT_P (src))
-    return simplify_gen_subreg (mode, src, src_mode,
-                               subreg_lowpart_offset (mode, src_mode));
+    {
+      /* simplify_gen_subreg can't be used here, as if simplify_subreg
+        fails, it will happily create (subreg (symbol_ref)) or similar
+        invalid SUBREGs.  */
+      unsigned int byte = subreg_lowpart_offset (mode, src_mode);
+      rtx ret = simplify_subreg (mode, src, src_mode, byte);
+      if (ret)
+       return ret;
+
+      if (GET_MODE (src) == VOIDmode
+         || !validate_subreg (mode, src_mode, src, byte))
+       return NULL_RTX;
+
+      src = force_reg (GET_MODE (src), src);
+      return gen_rtx_SUBREG (mode, src, byte);
+    }
 
   if (GET_MODE_CLASS (mode) == MODE_CC || GET_MODE_CLASS (src_mode) == MODE_CC)
     return NULL_RTX;
index b42b5df..1d3dc0a 100644 (file)
@@ -1,3 +1,8 @@
+2008-09-11  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/37382
+       * gcc.c-torture/compile/pr37382.c: New test.
+
 2008-09-11  Daniel Kraft  <d@domob.eu>
 
        PR fortran/36214
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37382.c b/gcc/testsuite/gcc.c-torture/compile/pr37382.c
new file mode 100644 (file)
index 0000000..47525bc
--- /dev/null
@@ -0,0 +1,16 @@
+/* PR target/37382 */
+
+void baz (char *);
+int c;
+
+void
+bar (void)
+{
+  char a[2];
+  int *ip = &c;
+  char *p = a, *q = (char *) &ip;
+  const char *r = q + 2;
+  for (; q != r; p++, q++)
+    *p = *q;
+  baz (a);
+}