[cfe-commits] r66277 - in /cfe/trunk: lib/CodeGen/CGCall.cpp test/CodeGen/x86_64-arguments.c
Daniel Dunbar
daniel at zuster.org
Fri Mar 6 09:50:25 PST 2009
Author: ddunbar
Date: Fri Mar 6 11:50:25 2009
New Revision: 66277
URL: http://llvm.org/viewvc/llvm-project?rev=66277&view=rev
Log:
x86_64 ABI: Handle long double in union when upper eightbyte results
in a lone X87 class.
- PR3735.
Modified:
cfe/trunk/lib/CodeGen/CGCall.cpp
cfe/trunk/test/CodeGen/x86_64-arguments.c
Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=66277&r1=66276&r2=66277&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Fri Mar 6 11:50:25 2009
@@ -473,8 +473,10 @@
// MEMORY is used as class.
//
// (f) Otherwise class SSE is used.
- assert((Accum == NoClass || Accum == Integer ||
- Accum == SSE || Accum == SSEUp) &&
+
+ // Accum should never be memory (we should have returned) or
+ // ComplexX87 (because this cannot be passed in a structure).
+ assert((Accum != Memory && Accum != ComplexX87) &&
"Invalid accumulated classification during merge.");
if (Accum == Field || Field == NoClass)
return Accum;
@@ -807,11 +809,13 @@
// AMD64-ABI 3.2.3p4: Rule 7. If the class is X87UP, the value is
// returned together with the previous X87 value in %st0.
- //
- // X87UP should always be preceeded by X87, so we don't need to do
- // anything here.
case X87Up:
- assert(Lo == X87 && "Unexpected X87Up classification.");
+ // If X87Up is preceeded by X87, we don't need to do
+ // anything. However, in some cases with unions it may not be
+ // preceeded by X87. In such situations we follow gcc and pass the
+ // extra bits in an SSE reg.
+ if (Lo != X87)
+ ResType = llvm::StructType::get(ResType, llvm::Type::DoubleTy, NULL);
break;
}
@@ -874,16 +878,20 @@
// which is passed in memory.
case Memory:
case X87:
- case X87Up:
case ComplexX87:
assert(0 && "Invalid classification for hi word.");
+ break;
case NoClass: break;
case Integer:
ResType = llvm::StructType::get(ResType, llvm::Type::Int64Ty, NULL);
++neededInt;
break;
- case SSE:
+
+ // X87Up generally doesn't occur here (long double is passed in
+ // memory), except in situations involving unions.
+ case X87Up:
+ case SSE:
ResType = llvm::StructType::get(ResType, llvm::Type::DoubleTy, NULL);
++neededSSE;
break;
Modified: cfe/trunk/test/CodeGen/x86_64-arguments.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/x86_64-arguments.c?rev=66277&r1=66276&r2=66277&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/x86_64-arguments.c (original)
+++ cfe/trunk/test/CodeGen/x86_64-arguments.c Fri Mar 6 11:50:25 2009
@@ -6,7 +6,10 @@
// RUN: grep 'define double @f4()' %t &&
// RUN: grep 'define x86_fp80 @f5()' %t &&
// RUN: grep 'define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8\* %a4)' %t &&
-// RUN: grep 'define void @f7(i32 %a0)' %t
+// RUN: grep 'define void @f7(i32 %a0)' %t &&
+// RUN: grep 'type { i64, double }.*type .0' %t &&
+// RUN: grep 'define .0 @f8_1()' %t &&
+// RUN: grep 'define void @f8_2(.0)' %t
char f0(void) {
}
@@ -33,3 +36,11 @@
void f7(E a0) {
}
+
+// Test merging/passing of upper eightbyte with X87 class.
+union u8 {
+ long double a;
+ int b;
+};
+union u8 f8_1() {}
+void f8_2(union u8 a0) {}
More information about the cfe-commits
mailing list