xref: /freebsd/contrib/llvm-project/clang/lib/CodeGen/Targets/SystemZ.cpp (revision 770cf0a5f02dc8983a89c6568d741fbc25baa999)
1 //===- SystemZ.cpp --------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "ABIInfoImpl.h"
10 #include "TargetInfo.h"
11 #include "clang/Basic/Builtins.h"
12 #include "llvm/IR/IntrinsicsS390.h"
13 
14 using namespace clang;
15 using namespace clang::CodeGen;
16 
17 //===----------------------------------------------------------------------===//
18 // SystemZ ABI Implementation
19 //===----------------------------------------------------------------------===//
20 
21 namespace {
22 
23 class SystemZABIInfo : public ABIInfo {
24   bool HasVector;
25   bool IsSoftFloatABI;
26 
27 public:
28   SystemZABIInfo(CodeGenTypes &CGT, bool HV, bool SF)
29       : ABIInfo(CGT), HasVector(HV), IsSoftFloatABI(SF) {}
30 
31   bool isPromotableIntegerTypeForABI(QualType Ty) const;
32   bool isCompoundType(QualType Ty) const;
33   bool isVectorArgumentType(QualType Ty) const;
34   llvm::Type *getFPArgumentType(QualType Ty, uint64_t Size) const;
35   QualType GetSingleElementType(QualType Ty) const;
36 
37   ABIArgInfo classifyReturnType(QualType RetTy) const;
38   ABIArgInfo classifyArgumentType(QualType ArgTy) const;
39 
40   void computeInfo(CGFunctionInfo &FI) const override;
41   RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
42                    AggValueSlot Slot) const override;
43 };
44 
45 class SystemZTargetCodeGenInfo : public TargetCodeGenInfo {
46   ASTContext &Ctx;
47 
48   // These are used for speeding up the search for a visible vector ABI.
49   mutable bool HasVisibleVecABIFlag = false;
50   mutable std::set<const Type *> SeenTypes;
51 
52   // Returns true (the first time) if Ty is, or is found to include, a vector
53   // type that exposes the vector ABI. This is any vector >=16 bytes which
54   // with vector support are aligned to only 8 bytes. When IsParam is true,
55   // the type belongs to a value as passed between functions. If it is a
56   // vector <=16 bytes it will be passed in a vector register (if supported).
57   bool isVectorTypeBased(const Type *Ty, bool IsParam) const;
58 
59 public:
60   SystemZTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector, bool SoftFloatABI)
61       : TargetCodeGenInfo(
62             std::make_unique<SystemZABIInfo>(CGT, HasVector, SoftFloatABI)),
63             Ctx(CGT.getContext()) {
64     SwiftInfo =
65         std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false);
66   }
67 
68   // The vector ABI is different when the vector facility is present and when
69   // a module e.g. defines an externally visible vector variable, a flag
70   // indicating a visible vector ABI is added. Eventually this will result in
71   // a GNU attribute indicating the vector ABI of the module.  Ty is the type
72   // of a variable or function parameter that is globally visible.
73   void handleExternallyVisibleObjABI(const Type *Ty, CodeGen::CodeGenModule &M,
74                                      bool IsParam) const {
75     if (!HasVisibleVecABIFlag && isVectorTypeBased(Ty, IsParam)) {
76       M.getModule().addModuleFlag(llvm::Module::Warning,
77                                   "s390x-visible-vector-ABI", 1);
78       HasVisibleVecABIFlag = true;
79     }
80   }
81 
82   void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
83                            CodeGen::CodeGenModule &M) const override {
84     if (!D)
85       return;
86 
87     // Check if the vector ABI becomes visible by an externally visible
88     // variable or function.
89     if (const auto *VD = dyn_cast<VarDecl>(D)) {
90       if (VD->isExternallyVisible())
91         handleExternallyVisibleObjABI(VD->getType().getTypePtr(), M,
92                                       /*IsParam*/false);
93     }
94     else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
95       if (FD->isExternallyVisible())
96         handleExternallyVisibleObjABI(FD->getType().getTypePtr(), M,
97                                       /*IsParam*/false);
98     }
99   }
100 
101   llvm::Value *testFPKind(llvm::Value *V, unsigned BuiltinID,
102                           CGBuilderTy &Builder,
103                           CodeGenModule &CGM) const override {
104     assert(V->getType()->isFloatingPointTy() && "V should have an FP type.");
105     // Only use TDC in constrained FP mode.
106     if (!Builder.getIsFPConstrained())
107       return nullptr;
108 
109     llvm::Type *Ty = V->getType();
110     if (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy() ||
111         Ty->isFP128Ty()) {
112       llvm::Module &M = CGM.getModule();
113       auto &Ctx = M.getContext();
114       llvm::Function *TDCFunc = llvm::Intrinsic::getOrInsertDeclaration(
115           &M, llvm::Intrinsic::s390_tdc, Ty);
116       unsigned TDCBits = 0;
117       switch (BuiltinID) {
118       case Builtin::BI__builtin_isnan:
119         TDCBits = 0xf;
120         break;
121       case Builtin::BIfinite:
122       case Builtin::BI__finite:
123       case Builtin::BIfinitef:
124       case Builtin::BI__finitef:
125       case Builtin::BIfinitel:
126       case Builtin::BI__finitel:
127       case Builtin::BI__builtin_isfinite:
128         TDCBits = 0xfc0;
129         break;
130       case Builtin::BI__builtin_isinf:
131         TDCBits = 0x30;
132         break;
133       default:
134         break;
135       }
136       if (TDCBits)
137         return Builder.CreateCall(
138             TDCFunc,
139             {V, llvm::ConstantInt::get(llvm::Type::getInt64Ty(Ctx), TDCBits)});
140     }
141     return nullptr;
142   }
143 };
144 }
145 
146 bool SystemZABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const {
147   // Treat an enum type as its underlying type.
148   if (const EnumType *EnumTy = Ty->getAs<EnumType>())
149     Ty = EnumTy->getDecl()->getIntegerType();
150 
151   // Promotable integer types are required to be promoted by the ABI.
152   if (ABIInfo::isPromotableIntegerTypeForABI(Ty))
153     return true;
154 
155   if (const auto *EIT = Ty->getAs<BitIntType>())
156     if (EIT->getNumBits() < 64)
157       return true;
158 
159   // 32-bit values must also be promoted.
160   if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
161     switch (BT->getKind()) {
162     case BuiltinType::Int:
163     case BuiltinType::UInt:
164       return true;
165     default:
166       return false;
167     }
168   return false;
169 }
170 
171 bool SystemZABIInfo::isCompoundType(QualType Ty) const {
172   return (Ty->isAnyComplexType() ||
173           Ty->isVectorType() ||
174           isAggregateTypeForABI(Ty));
175 }
176 
177 bool SystemZABIInfo::isVectorArgumentType(QualType Ty) const {
178   return (HasVector &&
179           Ty->isVectorType() &&
180           getContext().getTypeSize(Ty) <= 128);
181 }
182 
183 // The Size argument will in case of af an overaligned single element struct
184 // reflect the overalignment value. In such a case the argument will be
185 // passed using the type matching Size.
186 llvm::Type *SystemZABIInfo::getFPArgumentType(QualType Ty,
187                                               uint64_t Size) const {
188   if (IsSoftFloatABI)
189     return nullptr;
190 
191   if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
192     switch (BT->getKind()) {
193     case BuiltinType::Float16:
194       if (Size == 16)
195         return llvm::Type::getHalfTy(getVMContext());
196       LLVM_FALLTHROUGH;
197     case BuiltinType::Float:
198       if (Size == 32)
199         return llvm::Type::getFloatTy(getVMContext());
200       LLVM_FALLTHROUGH;
201     case BuiltinType::Double:
202       return llvm::Type::getDoubleTy(getVMContext());
203     default:
204       return nullptr;
205     }
206 
207   return nullptr;
208 }
209 
210 QualType SystemZABIInfo::GetSingleElementType(QualType Ty) const {
211   const RecordType *RT = Ty->getAs<RecordType>();
212 
213   if (RT && RT->isStructureOrClassType()) {
214     const RecordDecl *RD = RT->getDecl();
215     QualType Found;
216 
217     // If this is a C++ record, check the bases first.
218     if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
219       if (CXXRD->hasDefinition())
220         for (const auto &I : CXXRD->bases()) {
221           QualType Base = I.getType();
222 
223           // Empty bases don't affect things either way.
224           if (isEmptyRecord(getContext(), Base, true))
225             continue;
226 
227           if (!Found.isNull())
228             return Ty;
229           Found = GetSingleElementType(Base);
230         }
231 
232     // Check the fields.
233     for (const auto *FD : RD->fields()) {
234       // Unlike isSingleElementStruct(), empty structure and array fields
235       // do count.  So do anonymous bitfields that aren't zero-sized.
236 
237       // Like isSingleElementStruct(), ignore C++20 empty data members.
238       if (FD->hasAttr<NoUniqueAddressAttr>() &&
239           isEmptyRecord(getContext(), FD->getType(), true))
240         continue;
241 
242       // Unlike isSingleElementStruct(), arrays do not count.
243       // Nested structures still do though.
244       if (!Found.isNull())
245         return Ty;
246       Found = GetSingleElementType(FD->getType());
247     }
248 
249     // Unlike isSingleElementStruct(), trailing padding is allowed.
250     // An 8-byte aligned struct s { float f; } is passed as a double.
251     if (!Found.isNull())
252       return Found;
253   }
254 
255   return Ty;
256 }
257 
258 RValue SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
259                                  QualType Ty, AggValueSlot Slot) const {
260   // Assume that va_list type is correct; should be pointer to LLVM type:
261   // struct {
262   //   i64 __gpr;
263   //   i64 __fpr;
264   //   i8 *__overflow_arg_area;
265   //   i8 *__reg_save_area;
266   // };
267 
268   // Every non-vector argument occupies 8 bytes and is passed by preference
269   // in either GPRs or FPRs.  Vector arguments occupy 8 or 16 bytes and are
270   // always passed on the stack.
271   const SystemZTargetCodeGenInfo &SZCGI =
272       static_cast<const SystemZTargetCodeGenInfo &>(
273           CGT.getCGM().getTargetCodeGenInfo());
274   Ty = getContext().getCanonicalType(Ty);
275   auto TyInfo = getContext().getTypeInfoInChars(Ty);
276   llvm::Type *ArgTy = CGF.ConvertTypeForMem(Ty);
277   llvm::Type *DirectTy = ArgTy;
278   ABIArgInfo AI = classifyArgumentType(Ty);
279   bool IsIndirect = AI.isIndirect();
280   bool InFPRs = false;
281   bool IsVector = false;
282   CharUnits UnpaddedSize;
283   CharUnits DirectAlign;
284   SZCGI.handleExternallyVisibleObjABI(Ty.getTypePtr(), CGT.getCGM(),
285                                       /*IsParam*/true);
286   if (IsIndirect) {
287     DirectTy = llvm::PointerType::getUnqual(DirectTy->getContext());
288     UnpaddedSize = DirectAlign = CharUnits::fromQuantity(8);
289   } else {
290     if (AI.getCoerceToType())
291       ArgTy = AI.getCoerceToType();
292     InFPRs = (!IsSoftFloatABI &&
293               (ArgTy->isHalfTy() || ArgTy->isFloatTy() || ArgTy->isDoubleTy()));
294     IsVector = ArgTy->isVectorTy();
295     UnpaddedSize = TyInfo.Width;
296     DirectAlign = TyInfo.Align;
297   }
298   CharUnits PaddedSize = CharUnits::fromQuantity(8);
299   if (IsVector && UnpaddedSize > PaddedSize)
300     PaddedSize = CharUnits::fromQuantity(16);
301   assert((UnpaddedSize <= PaddedSize) && "Invalid argument size.");
302 
303   CharUnits Padding = (PaddedSize - UnpaddedSize);
304 
305   llvm::Type *IndexTy = CGF.Int64Ty;
306   llvm::Value *PaddedSizeV =
307     llvm::ConstantInt::get(IndexTy, PaddedSize.getQuantity());
308 
309   if (IsVector) {
310     // Work out the address of a vector argument on the stack.
311     // Vector arguments are always passed in the high bits of a
312     // single (8 byte) or double (16 byte) stack slot.
313     Address OverflowArgAreaPtr =
314         CGF.Builder.CreateStructGEP(VAListAddr, 2, "overflow_arg_area_ptr");
315     Address OverflowArgArea =
316         Address(CGF.Builder.CreateLoad(OverflowArgAreaPtr, "overflow_arg_area"),
317                 CGF.Int8Ty, TyInfo.Align);
318     Address MemAddr = OverflowArgArea.withElementType(DirectTy);
319 
320     // Update overflow_arg_area_ptr pointer
321     llvm::Value *NewOverflowArgArea = CGF.Builder.CreateGEP(
322         OverflowArgArea.getElementType(), OverflowArgArea.emitRawPointer(CGF),
323         PaddedSizeV, "overflow_arg_area");
324     CGF.Builder.CreateStore(NewOverflowArgArea, OverflowArgAreaPtr);
325 
326     return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(MemAddr, Ty), Slot);
327   }
328 
329   assert(PaddedSize.getQuantity() == 8);
330 
331   unsigned MaxRegs, RegCountField, RegSaveIndex;
332   CharUnits RegPadding;
333   if (InFPRs) {
334     MaxRegs = 4; // Maximum of 4 FPR arguments
335     RegCountField = 1; // __fpr
336     RegSaveIndex = 16; // save offset for f0
337     RegPadding = CharUnits(); // floats are passed in the high bits of an FPR
338   } else {
339     MaxRegs = 5; // Maximum of 5 GPR arguments
340     RegCountField = 0; // __gpr
341     RegSaveIndex = 2; // save offset for r2
342     RegPadding = Padding; // values are passed in the low bits of a GPR
343   }
344 
345   Address RegCountPtr =
346       CGF.Builder.CreateStructGEP(VAListAddr, RegCountField, "reg_count_ptr");
347   llvm::Value *RegCount = CGF.Builder.CreateLoad(RegCountPtr, "reg_count");
348   llvm::Value *MaxRegsV = llvm::ConstantInt::get(IndexTy, MaxRegs);
349   llvm::Value *InRegs = CGF.Builder.CreateICmpULT(RegCount, MaxRegsV,
350                                                  "fits_in_regs");
351 
352   llvm::BasicBlock *InRegBlock = CGF.createBasicBlock("vaarg.in_reg");
353   llvm::BasicBlock *InMemBlock = CGF.createBasicBlock("vaarg.in_mem");
354   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("vaarg.end");
355   CGF.Builder.CreateCondBr(InRegs, InRegBlock, InMemBlock);
356 
357   // Emit code to load the value if it was passed in registers.
358   CGF.EmitBlock(InRegBlock);
359 
360   // Work out the address of an argument register.
361   llvm::Value *ScaledRegCount =
362     CGF.Builder.CreateMul(RegCount, PaddedSizeV, "scaled_reg_count");
363   llvm::Value *RegBase =
364     llvm::ConstantInt::get(IndexTy, RegSaveIndex * PaddedSize.getQuantity()
365                                       + RegPadding.getQuantity());
366   llvm::Value *RegOffset =
367     CGF.Builder.CreateAdd(ScaledRegCount, RegBase, "reg_offset");
368   Address RegSaveAreaPtr =
369       CGF.Builder.CreateStructGEP(VAListAddr, 3, "reg_save_area_ptr");
370   llvm::Value *RegSaveArea =
371       CGF.Builder.CreateLoad(RegSaveAreaPtr, "reg_save_area");
372   Address RawRegAddr(
373       CGF.Builder.CreateGEP(CGF.Int8Ty, RegSaveArea, RegOffset, "raw_reg_addr"),
374       CGF.Int8Ty, PaddedSize);
375   Address RegAddr = RawRegAddr.withElementType(DirectTy);
376 
377   // Update the register count
378   llvm::Value *One = llvm::ConstantInt::get(IndexTy, 1);
379   llvm::Value *NewRegCount =
380     CGF.Builder.CreateAdd(RegCount, One, "reg_count");
381   CGF.Builder.CreateStore(NewRegCount, RegCountPtr);
382   CGF.EmitBranch(ContBlock);
383 
384   // Emit code to load the value if it was passed in memory.
385   CGF.EmitBlock(InMemBlock);
386 
387   // Work out the address of a stack argument.
388   Address OverflowArgAreaPtr =
389       CGF.Builder.CreateStructGEP(VAListAddr, 2, "overflow_arg_area_ptr");
390   Address OverflowArgArea =
391       Address(CGF.Builder.CreateLoad(OverflowArgAreaPtr, "overflow_arg_area"),
392               CGF.Int8Ty, PaddedSize);
393   Address RawMemAddr =
394       CGF.Builder.CreateConstByteGEP(OverflowArgArea, Padding, "raw_mem_addr");
395   Address MemAddr = RawMemAddr.withElementType(DirectTy);
396 
397   // Update overflow_arg_area_ptr pointer
398   llvm::Value *NewOverflowArgArea = CGF.Builder.CreateGEP(
399       OverflowArgArea.getElementType(), OverflowArgArea.emitRawPointer(CGF),
400       PaddedSizeV, "overflow_arg_area");
401   CGF.Builder.CreateStore(NewOverflowArgArea, OverflowArgAreaPtr);
402   CGF.EmitBranch(ContBlock);
403 
404   // Return the appropriate result.
405   CGF.EmitBlock(ContBlock);
406   Address ResAddr = emitMergePHI(CGF, RegAddr, InRegBlock, MemAddr, InMemBlock,
407                                  "va_arg.addr");
408 
409   if (IsIndirect)
410     ResAddr = Address(CGF.Builder.CreateLoad(ResAddr, "indirect_arg"), ArgTy,
411                       TyInfo.Align);
412 
413   return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(ResAddr, Ty), Slot);
414 }
415 
416 ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const {
417   if (RetTy->isVoidType())
418     return ABIArgInfo::getIgnore();
419   if (isVectorArgumentType(RetTy))
420     return ABIArgInfo::getDirect();
421   if (isCompoundType(RetTy) || getContext().getTypeSize(RetTy) > 64)
422     return getNaturalAlignIndirect(RetTy, getDataLayout().getAllocaAddrSpace());
423   return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
424                                                : ABIArgInfo::getDirect());
425 }
426 
427 ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const {
428   // Handle transparent union types.
429   Ty = useFirstFieldIfTransparentUnion(Ty);
430 
431   // Handle the generic C++ ABI.
432   if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
433     return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
434                                    RAA == CGCXXABI::RAA_DirectInMemory);
435 
436   // Integers and enums are extended to full register width.
437   if (isPromotableIntegerTypeForABI(Ty))
438     return ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty));
439 
440   // Handle vector types and vector-like structure types.  Note that
441   // as opposed to float-like structure types, we do not allow any
442   // padding for vector-like structures, so verify the sizes match.
443   uint64_t Size = getContext().getTypeSize(Ty);
444   QualType SingleElementTy = GetSingleElementType(Ty);
445   if (isVectorArgumentType(SingleElementTy) &&
446       getContext().getTypeSize(SingleElementTy) == Size)
447     return ABIArgInfo::getDirect(CGT.ConvertType(SingleElementTy));
448 
449   // Values that are not 1, 2, 4 or 8 bytes in size are passed indirectly.
450   if (Size != 8 && Size != 16 && Size != 32 && Size != 64)
451     return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
452                                    /*ByVal=*/false);
453 
454   // Handle small structures.
455   if (const RecordType *RT = Ty->getAs<RecordType>()) {
456     // Structures with flexible arrays have variable length, so really
457     // fail the size test above.
458     const RecordDecl *RD = RT->getDecl();
459     if (RD->hasFlexibleArrayMember())
460       return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
461                                      /*ByVal=*/false);
462 
463     // The structure is passed as an unextended integer, a half, a float,
464     // or a double.
465     if (llvm::Type *FPArgTy = getFPArgumentType(SingleElementTy, Size)) {
466       assert(Size == 16 || Size == 32 || Size == 64);
467       return ABIArgInfo::getDirect(FPArgTy);
468     } else {
469       llvm::IntegerType *PassTy = llvm::IntegerType::get(getVMContext(), Size);
470       return Size <= 32 ? ABIArgInfo::getNoExtend(PassTy)
471                         : ABIArgInfo::getDirect(PassTy);
472     }
473   }
474 
475   // Non-structure compounds are passed indirectly.
476   if (isCompoundType(Ty))
477     return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
478                                    /*ByVal=*/false);
479 
480   return ABIArgInfo::getDirect(nullptr);
481 }
482 
483 void SystemZABIInfo::computeInfo(CGFunctionInfo &FI) const {
484   const SystemZTargetCodeGenInfo &SZCGI =
485       static_cast<const SystemZTargetCodeGenInfo &>(
486           CGT.getCGM().getTargetCodeGenInfo());
487   if (!getCXXABI().classifyReturnType(FI))
488     FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
489   unsigned Idx = 0;
490   for (auto &I : FI.arguments()) {
491     I.info = classifyArgumentType(I.type);
492     if (FI.isVariadic() && Idx++ >= FI.getNumRequiredArgs())
493       // Check if a vararg vector argument is passed, in which case the
494       // vector ABI becomes visible as the va_list could be passed on to
495       // other functions.
496       SZCGI.handleExternallyVisibleObjABI(I.type.getTypePtr(), CGT.getCGM(),
497                                           /*IsParam*/true);
498   }
499 }
500 
501 bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty,
502                                                  bool IsParam) const {
503   if (!SeenTypes.insert(Ty).second)
504     return false;
505 
506   if (IsParam) {
507     // A narrow (<16 bytes) vector will as a parameter also expose the ABI as
508     // it will be passed in a vector register. A wide (>16 bytes) vector will
509     // be passed via "hidden" pointer where any extra alignment is not
510     // required (per GCC).
511     const Type *SingleEltTy = getABIInfo<SystemZABIInfo>()
512                                   .GetSingleElementType(QualType(Ty, 0))
513                                   .getTypePtr();
514     bool SingleVecEltStruct = SingleEltTy != Ty && SingleEltTy->isVectorType() &&
515       Ctx.getTypeSize(SingleEltTy) == Ctx.getTypeSize(Ty);
516     if (Ty->isVectorType() || SingleVecEltStruct)
517       return Ctx.getTypeSize(Ty) / 8 <= 16;
518   }
519 
520   // Assume pointers are dereferenced.
521   while (Ty->isPointerType() || Ty->isArrayType())
522     Ty = Ty->getPointeeOrArrayElementType();
523 
524   // Vectors >= 16 bytes expose the ABI through alignment requirements.
525   if (Ty->isVectorType() && Ctx.getTypeSize(Ty) / 8 >= 16)
526       return true;
527 
528   if (const auto *RecordTy = Ty->getAs<RecordType>()) {
529     const RecordDecl *RD = RecordTy->getDecl();
530     if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
531       if (CXXRD->hasDefinition())
532         for (const auto &I : CXXRD->bases())
533           if (isVectorTypeBased(I.getType().getTypePtr(), /*IsParam*/false))
534             return true;
535     for (const auto *FD : RD->fields())
536       if (isVectorTypeBased(FD->getType().getTypePtr(), /*IsParam*/false))
537         return true;
538   }
539 
540   if (const auto *FT = Ty->getAs<FunctionType>())
541     if (isVectorTypeBased(FT->getReturnType().getTypePtr(), /*IsParam*/true))
542       return true;
543   if (const FunctionProtoType *Proto = Ty->getAs<FunctionProtoType>())
544     for (const auto &ParamType : Proto->getParamTypes())
545       if (isVectorTypeBased(ParamType.getTypePtr(), /*IsParam*/true))
546         return true;
547 
548   return false;
549 }
550 
551 std::unique_ptr<TargetCodeGenInfo>
552 CodeGen::createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector,
553                                         bool SoftFloatABI) {
554   return std::make_unique<SystemZTargetCodeGenInfo>(CGM.getTypes(), HasVector,
555                                                     SoftFloatABI);
556 }
557