]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/29006 (Incorrect zeroing of unaligned 64-bit fields on MIPS targets)
authorRichard Sandiford <richard@codesourcery.com>
Sun, 10 Sep 2006 19:36:20 +0000 (19:36 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Sun, 10 Sep 2006 19:36:20 +0000 (19:36 +0000)
gcc/
PR target/29006
* config/mips/mips-protos.h (mips_mem_fits_mode_p): Declare.
* config/mips/mips.c (mips_expand_unaligned_store): Use the mode
returned by mode_for_size, rather than the mode of src itself,
to choose between 32-bit and 64-bit patterns.
(mips_mem_fits_mode_p): New function.
* config/mips/mips.md (mov_<load>l, mov_<load>r): Use it to check
that the size of the source matches the size of the destination.
(mov_<store>l, mov_<store>r): Likewise.

gcc/testsuite/
PR target/29006
* gcc.c-torture/execute/pr29006.c: New test.

From-SVN: r116824

gcc/ChangeLog
gcc/config/mips/mips-protos.h
gcc/config/mips/mips.c
gcc/config/mips/mips.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr29006.c [new file with mode: 0644]

index 1a9812b335b22047812a7efe1fd5575441a69b68..609f0a7a8f9e2ee0699600e0350939531c70b8b5 100644 (file)
@@ -1,3 +1,15 @@
+2006-09-10  Richard Sandiford  <richard@codesourcery.com>
+
+       PR target/29006
+       * config/mips/mips-protos.h (mips_mem_fits_mode_p): Declare.
+       * config/mips/mips.c (mips_expand_unaligned_store): Use the mode
+       returned by mode_for_size, rather than the mode of src itself,
+       to choose between 32-bit and 64-bit patterns.
+       (mips_mem_fits_mode_p): New function.
+       * config/mips/mips.md (mov_<load>l, mov_<load>r): Use it to check
+       that the size of the source matches the size of the destination.
+       (mov_<store>l, mov_<store>r): Likewise.
+
 2006-09-06  Matthias Klose  <doko@debian.org>
 
        * Makefile.in (s-macro_list): Conform to POSIX rules in single quoted
index 8569d429959b8fe145aaa2bf0fa32ab7a5c31f53..21fc7f357ddfcde91bd13def448487ad5b40d27b 100644 (file)
@@ -148,6 +148,7 @@ extern void mips_va_start (tree, rtx);
 
 extern bool mips_expand_unaligned_load (rtx, rtx, unsigned int, int);
 extern bool mips_expand_unaligned_store (rtx, rtx, unsigned int, int);
+extern bool mips_mem_fits_mode_p (enum machine_mode mode, rtx x);
 extern void override_options (void);
 extern void mips_conditional_register_usage (void);
 extern void mips_order_regs_for_local_alloc (void);
index 0dd7e0b6ffcdab81fef3cabe4dc1c3955c25bbb2..e443bdd62e16cea8f6b527c983a416b6ce32e62d 100644 (file)
@@ -3950,13 +3950,15 @@ bool
 mips_expand_unaligned_store (rtx dest, rtx src, unsigned int width, int bitpos)
 {
   rtx left, right;
+  enum machine_mode mode;
 
   if (!mips_get_unaligned_mem (&dest, width, bitpos, &left, &right))
     return false;
 
-  src = gen_lowpart (mode_for_size (width, MODE_INT, 0), src);
+  mode = mode_for_size (width, MODE_INT, 0);
+  src = gen_lowpart (mode, src);
 
-  if (GET_MODE (src) == DImode)
+  if (mode == DImode)
     {
       emit_insn (gen_mov_sdl (dest, src, left));
       emit_insn (gen_mov_sdr (copy_rtx (dest), copy_rtx (src), right));
@@ -3968,6 +3970,20 @@ mips_expand_unaligned_store (rtx dest, rtx src, unsigned int width, int bitpos)
     }
   return true;
 }
+
+/* Return true if X is a MEM with the same size as MODE.  */
+
+bool
+mips_mem_fits_mode_p (enum machine_mode mode, rtx x)
+{
+  rtx size;
+
+  if (!MEM_P (x))
+    return false;
+
+  size = MEM_SIZE (x);
+  return size && INTVAL (size) == GET_MODE_SIZE (mode);
+}
 \f
 /* Set up globals to generate code for the ISA or processor
    described by INFO.  */
index 44c22f5e58e77714e6e92b81889644b5931498bc..a7b47fdf13bf9e3cb7022af2f9e7598aa64cf204 100644 (file)
@@ -2835,7 +2835,7 @@ beq\t%2,%.,1b\;\
        (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
                     (match_operand:QI 2 "memory_operand" "m")]
                    UNSPEC_LOAD_LEFT))]
-  "!TARGET_MIPS16"
+  "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
   "<load>l\t%0,%2"
   [(set_attr "type" "load")
    (set_attr "mode" "<MODE>")])
@@ -2846,7 +2846,7 @@ beq\t%2,%.,1b\;\
                     (match_operand:QI 2 "memory_operand" "m")
                     (match_operand:GPR 3 "register_operand" "0")]
                    UNSPEC_LOAD_RIGHT))]
-  "!TARGET_MIPS16"
+  "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
   "<load>r\t%0,%2"
   [(set_attr "type" "load")
    (set_attr "mode" "<MODE>")])
@@ -2856,7 +2856,7 @@ beq\t%2,%.,1b\;\
        (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
                     (match_operand:QI 2 "memory_operand" "m")]
                    UNSPEC_STORE_LEFT))]
-  "!TARGET_MIPS16"
+  "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
   "<store>l\t%z1,%2"
   [(set_attr "type" "store")
    (set_attr "mode" "<MODE>")])
@@ -2867,7 +2867,7 @@ beq\t%2,%.,1b\;\
                     (match_operand:QI 2 "memory_operand" "m")
                     (match_dup 0)]
                    UNSPEC_STORE_RIGHT))]
-  "!TARGET_MIPS16"
+  "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
   "<store>r\t%z1,%2"
   [(set_attr "type" "store")
    (set_attr "mode" "<MODE>")])
index f653f619a47a2952a097344ac5845fd05bb1a386..64ffd93c35e43543c64aff7428037775c22d68ca 100644 (file)
@@ -1,3 +1,8 @@
+2006-09-10  Richard Sandiford  <richard@codesourcery.com>
+
+       PR target/29006
+       * gcc.c-torture/execute/pr29006.c: New test.
+
 2006-08-28  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
 
        PR c++/28860
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr29006.c b/gcc/testsuite/gcc.c-torture/execute/pr29006.c
new file mode 100644 (file)
index 0000000..4d1f138
--- /dev/null
@@ -0,0 +1,3 @@
+struct __attribute__((__packed__)) s { char c; unsigned long long x; };
+void __attribute__((__noinline__)) foo (struct s *s) { s->x = 0; }
+int main (void) { struct s s = { 1, ~0ULL }; foo (&s); return s.x != 0; }