diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2023-11-27 14:44:02 +0000 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2023-11-27 14:44:02 +0000 |
commit | 31e9074977bb7de83fa5d28d286323987d5d87f2 (patch) | |
tree | 01416ccbed7f3f35dafd883c897417378fe3ee4d | |
parent | f7884f7673444b8a2c10ea0981d480f2e82dd16a (diff) | |
download | gcc-31e9074977bb7de83fa5d28d286323987d5d87f2.zip gcc-31e9074977bb7de83fa5d28d286323987d5d87f2.tar.gz gcc-31e9074977bb7de83fa5d28d286323987d5d87f2.tar.bz2 |
aarch64: Move and generalise vect_all_same
The fix for PR106329 needs a way of testing for a ptrue of a particular
element size. We already had such a function for svlast, so this patch
moves it to common code and generalises it to work with all kinds of
vectors.
gcc/
* config/aarch64/aarch64-sve-builtins.h (vector_cst_all_same): Declare.
* config/aarch64/aarch64-sve-builtins.cc (vector_cst_all_same): New
function, a generalized replacement of...
* config/aarch64/aarch64-sve-builtins-base.cc
(svlast_impl::vect_all_same): ...this.
(svlast_impl::fold): Update accordingly.
-rw-r--r-- | gcc/config/aarch64/aarch64-sve-builtins-base.cc | 17 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64-sve-builtins.cc | 20 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64-sve-builtins.h | 2 |
3 files changed, 24 insertions, 15 deletions
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc b/gcc/config/aarch64/aarch64-sve-builtins-base.cc index 9010ecc..a6e527b 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc @@ -1105,19 +1105,6 @@ public: bool is_lasta () const { return m_unspec == UNSPEC_LASTA; } bool is_lastb () const { return m_unspec == UNSPEC_LASTB; } - bool vect_all_same (tree v, int step) const - { - int i; - int nelts = vector_cst_encoded_nelts (v); - tree first_el = VECTOR_CST_ENCODED_ELT (v, 0); - - for (i = 0; i < nelts; i += step) - if (!operand_equal_p (VECTOR_CST_ENCODED_ELT (v, i), first_el, 0)) - return false; - - return true; - } - /* Fold a svlast{a/b} call with constant predicate to a BIT_FIELD_REF. BIT_FIELD_REF lowers to Advanced SIMD element extract, so we have to ensure the index of the element being accessed is in the range of a @@ -1142,7 +1129,7 @@ public: without a linear search of the predicate vector: 1. LASTA if predicate is all true, return element 0. 2. LASTA if predicate all false, return element 0. */ - if (is_lasta () && vect_all_same (pred, step_1)) + if (is_lasta () && vector_cst_all_same (pred, step_1)) { b = build3 (BIT_FIELD_REF, TREE_TYPE (f.lhs), val, bitsize_int (step * BITS_PER_UNIT), bitsize_int (0)); @@ -1152,7 +1139,7 @@ public: /* Handle the all-false case for LASTB where SVE VL == 128b - return the highest numbered element. */ if (is_lastb () && known_eq (BYTES_PER_SVE_VECTOR, 16) - && vect_all_same (pred, step_1) + && vector_cst_all_same (pred, step_1) && integer_zerop (VECTOR_CST_ENCODED_ELT (pred, 0))) { b = build3 (BIT_FIELD_REF, TREE_TYPE (f.lhs), val, diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc index 161a14e..b611563 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins.cc @@ -2541,6 +2541,26 @@ function_checker::check () return shape->check (*this); } +/* Return true if V is a vector constant and if, for every in-range integer I, + element STEP*I is equal to element 0. */ +bool +vector_cst_all_same (tree v, unsigned int step) +{ + if (TREE_CODE (v) != VECTOR_CST) + return false; + + /* VECTOR_CST_NELTS_PER_PATTERN applies to any multiple of + VECTOR_CST_NPATTERNS. */ + unsigned int lcm = least_common_multiple (step, VECTOR_CST_NPATTERNS (v)); + unsigned int nelts = lcm * VECTOR_CST_NELTS_PER_PATTERN (v); + tree first_el = VECTOR_CST_ENCODED_ELT (v, 0); + for (unsigned int i = 0; i < nelts; i += step) + if (!operand_equal_p (VECTOR_CST_ENCODED_ELT (v, i), first_el, 0)) + return false; + + return true; +} + gimple_folder::gimple_folder (const function_instance &instance, tree fndecl, gimple_stmt_iterator *gsi_in, gcall *call_in) : function_call_info (gimple_location (call_in), instance, fndecl), diff --git a/gcc/config/aarch64/aarch64-sve-builtins.h b/gcc/config/aarch64/aarch64-sve-builtins.h index a301570..d646df1 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.h +++ b/gcc/config/aarch64/aarch64-sve-builtins.h @@ -672,6 +672,8 @@ extern tree acle_vector_types[MAX_TUPLE_SIZE][NUM_VECTOR_TYPES + 1]; extern tree acle_svpattern; extern tree acle_svprfop; +bool vector_cst_all_same (tree, unsigned int); + /* Return the ACLE type svbool_t. */ inline tree get_svbool_t (void) |