@@ -7941,10 +7941,10 @@ get_inner_reference (tree exp, poly_int64_pod *pbitsize,
if (size_tree != 0)
{
- if (! tree_fits_uhwi_p (size_tree))
+ if (! tree_fits_poly_uint64_p (size_tree))
mode = BLKmode, *pbitsize = -1;
else
- *pbitsize = tree_to_uhwi (size_tree);
+ *pbitsize = tree_to_poly_uint64 (size_tree);
}
*preversep = reverse_storage_order_for_component_p (exp);
@@ -1183,6 +1183,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),
@@ -7352,7 +7352,7 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
/* When adding a variable-sized variable, we have to handle all sorts
of additional bits of data: the pointer replacement variable, and
the parameters of the type. */
- if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
+ if (DECL_SIZE (decl) && !poly_int_tree_p (DECL_SIZE (decl)))
{
/* Add the pointer replacement variable as PRIVATE if the variable
replacement is private, else FIRSTPRIVATE since we'll need the
@@ -8002,7 +8002,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);
@@ -8013,16 +8014,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);
}
}
@@ -12417,7 +12416,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 (TREE_CODE (decl2) == INDIRECT_REF);
@@ -12826,7 +12825,7 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
}
}
else if (DECL_SIZE (decl)
- && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
+ && !poly_int_tree_p (DECL_SIZE (decl))
&& OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
&& OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
&& (OMP_CLAUSE_MAP_KIND (c)
@@ -12886,7 +12885,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 (TREE_CODE (decl2) == INDIRECT_REF);
@@ -1454,7 +1454,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 (TREE_CODE (decl2) == INDIRECT_REF);
@@ -1657,7 +1657,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
if (DECL_P (decl))
{
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 (TREE_CODE (decl2) == INDIRECT_REF);
@@ -1899,7 +1899,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
= remap_type (TREE_TYPE (decl), &ctx->cb);
}
else 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 (TREE_CODE (decl2) == INDIRECT_REF);
@@ -12838,7 +12838,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
}
if (DECL_SIZE (var)
- && TREE_CODE (DECL_SIZE (var)) != INTEGER_CST)
+ && !poly_int_tree_p (DECL_SIZE (var)))
{
tree var2 = DECL_VALUE_EXPR (var);
gcc_assert (TREE_CODE (var2) == INDIRECT_REF);
@@ -13165,7 +13165,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
else
{
if (DECL_SIZE (ovar)
- && TREE_CODE (DECL_SIZE (ovar)) != INTEGER_CST)
+ && !poly_int_tree_p (DECL_SIZE (ovar)))
{
tree ovar2 = DECL_VALUE_EXPR (ovar);
gcc_assert (TREE_CODE (ovar2) == INDIRECT_REF);
@@ -1977,6 +1977,25 @@ known_alignment (const poly_int_pod<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_pod<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. */
new file mode 100644
@@ -0,0 +1,27 @@
+/* { dg-options "-O -fopenmp" } */
+
+#include <stdint.h>
+#include <arm_sve.h>
+
+extern long N;
+extern double *a, *b, *c;
+
+void tuned_STREAM_Triad(double scalar)
+{
+ const uint64_t el = svcntd();
+ const svfloat64_t vscalar = svdup_n_f64(scalar);
+ const int Nadj = N/el;
+ int j;
+
+#pragma omp parallel for
+ for (j = 0; j < Nadj; j ++) {
+ svfloat64_t va, vb, vc;
+ vb = svld1_vnum_f64(svptrue_b64(), b, j);
+ vc = svld1_vnum_f64(svptrue_b64(), c, j);
+ va = svmla_f64_z(svptrue_b64(), vb , vscalar, vc );
+ svst1_vnum_f64(svptrue_b64(), a, j+0, va);
+ }
+
+ for (j = Nadj*el ; j < N ; j++)
+ a[j] = b[j] + scalar * c[j];
+}
new file mode 100644
@@ -0,0 +1,23 @@
+/* { dg-options "-O -fopenmp" } */
+
+#include <arm_sve.h>
+
+void ext(void *);
+svfloat32_t ext2();
+
+void
+foo (float32_t *ptr)
+{
+ svfloat32_t vec;
+ /* These directives are mostly nonsense, but they shouldn't ICE. */
+ #pragma omp target data use_device_addr(vec)
+ ext(&vec);
+ #pragma omp target map(to:vec)
+ ext(&vec);
+ #pragma omp target defaultmap(none) firstprivate(vec)
+ ext(&vec);
+ #pragma omp target
+ ext(&vec);
+ #pragma omp target update to(vec)
+ vec = ext2();
+}