aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const-call.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2019-08-13 21:33:51 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2019-08-13 21:33:51 +0000
commit0b1fe8cf6f1dde656c505dde6d27279dff388962 (patch)
treea3eff991a44ccd4c0437b4c3b39690ba2caa10a3 /gcc/fold-const-call.c
parentabb1d111f99fa2b480923e55dd74a974a62c9624 (diff)
downloadgcc-0b1fe8cf6f1dde656c505dde6d27279dff388962.zip
gcc-0b1fe8cf6f1dde656c505dde6d27279dff388962.tar.gz
gcc-0b1fe8cf6f1dde656c505dde6d27279dff388962.tar.bz2
Optimise constant IFN_WHILE_ULTs
This patch is a combination of two changes that have to be committed as a single unit: (1) Try to fold IFN_WHILE_ULTs with constant arguments to a VECTOR_CST (which is always possible for fixed-length vectors but is not necessarily so for variable-length vectors) (2) Make the SVE port recognise constants that map to PTRUE VLn, which includes those generated by the new fold. (2) can't be tested without (1) and (1) would be a significant pessimisation without (2). The target-specific parts also start moving towards doing predicate manipulation in a canonical VNx16BImode form, using rtx_vector_builders. 2019-08-13 Richard Sandiford <richard.sandiford@arm.com> gcc/ * tree.h (build_vector_a_then_b): Declare. * tree.c (build_vector_a_then_b): New function. * fold-const-call.c (fold_while_ult): Likewise. (fold_const_call): Use it to handle IFN_WHILE_ULT. * config/aarch64/aarch64-protos.h (AARCH64_FOR_SVPATTERN): New macro. (aarch64_svpattern): New enum. * config/aarch64/aarch64-sve.md (mov<PRED_ALL:mode>): Pass constants through aarch64_expand_mov_immediate. (*aarch64_sve_mov<PRED_ALL:mode>): Use aarch64_mov_operand rather than general_operand as the predicate for operand 1. (while_ult<GPI:mode><PRED_ALL:mode>): Add a '@' marker. * config/aarch64/aarch64.c (simd_immediate_info::PTRUE): New insn_type. (simd_immediate_info::simd_immediate_info): New overload that takes a scalar_int_mode and an svpattern. (simd_immediate_info::u): Add a "pattern" field. (svpattern_token): New function. (aarch64_get_sve_pred_bits, aarch64_widest_sve_pred_elt_size) (aarch64_partial_ptrue_length, aarch64_svpattern_for_vl) (aarch64_sve_move_pred_via_while): New functions. (aarch64_expand_mov_immediate): Try using aarch64_sve_move_pred_via_while for predicates that contain N ones followed by M zeros but that do not correspond to a VLnnn pattern. (aarch64_sve_pred_valid_immediate): New function. (aarch64_simd_valid_immediate): Use it instead of dealing directly with PTRUE and PFALSE. (aarch64_output_sve_mov_immediate): Handle new simd_immediate_info forms. gcc/testsuite/ * gcc.target/aarch64/sve/spill_2.c: Increase iteration counts beyond the range of a PTRUE. * gcc.target/aarch64/sve/while_6.c: New test. * gcc.target/aarch64/sve/while_7.c: Likewise. * gcc.target/aarch64/sve/while_8.c: Likewise. * gcc.target/aarch64/sve/while_9.c: Likewise. * gcc.target/aarch64/sve/while_10.c: Likewise. From-SVN: r274402
Diffstat (limited to 'gcc/fold-const-call.c')
-rw-r--r--gcc/fold-const-call.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/gcc/fold-const-call.c b/gcc/fold-const-call.c
index 702c8b4..e21d8e11 100644
--- a/gcc/fold-const-call.c
+++ b/gcc/fold-const-call.c
@@ -691,6 +691,36 @@ fold_const_vec_convert (tree ret_type, tree arg)
/* Try to evaluate:
+ IFN_WHILE_ULT (ARG0, ARG1, (TYPE) { ... })
+
+ Return the value on success and null on failure. */
+
+static tree
+fold_while_ult (tree type, poly_uint64 arg0, poly_uint64 arg1)
+{
+ if (known_ge (arg0, arg1))
+ return build_zero_cst (type);
+
+ if (maybe_ge (arg0, arg1))
+ return NULL_TREE;
+
+ poly_uint64 diff = arg1 - arg0;
+ poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (type);
+ if (known_ge (diff, nelts))
+ return build_all_ones_cst (type);
+
+ unsigned HOST_WIDE_INT const_diff;
+ if (known_le (diff, nelts) && diff.is_constant (&const_diff))
+ {
+ tree minus_one = build_minus_one_cst (TREE_TYPE (type));
+ tree zero = build_zero_cst (TREE_TYPE (type));
+ return build_vector_a_then_b (type, const_diff, minus_one, zero);
+ }
+ return NULL_TREE;
+}
+
+/* Try to evaluate:
+
*RESULT = FN (*ARG)
in format FORMAT. Return true on success. */
@@ -1782,6 +1812,14 @@ fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2)
}
return NULL_TREE;
+ case CFN_WHILE_ULT:
+ {
+ poly_uint64 parg0, parg1;
+ if (poly_int_tree_p (arg0, &parg0) && poly_int_tree_p (arg1, &parg1))
+ return fold_while_ult (type, parg0, parg1);
+ return NULL_TREE;
+ }
+
default:
return fold_const_call_1 (fn, type, arg0, arg1, arg2);
}