[cfe-commits] r144960 - in /cfe/trunk: lib/CodeGen/TargetInfo.cpp test/CodeGen/x86_32-arguments-darwin.c test/CodeGenCXX/x86_32-arguments.cpp
Eli Friedman
eli.friedman at gmail.com
Thu Nov 17 17:25:51 PST 2011
Author: efriedma
Date: Thu Nov 17 19:25:50 2011
New Revision: 144960
URL: http://llvm.org/viewvc/llvm-project?rev=144960&view=rev
Log:
Simplify code for returning a struct for Darwin x86-32 ABI. Use a better type for a function returning a struct containing only a pointer. Handle the edge case of a struct containing only a float or double plus some dead padding instead of asserting.
Modified:
cfe/trunk/lib/CodeGen/TargetInfo.cpp
cfe/trunk/test/CodeGen/x86_32-arguments-darwin.c
cfe/trunk/test/CodeGenCXX/x86_32-arguments.cpp
Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=144960&r1=144959&r2=144960&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Thu Nov 17 19:25:50 2011
@@ -252,6 +252,11 @@
}
}
+ // We don't consider a struct a single-element struct if it has
+ // padding beyond the element type.
+ if (Found && Context.getTypeSize(Found) != Context.getTypeSize(T))
+ return 0;
+
return Found;
}
@@ -561,51 +566,21 @@
if (!IsSmallStructInRegABI && !RetTy->isAnyComplexType())
return ABIArgInfo::getIndirect(0);
- // Classify "single element" structs as their element type.
- if (const Type *SeltTy = isSingleElementStruct(RetTy, getContext())) {
- if (const BuiltinType *BT = SeltTy->getAs<BuiltinType>()) {
- if (BT->isIntegerType()) {
- // We need to use the size of the structure, padding
- // bit-fields can adjust that to be larger than the single
- // element type.
- uint64_t Size = getContext().getTypeSize(RetTy);
- return ABIArgInfo::getDirect(
- llvm::IntegerType::get(getVMContext(), (unsigned)Size));
- }
-
- if (BT->getKind() == BuiltinType::Float) {
- assert(getContext().getTypeSize(RetTy) ==
- getContext().getTypeSize(SeltTy) &&
- "Unexpect single element structure size!");
- return ABIArgInfo::getDirect(llvm::Type::getFloatTy(getVMContext()));
- }
-
- if (BT->getKind() == BuiltinType::Double) {
- assert(getContext().getTypeSize(RetTy) ==
- getContext().getTypeSize(SeltTy) &&
- "Unexpect single element structure size!");
- return ABIArgInfo::getDirect(llvm::Type::getDoubleTy(getVMContext()));
- }
- } else if (SeltTy->isPointerType()) {
- // FIXME: It would be really nice if this could come out as the proper
- // pointer type.
- llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(getVMContext());
- return ABIArgInfo::getDirect(PtrTy);
- } else if (SeltTy->isVectorType()) {
- // 64- and 128-bit vectors are never returned in a
- // register when inside a structure.
- uint64_t Size = getContext().getTypeSize(RetTy);
- if (Size == 64 || Size == 128)
- return ABIArgInfo::getIndirect(0);
-
- return classifyReturnType(QualType(SeltTy, 0));
- }
- }
-
// Small structures which are register sized are generally returned
// in a register.
if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, getContext())) {
uint64_t Size = getContext().getTypeSize(RetTy);
+
+ // As a special-case, if the struct is a "single-element" struct, and
+ // the field is of type "float" or "double", return it in a
+ // floating-point register. We apply a similar transformation for
+ // pointer types to improve the quality of the generated IR.
+ if (const Type *SeltTy = isSingleElementStruct(RetTy, getContext()))
+ if (SeltTy->isRealFloatingType() || SeltTy->hasPointerRepresentation())
+ return ABIArgInfo::getDirect(CGT.ConvertType(QualType(SeltTy, 0)));
+
+ // FIXME: We should be able to narrow this integer in cases with dead
+ // padding.
return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),Size));
}
Modified: cfe/trunk/test/CodeGen/x86_32-arguments-darwin.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/x86_32-arguments-darwin.c?rev=144960&r1=144959&r2=144960&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/x86_32-arguments-darwin.c (original)
+++ cfe/trunk/test/CodeGen/x86_32-arguments-darwin.c Thu Nov 17 19:25:50 2011
@@ -173,7 +173,7 @@
// CHECK: define i64 @f43()
struct s43 { enum e40 f0; int f1; } f43(void) { }
-// CHECK: define i32 @f44()
+// CHECK: define void ()* @f44()
struct s44 { vvbp f0; } f44(void) { }
// CHECK: define i64 @f45()
@@ -281,6 +281,10 @@
struct s57 { _Complex int x; };
void f57(struct s57 x) {} void f57a(void) { f57((struct s57){1}); }
+// CHECK: define void @f58()
union u58 {};
void f58(union u58 x) {}
-// CHECK: define void @f58()
+
+// CHECK: define i64 @f59()
+struct s59 { float x __attribute((aligned(8))); };
+struct s59 f59() { while (1) {} }
Modified: cfe/trunk/test/CodeGenCXX/x86_32-arguments.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/x86_32-arguments.cpp?rev=144960&r1=144959&r2=144960&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/x86_32-arguments.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/x86_32-arguments.cpp Thu Nov 17 19:25:50 2011
@@ -84,7 +84,7 @@
struct s4_2 : s4_0, s4_1 { };
s4_2 f4() { return s4_2(); }
-// CHECK: define i32 @_Z2f5v()
+// CHECK: define i32* @_Z2f5v()
struct s5 { s5(); int &x; };
s5 f5() { return s5(); }
More information about the cfe-commits
mailing list