This is the mail archive of the gcc-bugs@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]

[Bug c/14323] New: stored_field (expr.c) should deal with PARALLELs in target


The following simple piece of code ICEs with a bus error in stored_field
on sparc-sun-solaris with -m64 -O2 (note you'll probably have to compile
with --enable-checking):

struct X { long long int p; long long int q;};
struct X f() {
	struct X ret;
	return ret;
}

The reason is that store_field doesn't deal with PARALLELs as
targets. Note that ssa rewrites this function like this:

f ()
{
  long long int ret$q;
  long long int ret$p;
  struct X ret;

<bb 0>:
  ret.p = ret$p;
  ret.q = ret$q;
  return ret;

}

The assignment ret.p = ret$p passes the parrallel of the whole
structure on to store_field and specifies offset 0.

I'm currently working around this with the following patch but
that is probably not perfect.


Index: expr.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/expr.c,v
retrieving revision 1.467.2.79
diff -u -r1.467.2.79 expr.c
--- expr.c	19 Feb 2004 09:05:24 -0000	1.467.2.79
+++ expr.c	27 Feb 2004 16:36:43 -0000
@@ -5299,6 +5299,28 @@
   else if (bitsize >= 0 && bitsize < HOST_BITS_PER_WIDE_INT)
     width_mask = ((HOST_WIDE_INT) 1 << bitsize) - 1;
 
+  /* If we are storing into a PARALLEL find the proper register part to
+     store in. FIXME: If exp crosses register boundaries we'll fail.  */
+  if (GET_CODE (target) == PARALLEL)
+    {
+      int len = XVECLEN (target, 0);
+      int i, pos = 0;
+      rtx reg;
+      for (i=0; i < len; ++i)
+        {
+	  if (XWINT (XEXP (XVECEXP(target, 0, i), 1), 0) * BITS_PER_UNIT > bitpos)
+	    break;
+	  reg = XEXP (XVECEXP (target, 0, i), 0);
+	  pos = XWINT (XEXP (XVECEXP (target, 0, i), 1), 0) * BITS_PER_UNIT;
+	}
+      target = reg;
+      bitpos -= pos;
+      if (GET_CODE (target) != REG)
+        abort ();
+      if (GET_MODE_SIZE (GET_MODE (target)) * BITS_PER_UNIT < bitpos + bitsize)
+        abort ();
+    }
+
   /* If we are storing into an unaligned field of an aligned union that is
      in a register, we may have the mode of TARGET being an integer mode but
      MODE == BLKmode.  In that case, get an aligned object whose size and


   regards   Christian

-- 
           Summary: stored_field (expr.c) should deal with PARALLELs in
                    target
           Product: gcc
           Version: tree-ssa
            Status: UNCONFIRMED
          Severity: critical
          Priority: P2
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: ehrhardt at mathematik dot uni-ulm dot de
                CC: gcc-bugs at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14323


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