diff options
-rw-r--r-- | gcc/expmed.cc | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr110717-2.c | 20 |
2 files changed, 26 insertions, 2 deletions
diff --git a/gcc/expmed.cc b/gcc/expmed.cc index fbd4ce2..b294eabb 100644 --- a/gcc/expmed.cc +++ b/gcc/expmed.cc @@ -1631,6 +1631,7 @@ extract_bit_field_as_subreg (machine_mode mode, rtx op0, } /* A subroutine of extract_bit_field, with the same arguments. + If UNSIGNEDP is -1, the result need not be sign or zero extended. If FALLBACK_P is true, fall back to extract_fixed_bit_field if we can find no other means of implementing the operation. if FALLBACK_P is false, return NULL instead. */ @@ -1933,7 +1934,8 @@ extract_integral_bit_field (rtx op0, opt_scalar_int_mode op0_mode, rtx result_part = extract_bit_field_1 (op0, MIN (BITS_PER_WORD, bitsize - i * BITS_PER_WORD), - bitnum + bit_offset, 1, target_part, + bitnum + bit_offset, + (unsignedp ? 1 : -1), target_part, mode, word_mode, reverse, fallback_p, NULL); gcc_assert (target_part); @@ -2187,6 +2189,7 @@ extract_fixed_bit_field (machine_mode tmode, rtx op0, /* Helper function for extract_fixed_bit_field, extracts the bit field always using MODE, which is the mode of OP0. + If UNSIGNEDP is -1, the result need not be sign or zero extended. The other arguments are as for extract_fixed_bit_field. */ static rtx @@ -2231,7 +2234,8 @@ extract_fixed_bit_field_1 (machine_mode tmode, rtx op0, scalar_int_mode mode, /* Unless the msb of the field used to be the msb when we shifted, mask out the upper bits. */ - if (GET_MODE_BITSIZE (mode) != bitnum + bitsize) + if (GET_MODE_BITSIZE (mode) != bitnum + bitsize + && unsignedp != -1) return expand_binop (new_mode, and_optab, op0, mask_rtx (new_mode, 0, bitsize, 0), target, 1, OPTAB_LIB_WIDEN); diff --git a/gcc/testsuite/gcc.target/i386/pr110717-2.c b/gcc/testsuite/gcc.target/i386/pr110717-2.c new file mode 100644 index 0000000..a3cb568 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr110717-2.c @@ -0,0 +1,20 @@ +/* PR target/110717 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#ifdef __SIZEOF_INT128__ +#define type __int128 +#define N 59 +#else +#define type long long +#define N 27 +#endif + +struct S { type a : sizeof (type) * __CHAR_BIT__ - N; }; + +unsigned type bar (struct S *p) +{ + return p->a; +} + +/* { dg-final { scan-assembler-not "andl" } } */ |