This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: fix rtl-opt/15289, part 4


Yet another quirk found by backporting to 3.4.  The ICE in mainline is
superficially hidden by the SRA pass, so I've added a test case that
explicitly turns it off.


r~


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

Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.751
diff -u -p -r1.751 expr.c
--- expr.c	1 Dec 2004 20:33:50 -0000	1.751
+++ expr.c	2 Dec 2004 05:21:21 -0000
@@ -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
 	{
Index: testsuite/gcc.dg/complex-3.c
===================================================================
RCS file: testsuite/gcc.dg/complex-3.c
diff -N testsuite/gcc.dg/complex-3.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/complex-3.c	2 Dec 2004 05:21:36 -0000
@@ -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);
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]