[llvm-commits] [llvm-gcc-4.2] r93445 - in /llvm-gcc-4.2/trunk/gcc/config/i386: i386.c llvm-i386.cpp

Stuart Hastings stuart at apple.com
Thu Jan 14 11:52:28 PST 2010


Author: stuart
Date: Thu Jan 14 13:52:28 2010
New Revision: 93445

URL: http://llvm.org/viewvc/llvm-project?rev=93445&view=rev
Log:
This is a fix for the x86-64 ABI code.  When a struct is passed across
a call, it will be broken into component machine types and passed in
suitable registers.  The callee is expected to use the values in
place.  However, if the callee is a variable-argument function, it
will re-assemble the original structure in a local temporary.  This
code controls the registers and widths used during reassembly.

The broken test case (in the GCC DejaGNU test suite) concerns a struct
wrapping an array of three floats will be passed in two SSE registers.
When storing into the temporary mentioned above, both compilers emit a
128-bit store, clobbering 32 adjacent bits.  This patch arranges for a
96-bit store.  (Both compilers are wrong, but GCC is luckier than
llvm-gcc.  :-)

Modified:
    llvm-gcc-4.2/trunk/gcc/config/i386/i386.c
    llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp

Modified: llvm-gcc-4.2/trunk/gcc/config/i386/i386.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/i386.c?rev=93445&r1=93444&r2=93445&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/i386/i386.c (original)
+++ llvm-gcc-4.2/trunk/gcc/config/i386/i386.c Thu Jan 14 13:52:28 2010
@@ -3458,17 +3458,24 @@
 	    if (!num)
 	      return 0;
 
-	    /* The partial classes are now full classes.  */
-	    if (subclasses[0] == X86_64_SSESF_CLASS && bytes != 4)
-	      subclasses[0] = X86_64_SSE_CLASS;
-	    if (subclasses[0] == X86_64_INTEGERSI_CLASS && bytes != 4)
-	      subclasses[0] = X86_64_INTEGER_CLASS;
-
+	    /* LLVM LOCAL begin 7387470 */
 	    for (i = 0; i < words; i++)
 	      classes[i] = subclasses[i % num];
 
-	    break;
+	    /* If 32-bit class, consider upgrade to 64-bit.  */
+	    if (bytes > 4 &&
+		(subclasses[0] == X86_64_SSESF_CLASS ||
+		 subclasses[0] == X86_64_INTEGERSI_CLASS)) {
+		enum x86_64_reg_class upgrade64 =
+		  (subclasses[0] == X86_64_SSESF_CLASS) ?
+		  X86_64_SSE_CLASS : X86_64_INTEGER_CLASS;
+		classes[0] = upgrade64;
+		if (bytes > 12)
+		  classes[1] = upgrade64;
+	    }
 	  }
+	  break;
+	  /* LLVM LOCAL end 7387470 */
 	case UNION_TYPE:
 	case QUAL_UNION_TYPE:
 	  /* Unions are similar to RECORD_TYPE but offset is always 0.

Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp?rev=93445&r1=93444&r2=93445&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp Thu Jan 14 13:52:28 2010
@@ -839,10 +839,6 @@
   if (!NumClasses)
     return false;
 
-  if (NumClasses == 1 && Class[0] == X86_64_INTEGERSI_CLASS)
-    // This will fit in one i32 register.
-    return false;
-
   for (int i = 0; i < NumClasses; ++i) {
     switch (Class[i]) {
     case X86_64_INTEGER_CLASS:





More information about the llvm-commits mailing list