Hi all,
The aarch64 target has a conditional negation instruction
CSNEG Rd, Rs1, Rs2, cond
with semantics Rd = if cond then Rs1 else -Rs2.
This, however doesn't get end up getting matched for code such as:
int
foo2 (unsigned a, unsigned b)
{
int r = 0;
r = a & b;
if (a & b)
return -r;
return r;
}
because the code in tree-ssa-phiopt.c transforms conditional negation
into (rhs ^ -cond) + cond. The transformation is guarded by this:
/* The replacement of conditional negation with a non-branching
sequence is really only a win when optimizing for speed and we
can avoid transformations by gimple if-conversion that result
in poor RTL generation.
Ideally either gimple if-conversion or the RTL expanders will
be improved and the code to emit branchless conditional negation
can be removed. */
bool replace_conditional_negation = false;
if (!do_store_elim)
replace_conditional_negation
= ((!optimize_size && optimize >= 2)
|| (((flag_tree_loop_vectorize || cfun->has_force_vectorize_loops)
&& flag_tree_loop_if_convert != 0)
|| flag_tree_loop_if_convert == 1
|| flag_tree_loop_if_convert_stores == 1));
I haven't been able to get combine to match the comparison+xor+neg+plus
RTL and it seems like it would be just a workaround to undo the
tree-level transformation.
What is the most acceptable way of disabling this transformation for a
target that has a conditional negation instruction?
Thanks,
Kyrill