re PR target/63483 (Scheduler performs Invalid move of aliased memory reference)
authorUros Bizjak <ubizjak@gmail.com>
Fri, 10 Oct 2014 17:36:21 +0000 (19:36 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Fri, 10 Oct 2014 17:36:21 +0000 (19:36 +0200)
PR rtl-optimization/63483
* alias.c (true_dependence_1): Do not exit early for MEM_READONLY_P
references when alignment ANDs are involved.
(write_dependence_p): Ditto.
(may_alias_p): Ditto.

From-SVN: r216100

gcc/ChangeLog
gcc/alias.c

index 3190099126b52fab8766861657e1ab373140aa31..d418235e08f5c946434edd53e648989fbb6ba2ae 100644 (file)
@@ -1,3 +1,11 @@
+2014-10-10  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR rtl-optimization/63483
+       * alias.c (true_dependence_1): Do not exit early for MEM_READONLY_P
+       references when alignment ANDs are involved.
+       (write_dependence_p): Ditto.
+       (may_alias_p): Ditto.
+
 2014-10-10  Marek Polacek  <polacek@redhat.com>
 
        * asan.c (pass_sanopt::execute): Handle IFN_UBSAN_OBJECT_SIZE.
index a098cb7fb70f3bf241deeaccab36119f3ad57f25..134b6fb5485b3df600f16aeb3b4333c2579c845d 100644 (file)
@@ -2458,18 +2458,6 @@ true_dependence_1 (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
       || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
     return 1;
 
-  /* Read-only memory is by definition never modified, and therefore can't
-     conflict with anything.  We don't expect to find read-only set on MEM,
-     but stupid user tricks can produce them, so don't die.  */
-  if (MEM_READONLY_P (x))
-    return 0;
-
-  /* If we have MEMs referring to different address spaces (which can
-     potentially overlap), we cannot easily tell from the addresses
-     whether the references overlap.  */
-  if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x))
-    return 1;
-
   if (! mem_addr)
     {
       mem_addr = XEXP (mem, 0);
@@ -2493,6 +2481,22 @@ true_dependence_1 (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
        }
     }
 
+  /* Read-only memory is by definition never modified, and therefore can't
+     conflict with anything.  However, don't assume anything when AND
+     addresses are involved and leave to the code below to determine
+     dependence.  We don't expect to find read-only set on MEM, but
+     stupid user tricks can produce them, so don't die.  */
+  if (MEM_READONLY_P (x)
+      && GET_CODE (x_addr) != AND
+      && GET_CODE (mem_addr) != AND)
+    return 0;
+
+  /* If we have MEMs referring to different address spaces (which can
+     potentially overlap), we cannot easily tell from the addresses
+     whether the references overlap.  */
+  if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x))
+    return 1;
+
   base = find_base_term (x_addr);
   if (base && (GET_CODE (base) == LABEL_REF
               || (GET_CODE (base) == SYMBOL_REF
@@ -2576,16 +2580,6 @@ write_dependence_p (const_rtx mem,
       || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
     return 1;
 
-  /* A read from read-only memory can't conflict with read-write memory.  */
-  if (!writep && MEM_READONLY_P (mem))
-    return 0;
-
-  /* If we have MEMs referring to different address spaces (which can
-     potentially overlap), we cannot easily tell from the addresses
-     whether the references overlap.  */
-  if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x))
-    return 1;
-
   mem_addr = XEXP (mem, 0);
   if (!x_addr)
     {
@@ -2603,6 +2597,21 @@ write_dependence_p (const_rtx mem,
        }
     }
 
+  /* A read from read-only memory can't conflict with read-write memory.
+     Don't assume anything when AND addresses are involved and leave to
+     the code below to determine dependence.  */
+  if (!writep
+      && MEM_READONLY_P (mem)
+      && GET_CODE (x_addr) != AND
+      && GET_CODE (mem_addr) != AND)
+    return 0;
+
+  /* If we have MEMs referring to different address spaces (which can
+     potentially overlap), we cannot easily tell from the addresses
+     whether the references overlap.  */
+  if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x))
+    return 1;
+
   base = find_base_term (mem_addr);
   if (! writep
       && base
@@ -2690,18 +2699,6 @@ may_alias_p (const_rtx mem, const_rtx x)
       || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
     return 1;
 
-  /* Read-only memory is by definition never modified, and therefore can't
-     conflict with anything.  We don't expect to find read-only set on MEM,
-     but stupid user tricks can produce them, so don't die.  */
-  if (MEM_READONLY_P (x))
-    return 0;
-
-  /* If we have MEMs referring to different address spaces (which can
-     potentially overlap), we cannot easily tell from the addresses
-     whether the references overlap.  */
-  if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x))
-    return 1;
-
   x_addr = XEXP (x, 0);
   mem_addr = XEXP (mem, 0);
   if (!((GET_CODE (x_addr) == VALUE
@@ -2715,6 +2712,22 @@ may_alias_p (const_rtx mem, const_rtx x)
       mem_addr = get_addr (mem_addr);
     }
 
+  /* Read-only memory is by definition never modified, and therefore can't
+     conflict with anything.  However, don't assume anything when AND
+     addresses are involved and leave to the code below to determine
+     dependence.  We don't expect to find read-only set on MEM, but
+     stupid user tricks can produce them, so don't die.  */
+  if (MEM_READONLY_P (x)
+      && GET_CODE (x_addr) != AND
+      && GET_CODE (mem_addr) != AND)
+    return 0;
+
+  /* If we have MEMs referring to different address spaces (which can
+     potentially overlap), we cannot easily tell from the addresses
+     whether the references overlap.  */
+  if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x))
+    return 1;
+
   rtx x_base = find_base_term (x_addr);
   rtx mem_base = find_base_term (mem_addr);
   if (! base_alias_check (x_addr, x_base, mem_addr, mem_base,