xref: /freebsd/contrib/llvm-project/clang/lib/CodeGen/Targets/SystemZ.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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:
SystemZABIInfo(CodeGenTypes & CGT,bool HV,bool SF)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   bool isFPArgumentType(QualType Ty) 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:
SystemZTargetCodeGenInfo(CodeGenTypes & CGT,bool HasVector,bool SoftFloatABI)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.
handleExternallyVisibleObjABI(const Type * Ty,CodeGen::CodeGenModule & M,bool IsParam) const73   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 
setTargetAttributes(const Decl * D,llvm::GlobalValue * GV,CodeGen::CodeGenModule & M) const82   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 
testFPKind(llvm::Value * V,unsigned BuiltinID,CGBuilderTy & Builder,CodeGenModule & CGM) const101   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->isFloatTy() || Ty->isDoubleTy() || Ty->isFP128Ty()) {
111       llvm::Module &M = CGM.getModule();
112       auto &Ctx = M.getContext();
113       llvm::Function *TDCFunc =
114           llvm::Intrinsic::getDeclaration(&M, llvm::Intrinsic::s390_tdc, Ty);
115       unsigned TDCBits = 0;
116       switch (BuiltinID) {
117       case Builtin::BI__builtin_isnan:
118         TDCBits = 0xf;
119         break;
120       case Builtin::BIfinite:
121       case Builtin::BI__finite:
122       case Builtin::BIfinitef:
123       case Builtin::BI__finitef:
124       case Builtin::BIfinitel:
125       case Builtin::BI__finitel:
126       case Builtin::BI__builtin_isfinite:
127         TDCBits = 0xfc0;
128         break;
129       case Builtin::BI__builtin_isinf:
130         TDCBits = 0x30;
131         break;
132       default:
133         break;
134       }
135       if (TDCBits)
136         return Builder.CreateCall(
137             TDCFunc,
138             {V, llvm::ConstantInt::get(llvm::Type::getInt64Ty(Ctx), TDCBits)});
139     }
140     return nullptr;
141   }
142 };
143 }
144 
isPromotableIntegerTypeForABI(QualType Ty) const145 bool SystemZABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const {
146   // Treat an enum type as its underlying type.
147   if (const EnumType *EnumTy = Ty->getAs<EnumType>())
148     Ty = EnumTy->getDecl()->getIntegerType();
149 
150   // Promotable integer types are required to be promoted by the ABI.
151   if (ABIInfo::isPromotableIntegerTypeForABI(Ty))
152     return true;
153 
154   if (const auto *EIT = Ty->getAs<BitIntType>())
155     if (EIT->getNumBits() < 64)
156       return true;
157 
158   // 32-bit values must also be promoted.
159   if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
160     switch (BT->getKind()) {
161     case BuiltinType::Int:
162     case BuiltinType::UInt:
163       return true;
164     default:
165       return false;
166     }
167   return false;
168 }
169 
isCompoundType(QualType Ty) const170 bool SystemZABIInfo::isCompoundType(QualType Ty) const {
171   return (Ty->isAnyComplexType() ||
172           Ty->isVectorType() ||
173           isAggregateTypeForABI(Ty));
174 }
175 
isVectorArgumentType(QualType Ty) const176 bool SystemZABIInfo::isVectorArgumentType(QualType Ty) const {
177   return (HasVector &&
178           Ty->isVectorType() &&
179           getContext().getTypeSize(Ty) <= 128);
180 }
181 
isFPArgumentType(QualType Ty) const182 bool SystemZABIInfo::isFPArgumentType(QualType Ty) const {
183   if (IsSoftFloatABI)
184     return false;
185 
186   if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
187     switch (BT->getKind()) {
188     case BuiltinType::Float:
189     case BuiltinType::Double:
190       return true;
191     default:
192       return false;
193     }
194 
195   return false;
196 }
197 
GetSingleElementType(QualType Ty) const198 QualType SystemZABIInfo::GetSingleElementType(QualType Ty) const {
199   const RecordType *RT = Ty->getAs<RecordType>();
200 
201   if (RT && RT->isStructureOrClassType()) {
202     const RecordDecl *RD = RT->getDecl();
203     QualType Found;
204 
205     // If this is a C++ record, check the bases first.
206     if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
207       if (CXXRD->hasDefinition())
208         for (const auto &I : CXXRD->bases()) {
209           QualType Base = I.getType();
210 
211           // Empty bases don't affect things either way.
212           if (isEmptyRecord(getContext(), Base, true))
213             continue;
214 
215           if (!Found.isNull())
216             return Ty;
217           Found = GetSingleElementType(Base);
218         }
219 
220     // Check the fields.
221     for (const auto *FD : RD->fields()) {
222       // Unlike isSingleElementStruct(), empty structure and array fields
223       // do count.  So do anonymous bitfields that aren't zero-sized.
224 
225       // Like isSingleElementStruct(), ignore C++20 empty data members.
226       if (FD->hasAttr<NoUniqueAddressAttr>() &&
227           isEmptyRecord(getContext(), FD->getType(), true))
228         continue;
229 
230       // Unlike isSingleElementStruct(), arrays do not count.
231       // Nested structures still do though.
232       if (!Found.isNull())
233         return Ty;
234       Found = GetSingleElementType(FD->getType());
235     }
236 
237     // Unlike isSingleElementStruct(), trailing padding is allowed.
238     // An 8-byte aligned struct s { float f; } is passed as a double.
239     if (!Found.isNull())
240       return Found;
241   }
242 
243   return Ty;
244 }
245 
EmitVAArg(CodeGenFunction & CGF,Address VAListAddr,QualType Ty,AggValueSlot Slot) const246 RValue SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
247                                  QualType Ty, AggValueSlot Slot) const {
248   // Assume that va_list type is correct; should be pointer to LLVM type:
249   // struct {
250   //   i64 __gpr;
251   //   i64 __fpr;
252   //   i8 *__overflow_arg_area;
253   //   i8 *__reg_save_area;
254   // };
255 
256   // Every non-vector argument occupies 8 bytes and is passed by preference
257   // in either GPRs or FPRs.  Vector arguments occupy 8 or 16 bytes and are
258   // always passed on the stack.
259   const SystemZTargetCodeGenInfo &SZCGI =
260       static_cast<const SystemZTargetCodeGenInfo &>(
261           CGT.getCGM().getTargetCodeGenInfo());
262   Ty = getContext().getCanonicalType(Ty);
263   auto TyInfo = getContext().getTypeInfoInChars(Ty);
264   llvm::Type *ArgTy = CGF.ConvertTypeForMem(Ty);
265   llvm::Type *DirectTy = ArgTy;
266   ABIArgInfo AI = classifyArgumentType(Ty);
267   bool IsIndirect = AI.isIndirect();
268   bool InFPRs = false;
269   bool IsVector = false;
270   CharUnits UnpaddedSize;
271   CharUnits DirectAlign;
272   SZCGI.handleExternallyVisibleObjABI(Ty.getTypePtr(), CGT.getCGM(),
273                                       /*IsParam*/true);
274   if (IsIndirect) {
275     DirectTy = llvm::PointerType::getUnqual(DirectTy);
276     UnpaddedSize = DirectAlign = CharUnits::fromQuantity(8);
277   } else {
278     if (AI.getCoerceToType())
279       ArgTy = AI.getCoerceToType();
280     InFPRs = (!IsSoftFloatABI && (ArgTy->isFloatTy() || ArgTy->isDoubleTy()));
281     IsVector = ArgTy->isVectorTy();
282     UnpaddedSize = TyInfo.Width;
283     DirectAlign = TyInfo.Align;
284   }
285   CharUnits PaddedSize = CharUnits::fromQuantity(8);
286   if (IsVector && UnpaddedSize > PaddedSize)
287     PaddedSize = CharUnits::fromQuantity(16);
288   assert((UnpaddedSize <= PaddedSize) && "Invalid argument size.");
289 
290   CharUnits Padding = (PaddedSize - UnpaddedSize);
291 
292   llvm::Type *IndexTy = CGF.Int64Ty;
293   llvm::Value *PaddedSizeV =
294     llvm::ConstantInt::get(IndexTy, PaddedSize.getQuantity());
295 
296   if (IsVector) {
297     // Work out the address of a vector argument on the stack.
298     // Vector arguments are always passed in the high bits of a
299     // single (8 byte) or double (16 byte) stack slot.
300     Address OverflowArgAreaPtr =
301         CGF.Builder.CreateStructGEP(VAListAddr, 2, "overflow_arg_area_ptr");
302     Address OverflowArgArea =
303         Address(CGF.Builder.CreateLoad(OverflowArgAreaPtr, "overflow_arg_area"),
304                 CGF.Int8Ty, TyInfo.Align);
305     Address MemAddr = OverflowArgArea.withElementType(DirectTy);
306 
307     // Update overflow_arg_area_ptr pointer
308     llvm::Value *NewOverflowArgArea = CGF.Builder.CreateGEP(
309         OverflowArgArea.getElementType(), OverflowArgArea.emitRawPointer(CGF),
310         PaddedSizeV, "overflow_arg_area");
311     CGF.Builder.CreateStore(NewOverflowArgArea, OverflowArgAreaPtr);
312 
313     return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(MemAddr, Ty), Slot);
314   }
315 
316   assert(PaddedSize.getQuantity() == 8);
317 
318   unsigned MaxRegs, RegCountField, RegSaveIndex;
319   CharUnits RegPadding;
320   if (InFPRs) {
321     MaxRegs = 4; // Maximum of 4 FPR arguments
322     RegCountField = 1; // __fpr
323     RegSaveIndex = 16; // save offset for f0
324     RegPadding = CharUnits(); // floats are passed in the high bits of an FPR
325   } else {
326     MaxRegs = 5; // Maximum of 5 GPR arguments
327     RegCountField = 0; // __gpr
328     RegSaveIndex = 2; // save offset for r2
329     RegPadding = Padding; // values are passed in the low bits of a GPR
330   }
331 
332   Address RegCountPtr =
333       CGF.Builder.CreateStructGEP(VAListAddr, RegCountField, "reg_count_ptr");
334   llvm::Value *RegCount = CGF.Builder.CreateLoad(RegCountPtr, "reg_count");
335   llvm::Value *MaxRegsV = llvm::ConstantInt::get(IndexTy, MaxRegs);
336   llvm::Value *InRegs = CGF.Builder.CreateICmpULT(RegCount, MaxRegsV,
337                                                  "fits_in_regs");
338 
339   llvm::BasicBlock *InRegBlock = CGF.createBasicBlock("vaarg.in_reg");
340   llvm::BasicBlock *InMemBlock = CGF.createBasicBlock("vaarg.in_mem");
341   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("vaarg.end");
342   CGF.Builder.CreateCondBr(InRegs, InRegBlock, InMemBlock);
343 
344   // Emit code to load the value if it was passed in registers.
345   CGF.EmitBlock(InRegBlock);
346 
347   // Work out the address of an argument register.
348   llvm::Value *ScaledRegCount =
349     CGF.Builder.CreateMul(RegCount, PaddedSizeV, "scaled_reg_count");
350   llvm::Value *RegBase =
351     llvm::ConstantInt::get(IndexTy, RegSaveIndex * PaddedSize.getQuantity()
352                                       + RegPadding.getQuantity());
353   llvm::Value *RegOffset =
354     CGF.Builder.CreateAdd(ScaledRegCount, RegBase, "reg_offset");
355   Address RegSaveAreaPtr =
356       CGF.Builder.CreateStructGEP(VAListAddr, 3, "reg_save_area_ptr");
357   llvm::Value *RegSaveArea =
358       CGF.Builder.CreateLoad(RegSaveAreaPtr, "reg_save_area");
359   Address RawRegAddr(
360       CGF.Builder.CreateGEP(CGF.Int8Ty, RegSaveArea, RegOffset, "raw_reg_addr"),
361       CGF.Int8Ty, PaddedSize);
362   Address RegAddr = RawRegAddr.withElementType(DirectTy);
363 
364   // Update the register count
365   llvm::Value *One = llvm::ConstantInt::get(IndexTy, 1);
366   llvm::Value *NewRegCount =
367     CGF.Builder.CreateAdd(RegCount, One, "reg_count");
368   CGF.Builder.CreateStore(NewRegCount, RegCountPtr);
369   CGF.EmitBranch(ContBlock);
370 
371   // Emit code to load the value if it was passed in memory.
372   CGF.EmitBlock(InMemBlock);
373 
374   // Work out the address of a stack argument.
375   Address OverflowArgAreaPtr =
376       CGF.Builder.CreateStructGEP(VAListAddr, 2, "overflow_arg_area_ptr");
377   Address OverflowArgArea =
378       Address(CGF.Builder.CreateLoad(OverflowArgAreaPtr, "overflow_arg_area"),
379               CGF.Int8Ty, PaddedSize);
380   Address RawMemAddr =
381       CGF.Builder.CreateConstByteGEP(OverflowArgArea, Padding, "raw_mem_addr");
382   Address MemAddr = RawMemAddr.withElementType(DirectTy);
383 
384   // Update overflow_arg_area_ptr pointer
385   llvm::Value *NewOverflowArgArea = CGF.Builder.CreateGEP(
386       OverflowArgArea.getElementType(), OverflowArgArea.emitRawPointer(CGF),
387       PaddedSizeV, "overflow_arg_area");
388   CGF.Builder.CreateStore(NewOverflowArgArea, OverflowArgAreaPtr);
389   CGF.EmitBranch(ContBlock);
390 
391   // Return the appropriate result.
392   CGF.EmitBlock(ContBlock);
393   Address ResAddr = emitMergePHI(CGF, RegAddr, InRegBlock, MemAddr, InMemBlock,
394                                  "va_arg.addr");
395 
396   if (IsIndirect)
397     ResAddr = Address(CGF.Builder.CreateLoad(ResAddr, "indirect_arg"), ArgTy,
398                       TyInfo.Align);
399 
400   return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(ResAddr, Ty), Slot);
401 }
402 
classifyReturnType(QualType RetTy) const403 ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const {
404   if (RetTy->isVoidType())
405     return ABIArgInfo::getIgnore();
406   if (isVectorArgumentType(RetTy))
407     return ABIArgInfo::getDirect();
408   if (isCompoundType(RetTy) || getContext().getTypeSize(RetTy) > 64)
409     return getNaturalAlignIndirect(RetTy);
410   return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
411                                                : ABIArgInfo::getDirect());
412 }
413 
classifyArgumentType(QualType Ty) const414 ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const {
415   // Handle transparent union types.
416   Ty = useFirstFieldIfTransparentUnion(Ty);
417 
418   // Handle the generic C++ ABI.
419   if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
420     return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory);
421 
422   // Integers and enums are extended to full register width.
423   if (isPromotableIntegerTypeForABI(Ty))
424     return ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty));
425 
426   // Handle vector types and vector-like structure types.  Note that
427   // as opposed to float-like structure types, we do not allow any
428   // padding for vector-like structures, so verify the sizes match.
429   uint64_t Size = getContext().getTypeSize(Ty);
430   QualType SingleElementTy = GetSingleElementType(Ty);
431   if (isVectorArgumentType(SingleElementTy) &&
432       getContext().getTypeSize(SingleElementTy) == Size)
433     return ABIArgInfo::getDirect(CGT.ConvertType(SingleElementTy));
434 
435   // Values that are not 1, 2, 4 or 8 bytes in size are passed indirectly.
436   if (Size != 8 && Size != 16 && Size != 32 && Size != 64)
437     return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
438 
439   // Handle small structures.
440   if (const RecordType *RT = Ty->getAs<RecordType>()) {
441     // Structures with flexible arrays have variable length, so really
442     // fail the size test above.
443     const RecordDecl *RD = RT->getDecl();
444     if (RD->hasFlexibleArrayMember())
445       return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
446 
447     // The structure is passed as an unextended integer, a float, or a double.
448     llvm::Type *PassTy;
449     if (isFPArgumentType(SingleElementTy)) {
450       assert(Size == 32 || Size == 64);
451       if (Size == 32)
452         PassTy = llvm::Type::getFloatTy(getVMContext());
453       else
454         PassTy = llvm::Type::getDoubleTy(getVMContext());
455     } else
456       PassTy = llvm::IntegerType::get(getVMContext(), Size);
457     return ABIArgInfo::getDirect(PassTy);
458   }
459 
460   // Non-structure compounds are passed indirectly.
461   if (isCompoundType(Ty))
462     return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
463 
464   return ABIArgInfo::getDirect(nullptr);
465 }
466 
computeInfo(CGFunctionInfo & FI) const467 void SystemZABIInfo::computeInfo(CGFunctionInfo &FI) const {
468   const SystemZTargetCodeGenInfo &SZCGI =
469       static_cast<const SystemZTargetCodeGenInfo &>(
470           CGT.getCGM().getTargetCodeGenInfo());
471   if (!getCXXABI().classifyReturnType(FI))
472     FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
473   unsigned Idx = 0;
474   for (auto &I : FI.arguments()) {
475     I.info = classifyArgumentType(I.type);
476     if (FI.isVariadic() && Idx++ >= FI.getNumRequiredArgs())
477       // Check if a vararg vector argument is passed, in which case the
478       // vector ABI becomes visible as the va_list could be passed on to
479       // other functions.
480       SZCGI.handleExternallyVisibleObjABI(I.type.getTypePtr(), CGT.getCGM(),
481                                           /*IsParam*/true);
482   }
483 }
484 
isVectorTypeBased(const Type * Ty,bool IsParam) const485 bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty,
486                                                  bool IsParam) const {
487   if (!SeenTypes.insert(Ty).second)
488     return false;
489 
490   if (IsParam) {
491     // A narrow (<16 bytes) vector will as a parameter also expose the ABI as
492     // it will be passed in a vector register. A wide (>16 bytes) vector will
493     // be passed via "hidden" pointer where any extra alignment is not
494     // required (per GCC).
495     const Type *SingleEltTy = getABIInfo<SystemZABIInfo>()
496                                   .GetSingleElementType(QualType(Ty, 0))
497                                   .getTypePtr();
498     bool SingleVecEltStruct = SingleEltTy != Ty && SingleEltTy->isVectorType() &&
499       Ctx.getTypeSize(SingleEltTy) == Ctx.getTypeSize(Ty);
500     if (Ty->isVectorType() || SingleVecEltStruct)
501       return Ctx.getTypeSize(Ty) / 8 <= 16;
502   }
503 
504   // Assume pointers are dereferenced.
505   while (Ty->isPointerType() || Ty->isArrayType())
506     Ty = Ty->getPointeeOrArrayElementType();
507 
508   // Vectors >= 16 bytes expose the ABI through alignment requirements.
509   if (Ty->isVectorType() && Ctx.getTypeSize(Ty) / 8 >= 16)
510       return true;
511 
512   if (const auto *RecordTy = Ty->getAs<RecordType>()) {
513     const RecordDecl *RD = RecordTy->getDecl();
514     if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
515       if (CXXRD->hasDefinition())
516         for (const auto &I : CXXRD->bases())
517           if (isVectorTypeBased(I.getType().getTypePtr(), /*IsParam*/false))
518             return true;
519     for (const auto *FD : RD->fields())
520       if (isVectorTypeBased(FD->getType().getTypePtr(), /*IsParam*/false))
521         return true;
522   }
523 
524   if (const auto *FT = Ty->getAs<FunctionType>())
525     if (isVectorTypeBased(FT->getReturnType().getTypePtr(), /*IsParam*/true))
526       return true;
527   if (const FunctionProtoType *Proto = Ty->getAs<FunctionProtoType>())
528     for (const auto &ParamType : Proto->getParamTypes())
529       if (isVectorTypeBased(ParamType.getTypePtr(), /*IsParam*/true))
530         return true;
531 
532   return false;
533 }
534 
535 std::unique_ptr<TargetCodeGenInfo>
createSystemZTargetCodeGenInfo(CodeGenModule & CGM,bool HasVector,bool SoftFloatABI)536 CodeGen::createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector,
537                                         bool SoftFloatABI) {
538   return std::make_unique<SystemZTargetCodeGenInfo>(CGM.getTypes(), HasVector,
539                                                     SoftFloatABI);
540 }
541