expr.c (expand_assignment): Handle CONCAT both as a final destination and as a middle point.

* expr.c (expand_assignment): Handle CONCAT both as a final
        destination and as a middle point.

From-SVN: r91614
This commit is contained in:
Richard Henderson 2004-12-01 21:24:11 -08:00 committed by Richard Henderson
parent ca3a791a16
commit 0becc98698
3 changed files with 40 additions and 2 deletions

View File

@ -1,3 +1,8 @@
2004-12-01 Richard Henderson <rth@redhat.com>
* expr.c (expand_assignment): Handle CONCAT both as a final
destination and as a middle point.
2004-12-01 Jeff Law <law@redhat.com>
* tree.h (save_eptr, save_filt): Now file scoped statics.

View File

@ -3757,8 +3757,16 @@ expand_assignment (tree to, tree from)
/* Handle expand_expr of a complex value returning a CONCAT. */
if (GET_CODE (to_rtx) == CONCAT)
{
gcc_assert (bitpos == 0 || bitpos == GET_MODE_BITSIZE (mode1));
result = store_expr (from, XEXP (to_rtx, bitpos != 0), false);
if (TREE_CODE (TREE_TYPE (from)) == COMPLEX_TYPE)
{
gcc_assert (bitpos == 0);
result = store_expr (from, to_rtx, false);
}
else
{
gcc_assert (bitpos == 0 || bitpos == GET_MODE_BITSIZE (mode1));
result = store_expr (from, XEXP (to_rtx, bitpos != 0), false);
}
}
else
{

View File

@ -0,0 +1,25 @@
/* Verify that rtl expansion cleanup doesn't get too aggressive about
code dealing with complex CONCATs. */
/* { dg-do run } */
/* { dg-options "-O -fno-tree-sra" } */
extern void abort (void);
extern void exit (int);
__complex__ float foo (void)
{
__complex__ float f[1];
__real__ f[0] = 1;
__imag__ f[0] = 1;
f[0] = __builtin_conjf (f[0]);
return f[0];
}
int main (void)
{
__complex__ double d[1];
d[0] = foo ();
if (__real__ d[0] != 1 || __imag__ d[0] != -1)
abort ();
exit (0);
}