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

--- Comment #8 from Uroš Bizjak <ubizjak at gmail dot com> ---
(In reply to Jakub Jelinek from comment #1)
> Started with r223689.  Though, generally that change looks like a useful
> GIMPLE canonicalization.


How about we amend the above change to:

diff --git a/gcc/match.pd b/gcc/match.pd
index 43bacb4f68e..1370ba7302d 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4506,6 +4506,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (cmp (negate @0) CONSTANT_CLASS_P@1)
   (if (FLOAT_TYPE_P (TREE_TYPE (@0))
        || (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+           && integer_nonzerop (@0)
           && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))))
    (with { tree tem = const_unop (NEGATE_EXPR, TREE_TYPE (@0), @1); }
     (if (tem && !TREE_OVERFLOW (tem))

so we simplify (cmp (negate @0) CONSTANT_CLASS_P@1)) only for non-zero integer
arguments. For the original testcase, the compare is eliminated:

test:
        negl    %edi
        pushq   %r12
        movl    %edi, %r12d
        je      .L2
        call    foo
        movl    %r12d, %eax
        popq    %r12
        ret
.L2:
        call    bar
        movl    %r12d, %eax
        popq    %r12
        ret

Please also note that for the slightly changed original testcase:

--cut here--
void f1 (void);
void f2 (void);

void
foo (int a)
{
  int r = -a;
  if (r)
    f1 ();
  else
    f2 ();
}
--cut here--

combine RTL pass manages to remove the negation without problems:

Trying 6 -> 7:
    6: {r84:SI=-r85:SI;clobber flags:CC;}
      REG_DEAD r85:SI
      REG_UNUSED flags:CC
    7: flags:CCZ=cmp(r84:SI,0)
      REG_DEAD r84:SI
Successfully matched this instruction:
(set (reg:CCZ 17 flags)
    (compare:CCZ (reg:SI 85)
        (const_int 0 [0])))

so the compilation (-O2) results in the same assembly:

foo:
        testl   %edi, %edi
        je      .L2
        jmp     f1
.L2:
        jmp     f2

Reply via email to