]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/23985 (Memory aliasing information incorrect in inlined memcpy)
authorRichard Earnshaw <rearnsha@arm.com>
Sat, 1 Oct 2005 13:31:38 +0000 (13:31 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Sat, 1 Oct 2005 13:31:38 +0000 (13:31 +0000)
PR target/23985
Back-port 2004-08-19  Richard Henderson  <rth@redhat.com>
* config/arm/arm.c (arm_gen_load_multiple): Use
adjust_automodify_address.  Take base memory and offset instead
of unchanging/struct/scalar bits.
(arm_gen_store_multiple): Likewise.
(arm_gen_movstrqi): Use adjust_automodify_address.
* config/arm/arm-protos.h: Update decls.
* config/arm/arm.md (load_multiple): Update arm_gen_load_multiple call.
(store_multiple): Similarly.

From-SVN: r104857

gcc/ChangeLog
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.c
gcc/config/arm/arm.md

index 7a1c22049963db91cfe4e64d70442563c698bd57..50a1af09847d9279b29148be3b284bf4d9cf7c34 100644 (file)
@@ -1,3 +1,16 @@
+2005-10-01  Richard Earnshaw  <richard.earnshaw@arm.com>
+
+       PR target/23985
+       Back-port 2004-08-19  Richard Henderson  <rth@redhat.com>
+       * config/arm/arm.c (arm_gen_load_multiple): Use
+       adjust_automodify_address.  Take base memory and offset instead
+       of unchanging/struct/scalar bits.
+       (arm_gen_store_multiple): Likewise.
+       (arm_gen_movstrqi): Use adjust_automodify_address.
+       * config/arm/arm-protos.h: Update decls.
+       * config/arm/arm.md (load_multiple): Update arm_gen_load_multiple call.
+       (store_multiple): Similarly.
+
 2005-09-29  Alan Modra  <amodra@bigpond.net.au>
 
        PR target/24102
index 2da99b82d6777799e1c786cd9218173889b63c85..0b28e74ea4f5dfc60adff55768b92977dcc8f42b 100644 (file)
@@ -105,8 +105,10 @@ extern int load_multiple_sequence (rtx *, int, int *, int *, HOST_WIDE_INT *);
 extern const char *emit_ldm_seq (rtx *, int);
 extern int store_multiple_sequence (rtx *, int, int *, int *, HOST_WIDE_INT *);
 extern const char * emit_stm_seq (rtx *, int);
-extern rtx arm_gen_load_multiple (int, int, rtx, int, int, int, int, int);
-extern rtx arm_gen_store_multiple (int, int, rtx, int, int, int, int, int);
+extern rtx arm_gen_load_multiple (int, int, rtx, int, int,
+                                 rtx, HOST_WIDE_INT *);
+extern rtx arm_gen_store_multiple (int, int, rtx, int, int,
+                                  rtx, HOST_WIDE_INT *);
 extern int arm_gen_movstrqi (rtx *);
 extern rtx arm_gen_rotated_half_load (rtx);
 extern enum machine_mode arm_select_cc_mode (RTX_CODE, rtx, rtx);
index 95188944be3d2a60eae70dfd6632b1fdc9eca60a..2f0eaedbe13e6826137d4935dcf26e82672a60e5 100644 (file)
@@ -5158,13 +5158,13 @@ multi_register_push (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
 
 rtx
 arm_gen_load_multiple (int base_regno, int count, rtx from, int up,
-                      int write_back, int unchanging_p, int in_struct_p,
-                      int scalar_p)
+                      int write_back, rtx basemem, HOST_WIDE_INT *offsetp)
 {
+  HOST_WIDE_INT offset = *offsetp;
   int i = 0, j;
   rtx result;
   int sign = up ? 1 : -1;
-  rtx mem;
+  rtx mem, addr;
 
   /* XScale has load-store double instructions, but they have stricter
      alignment requirements than load-store multiple, so we can not
@@ -5202,15 +5202,17 @@ arm_gen_load_multiple (int base_regno, int count, rtx from, int up,
       
       for (i = 0; i < count; i++)
        {
-         mem = gen_rtx_MEM (SImode, plus_constant (from, i * 4 * sign));
-         RTX_UNCHANGING_P (mem) = unchanging_p;
-         MEM_IN_STRUCT_P (mem) = in_struct_p;
-         MEM_SCALAR_P (mem) = scalar_p;
+         addr = plus_constant (from, i * 4 * sign);
+         mem = adjust_automodify_address (basemem, SImode, addr, offset);
          emit_move_insn (gen_rtx_REG (SImode, base_regno + i), mem);
+         offset += 4 * sign;
        }
 
       if (write_back)
-       emit_move_insn (from, plus_constant (from, count * 4 * sign));
+       {
+         emit_move_insn (from, plus_constant (from, count * 4 * sign));
+         *offsetp = offset;
+       }
 
       seq = get_insns ();
       end_sequence ();
@@ -5231,26 +5233,28 @@ arm_gen_load_multiple (int base_regno, int count, rtx from, int up,
 
   for (j = 0; i < count; i++, j++)
     {
-      mem = gen_rtx_MEM (SImode, plus_constant (from, j * 4 * sign));
-      RTX_UNCHANGING_P (mem) = unchanging_p;
-      MEM_IN_STRUCT_P (mem) = in_struct_p;
-      MEM_SCALAR_P (mem) = scalar_p;
+      addr = plus_constant (from, j * 4 * sign);
+      mem = adjust_automodify_address_nv (basemem, SImode, addr, offset);
       XVECEXP (result, 0, i)
        = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, base_regno + j), mem);
+      offset += 4 * sign;
     }
 
+  if (write_back)
+    *offsetp = offset;
+
   return result;
 }
 
 rtx
 arm_gen_store_multiple (int base_regno, int count, rtx to, int up,
-                       int write_back, int unchanging_p, int in_struct_p,
-                       int scalar_p)
+                       int write_back, rtx basemem, HOST_WIDE_INT *offsetp)
 {
+  HOST_WIDE_INT offset = *offsetp;
   int i = 0, j;
   rtx result;
   int sign = up ? 1 : -1;
-  rtx mem;
+  rtx mem, addr;
 
   /* See arm_gen_load_multiple for discussion of
      the pros/cons of ldm/stm usage for XScale.  */
@@ -5262,15 +5266,17 @@ arm_gen_store_multiple (int base_regno, int count, rtx to, int up,
       
       for (i = 0; i < count; i++)
        {
-         mem = gen_rtx_MEM (SImode, plus_constant (to, i * 4 * sign));
-         RTX_UNCHANGING_P (mem) = unchanging_p;
-         MEM_IN_STRUCT_P (mem) = in_struct_p;
-         MEM_SCALAR_P (mem) = scalar_p;
+         addr = plus_constant (to, i * 4 * sign);
+         mem = adjust_automodify_address (basemem, SImode, addr, offset);
          emit_move_insn (mem, gen_rtx_REG (SImode, base_regno + i));
+         offset += 4 * sign;
        }
 
       if (write_back)
-       emit_move_insn (to, plus_constant (to, count * 4 * sign));
+       {
+         emit_move_insn (to, plus_constant (to, count * 4 * sign));
+         *offsetp = offset;
+       }
 
       seq = get_insns ();
       end_sequence ();
@@ -5291,15 +5297,16 @@ arm_gen_store_multiple (int base_regno, int count, rtx to, int up,
 
   for (j = 0; i < count; i++, j++)
     {
-      mem = gen_rtx_MEM (SImode, plus_constant (to, j * 4 * sign));
-      RTX_UNCHANGING_P (mem) = unchanging_p;
-      MEM_IN_STRUCT_P (mem) = in_struct_p;
-      MEM_SCALAR_P (mem) = scalar_p;
-
+      addr = plus_constant (to, j * 4 * sign);
+      mem = adjust_automodify_address_nv (basemem, SImode, addr, offset);
       XVECEXP (result, 0, i)
        = gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (SImode, base_regno + j));
+      offset += 4 * sign;
     }
 
+  if (write_back)
+    *offsetp = offset;
+
   return result;
 }
 
@@ -5307,13 +5314,11 @@ int
 arm_gen_movstrqi (rtx *operands)
 {
   HOST_WIDE_INT in_words_to_go, out_words_to_go, last_bytes;
+  HOST_WIDE_INT srcoffset, dstoffset;
   int i;
-  rtx src, dst;
-  rtx st_src, st_dst, fin_src, fin_dst;
+  rtx src, dst, srcbase, dstbase;
   rtx part_bytes_reg = NULL;
   rtx mem;
-  int dst_unchanging_p, dst_in_struct_p, src_unchanging_p, src_in_struct_p;
-  int dst_scalar_p, src_scalar_p;
 
   if (GET_CODE (operands[2]) != CONST_INT
       || GET_CODE (operands[3]) != CONST_INT
@@ -5321,23 +5326,17 @@ arm_gen_movstrqi (rtx *operands)
       || INTVAL (operands[3]) & 3)
     return 0;
 
-  st_dst = XEXP (operands[0], 0);
-  st_src = XEXP (operands[1], 0);
-
-  dst_unchanging_p = RTX_UNCHANGING_P (operands[0]);
-  dst_in_struct_p = MEM_IN_STRUCT_P (operands[0]);
-  dst_scalar_p = MEM_SCALAR_P (operands[0]);
-  src_unchanging_p = RTX_UNCHANGING_P (operands[1]);
-  src_in_struct_p = MEM_IN_STRUCT_P (operands[1]);
-  src_scalar_p = MEM_SCALAR_P (operands[1]);
-
-  fin_dst = dst = copy_to_mode_reg (SImode, st_dst);
-  fin_src = src = copy_to_mode_reg (SImode, st_src);
+  dstbase = operands[0];
+  srcbase = operands[1];
+  
+  dst = copy_to_mode_reg (SImode, XEXP (dstbase, 0));
+  src = copy_to_mode_reg (SImode, XEXP (srcbase, 0));
 
   in_words_to_go = ARM_NUM_INTS (INTVAL (operands[2]));
   out_words_to_go = INTVAL (operands[2]) / 4;
   last_bytes = INTVAL (operands[2]) & 3;
-
+  dstoffset = srcoffset = 0;
+  
   if (out_words_to_go != in_words_to_go && ((in_words_to_go - 1) & 3) != 0)
     part_bytes_reg = gen_rtx_REG (SImode, (in_words_to_go - 1) & 3);
 
@@ -5345,38 +5344,32 @@ arm_gen_movstrqi (rtx *operands)
     {
       if (in_words_to_go > 4)
        emit_insn (arm_gen_load_multiple (0, 4, src, TRUE, TRUE,
-                                         src_unchanging_p,
-                                         src_in_struct_p,
-                                         src_scalar_p));
+                                         srcbase, &srcoffset));
       else
        emit_insn (arm_gen_load_multiple (0, in_words_to_go, src, TRUE, 
-                                         FALSE, src_unchanging_p,
-                                         src_in_struct_p, src_scalar_p));
+                                         FALSE, srcbase, &srcoffset));
 
       if (out_words_to_go)
        {
          if (out_words_to_go > 4)
            emit_insn (arm_gen_store_multiple (0, 4, dst, TRUE, TRUE,
-                                              dst_unchanging_p,
-                                              dst_in_struct_p,
-                                              dst_scalar_p));
+                                              dstbase, &dstoffset));
+         
          else if (out_words_to_go != 1)
            emit_insn (arm_gen_store_multiple (0, out_words_to_go,
                                               dst, TRUE, 
                                               (last_bytes == 0
                                                ? FALSE : TRUE),
-                                              dst_unchanging_p,
-                                              dst_in_struct_p,
-                                              dst_scalar_p));
+                                              dstbase, &dstoffset));
          else
            {
-             mem = gen_rtx_MEM (SImode, dst);
-             RTX_UNCHANGING_P (mem) = dst_unchanging_p;
-             MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
-             MEM_SCALAR_P (mem) = dst_scalar_p;
+             mem = adjust_automodify_address (dstbase, SImode, dst, dstoffset);
              emit_move_insn (mem, gen_rtx_REG (SImode, 0));
              if (last_bytes != 0)
-               emit_insn (gen_addsi3 (dst, dst, GEN_INT (4)));
+               {
+                 emit_insn (gen_addsi3 (dst, dst, GEN_INT (4)));
+                 dstoffset += 4;
+               }
            }
        }
 
@@ -5388,20 +5381,12 @@ arm_gen_movstrqi (rtx *operands)
   if (out_words_to_go)
     {
       rtx sreg;
-      
-      mem = gen_rtx_MEM (SImode, src);
-      RTX_UNCHANGING_P (mem) = src_unchanging_p;
-      MEM_IN_STRUCT_P (mem) = src_in_struct_p;
-      MEM_SCALAR_P (mem) = src_scalar_p;
-      emit_move_insn (sreg = gen_reg_rtx (SImode), mem);
-      emit_move_insn (fin_src = gen_reg_rtx (SImode), plus_constant (src, 4));
-      
-      mem = gen_rtx_MEM (SImode, dst);
-      RTX_UNCHANGING_P (mem) = dst_unchanging_p;
-      MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
-      MEM_SCALAR_P (mem) = dst_scalar_p;
+
+      mem = adjust_automodify_address (srcbase, SImode, src, srcoffset);
+      sreg = copy_to_reg (mem);
+
+      mem = adjust_automodify_address (dstbase, SImode, dst, dstoffset);
       emit_move_insn (mem, sreg);
-      emit_move_insn (fin_dst = gen_reg_rtx (SImode), plus_constant (dst, 4));
       in_words_to_go--;
       
       if (in_words_to_go)      /* Sanity check */
@@ -5413,10 +5398,7 @@ arm_gen_movstrqi (rtx *operands)
       if (in_words_to_go < 0)
        abort ();
 
-      mem = gen_rtx_MEM (SImode, src);
-      RTX_UNCHANGING_P (mem) = src_unchanging_p;
-      MEM_IN_STRUCT_P (mem) = src_in_struct_p;
-      MEM_SCALAR_P (mem) = src_scalar_p;
+      mem = adjust_automodify_address (srcbase, SImode, src, srcoffset);
       part_bytes_reg = copy_to_mode_reg (SImode, mem);
     }
 
@@ -5434,10 +5416,9 @@ arm_gen_movstrqi (rtx *operands)
       
       while (last_bytes)
        {
-         mem = gen_rtx_MEM (QImode, plus_constant (dst, last_bytes - 1));
-         RTX_UNCHANGING_P (mem) = dst_unchanging_p;
-         MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
-         MEM_SCALAR_P (mem) = dst_scalar_p;
+         mem = adjust_automodify_address (dstbase, QImode,
+                                          plus_constant (dst, last_bytes - 1),
+                                          dstoffset + last_bytes - 1);
          emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg));
 
          if (--last_bytes)
@@ -5453,10 +5434,7 @@ arm_gen_movstrqi (rtx *operands)
     {
       if (last_bytes > 1)
        {
-         mem = gen_rtx_MEM (HImode, dst);
-         RTX_UNCHANGING_P (mem) = dst_unchanging_p;
-         MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
-         MEM_SCALAR_P (mem) = dst_scalar_p;
+         mem = adjust_automodify_address (dstbase, HImode, dst, dstoffset);
          emit_move_insn (mem, gen_lowpart (HImode, part_bytes_reg));
          last_bytes -= 2;
          if (last_bytes)
@@ -5466,15 +5444,13 @@ arm_gen_movstrqi (rtx *operands)
              emit_insn (gen_addsi3 (dst, dst, GEN_INT (2)));
              emit_insn (gen_lshrsi3 (tmp, part_bytes_reg, GEN_INT (16)));
              part_bytes_reg = tmp;
+             dstoffset += 2;
            }
        }
       
       if (last_bytes)
        {
-         mem = gen_rtx_MEM (QImode, dst);
-         RTX_UNCHANGING_P (mem) = dst_unchanging_p;
-         MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
-         MEM_SCALAR_P (mem) = dst_scalar_p;
+         mem = adjust_automodify_address (dstbase, QImode, dst, dstoffset);
          emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg));
        }
     }
index 57926ba6b9bcf12595c682e51031a8f6189639c3..0a5e647aed0c963818143d2b9c50401dbc912189 100644 (file)
                           (match_operand:SI 1 "" ""))
                      (use (match_operand:SI 2 "" ""))])]
   "TARGET_ARM"
-  "
+{
+  HOST_WIDE_INT offset = 0;
+  
   /* Support only fixed point registers.  */
   if (GET_CODE (operands[2]) != CONST_INT
       || INTVAL (operands[2]) > 14
   operands[3]
     = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
                             force_reg (SImode, XEXP (operands[1], 0)),
-                            TRUE, FALSE, RTX_UNCHANGING_P(operands[1]),
-                            MEM_IN_STRUCT_P(operands[1]),
-                            MEM_SCALAR_P (operands[1]));
-  "
-)
+                            TRUE, FALSE, operands[1], &offset);
+
+})
 
 ;; Load multiple with write-back
 
                           (match_operand:SI 1 "" ""))
                      (use (match_operand:SI 2 "" ""))])]
   "TARGET_ARM"
-  "
+{
+  HOST_WIDE_INT offset = 0;
+
   /* Support only fixed point registers.  */
   if (GET_CODE (operands[2]) != CONST_INT
       || INTVAL (operands[2]) > 14
   operands[3]
     = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
                              force_reg (SImode, XEXP (operands[0], 0)),
-                             TRUE, FALSE, RTX_UNCHANGING_P (operands[0]),
-                             MEM_IN_STRUCT_P(operands[0]), 
-                             MEM_SCALAR_P (operands[0]));
-  "
-)
+                             TRUE, FALSE, operands[0], &offset);
+})
 
 ;; Store multiple with write-back