On April 29, 2019 9:51:11 AM GMT+02:00, Richard Sandiford <richard.sandif...@arm.com> wrote: >It's not obvious from the PR whether this is a regression, so I'm not >sure whether it deserves to be backported or not. Just in case... > >Tested on aarch64-linux-gnu, aarch64_be-elf and x86_64-linux-gnu. >OK for gcc-8-branch and gcc-7-branch?
Yes please. Richard. If not, should I close the PR? > >Thanks, >Richard > > > >The testcase was failing because we were trying to access >TREE_INT_CST_ELT (x, 1) of a 128-bit integer that was small enough >to need only a single element. > >2019-04-29 Richard Sandiford <richard.sandif...@arm.com> > >gcc/ > Backport from mainline: > 2019-01-25 Richard Sandiford <richard.sandif...@arm.com> > > PR middle-end/89037 > * varasm.c (output_constructor_bitfield): Use wi::extract_uhwi > instead of accessing TREE_INT_CST_ELT directly. > >gcc/testsuite/ > Backport from mainline: > 2019-01-25 Richard Sandiford <richard.sandif...@arm.com> > > PR middle-end/89037 > * gcc.dg/pr89037.c: New test. > >Index: gcc/varasm.c >=================================================================== >--- gcc/varasm.c 2019-04-29 08:40:40.141347619 +0100 >+++ gcc/varasm.c 2019-04-29 08:44:12.736632535 +0100 >@@ -5292,7 +5292,7 @@ output_constructor_bitfield (oc_local_st > { > int this_time; > int shift; >- HOST_WIDE_INT value; >+ unsigned HOST_WIDE_INT value; > HOST_WIDE_INT next_byte = next_offset / BITS_PER_UNIT; > HOST_WIDE_INT next_bit = next_offset % BITS_PER_UNIT; > >@@ -5324,15 +5324,13 @@ output_constructor_bitfield (oc_local_st > this_time = end - shift + 1; > } > >- /* Now get the bits from the appropriate constant word. */ >- value = TREE_INT_CST_ELT (local->val, shift / >HOST_BITS_PER_WIDE_INT); >- shift = shift & (HOST_BITS_PER_WIDE_INT - 1); >+ /* Now get the bits we want to insert. */ >+ value = wi::extract_uhwi (wi::to_widest (local->val), >+ shift, this_time); > > /* Get the result. This works only when: > 1 <= this_time <= HOST_BITS_PER_WIDE_INT. */ >- local->byte |= (((value >> shift) >- & (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1)) >- << (BITS_PER_UNIT - this_time - next_bit)); >+ local->byte |= value << (BITS_PER_UNIT - this_time - next_bit); > } > else > { >@@ -5349,15 +5347,13 @@ output_constructor_bitfield (oc_local_st > this_time > = HOST_BITS_PER_WIDE_INT - (shift & (HOST_BITS_PER_WIDE_INT - >1)); > >- /* Now get the bits from the appropriate constant word. */ >- value = TREE_INT_CST_ELT (local->val, shift / >HOST_BITS_PER_WIDE_INT); >- shift = shift & (HOST_BITS_PER_WIDE_INT - 1); >+ /* Now get the bits we want to insert. */ >+ value = wi::extract_uhwi (wi::to_widest (local->val), >+ shift, this_time); > > /* Get the result. This works only when: > 1 <= this_time <= HOST_BITS_PER_WIDE_INT. */ >- local->byte |= (((value >> shift) >- & (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1)) >- << next_bit); >+ local->byte |= value << next_bit; > } > > next_offset += this_time; >Index: gcc/testsuite/gcc.dg/pr89037.c >=================================================================== >--- /dev/null 2019-03-08 11:40:14.606883727 +0000 >+++ gcc/testsuite/gcc.dg/pr89037.c 2019-04-29 08:44:12.732632549 +0100 >@@ -0,0 +1,24 @@ >+/* { dg-do run { target int128 } } */ >+/* { dg-options "" } */ >+ >+struct s >+{ >+ __int128 y : 66; >+}; >+typedef struct s T; >+T a[] = { 1, 10000, 0x12345, 0xff000001, 1ULL << 63, (__int128) 1 << >64, >+ ((__int128) 1 << 64) | 1 }; >+ >+int >+main (void) >+{ >+ if (a[0].y != 1 >+ || a[1].y != 10000 >+ || a[2].y != 0x12345 >+ || a[3].y != 0xff000001 >+ || a[4].y != (1ULL << 63) >+ || a[5].y != ((__int128) 1 << 64) >+ || a[6].y != (((__int128) 1 << 64) | 1)) >+ __builtin_abort (); >+ return 0; >+}