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

Reply via email to