]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/59747 (wrong code at -Os and above on x86_64-linux-gnu in...
authorJeff Law <law@redhat.com>
Wed, 15 Jan 2014 18:13:52 +0000 (11:13 -0700)
committerJeff Law <law@gcc.gnu.org>
Wed, 15 Jan 2014 18:13:52 +0000 (11:13 -0700)
PR tree-optimization/59747
* ree.c (find_and_remove_re): Properly handle case where a second
eliminated extension requires widening a copy created for elimination
of a prior extension.
(combine_set_extension): Ensure that the number of hard regs needed
for a destination register does not change when we widen it.

PR tree-optimization/59747
* gcc.c-torture/execute/pr59747.c: New test.

From-SVN: r206638

gcc/ChangeLog
gcc/ree.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr59747.c [new file with mode: 0644]

index 1231e88b7359ff2055fad170648c2238a740119d..856bd46ac5253aa8ea04e9cbb15e4848ecf8202d 100644 (file)
@@ -1,3 +1,12 @@
+2014-01-15  Jeff Law  <law@redhat.com>
+
+       PR tree-optimization/59747
+       * ree.c (find_and_remove_re): Properly handle case where a second
+       eliminated extension requires widening a copy created for elimination
+       of a prior extension.
+       (combine_set_extension): Ensure that the number of hard regs needed
+       for a destination register does not change when we widen it.
+
 2014-01-15  Sebastian Huber  <sebastian.huber@embedded-brains.de>
 
        * config.gcc (*-*-rtems*): Add t-rtems to tmake_file.
index 63cc8cc7c32eaebda88bc664ec369f4fdf96aecc..19d821ce05afbf8d6e97264d103eca927374fc10 100644 (file)
--- a/gcc/ree.c
+++ b/gcc/ree.c
@@ -297,6 +297,12 @@ combine_set_extension (ext_cand *cand, rtx curr_insn, rtx *orig_set)
   else
     new_reg = gen_rtx_REG (cand->mode, REGNO (SET_DEST (*orig_set)));
 
+  /* We're going to be widening the result of DEF_INSN, ensure that doing so
+     doesn't change the number of hard registers needed for the result.  */
+  if (HARD_REGNO_NREGS (REGNO (new_reg), cand->mode)
+      != HARD_REGNO_NREGS (REGNO (orig_src), GET_MODE (SET_DEST (*orig_set))))
+       return false;
+
   /* Merge constants by directly moving the constant into the register under
      some conditions.  Recall that RTL constants are sign-extended.  */
   if (GET_CODE (orig_src) == CONST_INT
@@ -1017,11 +1023,20 @@ find_and_remove_re (void)
   for (unsigned int i = 0; i < reinsn_copy_list.length (); i += 2)
     {
       rtx curr_insn = reinsn_copy_list[i];
+      rtx def_insn = reinsn_copy_list[i + 1];
+
+      /* Use the mode of the destination of the defining insn
+        for the mode of the copy.  This is necessary if the
+        defining insn was used to eliminate a second extension
+        that was wider than the first.  */
+      rtx sub_rtx = *get_sub_rtx (def_insn);
       rtx pat = PATTERN (curr_insn);
-      rtx new_reg = gen_rtx_REG (GET_MODE (SET_DEST (pat)),
+      rtx new_dst = gen_rtx_REG (GET_MODE (SET_DEST (sub_rtx)),
                                 REGNO (XEXP (SET_SRC (pat), 0)));
-      rtx set = gen_rtx_SET (VOIDmode, new_reg, SET_DEST (pat));
-      emit_insn_after (set, reinsn_copy_list[i + 1]);
+      rtx new_src = gen_rtx_REG (GET_MODE (SET_DEST (sub_rtx)),
+                                REGNO (SET_DEST (pat)));
+      rtx set = gen_rtx_SET (VOIDmode, new_dst, new_src);
+      emit_insn_after (set, def_insn);
     }
 
   /* Delete all useless extensions here in one sweep.  */
index 4aadd851e852e0b8c0743c804e9ab69a20e40ac3..dcfb67197f0bf215e75b441a034dc0d36ae86112 100644 (file)
@@ -1,3 +1,8 @@
+2014-01-15  Jeff Law  <law@redhat.com>
+
+       PR tree-optimization/59747
+       * gcc.c-torture/execute/pr59747.c: New test.
+
 2014-01-15  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR target/59794
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr59747.c b/gcc/testsuite/gcc.c-torture/execute/pr59747.c
new file mode 100644 (file)
index 0000000..d45a908
--- /dev/null
@@ -0,0 +1,27 @@
+extern void abort (void);
+extern void exit (int);
+
+int a[6], b, c = 1, d;
+short e;
+
+int __attribute__ ((noinline))
+fn1 (int p)
+{
+  b = a[p];
+}
+
+int
+main ()
+{
+  if (sizeof (long long) != 8)
+    exit (0);
+
+  a[0] = 1;
+  if (c)
+    e--;
+  d = e;
+  long long f = e;
+  if (fn1 ((f >> 56) & 1) != 0)
+    abort ();
+  exit (0);
+}