On 24/04/2023 12:57, Richard Biener wrote:
On Thu, Apr 20, 2023 at 3:24 PM Andre Vieira (lists) via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
Rebased all three patches and made some small changes to the second one:
- removed sub and abd optabs from commutative_optab_p, I suspect this
was a copy paste mistake,
- removed what I believe to be a superfluous switch case in vectorizable
conversion, the one that was here:
+ if (code.is_fn_code ())
+ {
+ internal_fn ifn = as_internal_fn (code.as_fn_code ());
+ int ecf_flags = internal_fn_flags (ifn);
+ gcc_assert (ecf_flags & ECF_MULTI);
+
+ switch (code.as_fn_code ())
+ {
+ case CFN_VEC_WIDEN_PLUS:
+ break;
+ case CFN_VEC_WIDEN_MINUS:
+ break;
+ case CFN_LAST:
+ default:
+ return false;
+ }
+
+ internal_fn lo, hi;
+ lookup_multi_internal_fn (ifn, &lo, &hi);
+ *code1 = as_combined_fn (lo);
+ *code2 = as_combined_fn (hi);
+ optab1 = lookup_multi_ifn_optab (lo, !TYPE_UNSIGNED (vectype));
+ optab2 = lookup_multi_ifn_optab (hi, !TYPE_UNSIGNED (vectype));
}
I don't think we need to check they are a specfic fn code, as we look-up
optabs and if they succeed then surely we can vectorize?
OK for trunk?
In the first patch I see some uses of safe_as_tree_code like
+ if (ch.is_tree_code ())
+ return op1 == NULL_TREE ? gimple_build_assign (lhs,
ch.safe_as_tree_code (),
+ op0) :
+ gimple_build_assign (lhs, ch.safe_as_tree_code (),
+ op0, op1);
+ else
+ {
+ internal_fn fn = as_internal_fn (ch.safe_as_fn_code ());
+ gimple* stmt;
where the context actually requires a valid tree code. Please change those
to force to tree code / ifn code. Just use explicit casts here and the other
places that are similar. Before the as_internal_fn just put a
gcc_assert (ch.is_internal_fn ()).
Maybe the need for the (ugly) safe_as_tree_code/fn_code goes away then.
Otherwise patch1 looks OK.
Unfortunately there are no ChangeLog / patch descriptions on the changes.
patch2 has
- tree_code rhs_code = gimple_assign_rhs_code (assign);
- if (rhs_code != code && rhs_code != widened_code)
+ code_helper rhs_code;
+ if (is_gimple_assign (stmt))
+ {
+ rhs_code = gimple_assign_rhs_code (stmt);
+ if (rhs_code.safe_as_tree_code () != code
+ && rhs_code.get_rep () != widened_code.get_rep ())
+ return 0;
+ }
+ else if (is_gimple_call (stmt))
+ {
+ rhs_code = gimple_call_combined_fn (stmt);
+ if (rhs_code.get_rep () != widened_code.get_rep ())
+ return 0;
+ }
that looks mightly complicated - esp. the use of get_rep ()
looks dangerous? What's the intent of this? Not that I
understand the existing code much. A comment would
clearly help (also indicating test coverage).
I don't think the use of get_rep here is dangerous, it's meant to avoid
having to check whether widened_code is the same 'kind' as rhs_code.
With get_rep we don't have to do this check first because tree_codes
will have positive reps and combined_fns negative reps. Having said
that, this can all be simplified and we don't need to use get_rep either
as the == operator has been overloaded to use get_rep and even use the
constructor on the rhs of the ==, so I suggest moving the check after
assigning rhs_code and just doing:
if (rhs_code != code
&& rhs_code != widened_code)
return 0;
Kind regards,
Andre