diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-08-01 10:26:14 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-08-01 10:26:14 +0200 |
commit | ff03930a11f3a996e512ed3613eedc1b50ac5b30 (patch) | |
tree | af31b0e324512fbcd62de8f28468084fc6a23160 /gcc/expr.c | |
parent | 5e8fe12fccb2edeb1b699101167b1c921a742bb7 (diff) | |
download | gcc-ff03930a11f3a996e512ed3613eedc1b50ac5b30.zip gcc-ff03930a11f3a996e512ed3613eedc1b50ac5b30.tar.gz gcc-ff03930a11f3a996e512ed3613eedc1b50ac5b30.tar.bz2 |
re PR target/80846 (auto-vectorized AVX2 horizontal sum should narrow to 128b right away, to be more efficient for Ryzen and Intel)
PR target/80846
* optabs.def (vec_extract_optab, vec_init_optab): Change from
a direct optab to conversion optab.
* optabs.c (expand_vector_broadcast): Use convert_optab_handler
with GET_MODE_INNER as last argument instead of optab_handler.
* expmed.c (extract_bit_field_1): Likewise. Use vector from
vector extraction if possible and optab is available.
* expr.c (store_constructor): Use convert_optab_handler instead
of optab_handler. Use vector initialization from smaller
vectors if possible and optab is available.
* tree-vect-stmts.c (vectorizable_load): Likewise.
* doc/md.texi (vec_extract, vec_init): Document that the optabs
now have two modes.
* config/i386/i386.c (ix86_expand_vector_init): Handle expansion
of vec_init from half-sized vectors with the same element mode.
* config/i386/sse.md (ssehalfvecmode): Add V4TI case.
(ssehalfvecmodelower, ssescalarmodelower): New mode attributes.
(reduc_plus_scal_v8df, reduc_plus_scal_v4df, reduc_plus_scal_v2df,
reduc_plus_scal_v16sf, reduc_plus_scal_v8sf, reduc_plus_scal_v4sf,
reduc_<code>_scal_<mode>, reduc_umin_scal_v8hi): Add element mode
after mode in gen_vec_extract* calls.
(vec_extract<mode>): Renamed to ...
(vec_extract<mode><ssescalarmodelower>): ... this.
(vec_extract<mode><ssehalfvecmodelower>): New expander.
(rotl<mode>3, rotr<mode>3, <shift_insn><mode>3, ashrv2di3): Add
element mode after mode in gen_vec_init* calls.
(VEC_INIT_HALF_MODE): New mode iterator.
(vec_init<mode>): Renamed to ...
(vec_init<mode><ssescalarmodelower>): ... this.
(vec_init<mode><ssehalfvecmodelower>): New expander.
* config/i386/mmx.md (vec_extractv2sf): Renamed to ...
(vec_extractv2sfsf): ... this.
(vec_initv2sf): Renamed to ...
(vec_initv2sfsf): ... this.
(vec_extractv2si): Renamed to ...
(vec_extractv2sisi): ... this.
(vec_initv2si): Renamed to ...
(vec_initv2sisi): ... this.
(vec_extractv4hi): Renamed to ...
(vec_extractv4hihi): ... this.
(vec_initv4hi): Renamed to ...
(vec_initv4hihi): ... this.
(vec_extractv8qi): Renamed to ...
(vec_extractv8qiqi): ... this.
(vec_initv8qi): Renamed to ...
(vec_initv8qiqi): ... this.
* config/rs6000/vector.md (VEC_base_l): New mode attribute.
(vec_init<mode>): Renamed to ...
(vec_init<mode><VEC_base_l>): ... this.
(vec_extract<mode>): Renamed to ...
(vec_extract<mode><VEC_base_l>): ... this.
* config/rs6000/paired.md (vec_initv2sf): Renamed to ...
(vec_initv2sfsf): ... this.
* config/rs6000/altivec.md (splitter, altivec_copysign_v4sf3,
vec_unpacku_hi_v16qi, vec_unpacku_hi_v8hi, vec_unpacku_lo_v16qi,
vec_unpacku_lo_v8hi, mulv16qi3, altivec_vreve<mode>2): Add
element mode after mode in gen_vec_init* calls.
* config/aarch64/aarch64-simd.md (vec_init<mode>): Renamed to ...
(vec_init<mode><Vel>): ... this.
(vec_extract<mode>): Renamed to ...
(vec_extract<mode><Vel>): ... this.
* config/aarch64/iterators.md (Vel): New mode attribute.
* config/s390/s390.c (s390_expand_vec_strlen, s390_expand_vec_movstr):
Add element mode after mode in gen_vec_extract* calls.
* config/s390/vector.md (non_vec_l): New mode attribute.
(vec_extract<mode>): Renamed to ...
(vec_extract<mode><non_vec_l>): ... this.
(vec_init<mode>): Renamed to ...
(vec_init<mode><non_vec_l>): ... this.
* config/s390/s390-builtins.def (s390_vlgvb, s390_vlgvh, s390_vlgvf,
s390_vlgvf_flt, s390_vlgvg, s390_vlgvg_dbl): Add element mode after
vec_extract mode.
* config/arm/iterators.md (V_elem_l): New mode attribute.
* config/arm/neon.md (vec_extract<mode>): Renamed to ...
(vec_extract<mode><V_elem_l>): ... this.
(vec_extractv2di): Renamed to ...
(vec_extractv2didi): ... this.
(vec_init<mode>): Renamed to ...
(vec_init<mode><V_elem_l>): ... this.
(reduc_plus_scal_<mode>, reduc_plus_scal_v2di, reduc_smin_scal_<mode>,
reduc_smax_scal_<mode>, reduc_umin_scal_<mode>,
reduc_umax_scal_<mode>, neon_vget_lane<mode>, neon_vget_laneu<mode>):
Add element mode after gen_vec_extract* calls.
* config/mips/mips-msa.md (vec_init<mode>): Renamed to ...
(vec_init<mode><unitmode>): ... this.
(vec_extract<mode>): Renamed to ...
(vec_extract<mode><unitmode>): ... this.
* config/mips/loongson.md (vec_init<mode>): Renamed to ...
(vec_init<mode><unitmode>): ... this.
* config/mips/mips-ps-3d.md (vec_initv2sf): Renamed to ...
(vec_initv2sfsf): ... this.
(vec_extractv2sf): Renamed to ...
(vec_extractv2sfsf): ... this.
(reduc_plus_scal_v2sf, reduc_smin_scal_v2sf, reduc_smax_scal_v2sf):
Add element mode after gen_vec_extract* calls.
* config/mips/mips.md (unitmode): New mode iterator.
* config/spu/spu.c (spu_expand_prologue, spu_allocate_stack,
spu_builtin_extract): Add element mode after gen_vec_extract* calls.
* config/spu/spu.md (inner_l): New mode attribute.
(vec_init<mode>): Renamed to ...
(vec_init<mode><inner_l>): ... this.
(vec_extract<mode>): Renamed to ...
(vec_extract<mode><inner_l>): ... this.
* config/sparc/sparc.md (veltmode): New mode iterator.
(vec_init<VMALL:mode>): Renamed to ...
(vec_init<VMALL:mode><VMALL:veltmode>): ... this.
* config/ia64/vect.md (vec_initv2si): Renamed to ...
(vec_initv2sisi): ... this.
(vec_initv2sf): Renamed to ...
(vec_initv2sfsf): ... this.
(vec_extractv2sf): Renamed to ...
(vec_extractv2sfsf): ... this.
* config/powerpcspe/vector.md (VEC_base_l): New mode attribute.
(vec_init<mode>): Renamed to ...
(vec_init<mode><VEC_base_l>): ... this.
(vec_extract<mode>): Renamed to ...
(vec_extract<mode><VEC_base_l>): ... this.
* config/powerpcspe/paired.md (vec_initv2sf): Renamed to ...
(vec_initv2sfsf): ... this.
* config/powerpcspe/altivec.md (splitter, altivec_copysign_v4sf3,
vec_unpacku_hi_v16qi, vec_unpacku_hi_v8hi, vec_unpacku_lo_v16qi,
vec_unpacku_lo_v8hi, mulv16qi3): Add element mode after mode in
gen_vec_init* calls.
From-SVN: r250759
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 69 |
1 files changed, 38 insertions, 31 deletions
@@ -6589,6 +6589,7 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size, rtvec vector = NULL; unsigned n_elts; alias_set_type alias; + bool vec_vec_init_p = false; gcc_assert (eltmode != BLKmode); @@ -6596,27 +6597,30 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size, if (REG_P (target) && VECTOR_MODE_P (GET_MODE (target))) { machine_mode mode = GET_MODE (target); + machine_mode emode = eltmode; - icode = (int) optab_handler (vec_init_optab, mode); - /* Don't use vec_init<mode> if some elements have VECTOR_TYPE. */ - if (icode != CODE_FOR_nothing) + if (CONSTRUCTOR_NELTS (exp) + && (TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value)) + == VECTOR_TYPE)) { - tree value; - - FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value) - if (TREE_CODE (TREE_TYPE (value)) == VECTOR_TYPE) - { - icode = CODE_FOR_nothing; - break; - } + tree etype = TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value); + gcc_assert (CONSTRUCTOR_NELTS (exp) * TYPE_VECTOR_SUBPARTS (etype) + == n_elts); + emode = TYPE_MODE (etype); } + icode = (int) convert_optab_handler (vec_init_optab, mode, emode); if (icode != CODE_FOR_nothing) { - unsigned int i; + unsigned int i, n = n_elts; - vector = rtvec_alloc (n_elts); - for (i = 0; i < n_elts; i++) - RTVEC_ELT (vector, i) = CONST0_RTX (GET_MODE_INNER (mode)); + if (emode != eltmode) + { + n = CONSTRUCTOR_NELTS (exp); + vec_vec_init_p = true; + } + vector = rtvec_alloc (n); + for (i = 0; i < n; i++) + RTVEC_ELT (vector, i) = CONST0_RTX (emode); } } @@ -6634,10 +6638,10 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size, FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value) { - int n_elts_here = tree_to_uhwi - (int_const_binop (TRUNC_DIV_EXPR, - TYPE_SIZE (TREE_TYPE (value)), - TYPE_SIZE (elttype))); + tree sz = TYPE_SIZE (TREE_TYPE (value)); + int n_elts_here + = tree_to_uhwi (int_const_binop (TRUNC_DIV_EXPR, sz, + TYPE_SIZE (elttype))); count += n_elts_here; if (mostly_zeros_p (value)) @@ -6687,18 +6691,21 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size, if (vector) { - /* vec_init<mode> should not be used if there are VECTOR_TYPE - elements. */ - gcc_assert (TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE); - RTVEC_ELT (vector, eltpos) - = expand_normal (value); + if (vec_vec_init_p) + { + gcc_assert (ce->index == NULL_TREE); + gcc_assert (TREE_CODE (TREE_TYPE (value)) == VECTOR_TYPE); + eltpos = idx; + } + else + gcc_assert (TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE); + RTVEC_ELT (vector, eltpos) = expand_normal (value); } else { - machine_mode value_mode = - TREE_CODE (TREE_TYPE (value)) == VECTOR_TYPE - ? TYPE_MODE (TREE_TYPE (value)) - : eltmode; + machine_mode value_mode + = (TREE_CODE (TREE_TYPE (value)) == VECTOR_TYPE + ? TYPE_MODE (TREE_TYPE (value)) : eltmode); bitpos = eltpos * elt_size; store_constructor_field (target, bitsize, bitpos, 0, bitregion_end, value_mode, @@ -6707,9 +6714,9 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size, } if (vector) - emit_insn (GEN_FCN (icode) - (target, - gen_rtx_PARALLEL (GET_MODE (target), vector))); + emit_insn (GEN_FCN (icode) (target, + gen_rtx_PARALLEL (GET_MODE (target), + vector))); break; } |