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]

fix g++.dg/eh/simd-2.C and compat/vector-1 crash


Problem here was trying to use sse registers when they aren't available.  

That brings up a secondary problem in that the Intel-sponsored ABI means
that we have problems with gcc's generic vector extension.  There are
exactly two alternatives:  (1) the abi differs with and without -msse,
or (2) true i386 can't use gcc's generic vector extension.  I'll discard
here, for the moment, considerations such as magic type names or other
random hackery switches that frob the abi.

What I've done is add a warning when using sse vector types without sse
turned on, iff its actually used as a return value.  I.e. only if it 
would matter to the program under consideration.  I suppose we could add
a switch to say "yeah, i know, don't warn", but I don't think it's worth
it; at present we really have no one using our generic vector extension,
and I don't actually think that it would be a win to use it on x86
without actual vector hardware.  Registers are too scarse for such 4-wide
unpacking.

The vector-1 test still fails, but now due to the warning instead of a
compiler crash.  There doesn't appear to be dg-options support in that
directory.


r~



        * config/i386.i386.c (ix86_return_in_memory): Reformat.  Return true
        for 16-byte vector modes if sse not enabled; warn for abi change.
        (ix86_value_regno): Only return xmm0 for 16-byte vector types.
        * g++.dg/eh/simd-2.C: Add -w for x86.

Index: gcc/config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.596
diff -u -p -u -r1.596 i386.c
--- gcc/config/i386/i386.c	23 Aug 2003 21:18:57 -0000	1.596
+++ gcc/config/i386/i386.c	25 Aug 2003 01:58:58 -0000
@@ -2691,29 +2691,59 @@ ix86_function_value (tree valtype)
 int
 ix86_return_in_memory (tree type)
 {
-  int needed_intregs, needed_sseregs;
+  int needed_intregs, needed_sseregs, size;
+  enum machine_mode mode = TYPE_MODE (type);
+
   if (TARGET_64BIT)
+    return !examine_argument (mode, type, 1, &needed_intregs, &needed_sseregs);
+
+  if (mode == BLKmode)
+    return 1;
+
+  size = int_size_in_bytes (type);
+
+  if (MS_AGGREGATE_RETURN && AGGREGATE_TYPE_P (type) && size <= 8)
+    return 0;
+
+  if (VECTOR_MODE_P (mode) || mode == TImode)
     {
-      return !examine_argument (TYPE_MODE (type), type, 1,
-				&needed_intregs, &needed_sseregs);
-    }
-  else
-    {
-      if (TYPE_MODE (type) == BLKmode)
-	return 1;
-      else if (MS_AGGREGATE_RETURN
-	       && AGGREGATE_TYPE_P (type)
-	       && int_size_in_bytes(type) <= 8)
+      /* User-created vectors small enough to fit in EAX.  */
+      if (size < 8)
 	return 0;
-      else if ((VECTOR_MODE_P (TYPE_MODE (type))
-	        && int_size_in_bytes (type) == 8)
-	       || (int_size_in_bytes (type) > 12
-		   && TYPE_MODE (type) != TImode
-		   && TYPE_MODE (type) != TFmode
-		   && !VECTOR_MODE_P (TYPE_MODE (type))))
+
+      /* MMX/3dNow values are returned on the stack, since we've
+	 got to EMMS/FEMMS before returning.  */
+      if (size == 8)
 	return 1;
-      return 0;
+
+      /* SSE values are returned in XMM0.  */
+      /* ??? Except when it doesn't exist?  We have a choice of
+	 either (1) being abi incompatible with a -march switch,
+	 or (2) generating an error here.  Given no good solution,
+	 I think the safest thing is one warning.  The user won't
+	 be able to use -Werror, but...  */
+      if (size == 16)
+	{
+	  static bool warned;
+
+	  if (TARGET_SSE)
+	    return 0;
+
+	  if (!warned)
+	    {
+	      warned = true;
+	      warning ("SSE vector return without SSE enabled "
+		       "changes the ABI");
+	    }
+	  return 1;
+	}
     }
+
+  if (mode == TFmode)
+    return 0;
+  if (size > 12)
+    return 1;
+  return 0;
 }
 
 /* Define how to find the value returned by a library function
@@ -2746,10 +2776,14 @@ ix86_libcall_value (enum machine_mode mo
 static int
 ix86_value_regno (enum machine_mode mode)
 {
+  /* Floating point return values in %st(0).  */
   if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_FLOAT_RETURNS_IN_80387)
     return FIRST_FLOAT_REG;
-  if (mode == TImode || VECTOR_MODE_P (mode))
+  /* 16-byte vector modes in %xmm0.  See ix86_return_in_memory for where
+     we prevent this case when sse is not available.  */
+  if (mode == TImode || (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 16))
     return FIRST_SSE_REG;
+  /* Everything else in %eax.  */
   return 0;
 }
 
Index: gcc/testsuite/g++.dg/eh/simd-2.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/eh/simd-2.C,v
retrieving revision 1.2
diff -u -p -u -r1.2 simd-2.C
--- gcc/testsuite/g++.dg/eh/simd-2.C	2 Apr 2003 16:56:33 -0000	1.2
+++ gcc/testsuite/g++.dg/eh/simd-2.C	25 Aug 2003 01:58:58 -0000
@@ -1,6 +1,7 @@
 // Test EH when V4SI SIMD registers are involved.
 // Contributed by Aldy Hernandez (aldy@quesejoda.com).
 // { dg-options "-O" }
+// { dg-options "-O -w" { target i?86-*-* } }
 // { dg-do run }
 
 typedef int __attribute__((mode(V4SI))) vecint;


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