libgomp: Add AArch64 SVE target tests to libgomp.

Add AArch64 SVE target exectute tests to test various workshare constructs and
clauses with SVE types.

libgomp/ChangeLog:

	* testsuite/libgomp.c-target/aarch64/aarch64.exp: Test driver.
	* testsuite/libgomp.c-target/aarch64/firstprivate.c: New test.
	* testsuite/libgomp.c-target/aarch64/lastprivate.c: Likewise.
	* testsuite/libgomp.c-target/aarch64/private.c: Likewise.
	* testsuite/libgomp.c-target/aarch64/shared.c: Likewise.
	* testsuite/libgomp.c-target/aarch64/simd-aligned.c: Likewise.
	* testsuite/libgomp.c-target/aarch64/simd-nontemporal.c: Likewise.
	* testsuite/libgomp.c-target/aarch64/threadprivate.c: Likewise.
	* testsuite/libgomp.c-target/aarch64/udr-sve.c: Likewise.
This commit is contained in:
Tejas Belagod 2025-03-31 16:00:55 +05:30
parent 3651de6132
commit a9bbb60b7c
9 changed files with 963 additions and 0 deletions

View file

@ -0,0 +1,57 @@
# Copyright (C) 2006-2025 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/>.
# Load support procs.
load_lib libgomp-dg.exp
load_gcc_lib gcc-dg.exp
# Exit immediately if this isn't an AArch64 target.
if {![istarget aarch64*-*-*] } then {
return
}
lappend ALWAYS_CFLAGS "compiler=$GCC_UNDER_TEST"
if { [check_effective_target_aarch64_sve] } {
set sve_flags ""
} else {
set sve_flags "-march=armv8.2-a+sve"
}
# Initialize `dg'.
dg-init
#if ![check_effective_target_fopenmp] {
# return
#}
# Turn on OpenMP.
lappend ALWAYS_CFLAGS "additional_flags=-fopenmp"
# Gather a list of all tests.
set tests [lsort [find $srcdir/$subdir *.c]]
set ld_library_path $always_ld_library_path
append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST]
set_ld_library_path_env_vars
# Main loop.
dg-runtest $tests "" $sve_flags
# All done.
dg-finish

View file

@ -0,0 +1,127 @@
/* { dg-do run { target aarch64_sve256_hw } } */
/* { dg-options "-msve-vector-bits=256 -fopenmp -O2" } */
#include <arm_sve.h>
#include <omp.h>
static void __attribute__ ((noipa))
vec_compare (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 ();
}
void __attribute__ ((noipa))
firstprivate_sections ()
{
int b[8], c[8];
svint32_t vb, vc;
int i;
#pragma omp parallel for
for (i = 0; i < 8; i++)
{
b[i] = i;
c[i] = i + 1;
}
vb = svld1_s32 (svptrue_b32 (), b);
vc = svld1_s32 (svptrue_b32 (), c);
#pragma omp parallel sections firstprivate (vb, vc)
{
#pragma omp section
vec_compare (&vb, svindex_s32 (0, 1));
vec_compare (&vc, svindex_s32 (1, 1));
#pragma omp section
vec_compare (&vb, svindex_s32 (0, 1));
vec_compare (&vc, svindex_s32 (1, 1));
}
}
void __attribute__ ((noipa))
firstprivate_for ()
{
int a[32], b[32], c[32];
svint32_t va, vb, vc;
int i;
#pragma omp parallel for
for (i = 0; i < 32; i++)
{
b[i] = i;
c[i] = i + 1;
}
vb = svindex_s32 (1, 0);
vc = svindex_s32 (0, 1);
#pragma omp parallel for firstprivate (vb, vc) private (va)
for (i = 0; i < 4; i++)
{
svint32_t tb, tc;
vec_compare (&vb, svindex_s32 (1, 0));
vec_compare (&vc, svindex_s32 (0, 1));
tb = svld1_s32 (svptrue_b32 (), b + i * 8);
tc = svld1_s32 (svptrue_b32 (), c + i * 8);
va = svadd_s32_z (svptrue_b32 (), vb, vc);
va = svadd_s32_z (svptrue_b32 (), va, tb);
va = svadd_s32_z (svptrue_b32 (), va, tc);
svst1_s32 (svptrue_b32 (), a + i * 8, va);
}
for (i = 0; i < 32; i++)
if (a[i] != b[i] + c[i] + vb[i % 8] + vc[i % 8])
__builtin_abort ();
}
void __attribute__ ((noipa))
firstprivate_distribute ()
{
int a[32], b[32], c[32];
svint32_t va, vb, vc;
int i;
#pragma omp parallel for
for (i = 0; i < 32; i++)
{
b[i] = i;
c[i] = i + 1;
}
vb = svindex_s32 (1, 0);
vc = svindex_s32 (0, 1);
#pragma omp teams
#pragma omp distribute firstprivate (vb, vc) private (va)
for (i = 0; i < 4; i++)
{
svint32_t tb, tc;
vec_compare (&vb, svindex_s32 (1, 0));
vec_compare (&vc, svindex_s32 (0, 1));
tb = svld1_s32 (svptrue_b32 (), b + i * 8);
tc = svld1_s32 (svptrue_b32 (), c + i * 8);
va = svadd_s32_z (svptrue_b32 (), vb, vc);
va = svadd_s32_z (svptrue_b32 (), va, tb);
va = svadd_s32_z (svptrue_b32 (), va, tc);
svst1_s32 (svptrue_b32 (), a + i * 8, va);
}
for (i = 0; i < 32; i++)
if (a[i] != b[i] + c[i] + vb[i % 8] + vc[i % 8])
__builtin_abort ();
}
int
main ()
{
firstprivate_for ();
firstprivate_sections ();
firstprivate_distribute ();
}

View file

@ -0,0 +1,169 @@
/* { dg-do run { target aarch64_sve256_hw } } */
/* { dg-options "-msve-vector-bits=256 -fopenmp -O2" } */
#include <arm_sve.h>
#include <omp.h>
static svint32_t __attribute__ ((noipa))
foo (svint32_t *vb, svint32_t *vc, int tn)
{
svint32_t temp = svindex_s32 (tn, 0);
temp = svadd_s32_z (svptrue_b32 (), temp, *vb);
return svadd_s32_z (svptrue_b32 (), temp, *vc);
}
void __attribute__ ((noipa))
lastprivate_sections ()
{
int a[8], b[8], c[8];
svint32_t va, vb, vc;
int i;
#pragma omp parallel for
for (i = 0; i < 8; i++)
{
b[i] = i;
c[i] = i + 1;
}
#pragma omp parallel sections lastprivate (vb, vc) num_threads (2)
{
#pragma omp section
vb = svld1_s32 (svptrue_b32 (), b);
#pragma omp section
vb = svld1_s32 (svptrue_b32 (), b);
vc = svld1_s32 (svptrue_b32 (), c);
}
va = svadd_s32_z (svptrue_b32 (), vb, vc);
svst1_s32 (svptrue_b32 (), a, va);
for (i = 0; i < 8; i++)
if (a[i] != b[i] + c[i])
__builtin_abort ();
}
void __attribute__ ((noipa))
lastprivate_for ()
{
int a[32], b[32], c[32];
int aa[8], bb[8], cc[8];
svint32_t va, vb, vc;
int i, tn;
#pragma omp parallel for
for (i = 0; i < 32; i++)
{
b[i] = i;
c[i] = i + 1;
}
#pragma omp parallel for lastprivate (va, vb, vc, tn)
for (i = 0; i < 4; i++)
{
vb = svld1_s32 (svptrue_b32 (), b + i * 8);
vc = svld1_s32 (svptrue_b32 (), c + i * 8);
tn = i;
va = foo (&vb, &vc, tn);
svst1_s32 (svptrue_b32 (), a + i * 8, va);
}
svst1_s32 (svptrue_b32 (), aa, va);
svst1_s32 (svptrue_b32 (), bb, vb);
svst1_s32 (svptrue_b32 (), cc, vc);
for (i = 0; i < 8; i++)
if (aa[i] != bb[i] + cc[i] + tn)
__builtin_abort ();
for (i = 0; i < 32; i++)
if (a[i] != b[i] + c[i] + i / 8)
__builtin_abort ();
}
void __attribute__ ((noipa))
lastprivate_simd ()
{
int a[64], b[64], c[64];
int aa[8], bb[8], cc[8];
svint32_t va, vb, vc;
int i;
#pragma omp parallel for
for (i = 0; i < 64; i++)
{
b[i] = i;
c[i] = i + 1;
}
#pragma omp simd lastprivate (va, vb, vc)
for (i = 0; i < 8; i++)
{
vb = svld1_s32 (svptrue_b32 (), b + i * 8);
vc = svld1_s32 (svptrue_b32 (), c + i * 8);
va = svadd_s32_z (svptrue_b32 (), vb, vc);
svst1_s32 (svptrue_b32 (), a + i * 8, va);
}
svst1_s32 (svptrue_b32 (), aa, va);
svst1_s32 (svptrue_b32 (), bb, vb);
svst1_s32 (svptrue_b32 (), cc, vc);
for (i = 0; i < 8; i++)
if (aa[i] != bb[i] + cc[i])
__builtin_abort ();
for (i = 0; i < 64; i++)
if (a[i] != b[i] + c[i])
__builtin_abort ();
}
void __attribute__ ((noipa))
lastprivate_distribute ()
{
int a[32], b[32], c[32];
int aa[8], bb[8], cc[8];
svint32_t va, vb, vc;
int i, tn;
#pragma omp parallel for
for (i = 0; i < 32; i++)
{
b[i] = i;
c[i] = i + 1;
}
#pragma omp teams
#pragma omp distribute lastprivate (va, vb, vc, tn)
for (i = 0; i < 4; i++)
{
vb = svld1_s32 (svptrue_b32 (), b + i * 8);
vc = svld1_s32 (svptrue_b32 (), c + i * 8);
tn = i;
va = foo (&vb, &vc, tn);
svst1_s32 (svptrue_b32 (), a + i * 8, va);
}
svst1_s32 (svptrue_b32 (), aa, va);
svst1_s32 (svptrue_b32 (), bb, vb);
svst1_s32 (svptrue_b32 (), cc, vc);
for (i = 0; i < 8; i++)
if (aa[i] != bb[i] + cc[i] + tn)
__builtin_abort ();
for (i = 0; i < 32; i++)
if (a[i] != b[i] + c[i] + i / 8)
__builtin_abort ();
}
int
main ()
{
lastprivate_for ();
lastprivate_sections ();
lastprivate_simd ();
lastprivate_distribute ();
}

View file

@ -0,0 +1,105 @@
/* { dg-do run { target aarch64_sve256_hw } } */
/* { dg-options "-msve-vector-bits=256 -fopenmp -O2" } */
#include <arm_sve.h>
#include <omp.h>
static void __attribute__ ((noipa))
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 ();
}
void __attribute__ ((noipa))
private ()
{
svint32_t a;
#pragma omp parallel private (a) num_threads (10)
{
a = svindex_s32 (omp_get_thread_num (), 0);
#pragma omp barrier
compare_vec (&a, svindex_s32 (omp_get_thread_num (), 0));
}
}
void __attribute__ ((noipa))
firstprivate ()
{
svint32_t a = svindex_s32 (1,1);
svint32_t b;
#pragma omp parallel private (b) firstprivate (a) num_threads (12)
{
compare_vec (&a, svindex_s32 (1, 1));
b = svindex_s32 (omp_get_thread_num (), 0);
#pragma omp barrier
compare_vec (&a, svindex_s32 (1, 1));
compare_vec (&b, svindex_s32 (omp_get_thread_num (), 0));
if (omp_get_thread_num () == 5)
{
a = svindex_s32 (1, 2);
b = svindex_s32 (10, 0);
}
#pragma omp barrier
if (omp_get_thread_num () == 5)
{
compare_vec (&a, svindex_s32 (1, 2));
compare_vec (&b, svindex_s32 (10, 0));
}
else
{
compare_vec (&a, svindex_s32 (1, 1));
compare_vec (&b, svindex_s32 (omp_get_thread_num (), 0));
}
}
}
void __attribute__ ((noipa))
lastprivate ()
{
svint32_t a = svindex_s32 (1,1);
svint32_t b;
int i;
#pragma omp parallel for private (a) lastprivate (b)
for (i = 0; i < 16; i++)
{
b = svindex_s32 (i, 0);
compare_vec (&b, svindex_s32 (i, 0));
if (i == 5)
{
a = svindex_s32 (1, 2);
b = svindex_s32 (10, 0);
}
else
a = svindex_s32 (1, 1);
if (i == 5)
{
compare_vec (&a, svindex_s32 (1, 2));
compare_vec (&b, svindex_s32 (10, 0));
}
else
{
compare_vec (&a, svindex_s32 (1, 1));
compare_vec (&b, svindex_s32 (i, 0));
}
}
compare_vec (&b, svindex_s32 (15, 0));
}
int
main ()
{
private ();
firstprivate ();
lastprivate ();
}

View file

@ -0,0 +1,264 @@
/* { dg-do run { target aarch64_sve256_hw } } */
/* { dg-options "-msve-vector-bits=256 -fopenmp -O2" } */
#include <arm_sve.h>
#include <stdlib.h>
#include <omp.h>
static void __attribute__ ((noipa))
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 ();
}
static void __attribute__ ((noipa))
compare_vecb (svbool_t x, svbool_t y)
{
svbool_t p = sveor_b_z (svptrue_b32 (), x, y);
if (svptest_any (svptrue_b32 (), p))
__builtin_abort ();
}
void __attribute__ ((noipa))
implicit_shared_default (svint32_t a, svint32_t b, svbool_t p)
{
#pragma omp parallel default (shared) num_threads (10)
{
/* 'a', 'b' and 'p' are implicitly shared. */
compare_vec (a, svindex_s32 (0, 1));
compare_vec (b, svindex_s32 (8, 1));
compare_vecb (p, svptrue_b32 ());
#pragma omp barrier
if (omp_get_thread_num () == 2)
a = svadd_s32_z (p, a, b);
#pragma omp barrier
if (omp_get_thread_num () == 0)
{
compare_vec (a, svindex_s32 (8, 2));
compare_vec (b, svindex_s32 (8, 1));
compare_vecb (p, svptrue_b32 ());
b = svadd_s32_z (p, a, b);
}
#pragma omp barrier
compare_vec (a, svindex_s32 (8, 2));
compare_vec (b, svadd_s32_z (p, svindex_s32 (8, 2), svindex_s32 (8, 1)));
#pragma omp barrier
if (omp_get_thread_num () == 0 || omp_get_thread_num () == 2)
{
compare_vec (a, svindex_s32 (8, 2));
compare_vec (b, svadd_s32_z (p, svindex_s32 (8, 2), svindex_s32 (8, 1)));
}
}
}
void __attribute__ ((noipa))
explicit_shared (svint32_t a, svint32_t b, svbool_t p)
{
#pragma omp parallel shared (a, b, p) num_threads (12)
{
/* 'a', 'b' and 'p' are explicitly shared. */
compare_vec (a, svindex_s32 (0, 1));
compare_vec (b, svindex_s32 (8, 1));
compare_vecb (p, svptrue_b32 ());
#pragma omp barrier
if (omp_get_thread_num () == 2)
a = svadd_s32_z (p, a, b);
#pragma omp barrier
if (omp_get_thread_num () == 0)
{
compare_vec (a, svindex_s32 (8, 2));
compare_vec (b, svindex_s32 (8, 1));
compare_vecb (p, svptrue_b32 ());
b = svadd_s32_z (p, a, b);
}
#pragma omp barrier
compare_vec (a, svindex_s32 (8, 2));
compare_vec (b, svadd_s32_z (p, svindex_s32 (8, 2), svindex_s32 (8, 1)));
#pragma omp barrier
if (omp_get_thread_num () == 0 || omp_get_thread_num () == 2)
{
compare_vec (a, svindex_s32 (8, 2));
compare_vec (b, svadd_s32_z (p, svindex_s32 (8, 2), svindex_s32 (8, 1)));
}
}
}
void __attribute__ ((noipa))
implicit_shared_no_default (svint32_t a, svint32_t b, svbool_t p)
{
#pragma omp parallel num_threads (16)
{
/* 'a', 'b' and 'p' are implicitly shared without default clause. */
compare_vec (a, svindex_s32 (0, 1));
compare_vec (b, svindex_s32 (8, 1));
compare_vecb (p, svptrue_b32 ());
#pragma omp barrier
if (omp_get_thread_num () == 12)
a = svadd_s32_z (p, a, b);
#pragma omp barrier
if (omp_get_thread_num () == 15)
{
compare_vec (a, svindex_s32 (8, 2));
compare_vec (b, svindex_s32 (8, 1));
compare_vecb (p, svptrue_b32 ());
b = svadd_s32_z (p, a, b);
}
#pragma omp barrier
compare_vec (a, svindex_s32 (8, 2));
compare_vec (b, svadd_s32_z (p, svindex_s32 (8, 2), svindex_s32 (8, 1)));
#pragma omp barrier
if (omp_get_thread_num () == 12 || omp_get_thread_num () == 15)
{
compare_vec (a, svindex_s32 (8, 2));
compare_vec (b, svadd_s32_z (p, svindex_s32 (8, 2), svindex_s32 (8, 1)));
}
}
}
void __attribute__ ((noipa))
mix_shared (svint32_t b, svbool_t p)
{
svint32_t a = svindex_s32 (0, 0);
int *m = (int *) malloc (8 * sizeof (int));
int i;
#pragma omp parallel for
for (i = 0; i < 8; i++)
m[i] = i;
#pragma omp parallel num_threads (16)
{
compare_vec (a, svindex_s32 (0, 0));
compare_vec (b, svindex_s32 (8, 1));
#pragma omp barrier
/* 'm' is predetermined shared here. 'a' is implicitly shared here. */
if (omp_get_thread_num () == 10)
a = svld1_s32 (svptrue_b32 (), m);
#pragma omp barrier
/* 'a', 'b' and 'p' are implicitly shared without default clause. */
compare_vec (a, svindex_s32 (0, 1));
compare_vec (b, svindex_s32 (8, 1));
compare_vecb (p, svptrue_b32 ());
#pragma omp barrier
if (omp_get_thread_num () == 12)
a = svadd_s32_z (p, a, b);
#pragma omp barrier
if (omp_get_thread_num () == 15)
{
compare_vec (a, svindex_s32 (8, 2));
compare_vec (b, svindex_s32 (8, 1));
compare_vecb (p, svptrue_b32 ());
b = svadd_s32_z (p, a, b);
}
#pragma omp barrier
if (omp_get_thread_num () == 12 || omp_get_thread_num () == 15)
{
compare_vec (a, svindex_s32 (8, 2));
compare_vec (b, svadd_s32_z (p, svindex_s32 (8, 2), svindex_s32 (8, 1)));
}
#pragma omp barrier
compare_vec (a, svindex_s32 (8, 2));
compare_vec (b, svadd_s32_z (p, svindex_s32 (8, 2), svindex_s32 (8, 1)));
}
}
#define N __ARM_FEATURE_SVE_BITS
#define FIXED_ATTR __attribute__((arm_sve_vector_bits (N)))
typedef svint32_t v8si FIXED_ATTR;
void __attribute__ ((noipa))
predetermined_shared_static (int n)
{
int *m = (int *) malloc (8 * sizeof (int));
int i;
#pragma omp parallel for
/* 'm' is predetermined shared here. */
for (i = 0; i < 8; i++)
m[i] = i;
static v8si a = { 0, 1, 2, 3, 4, 5, 6, 7 };
#pragma omp parallel num_threads (16)
{
/* 'a' is implicit shared here. */
if (n == 0)
compare_vec (a, svindex_s32 (0, 1));
if (n == 1)
compare_vec (a, svindex_s32 (1, 1));
#pragma omp barrier
if (omp_get_thread_num () == 12)
{
if (n == 0)
compare_vec (a, svindex_s32 (0, 1));
if (n == 1)
compare_vec (a, svindex_s32 (1, 1));
a = svadd_s32_z (svptrue_b32 (), a, svindex_s32 (1, 0));
}
#pragma omp barrier
if (n == 0)
compare_vec (a, svindex_s32 (1, 1));
if (n == 1)
compare_vec (a, svindex_s32 (2, 1));
}
}
int
main ()
{
svint32_t x = svindex_s32 (0, 1);
svint32_t y = svindex_s32 (8, 1);
svbool_t p = svptrue_b32 ();
/* Implicit shared. */
implicit_shared_default (x, y, p);
/* Explicit shared. */
explicit_shared (x, y, p);
/* Implicit shared with no default clause. */
implicit_shared_no_default (x, y, p);
/* Mix shared. */
mix_shared (y, p);
/* Predetermined and static shared. */
predetermined_shared_static (0);
predetermined_shared_static (1);
}

View file

@ -0,0 +1,49 @@
/* { dg-do run { target aarch64_sve256_hw } } */
/* { dg-options "-msve-vector-bits=256 -fopenmp -O2" } */
#include <arm_sve.h>
#include <stdint.h>
#define N 256
int a[N] __attribute__ ((aligned (64)));
int b[N] __attribute__ ((aligned (64)));
void __attribute__ ((noipa))
foo (int *p, int *q, svint32_t *onesp)
{
svint32_t va, vc;
int i;
uint64_t sz = svcntw ();
#pragma omp simd aligned(p, q : 64) aligned (onesp : 128) \
private (va, vc) nontemporal (va, vc)
for (i = 0; i < N; i++)
{
if (i % sz == 0)
{
va = svld1_s32 (svptrue_b32 (), p);
vc = svadd_s32_z (svptrue_b32 (), va, *onesp);
svst1_s32 (svptrue_b32 (), q, vc);
q += sz;
}
}
}
int
main ()
{
svint32_t ones __attribute__ ((aligned(128))) = svindex_s32 (1, 0);
for (int i = 0; i < N; i++)
{
a[i] = 1;
b[i] = 0;
}
foo (a, b, &ones);
for (int i = 0; i < N; i++)
if (b[i] != 2)
__builtin_abort ();
}

View file

@ -0,0 +1,49 @@
/* { dg-do run { target aarch64_sve256_hw } } */
/* { dg-options "-msve-vector-bits=256 -fopenmp -O2" } */
#include <arm_sve.h>
#include <stdint.h>
#define N 256
int a[N] __attribute__ ((aligned (64)));
int b[N] __attribute__ ((aligned (64)));
void __attribute__ ((noipa))
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;
}
}
}
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 ();
}

View file

@ -0,0 +1,45 @@
/* { dg-do run { target aarch64_sve256_hw } } */
/* { dg-options "-msve-vector-bits=256 -fopenmp -O2" } */
#include <arm_sve.h>
#include <stdint.h>
typedef __SVInt32_t v8si __attribute__ ((arm_sve_vector_bits(256)));
v8si vec1;
#pragma omp threadprivate (vec1)
void __attribute__ ((noipa))
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 ();
}
}
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 ();
}
foo ();
}

View file

@ -0,0 +1,98 @@
/* { dg-do run { target aarch64_sve256_hw } } */
/* { dg-options "-msve-vector-bits=256 -fopenmp -O2" } */
#include <arm_sve.h>
#pragma omp declare reduction (+:svint32_t: omp_out = svadd_s32_z (svptrue_b32(), omp_in, omp_out)) \
initializer (omp_priv = svindex_s32 (0, 0))
void __attribute__ ((noipa))
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 ();
}
void __attribute__ ((noipa))
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 j;
int64_t res;
#pragma omp parallel for reduction (+:va)
for (j = 0; j < 8; j++)
va = svld1_s32 (svptrue_b32 (), a);
res = svaddv_s32 (svptrue_b32 (), va);
if (res != 64)
__builtin_abort ();
}
void __attribute__ ((noipa))
simd_reduction ()
{
int a[8];
svint32_t va = svindex_s32 (0, 0);
int i = 0;
int j;
int64_t res = 0;
for (j = 0; j < 8; j++)
a[j] = 1;
#pragma omp simd reduction (+:va, i)
for (j = 0; j < 16; j++)
va = svld1_s32 (svptrue_b32 (), a);
res = svaddv_s32 (svptrue_b32 (), va);
if (res != 8)
__builtin_abort ();
}
void __attribute__ ((noipa))
inscan_reduction_incl ()
{
svint32_t va = svindex_s32 (0, 0);
int j;
int64_t res = 0;
#pragma omp parallel
#pragma omp for reduction (inscan,+:va) firstprivate (res) lastprivate (res)
for (j = 0; j < 8; j++)
{
va = svindex_s32 (1, 0);
#pragma omp scan inclusive (va)
res += svaddv_s32 (svptrue_b32 (), va);
}
if (res != 64)
__builtin_abort ();
}
int
main ()
{
parallel_reduction ();
for_reduction ();
simd_reduction ();
inscan_reduction_incl ();
}