diff mbox

Fix signed bitfield BIT_NOT_EXPR expansion (PR middle-end/52209)

Message ID 20120211114952.GE18768@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Feb. 11, 2012, 11:49 a.m. UTC
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?

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.


	Jakub

Comments

Richard Biener Feb. 13, 2012, 10:30 a.m. UTC | #1
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
diff mbox

Patch

--- 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;
+}