https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103973

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #5)
> We are lowering this to
> 
> return <retval> = TARGET_EXPR <D.8264, SAVE_EXPR <a> != SAVE_EXPR <b> ?
> SAVE_EXPR <a> < SAVE_EXPR <b> ? less : SAVE_EXPR <b> < SAVE_EXPR <a> ?
> greater : unordered : equivalent>>>;
> 
> I don't think we can elide the first ucomisd, but we should be able to CSE
> the last (from the original quoted assembler), not sure if it ultimatively
> results in better code though.

Why we couldn't do that?  It is true that GIMPLE starts with != comparison that
shouldn't raise exceptions if a or b is qNaN, but if one or both of the
operands is qNaN, then they will compare unequal and < comparison that should
raise exceptions if a or b is qNaN is done.
So, it would be nice if we could at gimple_isel or expansion or later pattern
recognize this and emit optimal code for it.

C testcase:
int
foo (double a, double b)
{
  if (a == b)
    return 0;
  if (a < b)
    return -1;
  if (a > b)
    return 1;
  return 2;
}

We should have something like:
comisd %xmm0, %xmm1
jp 1f
movl $0, %eax
jne 2f
3:
ret
2:
sbbl %eax, %eax
andl $2, %eax
subl $1, %eax
ret
1:
movl $2, %eax
ret

Reply via email to