https://gcc.gnu.org/g:001fb23ae46ba4bd1b5e43f756fa89e6fb94ce18

commit r15-9268-g001fb23ae46ba4bd1b5e43f756fa89e6fb94ce18
Author: Richard Sandiford <richard.sandif...@arm.com>
Date:   Fri May 12 10:33:25 2023 +0100

    gomp: Various fixes for SVE types [PR101018]
    
    Various parts of the omp code checked whether the size of a decl
    was an INTEGER_CST in order to determine whether the decl was
    variable-sized or not.  If it was variable-sized, it was expected
    to have a DECL_VALUE_EXPR replacement, as for VLAs.
    
    This patch uses poly_int_tree_p instead, so that variable-length
    SVE vectors are treated like constant-length vectors.  This means
    that some structures become poly_int-sized, with some fields at
    poly_int offsets, but we already have code to handle that.
    
    An alternative would have been to handle the data via indirection
    instead.  However, that's likely to be more complicated, and it
    would contradict is_variable_sized, which already uses a check
    for TREE_CONSTANT rather than INTEGER_CST.
    
    gimple_add_tmp_var should probably not add a safelen of 1
    for SVE vectors, but that's really a separate thing and might
    be hard to test.
    
    Co-authored-by: Tejas Belagod <tejas.bela...@arm.com>
    
    gcc/
            PR middle-end/101018
            * poly-int.h (can_and_p): New function.
            * fold-const.cc (poly_int_binop): Use it to optimize BIT_AND_EXPRs
            involving POLY_INT_CSTs.
            * gimplify.cc (omp_notice_variable): Use poly_int_tree_p instead
            of INTEGER_CST when checking for constant-sized omp data.
            (gimplify_adjust_omp_clauses_1): Likewise.
            (gimplify_adjust_omp_clauses): Likewise.
            * omp-low.cc (scan_sharing_clauses): Likewise.

Diff:
---
 gcc/fold-const.cc |  7 +++++++
 gcc/gimplify.cc   | 19 +++++++++----------
 gcc/omp-low.cc    |  2 +-
 gcc/poly-int.h    | 19 +++++++++++++++++++
 4 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 3e20538de9fd..1275ef75315a 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -1284,6 +1284,13 @@ poly_int_binop (poly_wide_int &res, enum tree_code code,
        return false;
       break;
 
+    case BIT_AND_EXPR:
+      if (TREE_CODE (arg2) != INTEGER_CST
+         || !can_and_p (wi::to_poly_wide (arg1), wi::to_wide (arg2),
+                        &res))
+       return false;
+      break;
+
     case BIT_IOR_EXPR:
       if (TREE_CODE (arg2) != INTEGER_CST
          || !can_ior_p (wi::to_poly_wide (arg1), wi::to_wide (arg2),
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index e90220cc2a05..55cab7a74a88 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -9301,7 +9301,8 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree 
decl, bool in_code)
       && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
       && DECL_SIZE (decl))
     {
-      if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
+      tree size;
+      if (!poly_int_tree_p (DECL_SIZE (decl)))
        {
          splay_tree_node n2;
          tree t = DECL_VALUE_EXPR (decl);
@@ -9312,16 +9313,14 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree 
decl, bool in_code)
          n2->value |= GOVD_SEEN;
        }
       else if (omp_privatize_by_reference (decl)
-              && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
-              && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
-                  != INTEGER_CST))
+              && (size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
+              && !poly_int_tree_p (size))
        {
          splay_tree_node n2;
-         tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
-         gcc_assert (DECL_P (t));
-         n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
+         gcc_assert (DECL_P (size));
+         n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) size);
          if (n2)
-           omp_notice_variable (ctx, t, true);
+           omp_notice_variable (ctx, size, true);
        }
     }
 
@@ -14581,7 +14580,7 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void 
*data)
       if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
        OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause) = 1;
       if (DECL_SIZE (decl)
-         && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
+         && !poly_int_tree_p (DECL_SIZE (decl)))
        {
          tree decl2 = DECL_VALUE_EXPR (decl);
          gcc_assert (INDIRECT_REF_P (decl2));
@@ -15322,7 +15321,7 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, 
gimple_seq body, tree *list_p,
          if (!DECL_P (decl))
            break;
          if (DECL_SIZE (decl)
-             && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
+             && !poly_int_tree_p (DECL_SIZE (decl)))
            {
              tree decl2 = DECL_VALUE_EXPR (decl);
              gcc_assert (INDIRECT_REF_P (decl2));
diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
index e369df6e8f10..e1036adab288 100644
--- a/gcc/omp-low.cc
+++ b/gcc/omp-low.cc
@@ -1461,7 +1461,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
          else
            install_var_field (decl, false, 11, ctx);
          if (DECL_SIZE (decl)
-             && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
+             && !poly_int_tree_p (DECL_SIZE (decl)))
            {
              tree decl2 = DECL_VALUE_EXPR (decl);
              gcc_assert (INDIRECT_REF_P (decl2));
diff --git a/gcc/poly-int.h b/gcc/poly-int.h
index 7c8901a971a3..77f78752e74d 100644
--- a/gcc/poly-int.h
+++ b/gcc/poly-int.h
@@ -1906,6 +1906,25 @@ known_alignment (const poly_int<N, Ca> &a)
   return r & -r;
 }
 
+/* Return true if we can compute A & B at compile time, storing the
+   result in RES if so.  */
+
+template<unsigned int N, typename Ca, typename Cb, typename Cr>
+inline typename if_nonpoly<Cb, bool>::type
+can_and_p (const poly_int<N, Ca> &a, Cb b, Cr *result)
+{
+  /* Coefficients 1 and above must be a multiple of something greater
+     than ~B.  */
+  typedef POLY_INT_TYPE (Ca) int_type;
+  if (N >= 2)
+    for (unsigned int i = 1; i < N; i++)
+      if ((-(a.coeffs[i] & -a.coeffs[i]) & ~b) != int_type (0))
+       return false;
+  *result = a;
+  result->coeffs[0] &= b;
+  return true;
+}
+
 /* Return true if we can compute A | B at compile time, storing the
    result in RES if so.  */

Reply via email to