]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix output_constructor_bitfield handling of wide bitfields (PR89037)
authorRichard Sandiford <richard.sandiford@arm.com>
Tue, 7 May 2019 08:49:05 +0000 (08:49 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Tue, 7 May 2019 08:49:05 +0000 (08:49 +0000)
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-05-07  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
Backport from mainline:
2019-01-25  Richard Sandiford  <richard.sandiford@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.sandiford@arm.com>

PR middle-end/89037
* gcc.dg/pr89037.c: New test.

From-SVN: r270936

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr89037.c [new file with mode: 0644]
gcc/varasm.c

index 6d1af9a0ab5e18fb7483dc18cb9e518bfd4b57cc..933f1b28efdb7c4c878fc19c74f3040d7a856e18 100644 (file)
@@ -1,3 +1,12 @@
+2019-05-07  Richard Sandiford  <richard.sandiford@arm.com>
+
+       Backport from mainline:
+       2019-01-25  Richard Sandiford  <richard.sandiford@arm.com>
+
+       PR middle-end/89037
+       * varasm.c (output_constructor_bitfield): Use wi::extract_uhwi
+       instead of accessing TREE_INT_CST_ELT directly.
+
 2019-05-01  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
 
        Backport from mainline.
index d63484df11d60f85c95bc9e752b0811aaf273e8c..7b2d4657ab3160834429ab48e126221f4ede3944 100644 (file)
@@ -1,3 +1,11 @@
+2019-05-07  Richard Sandiford  <richard.sandiford@arm.com>
+
+       Backport from mainline:
+       2019-01-25  Richard Sandiford  <richard.sandiford@arm.com>
+
+       PR middle-end/89037
+       * gcc.dg/pr89037.c: New test.
+
 2019-05-05  Thomas Koenig <tkoenig@gcc.gnu.org>
 
        PR fortran/90344
diff --git a/gcc/testsuite/gcc.dg/pr89037.c b/gcc/testsuite/gcc.dg/pr89037.c
new file mode 100644 (file)
index 0000000..5511367
--- /dev/null
@@ -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;
+}
index 9ffef8abe3844794e24aa79eddd5d4c47b0478c0..e554cf56bc06617d770d9af1de48fb4a92864fdb 100644 (file)
@@ -5175,7 +5175,7 @@ output_constructor_bitfield (oc_local_state *local, unsigned int bit_offset)
     {
       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;
 
@@ -5207,15 +5207,13 @@ output_constructor_bitfield (oc_local_state *local, unsigned int bit_offset)
              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
        {
@@ -5232,15 +5230,13 @@ output_constructor_bitfield (oc_local_state *local, unsigned int bit_offset)
            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;