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

Reply via email to