diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2012-09-18 22:42:18 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2012-09-18 22:42:18 +0000 |
commit | 63d94e58b194a2f1a2022bfa03569ce51fd007f5 (patch) | |
tree | c5455487e4e74681465fd8b3190660245814f0f0 /gcc/expr.c | |
parent | 4f60e9d38fc40fc923451b9c0f03dcee86e6e4da (diff) | |
download | gcc-63d94e58b194a2f1a2022bfa03569ce51fd007f5.zip gcc-63d94e58b194a2f1a2022bfa03569ce51fd007f5.tar.gz gcc-63d94e58b194a2f1a2022bfa03569ce51fd007f5.tar.bz2 |
re PR middle-end/54617 (ICE on gcc.c-torture/compile/pr42025-2.c with -m64 and -O1)
PR middle-end/54617
* expr.c (store_field): Handle a PARALLEL in more cases.
From-SVN: r191451
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 37 |
1 files changed, 27 insertions, 10 deletions
@@ -6452,16 +6452,33 @@ store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos, /* Handle calls that return values in multiple non-contiguous locations. The Irix 6 ABI has examples of this. */ - if (bitpos == 0 - && bitsize == GET_MODE_BITSIZE (mode) - && GET_CODE (temp) == PARALLEL) - emit_group_store (target, temp, TREE_TYPE (exp), - int_size_in_bytes (TREE_TYPE (exp))); - else - /* Store the value in the bitfield. */ - store_bit_field (target, bitsize, bitpos, - bitregion_start, bitregion_end, - mode, temp); + if (GET_CODE (temp) == PARALLEL) + { + rtx temp_target; + + /* We are not supposed to have a true bitfield in this case. */ + gcc_assert (bitsize == GET_MODE_BITSIZE (mode)); + + /* If we don't store at bit 0, we need an intermediate pseudo + since emit_group_store only stores at bit 0. */ + if (bitpos != 0) + temp_target = gen_reg_rtx (mode); + else + temp_target = target; + + emit_group_store (temp_target, temp, TREE_TYPE (exp), + int_size_in_bytes (TREE_TYPE (exp))); + + if (temp_target == target) + return const0_rtx; + + temp = temp_target; + } + + /* Store the value in the bitfield. */ + store_bit_field (target, bitsize, bitpos, + bitregion_start, bitregion_end, + mode, temp); return const0_rtx; } |