[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