This enables the alias machinery for WITH_SIZE_EXPR which can appear
in call LHS and arguments.  In particular this drops the NULL
return from get_base_address and it adjusts get_ref_base_and_extent
and friends to use the size information in WITH_SIZE_EXPR and
look through it for further processing.

Bootstrapped and tested on x86_64-unknown-linux-gnu, will push
later.

2021-05-19  Richard Biener  <rguent...@suse.de>

        * builtins.c (get_object_alignment_1): Strip outer
        WITH_SIZE_EXPR.
        * tree-dfa.c (get_ref_base_and_extent): Handle outer
        WITH_SIZE_EXPR for size processing and process the
        containing ref.
        * tree-ssa-alias.c (ao_ref_base_alias_set): Strip
        outer WITH_SIZE_EXPR.
        (ao_ref_base_alias_ptr_type): Likewise.
        (refs_may_alias_p_2): Allow WITH_SIZE_EXPR in ref->ref
        and handle that accordingly, stripping it for the
        core alias workers.
        * tree.c (get_base_address): Handle WITH_SIZE_EXPR by
        looking through it instead of returning NULL.
---
 gcc/builtins.c       |  4 ++++
 gcc/tree-dfa.c       |  5 +++++
 gcc/tree-ssa-alias.c | 36 ++++++++++++++++++++++++++----------
 gcc/tree.c           |  7 ++-----
 4 files changed, 37 insertions(+), 15 deletions(-)

diff --git a/gcc/builtins.c b/gcc/builtins.c
index e1b284846b1..5fd10aeccc3 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -924,6 +924,10 @@ bool
 get_object_alignment_1 (tree exp, unsigned int *alignp,
                        unsigned HOST_WIDE_INT *bitposp)
 {
+  /* Strip a WITH_SIZE_EXPR, get_inner_reference doesn't know how to deal
+     with it.  */
+  if (TREE_CODE (exp) == WITH_SIZE_EXPR)
+    exp = TREE_OPERAND (exp, 0);
   return get_object_alignment_2 (exp, alignp, bitposp, false);
 }
 
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index 0482b05e26c..c6c3bd62223 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -394,6 +394,11 @@ get_ref_base_and_extent (tree exp, poly_int64_pod *poffset,
     size_tree = DECL_SIZE (TREE_OPERAND (exp, 1));
   else if (TREE_CODE (exp) == BIT_FIELD_REF)
     size_tree = TREE_OPERAND (exp, 1);
+  else if (TREE_CODE (exp) == WITH_SIZE_EXPR)
+    {
+      size_tree = TREE_OPERAND (exp, 1);
+      exp = TREE_OPERAND (exp, 0);
+    }
   else if (!VOID_TYPE_P (TREE_TYPE (exp)))
     {
       machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 6c7d2f1b7e0..0421bfac998 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -722,6 +722,8 @@ ao_ref_base_alias_set (ao_ref *ref)
   if (!ref->ref)
     return 0;
   base_ref = ref->ref;
+  if (TREE_CODE (base_ref) == WITH_SIZE_EXPR)
+    base_ref = TREE_OPERAND (base_ref, 0);
   while (handled_component_p (base_ref))
     base_ref = TREE_OPERAND (base_ref, 0);
   ref->base_alias_set = get_alias_set (base_ref);
@@ -752,6 +754,8 @@ ao_ref_base_alias_ptr_type (ao_ref *ref)
   if (!ref->ref)
     return NULL_TREE;
   base_ref = ref->ref;
+  if (TREE_CODE (base_ref) == WITH_SIZE_EXPR)
+    base_ref = TREE_OPERAND (base_ref, 0);
   while (handled_component_p (base_ref))
     base_ref = TREE_OPERAND (base_ref, 0);
   tree ret = reference_alias_ptr_type (base_ref);
@@ -2314,14 +2318,16 @@ refs_may_alias_p_2 (ao_ref *ref1, ao_ref *ref2, bool 
tbaa_p)
                        || TREE_CODE (ref1->ref) == STRING_CST
                        || handled_component_p (ref1->ref)
                        || TREE_CODE (ref1->ref) == MEM_REF
-                       || TREE_CODE (ref1->ref) == TARGET_MEM_REF)
+                       || TREE_CODE (ref1->ref) == TARGET_MEM_REF
+                       || TREE_CODE (ref1->ref) == WITH_SIZE_EXPR)
                       && (!ref2->ref
                           || TREE_CODE (ref2->ref) == SSA_NAME
                           || DECL_P (ref2->ref)
                           || TREE_CODE (ref2->ref) == STRING_CST
                           || handled_component_p (ref2->ref)
                           || TREE_CODE (ref2->ref) == MEM_REF
-                          || TREE_CODE (ref2->ref) == TARGET_MEM_REF));
+                          || TREE_CODE (ref2->ref) == TARGET_MEM_REF
+                          || TREE_CODE (ref2->ref) == WITH_SIZE_EXPR));
 
   /* Decompose the references into their base objects and the access.  */
   base1 = ao_ref_base (ref1);
@@ -2360,6 +2366,15 @@ refs_may_alias_p_2 (ao_ref *ref1, ao_ref *ref2, bool 
tbaa_p)
       && ref2->volatile_p)
     return true;
 
+  /* refN->ref may convey size information, do not confuse our workers
+     with that but strip it - ao_ref_base took it into account already.  */
+  tree ref1ref = ref1->ref;
+  if (ref1ref && TREE_CODE (ref1ref) == WITH_SIZE_EXPR)
+    ref1ref = TREE_OPERAND (ref1ref, 0);
+  tree ref2ref = ref2->ref;
+  if (ref2ref && TREE_CODE (ref2ref) == WITH_SIZE_EXPR)
+    ref2ref = TREE_OPERAND (ref2ref, 0);
+
   /* Defer to simple offset based disambiguation if we have
      references based on two decls.  Do this before defering to
      TBAA to handle must-alias cases in conformance with the
@@ -2367,9 +2382,9 @@ refs_may_alias_p_2 (ao_ref *ref1, ao_ref *ref2, bool 
tbaa_p)
   var1_p = DECL_P (base1);
   var2_p = DECL_P (base2);
   if (var1_p && var2_p)
-    return decl_refs_may_alias_p (ref1->ref, base1, offset1, max_size1,
+    return decl_refs_may_alias_p (ref1ref, base1, offset1, max_size1,
                                  ref1->size,
-                                 ref2->ref, base2, offset2, max_size2,
+                                 ref2ref, base2, offset2, max_size2,
                                  ref2->size);
 
   /* Handle restrict based accesses.
@@ -2379,14 +2394,14 @@ refs_may_alias_p_2 (ao_ref *ref1, ao_ref *ref2, bool 
tbaa_p)
   tree rbase2 = base2;
   if (var1_p)
     {
-      rbase1 = ref1->ref;
+      rbase1 = ref1ref;
       if (rbase1)
        while (handled_component_p (rbase1))
          rbase1 = TREE_OPERAND (rbase1, 0);
     }
   if (var2_p)
     {
-      rbase2 = ref2->ref;
+      rbase2 = ref2ref;
       if (rbase2)
        while (handled_component_p (rbase2))
          rbase2 = TREE_OPERAND (rbase2, 0);
@@ -2412,6 +2427,7 @@ refs_may_alias_p_2 (ao_ref *ref1, ao_ref *ref2, bool 
tbaa_p)
       std::swap (max_size1, max_size2);
       std::swap (base1, base2);
       std::swap (ref1, ref2);
+      std::swap (ref1ref, ref2ref);
       var1_p = true;
       ind1_p = false;
       var2_p = false;
@@ -2437,21 +2453,21 @@ refs_may_alias_p_2 (ao_ref *ref1, ao_ref *ref2, bool 
tbaa_p)
 
   /* Dispatch to the pointer-vs-decl or pointer-vs-pointer disambiguators.  */
   if (var1_p && ind2_p)
-    return indirect_ref_may_alias_decl_p (ref2->ref, base2,
+    return indirect_ref_may_alias_decl_p (ref2ref, base2,
                                          offset2, max_size2, ref2->size,
                                          ao_ref_alias_set (ref2),
                                          ao_ref_base_alias_set (ref2),
-                                         ref1->ref, base1,
+                                         ref1ref, base1,
                                          offset1, max_size1, ref1->size,
                                          ao_ref_alias_set (ref1),
                                          ao_ref_base_alias_set (ref1),
                                          tbaa_p);
   else if (ind1_p && ind2_p)
-    return indirect_refs_may_alias_p (ref1->ref, base1,
+    return indirect_refs_may_alias_p (ref1ref, base1,
                                      offset1, max_size1, ref1->size,
                                      ao_ref_alias_set (ref1),
                                      ao_ref_base_alias_set (ref1),
-                                     ref2->ref, base2,
+                                     ref2ref, base2,
                                      offset2, max_size2, ref2->size,
                                      ao_ref_alias_set (ref2),
                                      ao_ref_base_alias_set (ref2),
diff --git a/gcc/tree.c b/gcc/tree.c
index 31ac4245c9c..bdb29b82303 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -12382,6 +12382,8 @@ drop_tree_overflow (tree t)
 tree
 get_base_address (tree t)
 {
+  if (TREE_CODE (t) == WITH_SIZE_EXPR)
+    t = TREE_OPERAND (t, 0);
   while (handled_component_p (t))
     t = TREE_OPERAND (t, 0);
 
@@ -12390,11 +12392,6 @@ get_base_address (tree t)
       && TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR)
     t = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
 
-  /* ???  Either the alias oracle or all callers need to properly deal
-     with WITH_SIZE_EXPRs before we can look through those.  */
-  if (TREE_CODE (t) == WITH_SIZE_EXPR)
-    return NULL_TREE;
-
   return t;
 }
 
-- 
2.26.2

Reply via email to