From 4d9e473d125ec36ae4818d36d42bf4fea09cef1f Mon Sep 17 00:00:00 2001 From: Victor Do Nascimento Date: Mon, 23 Sep 2024 17:10:18 +0100 Subject: middle-end: Fix ifcvt predicate generation for masked function calls Up until now, due to a latent bug in the code for the ifcvt pass, irrespective of the branch taken in a conditional statement, the original condition for the if statement was used in masking the function call. Thus, for code such as: if (a[i] > limit) b[i] = fixed_const; else b[i] = fn (a[i]); we would generate the following (wrong) if-converted tree code: _1 = a[i_1]; _2 = _1 > limit; _3 = .MASK_CALL (fn, _1, _2); cstore_4 = _2 ? fixed_const : _3; as opposed to the correct expected sequence: _1 = a[i_1]; _2 = _1 > limit; _3 = ~_2; _4 = .MASK_CALL (fn, _1, _3); cstore_5 = _2 ? fixed_const : _4; This patch ensures that the correct predicate mask generation is carried out such that, upon autovectorization, the correct vector lanes are selected in the vectorized function call. gcc/ChangeLog: * tree-if-conv.cc (predicate_statements): Fix handling of predicated function calls. gcc/testsuite/ChangeLog: * gcc.dg/vect/vect-fncall-mask.c: New. --- gcc/tree-if-conv.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'gcc/tree-if-conv.cc') diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc index 0346a13..3b04d1e 100644 --- a/gcc/tree-if-conv.cc +++ b/gcc/tree-if-conv.cc @@ -2907,6 +2907,7 @@ predicate_statements (loop_p loop) This will cause the vectorizer to match the "in branch" clone variants, and serves to build the mask vector in a natural way. */ + tree mask = cond; gcall *call = dyn_cast (gsi_stmt (gsi)); tree orig_fn = gimple_call_fn (call); int orig_nargs = gimple_call_num_args (call); @@ -2914,7 +2915,18 @@ predicate_statements (loop_p loop) args.safe_push (orig_fn); for (int i = 0; i < orig_nargs; i++) args.safe_push (gimple_call_arg (call, i)); - args.safe_push (cond); + /* If `swap', we invert the mask used for the if branch for use + when masking the function call. */ + if (swap) + { + gimple_seq stmts = NULL; + tree true_val + = constant_boolean_node (true, TREE_TYPE (mask)); + mask = gimple_build (&stmts, BIT_XOR_EXPR, + TREE_TYPE (mask), mask, true_val); + gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT); + } + args.safe_push (mask); /* Replace the call with a IFN_MASK_CALL that has the extra condition parameter. */ -- cgit v1.1