From 3446fe483e3d734e38555a8034e7ab672afa68ee Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 30 Jun 2015 14:12:42 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 ++ gcc/omp-low.c | 99 +++++++++++++++++++---- libgomp/ChangeLog | 6 ++ libgomp/testsuite/libgomp.c++/pr66702-1.C | 49 +++++++++++ libgomp/testsuite/libgomp.c++/pr66702-2.C | 34 ++++++++ 5 files changed, 178 insertions(+), 16 deletions(-) create mode 100644 libgomp/testsuite/libgomp.c++/pr66702-1.C create mode 100644 libgomp/testsuite/libgomp.c++/pr66702-2.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6f919643f37..4d11ef546cc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-06-30 Jakub Jelinek + + 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 * fold-const.c (fold_unary_loc): Move abs(abs(x)) -> abs(x), diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 8218403f680..2e2070a7397 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -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); } } diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index a5c51f5639d..2f1346de106 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,9 @@ +2015-06-30 Jakub Jelinek + + 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 * testsuite/libgomp.c/parloops-exit-first-loop-alt-5.c: New test. diff --git a/libgomp/testsuite/libgomp.c++/pr66702-1.C b/libgomp/testsuite/libgomp.c++/pr66702-1.C new file mode 100644 index 00000000000..15772561b1a --- /dev/null +++ b/libgomp/testsuite/libgomp.c++/pr66702-1.C @@ -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 (); +} diff --git a/libgomp/testsuite/libgomp.c++/pr66702-2.C b/libgomp/testsuite/libgomp.c++/pr66702-2.C new file mode 100644 index 00000000000..7de3de010a7 --- /dev/null +++ b/libgomp/testsuite/libgomp.c++/pr66702-2.C @@ -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 (); +} -- 2.30.2