[llvm-commits] [llvm-gcc-4.2] r50107 - in /llvm-gcc-4.2/trunk/gcc: config/i386/llvm-i386.cpp testsuite/gcc.target/x86_64/abi/test_struct_returning.c
Devang Patel
dpatel at apple.com
Tue Apr 22 14:03:42 PDT 2008
Author: dpatel
Date: Tue Apr 22 16:03:42 2008
New Revision: 50107
URL: http://llvm.org/viewvc/llvm-project?rev=50107&view=rev
Log:
Return { float, float, float } as ret <4 x float>, float
Modified:
llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp
llvm-gcc-4.2/trunk/gcc/testsuite/gcc.target/x86_64/abi/test_struct_returning.c
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=50107&r1=50106&r2=50107&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 Tue Apr 22 16:03:42 2008
@@ -922,6 +922,7 @@
// of type TY should be returned using multiple value return instruction.
static bool llvm_suitable_multiple_ret_value_type(const Type *Ty,
tree TreeType) {
+
if (!TARGET_64BIT)
return false;
@@ -1013,7 +1014,16 @@
ElementTypes.push_back(Type::X86_FP80Ty);
return StructType::get(ElementTypes, STy->isPacked());
}
-
+
+ if (NumElements == 3
+ && STy->getElementType(0)->getTypeID() == Type::FloatTyID
+ && STy->getElementType(1)->getTypeID() == Type::FloatTyID
+ && STy->getElementType(2)->getTypeID() == Type::FloatTyID) {
+ ElementTypes.push_back(VectorType::get(Type::FloatTy, 4));
+ ElementTypes.push_back(Type::FloatTy);
+ return StructType::get(ElementTypes, STy->isPacked());
+ }
+
for (unsigned i = 0; i < NumElements; ++i) {
const Type *T = STy->getElementType(i);
@@ -1031,12 +1041,12 @@
if (ATy->getElementType()->isFloatingPoint()) {
switch (size) {
case 2:
- // use { <2 x float> } for struct { float[2]; }
- ElementTypes.push_back(VectorType::get(ATy->getElementType(), 2));
+ // use { <4 x float> } for struct { float[2]; }
+ ElementTypes.push_back(VectorType::get(ATy->getElementType(), 4));
break;
case 3:
- // use { <2 x float>, float } for struct { float[3]; }
- ElementTypes.push_back(VectorType::get(ATy->getElementType(), 2));
+ // use { <4 x float>, float } for struct { float[3]; }
+ ElementTypes.push_back(VectorType::get(ATy->getElementType(), 4));
ElementTypes.push_back(ATy->getElementType());
break;
case 4:
@@ -1072,6 +1082,30 @@
unsigned NumElements = RetSTy->getNumElements();
unsigned RNO = 0;
unsigned SNO = 0;
+
+ if (NumElements == 3
+ && RetSTy->getElementType(0)->getTypeID() == Type::FloatTyID
+ && RetSTy->getElementType(1)->getTypeID() == Type::FloatTyID
+ && RetSTy->getElementType(2)->getTypeID() == Type::FloatTyID) {
+ Value *GEP0 = Builder.CreateStructGEP(RetVal, 0, "mrv_idx");
+ Value *ElemVal0 = Builder.CreateLoad(GEP0, "mrv");
+ Value *GEP1 = Builder.CreateStructGEP(RetVal, 1, "mrv_idx");
+ Value *ElemVal1 = Builder.CreateLoad(GEP1, "mrv");
+ Value *GEP2 = Builder.CreateStructGEP(RetVal, 2, "mrv_idx");
+ Value *ElemVal2 = Builder.CreateLoad(GEP2, "mrv");
+
+ Value *R = Constant::getNullValue(STy->getElementType(0));
+ R = Builder.CreateInsertElement(R, ElemVal0,
+ ConstantInt::get(llvm::Type::Int32Ty, 0),
+ "mrv.f.");
+ R = Builder.CreateInsertElement(R, ElemVal1,
+ ConstantInt::get(llvm::Type::Int32Ty, 1),
+ "mrv.f.");
+ RetVals.push_back(R);
+ RetVals.push_back(ElemVal2);
+ return;
+ }
+
while (RNO < NumElements) {
const Type *ElemType = RetSTy->getElementType(RNO);
if (ElemType->isFirstClassType()) {
@@ -1081,7 +1115,8 @@
++RNO;
++SNO;
continue;
- }
+ }
+
// Special treatement for _Complex.
if (const StructType *ComplexType = dyn_cast<StructType>(ElemType)) {
llvm::Value *Idxs[3];
@@ -1188,6 +1223,32 @@
const StructType *DestTy = cast<StructType>(PTy->getElementType());
unsigned SNO = 0;
unsigned DNO = 0;
+
+ if (DestTy->getNumElements() == 3
+ && DestTy->getElementType(0)->getTypeID() == Type::FloatTyID
+ && DestTy->getElementType(1)->getTypeID() == Type::FloatTyID
+ && DestTy->getElementType(2)->getTypeID() == Type::FloatTyID) {
+ // DestTy is { float, float, float }
+ // STy is { <4 x float>, float > }
+
+ GetResultInst *GR = Builder.CreateGetResult(Src, 0, "mrv_gr");
+
+ Value *E0Index = ConstantInt::get(Type::Int32Ty, 0);
+ Value *GR0 = Builder.CreateExtractElement(GR, E0Index, "mrv.v");
+ Value *GEP0 = Builder.CreateStructGEP(Dest, 0, "mrv_gep");
+ Builder.CreateStore(GR0, GEP0, isVolatile);
+
+ Value *E1Index = ConstantInt::get(Type::Int32Ty, 1);
+ Value *GR1 = Builder.CreateExtractElement(GR, E1Index, "mrv.v");
+ Value *GEP1 = Builder.CreateStructGEP(Dest, 1, "mrv_gep");
+ Builder.CreateStore(GR1, GEP1, isVolatile);
+
+ Value *GEP2 = Builder.CreateStructGEP(Dest, 2, "mrv_gep");
+ GetResultInst *GR2 = Builder.CreateGetResult(Src, 1, "mrv_gr");
+ Builder.CreateStore(GR2, GEP2, isVolatile);
+ return;
+ }
+
while (SNO < NumElements) {
const Type *DestElemType = DestTy->getElementType(DNO);
Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.target/x86_64/abi/test_struct_returning.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.target/x86_64/abi/test_struct_returning.c?rev=50107&r1=50106&r2=50107&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.target/x86_64/abi/test_struct_returning.c (original)
+++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.target/x86_64/abi/test_struct_returning.c Tue Apr 22 16:03:42 2008
@@ -28,7 +28,10 @@
MEM,
INT_SSE,
SSE_INT,
- SSE_F_V
+ /* LLVM LOCAL begin */
+ SSE_F_V,
+ SSE_F_V3
+ /* LLVM LOCAL end */
} Type;
/* Structures which should be returned in INTEGER. */
@@ -165,6 +168,10 @@
#define D(I,MEMBERS,C,B) struct S_ ## I { MEMBERS ; }; Type class_ ## I = C; \
struct S_ ## I f_ ## I (void) { struct S_ ## I s; B; return s; }
D(600,float f[4], SSE_F_V, s.f[0] = s.f[1] = s.f[2] = s.f[3] = 42)
+/* LLVM LOCAL begin */
+D(601,float f[3], SSE_F_V3, s.f[0] = s.f[1] = s.f[2] = 42)
+D(602,float f0;float f1; float f2, SSE_F_V3, s.f0 = s.f1 = s.f2 = 42)
+/* LLVM LOCAL end */
#undef D
void clear_all (void)
@@ -181,6 +188,8 @@
case SSE_F: assert (xmm0f[0] == 42); break;
case SSE_D: assert (xmm0d[0] == 42); break;
case SSE_F_V: assert (xmm0f[0] == 42 && xmm0f[1]==42 && xmm1f[0] == 42 && xmm1f[1] == 42); break;
+ /* LLVM LOCAL */
+ case SSE_F_V3: assert (xmm0f[0] == 42 && xmm0f[1]==42 && xmm1f[0] == 42); break;
case X87: assert (x87_regs[0]._ldouble == 42); break;
case INT_SSE: check_300(); break;
case SSE_INT: check_400(); break;
@@ -222,7 +231,9 @@
D(530)
D(600)
- if (num_failed)
+ /* LLVM LOCAL */
+ D(601) D(602)
+ if (num_failed)
abort ();
return 0;
More information about the llvm-commits
mailing list