I was looking again at: http://gcc.gnu.org/ml/gcc-patches/2010-08/msg00294.html
and was comparing the RTL {true,output,anti}_dependence functions. output_dependence and anti_dependence call fixed_scalar_and_varying_struct_p with rtx_addr_varies_p. Many places also call true_dependence with rtx_addr_varies_p (which then gets passed to fixed_scalar_and_varying_struct_p). But this doesn't seem to make much sense. rtx_addr_varies_p checks whether an rtx X includes a MEM with a varying address, whereas fixed_scalar_and_varying_struct_p passes an _address_ rather than a MEM. So in these cases fixed_scalar_and_varying_struct_p effectively becomes a no-op on targets that don't allow MEMs in addresses and takes on suspicious semantics for those that do. In the former case, every address is treated as "unvarying" and f_s_a_v_s_p always returns null. In the latter case, things like REG addresses are (wrongly) treated as unvarying while a MEM address might correctly be treated as varying, leading to false positives. It looks like this goes back to when fixed_scalar_and_varying_struct_p was added in r24759 (1999). The anti_dependence change went from applying rtx_addr_varies_p to the MEM to applying rtx_addr_varies_p to the address: @@ -1234,16 +1279,25 @@ anti_dependence (mem, x) x_addr = XEXP (x, 0); mem_addr = XEXP (mem, 0); - return (memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr, - SIZE_FOR_MODE (x), x_addr, 0) - && ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem) - && GET_MODE (mem) != QImode - && GET_CODE (mem_addr) != AND - && ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x)) - && ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x) - && GET_MODE (x) != QImode - && GET_CODE (x_addr) != AND - && ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem))); + if (!memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr, + SIZE_FOR_MODE (x), x_addr, 0)) + return 0; + + fixed_scalar + = fixed_scalar_and_varying_struct_p (mem, x, rtx_addr_varies_p); + + return (!(fixed_scalar == mem && !aliases_everything_p (x)) + && !(fixed_scalar == x && !aliases_everything_p (mem))); This seems to have percolated into: expr.c:safe_from_p gcse.c:mems_conflict_for_gcse_p gcse.c:compute_transp postreload.c:find_mem_conflicts store-motion.c:load_kills_store which all pass rtx_addr_varies_p to true_dependence. AIUI, the true_dependence varies_p parameter exists for the benefit of CSE, so that it can use its local cse_rtx_varies_p function. All other callers should be using rtx_varies_p instead. Question is, should I make that change, or is it time to get rid of fixed_scalar_and_varying_struct_p instead? Richard