re PR rtl-optimization/17581 (Long long arithmetic fails inside a switch/case stateme...
authorRoger Sayle <roger@eyesopen.com>
Sat, 30 Oct 2004 00:56:59 +0000 (00:56 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Sat, 30 Oct 2004 00:56:59 +0000 (00:56 +0000)
PR rtl-optimization/17581
* cselib.c (cselib_process_insn): The last instruction of a libcall
block, with the REG_RETVAL note, should be considered in the libcall.
* gcse.c (do_local_cprop): Allow constants to be propagated outside
of libcall blocks.
(adjust_libcall_notes): Use simplify_replace_rtx instead of
replace_rtx to avoid creating invalid RTL in REG_RETVAL notes.

* gcc.dg/pr17581-1.c: New test case.

From-SVN: r89873

gcc/ChangeLog
gcc/cselib.c
gcc/gcse.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr17581-1.c [new file with mode: 0644]

index ae5c94b8e4215c847bb88c80c610cbaa73d79734..6ac0249c5561fbb6bc366ba64acc70a5be1fec01 100644 (file)
@@ -1,3 +1,13 @@
+2004-10-29  Roger Sayle  <roger@eyesopen.com>
+
+       PR rtl-optimization/17581
+       * cselib.c (cselib_process_insn): The last instruction of a libcall
+       block, with the REG_RETVAL note, should be considered in the libcall.
+       * gcse.c (do_local_cprop): Allow constants to be propagated outside
+       of libcall blocks.
+       (adjust_libcall_notes): Use simplify_replace_rtx instead of
+       replace_rtx to avoid creating invalid RTL in REG_RETVAL notes.
+
 2004-10-30  Kazu Hirata  <kazu@cs.umass.edu>
 
        * tree-phinodes.c (create_phi_node): Don't zero PHI_REWRITTEN.
index e58f2541d4d4d5b4a985aabb5ae4bbf6766f762d..eb0b52a2edcdd84119132c648a099e676743a0ba 100644 (file)
@@ -1346,8 +1346,6 @@ cselib_process_insn (rtx insn)
 
   if (find_reg_note (insn, REG_LIBCALL, NULL))
     cselib_current_insn_in_libcall = true;
-  if (find_reg_note (insn, REG_RETVAL, NULL))
-    cselib_current_insn_in_libcall = false;
   cselib_current_insn = insn;
 
   /* Forget everything at a CODE_LABEL, a volatile asm, or a setjmp.  */
@@ -1358,12 +1356,16 @@ cselib_process_insn (rtx insn)
          && GET_CODE (PATTERN (insn)) == ASM_OPERANDS
          && MEM_VOLATILE_P (PATTERN (insn))))
     {
+      if (find_reg_note (insn, REG_RETVAL, NULL))
+        cselib_current_insn_in_libcall = false;
       clear_table ();
       return;
     }
 
   if (! INSN_P (insn))
     {
+      if (find_reg_note (insn, REG_RETVAL, NULL))
+        cselib_current_insn_in_libcall = false;
       cselib_current_insn = 0;
       return;
     }
@@ -1399,6 +1401,8 @@ cselib_process_insn (rtx insn)
       if (GET_CODE (XEXP (x, 0)) == CLOBBER)
        cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0));
 
+  if (find_reg_note (insn, REG_RETVAL, NULL))
+    cselib_current_insn_in_libcall = false;
   cselib_current_insn = 0;
 
   if (n_useless_values > MAX_USELESS_VALUES)
index f1e1b0aa85fa4c87c429699c49c8dad3c3b326eb..f277801bcedcb7624448c3484808a052ea0f0480 100644 (file)
@@ -3134,7 +3134,8 @@ do_local_cprop (rtx x, rtx insn, int alter_jumps, rtx *libcall_sp)
          rtx this_rtx = l->loc;
          rtx note;
 
-         if (l->in_libcall)
+         /* Don't CSE non-constant values out of libcall blocks.  */
+         if (l->in_libcall && ! CONSTANT_P (this_rtx))
            continue;
 
          if (gcse_constant_p (this_rtx))
@@ -3222,7 +3223,7 @@ adjust_libcall_notes (rtx oldreg, rtx newval, rtx insn, rtx *libcall_sp)
              return true;
            }
        }
-      XEXP (note, 0) = replace_rtx (XEXP (note, 0), oldreg, newval);
+      XEXP (note, 0) = simplify_replace_rtx (XEXP (note, 0), oldreg, newval);
       insn = end;
     }
   return true;
index f6f3bded2750494986144242bbfb8155c939f3e6..eebb2e8a6fb16b5a9cf3cbd9453ec97e794c9724 100644 (file)
@@ -1,3 +1,8 @@
+2004-10-29  Roger Sayle  <roger@eyesopen.com>
+
+       PR rtl-optimization/17581
+       * gcc.dg/pr17581-1.c: New test case.
+
 2004-10-28  Nathan Sidwell  <nathan@codesourcery.com>
 
        * g++.dg/conversion/dr195.C: Adjust expected errors for DR195 not
diff --git a/gcc/testsuite/gcc.dg/pr17581-1.c b/gcc/testsuite/gcc.dg/pr17581-1.c
new file mode 100644 (file)
index 0000000..757661e
--- /dev/null
@@ -0,0 +1,28 @@
+/* PR rtl-optimization/17581 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+int foo(int x)
+{
+  unsigned long long tmp = 0;
+
+  switch(x) {
+    case 21:
+      tmp |= 1;
+      tmp |= 2;
+      tmp |= 8;
+      break;
+    default:
+      break;
+  }
+  
+  return (int)tmp;
+}
+
+int main()
+{
+  if (foo(21) != 11)
+    abort ();
+  return 0;
+}
+