This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/14323] New: stored_field (expr.c) should deal with PARALLELs in target
- From: "ehrhardt at mathematik dot uni-ulm dot de" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 27 Feb 2004 16:38:32 -0000
- Subject: [Bug c/14323] New: stored_field (expr.c) should deal with PARALLELs in target
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
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