diff mbox

[SPARC] Fix PR target/61535

Message ID 2105605.uXooVOTrUd@polaris
State New
Headers show

Commit Message

Eric Botcazou Nov. 11, 2014, 10:07 p.m. UTC
This is the RTL checking failure triggered by gcc.dg/vect/vect-singleton_1.c 
on SPARC 64-bit: the back-end gets confused passing 1-element float vectors.
As documented in the code, we pass all FP vectors like aggregate types.

Tested on SPARC64/Solaris, applied on the mainline.


2014-11-11  Eric Botcazou  <ebotcazou@adacore.com>

	PR target/61535
	* config/sparc/sparc.c (function_arg_vector_value): Deal with vectors
	smaller than 8 bytes.
	(sparc_function_arg_1): Tweak.
	(sparc_function_value_1): Tweak.
diff mbox

Patch

Index: config/sparc/sparc.c
===================================================================
--- config/sparc/sparc.c	(revision 217259)
+++ config/sparc/sparc.c	(working copy)
@@ -6819,28 +6819,30 @@  function_arg_union_value (int size, mach
 }
 
 /* Used by function_arg and sparc_function_value_1 to implement the conventions
-   for passing and returning large (BLKmode) vectors.
+   for passing and returning BLKmode vectors.
    Return an expression valid as a return value for the FUNCTION_ARG
    and TARGET_FUNCTION_VALUE.
 
-   SIZE is the size in bytes of the vector (at least 8 bytes).
+   SIZE is the size in bytes of the vector.
    REGNO is the FP hard register the vector will be passed in.  */
 
 static rtx
 function_arg_vector_value (int size, int regno)
 {
-  int i, nregs = size / 8;
-  rtx regs;
+  const int nregs = MAX (1, size / 8);
+  rtx regs = gen_rtx_PARALLEL (BLKmode, rtvec_alloc (nregs));
 
-  regs = gen_rtx_PARALLEL (BLKmode, rtvec_alloc (nregs));
-
-  for (i = 0; i < nregs; i++)
-    {
+  if (size < 8)
+    XVECEXP (regs, 0, 0)
+      = gen_rtx_EXPR_LIST (VOIDmode,
+			   gen_rtx_REG (SImode, regno),
+			   const0_rtx);
+  else
+    for (int i = 0; i < nregs; i++)
       XVECEXP (regs, 0, i)
 	= gen_rtx_EXPR_LIST (VOIDmode,
 			     gen_rtx_REG (DImode, regno + 2*i),
 			     GEN_INT (i*8));
-    }
 
   return regs;
 }
@@ -6886,10 +6888,9 @@  sparc_function_arg_1 (cumulative_args_t
 		  || (TARGET_ARCH64 && size <= 16));
 
       if (mode == BLKmode)
-	return function_arg_vector_value (size,
-					  SPARC_FP_ARG_FIRST + 2*slotno);
-      else
-	mclass = MODE_FLOAT;
+	return function_arg_vector_value (size, SPARC_FP_ARG_FIRST + 2*slotno);
+
+      mclass = MODE_FLOAT;
     }
 
   if (TARGET_ARCH32)
@@ -7333,10 +7334,9 @@  sparc_function_value_1 (const_tree type,
 		  || (TARGET_ARCH64 && size <= 32));
 
       if (mode == BLKmode)
-	return function_arg_vector_value (size,
-					  SPARC_FP_ARG_FIRST);
-      else
-	mclass = MODE_FLOAT;
+	return function_arg_vector_value (size, SPARC_FP_ARG_FIRST);
+
+      mclass = MODE_FLOAT;
     }
 
   if (TARGET_ARCH64 && type)