When create_mem_ref falls back to a (void *)0 base address we
currently only fall back to LEA plus indirection when the target
can use a second index register. But we also need to do this
if there's a scaled by one index. Or rather always to be safe.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.
This fell out from experiments changing IVOPTs determine_base_object.
* tree-ssa-loop-ivopts.cc (rewrite_use_address): Always
avoid TARGET_MEM_REF with a base of zero.
* tree-ssa-sccvn.cc (vn_reference_maybe_forwprop_address): Do
not forward TARGET_MEM_REF addresses.
---
gcc/tree-ssa-loop-ivopts.cc | 3 +--
gcc/tree-ssa-sccvn.cc | 3 +++
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc
index 4ca55325188..f8dfc77de4a 100644
--- a/gcc/tree-ssa-loop-ivopts.cc
+++ b/gcc/tree-ssa-loop-ivopts.cc
@@ -7639,11 +7639,10 @@ rewrite_use_address (struct ivopts_data *data,
else
{
/* When we end up confused enough and have no suitable base but
- stuffed everything to index2 use a LEA for the address and
+ stuffed everything to indexes use a LEA for the address and
create a plain MEM_REF to avoid basing a memory reference
on address zero which create_mem_ref_raw does as fallback. */
if (TREE_CODE (ref) == TARGET_MEM_REF
- && TMR_INDEX2 (ref) != NULL_TREE
&& integer_zerop (TREE_OPERAND (ref, 0)))
{
ref = fold_build1 (ADDR_EXPR, TREE_TYPE (TREE_OPERAND (ref, 0)), ref);
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index 98b837be01d..a95350abccb 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -1507,6 +1507,9 @@ vn_reference_maybe_forwprop_address
(vec<vn_reference_op_s> *ops,
= wide_int_to_tree (TREE_TYPE (mem_op->op0),
wi::to_poly_wide (new_mem_op->op0));
}
+ /* Do not forward addresses of TARGET_MEM_REF. */
+ else if (tem[0].opcode == TARGET_MEM_REF)
+ return changed;
else
gcc_assert (tem.last ().opcode == STRING_CST);
ops->pop ();
--
2.51.0