Commit 7d293b58 by Jakub Jelinek Committed by Jakub Jelinek

re PR middle-end/37870 (ICE in extract_bit_field_1)

	PR middle-end/37870
	* expmed.c (extract_bit_field_1): If int_mode_for_mode returns
	BLKmode for non-memory, convert using a wider MODE_INT mode
	or through memory.

	* gcc.target/i386/pr37870.c: New test.

From-SVN: r141430
parent d3f7b2c6
2008-10-29 Jakub Jelinek <jakub@redhat.com> 2008-10-29 Jakub Jelinek <jakub@redhat.com>
PR middle-end/37870
* expmed.c (extract_bit_field_1): If int_mode_for_mode returns
BLKmode for non-memory, convert using a wider MODE_INT mode
or through memory.
PR middle-end/37913 PR middle-end/37913
* tree-cfgcleanup.c (split_bbs_on_noreturn_calls): Only split bbs * tree-cfgcleanup.c (split_bbs_on_noreturn_calls): Only split bbs
that haven't been removed yet. that haven't been removed yet.
......
/* Medium-level subroutines: convert bit-field store and extract /* Medium-level subroutines: convert bit-field store and extract
and shifts, multiplies and divides to rtl instructions. and shifts, multiplies and divides to rtl instructions.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc. Free Software Foundation, Inc.
This file is part of GCC. This file is part of GCC.
...@@ -1278,9 +1278,8 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, ...@@ -1278,9 +1278,8 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
{ {
if (MEM_P (op0)) if (MEM_P (op0))
op0 = adjust_address (op0, imode, 0); op0 = adjust_address (op0, imode, 0);
else else if (imode != BLKmode)
{ {
gcc_assert (imode != BLKmode);
op0 = gen_lowpart (imode, op0); op0 = gen_lowpart (imode, op0);
/* If we got a SUBREG, force it into a register since we /* If we got a SUBREG, force it into a register since we
...@@ -1288,6 +1287,24 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, ...@@ -1288,6 +1287,24 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
if (GET_CODE (op0) == SUBREG) if (GET_CODE (op0) == SUBREG)
op0 = force_reg (imode, op0); op0 = force_reg (imode, op0);
} }
else if (REG_P (op0))
{
rtx reg, subreg;
imode = smallest_mode_for_size (GET_MODE_BITSIZE (GET_MODE (op0)),
MODE_INT);
reg = gen_reg_rtx (imode);
subreg = gen_lowpart_SUBREG (GET_MODE (op0), reg);
emit_move_insn (subreg, op0);
op0 = reg;
bitnum += SUBREG_BYTE (subreg) * BITS_PER_UNIT;
}
else
{
rtx mem = assign_stack_temp (GET_MODE (op0),
GET_MODE_SIZE (GET_MODE (op0)), 0);
emit_move_insn (mem, op0);
op0 = adjust_address (mem, BLKmode, 0);
}
} }
} }
......
2008-10-29 Jakub Jelinek <jakub@redhat.com>
PR middle-end/37870
* gcc.target/i386/pr37870.c: New test.
2008-10-29 Manuel López-Ibáñez <manu@gcc.gnu.org> 2008-10-29 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR c++/26997 PR c++/26997
......
/* PR middle-end/37870 */
/* { dg-do run } */
/* { dg-options "-O2" } */
unsigned int
foo (long double x)
{
struct { char a[8]; unsigned int b:7; } c;
__builtin_memcpy (&c, &x, sizeof (c));
return c.b;
}
unsigned int
bar (long double x)
{
union { struct { char a[8]; unsigned int b:7; } c; long double d; } u;
u.d = x;
return u.c.b;
}
int
main (void)
{
if (foo (1.245L) != bar (1.245L)
|| foo (245.67L) != bar (245.67L)
|| foo (0.00567L) != bar (0.00567L))
__builtin_abort ();
return 0;
}
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