On Tue, 25 Apr 2017, Richard Biener wrote: > > The following fixes redundant hard-register "stores" to be not eliminated > by FRE/PRE and the alias machinery to properly handle different > local VAR_DECLs with the same asm specification. > > Comments are welcome. I tested the testcase on x86_64, ppc64le and > aarch64 and all seem to be happy with *4 as register specification. > > Bootstrap / regtest running on x86_64-unknown-linux-gnu.
So in bugzilla the conclusion is that the DSE is valid (for the testcase it's not because it failed to compute aliasing properly). And I can't see any reason to not do the transform (the corresponding CSE is not done to avoid increasing register pressure by increased lifetime). That is, removing a redundant setting of a hardreg reduces the lifetime of the value stored. Bootstrapped on x86_64-unknown-linux-gnu, testing still in progress. Richard. 2017-04-25 Richard Biener <rguent...@suse.de> PR tree-optimization/80492 * alias.c (compare_base_decls): Handle registers with asm specification conservatively. * tree-ssa-alias.c (decl_refs_may_alias_p): Handle compare_base_decls returning dont-know properly. * gcc.dg/pr80492.c: New testcase. Index: gcc/alias.c =================================================================== --- gcc/alias.c (revision 247147) +++ gcc/alias.c (working copy) @@ -2046,6 +2046,18 @@ compare_base_decls (tree base1, tree bas if (base1 == base2) return 1; + /* If we have two register decls with register specification we + cannot decide unless their assembler name is the same. */ + if (DECL_REGISTER (base1) + && DECL_REGISTER (base2) + && DECL_ASSEMBLER_NAME_SET_P (base1) + && DECL_ASSEMBLER_NAME_SET_P (base2)) + { + if (DECL_ASSEMBLER_NAME (base1) == DECL_ASSEMBLER_NAME (base2)) + return 1; + return -1; + } + /* Declarations of non-automatic variables may have aliases. All other decls are unique. */ if (!decl_in_symtab_p (base1) Index: gcc/passes.c =================================================================== --- gcc/passes.c (revision 247147) +++ gcc/passes.c (working copy) @@ -1532,7 +1532,7 @@ pass_manager::pass_manager (context *ctx : all_passes (NULL), all_small_ipa_passes (NULL), all_lowering_passes (NULL), all_regular_ipa_passes (NULL), all_late_ipa_passes (NULL), passes_by_id (NULL), passes_by_id_size (0), - m_ctxt (ctxt) + m_ctxt (ctxt), m_name_to_pass_map (NULL) { opt_pass **p; Index: gcc/testsuite/gcc.dg/pr80492.c =================================================================== --- gcc/testsuite/gcc.dg/pr80492.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr80492.c (working copy) @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-w -O2 -fdump-tree-optimized" } */ + +static __inline__ __attribute__((__always_inline__)) +void syscall_7 (int val) +{ + register int reg __asm ("4") = val; + __asm __volatile__ ("/* Some Code %0 */" :: "r" (reg)); +} + +void do_syscalls (void) +{ + for (int s = 0; s < 2; s++) + { + syscall_7 (0); + syscall_7 (1); + } +} + +/* { dg-final { scan-tree-dump-times "reg = " 4 "optimized" } } */ Index: gcc/tree-ssa-alias.c =================================================================== --- gcc/tree-ssa-alias.c (revision 247147) +++ gcc/tree-ssa-alias.c (working copy) @@ -1096,13 +1096,16 @@ decl_refs_may_alias_p (tree ref1, tree b { gcc_checking_assert (DECL_P (base1) && DECL_P (base2)); + int cmp = compare_base_decls (base1, base2); + /* If both references are based on different variables, they cannot alias. */ - if (compare_base_decls (base1, base2) == 0) + if (cmp == 0) return false; /* If both references are based on the same variable, they cannot alias if the accesses do not overlap. */ - if (!ranges_overlap_p (offset1, max_size1, offset2, max_size2)) + if (cmp == 1 + && !ranges_overlap_p (offset1, max_size1, offset2, max_size2)) return false; /* For components with variable position, the above test isn't sufficient,