OSDN Git Service

PR rtl-optimization/19683
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 7 Mar 2005 17:48:46 +0000 (17:48 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 7 Mar 2005 17:48:46 +0000 (17:48 +0000)
* reload1.c (choose_reload_regs): Pass the number of bits, not the
number of bytes, to smallest_int_for_mode.  Fix arguments to
REG_CANNOT_CHANGE_MODE_P.

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

gcc/ChangeLog
gcc/reload1.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr19683-1.c [new file with mode: 0644]

index 9c6b448..86bc853 100644 (file)
@@ -1,3 +1,10 @@
+2005-03-07  Richard Sandiford  <rsandifo@redhat.com>
+
+       PR rtl-optimization/19683
+       * reload1.c (choose_reload_regs): Pass the number of bits, not the
+       number of bytes, to smallest_int_for_mode.  Fix arguments to
+       REG_CANNOT_CHANGE_MODE_P.
+
 2005-03-07  Eric Botcazou  <ebotcazou@libertysurf.fr>
 
        * reorg.c (relax_delay_slots): Check that the jump is
index 32f8ddc..31407b3 100644 (file)
@@ -5411,19 +5411,18 @@ choose_reload_regs (struct insn_chain *chain)
                    need_mode = mode;
                  else
                    need_mode
-                     = smallest_mode_for_size (GET_MODE_SIZE (mode) + byte,
+                     = smallest_mode_for_size (GET_MODE_BITSIZE (mode)
+                                               + byte * BITS_PER_UNIT,
                                                GET_MODE_CLASS (mode));
 
-                 if (
-#ifdef CANNOT_CHANGE_MODE_CLASS
-                     (!REG_CANNOT_CHANGE_MODE_P (i, GET_MODE (last_reg),
-                                                 need_mode)
-                      &&
-#endif
-                     (GET_MODE_SIZE (GET_MODE (last_reg))
+                 if ((GET_MODE_SIZE (GET_MODE (last_reg))
                       >= GET_MODE_SIZE (need_mode))
 #ifdef CANNOT_CHANGE_MODE_CLASS
-                     )
+                     /* Verify that the register in "i" can be obtained
+                        from LAST_REG.  */
+                     && !REG_CANNOT_CHANGE_MODE_P (REGNO (last_reg),
+                                                   GET_MODE (last_reg),
+                                                   mode)
 #endif
                      && reg_reloaded_contents[i] == regno
                      && TEST_HARD_REG_BIT (reg_reloaded_valid, i)
index 1abdca1..3b33042 100644 (file)
@@ -1,3 +1,7 @@
+2005-03-07  Richard Sandiford  <rsandifo@redhat.com>
+
+       * gcc.dg/torture/pr19683-1.c: New test.
+
 2005-03-06  Steven G. Kargl  <kargls@comcast.net>
 
        * gfortran.dg/g77/19990313-1.f: Replace tabs with spaces.
diff --git a/gcc/testsuite/gcc.dg/torture/pr19683-1.c b/gcc/testsuite/gcc.dg/torture/pr19683-1.c
new file mode 100644 (file)
index 0000000..4015fb9
--- /dev/null
@@ -0,0 +1,42 @@
+/* From PR rtl-optimization/19683.  On little-endian MIPS targets,
+   reload would incorrectly inherit the high part of the multiplication
+   result.  */
+/* { dg-do run { target mips*-*-* } } */
+
+extern void abort (void);
+extern void exit (int);
+
+#define REPEAT10(X, Y)                                 \
+  X(Y##0); X(Y##1); X(Y##2); X(Y##3); X(Y##4);         \
+  X(Y##5); X(Y##6); X(Y##7); X(Y##8); X(Y##9)
+
+#define REPEAT30(X) REPEAT10 (X, 0); REPEAT10 (X, 1); REPEAT10 (X, 2)
+#define IN(X) unsigned int x##X = ptr[0]
+#define OUT(X) ptr[0] = x##X
+
+union u { unsigned long long ll; unsigned int i[2]; };
+
+unsigned int
+foo (volatile unsigned int *ptr)
+{
+  union u u;
+  int result;
+
+  u.ll = (unsigned long long) ptr[0] * ptr[0];
+  REPEAT30 (IN);
+  REPEAT30 (OUT);
+  asm ("#" : "=l" (result) : "l" (u.i[1]));
+  return result;
+}
+
+int
+main (void)
+{
+  unsigned int array[] = { 1000 * 1000 * 1000 };
+  union u u;
+
+  u.ll = (unsigned long long) array[0] * array[0];
+  if (foo (array) != u.i[1])
+    abort ();
+  exit (0);
+}