[PATCH] Fix PR optimization/6177

Jakub Jelinek jakub@redhat.com
Thu Apr 11 06:58:00 GMT 2002


Hi!

As noted by Janis, this got broken
by http://gcc.gnu.org/ml/gcc-patches/2002-04/msg00041.html
patch, because arrays can now have modes they couldn't before.
Particularly in this case expand_expr [ARRAY_REF] (well, after fallthrough
to COMPONENT_REF) did not expand op0 to have anything but REG, SUBREG or
MEM code. Neither the REG/SUBREG/... case nor MEM case can be used for
concat, since the former calls extract_bit_field (which doesn't work
on CONCAT), the latter calls adjust_address*, which is MEM only.
As CONCAT never made it to this part of expand_expr before and
this changed because of the one element array mode change, I think it is
enough to handle CONCAT with bitsize == GET_MODE_BITSIZE (GET_MODE (op0))
and bitpos == 0 (ie. actually accessing the element of a
single element array).
Ok to commit (provided testing succeeds)?

2002-04-11  Jakub Jelinek  <jakub@redhat.com>

	PR optimization/6177
	* expr.c (expand_expr) [COMPONENT_REF]: Handle op0 CONCAT if
	bitpos is 0 and bitsize CONCAT size.

	* gcc.c-torture/execute/20020411-1.c: New test.

--- gcc/testsuite/gcc.c-torture/execute/20020411-1.c.jj	Thu Apr 11 15:46:40 2002
+++ gcc/testsuite/gcc.c-torture/execute/20020411-1.c	Thu Apr 11 15:51:04 2002
@@ -0,0 +1,25 @@
+/* PR optimization/6177
+   This testcase ICEd because expr.c did not expect to see a CONCAT
+   as array rtl.  */
+
+extern void abort (void);
+extern void exit (int);
+
+__complex__ float foo (void)
+{
+  __complex__ float f[1];
+  __real__ f[0] = 1.0;
+  __imag__ f[0] = 1.0;
+  f[0] = __builtin_conjf (f[0]);
+  return f[0];
+}
+
+int main (void)
+{
+  __complex__ double d[1];
+  d[0] = foo ();
+  if (__real__ d[0] != 1.0
+      || __imag__ d[0] != -1.0)
+    abort ();
+  exit (0);
+}
--- gcc/expr.c.jj	Thu Apr 11 14:34:55 2002
+++ gcc/expr.c	Thu Apr 11 15:39:46 2002
@@ -6956,6 +6956,16 @@ expand_expr (exp, target, tmode, modifie
 	    MEM_VOLATILE_P (op0) = 1;
 	  }
 
+	/* The following code doesn't handle CONCAT.
+	   Assume only bitpos == 0 can be used for CONCAT, due to
+	   one element arrays having the same mode as its element.  */
+	if (GET_CODE (op0) == CONCAT)
+	  {
+	    if (bitpos != 0 || bitsize != GET_MODE_BITSIZE (GET_MODE (op0)))
+	      abort ();
+	    return op0;
+	  }
+
 	/* In cases where an aligned union has an unaligned object
 	   as a field, we might be extracting a BLKmode value from
 	   an integer-mode (e.g., SImode) object.  Handle this case

	Jakub



More information about the Gcc-patches mailing list