diff options
author | Richard Biener <rguenther@suse.de> | 2023-02-10 13:09:10 +0100 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2023-04-28 11:05:53 +0200 |
commit | 821ef93976e750c118d42a2ad33b96dbd1b9f3a5 (patch) | |
tree | 7b6c9222dd6d0f2177388c680e3a36998c076055 /gcc/tree.cc | |
parent | 9a41d2cdbcd2af77a3a91a840a3a13f0eb39971b (diff) | |
download | gcc-821ef93976e750c118d42a2ad33b96dbd1b9f3a5.zip gcc-821ef93976e750c118d42a2ad33b96dbd1b9f3a5.tar.gz gcc-821ef93976e750c118d42a2ad33b96dbd1b9f3a5.tar.bz2 |
tree-optimization/108752 - vectorize emulated vectors in lowered form
The following makes sure to emit operations lowered to bit operations
when vectorizing using emulated vectors. This avoids relying on
the vector lowering pass adhering to the exact same cost considerations
as the vectorizer.
PR tree-optimization/108752
* tree-vect-generic.cc (build_replicated_const): Rename
to build_replicated_int_cst and move to tree.{h,cc}.
(do_plus_minus): Adjust.
(do_negate): Likewise.
* tree-vect-stmts.cc (vectorizable_operation): Emit emulated
arithmetic vector operations in lowered form.
* tree.h (build_replicated_int_cst): Declare.
* tree.cc (build_replicated_int_cst): Moved from
tree-vect-generic.cc build_replicated_const.
Diffstat (limited to 'gcc/tree.cc')
-rw-r--r-- | gcc/tree.cc | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/gcc/tree.cc b/gcc/tree.cc index ead4248..7e6de28 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -2667,6 +2667,36 @@ build_zero_cst (tree type) } } +/* Build a constant of integer type TYPE, made of VALUE's bits replicated + every WIDTH bits to fit TYPE's precision. */ + +tree +build_replicated_int_cst (tree type, unsigned int width, HOST_WIDE_INT value) +{ + int n = (TYPE_PRECISION (type) + HOST_BITS_PER_WIDE_INT - 1) + / HOST_BITS_PER_WIDE_INT; + unsigned HOST_WIDE_INT low, mask; + HOST_WIDE_INT a[WIDE_INT_MAX_ELTS]; + int i; + + gcc_assert (n && n <= WIDE_INT_MAX_ELTS); + + if (width == HOST_BITS_PER_WIDE_INT) + low = value; + else + { + mask = ((HOST_WIDE_INT)1 << width) - 1; + low = (unsigned HOST_WIDE_INT) ~0 / mask * (value & mask); + } + + for (i = 0; i < n; i++) + a[i] = low; + + gcc_assert (TYPE_PRECISION (type) <= MAX_BITSIZE_MODE_ANY_INT); + return wide_int_to_tree + (type, wide_int::from_array (a, n, TYPE_PRECISION (type))); +} + /* If floating-point type TYPE has an IEEE-style sign bit, return an unsigned constant in which only the sign bit is set. Return null otherwise. */ |