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 | |
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
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/expr.c | 37 |
2 files changed, 32 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d8c0e23..ed8d8b1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2012-09-18 Eric Botcazou <ebotcazou@adacore.com> + + PR middle-end/54617 + * expr.c (store_field): Handle a PARALLEL in more cases. + 2012-09-18 Segher Boessenkool <segher@kernel.crashing.org> * config/rs6000/rs6000.md (sminsi3, smaxsi3, uminsi3, umaxsi3): @@ -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; } |