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