This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR80492


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.

Richard.

2017-04-25  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/80492
	* tree-ssa-pre.c (eliminate_dom_walker::before_dom_children):
	Do not eliminate redundant hardregister stores.
	* 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/tree-ssa-pre.c
===================================================================
*** gcc/tree-ssa-pre.c	(revision 247095)
--- gcc/tree-ssa-pre.c	(working copy)
*************** eliminate_dom_walker::before_dom_childre
*** 4495,4500 ****
--- 4519,4526 ----
        if (gimple_assign_single_p (stmt)
  	  && !gimple_has_volatile_ops (stmt)
  	  && !is_gimple_reg (gimple_assign_lhs (stmt))
+ 	  && !(TREE_CODE (gimple_assign_lhs (stmt)) == VAR_DECL
+ 	       && DECL_HARD_REGISTER (gimple_assign_lhs (stmt)))
  	  && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
  	      || is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
  	{
Index: gcc/alias.c
===================================================================
*** gcc/alias.c	(revision 247095)
--- gcc/alias.c	(working copy)
*************** compare_base_decls (tree base1, tree bas
*** 2046,2051 ****
--- 2046,2063 ----
    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/tree-ssa-alias.c
===================================================================
*** gcc/tree-ssa-alias.c	(revision 247095)
--- gcc/tree-ssa-alias.c	(working copy)
*************** decl_refs_may_alias_p (tree ref1, tree b
*** 1096,1116 ****
  {
    gcc_checking_assert (DECL_P (base1) && DECL_P (base2));
  
    /* If both references are based on different variables, they cannot alias.  */
!   if (compare_base_decls (base1, base2) == 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))
!     return false;
  
!   /* For components with variable position, the above test isn't sufficient,
!      so we disambiguate component references manually.  */
!   if (ref1 && ref2
!       && handled_component_p (ref1) && handled_component_p (ref2)
!       && nonoverlapping_component_refs_of_decl_p (ref1, ref2))
!     return false;
  
    return true;     
  }
--- 1128,1153 ----
  {
    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 (cmp == 0)
      return false;
  
    /* If both references are based on the same variable, they cannot alias if
       the accesses do not overlap.  */
!   if (cmp == 1)
!     {
!       if (!ranges_overlap_p (offset1, max_size1, offset2, max_size2))
! 	return false;
  
!       /* For components with variable position, the above test isn't sufficient,
! 	 so we disambiguate component references manually.  */
!       if (ref1 && ref2
! 	  && handled_component_p (ref1) && handled_component_p (ref2)
! 	  && nonoverlapping_component_refs_of_decl_p (ref1, ref2))
! 	return false;
!     }
  
    return true;     
  }
Index: gcc/testsuite/gcc.dg/pr80492.c
===================================================================
*** gcc/testsuite/gcc.dg/pr80492.c	(nonexistent)
--- gcc/testsuite/gcc.dg/pr80492.c	(working copy)
***************
*** 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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]