re PR middle-end/66702 (#pragma omp declare simd uniform and linear issues)

PR middle-end/66702
	* omp-low.c (simd_clone_adjust): Handle addressable linear
	or uniform parameters or non-gimple type uniform parameters.

	* testsuite/libgomp.c++/pr66702-1.C: New test.
	* testsuite/libgomp.c++/pr66702-2.C: New test.

From-SVN: r225179
This commit is contained in:
Jakub Jelinek 2015-06-30 14:12:42 +02:00 committed by Jakub Jelinek
parent b14a9c57cf
commit 3446fe483e
5 changed files with 178 additions and 16 deletions

View File

@ -1,3 +1,9 @@
2015-06-30 Jakub Jelinek <jakub@redhat.com>
PR middle-end/66702
* omp-low.c (simd_clone_adjust): Handle addressable linear
or uniform parameters or non-gimple type uniform parameters.
2015-06-30 Richard Biener <rguenther@suse.de>
* fold-const.c (fold_unary_loc): Move abs(abs(x)) -> abs(x),

View File

@ -13425,12 +13425,54 @@ simd_clone_adjust (struct cgraph_node *node)
uniform args with __builtin_assume_aligned (arg_N(D), alignment)
lhs. Handle linear by adding PHIs. */
for (unsigned i = 0; i < node->simdclone->nargs; i++)
if (node->simdclone->args[i].alignment
&& node->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM
&& (node->simdclone->args[i].alignment
& (node->simdclone->args[i].alignment - 1)) == 0
&& TREE_CODE (TREE_TYPE (node->simdclone->args[i].orig_arg))
== POINTER_TYPE)
if (node->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM
&& (TREE_ADDRESSABLE (node->simdclone->args[i].orig_arg)
|| !is_gimple_reg_type
(TREE_TYPE (node->simdclone->args[i].orig_arg))))
{
tree orig_arg = node->simdclone->args[i].orig_arg;
if (is_gimple_reg_type (TREE_TYPE (orig_arg)))
iter1 = make_ssa_name (TREE_TYPE (orig_arg));
else
{
iter1 = create_tmp_var_raw (TREE_TYPE (orig_arg));
gimple_add_tmp_var (iter1);
}
gsi = gsi_after_labels (entry_bb);
g = gimple_build_assign (iter1, orig_arg);
gsi_insert_before (&gsi, g, GSI_NEW_STMT);
gsi = gsi_after_labels (body_bb);
g = gimple_build_assign (orig_arg, iter1);
gsi_insert_before (&gsi, g, GSI_NEW_STMT);
}
else if (node->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM
&& DECL_BY_REFERENCE (node->simdclone->args[i].orig_arg)
&& TREE_CODE (TREE_TYPE (node->simdclone->args[i].orig_arg))
== REFERENCE_TYPE
&& TREE_ADDRESSABLE
(TREE_TYPE (TREE_TYPE (node->simdclone->args[i].orig_arg))))
{
tree orig_arg = node->simdclone->args[i].orig_arg;
tree def = ssa_default_def (cfun, orig_arg);
if (def && !has_zero_uses (def))
{
iter1 = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (orig_arg)));
gimple_add_tmp_var (iter1);
gsi = gsi_after_labels (entry_bb);
g = gimple_build_assign (iter1, build_simple_mem_ref (def));
gsi_insert_before (&gsi, g, GSI_NEW_STMT);
gsi = gsi_after_labels (body_bb);
g = gimple_build_assign (build_simple_mem_ref (def), iter1);
gsi_insert_before (&gsi, g, GSI_NEW_STMT);
}
}
else if (node->simdclone->args[i].alignment
&& node->simdclone->args[i].arg_type
== SIMD_CLONE_ARG_TYPE_UNIFORM
&& (node->simdclone->args[i].alignment
& (node->simdclone->args[i].alignment - 1)) == 0
&& TREE_CODE (TREE_TYPE (node->simdclone->args[i].orig_arg))
== POINTER_TYPE)
{
unsigned int alignment = node->simdclone->args[i].alignment;
tree orig_arg = node->simdclone->args[i].orig_arg;
@ -13480,13 +13522,31 @@ simd_clone_adjust (struct cgraph_node *node)
== SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP)
{
tree orig_arg = node->simdclone->args[i].orig_arg;
tree def = ssa_default_def (cfun, orig_arg);
gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
|| POINTER_TYPE_P (TREE_TYPE (orig_arg)));
if (def && !has_zero_uses (def))
tree def = NULL_TREE;
if (TREE_ADDRESSABLE (orig_arg))
{
def = make_ssa_name (TREE_TYPE (orig_arg));
iter1 = make_ssa_name (TREE_TYPE (orig_arg));
iter2 = make_ssa_name (TREE_TYPE (orig_arg));
gsi = gsi_after_labels (entry_bb);
g = gimple_build_assign (def, orig_arg);
gsi_insert_before (&gsi, g, GSI_NEW_STMT);
}
else
{
def = ssa_default_def (cfun, orig_arg);
if (!def || has_zero_uses (def))
def = NULL_TREE;
else
{
iter1 = make_ssa_name (orig_arg);
iter2 = make_ssa_name (orig_arg);
}
}
if (def)
{
iter1 = make_ssa_name (orig_arg);
iter2 = make_ssa_name (orig_arg);
phi = create_phi_node (iter1, body_bb);
add_phi_arg (phi, def, preheader_edge, UNKNOWN_LOCATION);
add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION);
@ -13503,12 +13563,19 @@ simd_clone_adjust (struct cgraph_node *node)
imm_use_iterator iter;
use_operand_p use_p;
gimple use_stmt;
FOR_EACH_IMM_USE_STMT (use_stmt, iter, def)
if (use_stmt == phi)
continue;
else
FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
SET_USE (use_p, iter1);
if (TREE_ADDRESSABLE (orig_arg))
{
gsi = gsi_after_labels (body_bb);
g = gimple_build_assign (orig_arg, iter1);
gsi_insert_before (&gsi, g, GSI_NEW_STMT);
}
else
FOR_EACH_IMM_USE_STMT (use_stmt, iter, def)
if (use_stmt == phi)
continue;
else
FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
SET_USE (use_p, iter1);
}
}

View File

@ -1,3 +1,9 @@
2015-06-30 Jakub Jelinek <jakub@redhat.com>
PR middle-end/66702
* testsuite/libgomp.c++/pr66702-1.C: New test.
* testsuite/libgomp.c++/pr66702-2.C: New test.
2015-06-30 Tom de Vries <tom@codesourcery.com>
* testsuite/libgomp.c/parloops-exit-first-loop-alt-5.c: New test.

View File

@ -0,0 +1,49 @@
// PR middle-end/66702
// { dg-options "-O2" }
// { dg-additional-options "-msse2" { target sse2_runtime } }
// { dg-additional-options "-mavx" { target avx_runtime } }
void
bar (int &a, int &b, int *&c, int &d)
{
volatile int x;
int *volatile y;
x = a; a = x;
x = b; b = x;
y = c; c = y;
x = d; d = x;
}
void (*volatile barp) (int &, int &, int *&, int &) = bar;
#pragma omp declare simd uniform(b, c) linear(d:2) aligned(c:32) notinbranch
int
foo (int a, int b, int *c, int d)
{
a++;
b++;
c += 8;
d += 2;
barp (a, b, c, d);
return a + b + *c + d;
}
volatile int e = 5;
int c[64] __attribute__((aligned (32)));
int
main ()
{
int d = 7, r = 0;
int b = e;
for (int i = 0; i < 64; i++)
c[i] = i;
#pragma omp simd reduction(+:r) linear(d:2)
for (int i = 0; i < 64; i++)
{
r += foo (i, b, c, d);
d += 2;
}
if (r != 7584)
__builtin_abort ();
}

View File

@ -0,0 +1,34 @@
// PR middle-end/66702
// { dg-options "-O2" }
// { dg-additional-options "-msse2" { target sse2_runtime } }
// { dg-additional-options "-mavx" { target avx_runtime } }
struct S { int s1, s2; };
struct T { T (); ~T (); int t; };
T::T () : t(0) {}
T::~T () {}
#pragma omp declare simd uniform(b, c) notinbranch
__attribute__((noinline)) int
foo (int a, S b, T c)
{
a++;
b.s1++;
b.s2++;
c.t++;
return a + b.s1 + b.s2 + c.t;
}
int
main ()
{
int r = 0;
S s = { 2, 3 };
T t;
#pragma omp simd reduction(+:r)
for (int i = 0; i < 64; i++)
r += foo (i, s, t);
if (r != 2592)
__builtin_abort ();
}