* 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?

Reply via email to