On 14/07/15 11:06, Andrew Pinski wrote:
On Tue, Jul 14, 2015 at 1:18 AM, Kyrill Tkachov <kyrylo.tkac...@arm.com> wrote:
Hi Segher,

On 14/07/15 01:38, Segher Boessenkool wrote:
On Mon, Jul 13, 2015 at 10:48:19AM +0100, Kyrill Tkachov wrote:
For the testcase in the patch we were generating an extra neg
instruction:
          cmp     w0, wzr
          csneg   w0, w0, w0, ge
          neg     w0, w0
          ret

instead of the optimal:
          cmp     w0, wzr
          csneg   w0, w0, w0, lt
          ret

The reason is that combine tries to merge the operation into a negation
of
an abs.
Before combine, you have two insns, a negation and an abs, so that is
not so very strange :-)

Well, because the aarch64 integer abs expander expands to a compare
and a conditional negate, we have a compare followed by an if_then_else
with a neg in it. That's followed by a neg of that:
(insn 6 3 7 2 (set (reg:CC 66 cc)
         (compare:CC (reg/v:SI 76 [ x ])
             (const_int 0 [0]))) abs.c:1 374 {*cmpsi}
      (nil))
(insn 7 6 8 2 (set (reg:SI 78 [ D.2683 ])
         (if_then_else:SI (lt (reg:CC 66 cc)
                 (const_int 0 [0]))
             (neg:SI (reg/v:SI 76 [ x ]))
             (reg/v:SI 76 [ x ]))) abs.c:1 441 {csneg3si_insn}
      (expr_list:REG_DEAD (reg/v:SI 76 [ x ])
         (expr_list:REG_DEAD (reg:CC 66 cc)
             (expr_list:REG_EQUAL (abs:SI (reg/v:SI 76 [ x ]))
                 (nil)))))
(insn 8 7 13 2 (set (reg:SI 77 [ D.2683 ])
         (neg:SI (reg:SI 78 [ D.2683 ]))) abs.c:1 319 {negsi2}
      (expr_list:REG_DEAD (reg:SI 78 [ D.2683 ])
         (nil)))

What does combine do when it props 7 into 8?  I suspect you want to
optimize that instead of doing it any other way.
That is if prop the neg into the two sides of the conditional and if
one simplifies, produce a new rtl.

Yeah, that's what combine tries in simplify_if_then_else, instead of
propagating the neg it tries a (neg (abs x)). I did consider telling it not
to do that, but how would it be gated?
Should we look if the one arm of the if_then_else is a neg of the other and
invert the comparison code instead of trying (neg (abs x)) when 
HAVE_conditional_move?

Kyrill

Thanks,
Andrew Pinski


combine tries to convert it into a neg-of-an-abs in simplify_if_then_else

Some archs have actual nabs insns btw (for floating point, anyway).

Archs without abs or conditional assignment, and with cheap branches,
get a branch around a neg followed by another neg, at expand time.
This then isn't optimised away either.

So I'd say expand should be made a bit smarter for this.  Failing
that, your approach looks fine to me -- assuming you want to have a
fake "abs" insn at all.

On to the patch...


+;; Combine will try merging (c > 0 ? -x : x) into (-|x|).  This isn't a
good
"x > 0" here.

Thanks, I'll fix that when committing if approved.

Kyrill

Segher


Reply via email to