From 0becc98698a748a8b28af730ca55986fa02b9811 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 1 Dec 2004 21:24:11 -0800 Subject: [PATCH] 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 --- gcc/ChangeLog | 5 +++++ gcc/expr.c | 12 ++++++++++-- gcc/testsuite/gcc.dg/complex-3.c | 25 +++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/complex-3.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6c7d2a062c3..7e4bd4ded5c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2004-12-01 Richard Henderson + + * expr.c (expand_assignment): Handle CONCAT both as a final + destination and as a middle point. + 2004-12-01 Jeff Law * tree.h (save_eptr, save_filt): Now file scoped statics. diff --git a/gcc/expr.c b/gcc/expr.c index 4616f2190dc..f16f82f10a7 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -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 { diff --git a/gcc/testsuite/gcc.dg/complex-3.c b/gcc/testsuite/gcc.dg/complex-3.c new file mode 100644 index 00000000000..54ec82c0d1a --- /dev/null +++ b/gcc/testsuite/gcc.dg/complex-3.c @@ -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); +}