public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 00/11] AArch64/OpenMP: Test SVE ACLE types with various OpenMP constructs.
@ 2024-05-27  5:06 Tejas Belagod
  2024-05-27  5:06 ` [PATCH 01/11] OpenMP/PolyInt: Pass poly-int structures by address to OMP libs Tejas Belagod
                   ` (12 more replies)
  0 siblings, 13 replies; 22+ messages in thread
From: Tejas Belagod @ 2024-05-27  5:06 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tejas Belagod, richard.sandiford, jakub

Note: This patch series is based on Richard's initial patch
  https://gcc.gnu.org/pipermail/gcc-patches/2022-November/606741.html
and Jakub's suggestion
  https://gcc.gnu.org/pipermail/gcc-patches/2023-February/611892.html

The following patch series handles various scenarios with OpenMP and SVE types.
The starting point for the series follows a suggestion from Jakub to cover all 
the possible scenarios that could arise when OMP constructs/clauses etc are 
used with SVE ACLE types. Here are a few instances that this patch series tests
and in some cases fixes the expected output.  This patch series does not follow
a formal definition or a spec of how OMP interacts with SVE ACLE types, so it's 
more of a proposed behaviour.  Comments and discussion welcome.

This list is not exhaustive, but covers most scenarios of how SVE ACLE types
ought to interact with OMP constructs/clauses.

1. Poly-int structures that represent variable-sized objects and OMP runtime.

Currently poly-int type structures are passed by value to OpenMP runtime
functions for shared clauses etc.  This patch improves on this by passing
around poly-int structures by address to avoid copy-overhead.

2. SVE ACLE types in OMP Shared clauses.

We test the behaviour where SVE ACLE type objects are shared in the following
methods into an OMP region:
  a. Explicit Shared clause on SVE ACLE type objects.
  b. Implicit shared clause.
  c. Implicit shared with default clause.
  d. SVE ALCE types in the presence of predetermined (static) shared objects.

The associated tests ensure that all such shared objects are passed by address
into the OMP runtime.  There are runtime tests to verify the functional
correctness of the change.

3. Offloading and SVE ACLE types.

The target clause in OpenMP is used to offload loop kernels to accelerator
peripeherals.  target's 'map' clause is used to move data from and to the 
accelarator.  When the data is SVE type, it may not be suitable because of
various reasons i.e. the two SVE targets may not agree on vector size or
some targets don't support variable vector size.  This makes SVE unsuitable
for use in OMP's 'map' clause.  We diagnose all such cases and issue errors
where appropriate.  The cases we cover in this patch are:

  a. Implicitly-mapped SVE ACLE types in OMP target regions are diagnosed.
  b. Explicitly-mapped SVE ACLE types in OMP target regions using map clause
     are diagnosed.
  c. Explicilty-mapped SVLE ACLE types of various directions - to, from, tofrom
     in the map clause are diagnosed.
  d. target enter and exit data clauses with map on SVE ACLE types are 
     diagnosed.
  e. target data map with alloc on SVE ACLE types are diagnosed.
  f. target update from clause on SVE ACLE types are diagnosed.
  g. target private firstprivate with SVE ACLE types are diagnosed.
  h. All combinations of target with work-sharing constructs like parallel,
     loop, simd, teams, distribute etc are also diagnosed when SVE ACLE types
     are involved.

3. Lastprivate and SVE ACLE types.

Various OpenMP lastprivate clause scenarios with SVE object types are 
diagnosed.  Worksharing constructs like sections, for, distribute bind to an
implicit outer parallel region in whose scope SVE ACLE types are declared and 
are therefore default private.  The lastprivate clause list with SVE ACLE type
object items are diagnosed in this scenario.

4. Threadprivate on SVE ACLE type objects.

We ensure threadprivate SVE ACLE type objects are supported. We also ensure
copyin clause is also supported.

5. User-Defined Reductions on SVE ACLE types.

We define a reduction using OMP declare reduction using SVE ACLE intrinsics and
ensure its functional correctness with various work-sharing constructs like
for, simd, parallel, task, taskloop.

6. Uniform and Aligned Clause with SVE ACLE

We ensure the uniform clause's functional correctness with simd construct and
associated SVE ACLE intrinsics in the simd region.  There is no direct
interaction between uniform and SVE ACLE type objects, but we ensure the uniform
clause applies correctly to a region where SVE ACLE intrinsics are present.
Similarly for the aligned clause.

7. Linear clause and SVE ACLE type.

We diagnose if a linear clause list item has SVE ACLE type objects present.
Its doesn't mean much if the linear clause is applied to SVE ACLE types.

8. Depend clause and SVE ACLE objects.

We test for functional correctness many combinations of dependency of shared
SVE ACLE type objects in parallel regions.  We test if in, out dependencies and
anti-dependencies are supported for SVE ACLE type objects using the depend
clause with work-sharing constructs like task.

9. 'doacross' clause and SVE ACLE object types.

doacross is mainly supported for scalars and loop iteration variables.  We
diagnose cases where SVE ACLE objects are used in doacross list items.

Tejas Belagod (11):
  OpenMP/PolyInt: Pass poly-int structures by address to OMP libs.
  AArch64: Add test cases for SVE types in OpenMP shared clause.
  AArch64: Diagnose OpenMP offloading when SVE types involved.
  AArch64: Test OpenMP lastprivate clause for various constructs.
  AArch64: Test OpenMP threadprivate clause on SVE type.
  AArch64: Test OpenMP user-defined reductions with SVE types.
  AArch64: Test OpenMP uniform clause on SVE types.
  AArch64: Test OpenMP simd aligned clause with SVE types.
  AArch64: Diagnose OpenMP linear clause for SVE type objects.
  AArch64: Test OpenMP depend clause and its variations on SVE types
  AArch64: Diagnose SVE type objects when applied to OpenMP doacross
    clause.

 gcc/config/aarch64/aarch64-sve-builtins.cc    |  31 +++
 gcc/gimplify.cc                               |  34 ++-
 gcc/omp-low.cc                                |   3 +-
 gcc/target.h                                  |  19 +-
 .../aarch64/sve/omp/aarch64-sve-omp.exp       |  80 ++++++
 .../gcc.target/aarch64/sve/omp/depend-1.c     | 223 ++++++++++++++++
 .../gcc.target/aarch64/sve/omp/doacross.c     |  22 ++
 .../gcc.target/aarch64/sve/omp/lastprivate.c  | 121 +++++++++
 .../gcc.target/aarch64/sve/omp/linear.c       |  33 +++
 .../gcc.target/aarch64/sve/omp/offload-1.c    | 237 ++++++++++++++++++
 .../gcc.target/aarch64/sve/omp/offload-2.c    | 198 +++++++++++++++
 .../aarch64/sve/omp/offload-parallel-loop.c   | 236 +++++++++++++++++
 .../aarch64/sve/omp/offload-parallel.c        | 195 ++++++++++++++
 .../gcc.target/aarch64/sve/omp/offload-simd.c | 236 +++++++++++++++++
 .../sve/omp/offload-teams-distribute-simd.c   | 237 ++++++++++++++++++
 .../sve/omp/offload-teams-distribute.c        | 236 +++++++++++++++++
 .../aarch64/sve/omp/offload-teams-loop.c      | 237 ++++++++++++++++++
 .../aarch64/sve/omp/offload-teams.c           | 195 ++++++++++++++
 .../gcc.target/aarch64/sve/omp/shared.c       | 186 ++++++++++++++
 .../gcc.target/aarch64/sve/omp/simd-aligned.c |  50 ++++
 .../gcc.target/aarch64/sve/omp/simd-uniform.c |  71 ++++++
 .../aarch64/sve/omp/target-device.c           |  97 +++++++
 .../gcc.target/aarch64/sve/omp/target-link.c  |  48 ++++
 .../aarch64/sve/omp/threadprivate.c           |  44 ++++
 .../gcc.target/aarch64/sve/omp/udr-sve.c      | 166 ++++++++++++
 25 files changed, 3232 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/aarch64-sve-omp.exp
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/depend-1.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/doacross.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/lastprivate.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/linear.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-1.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-2.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel-loop.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-simd.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute-simd.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-loop.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/shared.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/simd-aligned.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/simd-uniform.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/target-device.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/target-link.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/threadprivate.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/udr-sve.c

-- 
2.25.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 01/11] OpenMP/PolyInt: Pass poly-int structures by address to OMP libs.
  2024-05-27  5:06 [PATCH 00/11] AArch64/OpenMP: Test SVE ACLE types with various OpenMP constructs Tejas Belagod
@ 2024-05-27  5:06 ` Tejas Belagod
  2024-05-30 12:58   ` Richard Sandiford
  2024-05-27  5:06 ` [PATCH 02/11] AArch64: Add test cases for SVE types in OpenMP shared clause Tejas Belagod
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 22+ messages in thread
From: Tejas Belagod @ 2024-05-27  5:06 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tejas Belagod, richard.sandiford, jakub

Currently poly-int type structures are passed by value to OpenMP runtime
functions for shared clauses etc.  This patch improves on this by passing
around poly-int structures by address to avoid copy-overhead.

gcc/ChangeLog
	* omp-low.c (use_pointer_for_field): Use pointer if the OMP data
	structure's field type is a poly-int.
---
 gcc/omp-low.cc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
index 1a65229cc37..b15607f4ef5 100644
--- a/gcc/omp-low.cc
+++ b/gcc/omp-low.cc
@@ -466,7 +466,8 @@ static bool
 use_pointer_for_field (tree decl, omp_context *shared_ctx)
 {
   if (AGGREGATE_TYPE_P (TREE_TYPE (decl))
-      || TYPE_ATOMIC (TREE_TYPE (decl)))
+      || TYPE_ATOMIC (TREE_TYPE (decl))
+      || POLY_INT_CST_P (DECL_SIZE (decl)))
     return true;
 
   /* We can only use copy-in/copy-out semantics for shared variables
-- 
2.25.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 02/11] AArch64: Add test cases for SVE types in OpenMP shared clause.
  2024-05-27  5:06 [PATCH 00/11] AArch64/OpenMP: Test SVE ACLE types with various OpenMP constructs Tejas Belagod
  2024-05-27  5:06 ` [PATCH 01/11] OpenMP/PolyInt: Pass poly-int structures by address to OMP libs Tejas Belagod
@ 2024-05-27  5:06 ` Tejas Belagod
  2024-05-30 12:38   ` Richard Sandiford
  2024-05-27  5:06 ` [PATCH 03/11] AArch64: Diagnose OpenMP offloading when SVE types involved Tejas Belagod
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 22+ messages in thread
From: Tejas Belagod @ 2024-05-27  5:06 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tejas Belagod, richard.sandiford, jakub

This patch tests various shared clauses with SVE types.  It also adds a test
scaffold to run OpenMP tests in under the gcc.target testsuite.

gcc/testsuite/ChangeLog:

	* gcc.target/aarch64/sve/omp/aarch64-sve-omp.exp: New scaffold.
	* gcc/testsuite/gcc.target/aarch64/sve/omp/shared.c: New test.
---
 .../aarch64/sve/omp/aarch64-sve-omp.exp       |  80 ++++++++
 .../gcc.target/aarch64/sve/omp/shared.c       | 186 ++++++++++++++++++
 2 files changed, 266 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/aarch64-sve-omp.exp
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/shared.c

diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/aarch64-sve-omp.exp b/gcc/testsuite/gcc.target/aarch64/sve/omp/aarch64-sve-omp.exp
new file mode 100644
index 00000000000..1997c80c334
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/aarch64-sve-omp.exp
@@ -0,0 +1,80 @@
+# Copyright (C) 2006-2024 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Exit immediately if this isn't an AArch64 target.
+if {![istarget aarch64*-*-*] } then {
+  return
+}
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+if ![check_effective_target_fopenmp] {
+  return
+}
+
+proc omp_link_flags { } {
+    global ld_library_path
+    global TOOL_OPTIONS
+
+    set flags ""
+
+    if ![is_remote host] {
+	if [info exists TOOL_OPTIONS] {
+	    set gccpath "[get_multilibs ${TOOL_OPTIONS}]"
+	} else {
+	    set gccpath "[get_multilibs]"
+	}
+    }
+
+    if { $gccpath != "" } {
+      if [file exists "${gccpath}/libgomp/libgomp.spec"] {
+	  append flags "-B${gccpath}/libgomp/ -L${gccpath}/libgomp/.libs -I${gccpath}/libgomp/"
+	  append ld_library_path ":${gccpath}/libgomp/.libs"
+      }
+    } else {
+      global tool_root_dir
+
+      set libgomp [lookfor_file ${tool_root_dir} libgomp]
+      if { $libgomp != "" } {
+          append flags "-L${libgomp} -B${libgomp}"
+          append ld_library_path ":${libgomp}"
+      }
+    }
+
+    set_ld_library_path_env_vars
+
+    return "$flags"
+}
+
+if { [check_effective_target_aarch64_sve] } {
+    set sve_flags ""
+} else {
+    set sve_flags "-march=armv8.2-a+sve"
+}
+
+# Main loop.
+dg-runtest [lsort [find $srcdir/$subdir *.c]] "[omp_link_flags] $sve_flags -fopenmp" ""
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/shared.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/shared.c
new file mode 100644
index 00000000000..3f380d95da4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/shared.c
@@ -0,0 +1,186 @@
+/* { dg-do run { target aarch64_sve256_hw } } */
+/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
+
+#include <arm_sve.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+svint32_t
+__attribute__ ((noinline))
+explicit_shared (svint32_t a, svint32_t b, svbool_t p)
+{
+
+#pragma omp parallel shared (a, b, p) num_threads (1)
+  {
+    /* 'a', 'b' and 'p' are explicitly shared.  */
+    a = svadd_s32_z (p, a, b);
+  }
+
+#pragma omp parallel shared (a, b, p) num_threads (1)
+  {
+    a = svadd_s32_z (p, a, b);
+  }
+
+  return a;
+}
+
+svint32_t
+__attribute__ ((noinline))
+implicit_shared_default (svint32_t a, svint32_t b, svbool_t p)
+{
+
+#pragma omp parallel default (shared) num_threads (1)
+  {
+    /* 'a', 'b' and 'p' are implicitly shared.  */
+    a = svadd_s32_z (p, a, b);
+  }
+
+#pragma omp parallel default (shared) num_threads (1)
+  {
+    a = svadd_s32_z (p, a, b);
+  }
+
+  return a;
+}
+
+svint32_t
+__attribute__ ((noinline))
+implicit_shared_no_default (svint32_t a, svint32_t b, svbool_t p)
+{
+
+#pragma omp parallel num_threads (1)
+  {
+    /* 'a', 'b' and 'p' are implicitly shared without default clause.  */
+    a = svadd_s32_z (p, a, b);
+  }
+
+#pragma omp parallel num_threads (1)
+  {
+    a = svadd_s32_z (p, a, b);
+  }
+
+  return a;
+}
+
+svint32_t
+__attribute__ ((noinline))
+mix_shared (svint32_t b, svbool_t p)
+{
+
+  svint32_t a;
+  int32_t *m = (int32_t *)malloc (8 * sizeof (int32_t));
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < 8; i++)
+    m[i] = i;
+
+#pragma omp parallel
+  {
+    /* 'm' is predetermined shared here.  'a' is implicitly shared here.  */
+    a = svld1_s32 (svptrue_b32 (), m);
+  }
+
+#pragma omp parallel num_threads (1)
+  {
+    /* 'a', 'b' and 'p' are implicitly shared here.  */
+    a = svadd_s32_z (p, a, b);
+  }
+
+#pragma omp parallel shared (a, b, p) num_threads (1)
+  {
+    /* 'a', 'b' and 'p' are explicitly shared here.  */
+    a = svadd_s32_z (p, a, b);
+  }
+
+  return a;
+}
+
+void
+__attribute__ ((noinline))
+predetermined_shared_static (bool x)
+{
+
+  int32_t *m = (int32_t *)malloc (8 * sizeof (int32_t));
+  int i;
+
+#pragma omp parallel for
+  /* 'm' is predetermined shared here.  */
+  for (i = 0; i < 8; i++)
+  {
+    m[i] = i;
+  }
+
+#pragma omp parallel
+  {
+    /* 'a' is predetermined shared here.  */
+    static int64_t n;
+    svint32_t a;
+    #pragma omp parallel
+    {
+      /* 'n' is predetermined shared here.  */
+      if (x)
+	{
+	  a = svld1_s32 (svptrue_b32 (), m);
+	  n = svaddv_s32 (svptrue_b32 (), a);
+	}
+      if (!x && n != 28)
+        __builtin_abort ();
+    }
+  }
+}
+
+svint32_t
+__attribute__ ((noinline))
+foo (svint32_t a, svint32_t b, svbool_t p)
+{
+  a = svadd_s32_z (p, a, b);
+  a = svadd_s32_z (p, a, b);
+  return a;
+}
+
+void compare_vec (svint32_t x, svint32_t y)
+{
+  svbool_t p = svnot_b_z (svptrue_b32 (), svcmpeq_s32 (svptrue_b32 (), x, y));
+
+  if (svptest_any (svptrue_b32 (), p))
+    __builtin_abort ();
+}
+
+int
+main ()
+{
+  svint32_t x = svindex_s32 (0 ,1);
+  svint32_t y = svindex_s32 (8, 1);
+  svint32_t a, b;
+  svbool_t p;
+
+  /* Implicit shared.  */
+  a = foo (x, y, p);
+  b = implicit_shared_default (x, y, p);
+  compare_vec (a, b);
+
+  /* Explicit shared.  */
+  a = foo (x ,y, p);
+  b = explicit_shared (x, y, p);
+  compare_vec (a, b);
+
+  /* Implicit shared with no default clause.  */
+  a = foo (x ,y, p);
+  b = implicit_shared_no_default (x, y, p);
+  compare_vec (a, b);
+
+  /* Mix shared.  */
+  a = foo (x ,y, p);
+  b = mix_shared (y, p);
+  compare_vec (a, b);
+
+  /* Predetermined shared.  */
+  predetermined_shared_static (true);
+  predetermined_shared_static (false);
+
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "value-expr: \*.omp_data_i->a" 10 "ompexp" } } */
-- 
2.25.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 03/11] AArch64: Diagnose OpenMP offloading when SVE types involved.
  2024-05-27  5:06 [PATCH 00/11] AArch64/OpenMP: Test SVE ACLE types with various OpenMP constructs Tejas Belagod
  2024-05-27  5:06 ` [PATCH 01/11] OpenMP/PolyInt: Pass poly-int structures by address to OMP libs Tejas Belagod
  2024-05-27  5:06 ` [PATCH 02/11] AArch64: Add test cases for SVE types in OpenMP shared clause Tejas Belagod
@ 2024-05-27  5:06 ` Tejas Belagod
  2024-05-30 12:50   ` Richard Sandiford
  2024-05-27  5:06 ` [PATCH 04/11] AArch64: Test OpenMP lastprivate clause for various constructs Tejas Belagod
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 22+ messages in thread
From: Tejas Belagod @ 2024-05-27  5:06 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tejas Belagod, richard.sandiford, jakub, Andrea Corallo

The target clause in OpenMP is used to offload loop kernels to accelarator
peripeherals.  target's 'map' clause is used to move data from and to the
accelarator.  When the data is SVE type, it may not be suitable because of
various reasons i.e. the two SVE targets may not agree on vector size or
some targets don't support variable vector size.  This makes SVE unsuitable
for use in OMP's 'map' clause.  This patch diagnoses all such cases and issues
an error where SVE types are not suitable.

Co-authored-by: Andrea Corallo <andrea.corallo@arm.com>

gcc/ChangeLog:

	* target.h (type_context_kind): Add new context kinds for target clauses.
	* config/aarch64/aarch64-sve-builtins.cc (verify_type_context): Diagnose
	SVE types for a given OpenMP context.
	* gimplify.cc (omp_notice_variable):  Diagnose implicitly-mapped SVE
	objects in OpenMP regions.
	(gimplify_scan_omp_clauses): Diagnose SVE types for various target
	clauses.

gcc/testsuite/ChangeLog:

	* gcc.target/aarch64/sve/omp/offload-1.c: New test.
	* gcc.target/aarch64/sve/omp/offload-2.c: Likewise.
	* gcc.target/aarch64/sve/omp/offload-parallel-loop.c: Likewise.
	* gcc.target/aarch64/sve/omp/offload-parallel.c: Likewise.
	* gcc.target/aarch64/sve/omp/offload-simd.c: Likewise.
	* gcc.target/aarch64/sve/omp/offload-teams-distribute-simd.c: Likewise.
	* gcc.target/aarch64/sve/omp/offload-teams-distribute.c: Likewise.
	* gcc.target/aarch64/sve/omp/offload-teams-loop.c: Likewise.
	* gcc.target/aarch64/sve/omp/offload-teams.c: Likewise.
	* gcc.target/aarch64/sve/omp/target-device.c: Likewise.
	* gcc.target/aarch64/sve/omp/target-link.c: Likewise.
---
 gcc/config/aarch64/aarch64-sve-builtins.cc    |  31 +++
 gcc/gimplify.cc                               |  34 ++-
 gcc/target.h                                  |  19 +-
 .../gcc.target/aarch64/sve/omp/offload-1.c    | 237 ++++++++++++++++++
 .../gcc.target/aarch64/sve/omp/offload-2.c    | 198 +++++++++++++++
 .../aarch64/sve/omp/offload-parallel-loop.c   | 236 +++++++++++++++++
 .../aarch64/sve/omp/offload-parallel.c        | 195 ++++++++++++++
 .../gcc.target/aarch64/sve/omp/offload-simd.c | 236 +++++++++++++++++
 .../sve/omp/offload-teams-distribute-simd.c   | 237 ++++++++++++++++++
 .../sve/omp/offload-teams-distribute.c        | 236 +++++++++++++++++
 .../aarch64/sve/omp/offload-teams-loop.c      | 237 ++++++++++++++++++
 .../aarch64/sve/omp/offload-teams.c           | 195 ++++++++++++++
 .../aarch64/sve/omp/target-device.c           |  97 +++++++
 .../gcc.target/aarch64/sve/omp/target-link.c  |  48 ++++
 14 files changed, 2234 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-1.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-2.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel-loop.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-simd.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute-simd.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-loop.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/target-device.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/target-link.c

diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc
index f3983a123e3..ee1064c3bb7 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins.cc
@@ -5000,6 +5000,29 @@ bool
 verify_type_context (location_t loc, type_context_kind context,
 		     const_tree type, bool silent_p)
 {
+  if (aarch64_sve::builtin_type_p (type)
+      || (POINTER_TYPE_P (type)
+	  && aarch64_sve::builtin_type_p (TREE_TYPE (type))))
+    switch (context)
+    {
+      case TCTX_OMP_MAP:
+	error_at (loc, "SVE type %qT not allowed in map clause", type);
+	return false;
+      case TCTX_OMP_MAP_IMP_REF:
+	return false;
+      case TCTX_OMP_PRIVATE:
+	error_at (loc, "SVE type %qT not allowed in target private clause", type);
+	return false;
+      case TCTX_OMP_FIRSTPRIVATE:
+	error_at (loc, "SVE type %qT not allowed in target firstprivate clause", type);
+	return false;
+      case TCTX_OMP_DEVICE_ADDR:
+	error_at (loc, "SVE type %qT not allowed in target device clauses", type);
+	return false;
+      default:
+	break;
+    }
+
   if (!sizeless_type_p (type))
     return true;
 
@@ -5060,6 +5083,14 @@ verify_type_context (location_t loc, type_context_kind context,
       if (!silent_p)
 	error_at (loc, "capture by copy of SVE type %qT", type);
       return false;
+
+    case TCTX_OMP_MAP:
+    case TCTX_OMP_MAP_IMP_REF:
+    case TCTX_OMP_PRIVATE:
+    case TCTX_OMP_FIRSTPRIVATE:
+    case TCTX_OMP_DEVICE_ADDR:
+    default:
+      break;
     }
   gcc_unreachable ();
 }
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index d87eb433395..dc958d2f55d 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -8349,11 +8349,13 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
 			  | GOVD_MAP_ALLOC_ONLY)) == flags)
 	    {
 	      tree type = TREE_TYPE (decl);
+	      location_t dummy = UNKNOWN_LOCATION;
 
 	      if (gimplify_omp_ctxp->target_firstprivatize_array_bases
 		  && omp_privatize_by_reference (decl))
 		type = TREE_TYPE (type);
-	      if (!omp_mappable_type (type))
+	      if (!omp_mappable_type (type)
+		  || !verify_type_context (dummy, TCTX_OMP_MAP_IMP_REF, type))
 		{
 		  error ("%qD referenced in target region does not have "
 			 "a mappable type", decl);
@@ -12083,6 +12085,8 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
       unsigned int flags;
       tree decl;
       auto_vec<omp_addr_token *, 10> addr_tokens;
+      tree op = NULL_TREE;
+      location_t loc = OMP_CLAUSE_LOCATION (c);
 
       if (grp_end && c == OMP_CLAUSE_CHAIN (grp_end))
 	{
@@ -12090,6 +12094,34 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
 	  grp_end = NULL_TREE;
 	}
 
+      if (code == OMP_TARGET || code == OMP_TARGET_DATA
+	  || code == OMP_TARGET_ENTER_DATA || code == OMP_TARGET_EXIT_DATA)
+	/* Do some target-specific type checks for map operands.  */
+	switch (OMP_CLAUSE_CODE (c))
+	  {
+	  case OMP_CLAUSE_MAP:
+	    op = OMP_CLAUSE_OPERAND (c, 0);
+	    verify_type_context (loc, TCTX_OMP_MAP, TREE_TYPE (op));
+	    break;
+	  case OMP_CLAUSE_PRIVATE:
+	    op = OMP_CLAUSE_OPERAND (c, 0);
+	    verify_type_context (loc, TCTX_OMP_PRIVATE, TREE_TYPE (op));
+	    break;
+	  case OMP_CLAUSE_FIRSTPRIVATE:
+	    op = OMP_CLAUSE_OPERAND (c, 0);
+	    verify_type_context (loc, TCTX_OMP_FIRSTPRIVATE, TREE_TYPE (op));
+	    break;
+	  case OMP_CLAUSE_IS_DEVICE_PTR:
+	  case OMP_CLAUSE_USE_DEVICE_ADDR:
+	  case OMP_CLAUSE_USE_DEVICE_PTR:
+	  case OMP_CLAUSE_HAS_DEVICE_ADDR:
+	    op = OMP_CLAUSE_OPERAND (c, 0);
+	    verify_type_context (loc, TCTX_OMP_DEVICE_ADDR, TREE_TYPE (op));
+	    break;
+	  default:
+	    break;
+	  }
+
       switch (OMP_CLAUSE_CODE (c))
 	{
 	case OMP_CLAUSE_PRIVATE:
diff --git a/gcc/target.h b/gcc/target.h
index c1f99b97b86..9cebd354fdb 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -271,7 +271,24 @@ enum type_context_kind {
   TCTX_EXCEPTIONS,
 
   /* Capturing objects of type T by value in a closure.  */
-  TCTX_CAPTURE_BY_COPY
+  TCTX_CAPTURE_BY_COPY,
+
+  /* Objects of type T appearing in OpenMP map clause.  */
+  TCTX_OMP_MAP,
+
+  /* Objects of type T appearing in OpenMP target region
+     without explicit map.  */
+  TCTX_OMP_MAP_IMP_REF,
+
+  /* Objects of type T appearing in OpenMP private clause.  */
+  TCTX_OMP_PRIVATE,
+
+  /* Objects of type T appearing in OpenMP firstprivate clause.  */
+  TCTX_OMP_FIRSTPRIVATE,
+
+  /* Objects of type T appearing in OpenMP device clauses.  */
+  TCTX_OMP_DEVICE_ADDR
+
 };
 
 enum poly_value_estimate_kind
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-1.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-1.c
new file mode 100644
index 00000000000..20dd478e079
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-1.c
@@ -0,0 +1,237 @@
+/* { dg-do compile } */
+/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
+
+#include <arm_sve.h>
+
+#define N 256
+
+#ifndef CONSTRUCT
+#define CONSTRUCT
+#endif
+
+svint32_t
+__attribute__ ((noinline))
+omp_target ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+    }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_data_map_1 ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+    }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_data_map_2 ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+    }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(tofrom: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, va);
+      va = svadd_s32_z (svptrue_b32 (), vc, va);
+    }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_map_data_enter_exit ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target enter data map(to: b, c)
+
+#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc);
+      }
+
+#pragma omp target CONSTRUCT map(to: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, va);
+	va = svadd_s32_z (svptrue_b32 (), vc, va);
+      }
+
+#pragma omp target exit data map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_map_data_alloc_update ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target data map(to: b, c) map(alloc: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+{
+#pragma omp target CONSTRUCT
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+      }
+
+/* Update va on the host from target.  */
+#pragma omp target update from(va)
+
+#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, va);
+	va = svadd_s32_z (svptrue_b32 (), vc, va);
+      }
+}
+  return va;
+}
+
+int64_t __attribute__ ((noinline))
+omp_target_private ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int64_t res;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT private (va, vb, vc) map (to: b, c) map (from: res) /* { dg-error {SVE type 'svint32_t' not allowed in target private clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b);
+      vc = svld1_s32 (svptrue_b32 (), c);
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+      res = svaddv_s32 (svptrue_b32 (), va);
+    }
+
+  return res;
+}
+
+int64_t __attribute__ ((noinline))
+omp_target_firstprivate (svbool_t vp)
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int64_t res;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT firstprivate (vp) map (to: b, c) map (from: res)/* { dg-error {SVE type 'svbool_t' not allowed in target firstprivate clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (vp, b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (vp, c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (vp, vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+      res = svaddv_s32 (svptrue_b32 (), va);
+    }
+
+  return res;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-2.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-2.c
new file mode 100644
index 00000000000..efb4d274de8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-2.c
@@ -0,0 +1,198 @@
+/* { dg-do compile } */
+/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
+
+#include <arm_sve.h>
+
+#define N 256
+
+#ifndef CONSTRUCT
+#define CONSTRUCT
+#endif
+
+svint32_t
+__attribute__ ((noinline))
+omp_target ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+      }
+  }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_data_map_1 ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc);
+      }
+  }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_data_map_2 ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+
+#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc);
+      }
+  }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(tofrom: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, va);
+	va = svadd_s32_z (svptrue_b32 (), vc, va);
+      }
+  }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_map_data_enter_exit ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target enter data map(to: b, c)
+
+#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc);
+      }
+  }
+
+#pragma omp target CONSTRUCT map(to: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, va);
+	va = svadd_s32_z (svptrue_b32 (), vc, va);
+      }
+  }
+
+#pragma omp target exit data map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_map_data_alloc_update ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target data map(to: b, c) map(alloc: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+{
+#pragma omp target CONSTRUCT
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+      }
+  }
+
+/* Update va on the host from target.  */
+#pragma omp target update from(va)
+
+#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, va);
+	va = svadd_s32_z (svptrue_b32 (), vc, va);
+      }
+  }
+}
+  return va;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel-loop.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel-loop.c
new file mode 100644
index 00000000000..4c6a0d4d96a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel-loop.c
@@ -0,0 +1,236 @@
+/* { dg-do compile } */
+/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
+
+#include <arm_sve.h>
+
+#define N 256
+#define CONSTRUCT parallel loop
+
+svint32_t
+__attribute__ ((noinline))
+omp_target ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+    }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_data_map_1 ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+    }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_data_map_2 ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+    }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(tofrom: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, va);
+      va = svadd_s32_z (svptrue_b32 (), vc, va);
+    }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_map_data_enter_exit ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target enter data map(to: b, c)
+
+#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc);
+      }
+
+#pragma omp target CONSTRUCT map(to: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, va);
+	va = svadd_s32_z (svptrue_b32 (), vc, va);
+      }
+
+#pragma omp target exit data map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_map_data_alloc_update ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target data map(to: b, c) map(alloc: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+{
+#pragma omp target CONSTRUCT
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+      }
+
+/* Update va on the host from target.  */
+#pragma omp target update from(va)
+
+#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, va);
+	va = svadd_s32_z (svptrue_b32 (), vc, va);
+      }
+}
+  return va;
+}
+
+int64_t __attribute__ ((noinline))
+omp_target_private ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int64_t res;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+/* Combined construct scenario: here private applies to the parallel loop
+   construct, so no error.  */
+#pragma omp target CONSTRUCT private (va, vb, vc) map (to: b, c) map (from: res)
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b);
+      vc = svld1_s32 (svptrue_b32 (), c);
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+      res = svaddv_s32 (svptrue_b32 (), va);
+    }
+
+  return res;
+}
+
+int64_t __attribute__ ((noinline))
+omp_target_firstprivate (svbool_t vp)
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int64_t res;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT firstprivate (vp) map (to: b, c) map (from: res)/* { dg-error {SVE type 'svbool_t' not allowed in target firstprivate clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (vp, b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (vp, c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (vp, vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+      res = svaddv_s32 (svptrue_b32 (), va);
+    }
+
+  return res;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel.c
new file mode 100644
index 00000000000..39dcd39a5f5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel.c
@@ -0,0 +1,195 @@
+/* { dg-do compile } */
+/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
+
+#include <arm_sve.h>
+
+#define CONSTRUCT parallel
+#define N 256
+
+svint32_t
+__attribute__ ((noinline))
+omp_target ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+      }
+  }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_data_map_1 ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc);
+      }
+  }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_data_map_2 ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+
+#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc);
+      }
+  }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(tofrom: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, va);
+	va = svadd_s32_z (svptrue_b32 (), vc, va);
+      }
+  }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_map_data_enter_exit ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target enter data map(to: b, c)
+
+#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc);
+      }
+  }
+
+#pragma omp target CONSTRUCT map(to: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, va);
+	va = svadd_s32_z (svptrue_b32 (), vc, va);
+      }
+  }
+
+#pragma omp target exit data map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_map_data_alloc_update ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target data map(to: b, c) map(alloc: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+{
+#pragma omp target CONSTRUCT
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+      }
+  }
+
+/* Update va on the host from target.  */
+#pragma omp target update from(va)
+
+#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, va);
+	va = svadd_s32_z (svptrue_b32 (), vc, va);
+      }
+  }
+}
+  return va;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-simd.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-simd.c
new file mode 100644
index 00000000000..2bb2a884fcf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-simd.c
@@ -0,0 +1,236 @@
+/* { dg-do compile } */
+/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
+
+#include <arm_sve.h>
+
+#define N 256
+#define CONSTRUCT simd
+
+svint32_t
+__attribute__ ((noinline))
+omp_target ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+    }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_data_map_1 ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+    }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_data_map_2 ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+    }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(tofrom: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, va);
+      va = svadd_s32_z (svptrue_b32 (), vc, va);
+    }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_map_data_enter_exit ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target enter data map(to: b, c)
+
+#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc);
+      }
+
+#pragma omp target CONSTRUCT map(to: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, va);
+	va = svadd_s32_z (svptrue_b32 (), vc, va);
+      }
+
+#pragma omp target exit data map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_map_data_alloc_update ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target data map(to: b, c) map(alloc: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+{
+#pragma omp target CONSTRUCT
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+      }
+
+/* Update va on the host from target.  */
+#pragma omp target update from(va)
+
+#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, va);
+	va = svadd_s32_z (svptrue_b32 (), vc, va);
+      }
+}
+  return va;
+}
+
+int64_t __attribute__ ((noinline))
+omp_target_private ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int64_t res;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+/* Combined construct scenario: here private applies to the simd construct so
+   no error.  */
+#pragma omp target CONSTRUCT private (va, vb, vc) map (to: b, c) map (from: res)
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b);
+      vc = svld1_s32 (svptrue_b32 (), c);
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+      res = svaddv_s32 (svptrue_b32 (), va);
+    }
+
+  return res;
+}
+
+int64_t __attribute__ ((noinline))
+omp_target_firstprivate (svbool_t vp)
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int64_t res;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT firstprivate (vp) map (to: b, c) map (from: res)/* { dg-error {SVE type 'svbool_t' not allowed in target firstprivate clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (vp, b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (vp, c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (vp, vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+      res = svaddv_s32 (svptrue_b32 (), va);
+    }
+
+  return res;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute-simd.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute-simd.c
new file mode 100644
index 00000000000..6a61883e80a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute-simd.c
@@ -0,0 +1,237 @@
+/* { dg-do compile } */
+/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
+
+#include <arm_sve.h>
+
+#define N 256
+#define CONSTRUCT teams distribute simd
+
+svint32_t
+__attribute__ ((noinline))
+omp_target ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+    }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_data_map_1 ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+    }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_data_map_2 ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+    }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(tofrom: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, va);
+      va = svadd_s32_z (svptrue_b32 (), vc, va);
+    }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_map_data_enter_exit ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target enter data map(to: b, c)
+
+#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc);
+      }
+
+#pragma omp target CONSTRUCT map(to: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, va);
+	va = svadd_s32_z (svptrue_b32 (), vc, va);
+      }
+
+#pragma omp target exit data map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_map_data_alloc_update ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target data map(to: b, c) map(alloc: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+{
+#pragma omp target CONSTRUCT
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+      }
+
+/* Update va on the host from target.  */
+#pragma omp target update from(va)
+
+#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, va);
+	va = svadd_s32_z (svptrue_b32 (), vc, va);
+      }
+}
+  return va;
+}
+
+int64_t __attribute__ ((noinline))
+omp_target_private ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int64_t res;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+/* Combined construct scenario: here private applies to the distribute simd
+   construct, so no error.  */
+#pragma omp target CONSTRUCT private (va, vb, vc) map (to: b, c) map (from: res)
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b);
+      vc = svld1_s32 (svptrue_b32 (), c);
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+      res = svaddv_s32 (svptrue_b32 (), va);
+    }
+
+  return res;
+}
+
+int64_t __attribute__ ((noinline))
+omp_target_firstprivate (svbool_t vp)
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int64_t res;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT firstprivate (vp) map (to: b, c) map (from: res)/* { dg-error {SVE type 'svbool_t' not allowed in target firstprivate clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (vp, b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (vp, c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (vp, vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+      res = svaddv_s32 (svptrue_b32 (), va);
+    }
+
+  return res;
+}
+
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute.c
new file mode 100644
index 00000000000..6852d427866
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute.c
@@ -0,0 +1,236 @@
+/* { dg-do compile } */
+/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
+
+#include <arm_sve.h>
+
+#define N 256
+#define CONSTRUCT teams distribute
+
+svint32_t
+__attribute__ ((noinline))
+omp_target ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+    }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_data_map_1 ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+    }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_data_map_2 ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+    }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(tofrom: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, va);
+      va = svadd_s32_z (svptrue_b32 (), vc, va);
+    }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_map_data_enter_exit ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target enter data map(to: b, c)
+
+#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc);
+      }
+
+#pragma omp target CONSTRUCT map(to: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, va);
+	va = svadd_s32_z (svptrue_b32 (), vc, va);
+      }
+
+#pragma omp target exit data map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_map_data_alloc_update ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target data map(to: b, c) map(alloc: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+{
+#pragma omp target CONSTRUCT
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+      }
+
+/* Update va on the host from target.  */
+#pragma omp target update from(va)
+
+#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, va);
+	va = svadd_s32_z (svptrue_b32 (), vc, va);
+      }
+}
+  return va;
+}
+
+int64_t __attribute__ ((noinline))
+omp_target_private ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int64_t res;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+/* Combined construct scenario: here private applies to the teams distribute
+   construct, so no error.  */
+#pragma omp target CONSTRUCT private (va, vb, vc) map (to: b, c) map (from: res)
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b);
+      vc = svld1_s32 (svptrue_b32 (), c);
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+      res = svaddv_s32 (svptrue_b32 (), va);
+    }
+
+  return res;
+}
+
+int64_t __attribute__ ((noinline))
+omp_target_firstprivate (svbool_t vp)
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int64_t res;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT firstprivate (vp) map (to: b, c) map (from: res)/* { dg-error {SVE type 'svbool_t' not allowed in target firstprivate clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (vp, b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (vp, c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (vp, vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+      res = svaddv_s32 (svptrue_b32 (), va);
+    }
+
+  return res;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-loop.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-loop.c
new file mode 100644
index 00000000000..aad6c47067c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-loop.c
@@ -0,0 +1,237 @@
+/* { dg-do compile } */
+/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
+
+#include <arm_sve.h>
+
+#define N 256
+#define CONSTRUCT teams loop
+
+svint32_t
+__attribute__ ((noinline))
+omp_target ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+    }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_data_map_1 ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+    }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_data_map_2 ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+    }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(tofrom: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (svptrue_b32 (), vb, va);
+      va = svadd_s32_z (svptrue_b32 (), vc, va);
+    }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_map_data_enter_exit ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target enter data map(to: b, c)
+
+#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc);
+      }
+
+#pragma omp target CONSTRUCT map(to: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, va);
+	va = svadd_s32_z (svptrue_b32 (), vc, va);
+      }
+
+#pragma omp target exit data map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_map_data_alloc_update ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target data map(to: b, c) map(alloc: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+{
+#pragma omp target CONSTRUCT
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+      }
+
+/* Update va on the host from target.  */
+#pragma omp target update from(va)
+
+#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, va);
+	va = svadd_s32_z (svptrue_b32 (), vc, va);
+      }
+}
+  return va;
+}
+
+int64_t __attribute__ ((noinline))
+omp_target_private ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int64_t res;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+/* Combined construct scenario: here private applies to the teams loop
+   construct, so no error.  */
+#pragma omp target CONSTRUCT private (va, vb, vc) map (to: b, c) map (from: res)
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b);
+      vc = svld1_s32 (svptrue_b32 (), c);
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+      res = svaddv_s32 (svptrue_b32 (), va);
+    }
+
+  return res;
+}
+
+int64_t __attribute__ ((noinline))
+omp_target_firstprivate (svbool_t vp)
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int64_t res;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT firstprivate (vp) map (to: b, c) map (from: res)/* { dg-error {SVE type 'svbool_t' not allowed in target firstprivate clause} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (vp, b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (vp, c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (vp, vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+      res = svaddv_s32 (svptrue_b32 (), va);
+    }
+
+  return res;
+}
+
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams.c
new file mode 100644
index 00000000000..a4269108166
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams.c
@@ -0,0 +1,195 @@
+/* { dg-do compile } */
+/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
+
+#include <arm_sve.h>
+
+#define N 256
+#define CONSTRUCT teams
+
+svint32_t
+__attribute__ ((noinline))
+omp_target ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+      }
+  }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_data_map_1 ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc);
+      }
+  }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_data_map_2 ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+
+#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc);
+      }
+  }
+
+#pragma omp target CONSTRUCT map(to: b, c) map(tofrom: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, va);
+	va = svadd_s32_z (svptrue_b32 (), vc, va);
+      }
+  }
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_map_data_enter_exit ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target enter data map(to: b, c)
+
+#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc);
+      }
+  }
+
+#pragma omp target CONSTRUCT map(to: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, va);
+	va = svadd_s32_z (svptrue_b32 (), vc, va);
+      }
+  }
+
+#pragma omp target exit data map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+
+  return va;
+}
+
+svint32_t
+__attribute__ ((noinline))
+omp_target_map_data_alloc_update ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target data map(to: b, c) map(alloc: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+{
+#pragma omp target CONSTRUCT
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+      }
+  }
+
+/* Update va on the host from target.  */
+#pragma omp target update from(va)
+
+#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
+  {
+    for (i = 0; i < 8; i++)
+      {
+	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+	va = svadd_s32_z (svptrue_b32 (), vb, va);
+	va = svadd_s32_z (svptrue_b32 (), vc, va);
+      }
+  }
+}
+  return va;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/target-device.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/target-device.c
new file mode 100644
index 00000000000..4c92015837f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/target-device.c
@@ -0,0 +1,97 @@
+/* { dg-do compile } */
+/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
+
+#include <arm_sve.h>
+
+#define N 256
+
+typedef __SVInt32_t v8si __attribute__((arm_sve_vector_bits(256)));
+
+int64_t __attribute__ ((noinline))
+omp_target_device_ptr (svbool_t vp, v8si *vptr)
+{
+
+  int a[N], b[N], c[N];
+  v8si va, vb, vc;
+  int64_t res;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target data use_device_ptr (vptr) map (to: b, c) /* { dg-error {SVE type 'v8si \*' {aka 'svint32_t __attribute__\(\(arm_sve_vector_bits\([0-9]+\)\)\) \*'} not allowed in target device clauses} } */
+#pragma omp target is_device_ptr (vptr) map (to: b, c) map (from: res) /* { dg-error {SVE type 'v8si \*' {aka 'svint32_t __attribute__\(\(arm_sve_vector_bits\(256\)\)\) \*'} not allowed in target device clauses} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = *vptr; /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (vp, c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+			      /* { dg-error {'vp' referenced in target region does not have a mappable type} "" { target *-*-* } .-1 } */
+      va = svadd_s32_z (vp, vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+      res = svaddv_s32 (svptrue_b32 (), va);
+    }
+
+  return res;
+}
+
+int64_t __attribute__ ((noinline))
+omp_target_device_addr (svbool_t vp, v8si *vptr)
+{
+
+  int a[N], b[N], c[N];
+  v8si va, vb, vc;
+  int64_t res;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target data use_device_addr (vb) map (to: b, c) /* { dg-error {SVE type 'v8si' {aka 'svint32_t __attribute__\(\(arm_sve_vector_bits\(256\)\)\)'} not allowed in target device clauses} } */
+#pragma omp target is_device_ptr (vptr) map (to: b, c) map (from: res) /* { dg-error {SVE type 'v8si \*' {aka 'svint32_t __attribute__\(\(arm_sve_vector_bits\(256\)\)\) \*'} not allowed in target device clauses} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = *vptr; /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (vp, c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+			      /* { dg-error {'vp' referenced in target region does not have a mappable type} "" { target *-*-* } .-1 } */
+      va = svadd_s32_z (vp, vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+      res = svaddv_s32 (svptrue_b32 (), va);
+    }
+
+  return res;
+}
+
+int64_t __attribute__ ((noinline))
+omp_target_has_device_addr (svbool_t vp, v8si *vptr)
+{
+
+  int a[N], b[N], c[N];
+  v8si va, vb, vc;
+  int64_t res;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp target data use_device_addr (vb) map (to: b, c) /* { dg-error {SVE type 'v8si' {aka 'svint32_t __attribute__\(\(arm_sve_vector_bits\(256\)\)\)'} not allowed in target device clauses} } */
+#pragma omp target has_device_addr (vb) map (to: b, c) map (from: res) /* { dg-error {SVE type 'v8si' {aka 'svint32_t __attribute__\(\(arm_sve_vector_bits\(256\)\)\)'} not allowed in target device clauses} } */
+  for (i = 0; i < 8; i++)
+    {
+      vb = svld1_s32 (vp, b); /* { dg-error {'vp' referenced in target region does not have a mappable type} } */
+      vc = svld1_s32 (vp, c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
+      va = svadd_s32_z (vp, vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
+      res = svaddv_s32 (svptrue_b32 (), va);
+    }
+
+  return res;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/target-link.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/target-link.c
new file mode 100644
index 00000000000..a6e80cfd559
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/target-link.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
+
+#include <arm_sve.h>
+
+typedef __SVInt32_t v8si __attribute__((arm_sve_vector_bits(256)));
+
+static v8si local_vec;
+#pragma omp declare target link(local_vec)
+
+v8si global_vec;
+#pragma omp declare target link(global_vec)
+
+void
+one_get_inc2_local_vec ()
+{
+  v8si res, res2, tmp;
+
+#pragma omp target map(from: res, res2) /* { dg-error {SVE type 'v8si' {aka 'svint32_t __attribute__\(\(arm_sve_vector_bits\(256\)\)\)'} not allowed in map clause} } */
+  {
+    res = local_vec; /* { dg-error {'local_vec' referenced in target region does not have a mappable type} } */
+    local_vec = svadd_s32_z (svptrue_b32 (), local_vec, local_vec);
+    res2 = local_vec;
+  }
+
+  tmp = svadd_s32_z (svptrue_b32 (), res, res);
+  svbool_t p = svcmpne_s32 (svptrue_b32 (), tmp, res2);
+  if (svptest_any (svptrue_b32 (), p))
+    __builtin_abort ();
+}
+
+void
+one_get_inc3_global_vec ()
+{
+  v8si res, res2, tmp;
+
+#pragma omp target map(from: res, res2) /* { dg-error {SVE type 'v8si' {aka 'svint32_t __attribute__\(\(arm_sve_vector_bits\(256\)\)\)'} not allowed in map clause} } */
+  {
+    res = global_vec; /* { dg-error {'global_vec' referenced in target region does not have a mappable type} } */
+    global_vec = svadd_s32_z (svptrue_b32 (), global_vec, global_vec);
+    res2 = global_vec;
+  }
+
+  tmp = svadd_s32_z (svptrue_b32 (), res, res);
+  svbool_t p = svcmpne_s32 (svptrue_b32 (), tmp, res2);
+  if (svptest_any (svptrue_b32 (), p))
+    __builtin_abort ();
+}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 04/11] AArch64: Test OpenMP lastprivate clause for various constructs.
  2024-05-27  5:06 [PATCH 00/11] AArch64/OpenMP: Test SVE ACLE types with various OpenMP constructs Tejas Belagod
                   ` (2 preceding siblings ...)
  2024-05-27  5:06 ` [PATCH 03/11] AArch64: Diagnose OpenMP offloading when SVE types involved Tejas Belagod
@ 2024-05-27  5:06 ` Tejas Belagod
  2024-05-27  5:06 ` [PATCH 05/11] AArch64: Test OpenMP threadprivate clause on SVE type Tejas Belagod
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 22+ messages in thread
From: Tejas Belagod @ 2024-05-27  5:06 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tejas Belagod, richard.sandiford, jakub

This patch tests various OpenMP lastprivate clause with SVE object types in
various construct contexts.

gcc/testsuite/ChangeLog:

	* gcc.target/aarch64/sve/omp/lastprivate.c: New test.
---
 .../gcc.target/aarch64/sve/omp/lastprivate.c  | 121 ++++++++++++++++++
 1 file changed, 121 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/lastprivate.c

diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/lastprivate.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/lastprivate.c
new file mode 100644
index 00000000000..e4ecc58a9c4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/lastprivate.c
@@ -0,0 +1,121 @@
+/* { dg-do compile } */
+/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
+
+#include <arm_sve.h>
+
+#define N 8
+
+#ifndef CONSTRUCT
+#define CONSTRUCT
+#endif
+
+svint32_t __attribute__ ((noinline))
+omp_lastprivate_sections ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+/* This worksharing construct binds to an implicit outer parallel region in
+    whose scope va is declared and therefore is default private.  This causes
+    the lastprivate clause list item va to be diagnosed as private in the outer
+    context.  Similarly for constructs for and distribute.  */
+#pragma omp sections lastprivate (va) /* { dg-error {lastprivate variable 'va' is private in outer context} } */
+    {
+      #pragma omp section
+      vb = svld1_s32 (svptrue_b32 (), b);
+      #pragma omp section
+      vc = svld1_s32 (svptrue_b32 (), c);
+      #pragma omp section
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+    }
+
+  return va;
+}
+
+
+svint32_t __attribute__ ((noinline))
+omp_lastprivate_for ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp for lastprivate (va) /* { dg-error {lastprivate variable 'va' is private in outer context} } */
+  for (i = 0; i < 1; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b);
+      vc = svld1_s32 (svptrue_b32 (), c);
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+    }
+
+  return va;
+}
+
+svint32_t __attribute__ ((noinline))
+omp_lastprivate_simd ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp simd lastprivate (va)
+  for (i = 0; i < 1; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b);
+      vc = svld1_s32 (svptrue_b32 (), c);
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+    }
+
+  return va;
+}
+
+svint32_t __attribute__ ((noinline))
+omp_lastprivate_distribute ()
+{
+
+  int a[N], b[N], c[N];
+  svint32_t va, vb, vc;
+  int i;
+
+#pragma omp parallel for
+  for (i = 0; i < N; i++)
+    {
+      b[i] = i;
+      c[i] = i + 1;
+    }
+
+#pragma omp distribute lastprivate (va) /* { dg-error {lastprivate variable 'va' is private in outer context} } */
+  for (i = 0; i < 1; i++)
+    {
+      vb = svld1_s32 (svptrue_b32 (), b);
+      vc = svld1_s32 (svptrue_b32 (), c);
+      va = svadd_s32_z (svptrue_b32 (), vb, vc);
+    }
+
+  return va;
+}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 05/11] AArch64: Test OpenMP threadprivate clause on SVE type.
  2024-05-27  5:06 [PATCH 00/11] AArch64/OpenMP: Test SVE ACLE types with various OpenMP constructs Tejas Belagod
                   ` (3 preceding siblings ...)
  2024-05-27  5:06 ` [PATCH 04/11] AArch64: Test OpenMP lastprivate clause for various constructs Tejas Belagod
@ 2024-05-27  5:06 ` Tejas Belagod
  2024-05-27  5:06 ` [PATCH 06/11] AArch64: Test OpenMP user-defined reductions with SVE types Tejas Belagod
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 22+ messages in thread
From: Tejas Belagod @ 2024-05-27  5:06 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tejas Belagod, richard.sandiford, jakub

This patch adds a test for ensuring threadprivate clause works for SVE type
objects.

gcc/testsuite/ChangeLog

	* gcc.target/aarch64/sve/omp/threadprivate.c: New test.
---
 .../aarch64/sve/omp/threadprivate.c           | 44 +++++++++++++++++++
 1 file changed, 44 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/threadprivate.c

diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/threadprivate.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/threadprivate.c
new file mode 100644
index 00000000000..0a46b0a7770
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/threadprivate.c
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
+
+#include <arm_sve.h>
+
+typedef __SVInt32_t v8si __attribute__((arm_sve_vector_bits(256)));
+
+v8si vec1;
+#pragma omp threadprivate (vec1)
+
+int main()
+{
+  int64_t res = 0;
+
+#pragma omp parallel firstprivate (res) num_threads(10)
+  {
+    vec1 = svindex_s32 (1, 0);
+    res = svaddv_s32 (svptrue_b32 (), vec1);
+
+#pragma omp barrier
+    if (res != 8LL)
+      __builtin_abort ();
+  }
+
+  return 0;
+}
+
+int foo ()
+{
+  int64_t res = 0;
+
+  vec1 = svindex_s32 (1, 0);
+
+#pragma omp parallel copyin (vec1) firstprivate (res) num_threads(10)
+  {
+    res = svaddv_s32 (svptrue_b32 (), vec1);
+
+#pragma omp barrier
+    if (res != 8LL)
+      __builtin_abort ();
+  }
+
+  return 0;
+}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 06/11] AArch64: Test OpenMP user-defined reductions with SVE types.
  2024-05-27  5:06 [PATCH 00/11] AArch64/OpenMP: Test SVE ACLE types with various OpenMP constructs Tejas Belagod
                   ` (4 preceding siblings ...)
  2024-05-27  5:06 ` [PATCH 05/11] AArch64: Test OpenMP threadprivate clause on SVE type Tejas Belagod
@ 2024-05-27  5:06 ` Tejas Belagod
  2024-05-27  5:06 ` [PATCH 07/11] AArch64: Test OpenMP uniform clause on " Tejas Belagod
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 22+ messages in thread
From: Tejas Belagod @ 2024-05-27  5:06 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tejas Belagod, richard.sandiford, jakub

This patch tests user-defined reductions on various constructs with objects
of SVE type.

gcc/testsuite/ChangeLog

	* gcc.target/aarch64/sve/omp/udr-sve.c: New test.
---
 .../gcc.target/aarch64/sve/omp/udr-sve.c      | 166 ++++++++++++++++++
 1 file changed, 166 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/udr-sve.c

diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/udr-sve.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/udr-sve.c
new file mode 100644
index 00000000000..049fbee9056
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/udr-sve.c
@@ -0,0 +1,166 @@
+/* { dg-do run } */
+/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
+
+#include <arm_sve.h>
+
+#pragma omp declare reduction (+:svint32_t: omp_out = svadd_s32_z (svptrue_b32(), omp_in, omp_out))
+
+int parallel_reduction ()
+{
+  int a[8] = {1 ,1, 1, 1, 1, 1, 1, 1};
+  int b[8] = {0 ,0, 0, 0, 0, 0, 0, 0};
+  svint32_t va = svld1_s32 (svptrue_b32 (), b);
+  int i = 0;
+  int64_t res;
+
+  #pragma omp parallel reduction (+:va, i)
+    {
+      va = svld1_s32 (svptrue_b32 (), a);
+      i++;
+    }
+
+  res = svaddv_s32 (svptrue_b32 (), va);
+
+  if (res != i * 8)
+    __builtin_abort ();
+
+  return 0;
+}
+
+int for_reduction ()
+{
+  int a[8] = {1 ,1, 1, 1, 1, 1, 1, 1};
+  int b[8] = {0 ,0, 0, 0, 0, 0, 0, 0};
+  svint32_t va = svld1_s32 (svptrue_b32 (), b);
+  int i = 0;
+  int j;
+  int64_t res;
+
+  #pragma omp parallel for reduction (+:va, i)
+  for (j = 0; j < 8; j++)
+    {
+      va = svld1_s32 (svptrue_b32 (), a);
+      i++;
+    }
+
+  res = svaddv_s32 (svptrue_b32 (), va);
+
+  if (res != i * 8)
+    __builtin_abort ();
+
+  return 0;
+}
+
+int simd_reduction ()
+{
+  int a[8] = {1 ,1, 1, 1, 1, 1, 1, 1};
+  int b[8] = {0 ,0, 0, 0, 0, 0, 0, 0};
+  svint32_t va = svld1_s32 (svptrue_b32 (), b);
+  int i = 0;
+  int j;
+  int64_t res;
+
+  /* The list includes va that is already vectorized, so the only impact here
+     is on the scalar variable i.  OMP spec says only scalar variables are
+     allowed in the list.  Should non-scalars be diagnosed?  */
+  #pragma omp simd reduction (+:va, i)
+  for (j = 0; j < 8; j++)
+    {
+      va = svld1_s32 (svptrue_b32 (), a);
+      i++;
+    }
+
+  res = svaddv_s32 (svptrue_b32 (), va);
+
+  if (res != i)
+    __builtin_abort ();
+
+  return 0;
+}
+
+int taskloop_reduction ()
+{
+  int a[8] = {1 ,1, 1, 1, 1, 1, 1, 1};
+  int b[8] = {0 ,0, 0, 0, 0, 0, 0, 0};
+  svint32_t va = svld1_s32 (svptrue_b32 (), b);
+  int i = 0;
+  int j;
+  int64_t res;
+
+  #pragma omp taskloop reduction (+:va, i)
+  for (j = 0; j < 8; j++)
+    {
+      svint32_t tva = svld1_s32 (svptrue_b32 (), a);
+      #pragma omp in_reduction (+: va)
+      va = svadd_s32_z (svptrue_b32 (), tva, va);
+      i++;
+    }
+
+  res = svaddv_s32 (svptrue_b32 (), va);
+
+  if (res != i * 8)
+    __builtin_abort ();
+
+  return 0;
+}
+
+int task_reduction ()
+{
+  int a[8] = {1 ,1, 1, 1, 1, 1, 1, 1};
+  int b[8] = {0 ,0, 0, 0, 0, 0, 0, 0};
+  svint32_t va = svld1_s32 (svptrue_b32 (), b);
+  int i = 0;
+  int j;
+  int64_t res;
+
+  #pragma omp parallel reduction (task,+:va)
+  {
+    va = svadd_s32_z (svptrue_b32 (), svld1_s32 (svptrue_b32 (), a), va);
+    i++;
+  }
+
+  res = svaddv_s32 (svptrue_b32 (), va);
+
+  if (res != i * 8)
+    __builtin_abort ();
+
+  return 0;
+}
+
+int inscan_reduction_incl ()
+{
+  int a[8] = {1 ,1, 1, 1, 1, 1, 1, 1};
+  int b[8] = {0 ,0, 0, 0, 0, 0, 0, 0};
+  svint32_t va = svld1_s32 (svptrue_b32 (), b);
+  int j;
+  int i = 0;
+  int64_t res = 0;
+
+  #pragma omp parallel
+  #pragma omp for reduction (inscan,+:va, i)
+  for (j = 0; j < 8; j++)
+    {
+      va = svld1_s32 (svptrue_b32 (), a);
+      i++;
+      #pragma omp scan inclusive (va, i)
+      res += svaddv_s32 (svptrue_b32 (), va);
+    }
+
+  if (res != i * 8)
+    __builtin_abort ();
+
+  return 0;
+}
+
+int
+main()
+{
+  parallel_reduction ();
+  task_reduction ();
+  inscan_reduction_incl ();
+  taskloop_reduction ();
+  simd_reduction ();
+  for_reduction ();
+
+  return 0;
+}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 07/11] AArch64: Test OpenMP uniform clause on SVE types.
  2024-05-27  5:06 [PATCH 00/11] AArch64/OpenMP: Test SVE ACLE types with various OpenMP constructs Tejas Belagod
                   ` (5 preceding siblings ...)
  2024-05-27  5:06 ` [PATCH 06/11] AArch64: Test OpenMP user-defined reductions with SVE types Tejas Belagod
@ 2024-05-27  5:06 ` Tejas Belagod
  2024-05-27  5:06 ` [PATCH 08/11] AArch64: Test OpenMP simd aligned clause with " Tejas Belagod
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 22+ messages in thread
From: Tejas Belagod @ 2024-05-27  5:06 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tejas Belagod, richard.sandiford, jakub

This patch tests if simd uniform clause works with SVE types in simd regions.

gcc/testsuite/ChangeLog

	* gcc.target/aarch64/sve/omp/simd-uniform.c: New test.
---
 .../gcc.target/aarch64/sve/omp/simd-uniform.c | 71 +++++++++++++++++++
 1 file changed, 71 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/simd-uniform.c

diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/simd-uniform.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/simd-uniform.c
new file mode 100644
index 00000000000..6256ce9fdc1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/simd-uniform.c
@@ -0,0 +1,71 @@
+/* { dg-do run { target aarch64_sve256_hw } } */
+/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
+
+#include <arm_sve.h>
+
+#define N 256
+
+void init(int *a, int *a_ref, int *b, int n)
+{
+   int i;
+   for ( i=0; i<N; i++ )
+   {
+      a[i] = i;
+      a_ref[i] = i;
+      b[i] = N-i;
+   }
+}
+
+#pragma omp declare simd uniform(a, b, sz) linear (i)
+void vec_add(int *a, int *b, int i, int64_t sz)
+{
+   svint32_t va, vb, vc, tmp;
+   svint32_t ones = svdup_n_s32 (1);
+
+   va = svld1_s32 (svptrue_b32 (), a + i * sz);
+   vb = svld1_s32 (svptrue_b32 (), b + i * sz);
+   tmp = svadd_s32_z (svptrue_b32 (), va, vb);
+   vc = svadd_s32_z (svptrue_b32 (), tmp, ones);
+   svst1_s32 (svptrue_b32 (), a + i * sz, vc);
+}
+
+void work(int *a, int *b, int n)
+{
+  int i;
+  int64_t sz = svcntw ();
+
+  #pragma omp simd
+  for (i = 0; i < n/sz; i++)
+    vec_add (a, b, i, sz);
+}
+
+void work_ref(int *a, int *b, int n)
+{
+   int i;
+   for ( i = 0; i < n; i++ ) {
+     a[i] = a[i] + b[i] + 1;
+   }
+}
+
+void check (int *a, int *b)
+{
+  int i;
+  for (i = 0; i < N; i++)
+    if (a[i] != b[i])
+      __builtin_abort ();
+}
+
+int main ()
+{
+   int i;
+   int a[N], a_ref[N], b[N];
+
+   init(a, a_ref, b, N);
+
+   work(a, b, N );
+   work_ref(a_ref, b, N );
+
+   check(a, a_ref);
+
+   return 0;
+}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 08/11] AArch64: Test OpenMP simd aligned clause with SVE types.
  2024-05-27  5:06 [PATCH 00/11] AArch64/OpenMP: Test SVE ACLE types with various OpenMP constructs Tejas Belagod
                   ` (6 preceding siblings ...)
  2024-05-27  5:06 ` [PATCH 07/11] AArch64: Test OpenMP uniform clause on " Tejas Belagod
@ 2024-05-27  5:06 ` Tejas Belagod
  2024-05-27  5:06 ` [PATCH 09/11] AArch64: Diagnose OpenMP linear clause for SVE type objects Tejas Belagod
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 22+ messages in thread
From: Tejas Belagod @ 2024-05-27  5:06 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tejas Belagod, richard.sandiford, jakub

This patch tests simd aligned clause and their interaction with SVE types.

gcc/testsuite/ChangeLog

	* gcc.target/aarch64/sve/omp/simd-aligned.c: New test.
---
 .../gcc.target/aarch64/sve/omp/simd-aligned.c | 50 +++++++++++++++++++
 1 file changed, 50 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/simd-aligned.c

diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/simd-aligned.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/simd-aligned.c
new file mode 100644
index 00000000000..6c75bb5a714
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/simd-aligned.c
@@ -0,0 +1,50 @@
+/* { dg-do run } */
+/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
+#include <arm_sve.h>
+
+#define N 256
+
+int a[N] __attribute__((aligned (64)));
+int b[N] __attribute__((aligned (64)));
+
+
+__attribute((noipa))
+void foo (int *p, int *q)
+{
+   svint32_t va, vb, vc;
+   int i;
+   uint64_t sz = svcntw ();
+
+#pragma omp simd aligned(p, q : 64) private (va, vb, vc) nontemporal (va, vb, vc)
+  for (i = 0; i < N; i++)
+    {
+      if (i % sz == 0)
+	{
+	  va = svld1_s32 (svptrue_b32 (), p);
+	  vb = svindex_s32 (1, 0);
+	  vc = svadd_s32_z (svptrue_b32 (), va, vb);
+	  svst1_s32 (svptrue_b32 (), q, vc);
+	  q += sz;
+	}
+    }
+
+  return;
+}
+
+int main ()
+{
+
+  for (int i = 0;i < N; i++)
+    {
+      a[i] = 1;
+      b[i] = 0;
+    }
+
+  foo (a, b);
+
+  for (int i = 0;i < N; i++)
+    if (b[i] != 2)
+      __builtin_abort ();
+
+  return 0;
+}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 09/11] AArch64: Diagnose OpenMP linear clause for SVE type objects.
  2024-05-27  5:06 [PATCH 00/11] AArch64/OpenMP: Test SVE ACLE types with various OpenMP constructs Tejas Belagod
                   ` (7 preceding siblings ...)
  2024-05-27  5:06 ` [PATCH 08/11] AArch64: Test OpenMP simd aligned clause with " Tejas Belagod
@ 2024-05-27  5:06 ` Tejas Belagod
  2024-05-27  5:06 ` [PATCH 10/11] AArch64: Test OpenMP depend clause and its variations on SVE types Tejas Belagod
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 22+ messages in thread
From: Tejas Belagod @ 2024-05-27  5:06 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tejas Belagod, richard.sandiford, jakub

This patch tests if SVE object types if applied to linear clause is diagnosed
as expected.

gcc/testsuite/ChangeLog

	* gcc.target/aarch64/sve/omp/linear.c: New test.
---
 .../gcc.target/aarch64/sve/omp/linear.c       | 33 +++++++++++++++++++
 1 file changed, 33 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/linear.c

diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/linear.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/linear.c
new file mode 100644
index 00000000000..77b823a73d4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/linear.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
+
+#include <arm_sve.h>
+
+int a[256];
+
+__attribute__((noinline, noclone)) int
+f1 (svint32_t va, int i)
+{
+  #pragma omp parallel for linear (va: 8) linear (i: 4) /* { dg-error {linear clause applied to non-integral non-pointer variable with type 'svint32_t'} } */
+  for (int j = 16; j < 64; j++)
+    {
+      a[i] = j;
+      i += 4;
+      va = svindex_s32 (0,1);
+    }
+  return i;
+}
+
+__attribute__((noinline, noclone)) int
+f2 (svbool_t p, int i)
+{
+  #pragma omp parallel for linear (p: 0) linear (i: 4) /* { dg-error {linear clause applied to non-integral non-pointer variable with type 'svbool_t'} } */
+  for (int j = 16; j < 64; j++)
+    {
+      a[i] = j;
+      i += 4;
+      p = svptrue_b32 ();
+    }
+  return i;
+}
+
-- 
2.25.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 10/11] AArch64: Test OpenMP depend clause and its variations on SVE types
  2024-05-27  5:06 [PATCH 00/11] AArch64/OpenMP: Test SVE ACLE types with various OpenMP constructs Tejas Belagod
                   ` (8 preceding siblings ...)
  2024-05-27  5:06 ` [PATCH 09/11] AArch64: Diagnose OpenMP linear clause for SVE type objects Tejas Belagod
@ 2024-05-27  5:06 ` Tejas Belagod
  2024-05-27  5:06 ` [PATCH 11/11] AArch64: Diagnose SVE type objects when applied to OpenMP doacross clause Tejas Belagod
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 22+ messages in thread
From: Tejas Belagod @ 2024-05-27  5:06 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tejas Belagod, richard.sandiford, jakub

This patch adds a test to test depend clause and its various dependency
variations with SVE type objects.

gcc/testsuite/ChangeLog

	* gcc.target/aarch64/sve/omp/depend-1.c: New test.
---
 .../gcc.target/aarch64/sve/omp/depend-1.c     | 223 ++++++++++++++++++
 1 file changed, 223 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/depend-1.c

diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/depend-1.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/depend-1.c
new file mode 100644
index 00000000000..734c20fb9ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/depend-1.c
@@ -0,0 +1,223 @@
+/* { dg-do run { target aarch64_sve256_hw } } */
+/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
+
+#include <arm_sve.h>
+
+int zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0};
+int ones[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };
+int twos[8] = { 2, 2, 2, 2, 2, 2, 2, 2 };
+
+void
+dep (void)
+{
+  svint32_t x = svld1_s32 (svptrue_b32 (), ones);
+
+  #pragma omp parallel
+  #pragma omp single
+  {
+    #pragma omp task shared (x) depend(out: x)
+    x = svld1_s32 (svptrue_b32 (), twos);
+    #pragma omp task shared (x) depend(in: x)
+    if (svptest_any (svptrue_b32(), svcmpne_n_s32 (svptrue_b32 (), x, 2)))
+      __builtin_abort  ();
+  }
+}
+
+void
+dep2 (void)
+{
+  #pragma omp parallel
+  #pragma omp single
+  {
+    svint32_t x = svld1_s32 (svptrue_b32 (), ones);
+    #pragma omp task shared (x) depend(out: x)
+    x = svld1_s32 (svptrue_b32 (), twos);
+    #pragma omp task shared (x) depend(in: x)
+    if (svptest_any (svptrue_b32(), svcmpne_n_s32 (svptrue_b32 (), x, 2)))
+      __builtin_abort  ();
+    #pragma omp taskwait
+  }
+}
+
+void
+dep3 (void)
+{
+  #pragma omp parallel
+  {
+    svint32_t x = svld1_s32 (svptrue_b32 (), ones);
+    #pragma omp single
+    {
+      #pragma omp task shared (x) depend(out: x)
+      x = svld1_s32 (svptrue_b32 (), twos);
+      #pragma omp task shared (x) depend(in: x)
+      if (svptest_any (svptrue_b32(), svcmpne_n_s32 (svptrue_b32 (), x, 2)))
+	__builtin_abort  ();
+    }
+  }
+}
+
+void
+firstpriv (void)
+{
+  #pragma omp parallel
+  #pragma omp single
+  {
+    svint32_t x = svld1_s32 (svptrue_b32 (), ones);
+    #pragma omp task depend(out: x)
+    x = svld1_s32 (svptrue_b32 (), twos);
+    #pragma omp task depend(in: x)
+    if (svptest_any (svptrue_b32(), svcmpne_n_s32 (svptrue_b32 (), x, 1)))
+      __builtin_abort  ();
+  }
+}
+
+void
+antidep (void)
+{
+  svint32_t x = svld1_s32 (svptrue_b32 (), ones);
+  #pragma omp parallel
+  #pragma omp single
+  {
+    #pragma omp task shared(x) depend(in: x)
+    if (svptest_any (svptrue_b32(), svcmpne_n_s32 (svptrue_b32 (), x, 1)))
+      __builtin_abort  ();
+    #pragma omp task shared(x) depend(out: x)
+    x = svld1_s32 (svptrue_b32 (), twos);
+  }
+}
+
+void
+antidep2 (void)
+{
+  #pragma omp parallel
+  #pragma omp single
+  {
+    svint32_t x = svld1_s32 (svptrue_b32 (), ones);
+    #pragma omp taskgroup
+    {
+      #pragma omp task shared(x) depend(in: x)
+      if (svptest_any (svptrue_b32(), svcmpne_n_s32 (svptrue_b32 (), x, 1)))
+	__builtin_abort  ();
+      #pragma omp task shared(x) depend(out: x)
+      x = svld1_s32 (svptrue_b32 (), twos);
+    }
+  }
+}
+
+void
+antidep3 (void)
+{
+  #pragma omp parallel
+  {
+    svint32_t x = svld1_s32 (svptrue_b32 (), ones);
+    #pragma omp single
+    {
+      #pragma omp task shared(x) depend(in: x)
+      if (svptest_any (svptrue_b32(), svcmpne_n_s32 (svptrue_b32 (), x, 1)))
+	__builtin_abort  ();
+      #pragma omp task shared(x) depend(out: x)
+      x = svld1_s32 (svptrue_b32 (), twos);
+    }
+  }
+}
+
+
+void
+outdep (void)
+{
+  #pragma omp parallel
+  #pragma omp single
+  {
+    svint32_t x = svld1_s32 (svptrue_b32 (), zeros);
+    #pragma omp task shared(x) depend(out: x)
+    x = svld1_s32 (svptrue_b32 (), ones);
+    #pragma omp task shared(x) depend(out: x)
+    x = svld1_s32 (svptrue_b32 (), twos);
+    #pragma omp taskwait
+    if (svptest_any (svptrue_b32(), svcmpne_n_s32 (svptrue_b32 (), x, 2)))
+      __builtin_abort  ();
+  }
+}
+
+void
+concurrent (void)
+{
+  svint32_t x = svld1_s32 (svptrue_b32 (), ones);
+  #pragma omp parallel
+  #pragma omp single
+  {
+    #pragma omp task shared (x) depend(out: x)
+    x = svld1_s32 (svptrue_b32 (), twos);
+    #pragma omp task shared (x) depend(in: x)
+    if (svptest_any (svptrue_b32(), svcmpne_n_s32 (svptrue_b32 (), x, 2)))
+      __builtin_abort  ();
+    #pragma omp task shared (x) depend(in: x)
+    if (svptest_any (svptrue_b32(), svcmpne_n_s32 (svptrue_b32 (), x, 2)))
+      __builtin_abort  ();
+    #pragma omp task shared (x) depend(in: x)
+    if (svptest_any (svptrue_b32(), svcmpne_n_s32 (svptrue_b32 (), x, 2)))
+      __builtin_abort  ();
+  }
+}
+
+void
+concurrent2 (void)
+{
+  #pragma omp parallel
+  #pragma omp single
+  {
+    svint32_t x = svld1_s32 (svptrue_b32 (), ones);
+    #pragma omp task shared (x) depend(out: x)
+    x = svld1_s32 (svptrue_b32 (), twos);
+    #pragma omp task shared (x) depend(in: x)
+    if (svptest_any (svptrue_b32(), svcmpne_n_s32 (svptrue_b32 (), x, 2)))
+      __builtin_abort  ();
+    #pragma omp task shared (x) depend(in: x)
+    if (svptest_any (svptrue_b32(), svcmpne_n_s32 (svptrue_b32 (), x, 2)))
+      __builtin_abort  ();
+    #pragma omp task shared (x) depend(in: x)
+    if (svptest_any (svptrue_b32(), svcmpne_n_s32 (svptrue_b32 (), x, 2)))
+      __builtin_abort  ();
+    #pragma omp taskwait
+  }
+}
+
+void
+concurrent3 (void)
+{
+  #pragma omp parallel
+  {
+    svint32_t x = svld1_s32 (svptrue_b32 (), ones);
+    #pragma omp single
+    {
+      #pragma omp task shared (x) depend(out: x)
+      x = svld1_s32 (svptrue_b32 (), twos);
+      #pragma omp task shared (x) depend(in: x)
+      if (svptest_any (svptrue_b32(), svcmpne_n_s32 (svptrue_b32 (), x, 2)))
+	__builtin_abort  ();
+      #pragma omp task shared (x) depend(in: x)
+      if (svptest_any (svptrue_b32(), svcmpne_n_s32 (svptrue_b32 (), x, 2)))
+	__builtin_abort  ();
+      #pragma omp task shared (x) depend(in: x)
+      if (svptest_any (svptrue_b32(), svcmpne_n_s32 (svptrue_b32 (), x, 2)))
+	__builtin_abort  ();
+    }
+  }
+}
+
+int
+main ()
+{
+  dep ();
+  dep2 ();
+  dep3 ();
+  firstpriv ();
+  antidep ();
+  antidep2 ();
+  antidep3 ();
+  outdep ();
+  concurrent ();
+  concurrent2 ();
+  concurrent3 ();
+  return 0;
+}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 11/11] AArch64: Diagnose SVE type objects when applied to OpenMP doacross clause.
  2024-05-27  5:06 [PATCH 00/11] AArch64/OpenMP: Test SVE ACLE types with various OpenMP constructs Tejas Belagod
                   ` (9 preceding siblings ...)
  2024-05-27  5:06 ` [PATCH 10/11] AArch64: Test OpenMP depend clause and its variations on SVE types Tejas Belagod
@ 2024-05-27  5:06 ` Tejas Belagod
  2024-05-30 12:58 ` [PATCH 00/11] AArch64/OpenMP: Test SVE ACLE types with various OpenMP constructs Richard Sandiford
  2024-06-20  4:46 ` Tejas Belagod
  12 siblings, 0 replies; 22+ messages in thread
From: Tejas Belagod @ 2024-05-27  5:06 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tejas Belagod, richard.sandiford, jakub

This patch tests if SVE type objects when applied to doacross clause are
correctly diagnosed.

gcc/testsuite/ChangeLog

	* gcc.target/aarch64/sve/omp/doacross.c: New test.
---
 .../gcc.target/aarch64/sve/omp/doacross.c     | 22 +++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/doacross.c

diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/doacross.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/doacross.c
new file mode 100644
index 00000000000..a311887926b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/doacross.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
+
+#include <arm_sve.h>
+
+int a[256];
+
+__attribute__((noinline, noclone)) int
+f1 (svint32_t va)
+{
+  int j;
+  #pragma omp for ordered (1)
+  for (j = 16; j < 64; j++)
+    {
+      #pragma omp ordered doacross(sink: va) /* { dg-error {variable 'va' is not an iteration of outermost loop 1, expected 'j'} } */
+      a[j - 1] = j + svaddv_s32 (svptrue_b32 (), va);
+      #pragma omp ordered doacross(source: omp_cur_iteration)
+      j += 4;
+      va = svindex_s32 (0,1);
+    }
+  return j;
+}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 02/11] AArch64: Add test cases for SVE types in OpenMP shared clause.
  2024-05-27  5:06 ` [PATCH 02/11] AArch64: Add test cases for SVE types in OpenMP shared clause Tejas Belagod
@ 2024-05-30 12:38   ` Richard Sandiford
  2024-05-31  7:01     ` Tejas Belagod
  0 siblings, 1 reply; 22+ messages in thread
From: Richard Sandiford @ 2024-05-30 12:38 UTC (permalink / raw)
  To: Tejas Belagod; +Cc: gcc-patches, jakub

Tejas Belagod <tejas.belagod@arm.com> writes:
> This patch tests various shared clauses with SVE types.  It also adds a test
> scaffold to run OpenMP tests in under the gcc.target testsuite.
>
> gcc/testsuite/ChangeLog:
>
> 	* gcc.target/aarch64/sve/omp/aarch64-sve-omp.exp: New scaffold.

Hopefully Jakub can comment on whether we should test this in the
GCC testsuite or libgomp testsuite.

On the test:

> [...]
> +int
> +main ()
> +{
> +  svint32_t x = svindex_s32 (0 ,1);
> +  svint32_t y = svindex_s32 (8, 1);
> +  svint32_t a, b;
> +  svbool_t p;
> +
> +  /* Implicit shared.  */
> +  a = foo (x, y, p);
> +  b = implicit_shared_default (x, y, p);

It looks like p is used uninitialised here.  Can you check locally
that using svptrue_b8 () (or whatever) as an initialiser allows the
test to pass while svpfalse_b () causes it to fail?

Thanks,
Richard

> +  compare_vec (a, b);
> +
> +  /* Explicit shared.  */
> +  a = foo (x ,y, p);
> +  b = explicit_shared (x, y, p);
> +  compare_vec (a, b);
> +
> +  /* Implicit shared with no default clause.  */
> +  a = foo (x ,y, p);
> +  b = implicit_shared_no_default (x, y, p);
> +  compare_vec (a, b);
> +
> +  /* Mix shared.  */
> +  a = foo (x ,y, p);
> +  b = mix_shared (y, p);
> +  compare_vec (a, b);
> +
> +  /* Predetermined shared.  */
> +  predetermined_shared_static (true);
> +  predetermined_shared_static (false);
> +
> +  return 0;
> +}
> +
> +/* { dg-final { scan-tree-dump-times "value-expr: \*.omp_data_i->a" 10 "ompexp" } } */

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 03/11] AArch64: Diagnose OpenMP offloading when SVE types involved.
  2024-05-27  5:06 ` [PATCH 03/11] AArch64: Diagnose OpenMP offloading when SVE types involved Tejas Belagod
@ 2024-05-30 12:50   ` Richard Sandiford
  0 siblings, 0 replies; 22+ messages in thread
From: Richard Sandiford @ 2024-05-30 12:50 UTC (permalink / raw)
  To: Tejas Belagod; +Cc: gcc-patches, jakub, Andrea Corallo

Tejas Belagod <tejas.belagod@arm.com> writes:
> The target clause in OpenMP is used to offload loop kernels to accelarator
> peripeherals.  target's 'map' clause is used to move data from and to the
> accelarator.  When the data is SVE type, it may not be suitable because of
> various reasons i.e. the two SVE targets may not agree on vector size or
> some targets don't support variable vector size.  This makes SVE unsuitable
> for use in OMP's 'map' clause.  This patch diagnoses all such cases and issues
> an error where SVE types are not suitable.
>
> Co-authored-by: Andrea Corallo <andrea.corallo@arm.com>
>
> gcc/ChangeLog:
>
> 	* target.h (type_context_kind): Add new context kinds for target clauses.
> 	* config/aarch64/aarch64-sve-builtins.cc (verify_type_context): Diagnose
> 	SVE types for a given OpenMP context.
> 	* gimplify.cc (omp_notice_variable):  Diagnose implicitly-mapped SVE
> 	objects in OpenMP regions.
> 	(gimplify_scan_omp_clauses): Diagnose SVE types for various target
> 	clauses.
>
> gcc/testsuite/ChangeLog:
>
> 	* gcc.target/aarch64/sve/omp/offload-1.c: New test.
> 	* gcc.target/aarch64/sve/omp/offload-2.c: Likewise.
> 	* gcc.target/aarch64/sve/omp/offload-parallel-loop.c: Likewise.
> 	* gcc.target/aarch64/sve/omp/offload-parallel.c: Likewise.
> 	* gcc.target/aarch64/sve/omp/offload-simd.c: Likewise.
> 	* gcc.target/aarch64/sve/omp/offload-teams-distribute-simd.c: Likewise.
> 	* gcc.target/aarch64/sve/omp/offload-teams-distribute.c: Likewise.
> 	* gcc.target/aarch64/sve/omp/offload-teams-loop.c: Likewise.
> 	* gcc.target/aarch64/sve/omp/offload-teams.c: Likewise.
> 	* gcc.target/aarch64/sve/omp/target-device.c: Likewise.
> 	* gcc.target/aarch64/sve/omp/target-link.c: Likewise.
> ---
>  gcc/config/aarch64/aarch64-sve-builtins.cc    |  31 +++
>  gcc/gimplify.cc                               |  34 ++-
>  gcc/target.h                                  |  19 +-
>  .../gcc.target/aarch64/sve/omp/offload-1.c    | 237 ++++++++++++++++++
>  .../gcc.target/aarch64/sve/omp/offload-2.c    | 198 +++++++++++++++
>  .../aarch64/sve/omp/offload-parallel-loop.c   | 236 +++++++++++++++++
>  .../aarch64/sve/omp/offload-parallel.c        | 195 ++++++++++++++
>  .../gcc.target/aarch64/sve/omp/offload-simd.c | 236 +++++++++++++++++
>  .../sve/omp/offload-teams-distribute-simd.c   | 237 ++++++++++++++++++
>  .../sve/omp/offload-teams-distribute.c        | 236 +++++++++++++++++
>  .../aarch64/sve/omp/offload-teams-loop.c      | 237 ++++++++++++++++++
>  .../aarch64/sve/omp/offload-teams.c           | 195 ++++++++++++++
>  .../aarch64/sve/omp/target-device.c           |  97 +++++++
>  .../gcc.target/aarch64/sve/omp/target-link.c  |  48 ++++
>  14 files changed, 2234 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-1.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-2.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel-loop.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-simd.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute-simd.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-loop.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/target-device.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/target-link.c
>
> diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc
> index f3983a123e3..ee1064c3bb7 100644
> --- a/gcc/config/aarch64/aarch64-sve-builtins.cc
> +++ b/gcc/config/aarch64/aarch64-sve-builtins.cc
> @@ -5000,6 +5000,29 @@ bool
>  verify_type_context (location_t loc, type_context_kind context,
>  		     const_tree type, bool silent_p)
>  {
> +  if (aarch64_sve::builtin_type_p (type)
> +      || (POINTER_TYPE_P (type)
> +	  && aarch64_sve::builtin_type_p (TREE_TYPE (type))))

Could you say in more detail why we check for zero or one levels
of pointer indirection but not for more?

Also, was there a reason for checking builtin_type_p rather than
sizeless_type_p?  Things like svbool_t remain sizeless even for
-msve-vector-bits=128 etc., so sizeless_type_p would still cover
that case.  But arm_sve_vector_bits makes it possible to define
fixed-length vector types that are treated for ABI & ACLE purposes
like SVE types.  I don't think those should be treated differently
from normal vectors by omp, since the size is fixed by the attribute
(and types with different attributes are distinct).

Thanks,
Richard

> +    switch (context)
> +    {
> +      case TCTX_OMP_MAP:
> +	error_at (loc, "SVE type %qT not allowed in map clause", type);
> +	return false;
> +      case TCTX_OMP_MAP_IMP_REF:
> +	return false;
> +      case TCTX_OMP_PRIVATE:
> +	error_at (loc, "SVE type %qT not allowed in target private clause", type);
> +	return false;
> +      case TCTX_OMP_FIRSTPRIVATE:
> +	error_at (loc, "SVE type %qT not allowed in target firstprivate clause", type);
> +	return false;
> +      case TCTX_OMP_DEVICE_ADDR:
> +	error_at (loc, "SVE type %qT not allowed in target device clauses", type);
> +	return false;
> +      default:
> +	break;
> +    }
> +
>    if (!sizeless_type_p (type))
>      return true;
>  
> @@ -5060,6 +5083,14 @@ verify_type_context (location_t loc, type_context_kind context,
>        if (!silent_p)
>  	error_at (loc, "capture by copy of SVE type %qT", type);
>        return false;
> +
> +    case TCTX_OMP_MAP:
> +    case TCTX_OMP_MAP_IMP_REF:
> +    case TCTX_OMP_PRIVATE:
> +    case TCTX_OMP_FIRSTPRIVATE:
> +    case TCTX_OMP_DEVICE_ADDR:
> +    default:
> +      break;
>      }
>    gcc_unreachable ();
>  }
> diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
> index d87eb433395..dc958d2f55d 100644
> --- a/gcc/gimplify.cc
> +++ b/gcc/gimplify.cc
> @@ -8349,11 +8349,13 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
>  			  | GOVD_MAP_ALLOC_ONLY)) == flags)
>  	    {
>  	      tree type = TREE_TYPE (decl);
> +	      location_t dummy = UNKNOWN_LOCATION;
>  
>  	      if (gimplify_omp_ctxp->target_firstprivatize_array_bases
>  		  && omp_privatize_by_reference (decl))
>  		type = TREE_TYPE (type);
> -	      if (!omp_mappable_type (type))
> +	      if (!omp_mappable_type (type)
> +		  || !verify_type_context (dummy, TCTX_OMP_MAP_IMP_REF, type))
>  		{
>  		  error ("%qD referenced in target region does not have "
>  			 "a mappable type", decl);
> @@ -12083,6 +12085,8 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
>        unsigned int flags;
>        tree decl;
>        auto_vec<omp_addr_token *, 10> addr_tokens;
> +      tree op = NULL_TREE;
> +      location_t loc = OMP_CLAUSE_LOCATION (c);
>  
>        if (grp_end && c == OMP_CLAUSE_CHAIN (grp_end))
>  	{
> @@ -12090,6 +12094,34 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
>  	  grp_end = NULL_TREE;
>  	}
>  
> +      if (code == OMP_TARGET || code == OMP_TARGET_DATA
> +	  || code == OMP_TARGET_ENTER_DATA || code == OMP_TARGET_EXIT_DATA)
> +	/* Do some target-specific type checks for map operands.  */
> +	switch (OMP_CLAUSE_CODE (c))
> +	  {
> +	  case OMP_CLAUSE_MAP:
> +	    op = OMP_CLAUSE_OPERAND (c, 0);
> +	    verify_type_context (loc, TCTX_OMP_MAP, TREE_TYPE (op));
> +	    break;
> +	  case OMP_CLAUSE_PRIVATE:
> +	    op = OMP_CLAUSE_OPERAND (c, 0);
> +	    verify_type_context (loc, TCTX_OMP_PRIVATE, TREE_TYPE (op));
> +	    break;
> +	  case OMP_CLAUSE_FIRSTPRIVATE:
> +	    op = OMP_CLAUSE_OPERAND (c, 0);
> +	    verify_type_context (loc, TCTX_OMP_FIRSTPRIVATE, TREE_TYPE (op));
> +	    break;
> +	  case OMP_CLAUSE_IS_DEVICE_PTR:
> +	  case OMP_CLAUSE_USE_DEVICE_ADDR:
> +	  case OMP_CLAUSE_USE_DEVICE_PTR:
> +	  case OMP_CLAUSE_HAS_DEVICE_ADDR:
> +	    op = OMP_CLAUSE_OPERAND (c, 0);
> +	    verify_type_context (loc, TCTX_OMP_DEVICE_ADDR, TREE_TYPE (op));
> +	    break;
> +	  default:
> +	    break;
> +	  }
> +
>        switch (OMP_CLAUSE_CODE (c))
>  	{
>  	case OMP_CLAUSE_PRIVATE:
> diff --git a/gcc/target.h b/gcc/target.h
> index c1f99b97b86..9cebd354fdb 100644
> --- a/gcc/target.h
> +++ b/gcc/target.h
> @@ -271,7 +271,24 @@ enum type_context_kind {
>    TCTX_EXCEPTIONS,
>  
>    /* Capturing objects of type T by value in a closure.  */
> -  TCTX_CAPTURE_BY_COPY
> +  TCTX_CAPTURE_BY_COPY,
> +
> +  /* Objects of type T appearing in OpenMP map clause.  */
> +  TCTX_OMP_MAP,
> +
> +  /* Objects of type T appearing in OpenMP target region
> +     without explicit map.  */
> +  TCTX_OMP_MAP_IMP_REF,
> +
> +  /* Objects of type T appearing in OpenMP private clause.  */
> +  TCTX_OMP_PRIVATE,
> +
> +  /* Objects of type T appearing in OpenMP firstprivate clause.  */
> +  TCTX_OMP_FIRSTPRIVATE,
> +
> +  /* Objects of type T appearing in OpenMP device clauses.  */
> +  TCTX_OMP_DEVICE_ADDR
> +
>  };
>  
>  enum poly_value_estimate_kind
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-1.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-1.c
> new file mode 100644
> index 00000000000..20dd478e079
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-1.c
> @@ -0,0 +1,237 @@
> +/* { dg-do compile } */
> +/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
> +
> +#include <arm_sve.h>
> +
> +#define N 256
> +
> +#ifndef CONSTRUCT
> +#define CONSTRUCT
> +#endif
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +    }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_data_map_1 ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +    }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_data_map_2 ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +    }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(tofrom: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, va);
> +      va = svadd_s32_z (svptrue_b32 (), vc, va);
> +    }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_map_data_enter_exit ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target enter data map(to: b, c)
> +
> +#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +      }
> +
> +#pragma omp target CONSTRUCT map(to: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, va);
> +	va = svadd_s32_z (svptrue_b32 (), vc, va);
> +      }
> +
> +#pragma omp target exit data map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_map_data_alloc_update ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target data map(to: b, c) map(alloc: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +{
> +#pragma omp target CONSTRUCT
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +      }
> +
> +/* Update va on the host from target.  */
> +#pragma omp target update from(va)
> +
> +#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, va);
> +	va = svadd_s32_z (svptrue_b32 (), vc, va);
> +      }
> +}
> +  return va;
> +}
> +
> +int64_t __attribute__ ((noinline))
> +omp_target_private ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int64_t res;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT private (va, vb, vc) map (to: b, c) map (from: res) /* { dg-error {SVE type 'svint32_t' not allowed in target private clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b);
> +      vc = svld1_s32 (svptrue_b32 (), c);
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +      res = svaddv_s32 (svptrue_b32 (), va);
> +    }
> +
> +  return res;
> +}
> +
> +int64_t __attribute__ ((noinline))
> +omp_target_firstprivate (svbool_t vp)
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int64_t res;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT firstprivate (vp) map (to: b, c) map (from: res)/* { dg-error {SVE type 'svbool_t' not allowed in target firstprivate clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (vp, b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (vp, c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (vp, vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +      res = svaddv_s32 (svptrue_b32 (), va);
> +    }
> +
> +  return res;
> +}
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-2.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-2.c
> new file mode 100644
> index 00000000000..efb4d274de8
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-2.c
> @@ -0,0 +1,198 @@
> +/* { dg-do compile } */
> +/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
> +
> +#include <arm_sve.h>
> +
> +#define N 256
> +
> +#ifndef CONSTRUCT
> +#define CONSTRUCT
> +#endif
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +      }
> +  }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_data_map_1 ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +      }
> +  }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_data_map_2 ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +      }
> +  }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(tofrom: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, va);
> +	va = svadd_s32_z (svptrue_b32 (), vc, va);
> +      }
> +  }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_map_data_enter_exit ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target enter data map(to: b, c)
> +
> +#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +      }
> +  }
> +
> +#pragma omp target CONSTRUCT map(to: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, va);
> +	va = svadd_s32_z (svptrue_b32 (), vc, va);
> +      }
> +  }
> +
> +#pragma omp target exit data map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_map_data_alloc_update ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target data map(to: b, c) map(alloc: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +{
> +#pragma omp target CONSTRUCT
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +      }
> +  }
> +
> +/* Update va on the host from target.  */
> +#pragma omp target update from(va)
> +
> +#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, va);
> +	va = svadd_s32_z (svptrue_b32 (), vc, va);
> +      }
> +  }
> +}
> +  return va;
> +}
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel-loop.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel-loop.c
> new file mode 100644
> index 00000000000..4c6a0d4d96a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel-loop.c
> @@ -0,0 +1,236 @@
> +/* { dg-do compile } */
> +/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
> +
> +#include <arm_sve.h>
> +
> +#define N 256
> +#define CONSTRUCT parallel loop
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +    }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_data_map_1 ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +    }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_data_map_2 ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +    }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(tofrom: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, va);
> +      va = svadd_s32_z (svptrue_b32 (), vc, va);
> +    }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_map_data_enter_exit ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target enter data map(to: b, c)
> +
> +#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +      }
> +
> +#pragma omp target CONSTRUCT map(to: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, va);
> +	va = svadd_s32_z (svptrue_b32 (), vc, va);
> +      }
> +
> +#pragma omp target exit data map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_map_data_alloc_update ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target data map(to: b, c) map(alloc: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +{
> +#pragma omp target CONSTRUCT
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +      }
> +
> +/* Update va on the host from target.  */
> +#pragma omp target update from(va)
> +
> +#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, va);
> +	va = svadd_s32_z (svptrue_b32 (), vc, va);
> +      }
> +}
> +  return va;
> +}
> +
> +int64_t __attribute__ ((noinline))
> +omp_target_private ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int64_t res;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +/* Combined construct scenario: here private applies to the parallel loop
> +   construct, so no error.  */
> +#pragma omp target CONSTRUCT private (va, vb, vc) map (to: b, c) map (from: res)
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b);
> +      vc = svld1_s32 (svptrue_b32 (), c);
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +      res = svaddv_s32 (svptrue_b32 (), va);
> +    }
> +
> +  return res;
> +}
> +
> +int64_t __attribute__ ((noinline))
> +omp_target_firstprivate (svbool_t vp)
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int64_t res;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT firstprivate (vp) map (to: b, c) map (from: res)/* { dg-error {SVE type 'svbool_t' not allowed in target firstprivate clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (vp, b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (vp, c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (vp, vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +      res = svaddv_s32 (svptrue_b32 (), va);
> +    }
> +
> +  return res;
> +}
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel.c
> new file mode 100644
> index 00000000000..39dcd39a5f5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel.c
> @@ -0,0 +1,195 @@
> +/* { dg-do compile } */
> +/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
> +
> +#include <arm_sve.h>
> +
> +#define CONSTRUCT parallel
> +#define N 256
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +      }
> +  }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_data_map_1 ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +      }
> +  }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_data_map_2 ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +      }
> +  }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(tofrom: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, va);
> +	va = svadd_s32_z (svptrue_b32 (), vc, va);
> +      }
> +  }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_map_data_enter_exit ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target enter data map(to: b, c)
> +
> +#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +      }
> +  }
> +
> +#pragma omp target CONSTRUCT map(to: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, va);
> +	va = svadd_s32_z (svptrue_b32 (), vc, va);
> +      }
> +  }
> +
> +#pragma omp target exit data map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_map_data_alloc_update ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target data map(to: b, c) map(alloc: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +{
> +#pragma omp target CONSTRUCT
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +      }
> +  }
> +
> +/* Update va on the host from target.  */
> +#pragma omp target update from(va)
> +
> +#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, va);
> +	va = svadd_s32_z (svptrue_b32 (), vc, va);
> +      }
> +  }
> +}
> +  return va;
> +}
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-simd.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-simd.c
> new file mode 100644
> index 00000000000..2bb2a884fcf
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-simd.c
> @@ -0,0 +1,236 @@
> +/* { dg-do compile } */
> +/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
> +
> +#include <arm_sve.h>
> +
> +#define N 256
> +#define CONSTRUCT simd
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +    }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_data_map_1 ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +    }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_data_map_2 ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +    }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(tofrom: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, va);
> +      va = svadd_s32_z (svptrue_b32 (), vc, va);
> +    }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_map_data_enter_exit ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target enter data map(to: b, c)
> +
> +#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +      }
> +
> +#pragma omp target CONSTRUCT map(to: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, va);
> +	va = svadd_s32_z (svptrue_b32 (), vc, va);
> +      }
> +
> +#pragma omp target exit data map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_map_data_alloc_update ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target data map(to: b, c) map(alloc: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +{
> +#pragma omp target CONSTRUCT
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +      }
> +
> +/* Update va on the host from target.  */
> +#pragma omp target update from(va)
> +
> +#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, va);
> +	va = svadd_s32_z (svptrue_b32 (), vc, va);
> +      }
> +}
> +  return va;
> +}
> +
> +int64_t __attribute__ ((noinline))
> +omp_target_private ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int64_t res;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +/* Combined construct scenario: here private applies to the simd construct so
> +   no error.  */
> +#pragma omp target CONSTRUCT private (va, vb, vc) map (to: b, c) map (from: res)
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b);
> +      vc = svld1_s32 (svptrue_b32 (), c);
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +      res = svaddv_s32 (svptrue_b32 (), va);
> +    }
> +
> +  return res;
> +}
> +
> +int64_t __attribute__ ((noinline))
> +omp_target_firstprivate (svbool_t vp)
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int64_t res;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT firstprivate (vp) map (to: b, c) map (from: res)/* { dg-error {SVE type 'svbool_t' not allowed in target firstprivate clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (vp, b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (vp, c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (vp, vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +      res = svaddv_s32 (svptrue_b32 (), va);
> +    }
> +
> +  return res;
> +}
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute-simd.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute-simd.c
> new file mode 100644
> index 00000000000..6a61883e80a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute-simd.c
> @@ -0,0 +1,237 @@
> +/* { dg-do compile } */
> +/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
> +
> +#include <arm_sve.h>
> +
> +#define N 256
> +#define CONSTRUCT teams distribute simd
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +    }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_data_map_1 ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +    }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_data_map_2 ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +    }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(tofrom: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, va);
> +      va = svadd_s32_z (svptrue_b32 (), vc, va);
> +    }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_map_data_enter_exit ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target enter data map(to: b, c)
> +
> +#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +      }
> +
> +#pragma omp target CONSTRUCT map(to: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, va);
> +	va = svadd_s32_z (svptrue_b32 (), vc, va);
> +      }
> +
> +#pragma omp target exit data map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_map_data_alloc_update ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target data map(to: b, c) map(alloc: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +{
> +#pragma omp target CONSTRUCT
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +      }
> +
> +/* Update va on the host from target.  */
> +#pragma omp target update from(va)
> +
> +#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, va);
> +	va = svadd_s32_z (svptrue_b32 (), vc, va);
> +      }
> +}
> +  return va;
> +}
> +
> +int64_t __attribute__ ((noinline))
> +omp_target_private ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int64_t res;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +/* Combined construct scenario: here private applies to the distribute simd
> +   construct, so no error.  */
> +#pragma omp target CONSTRUCT private (va, vb, vc) map (to: b, c) map (from: res)
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b);
> +      vc = svld1_s32 (svptrue_b32 (), c);
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +      res = svaddv_s32 (svptrue_b32 (), va);
> +    }
> +
> +  return res;
> +}
> +
> +int64_t __attribute__ ((noinline))
> +omp_target_firstprivate (svbool_t vp)
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int64_t res;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT firstprivate (vp) map (to: b, c) map (from: res)/* { dg-error {SVE type 'svbool_t' not allowed in target firstprivate clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (vp, b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (vp, c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (vp, vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +      res = svaddv_s32 (svptrue_b32 (), va);
> +    }
> +
> +  return res;
> +}
> +
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute.c
> new file mode 100644
> index 00000000000..6852d427866
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute.c
> @@ -0,0 +1,236 @@
> +/* { dg-do compile } */
> +/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
> +
> +#include <arm_sve.h>
> +
> +#define N 256
> +#define CONSTRUCT teams distribute
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +    }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_data_map_1 ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +    }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_data_map_2 ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +    }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(tofrom: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, va);
> +      va = svadd_s32_z (svptrue_b32 (), vc, va);
> +    }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_map_data_enter_exit ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target enter data map(to: b, c)
> +
> +#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +      }
> +
> +#pragma omp target CONSTRUCT map(to: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, va);
> +	va = svadd_s32_z (svptrue_b32 (), vc, va);
> +      }
> +
> +#pragma omp target exit data map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_map_data_alloc_update ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target data map(to: b, c) map(alloc: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +{
> +#pragma omp target CONSTRUCT
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +      }
> +
> +/* Update va on the host from target.  */
> +#pragma omp target update from(va)
> +
> +#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, va);
> +	va = svadd_s32_z (svptrue_b32 (), vc, va);
> +      }
> +}
> +  return va;
> +}
> +
> +int64_t __attribute__ ((noinline))
> +omp_target_private ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int64_t res;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +/* Combined construct scenario: here private applies to the teams distribute
> +   construct, so no error.  */
> +#pragma omp target CONSTRUCT private (va, vb, vc) map (to: b, c) map (from: res)
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b);
> +      vc = svld1_s32 (svptrue_b32 (), c);
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +      res = svaddv_s32 (svptrue_b32 (), va);
> +    }
> +
> +  return res;
> +}
> +
> +int64_t __attribute__ ((noinline))
> +omp_target_firstprivate (svbool_t vp)
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int64_t res;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT firstprivate (vp) map (to: b, c) map (from: res)/* { dg-error {SVE type 'svbool_t' not allowed in target firstprivate clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (vp, b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (vp, c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (vp, vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +      res = svaddv_s32 (svptrue_b32 (), va);
> +    }
> +
> +  return res;
> +}
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-loop.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-loop.c
> new file mode 100644
> index 00000000000..aad6c47067c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-loop.c
> @@ -0,0 +1,237 @@
> +/* { dg-do compile } */
> +/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
> +
> +#include <arm_sve.h>
> +
> +#define N 256
> +#define CONSTRUCT teams loop
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +    }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_data_map_1 ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +    }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_data_map_2 ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +    }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(tofrom: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (svptrue_b32 (), vb, va);
> +      va = svadd_s32_z (svptrue_b32 (), vc, va);
> +    }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_map_data_enter_exit ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target enter data map(to: b, c)
> +
> +#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +      }
> +
> +#pragma omp target CONSTRUCT map(to: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, va);
> +	va = svadd_s32_z (svptrue_b32 (), vc, va);
> +      }
> +
> +#pragma omp target exit data map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_map_data_alloc_update ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target data map(to: b, c) map(alloc: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +{
> +#pragma omp target CONSTRUCT
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +      }
> +
> +/* Update va on the host from target.  */
> +#pragma omp target update from(va)
> +
> +#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, va);
> +	va = svadd_s32_z (svptrue_b32 (), vc, va);
> +      }
> +}
> +  return va;
> +}
> +
> +int64_t __attribute__ ((noinline))
> +omp_target_private ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int64_t res;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +/* Combined construct scenario: here private applies to the teams loop
> +   construct, so no error.  */
> +#pragma omp target CONSTRUCT private (va, vb, vc) map (to: b, c) map (from: res)
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (svptrue_b32 (), b);
> +      vc = svld1_s32 (svptrue_b32 (), c);
> +      va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +      res = svaddv_s32 (svptrue_b32 (), va);
> +    }
> +
> +  return res;
> +}
> +
> +int64_t __attribute__ ((noinline))
> +omp_target_firstprivate (svbool_t vp)
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int64_t res;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT firstprivate (vp) map (to: b, c) map (from: res)/* { dg-error {SVE type 'svbool_t' not allowed in target firstprivate clause} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (vp, b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (vp, c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (vp, vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +      res = svaddv_s32 (svptrue_b32 (), va);
> +    }
> +
> +  return res;
> +}
> +
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams.c
> new file mode 100644
> index 00000000000..a4269108166
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams.c
> @@ -0,0 +1,195 @@
> +/* { dg-do compile } */
> +/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
> +
> +#include <arm_sve.h>
> +
> +#define N 256
> +#define CONSTRUCT teams
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +      }
> +  }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_data_map_1 ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +      }
> +  }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_data_map_2 ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +      }
> +  }
> +
> +#pragma omp target CONSTRUCT map(to: b, c) map(tofrom: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, va);
> +	va = svadd_s32_z (svptrue_b32 (), vc, va);
> +      }
> +  }
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_map_data_enter_exit ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target enter data map(to: b, c)
> +
> +#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc);
> +      }
> +  }
> +
> +#pragma omp target CONSTRUCT map(to: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, va);
> +	va = svadd_s32_z (svptrue_b32 (), vc, va);
> +      }
> +  }
> +
> +#pragma omp target exit data map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +
> +  return va;
> +}
> +
> +svint32_t
> +__attribute__ ((noinline))
> +omp_target_map_data_alloc_update ()
> +{
> +
> +  int a[N], b[N], c[N];
> +  svint32_t va, vb, vc;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target data map(to: b, c) map(alloc: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +{
> +#pragma omp target CONSTRUCT
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +      }
> +  }
> +
> +/* Update va on the host from target.  */
> +#pragma omp target update from(va)
> +
> +#pragma omp target CONSTRUCT map(from: va) /* { dg-error {SVE type 'svint32_t' not allowed in map clause} } */
> +  {
> +    for (i = 0; i < 8; i++)
> +      {
> +	vb = svld1_s32 (svptrue_b32 (), b); /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +	vc = svld1_s32 (svptrue_b32 (), c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +	va = svadd_s32_z (svptrue_b32 (), vb, va);
> +	va = svadd_s32_z (svptrue_b32 (), vc, va);
> +      }
> +  }
> +}
> +  return va;
> +}
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/target-device.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/target-device.c
> new file mode 100644
> index 00000000000..4c92015837f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/target-device.c
> @@ -0,0 +1,97 @@
> +/* { dg-do compile } */
> +/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
> +
> +#include <arm_sve.h>
> +
> +#define N 256
> +
> +typedef __SVInt32_t v8si __attribute__((arm_sve_vector_bits(256)));
> +
> +int64_t __attribute__ ((noinline))
> +omp_target_device_ptr (svbool_t vp, v8si *vptr)
> +{
> +
> +  int a[N], b[N], c[N];
> +  v8si va, vb, vc;
> +  int64_t res;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target data use_device_ptr (vptr) map (to: b, c) /* { dg-error {SVE type 'v8si \*' {aka 'svint32_t __attribute__\(\(arm_sve_vector_bits\([0-9]+\)\)\) \*'} not allowed in target device clauses} } */
> +#pragma omp target is_device_ptr (vptr) map (to: b, c) map (from: res) /* { dg-error {SVE type 'v8si \*' {aka 'svint32_t __attribute__\(\(arm_sve_vector_bits\(256\)\)\) \*'} not allowed in target device clauses} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = *vptr; /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (vp, c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +			      /* { dg-error {'vp' referenced in target region does not have a mappable type} "" { target *-*-* } .-1 } */
> +      va = svadd_s32_z (vp, vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +      res = svaddv_s32 (svptrue_b32 (), va);
> +    }
> +
> +  return res;
> +}
> +
> +int64_t __attribute__ ((noinline))
> +omp_target_device_addr (svbool_t vp, v8si *vptr)
> +{
> +
> +  int a[N], b[N], c[N];
> +  v8si va, vb, vc;
> +  int64_t res;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target data use_device_addr (vb) map (to: b, c) /* { dg-error {SVE type 'v8si' {aka 'svint32_t __attribute__\(\(arm_sve_vector_bits\(256\)\)\)'} not allowed in target device clauses} } */
> +#pragma omp target is_device_ptr (vptr) map (to: b, c) map (from: res) /* { dg-error {SVE type 'v8si \*' {aka 'svint32_t __attribute__\(\(arm_sve_vector_bits\(256\)\)\) \*'} not allowed in target device clauses} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = *vptr; /* { dg-error {'vb' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (vp, c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +			      /* { dg-error {'vp' referenced in target region does not have a mappable type} "" { target *-*-* } .-1 } */
> +      va = svadd_s32_z (vp, vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +      res = svaddv_s32 (svptrue_b32 (), va);
> +    }
> +
> +  return res;
> +}
> +
> +int64_t __attribute__ ((noinline))
> +omp_target_has_device_addr (svbool_t vp, v8si *vptr)
> +{
> +
> +  int a[N], b[N], c[N];
> +  v8si va, vb, vc;
> +  int64_t res;
> +  int i;
> +
> +#pragma omp parallel for
> +  for (i = 0; i < N; i++)
> +    {
> +      b[i] = i;
> +      c[i] = i + 1;
> +    }
> +
> +#pragma omp target data use_device_addr (vb) map (to: b, c) /* { dg-error {SVE type 'v8si' {aka 'svint32_t __attribute__\(\(arm_sve_vector_bits\(256\)\)\)'} not allowed in target device clauses} } */
> +#pragma omp target has_device_addr (vb) map (to: b, c) map (from: res) /* { dg-error {SVE type 'v8si' {aka 'svint32_t __attribute__\(\(arm_sve_vector_bits\(256\)\)\)'} not allowed in target device clauses} } */
> +  for (i = 0; i < 8; i++)
> +    {
> +      vb = svld1_s32 (vp, b); /* { dg-error {'vp' referenced in target region does not have a mappable type} } */
> +      vc = svld1_s32 (vp, c); /* { dg-error {'vc' referenced in target region does not have a mappable type} } */
> +      va = svadd_s32_z (vp, vb, vc); /* { dg-error {'va' referenced in target region does not have a mappable type} } */
> +      res = svaddv_s32 (svptrue_b32 (), va);
> +    }
> +
> +  return res;
> +}
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/omp/target-link.c b/gcc/testsuite/gcc.target/aarch64/sve/omp/target-link.c
> new file mode 100644
> index 00000000000..a6e80cfd559
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/omp/target-link.c
> @@ -0,0 +1,48 @@
> +/* { dg-do compile } */
> +/* { dg-options "-msve-vector-bits=256 -std=gnu99 -fopenmp -O2 -fdump-tree-ompexp" } */
> +
> +#include <arm_sve.h>
> +
> +typedef __SVInt32_t v8si __attribute__((arm_sve_vector_bits(256)));
> +
> +static v8si local_vec;
> +#pragma omp declare target link(local_vec)
> +
> +v8si global_vec;
> +#pragma omp declare target link(global_vec)
> +
> +void
> +one_get_inc2_local_vec ()
> +{
> +  v8si res, res2, tmp;
> +
> +#pragma omp target map(from: res, res2) /* { dg-error {SVE type 'v8si' {aka 'svint32_t __attribute__\(\(arm_sve_vector_bits\(256\)\)\)'} not allowed in map clause} } */
> +  {
> +    res = local_vec; /* { dg-error {'local_vec' referenced in target region does not have a mappable type} } */
> +    local_vec = svadd_s32_z (svptrue_b32 (), local_vec, local_vec);
> +    res2 = local_vec;
> +  }
> +
> +  tmp = svadd_s32_z (svptrue_b32 (), res, res);
> +  svbool_t p = svcmpne_s32 (svptrue_b32 (), tmp, res2);
> +  if (svptest_any (svptrue_b32 (), p))
> +    __builtin_abort ();
> +}
> +
> +void
> +one_get_inc3_global_vec ()
> +{
> +  v8si res, res2, tmp;
> +
> +#pragma omp target map(from: res, res2) /* { dg-error {SVE type 'v8si' {aka 'svint32_t __attribute__\(\(arm_sve_vector_bits\(256\)\)\)'} not allowed in map clause} } */
> +  {
> +    res = global_vec; /* { dg-error {'global_vec' referenced in target region does not have a mappable type} } */
> +    global_vec = svadd_s32_z (svptrue_b32 (), global_vec, global_vec);
> +    res2 = global_vec;
> +  }
> +
> +  tmp = svadd_s32_z (svptrue_b32 (), res, res);
> +  svbool_t p = svcmpne_s32 (svptrue_b32 (), tmp, res2);
> +  if (svptest_any (svptrue_b32 (), p))
> +    __builtin_abort ();
> +}

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 01/11] OpenMP/PolyInt: Pass poly-int structures by address to OMP libs.
  2024-05-27  5:06 ` [PATCH 01/11] OpenMP/PolyInt: Pass poly-int structures by address to OMP libs Tejas Belagod
@ 2024-05-30 12:58   ` Richard Sandiford
  2024-05-31  6:30     ` Tejas Belagod
  0 siblings, 1 reply; 22+ messages in thread
From: Richard Sandiford @ 2024-05-30 12:58 UTC (permalink / raw)
  To: Tejas Belagod; +Cc: gcc-patches, jakub

Tejas Belagod <tejas.belagod@arm.com> writes:
> Currently poly-int type structures are passed by value to OpenMP runtime
> functions for shared clauses etc.  This patch improves on this by passing
> around poly-int structures by address to avoid copy-overhead.
>
> gcc/ChangeLog
> 	* omp-low.c (use_pointer_for_field): Use pointer if the OMP data
> 	structure's field type is a poly-int.
> ---
>  gcc/omp-low.cc | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
> index 1a65229cc37..b15607f4ef5 100644
> --- a/gcc/omp-low.cc
> +++ b/gcc/omp-low.cc
> @@ -466,7 +466,8 @@ static bool
>  use_pointer_for_field (tree decl, omp_context *shared_ctx)
>  {
>    if (AGGREGATE_TYPE_P (TREE_TYPE (decl))
> -      || TYPE_ATOMIC (TREE_TYPE (decl)))
> +      || TYPE_ATOMIC (TREE_TYPE (decl))
> +      || POLY_INT_CST_P (DECL_SIZE (decl)))
>      return true;
>  
>    /* We can only use copy-in/copy-out semantics for shared variables

Realise this is also true of my original patch, but:

I suppose a question here is whether this function is only ever used for
local interfaces between code generated by the same source code function,
or whether it's ABI in a more general sense.  If the latter, I suppose
we should make sure to handle ACLE types the same way regardless of
whether the SVE vector size is known.

(At the moment, the vector size is fixed for a TU, not just a function,
but we should probably plan for relaxing that in future.)

Thanks,
Richard

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 00/11] AArch64/OpenMP: Test SVE ACLE types with various OpenMP constructs.
  2024-05-27  5:06 [PATCH 00/11] AArch64/OpenMP: Test SVE ACLE types with various OpenMP constructs Tejas Belagod
                   ` (10 preceding siblings ...)
  2024-05-27  5:06 ` [PATCH 11/11] AArch64: Diagnose SVE type objects when applied to OpenMP doacross clause Tejas Belagod
@ 2024-05-30 12:58 ` Richard Sandiford
  2024-06-20  4:46 ` Tejas Belagod
  12 siblings, 0 replies; 22+ messages in thread
From: Richard Sandiford @ 2024-05-30 12:58 UTC (permalink / raw)
  To: Tejas Belagod; +Cc: gcc-patches, jakub

Tejas Belagod <tejas.belagod@arm.com> writes:
> Note: This patch series is based on Richard's initial patch
>   https://gcc.gnu.org/pipermail/gcc-patches/2022-November/606741.html
> and Jakub's suggestion
>   https://gcc.gnu.org/pipermail/gcc-patches/2023-February/611892.html
>
> The following patch series handles various scenarios with OpenMP and SVE types.
> The starting point for the series follows a suggestion from Jakub to cover all 
> the possible scenarios that could arise when OMP constructs/clauses etc are 
> used with SVE ACLE types. Here are a few instances that this patch series tests
> and in some cases fixes the expected output.  This patch series does not follow
> a formal definition or a spec of how OMP interacts with SVE ACLE types, so it's 
> more of a proposed behaviour.  Comments and discussion welcome.

Thanks for doing this.  I've left some comments on individual patches,
but generally the series looks good from my limited abilit to evaluate it.
Hopefully Jakub can say whether this catches all the cases that matter.

Richard

> This list is not exhaustive, but covers most scenarios of how SVE ACLE types
> ought to interact with OMP constructs/clauses.
>
> 1. Poly-int structures that represent variable-sized objects and OMP runtime.
>
> Currently poly-int type structures are passed by value to OpenMP runtime
> functions for shared clauses etc.  This patch improves on this by passing
> around poly-int structures by address to avoid copy-overhead.
>
> 2. SVE ACLE types in OMP Shared clauses.
>
> We test the behaviour where SVE ACLE type objects are shared in the following
> methods into an OMP region:
>   a. Explicit Shared clause on SVE ACLE type objects.
>   b. Implicit shared clause.
>   c. Implicit shared with default clause.
>   d. SVE ALCE types in the presence of predetermined (static) shared objects.
>
> The associated tests ensure that all such shared objects are passed by address
> into the OMP runtime.  There are runtime tests to verify the functional
> correctness of the change.
>
> 3. Offloading and SVE ACLE types.
>
> The target clause in OpenMP is used to offload loop kernels to accelerator
> peripeherals.  target's 'map' clause is used to move data from and to the 
> accelarator.  When the data is SVE type, it may not be suitable because of
> various reasons i.e. the two SVE targets may not agree on vector size or
> some targets don't support variable vector size.  This makes SVE unsuitable
> for use in OMP's 'map' clause.  We diagnose all such cases and issue errors
> where appropriate.  The cases we cover in this patch are:
>
>   a. Implicitly-mapped SVE ACLE types in OMP target regions are diagnosed.
>   b. Explicitly-mapped SVE ACLE types in OMP target regions using map clause
>      are diagnosed.
>   c. Explicilty-mapped SVLE ACLE types of various directions - to, from, tofrom
>      in the map clause are diagnosed.
>   d. target enter and exit data clauses with map on SVE ACLE types are 
>      diagnosed.
>   e. target data map with alloc on SVE ACLE types are diagnosed.
>   f. target update from clause on SVE ACLE types are diagnosed.
>   g. target private firstprivate with SVE ACLE types are diagnosed.
>   h. All combinations of target with work-sharing constructs like parallel,
>      loop, simd, teams, distribute etc are also diagnosed when SVE ACLE types
>      are involved.
>
> 3. Lastprivate and SVE ACLE types.
>
> Various OpenMP lastprivate clause scenarios with SVE object types are 
> diagnosed.  Worksharing constructs like sections, for, distribute bind to an
> implicit outer parallel region in whose scope SVE ACLE types are declared and 
> are therefore default private.  The lastprivate clause list with SVE ACLE type
> object items are diagnosed in this scenario.
>
> 4. Threadprivate on SVE ACLE type objects.
>
> We ensure threadprivate SVE ACLE type objects are supported. We also ensure
> copyin clause is also supported.
>
> 5. User-Defined Reductions on SVE ACLE types.
>
> We define a reduction using OMP declare reduction using SVE ACLE intrinsics and
> ensure its functional correctness with various work-sharing constructs like
> for, simd, parallel, task, taskloop.
>
> 6. Uniform and Aligned Clause with SVE ACLE
>
> We ensure the uniform clause's functional correctness with simd construct and
> associated SVE ACLE intrinsics in the simd region.  There is no direct
> interaction between uniform and SVE ACLE type objects, but we ensure the uniform
> clause applies correctly to a region where SVE ACLE intrinsics are present.
> Similarly for the aligned clause.
>
> 7. Linear clause and SVE ACLE type.
>
> We diagnose if a linear clause list item has SVE ACLE type objects present.
> Its doesn't mean much if the linear clause is applied to SVE ACLE types.
>
> 8. Depend clause and SVE ACLE objects.
>
> We test for functional correctness many combinations of dependency of shared
> SVE ACLE type objects in parallel regions.  We test if in, out dependencies and
> anti-dependencies are supported for SVE ACLE type objects using the depend
> clause with work-sharing constructs like task.
>
> 9. 'doacross' clause and SVE ACLE object types.
>
> doacross is mainly supported for scalars and loop iteration variables.  We
> diagnose cases where SVE ACLE objects are used in doacross list items.
>
> Tejas Belagod (11):
>   OpenMP/PolyInt: Pass poly-int structures by address to OMP libs.
>   AArch64: Add test cases for SVE types in OpenMP shared clause.
>   AArch64: Diagnose OpenMP offloading when SVE types involved.
>   AArch64: Test OpenMP lastprivate clause for various constructs.
>   AArch64: Test OpenMP threadprivate clause on SVE type.
>   AArch64: Test OpenMP user-defined reductions with SVE types.
>   AArch64: Test OpenMP uniform clause on SVE types.
>   AArch64: Test OpenMP simd aligned clause with SVE types.
>   AArch64: Diagnose OpenMP linear clause for SVE type objects.
>   AArch64: Test OpenMP depend clause and its variations on SVE types
>   AArch64: Diagnose SVE type objects when applied to OpenMP doacross
>     clause.
>
>  gcc/config/aarch64/aarch64-sve-builtins.cc    |  31 +++
>  gcc/gimplify.cc                               |  34 ++-
>  gcc/omp-low.cc                                |   3 +-
>  gcc/target.h                                  |  19 +-
>  .../aarch64/sve/omp/aarch64-sve-omp.exp       |  80 ++++++
>  .../gcc.target/aarch64/sve/omp/depend-1.c     | 223 ++++++++++++++++
>  .../gcc.target/aarch64/sve/omp/doacross.c     |  22 ++
>  .../gcc.target/aarch64/sve/omp/lastprivate.c  | 121 +++++++++
>  .../gcc.target/aarch64/sve/omp/linear.c       |  33 +++
>  .../gcc.target/aarch64/sve/omp/offload-1.c    | 237 ++++++++++++++++++
>  .../gcc.target/aarch64/sve/omp/offload-2.c    | 198 +++++++++++++++
>  .../aarch64/sve/omp/offload-parallel-loop.c   | 236 +++++++++++++++++
>  .../aarch64/sve/omp/offload-parallel.c        | 195 ++++++++++++++
>  .../gcc.target/aarch64/sve/omp/offload-simd.c | 236 +++++++++++++++++
>  .../sve/omp/offload-teams-distribute-simd.c   | 237 ++++++++++++++++++
>  .../sve/omp/offload-teams-distribute.c        | 236 +++++++++++++++++
>  .../aarch64/sve/omp/offload-teams-loop.c      | 237 ++++++++++++++++++
>  .../aarch64/sve/omp/offload-teams.c           | 195 ++++++++++++++
>  .../gcc.target/aarch64/sve/omp/shared.c       | 186 ++++++++++++++
>  .../gcc.target/aarch64/sve/omp/simd-aligned.c |  50 ++++
>  .../gcc.target/aarch64/sve/omp/simd-uniform.c |  71 ++++++
>  .../aarch64/sve/omp/target-device.c           |  97 +++++++
>  .../gcc.target/aarch64/sve/omp/target-link.c  |  48 ++++
>  .../aarch64/sve/omp/threadprivate.c           |  44 ++++
>  .../gcc.target/aarch64/sve/omp/udr-sve.c      | 166 ++++++++++++
>  25 files changed, 3232 insertions(+), 3 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/aarch64-sve-omp.exp
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/depend-1.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/doacross.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/lastprivate.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/linear.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-1.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-2.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel-loop.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-simd.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute-simd.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-loop.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/shared.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/simd-aligned.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/simd-uniform.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/target-device.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/target-link.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/threadprivate.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/udr-sve.c

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 01/11] OpenMP/PolyInt: Pass poly-int structures by address to OMP libs.
  2024-05-30 12:58   ` Richard Sandiford
@ 2024-05-31  6:30     ` Tejas Belagod
  2024-05-31  7:45       ` Richard Sandiford
  0 siblings, 1 reply; 22+ messages in thread
From: Tejas Belagod @ 2024-05-31  6:30 UTC (permalink / raw)
  To: gcc-patches, jakub, richard.sandiford

On 5/30/24 6:28 PM, Richard Sandiford wrote:
> Tejas Belagod <tejas.belagod@arm.com> writes:
>> Currently poly-int type structures are passed by value to OpenMP runtime
>> functions for shared clauses etc.  This patch improves on this by passing
>> around poly-int structures by address to avoid copy-overhead.
>>
>> gcc/ChangeLog
>> 	* omp-low.c (use_pointer_for_field): Use pointer if the OMP data
>> 	structure's field type is a poly-int.
>> ---
>>   gcc/omp-low.cc | 3 ++-
>>   1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
>> index 1a65229cc37..b15607f4ef5 100644
>> --- a/gcc/omp-low.cc
>> +++ b/gcc/omp-low.cc
>> @@ -466,7 +466,8 @@ static bool
>>   use_pointer_for_field (tree decl, omp_context *shared_ctx)
>>   {
>>     if (AGGREGATE_TYPE_P (TREE_TYPE (decl))
>> -      || TYPE_ATOMIC (TREE_TYPE (decl)))
>> +      || TYPE_ATOMIC (TREE_TYPE (decl))
>> +      || POLY_INT_CST_P (DECL_SIZE (decl)))
>>       return true;
>>   
>>     /* We can only use copy-in/copy-out semantics for shared variables
> 

Thanks for the reviews.

> Realise this is also true of my original patch, but:
> 
> I suppose a question here is whether this function is only ever used for
> local interfaces between code generated by the same source code function,
> or whether it's ABI in a more general sense.  

I'm not a 100% sure, but AFAICS, 'use_pointer_for_field' seems to be 
used only for local interface between source and generated functions. I 
don't see any backend hooks into this or backend hooking into this 
function for general ABI. Ofcourse, I'm not the expert on OMP lowering, 
so it would be great to get an expert opinion on this.

> If the latter, I suppose
> we should make sure to handle ACLE types the same way regardless of
> whether the SVE vector size is known.
> 

When you say same way, do you mean the way SVE ABI defines the rules for 
SVE types?

Thanks,
Tejas.

> (At the moment, the vector size is fixed for a TU, not just a function,
> but we should probably plan for relaxing that in future.)
> 
> Thanks,
> Richard


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 02/11] AArch64: Add test cases for SVE types in OpenMP shared clause.
  2024-05-30 12:38   ` Richard Sandiford
@ 2024-05-31  7:01     ` Tejas Belagod
  0 siblings, 0 replies; 22+ messages in thread
From: Tejas Belagod @ 2024-05-31  7:01 UTC (permalink / raw)
  To: gcc-patches, jakub, richard.sandiford

On 5/30/24 6:08 PM, Richard Sandiford wrote:
> Tejas Belagod <tejas.belagod@arm.com> writes:
>> This patch tests various shared clauses with SVE types.  It also adds a test
>> scaffold to run OpenMP tests in under the gcc.target testsuite.
>>
>> gcc/testsuite/ChangeLog:
>>
>> 	* gcc.target/aarch64/sve/omp/aarch64-sve-omp.exp: New scaffold.
> 
> Hopefully Jakub can comment on whether we should test this in the
> GCC testsuite or libgomp testsuite.
> 
> On the test:
> 
>> [...]
>> +int
>> +main ()
>> +{
>> +  svint32_t x = svindex_s32 (0 ,1);
>> +  svint32_t y = svindex_s32 (8, 1);
>> +  svint32_t a, b;
>> +  svbool_t p;
>> +
>> +  /* Implicit shared.  */
>> +  a = foo (x, y, p);
>> +  b = implicit_shared_default (x, y, p);
> 
> It looks like p is used uninitialised here.  Can you check locally
> that using svptrue_b8 () (or whatever) as an initialiser allows the
> test to pass while svpfalse_b () causes it to fail?
> 

Oops, thanks for spotting that. Now verified - will wait for Jakub's 
comment on tests' home before I respin.

Thanks,
Tejas.

> Thanks,
> Richard
> 
>> +  compare_vec (a, b);
>> +
>> +  /* Explicit shared.  */
>> +  a = foo (x ,y, p);
>> +  b = explicit_shared (x, y, p);
>> +  compare_vec (a, b);
>> +
>> +  /* Implicit shared with no default clause.  */
>> +  a = foo (x ,y, p);
>> +  b = implicit_shared_no_default (x, y, p);
>> +  compare_vec (a, b);
>> +
>> +  /* Mix shared.  */
>> +  a = foo (x ,y, p);
>> +  b = mix_shared (y, p);
>> +  compare_vec (a, b);
>> +
>> +  /* Predetermined shared.  */
>> +  predetermined_shared_static (true);
>> +  predetermined_shared_static (false);
>> +
>> +  return 0;
>> +}
>> +
>> +/* { dg-final { scan-tree-dump-times "value-expr: \*.omp_data_i->a" 10 "ompexp" } } */


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 01/11] OpenMP/PolyInt: Pass poly-int structures by address to OMP libs.
  2024-05-31  6:30     ` Tejas Belagod
@ 2024-05-31  7:45       ` Richard Sandiford
  2024-05-31  8:01         ` Jakub Jelinek
  0 siblings, 1 reply; 22+ messages in thread
From: Richard Sandiford @ 2024-05-31  7:45 UTC (permalink / raw)
  To: Tejas Belagod; +Cc: gcc-patches, jakub

Tejas Belagod <tejas.belagod@arm.com> writes:
> On 5/30/24 6:28 PM, Richard Sandiford wrote:
>> Tejas Belagod <tejas.belagod@arm.com> writes:
>>> Currently poly-int type structures are passed by value to OpenMP runtime
>>> functions for shared clauses etc.  This patch improves on this by passing
>>> around poly-int structures by address to avoid copy-overhead.
>>>
>>> gcc/ChangeLog
>>> 	* omp-low.c (use_pointer_for_field): Use pointer if the OMP data
>>> 	structure's field type is a poly-int.
>>> ---
>>>   gcc/omp-low.cc | 3 ++-
>>>   1 file changed, 2 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
>>> index 1a65229cc37..b15607f4ef5 100644
>>> --- a/gcc/omp-low.cc
>>> +++ b/gcc/omp-low.cc
>>> @@ -466,7 +466,8 @@ static bool
>>>   use_pointer_for_field (tree decl, omp_context *shared_ctx)
>>>   {
>>>     if (AGGREGATE_TYPE_P (TREE_TYPE (decl))
>>> -      || TYPE_ATOMIC (TREE_TYPE (decl)))
>>> +      || TYPE_ATOMIC (TREE_TYPE (decl))
>>> +      || POLY_INT_CST_P (DECL_SIZE (decl)))
>>>       return true;
>>>   
>>>     /* We can only use copy-in/copy-out semantics for shared variables
>> 
>
> Thanks for the reviews.
>
>> Realise this is also true of my original patch, but:
>> 
>> I suppose a question here is whether this function is only ever used for
>> local interfaces between code generated by the same source code function,
>> or whether it's ABI in a more general sense.  
>
> I'm not a 100% sure, but AFAICS, 'use_pointer_for_field' seems to be 
> used only for local interface between source and generated functions. I 
> don't see any backend hooks into this or backend hooking into this 
> function for general ABI. Ofcourse, I'm not the expert on OMP lowering, 
> so it would be great to get an expert opinion on this.
>
>> If the latter, I suppose
>> we should make sure to handle ACLE types the same way regardless of
>> whether the SVE vector size is known.
>> 
>
> When you say same way, do you mean the way SVE ABI defines the rules for 
> SVE types?

No, sorry, I meant that if the choice isn't purely local to a source
code function, the condition should be something like sizeless_type_p
(suitably abstracted) rather than POLY_INT_CST_P.  That way, the "ABI"
stays the same regardless of -msve-vector-bits.

Thanks,
Richard

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 01/11] OpenMP/PolyInt: Pass poly-int structures by address to OMP libs.
  2024-05-31  7:45       ` Richard Sandiford
@ 2024-05-31  8:01         ` Jakub Jelinek
  2024-05-31  8:23           ` Richard Sandiford
  0 siblings, 1 reply; 22+ messages in thread
From: Jakub Jelinek @ 2024-05-31  8:01 UTC (permalink / raw)
  To: Tejas Belagod, gcc-patches, richard.sandiford

On Fri, May 31, 2024 at 08:45:54AM +0100, Richard Sandiford wrote:
> > When you say same way, do you mean the way SVE ABI defines the rules for 
> > SVE types?
> 
> No, sorry, I meant that if the choice isn't purely local to a source
> code function, the condition should be something like sizeless_type_p
> (suitably abstracted) rather than POLY_INT_CST_P.  That way, the "ABI"
> stays the same regardless of -msve-vector-bits.

There is no ABI, it is how the caller and indirect callee communicate,
but both parts are compiled with the same compiler, so it can choose
differently based on different compiler version etc.
It is effectively simplified:
struct whatever { ... };
void callee (void *x) { struct whatever *w = *x; use *w; }
void caller (void) { struct whatever w; fill in w; ABI_call (callee, &w); }
(plus in some cases the callee can also update values and propagate that
back to caller).
In any case, it is a similar "ABI" to e.g. tree-nested.cc communication
between caller and nested callee, how exactly are the variables laid out
in a struct depends on compiler version and whatever it decides, same
compiler then emits both sides.

	Jakub


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 01/11] OpenMP/PolyInt: Pass poly-int structures by address to OMP libs.
  2024-05-31  8:01         ` Jakub Jelinek
@ 2024-05-31  8:23           ` Richard Sandiford
  0 siblings, 0 replies; 22+ messages in thread
From: Richard Sandiford @ 2024-05-31  8:23 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Tejas Belagod, gcc-patches

Jakub Jelinek <jakub@redhat.com> writes:
> On Fri, May 31, 2024 at 08:45:54AM +0100, Richard Sandiford wrote:
>> > When you say same way, do you mean the way SVE ABI defines the rules for 
>> > SVE types?
>> 
>> No, sorry, I meant that if the choice isn't purely local to a source
>> code function, the condition should be something like sizeless_type_p
>> (suitably abstracted) rather than POLY_INT_CST_P.  That way, the "ABI"
>> stays the same regardless of -msve-vector-bits.
>
> There is no ABI, it is how the caller and indirect callee communicate,
> but both parts are compiled with the same compiler, so it can choose
> differently based on different compiler version etc.
> It is effectively simplified:
> struct whatever { ... };
> void callee (void *x) { struct whatever *w = *x; use *w; }
> void caller (void) { struct whatever w; fill in w; ABI_call (callee, &w); }
> (plus in some cases the callee can also update values and propagate that
> back to caller).
> In any case, it is a similar "ABI" to e.g. tree-nested.cc communication
> between caller and nested callee, how exactly are the variables laid out
> in a struct depends on compiler version and whatever it decides, same
> compiler then emits both sides.

Ah, ok, thanks.  In that case I guess POLY_INT_CST_P should be
safe/correct after all.

Richard

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 00/11] AArch64/OpenMP: Test SVE ACLE types with various OpenMP constructs.
  2024-05-27  5:06 [PATCH 00/11] AArch64/OpenMP: Test SVE ACLE types with various OpenMP constructs Tejas Belagod
                   ` (11 preceding siblings ...)
  2024-05-30 12:58 ` [PATCH 00/11] AArch64/OpenMP: Test SVE ACLE types with various OpenMP constructs Richard Sandiford
@ 2024-06-20  4:46 ` Tejas Belagod
  12 siblings, 0 replies; 22+ messages in thread
From: Tejas Belagod @ 2024-06-20  4:46 UTC (permalink / raw)
  To: gcc-patches; +Cc: richard.sandiford, jakub

PING for the series.

Thanks,
Tejas.

On 5/27/24 10:36 AM, Tejas Belagod wrote:
> Note: This patch series is based on Richard's initial patch
>    https://gcc.gnu.org/pipermail/gcc-patches/2022-November/606741.html
> and Jakub's suggestion
>    https://gcc.gnu.org/pipermail/gcc-patches/2023-February/611892.html
> 
> The following patch series handles various scenarios with OpenMP and SVE types.
> The starting point for the series follows a suggestion from Jakub to cover all
> the possible scenarios that could arise when OMP constructs/clauses etc are
> used with SVE ACLE types. Here are a few instances that this patch series tests
> and in some cases fixes the expected output.  This patch series does not follow
> a formal definition or a spec of how OMP interacts with SVE ACLE types, so it's
> more of a proposed behaviour.  Comments and discussion welcome.
> 
> This list is not exhaustive, but covers most scenarios of how SVE ACLE types
> ought to interact with OMP constructs/clauses.
> 
> 1. Poly-int structures that represent variable-sized objects and OMP runtime.
> 
> Currently poly-int type structures are passed by value to OpenMP runtime
> functions for shared clauses etc.  This patch improves on this by passing
> around poly-int structures by address to avoid copy-overhead.
> 
> 2. SVE ACLE types in OMP Shared clauses.
> 
> We test the behaviour where SVE ACLE type objects are shared in the following
> methods into an OMP region:
>    a. Explicit Shared clause on SVE ACLE type objects.
>    b. Implicit shared clause.
>    c. Implicit shared with default clause.
>    d. SVE ALCE types in the presence of predetermined (static) shared objects.
> 
> The associated tests ensure that all such shared objects are passed by address
> into the OMP runtime.  There are runtime tests to verify the functional
> correctness of the change.
> 
> 3. Offloading and SVE ACLE types.
> 
> The target clause in OpenMP is used to offload loop kernels to accelerator
> peripeherals.  target's 'map' clause is used to move data from and to the
> accelarator.  When the data is SVE type, it may not be suitable because of
> various reasons i.e. the two SVE targets may not agree on vector size or
> some targets don't support variable vector size.  This makes SVE unsuitable
> for use in OMP's 'map' clause.  We diagnose all such cases and issue errors
> where appropriate.  The cases we cover in this patch are:
> 
>    a. Implicitly-mapped SVE ACLE types in OMP target regions are diagnosed.
>    b. Explicitly-mapped SVE ACLE types in OMP target regions using map clause
>       are diagnosed.
>    c. Explicilty-mapped SVLE ACLE types of various directions - to, from, tofrom
>       in the map clause are diagnosed.
>    d. target enter and exit data clauses with map on SVE ACLE types are
>       diagnosed.
>    e. target data map with alloc on SVE ACLE types are diagnosed.
>    f. target update from clause on SVE ACLE types are diagnosed.
>    g. target private firstprivate with SVE ACLE types are diagnosed.
>    h. All combinations of target with work-sharing constructs like parallel,
>       loop, simd, teams, distribute etc are also diagnosed when SVE ACLE types
>       are involved.
> 
> 3. Lastprivate and SVE ACLE types.
> 
> Various OpenMP lastprivate clause scenarios with SVE object types are
> diagnosed.  Worksharing constructs like sections, for, distribute bind to an
> implicit outer parallel region in whose scope SVE ACLE types are declared and
> are therefore default private.  The lastprivate clause list with SVE ACLE type
> object items are diagnosed in this scenario.
> 
> 4. Threadprivate on SVE ACLE type objects.
> 
> We ensure threadprivate SVE ACLE type objects are supported. We also ensure
> copyin clause is also supported.
> 
> 5. User-Defined Reductions on SVE ACLE types.
> 
> We define a reduction using OMP declare reduction using SVE ACLE intrinsics and
> ensure its functional correctness with various work-sharing constructs like
> for, simd, parallel, task, taskloop.
> 
> 6. Uniform and Aligned Clause with SVE ACLE
> 
> We ensure the uniform clause's functional correctness with simd construct and
> associated SVE ACLE intrinsics in the simd region.  There is no direct
> interaction between uniform and SVE ACLE type objects, but we ensure the uniform
> clause applies correctly to a region where SVE ACLE intrinsics are present.
> Similarly for the aligned clause.
> 
> 7. Linear clause and SVE ACLE type.
> 
> We diagnose if a linear clause list item has SVE ACLE type objects present.
> Its doesn't mean much if the linear clause is applied to SVE ACLE types.
> 
> 8. Depend clause and SVE ACLE objects.
> 
> We test for functional correctness many combinations of dependency of shared
> SVE ACLE type objects in parallel regions.  We test if in, out dependencies and
> anti-dependencies are supported for SVE ACLE type objects using the depend
> clause with work-sharing constructs like task.
> 
> 9. 'doacross' clause and SVE ACLE object types.
> 
> doacross is mainly supported for scalars and loop iteration variables.  We
> diagnose cases where SVE ACLE objects are used in doacross list items.
> 
> Tejas Belagod (11):
>    OpenMP/PolyInt: Pass poly-int structures by address to OMP libs.
>    AArch64: Add test cases for SVE types in OpenMP shared clause.
>    AArch64: Diagnose OpenMP offloading when SVE types involved.
>    AArch64: Test OpenMP lastprivate clause for various constructs.
>    AArch64: Test OpenMP threadprivate clause on SVE type.
>    AArch64: Test OpenMP user-defined reductions with SVE types.
>    AArch64: Test OpenMP uniform clause on SVE types.
>    AArch64: Test OpenMP simd aligned clause with SVE types.
>    AArch64: Diagnose OpenMP linear clause for SVE type objects.
>    AArch64: Test OpenMP depend clause and its variations on SVE types
>    AArch64: Diagnose SVE type objects when applied to OpenMP doacross
>      clause.
> 
>   gcc/config/aarch64/aarch64-sve-builtins.cc    |  31 +++
>   gcc/gimplify.cc                               |  34 ++-
>   gcc/omp-low.cc                                |   3 +-
>   gcc/target.h                                  |  19 +-
>   .../aarch64/sve/omp/aarch64-sve-omp.exp       |  80 ++++++
>   .../gcc.target/aarch64/sve/omp/depend-1.c     | 223 ++++++++++++++++
>   .../gcc.target/aarch64/sve/omp/doacross.c     |  22 ++
>   .../gcc.target/aarch64/sve/omp/lastprivate.c  | 121 +++++++++
>   .../gcc.target/aarch64/sve/omp/linear.c       |  33 +++
>   .../gcc.target/aarch64/sve/omp/offload-1.c    | 237 ++++++++++++++++++
>   .../gcc.target/aarch64/sve/omp/offload-2.c    | 198 +++++++++++++++
>   .../aarch64/sve/omp/offload-parallel-loop.c   | 236 +++++++++++++++++
>   .../aarch64/sve/omp/offload-parallel.c        | 195 ++++++++++++++
>   .../gcc.target/aarch64/sve/omp/offload-simd.c | 236 +++++++++++++++++
>   .../sve/omp/offload-teams-distribute-simd.c   | 237 ++++++++++++++++++
>   .../sve/omp/offload-teams-distribute.c        | 236 +++++++++++++++++
>   .../aarch64/sve/omp/offload-teams-loop.c      | 237 ++++++++++++++++++
>   .../aarch64/sve/omp/offload-teams.c           | 195 ++++++++++++++
>   .../gcc.target/aarch64/sve/omp/shared.c       | 186 ++++++++++++++
>   .../gcc.target/aarch64/sve/omp/simd-aligned.c |  50 ++++
>   .../gcc.target/aarch64/sve/omp/simd-uniform.c |  71 ++++++
>   .../aarch64/sve/omp/target-device.c           |  97 +++++++
>   .../gcc.target/aarch64/sve/omp/target-link.c  |  48 ++++
>   .../aarch64/sve/omp/threadprivate.c           |  44 ++++
>   .../gcc.target/aarch64/sve/omp/udr-sve.c      | 166 ++++++++++++
>   25 files changed, 3232 insertions(+), 3 deletions(-)
>   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/aarch64-sve-omp.exp
>   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/depend-1.c
>   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/doacross.c
>   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/lastprivate.c
>   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/linear.c
>   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-1.c
>   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-2.c
>   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel-loop.c
>   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-parallel.c
>   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-simd.c
>   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute-simd.c
>   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-distribute.c
>   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams-loop.c
>   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/offload-teams.c
>   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/shared.c
>   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/simd-aligned.c
>   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/simd-uniform.c
>   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/target-device.c
>   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/target-link.c
>   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/threadprivate.c
>   create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/omp/udr-sve.c
> 


^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2024-06-20  4:46 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-27  5:06 [PATCH 00/11] AArch64/OpenMP: Test SVE ACLE types with various OpenMP constructs Tejas Belagod
2024-05-27  5:06 ` [PATCH 01/11] OpenMP/PolyInt: Pass poly-int structures by address to OMP libs Tejas Belagod
2024-05-30 12:58   ` Richard Sandiford
2024-05-31  6:30     ` Tejas Belagod
2024-05-31  7:45       ` Richard Sandiford
2024-05-31  8:01         ` Jakub Jelinek
2024-05-31  8:23           ` Richard Sandiford
2024-05-27  5:06 ` [PATCH 02/11] AArch64: Add test cases for SVE types in OpenMP shared clause Tejas Belagod
2024-05-30 12:38   ` Richard Sandiford
2024-05-31  7:01     ` Tejas Belagod
2024-05-27  5:06 ` [PATCH 03/11] AArch64: Diagnose OpenMP offloading when SVE types involved Tejas Belagod
2024-05-30 12:50   ` Richard Sandiford
2024-05-27  5:06 ` [PATCH 04/11] AArch64: Test OpenMP lastprivate clause for various constructs Tejas Belagod
2024-05-27  5:06 ` [PATCH 05/11] AArch64: Test OpenMP threadprivate clause on SVE type Tejas Belagod
2024-05-27  5:06 ` [PATCH 06/11] AArch64: Test OpenMP user-defined reductions with SVE types Tejas Belagod
2024-05-27  5:06 ` [PATCH 07/11] AArch64: Test OpenMP uniform clause on " Tejas Belagod
2024-05-27  5:06 ` [PATCH 08/11] AArch64: Test OpenMP simd aligned clause with " Tejas Belagod
2024-05-27  5:06 ` [PATCH 09/11] AArch64: Diagnose OpenMP linear clause for SVE type objects Tejas Belagod
2024-05-27  5:06 ` [PATCH 10/11] AArch64: Test OpenMP depend clause and its variations on SVE types Tejas Belagod
2024-05-27  5:06 ` [PATCH 11/11] AArch64: Diagnose SVE type objects when applied to OpenMP doacross clause Tejas Belagod
2024-05-30 12:58 ` [PATCH 00/11] AArch64/OpenMP: Test SVE ACLE types with various OpenMP constructs Richard Sandiford
2024-06-20  4:46 ` Tejas Belagod

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).