re PR middle-end/90840 (ICE in simplify_subreg, at simplify-rtx.c:6441)

PR middle-end/90840
	* expmed.c (store_bit_field_1): Handle the case where op0 is not a MEM
	and has a mode that doesn't have corresponding integral type.

	* gcc.c-torture/compile/pr90840.c: New test.

From-SVN: r278483
This commit is contained in:
Jakub Jelinek 2019-11-20 09:32:56 +01:00 committed by Jakub Jelinek
parent 94cdd3b7ce
commit d742b0c1a0
4 changed files with 47 additions and 0 deletions

View File

@ -1,5 +1,9 @@
2019-11-20 Jakub Jelinek <jakub@redhat.com>
PR middle-end/90840
* expmed.c (store_bit_field_1): Handle the case where op0 is not a MEM
and has a mode that doesn't have corresponding integral type.
PR target/90867
* config/i386/i386-options.c (ix86_valid_target_attribute_tree): Don't
clear opts->x_ix86_isa_flags{,2} here...

View File

@ -840,6 +840,27 @@ store_bit_field_1 (rtx str_rtx, poly_uint64 bitsize, poly_uint64 bitnum,
if (MEM_P (op0))
op0 = adjust_bitfield_address_size (op0, op0_mode.else_blk (),
0, MEM_SIZE (op0));
else if (!op0_mode.exists ())
{
if (ibitnum == 0
&& known_eq (ibitsize, GET_MODE_BITSIZE (GET_MODE (op0)))
&& MEM_P (value)
&& !reverse)
{
value = adjust_address (value, GET_MODE (op0), 0);
emit_move_insn (op0, value);
return true;
}
if (!fallback_p)
return false;
rtx temp = assign_stack_temp (GET_MODE (op0),
GET_MODE_SIZE (GET_MODE (op0)));
emit_move_insn (temp, op0);
store_bit_field_1 (temp, bitsize, bitnum, 0, 0, fieldmode, value,
reverse, fallback_p);
emit_move_insn (op0, temp);
return true;
}
else
op0 = gen_lowpart (op0_mode.require (), op0);
}

View File

@ -1,5 +1,8 @@
2019-11-20 Jakub Jelinek <jakub@redhat.com>
PR middle-end/90840
* gcc.c-torture/compile/pr90840.c: New test.
PR target/90867
* gcc.target/i386/pr90867.c: New test.

View File

@ -0,0 +1,19 @@
/* PR middle-end/90840 */
struct S { long long a; int b; };
struct S foo (void);
struct __attribute__((packed)) T { long long a; char b; };
struct T baz (void);
void
bar (void)
{
_Complex long double c;
*(struct S *) &c = foo ();
}
void
qux (void)
{
_Complex long double c;
*(struct T *) &c = baz ();
}