Message ID | 20120211114952.GE18768@tyan-ft48-01.lab.bos.redhat.com |
---|---|
State | New |
Headers | show |
On Sat, Feb 11, 2012 at 12:49 PM, Jakub Jelinek <jakub@redhat.com> wrote: > Hi! > > In July Richard changed reduce_bit_field BIT_NOT_EXPR expansion from > NOT unop to XOR with all the bits in the bitfield's precision set. > Unfortunately that is correct for unsigned bitfields only, for signed > bitfields, where op0 is already sign-extended to its mode before this, > expanding this as NOT is the right thing. > > Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for > trunk? Ok. Thanks, Richard. > 2012-02-11 Jakub Jelinek <jakub@redhat.com> > > PR middle-end/52209 > * expr.c (expand_expr_real_2) <case BIT_NOT_EXPR>: Only expand using > XOR for reduce_bit_field if type is unsigned. > > * gcc.c-torture/execute/pr52209.c: New test. > > --- gcc/expr.c.jj 2012-02-07 16:05:51.000000000 +0100 > +++ gcc/expr.c 2012-02-11 10:08:44.162924423 +0100 > @@ -8582,8 +8582,9 @@ expand_expr_real_2 (sepops ops, rtx targ > if (modifier == EXPAND_STACK_PARM) > target = 0; > /* In case we have to reduce the result to bitfield precision > - expand this as XOR with a proper constant instead. */ > - if (reduce_bit_field) > + for unsigned bitfield expand this as XOR with a proper constant > + instead. */ > + if (reduce_bit_field && TYPE_UNSIGNED (type)) > temp = expand_binop (mode, xor_optab, op0, > immed_double_int_const > (double_int_mask (TYPE_PRECISION (type)), mode), > --- gcc/testsuite/gcc.c-torture/execute/pr52209.c.jj 2012-02-11 10:09:46.080571803 +0100 > +++ gcc/testsuite/gcc.c-torture/execute/pr52209.c 2012-02-11 10:09:28.000000000 +0100 > @@ -0,0 +1,14 @@ > +/* PR middle-end/52209 */ > + > +extern void abort (void); > +struct S0 { int f2 : 1; } c; > +int b; > + > +int > +main () > +{ > + b = -1 ^ c.f2; > + if (b != -1) > + abort (); > + return 0; > +} > > Jakub
--- gcc/expr.c.jj 2012-02-07 16:05:51.000000000 +0100 +++ gcc/expr.c 2012-02-11 10:08:44.162924423 +0100 @@ -8582,8 +8582,9 @@ expand_expr_real_2 (sepops ops, rtx targ if (modifier == EXPAND_STACK_PARM) target = 0; /* In case we have to reduce the result to bitfield precision - expand this as XOR with a proper constant instead. */ - if (reduce_bit_field) + for unsigned bitfield expand this as XOR with a proper constant + instead. */ + if (reduce_bit_field && TYPE_UNSIGNED (type)) temp = expand_binop (mode, xor_optab, op0, immed_double_int_const (double_int_mask (TYPE_PRECISION (type)), mode), --- gcc/testsuite/gcc.c-torture/execute/pr52209.c.jj 2012-02-11 10:09:46.080571803 +0100 +++ gcc/testsuite/gcc.c-torture/execute/pr52209.c 2012-02-11 10:09:28.000000000 +0100 @@ -0,0 +1,14 @@ +/* PR middle-end/52209 */ + +extern void abort (void); +struct S0 { int f2 : 1; } c; +int b; + +int +main () +{ + b = -1 ^ c.f2; + if (b != -1) + abort (); + return 0; +}