re PR middle-end/43300 (ICE: in emit_move_insn, at expr.c:3432)

PR middle-end/43300
	* tree-outof-ssa.c (emit_partition_copy): New argument sizeexp,
	use it to expand block copies.
	(insert_partition_copy_on_edge, insert_rtx_to_part_on_edge,
	insert_part_to_rtx_on_edge): Adjust callers of emit_partition_copy.
	(insert_value_copy_on_edge): Use store_expr for BLKmode values.

testsuite/
	* gcc.dg/pr43300.c: New testcase.

From-SVN: r157461
This commit is contained in:
Michael Matz 2010-03-15 16:13:28 +00:00 committed by Michael Matz
parent 610b64e2a2
commit c217233895
4 changed files with 61 additions and 9 deletions

View File

@ -1,3 +1,12 @@
2010-03-15 Michael Matz <matz@suse.de>
PR middle-end/43300
* tree-outof-ssa.c (emit_partition_copy): New argument sizeexp,
use it to expand block copies.
(insert_partition_copy_on_edge, insert_rtx_to_part_on_edge,
insert_part_to_rtx_on_edge): Adjust callers of emit_partition_copy.
(insert_value_copy_on_edge): Use store_expr for BLKmode values.
2010-03-15 Richard Guenther <rguenther@suse.de>
PR tree-optimization/43367

View File

@ -1,3 +1,8 @@
2010-03-15 Michael Matz <matz@suse.de>
PR middle-end/43300
* gcc.dg/pr43300.c: New testcase.
2010-03-15 Richard Guenther <rguenther@suse.de>
PR tree-optimization/43367

View File

@ -0,0 +1,17 @@
/* { dg-do compile } */
/* { dg-options "-Os" } */
typedef float V2SF __attribute__ ((vector_size (128)));
V2SF
foo (int x, V2SF a)
{
V2SF b;
if (x & 42)
b = a;
else
b = a + (V2SF) {1.0f/0.0f - 1.0f/0.0f, 1.0f/0.0f - 1.0f/0.0f};
while (x--)
a += b;
return a;
}

View File

@ -140,10 +140,12 @@ set_location_for_edge (edge e)
}
}
/* Emit insns to copy SRC into DEST converting SRC if necessary. */
/* Emit insns to copy SRC into DEST converting SRC if necessary. As
SRC/DEST might be BLKmode memory locations SIZEEXP is a tree from
which we deduce the size to copy in that case. */
static inline rtx
emit_partition_copy (rtx dest, rtx src, int unsignedsrcp)
emit_partition_copy (rtx dest, rtx src, int unsignedsrcp, tree sizeexp)
{
rtx seq;
@ -151,7 +153,13 @@ emit_partition_copy (rtx dest, rtx src, int unsignedsrcp)
if (GET_MODE (src) != VOIDmode && GET_MODE (src) != GET_MODE (dest))
src = convert_to_mode (GET_MODE (dest), src, unsignedsrcp);
emit_move_insn (dest, src);
if (GET_MODE (src) == BLKmode)
{
gcc_assert (GET_MODE (dest) == BLKmode);
emit_block_move (dest, src, expr_size (sizeexp), BLOCK_OP_NORMAL);
}
else
emit_move_insn (dest, src);
seq = get_insns ();
end_sequence ();
@ -164,6 +172,7 @@ emit_partition_copy (rtx dest, rtx src, int unsignedsrcp)
static void
insert_partition_copy_on_edge (edge e, int dest, int src, source_location locus)
{
tree var;
rtx seq;
if (dump_file && (dump_flags & TDF_DETAILS))
{
@ -183,10 +192,11 @@ insert_partition_copy_on_edge (edge e, int dest, int src, source_location locus)
if (locus)
set_curr_insn_source_location (locus);
var = partition_to_var (SA.map, src);
seq = emit_partition_copy (SA.partition_to_pseudo[dest],
SA.partition_to_pseudo[src],
TYPE_UNSIGNED (TREE_TYPE (
partition_to_var (SA.map, src))));
TYPE_UNSIGNED (TREE_TYPE (var)),
var);
insert_insn_on_edge (seq, e);
}
@ -232,6 +242,11 @@ insert_value_copy_on_edge (edge e, int dest, tree src, source_location locus)
x = expand_expr (src, NULL, src_mode, EXPAND_NORMAL);
x = convert_modes (dest_mode, src_mode, x, unsignedp);
}
else if (src_mode == BLKmode)
{
x = SA.partition_to_pseudo[dest];
store_expr (src, x, 0, false);
}
else
x = expand_expr (src, SA.partition_to_pseudo[dest],
dest_mode, EXPAND_NORMAL);
@ -269,9 +284,13 @@ insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp,
if (locus)
set_curr_insn_source_location (locus);
/* We give the destination as sizeexp in case src/dest are BLKmode
mems. Usually we give the source. As we result from SSA names
the left and right size should be the same (and no WITH_SIZE_EXPR
involved), so it doesn't matter. */
seq = emit_partition_copy (SA.partition_to_pseudo[dest],
src,
unsignedsrcp);
src, unsignedsrcp,
partition_to_var (SA.map, dest));
insert_insn_on_edge (seq, e);
}
@ -282,6 +301,7 @@ insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp,
static void
insert_part_to_rtx_on_edge (edge e, rtx dest, int src, source_location locus)
{
tree var;
rtx seq;
if (dump_file && (dump_flags & TDF_DETAILS))
{
@ -300,10 +320,11 @@ insert_part_to_rtx_on_edge (edge e, rtx dest, int src, source_location locus)
if (locus)
set_curr_insn_source_location (locus);
var = partition_to_var (SA.map, src);
seq = emit_partition_copy (dest,
SA.partition_to_pseudo[src],
TYPE_UNSIGNED (TREE_TYPE (
partition_to_var (SA.map, src))));
TYPE_UNSIGNED (TREE_TYPE (var)),
var);
insert_insn_on_edge (seq, e);
}