From 63d94e58b194a2f1a2022bfa03569ce51fd007f5 Mon Sep 17 00:00:00 2001 From: Eric Botcazou <ebotcazou@adacore.com> Date: Tue, 18 Sep 2012 22:42:18 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 5 +++++ gcc/expr.c | 37 +++++++++++++++++++++++++++---------- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d8c0e23c013d..ed8d8b1575b8 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): diff --git a/gcc/expr.c b/gcc/expr.c index c53f1a8dc9b7..36f4dd7d53ec 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -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; } -- GitLab