===================================================================
@@ -8037,7 +8037,15 @@ expand_expr_real_2 (sepops ops, rtx targ
VOIDmode, EXPAND_NORMAL);
if (modifier == EXPAND_STACK_PARM)
target = 0;
- temp = expand_unop (mode, one_cmpl_optab, op0, target, 1);
+ /* In case we have to reduce the result to bitfield precision
+ expand this as XOR with a proper constant instead. */
+ if (reduce_bit_field)
+ temp = expand_binop (mode, xor_optab, op0,
+ immed_double_int_const
+ (double_int_mask (TYPE_PRECISION (type)), mode),
+ target, 1, OPTAB_LIB_WIDEN);
+ else
+ temp = expand_unop (mode, one_cmpl_optab, op0, target, 1);
gcc_assert (temp);
return temp;
===================================================================
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+
+extern void abort (void);
+struct X { unsigned long i : 33; };
+unsigned long __attribute__((noinline))
+foo (struct X *p)
+{
+ return ~p->i;
+}
+int main()
+{
+ struct X x;
+ x.i = -1;
+ if (foo (&x) != 0)
+ abort ();
+ return 0;
+}