diff options
author | Jeff Law <law@redhat.com> | 2017-01-05 00:38:48 -0700 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2017-01-05 00:38:48 -0700 |
commit | d80c6d02fdf0c37596e51392ade43414a350373a (patch) | |
tree | 8e37be87c8ec04e67bbf7f825c453fd039b46d57 /gcc/gcse.c | |
parent | 0f9cf7ff836bbc7d4f68e47918c878983c08e386 (diff) | |
download | gcc-d80c6d02fdf0c37596e51392ade43414a350373a.tar.gz |
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
Diffstat (limited to 'gcc/gcse.c')
-rw-r--r-- | gcc/gcse.c | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/gcc/gcse.c b/gcc/gcse.c index fbc770a48de..d28288df95c 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 |