craig.topper created this revision.
craig.topper added reviewers: eli.friedman, RKSimon, spatel, rnk.

As far as I can tell, gcc passes 256/512 bit vectors __int128 in memory. And 
passes a vector of 1 _int128 in an xmm register. The backend considers <X x 
i128> as an illegal type and will scalarize any arguments with that type. So we 
need to coerce the argument types in the frontend to match to avoid the illegal 
type.

Are there other element types to consider? Do we need to keep the old behavior 
on platforms where clang is the de facto compiler?

This issue was identified in PR42607. Though even with the types changed, we 
still seem to be doing some unnecessary stack realignment.

I'll add test cases later today or over the weekend.


https://reviews.llvm.org/D64672

Files:
  clang/lib/CodeGen/TargetInfo.cpp


Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -2657,6 +2657,14 @@
         Hi = Lo;
     } else if (Size == 128 ||
                (isNamedArg && Size <= getNativeVectorSizeForAVXABI(AVXLevel))) 
{
+      QualType ElementType = VT->getElementType();
+
+      // gcc passes 256 and 512 bit <X x int128> vectors in memory. :(
+      if (Size != 128 &&
+          (ElementType->isSpecificBuiltinType(BuiltinType::Int128) ||
+           ElementType->isSpecificBuiltinType(BuiltinType::UInt128)))
+        return;
+
       // Arguments of 256-bits are split into four eightbyte chunks. The
       // least significant one belongs to class SSE and all the others to class
       // SSEUP. The original Lo and Hi design considers that types can't be
@@ -2899,6 +2907,10 @@
     unsigned LargestVector = getNativeVectorSizeForAVXABI(AVXLevel);
     if (Size <= 64 || Size > LargestVector)
       return true;
+    QualType EltTy = VecTy->getElementType();
+    if (EltTy->isSpecificBuiltinType(BuiltinType::Int128) ||
+        EltTy->isSpecificBuiltinType(BuiltinType::UInt128))
+      return true;
   }
 
   return false;
@@ -2972,8 +2984,11 @@
   if (const Type *InnerTy = isSingleElementStruct(Ty, getContext()))
     Ty = QualType(InnerTy, 0);
 
+  // Don't pass vXi128 vectors in their native type, the backend can't
+  // legalize them.
   llvm::Type *IRType = CGT.ConvertType(Ty);
-  if (isa<llvm::VectorType>(IRType) ||
+  if ((isa<llvm::VectorType>(IRType) &&
+       !IRType->getVectorElementType()->isIntegerTy(128)) ||
       IRType->getTypeID() == llvm::Type::FP128TyID)
     return IRType;
 


Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -2657,6 +2657,14 @@
         Hi = Lo;
     } else if (Size == 128 ||
                (isNamedArg && Size <= getNativeVectorSizeForAVXABI(AVXLevel))) {
+      QualType ElementType = VT->getElementType();
+
+      // gcc passes 256 and 512 bit <X x int128> vectors in memory. :(
+      if (Size != 128 &&
+          (ElementType->isSpecificBuiltinType(BuiltinType::Int128) ||
+           ElementType->isSpecificBuiltinType(BuiltinType::UInt128)))
+        return;
+
       // Arguments of 256-bits are split into four eightbyte chunks. The
       // least significant one belongs to class SSE and all the others to class
       // SSEUP. The original Lo and Hi design considers that types can't be
@@ -2899,6 +2907,10 @@
     unsigned LargestVector = getNativeVectorSizeForAVXABI(AVXLevel);
     if (Size <= 64 || Size > LargestVector)
       return true;
+    QualType EltTy = VecTy->getElementType();
+    if (EltTy->isSpecificBuiltinType(BuiltinType::Int128) ||
+        EltTy->isSpecificBuiltinType(BuiltinType::UInt128))
+      return true;
   }
 
   return false;
@@ -2972,8 +2984,11 @@
   if (const Type *InnerTy = isSingleElementStruct(Ty, getContext()))
     Ty = QualType(InnerTy, 0);
 
+  // Don't pass vXi128 vectors in their native type, the backend can't
+  // legalize them.
   llvm::Type *IRType = CGT.ConvertType(Ty);
-  if (isa<llvm::VectorType>(IRType) ||
+  if ((isa<llvm::VectorType>(IRType) &&
+       !IRType->getVectorElementType()->isIntegerTy(128)) ||
       IRType->getTypeID() == llvm::Type::FP128TyID)
     return IRType;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D64672: [X86] Preven... Craig Topper via Phabricator via cfe-commits

Reply via email to