+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.
/* 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
{
--- /dev/null
+/* 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);
+}