[PATCH] D64672: [X86] Prevent passing vectors of __int128 as <X x i128> in llvm IR

Craig Topper via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 12 15:10:17 PDT 2019


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;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D64672.209596.patch
Type: text/x-patch
Size: 1736 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190712/18daf1dc/attachment.bin>


More information about the cfe-commits mailing list