Commit 3c35efc3 by Richard Sandiford Committed by Richard Sandiford

Fix output_constructor_bitfield handling of wide bitfields (PR89037)

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-01-25  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	PR middle-end/89037
	* varasm.c (output_constructor_bitfield): Use wi::extract_uhwi
	instead of accessing TREE_INT_CST_ELT directly.

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

From-SVN: r268272
parent 62fa42ce
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-01-25 Christophe Lyon <christophe.lyon@linaro.org> 2019-01-25 Christophe Lyon <christophe.lyon@linaro.org>
* doc/sourcebuild.texi (Environment attributes): Add fenv and * doc/sourcebuild.texi (Environment attributes): Add fenv and
......
2019-01-25 Richard Sandiford <richard.sandiford@arm.com>
PR middle-end/89037
* gcc.dg/pr89037.c: New test.
2019-01-25 Christophe Lyon <christophe.lyon@linaro.org> 2019-01-25 Christophe Lyon <christophe.lyon@linaro.org>
* lib/target-supports.exp (check_effective_target_fenv): New. * lib/target-supports.exp (check_effective_target_fenv): New.
......
/* { 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;
}
...@@ -5349,7 +5349,7 @@ output_constructor_bitfield (oc_local_state *local, unsigned int bit_offset) ...@@ -5349,7 +5349,7 @@ output_constructor_bitfield (oc_local_state *local, unsigned int bit_offset)
{ {
int this_time; int this_time;
int shift; 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_byte = next_offset / BITS_PER_UNIT;
HOST_WIDE_INT next_bit = next_offset % BITS_PER_UNIT; HOST_WIDE_INT next_bit = next_offset % BITS_PER_UNIT;
...@@ -5381,15 +5381,13 @@ output_constructor_bitfield (oc_local_state *local, unsigned int bit_offset) ...@@ -5381,15 +5381,13 @@ output_constructor_bitfield (oc_local_state *local, unsigned int bit_offset)
this_time = end - shift + 1; this_time = end - shift + 1;
} }
/* Now get the bits from the appropriate constant word. */ /* Now get the bits we want to insert. */
value = TREE_INT_CST_ELT (local->val, shift / HOST_BITS_PER_WIDE_INT); value = wi::extract_uhwi (wi::to_widest (local->val),
shift = shift & (HOST_BITS_PER_WIDE_INT - 1); shift, this_time);
/* Get the result. This works only when: /* Get the result. This works only when:
1 <= this_time <= HOST_BITS_PER_WIDE_INT. */ 1 <= this_time <= HOST_BITS_PER_WIDE_INT. */
local->byte |= (((value >> shift) local->byte |= value << (BITS_PER_UNIT - this_time - next_bit);
& (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1))
<< (BITS_PER_UNIT - this_time - next_bit));
} }
else else
{ {
...@@ -5406,15 +5404,13 @@ output_constructor_bitfield (oc_local_state *local, unsigned int bit_offset) ...@@ -5406,15 +5404,13 @@ output_constructor_bitfield (oc_local_state *local, unsigned int bit_offset)
this_time this_time
= HOST_BITS_PER_WIDE_INT - (shift & (HOST_BITS_PER_WIDE_INT - 1)); = HOST_BITS_PER_WIDE_INT - (shift & (HOST_BITS_PER_WIDE_INT - 1));
/* Now get the bits from the appropriate constant word. */ /* Now get the bits we want to insert. */
value = TREE_INT_CST_ELT (local->val, shift / HOST_BITS_PER_WIDE_INT); value = wi::extract_uhwi (wi::to_widest (local->val),
shift = shift & (HOST_BITS_PER_WIDE_INT - 1); shift, this_time);
/* Get the result. This works only when: /* Get the result. This works only when:
1 <= this_time <= HOST_BITS_PER_WIDE_INT. */ 1 <= this_time <= HOST_BITS_PER_WIDE_INT. */
local->byte |= (((value >> shift) local->byte |= value << next_bit;
& (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1))
<< next_bit);
} }
next_offset += this_time; next_offset += this_time;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment