[llvm-commits] [llvm-gcc-4.2] r50069 - /llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp
Devang Patel
dpatel at apple.com
Mon Apr 21 16:03:32 PDT 2008
Author: dpatel
Date: Mon Apr 21 18:03:31 2008
New Revision: 50069
URL: http://llvm.org/viewvc/llvm-project?rev=50069&view=rev
Log:
Use { <4 x float>, <4 x float> } to return struct { float[4]; }.
Modified:
llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp
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=50069&r1=50068&r2=50069&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 Mon Apr 21 18:03:31 2008
@@ -1047,9 +1047,9 @@
ElementTypes.push_back(ATy->getElementType());
break;
case 4:
- // use { <4 x float> } for struct { float[4]; }
- ElementTypes.push_back(VectorType::get(ATy->getElementType(), 2));
- ElementTypes.push_back(VectorType::get(ATy->getElementType(), 2));
+ // use { <4 x float>, <4 x float> } for struct { float[4]; }
+ ElementTypes.push_back(VectorType::get(ATy->getElementType(), 4));
+ ElementTypes.push_back(VectorType::get(ATy->getElementType(), 4));
break;
default:
assert (0 && "Unexpected floating point array size!");
@@ -1062,36 +1062,6 @@
return StructType::get(ElementTypes, STy->isPacked());
}
-// llvm_x86_build_mrv_array_element - This is a helper function used by
-// llvm_x6_build_multiple_return_value.
-static Value *llvm_x86_build_mrv_array_element(const Type *STyFieldTy,
- Value *RetVal,
- unsigned FieldNo,
- IRBuilder &Builder,
- unsigned ArrayElemNo = 0) {
- llvm::Value *Idxs[3];
- Idxs[0] = ConstantInt::get(llvm::Type::Int32Ty, 0);
- Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, FieldNo);
- if (const VectorType *VTy = dyn_cast<VectorType>(STyFieldTy)) {
- // Source field is a vector. Use insertelement.
- Value *R1 = UndefValue::get(STyFieldTy);
- unsigned ArraySize = VTy->getNumElements();
- for (unsigned i = ArrayElemNo; i < ArraySize; ++i) {
- Idxs[2] = ConstantInt::get(llvm::Type::Int32Ty, i);
- Value *GEP = Builder.CreateGEP(RetVal, Idxs, Idxs+3, "mrv_gep");
- Value *ElemVal = Builder.CreateLoad(GEP, "mrv");
- R1 = Builder.CreateInsertElement(R1, ElemVal,
- ConstantInt::get(llvm::Type::Int32Ty, i),
- "mrv");
- }
- return R1;
- } else {
- Idxs[2] = ConstantInt::get(llvm::Type::Int32Ty, ArrayElemNo);
- Value *GEP = Builder.CreateGEP(RetVal, Idxs, Idxs+3, "mrv_gep");
- return Builder.CreateLoad(GEP, "mrv");
- }
-}
-
// llvm_x86_build_multiple_return_value - Function FN returns multiple value
// where RETVAL points to the aggregate being returned. Build a RETVALS vector
// of individual values from RETVAL aggregate. RETVALS will be used by
@@ -1136,23 +1106,42 @@
}
const ArrayType *ATy = cast<ArrayType>(ElemType);
unsigned ArraySize = ATy->getNumElements();
+ // AElemNo keeps track of array elements. This may not match index (VElemNo)
+ // that tracks vector elements when Src field type is VectorType..
unsigned AElemNo = 0;
while (AElemNo < ArraySize) {
const Type *SElemTy = STy->getElementType(SNO);
if (const VectorType *SVElemTy = dyn_cast<VectorType>(SElemTy)) {
- // Build array elements from a vector.
- unsigned VSize = SVElemTy->getNumElements();
- assert (ArraySize - AElemNo >= VSize
- && "Invalid multiple return value type!");
- Value *R = llvm_x86_build_mrv_array_element(SVElemTy, RetVal, RNO,
- Builder, AElemNo);
+ llvm::Value *Idxs[3];
+ Idxs[0] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+ Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, RNO);
+ Value *R = Constant::getNullValue(SElemTy);
+ unsigned VElemNo = 0;
+ unsigned Size = AElemNo + SVElemTy->getNumElements();
+
+ // Only first two elements from <4 x float> are used, for example float[4] is
+ // transformed into two <4 x float> vectors.
+ if (SVElemTy->getElementType()->getTypeID() == Type::FloatTyID
+ && Size == 4)
+ Size = AElemNo + 2;
+ while (AElemNo < Size) {
+ Idxs[2] = ConstantInt::get(llvm::Type::Int32Ty, AElemNo);
+ Value *GEP = Builder.CreateGEP(RetVal, Idxs, Idxs+3, "mrv.av.gep");
+ Value *ElemVal = Builder.CreateLoad(GEP, "mrv");
+ R = Builder.CreateInsertElement(R, ElemVal,
+ ConstantInt::get(llvm::Type::Int32Ty, VElemNo++),
+ "mrv.av.");
+ AElemNo++;
+ }
RetVals.push_back(R);
- AElemNo += VSize;
} else {
- Value *R = llvm_x86_build_mrv_array_element(SElemTy, RetVal, RNO,
- Builder, AElemNo);
+ llvm::Value *Idxs[3];
+ Idxs[0] = ConstantInt::get(llvm::Type::Int32Ty, 0);
+ Idxs[1] = ConstantInt::get(llvm::Type::Int32Ty, RNO);
+ Idxs[2] = ConstantInt::get(llvm::Type::Int32Ty, AElemNo++);
+ Value *GEP = Builder.CreateGEP(RetVal, Idxs, Idxs+3, "mrv.a.gep");
+ Value *R = Builder.CreateLoad(GEP, "mrv.a");
RetVals.push_back(R);
- ++AElemNo;
}
// Next Src field.
++SNO;
@@ -1245,17 +1234,21 @@
unsigned ArraySize = ATy->getNumElements();
unsigned DElemNo = 0; // DestTy's DNO field's element number
while (DElemNo < ArraySize) {
- const VectorType *SElemTy = dyn_cast<VectorType>(STy->getElementType(SNO));
- if (!SElemTy) {
- llvm_x86_extract_mrv_array_element(Src, Dest, SNO, 0, DNO, DElemNo,
+ unsigned i = 0;
+ unsigned Size = 1;
+
+ if (const VectorType *SElemTy =
+ dyn_cast<VectorType>(STy->getElementType(SNO))) {
+ Size = SElemTy->getNumElements();
+ if (SElemTy->getElementType()->getTypeID() == Type::FloatTyID
+ && Size == 4)
+ // Ignore last two <4 x float> elements.
+ Size = 2;
+ }
+ while (i < Size) {
+ llvm_x86_extract_mrv_array_element(Src, Dest, SNO, i++,
+ DNO, DElemNo++,
Builder, isVolatile);
- ++DElemNo;
- } else {
- for (unsigned i = 0; i < SElemTy->getNumElements(); ++i) {
- llvm_x86_extract_mrv_array_element(Src, Dest, SNO, i, DNO, DElemNo,
- Builder, isVolatile);
- ++DElemNo;
- }
}
// Consumed this src field. Try next one.
++SNO;
More information about the llvm-commits
mailing list