aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.cc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2023-02-10 13:09:10 +0100
committerRichard Biener <rguenther@suse.de>2023-04-28 11:05:53 +0200
commit821ef93976e750c118d42a2ad33b96dbd1b9f3a5 (patch)
tree7b6c9222dd6d0f2177388c680e3a36998c076055 /gcc/tree.cc
parent9a41d2cdbcd2af77a3a91a840a3a13f0eb39971b (diff)
downloadgcc-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.cc30
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. */