summaryrefslogtreecommitdiff
path: root/gcc/gimple-expr.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2020-01-09 15:08:26 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2020-01-09 15:08:26 +0000
commit482b2b43e5101921ad94e51e052a18b353f8a3f5 (patch)
tree7a5e26df37104db694de370115b38bbb80407fc2 /gcc/gimple-expr.c
parent15df0040707d630b78f4dd34dd4f435026dea56c (diff)
Add a compatible_vector_types_p target hook
One problem with adding an N-bit vector extension to an existing architecture is to decide how N-bit vectors should be passed to functions and returned from functions. Allowing all N-bit vector types to be passed in registers breaks backwards compatibility, since N-bit vectors could be used (and emulated) before the vector extension was added. But always passing N-bit vectors on the stack would be inefficient for things like vector libm functions. For SVE we took the compromise position of predefining new SVE vector types that are distinct from all existing vector types, including GNU-style vectors. The new types are passed and returned in an efficient way while existing vector types are passed and returned in the traditional way. In the right circumstances, the two types are inter-convertible. The SVE types are created using: vectype = build_distinct_type_copy (vectype); SET_TYPE_STRUCTURAL_EQUALITY (vectype); TYPE_ARTIFICIAL (vectype) = 1; The C frontend maintains this distinction, using VIEW_CONVERT_EXPR to convert from one type to the other. However, the distinction can be lost during gimple, which treats two vector types with the same mode, number of elements, and element type as equivalent. And for most targets that's the right thing to do. This patch therefore adds a hook that lets the target choose whether such vector types are indeed equivalent. Note that the new tests fail for -mabi=ilp32 in the same way as other ACLE-based tests. I'm still planning to fix that as a follow-on. 2020-01-09 Richard Sandiford <richard.sandiford@arm.com> gcc/ * target.def (compatible_vector_types_p): New target hook. * hooks.h (hook_bool_const_tree_const_tree_true): Declare. * hooks.c (hook_bool_const_tree_const_tree_true): New function. * doc/tm.texi.in (TARGET_COMPATIBLE_VECTOR_TYPES_P): New hook. * doc/tm.texi: Regenerate. * gimple-expr.c: Include target.h. (useless_type_conversion_p): Use targetm.compatible_vector_types_p. * config/aarch64/aarch64.c (aarch64_compatible_vector_types_p): New function. (TARGET_COMPATIBLE_VECTOR_TYPES_P): Define. * config/aarch64/aarch64-sve-builtins.cc (gimple_folder::convert_pred): Use the original predicate if it already has a suitable type. gcc/testsuite/ * gcc.target/aarch64/sve/pcs/gnu_vectors_1.c: New test. * gcc.target/aarch64/sve/pcs/gnu_vectors_2.c: Likewise. From-SVN: r280047
Diffstat (limited to 'gcc/gimple-expr.c')
-rw-r--r--gcc/gimple-expr.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/gcc/gimple-expr.c b/gcc/gimple-expr.c
index 8116993b870..44a0b8790f5 100644
--- a/gcc/gimple-expr.c
+++ b/gcc/gimple-expr.c
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "stringpool.h"
#include "attribs.h"
+#include "target.h"
/* ----- Type related ----- */
@@ -147,10 +148,12 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
/* Recurse for vector types with the same number of subparts. */
else if (TREE_CODE (inner_type) == VECTOR_TYPE
- && TREE_CODE (outer_type) == VECTOR_TYPE
- && TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type))
- return useless_type_conversion_p (TREE_TYPE (outer_type),
- TREE_TYPE (inner_type));
+ && TREE_CODE (outer_type) == VECTOR_TYPE)
+ return (known_eq (TYPE_VECTOR_SUBPARTS (inner_type),
+ TYPE_VECTOR_SUBPARTS (outer_type))
+ && useless_type_conversion_p (TREE_TYPE (outer_type),
+ TREE_TYPE (inner_type))
+ && targetm.compatible_vector_types_p (inner_type, outer_type));
else if (TREE_CODE (inner_type) == ARRAY_TYPE
&& TREE_CODE (outer_type) == ARRAY_TYPE)