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

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to ptomsich from comment #2)
> To copy the last piece of info from our internal tracker...
> 
> LLVM learned this new trick only in the run-up to LLVM 18.
> Up until then, GCC and LLVM performed identically on this snippet.

Yes it looks like it is pattern matching what I suggested (well with and
without the and).

Note we do need another pattern, one without the bit_and:
(simplify
 (bit_ior
  (ne@n4 @0 @1)
  (cmp
   (bit_xor @0 @1)
   @2))
 (bit_ior @n4 
  (cmp { build_zero_cst (TREE_TYPE (@0)); } @2))
)

And we need one more for bit_ior:
(simplify
 (bit_ior
  (ne@n4 @0 @1)
  (cmp
   (bit_ior
    (bit_xor @0 @1)
    @2)
   @3))
 (bit_ior @n4 
  (cmp @2 @3))
)

Note it looks like clang does not handle non-contants that well, (they handle d
== 0 though).

E.g.:
```
int foo(void);
int cmp1(unsigned d1, unsigned d2, unsigned c, unsigned d) {
  int t = ((d1 ^ d2) & c ) == (d);
  int t1 = d1 != d2;
  int tt = t | t1;
  return tt;
}

```

Should be optimized to:
int foo(void);
int cmp1(unsigned d1, unsigned d2, unsigned c, unsigned d) {
  int t = 0 == d;
  int t1 = d1 != d2;
  int tt = t | t1;
  return tt;
}
```

Reply via email to