aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2017-01-05 00:38:48 -0700
committerJeff Law <law@gcc.gnu.org>2017-01-05 00:38:48 -0700
commitd80c6d02fdf0c37596e51392ade43414a350373a (patch)
tree8e37be87c8ec04e67bbf7f825c453fd039b46d57
parent0f9cf7ff836bbc7d4f68e47918c878983c08e386 (diff)
downloadgcc-d80c6d02fdf0c37596e51392ade43414a350373a.zip
gcc-d80c6d02fdf0c37596e51392ade43414a350373a.tar.gz
gcc-d80c6d02fdf0c37596e51392ade43414a350373a.tar.bz2
re PR rtl-optimization/78812 (Wrong code generation due to hoisting memory load across function call)
PR tree-optimizatin/78812 * rtl.h (contains_mem_rtx_p): Prototype. * ifcvt.c (containts_mem_rtx_p): Move from here to... * rtlanal.c (contains_mem_rtx_p): Here and remvoe static linkage. * gcse.c (prune_expressions): Use contains_mem_rtx_p to discover and prune MEMs that are not at the toplevel of a SET_SRC rtx. Look through ZERO_EXTEND and SIGN_EXTEND when trying to avoid pruning MEMs. PR tree-optimization/78812 * g++.dg/torture/pr78812.C: New test. From-SVN: r244093
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/gcse.c33
-rw-r--r--gcc/ifcvt.c13
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/rtlanal.c13
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/torture/pr78812.C24
7 files changed, 77 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ce11bc4..78b4412 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2017-01-04 Jeff Law <law@redhat.com>
+
+ PR tree-optimizatin/78812
+ * rtl.h (contains_mem_rtx_p): Prototype.
+ * ifcvt.c (containts_mem_rtx_p): Move from here to...
+ * rtlanal.c (contains_mem_rtx_p): Here and remvoe static linkage.
+ * gcse.c (prune_expressions): Use contains_mem_rtx_p to discover
+ and prune MEMs that are not at the toplevel of a SET_SRC rtx. Look
+ through ZERO_EXTEND and SIGN_EXTEND when trying to avoid pruning
+ MEMs.
+
2017-01-04 Alexandre Oliva <aoliva@redhat.com>
* input.c (assert_char_at_range): Default-initialize
diff --git a/gcc/gcse.c b/gcc/gcse.c
index fbc770a..d28288d 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -1709,7 +1709,7 @@ prune_expressions (bool pre_p)
continue;
}
- if (!pre_p && MEM_P (expr->expr))
+ if (!pre_p && contains_mem_rtx_p (expr->expr))
/* Note memory references that can be clobbered by a call.
We do not split abnormal edges in hoisting, so would
a memory reference get hoisted along an abnormal edge,
@@ -1717,15 +1717,28 @@ prune_expressions (bool pre_p)
constant memory references can be hoisted along abnormal
edges. */
{
- if (GET_CODE (XEXP (expr->expr, 0)) == SYMBOL_REF
- && CONSTANT_POOL_ADDRESS_P (XEXP (expr->expr, 0)))
- continue;
-
- if (MEM_READONLY_P (expr->expr)
- && !MEM_VOLATILE_P (expr->expr)
- && MEM_NOTRAP_P (expr->expr))
- /* Constant memory reference, e.g., a PIC address. */
- continue;
+ rtx x = expr->expr;
+
+ /* Common cases where we might find the MEM which may allow us
+ to avoid pruning the expression. */
+ while (GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND)
+ x = XEXP (x, 0);
+
+ /* If we found the MEM, go ahead and look at it to see if it has
+ properties that allow us to avoid pruning its expression out
+ of the tables. */
+ if (MEM_P (x))
+ {
+ if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
+ && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)))
+ continue;
+
+ if (MEM_READONLY_P (x)
+ && !MEM_VOLATILE_P (x)
+ && MEM_NOTRAP_P (x))
+ /* Constant memory reference, e.g., a PIC address. */
+ continue;
+ }
/* ??? Optimally, we would use interprocedural alias
analysis to determine if this mem is actually killed
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 56c785e..68c1a1d 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -3010,19 +3010,6 @@ noce_operand_ok (const_rtx op)
return ! may_trap_p (op);
}
-/* Return true if X contains a MEM subrtx. */
-
-static bool
-contains_mem_rtx_p (rtx x)
-{
- subrtx_iterator::array_type array;
- FOR_EACH_SUBRTX (iter, array, x, ALL)
- if (MEM_P (*iter))
- return true;
-
- return false;
-}
-
/* Return true iff basic block TEST_BB is valid for noce if-conversion.
The condition used in this if-conversion is in COND.
In practice, check that TEST_BB ends with a single set
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 302afc0..b9a7989 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -3090,6 +3090,7 @@ extern bool rtx_referenced_p (const_rtx, const_rtx);
extern bool tablejump_p (const rtx_insn *, rtx_insn **, rtx_jump_table_data **);
extern int computed_jump_p (const rtx_insn *);
extern bool tls_referenced_p (const_rtx);
+extern bool contains_mem_rtx_p (rtx x);
/* Overload for refers_to_regno_p for checking a single register. */
inline bool
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index ef93584..acb4230 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -685,6 +685,19 @@ rtx_addr_can_trap_p (const_rtx x)
return rtx_addr_can_trap_p_1 (x, 0, 0, VOIDmode, false);
}
+/* Return true if X contains a MEM subrtx. */
+
+bool
+contains_mem_rtx_p (rtx x)
+{
+ subrtx_iterator::array_type array;
+ FOR_EACH_SUBRTX (iter, array, x, ALL)
+ if (MEM_P (*iter))
+ return true;
+
+ return false;
+}
+
/* Return true if X is an address that is known to not be zero. */
bool
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 74e8d0d..16b27e6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2017-01-04 Jeff Law <law@redhat.com>
+
+ PR tree-optimization/78812
+ * g++.dg/torture/pr78812.C: New test.
+
2017-01-04 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/71977
diff --git a/gcc/testsuite/g++.dg/torture/pr78812.C b/gcc/testsuite/g++.dg/torture/pr78812.C
new file mode 100644
index 0000000..efe0936
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr78812.C
@@ -0,0 +1,24 @@
+// { dg-do run }
+// { dg-options "-fpic" { target fpic } }
+
+struct T
+{
+ bool a;
+ T () : a (false) {}
+ ~T () { if (!a) __builtin_abort (); }
+};
+
+__attribute__((noinline))
+void
+test (T &x)
+{
+ x.a = true;
+}
+
+int
+main ()
+{
+ T T;
+ test (T);
+}
+