Hi! As the first testcase shows, we were mishandling addressable uniform/linear parameters, in that case keeping them to use the (D) ssa name for uniform or doing the iteration for linear doesn't work, so we need to handle it slightly differently.
Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk/5.2. 2015-06-30 Jakub Jelinek <ja...@redhat.com> 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. --- gcc/omp-low.c.jj 2015-06-17 20:11:10.000000000 +0200 +++ gcc/omp-low.c 2015-06-30 11:38:24.550092307 +0200 @@ -13427,12 +13427,54 @@ simd_clone_adjust (struct cgraph_node *n 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; @@ -13482,13 +13524,31 @@ simd_clone_adjust (struct cgraph_node *n == 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); @@ -13505,12 +13565,19 @@ simd_clone_adjust (struct cgraph_node *n 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); } } --- libgomp/testsuite/libgomp.c++/pr66702-1.C.jj 2015-06-30 11:43:58.621078611 +0200 +++ libgomp/testsuite/libgomp.c++/pr66702-1.C 2015-06-30 11:45:04.260093508 +0200 @@ -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 (); +} --- libgomp/testsuite/libgomp.c++/pr66702-2.C.jj 2015-06-30 11:47:23.723000466 +0200 +++ libgomp/testsuite/libgomp.c++/pr66702-2.C 2015-06-30 11:47:59.524463162 +0200 @@ -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 (); +} Jakub