public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jan Hubicka <hubicka@ucw.cz>
To: gcc-patches@gcc.gnu.org, rguenther@suse.de, d@dcepelik.cz
Subject: indirect_ref_may_alias_decl_p fix
Date: Thu, 13 Jun 2019 12:06:00 -0000	[thread overview]
Message-ID: <20190613120550.7wtzpieeszazjn7i@kam.mff.cuni.cz> (raw)

Hi,
after spending some time on the view converting MEM_REFs, I noticed that
most of reasons we give up on view converts is not actually MEM_REF created
but test
 same_type_for_tbaa (TREE_TYPE (dbase2), TREE_TYPE (base2))
in indirect_ref_may_alias_decl_p

Here base2 is VAR_DECL while dbase2 is MEM_REF used to access it.

In the testcase:
struct a {int a1; int a2;};
struct b:a {};

struct b bvar,*bptr2;
int
test(void)
{
  struct a *bptr = &bvar;
  bptr->a2=0;
  bptr2->a1=1;
  return bptr->a2;
}

We have variable of type b, while we access it via its basetype.
This mean that TREE_TYPE (base) is "struct b" while TREE_TYPE (dbase)
is "struct a" which is perfectly normal and we could to the access path
tests at least in the same strength as we would do if bptr=$bvar was 
not visible to compiler (in that case we optimize things correctly).

Of course later in aliasing_component_refs_p we should not assume that
"struct a" is the type of memory slot since the access path may contain
b, but I think we can not assume that about "struct b" either, see below.

We should not give up on this case and just proceed the same way as
indirect_refs_may_alias_p does.  In fact I would like to commonize the
access path oracle of these functions incremetally but first I want to 
drop main differences. In particular

 1) indirect_refs_may_alias_decl_p passing ref2_is_decl as true to 
    aliasing_component_refs_p.

    This makes aliasing_component_refs_p to assume that all access paths
    conflicting with REF2 must start by type of BASE2 or its subtype.

    IMO this is not quite right in gimple memory model where decls are just
    untyped memory slots, since I can, for example, I can rewrite decl
    of type a by a new data of type struct b {struct a a;};
    which will confuse this logic.

    I will try to get rid of this incrementally - I would like to have it
    logged how much optimization we lose here.

 2) indirect_refs_may_alias_decl_p does

  if ((TREE_CODE (base1) != TARGET_MEM_REF                                      
       || (!TMR_INDEX (base1) && !TMR_INDEX2 (base1)))                          
      && same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (dbase2)) == 1        
      && (TREE_CODE (TREE_TYPE (base1)) != ARRAY_TYPE                           
          || (TYPE_SIZE (TREE_TYPE (base1))                                     
              && TREE_CODE (TYPE_SIZE (TREE_TYPE (base1))) == INTEGER_CST)))    
    return ranges_maybe_overlap_p (doffset1, max_size1, doffset2, max_size2);   

     while indirect_refs_may_alias_p does:

  if ((TREE_CODE (base1) != TARGET_MEM_REF                                      
       || (!TMR_INDEX (base1) && !TMR_INDEX2 (base1)))                          
      && (TREE_CODE (base2) != TARGET_MEM_REF                                   
          || (!TMR_INDEX (base2) && !TMR_INDEX2 (base2)))                       
      && same_type_for_tbaa (TREE_TYPE (ptrtype1),                              
                             TREE_TYPE (ptrtype2)) == 1                         
      /* But avoid treating arrays as "objects", instead assume they            
         can overlap by an exact multiple of their element size.                
         See gcc.dg/torture/alias-2.c.  */                                      
      && TREE_CODE (TREE_TYPE (ptrtype1)) != ARRAY_TYPE)                        
    return ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2);     

     Sincce we already checked that TREEE_TYPE (ptrtype) is same as TREE_TYPE (base1)
     the same_type_for_tbaa check is equivalent in both.

     Notice however that first tests that array is VLA, while other
     supports partial overlaps on all array types.  I suppose we want to
     choose which way we support that and go with one or another.

     Of course even in that case overlap check is not completely lost,
     I attached testcase for that to
     https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90869
     All we need is to wrap the checks by array size.

  With these differences sorted out I think both functions may dispatch to
  common access path oracle after doing the case specific work.

Bootstrapped/regtested x86_64-linux, makes sense?

	PR tree-optimize/90869
	* tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Watch for view
	converts in MEM_REF referencing decl rather than view converts
	from decl type to MEM_REF type.

	* g++.dg/tree-ssa/alias-access-path-1.C: New testcase.
Index: tree-ssa-alias.c
===================================================================
--- tree-ssa-alias.c	(revision 272037)
+++ tree-ssa-alias.c	(working copy)
@@ -1370,11 +1410,16 @@ indirect_ref_may_alias_decl_p (tree ref1
   poly_offset_int doffset2 = offset2;
   if (TREE_CODE (dbase2) == MEM_REF
       || TREE_CODE (dbase2) == TARGET_MEM_REF)
-    doffset2 -= mem_ref_offset (dbase2) << LOG2_BITS_PER_UNIT;
+    {
+      doffset2 -= mem_ref_offset (dbase2) << LOG2_BITS_PER_UNIT;
+      tree ptrtype2 = TREE_TYPE (TREE_OPERAND (dbase2, 1));
+      /* If second reference is view-converted, give up now.  */
+      if (same_type_for_tbaa (TREE_TYPE (dbase2), TREE_TYPE (ptrtype2)) != 1)
+	return true;
+    }
 
-  /* If either reference is view-converted, give up now.  */
-  if (same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) != 1
-      || same_type_for_tbaa (TREE_TYPE (dbase2), TREE_TYPE (base2)) != 1)
+  /* If first reference is view-converted, give up now.  */
+  if (same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) != 1)
     return true;
 
   /* If both references are through the same type, they do not alias
@@ -1408,7 +1457,13 @@ indirect_ref_may_alias_decl_p (tree ref1
 				      offset1, max_size1,
 				      ref2,
 				      ref2_alias_set, base2_alias_set,
-				      offset2, max_size2, true);
+				      offset2, max_size2, 
+				      /* Only if the other reference is actual
+					 decl we can safely check only toplevel
+					 part of access path 1.  */
+				      same_type_for_tbaa (TREE_TYPE (dbase2),
+					                  TREE_TYPE (base2))
+				      == 1);
 
   return true;
 }
Index: testsuite/g++.dg/tree-ssa/alias-access-path-1.C
===================================================================
--- testsuite/g++.dg/tree-ssa/alias-access-path-1.C	(nonexistent)
+++ testsuite/g++.dg/tree-ssa/alias-access-path-1.C	(working copy)
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-fre1" } */
+
+struct a {int a1; int a2;};
+struct b:a {};
+
+struct b bvar,*bptr2;
+int
+test(void)
+{
+  struct a *bptr = &bvar;
+  bptr->a2=0;
+  bptr2->a1=1;
+  return bptr->a2;
+}
+int
+test2(void)
+{
+  struct b *bptr = &bvar;
+  bptr->a2=0;
+  bptr2->a1=1;
+  return bptr->a2;
+}
+/* { dg-final { scan-tree-dump-times "return 0" 2 "fre1" } } */

             reply	other threads:[~2019-06-13 12:06 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-13 12:06 Jan Hubicka [this message]
2019-06-13 12:15 ` Richard Biener
2019-06-13 12:29   ` Jan Hubicka
2019-06-13 20:17     ` Christophe Lyon
2019-06-13 20:28       ` Jan Hubicka
2019-06-13 20:33       ` Rainer Orth
2019-06-13 20:55         ` Jan Hubicka
2019-06-13 21:15         ` Jan Hubicka
2019-06-14  6:59           ` Rainer Orth
2019-06-14  8:00             ` Jan Hubicka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190613120550.7wtzpieeszazjn7i@kam.mff.cuni.cz \
    --to=hubicka@ucw.cz \
    --cc=d@dcepelik.cz \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=rguenther@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).