re PR rtl-optimization/23567 (if-conversion causes wrong code)
authorJakub Jelinek <jakub@redhat.com>
Mon, 7 Nov 2005 08:01:54 +0000 (09:01 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 7 Nov 2005 08:01:54 +0000 (09:01 +0100)
PR rtl-optimization/23567
* ifcvt.c (noce_mem_write_may_trap_or_fault_p): New function.
(noce_process_if_block): Don't do any optimizations except
if (cond) x = x; if !set_b and write into orig_x may trap
or fault.  Remove the MEM_READONLY_P check.

* gcc.c-torture/execute/20051104-1.c: New test.

From-SVN: r106585

gcc/ChangeLog
gcc/ifcvt.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20051104-1.c [new file with mode: 0644]

index dbe9c080c941bbf6cfe473a1f5aff79b916f10d3..fb378115a8f1c5506dce0401608318998e55e7ed 100644 (file)
@@ -1,3 +1,11 @@
+2005-11-07  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/23567
+       * ifcvt.c (noce_mem_write_may_trap_or_fault_p): New function.
+       (noce_process_if_block): Don't do any optimizations except
+       if (cond) x = x; if !set_b and write into orig_x may trap
+       or fault.  Remove the MEM_READONLY_P check.
+
 2005-11-06  Diego Novillo  <dnovillo@redhat.com>
 
        PR 24670
index d74d9457d7becadfef6ad02bb1e134476d9424ec..da32ab45a71c10549c3bc617680da5850c3ab16e 100644 (file)
@@ -2025,6 +2025,59 @@ noce_operand_ok (rtx op)
   return ! may_trap_p (op);
 }
 
+/* Return true if a write into MEM may trap or fault.  */
+
+static bool
+noce_mem_write_may_trap_or_fault_p (rtx mem)
+{
+  rtx addr;
+
+  if (MEM_READONLY_P (mem))
+    return true;
+
+  if (may_trap_or_fault_p (mem))
+    return true;
+
+  addr = XEXP (mem, 0);
+
+  /* Call target hook to avoid the effects of -fpic etc....  */
+  addr = targetm.delegitimize_address (addr);
+
+  while (addr)
+    switch (GET_CODE (addr))
+      {
+      case CONST:
+      case PRE_DEC:
+      case PRE_INC:
+      case POST_DEC:
+      case POST_INC:
+      case POST_MODIFY:
+       addr = XEXP (addr, 0);
+       break;
+      case LO_SUM:
+      case PRE_MODIFY:
+       addr = XEXP (addr, 1);
+       break;
+      case PLUS:
+       if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
+         addr = XEXP (addr, 0);
+       else
+         return false;
+       break;
+      case LABEL_REF:
+       return true;
+      case SYMBOL_REF:
+       if (SYMBOL_REF_DECL (addr)
+           && decl_readonly_section (SYMBOL_REF_DECL (addr), 0))
+         return true;
+       return false;
+      default:
+       return false;
+      }
+
+  return false;
+}
+
 /* Given a simple IF-THEN or IF-THEN-ELSE block, attempt to convert it
    without using conditional execution.  Return TRUE if we were
    successful at converting the block.  */
@@ -2136,14 +2189,6 @@ noce_process_if_block (struct ce_if_block * ce_info)
   if (side_effects_p (x))
     return FALSE;
 
-  /* If x is a read-only memory, then the program is valid only if we
-     avoid the store into it.  If there are stores on both the THEN and
-     ELSE arms, then we can go ahead with the conversion; either the 
-     program is broken, or the condition is always false such that the
-     other memory is selected.  */
-  if (!set_b && MEM_P (x) && MEM_READONLY_P (x))
-    return FALSE;
-
   b = (set_b ? SET_SRC (set_b) : x);
 
   /* Only operate on register destinations, and even then avoid extending
@@ -2211,23 +2256,16 @@ noce_process_if_block (struct ce_if_block * ce_info)
     }
 
   /* Disallow the "if (...) x = a;" form (with an implicit "else x = x;")
-     for most optimizations if writing to x may trap, i.e. it's a memory
-     other than a static var or a stack slot.  */
-  if (! set_b
-      && MEM_P (orig_x)
-      && ! MEM_NOTRAP_P (orig_x)
-      && rtx_addr_can_trap_p (XEXP (orig_x, 0)))
-    {
-      if (HAVE_conditional_move)
-       {
-         if (noce_try_cmove (&if_info))
-           goto success;
-         if (! HAVE_conditional_execution
-             && noce_try_cmove_arith (&if_info))
-           goto success;
-       }
-      return FALSE;
-    }
+     for optimizations if writing to x may trap or fault, i.e. it's a memory
+     other than a static var or a stack slot, is misaligned on strict
+     aligned machines or is read-only.
+     If x is a read-only memory, then the program is valid only if we
+     avoid the store into it.  If there are stores on both the THEN and
+     ELSE arms, then we can go ahead with the conversion; either the
+     program is broken, or the condition is always false such that the
+     other memory is selected.  */
+  if (!set_b && MEM_P (orig_x) && noce_mem_write_may_trap_or_fault_p (orig_x))
+    return FALSE;
 
   if (noce_try_move (&if_info))
     goto success;
index 0dca65ba8113117244fce1780c09717d91e98555..0ab25393c78c881258869db68007a500471dbbf0 100644 (file)
@@ -1,3 +1,8 @@
+2005-11-07  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/23567
+       * gcc.c-torture/execute/20051104-1.c: New test.
+
 2005-11-06  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/24534
diff --git a/gcc/testsuite/gcc.c-torture/execute/20051104-1.c b/gcc/testsuite/gcc.c-torture/execute/20051104-1.c
new file mode 100644 (file)
index 0000000..1657877
--- /dev/null
@@ -0,0 +1,17 @@
+/* PR rtl-optimization/23567 */
+
+struct
+{
+  int len;
+  char *name;
+} s;
+
+int
+main (void)
+{
+  s.len = 0;
+  s.name = "";
+  if (s.name [s.len] != 0)
+    s.name [s.len] = 0;
+  return 0;
+}