[Bug middle-end/103071] Missed optimization for symmetric subset: (a & b) == a || (a & b) == b

rguenth at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Thu Nov 4 09:11:25 GMT 2021


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

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
So a

_Bool EitherIsSubset (unsigned long v0, unsigned long v1)
{
  return (v0 & v1) == v0 || (v0 & v1) == v1;
}

is compiled to

EitherIsSubset:
.LFB0:
        .cfi_startproc
        movq    %rdi, %rdx
        andq    %rsi, %rdx
        cmpq    %rsi, %rdx
        sete    %al
        cmpq    %rdi, %rdx
        sete    %dl
        orl     %edx, %eax
        ret

your super-opt asm doesn't call foo or bar.

On the GIMPLE level we eventually see

  _1 = v0_3(D) & v1_4(D);
  _8 = _1 == v1_4(D);
  _9 = _1 == v0_3(D);
  _10 = _8 | _9;

which I think is quite optimal.  With the calls it becomes and if-conversion
problem on RTL (or an early RTL generation one).


More information about the Gcc-bugs mailing list