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

--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> ---
We're still "stuck" on GIMPLE, on x86_64 we manage to elide the redundant load
now and get

foo:
.LFB0:
        .cfi_startproc
        movzbl  (%rdi), %eax
        movl    %eax, %edx
        shrb    %dl
        orl     %eax, %edx
        andl    $-2, %eax
        andl    $1, %edx
        orl     %edx, %eax
        movb    %al, (%rdi)
        ret

where we fail to notice the RMW.  A simpler testcase is

struct B { unsigned bit0 : 1; };

void
bar  (struct B *b, _Bool x)
{
  b->bit0 |= x;
}

which generates

bar:
.LFB0:
        .cfi_startproc
        movzbl  (%rdi), %eax
        orl     %eax, %esi
        andl    $-2, %eax
        andl    $1, %esi
        orl     %esi, %eax
        movb    %al, (%rdi)
        ret

we'd need to recognize

            (set (reg:QI 96)
                (ior:QI (and:QI (reg:QI 90 [ *b_3(D) ])
                         (const_int -2 [0xfffffffffffffffe])))
                    (and:QI (ior:QI (reg:QI 90 [ *b_3(D) ])
                             (subreg:QI (reg:SI 98) 0))
                     (const_int 1 [0x1]))))

(r90 & -2) | ((r90 | rx) & 1)
-> (r90 & -2) | (r90 & 1) | (rx & 1)
-> r90 | (rx & 1)

I have a patch for simplify-rtx.c that recognizes this generating

foo:
.LFB0:
        .cfi_startproc
        movzbl  (%rdi), %edx
        movl    %edx, %eax
        shrb    %al
        andl    $1, %eax
        orl     %edx, %eax
        movb    %al, (%rdi)
        ret

and

bar:
.LFB1:
        .cfi_startproc
        andl    $1, %esi
        orb     %sil, (%rdi)
        ret

Reply via email to