Index: clang/lib/CodeGen/TargetInfo.cpp =================================================================== --- clang/lib/CodeGen/TargetInfo.cpp +++ clang/lib/CodeGen/TargetInfo.cpp @@ -7418,18 +7418,25 @@ }; class SystemZTargetCodeGenInfo : public TargetCodeGenInfo { + ASTContext &Ctx; + // These are used for speeding up the search for a visible vector ABI. mutable bool HasVisibleVecABIFlag = false; mutable std::set SeenTypes; - // Returns true (the first time) if Ty is or found to make use of a vector - // type (e.g. as a function argument). - bool isVectorTypeBased(const Type *Ty) const; + // Returns true (the first time) if Ty is, or is found to include, a vector + // type that exposes the vector ABI. This is any vector >=16 bytes which + // with vector support are aligned to only 8 bytes. When IsParam is true, + // the type belongs to a value as passed between functions. If it is a + // vector <=16 bytes it will be passed in a register in case of vector + // support. + bool isVectorTypeBased(const Type *Ty, bool IsParam = false) const; public: SystemZTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector, bool SoftFloatABI) : TargetCodeGenInfo( - std::make_unique(CGT, HasVector, SoftFloatABI)) { + std::make_unique(CGT, HasVector, SoftFloatABI)), + Ctx(CGT.getContext()) { SwiftInfo = std::make_unique(CGT, /*SwiftErrorInRegister=*/false); } @@ -7847,13 +7854,17 @@ } } -bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty) const { +bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty, + bool IsParam) const { while (Ty->isPointerType() || Ty->isArrayType()) Ty = Ty->getPointeeOrArrayElementType(); if (!SeenTypes.insert(Ty).second) return false; - if (Ty->isVectorType()) - return true; + if (Ty->isVectorType()) { + unsigned Bytes = Ctx.getTypeSize(Ty) / 8; + if (Bytes >= 16 || IsParam) + return true; + } if (const auto *RecordTy = Ty->getAs()) { const RecordDecl *RD = RecordTy->getDecl(); if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) @@ -7866,11 +7877,11 @@ return true; } if (const auto *FT = Ty->getAs()) - if (isVectorTypeBased(FT->getReturnType().getTypePtr())) + if (isVectorTypeBased(FT->getReturnType().getTypePtr(), true)) return true; if (const FunctionProtoType *Proto = Ty->getAs()) for (auto ParamType : Proto->getParamTypes()) - if (isVectorTypeBased(ParamType.getTypePtr())) + if (isVectorTypeBased(ParamType.getTypePtr(), true)) return true; return false; } Index: clang/test/CodeGen/SystemZ/vec-abi-gnuattr-03b.c =================================================================== --- /dev/null +++ clang/test/CodeGen/SystemZ/vec-abi-gnuattr-03b.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple s390x-ibm-linux -emit-llvm -fzvector -o - %s 2>&1 \ +// RUN: | FileCheck %s +// +// Test that the "s390x-visible-vector-ABI" module flag is emitted. + +// Call to external function with with narrow vector argument. + +typedef __attribute__((vector_size(8))) int v2i32; + +void bar(v2i32 arg); + +void foo() { + v2i32 Var = {0, 0}; + bar(Var); +} + +//CHECK: !llvm.module.flags = !{!0, !1} +//CHECK: !0 = !{i32 2, !"s390x-visible-vector-ABI", i32 1} + Index: clang/test/CodeGen/SystemZ/vec-abi-gnuattr-17b.c =================================================================== --- /dev/null +++ clang/test/CodeGen/SystemZ/vec-abi-gnuattr-17b.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple s390x-ibm-linux -emit-llvm -fzvector -o - %s 2>&1 \ +// RUN: | FileCheck %s +// +// Test that the "s390x-visible-vector-ABI" module flag is emitted. + +// Globally visible function pointer with narrow vector argument. + +typedef __attribute__((vector_size(16))) int v2i32; + +void (*bar)(v2i32 Arg); + +//CHECK: !llvm.module.flags = !{!0, !1} +//CHECK: !0 = !{i32 2, !"s390x-visible-vector-ABI", i32 1} Index: clang/test/CodeGen/SystemZ/vec-abi-gnuattr-24.c =================================================================== --- clang/test/CodeGen/SystemZ/vec-abi-gnuattr-24.c +++ clang/test/CodeGen/SystemZ/vec-abi-gnuattr-24.c @@ -34,4 +34,8 @@ return foo(V)[0] + GlobVal + GlobExtVar; } +// Globally visible vector variable less than 16 bytes in size. +typedef __attribute__((vector_size(8))) int v2i32; +v2i32 NarrowVecVar; + //CHECK-NOT: !{i32 2, !"s390x-visible-vector-ABI", i32 1}