* Jeff Law:
> This is Shreya's work except for the SH testcase which I added after
> realizing her work would also fix the testcases for that port. I
> bootstrapped and regression tested this on sh4-linux-gnu, x86_64 &
> risc-v. It also was tested across all the embedded targets in my tester
> without regressions.
>
> --
>
>
> We are extracting two single-bit bitfields from a structure and
> determining whether they both have the value 0 or if at least one bit is
> set. This has been generating poor code:
>
> > lw a5,0(a0)
> > bexti a0,a5,1
> > bexti a5,a5,2
> > or a0,a0,a5
> > ret
>
> We address this as a simplification problem and optimize this using an
> andi of the original value and a mask with just the desired bits set,
> followed by a snez. This results in a 1 if any of those bits are set or
> 0 if none.
>
> For cases where we want to extract three or more single-bit bitfields,
> we build on the previous case. We take the result of the 2-bitfield
> case, extract the mask, update it to include the new single-bit
> bitfield, and again perform an andi + snez.
>
> In our new testfile, we scan to ensure we do not see a bexti or an or
> instruction, and that we have the correct assembly for both two and
> three single-bit bitfield cases: lw + andi + snez + ret.
We still have horrible code generation for this on x86-64.
>From the bug report:
typedef struct
{
_Bool a : 1;
_Bool b : 1;
_Bool c : 1;
_Bool d : 1;
unsigned int e : 4;
} S;
_Bool test_00 (S* s)
{
return s->b | s->c;
}
We get this:
test_00:
movzbl (%rdi), %edx
movl %edx, %ecx
movl %edx, %eax
shrb %cl
shrb $2, %al
orl %ecx, %eax
andl $1, %eax
ret
This should be something like this instead:
test_00:
xorl %eax, %eax
testb $6, (%rdi)
setne %al
retq
Is there no generic infrastructure that could handle this?