[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