diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cfgexpand.c | 22 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/store_lane_spill_1.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/sve/store_lane_spill_1.c | 19 | ||||
-rw-r--r-- | gcc/tree-vect-stmts.c | 44 |
6 files changed, 105 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 654328f..83d01ed 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2018-05-09 Richard Sandiford <richard.sandiford@linaro.org> + + * cfgexpand.c (expand_clobber): New function. + (expand_gimple_stmt_1): Use it. + * tree-vect-stmts.c (vect_clobber_variable): New function, + split out from... + (vectorizable_simd_clone_call): ...here. + (vectorizable_store): Emit a clobber either side of an + IFN_STORE_LANES sequence. + (vectorizable_load): Emit a clobber after an IFN_LOAD_LANES sequence. + 2018-05-09 Tom de Vries <tom@codesourcery.com> PR target/85626 diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index ff2f407..ef143a3 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -3582,6 +3582,26 @@ expand_return (tree retval, tree bounds) } } +/* Expand a clobber of LHS. If LHS is stored it in a multi-part + register, tell the rtl optimizers that its value is no longer + needed. */ + +static void +expand_clobber (tree lhs) +{ + if (DECL_P (lhs)) + { + rtx decl_rtl = DECL_RTL_IF_SET (lhs); + if (decl_rtl && REG_P (decl_rtl)) + { + machine_mode decl_mode = GET_MODE (decl_rtl); + if (maybe_gt (GET_MODE_SIZE (decl_mode), + REGMODE_NATURAL_SIZE (decl_mode))) + emit_clobber (decl_rtl); + } + } +} + /* A subroutine of expand_gimple_stmt, expanding one gimple statement STMT that doesn't require special handling for outgoing edges. That is no tailcalls and no GIMPLE_COND. */ @@ -3687,7 +3707,7 @@ expand_gimple_stmt_1 (gimple *stmt) if (TREE_CLOBBER_P (rhs)) /* This is a clobber to mark the going out of scope for this LHS. */ - ; + expand_clobber (lhs); else expand_assignment (lhs, rhs, gimple_assign_nontemporal_move_p ( diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9555222..85c2255 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-05-09 Richard Sandiford <richard.sandiford@linaro.org> + + * gcc.target/aarch64/store_lane_spill_1.c: New test. + * gcc.target/aarch64/sve/store_lane_spill_1.c: Likewise. + 2018-05-08 Carl Love <cel@us.ibm.com> * gcc.target/powerpc/builtins-8-p9-runnable.c: Add new test file. diff --git a/gcc/testsuite/gcc.target/aarch64/store_lane_spill_1.c b/gcc/testsuite/gcc.target/aarch64/store_lane_spill_1.c new file mode 100644 index 0000000..80683c2 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/store_lane_spill_1.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize" } */ + +#pragma GCC target "+nosve" + +int cont (void); + +void +f (int (*x)[3], int *a, int *b, int *c, int n) +{ + do + for (int i = 0; i < n; ++i) + { + x[i][0] = a[i] + 1; + x[i][1] = b[i] + 2; + x[i][2] = c[i] + 3; + } + while (cont ()); +} + +/* { dg-final { scan-assembler-not {\tst1\t} } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/store_lane_spill_1.c b/gcc/testsuite/gcc.target/aarch64/sve/store_lane_spill_1.c new file mode 100644 index 0000000..7e17f62 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/store_lane_spill_1.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize" } */ + +int cont (void); + +void +f (int (*x)[3], int *a, int *b, int *c, int n) +{ + do + for (int i = 0; i < n; ++i) + { + x[i][0] = a[i] + 1; + x[i][1] = b[i] + 2; + x[i][2] = c[i] + 3; + } + while (cont ()); +} + +/* { dg-final { scan-assembler-not {\tstr\tz[0-9]} } } */ diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 7ebc426..1e8ccbc 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -182,6 +182,17 @@ create_array_ref (tree type, tree ptr, tree alias_ptr_type) return mem_ref; } +/* Add a clobber of variable VAR to the vectorization of STMT. + Emit the clobber before *GSI. */ + +static void +vect_clobber_variable (gimple *stmt, gimple_stmt_iterator *gsi, tree var) +{ + tree clobber = build_clobber (TREE_TYPE (var)); + gimple *new_stmt = gimple_build_assign (var, clobber); + vect_finish_stmt_generation (stmt, new_stmt, gsi); +} + /* Utility functions used by vect_mark_stmts_to_be_vectorized. */ /* Function vect_mark_relevant. @@ -4128,12 +4139,7 @@ vectorizable_simd_clone_call (gimple *stmt, gimple_stmt_iterator *gsi, } if (ratype) - { - tree clobber = build_constructor (ratype, NULL); - TREE_THIS_VOLATILE (clobber) = 1; - new_stmt = gimple_build_assign (new_temp, clobber); - vect_finish_stmt_generation (stmt, new_stmt, gsi); - } + vect_clobber_variable (stmt, gsi, new_temp); continue; } else if (simd_clone_subparts (vectype) > nunits) @@ -4156,10 +4162,7 @@ vectorizable_simd_clone_call (gimple *stmt, gimple_stmt_iterator *gsi, CONSTRUCTOR_APPEND_ELT (ret_ctor_elts, NULL_TREE, gimple_assign_lhs (new_stmt)); } - tree clobber = build_constructor (ratype, NULL); - TREE_THIS_VOLATILE (clobber) = 1; - new_stmt = gimple_build_assign (new_temp, clobber); - vect_finish_stmt_generation (stmt, new_stmt, gsi); + vect_clobber_variable (stmt, gsi, new_temp); } else CONSTRUCTOR_APPEND_ELT (ret_ctor_elts, NULL_TREE, new_temp); @@ -4186,11 +4189,7 @@ vectorizable_simd_clone_call (gimple *stmt, gimple_stmt_iterator *gsi, new_stmt = gimple_build_assign (make_ssa_name (vec_dest), t); vect_finish_stmt_generation (stmt, new_stmt, gsi); - tree clobber = build_constructor (ratype, NULL); - TREE_THIS_VOLATILE (clobber) = 1; - vect_finish_stmt_generation (stmt, - gimple_build_assign (new_temp, - clobber), gsi); + vect_clobber_variable (stmt, gsi, new_temp); } } @@ -6913,8 +6912,15 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, { tree vec_array; - /* Combine all the vectors into an array. */ + /* Get an array into which we can store the individual vectors. */ vec_array = create_vector_array (vectype, vec_num); + + /* Invalidate the current contents of VEC_ARRAY. This should + become an RTL clobber too, which prevents the vector registers + from being upward-exposed. */ + vect_clobber_variable (stmt, gsi, vec_array); + + /* Store the individual vectors into the array. */ for (i = 0; i < vec_num; i++) { vec_oprnd = dr_chain[i]; @@ -6953,6 +6959,9 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, gimple_call_set_nothrow (call, true); new_stmt = call; vect_finish_stmt_generation (stmt, new_stmt, gsi); + + /* Record that VEC_ARRAY is now dead. */ + vect_clobber_variable (stmt, gsi, vec_array); } else { @@ -8105,6 +8114,9 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, /* Record the mapping between SSA_NAMEs and statements. */ vect_record_grouped_load_vectors (stmt, dr_chain); + + /* Record that VEC_ARRAY is now dead. */ + vect_clobber_variable (stmt, gsi, vec_array); } else { |