Index: clang/lib/CodeGen/TargetInfo.cpp =================================================================== --- clang/lib/CodeGen/TargetInfo.cpp +++ clang/lib/CodeGen/TargetInfo.cpp @@ -7222,7 +7222,7 @@ bool isPromotableIntegerTypeForABI(QualType Ty) const; bool isCompoundType(QualType Ty) const; - bool isVectorArgumentType(QualType Ty) const; + bool isVectorArgumentType(QualType Ty, bool AsCodeGened = true) const; bool isFPArgumentType(QualType Ty) const; QualType GetSingleElementType(QualType Ty) const; @@ -7254,6 +7254,26 @@ : TargetCodeGenInfo( std::make_unique(CGT, HasVector, SoftFloatABI)) {} + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &CGM) const override { + if (!D) + return; + if (const FunctionDecl *FnDecl = D->getAsFunction()) { + const SystemZABIInfo &SZABII = + static_cast(TargetCodeGenInfo::getABIInfo()); + QualType RTy = FnDecl->getReturnType(); + bool HasVectorArg = SZABII.isVectorArgumentType(RTy, false/*AsCodeGened*/); + for (unsigned I = 0; I < FnDecl->getNumParams() && !HasVectorArg; I++) { + QualType PTy = FnDecl->getParamDecl(I)->getType(); + HasVectorArg |= SZABII.isVectorArgumentType(PTy, false/*AsCodeGened*/); + } + if (HasVectorArg) { + llvm::Function *Fn = cast(GV); + Fn->addFnAttr("has-vector-args"); + } + } + } + llvm::Value *testFPKind(llvm::Value *V, unsigned BuiltinID, CGBuilderTy &Builder, CodeGenModule &CGM) const override { @@ -7329,8 +7349,8 @@ isAggregateTypeForABI(Ty)); } -bool SystemZABIInfo::isVectorArgumentType(QualType Ty) const { - return (HasVector && +bool SystemZABIInfo::isVectorArgumentType(QualType Ty, bool AsCodeGened) const { + return ((HasVector || !AsCodeGened) && Ty->isVectorType() && getContext().getTypeSize(Ty) <= 128); } Index: clang/test/CodeGen/SystemZ/has-vector-args.c =================================================================== --- /dev/null +++ clang/test/CodeGen/SystemZ/has-vector-args.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple s390x-ibm-linux -target-cpu arch10 -emit-llvm \ +// RUN: -fzvector -o - %s 2>&1 | FileCheck %s --check-prefix=ARCH10 +// RUN: %clang_cc1 -triple s390x-ibm-linux -target-cpu arch13 -emit-llvm \ +// RUN: -fzvector -o - %s 2>&1 | FileCheck %s --check-prefix=ARCH13 + +// Globally visible function with vector argument. +vector int fun0(vector int v1) { return v1; } + +// Globally visible function with vector return value. +vector int fun1(void) { return ((vector int) 0); } + +//ARCH10: define dso_local void @fun0(<4 x i32>* noalias sret(<4 x i32>) align 16 %agg.result, <4 x i32>* %0) #0 +//ARCH10: define dso_local void @fun1(<4 x i32>* noalias sret(<4 x i32>) align 16 %agg.result) #0 + +//ARCH13: define dso_local <4 x i32> @fun0(<4 x i32> %v1) #0 +//ARCH13: define dso_local <4 x i32> @fun1() #0 + +//CHECK: attributes #0 = { {{.*}}"has-vector-args" {{.*}} } Index: llvm/lib/Target/SystemZ/SystemZAsmPrinter.h =================================================================== --- llvm/lib/Target/SystemZ/SystemZAsmPrinter.h +++ llvm/lib/Target/SystemZ/SystemZAsmPrinter.h @@ -49,6 +49,7 @@ void LowerFENTRY_CALL(const MachineInstr &MI, SystemZMCInstLower &MCIL); void LowerSTACKMAP(const MachineInstr &MI); void LowerPATCHPOINT(const MachineInstr &MI, SystemZMCInstLower &Lower); + void emitGNUAttributes(Module &M); }; } // end namespace llvm Index: llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp =================================================================== --- llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -698,6 +698,37 @@ getSubtargetInfo()); } +void SystemZAsmPrinter::emitGNUAttributes(Module &M) { + bool HasVectorABI = false; + for (const GlobalValue &GV : M.global_values()) { + if (!GV.hasLocalLinkage() && (!GV.isDeclaration() || !GV.use_empty())) { + if (const Function *F = dyn_cast(&GV)) { + if (F->hasFnAttribute("has-vector-args")) { + HasVectorABI = true; + break; + } + } + else if (const GlobalVariable *GVar = dyn_cast(&GV)) { + if (GVar->getValueType()->isVectorTy()) { + HasVectorABI = true; + break; + } + } + } + } + + if (HasVectorABI) { + bool HasVectorFeature = + TM.getMCSubtargetInfo()->getFeatureBits()[SystemZ::FeatureVector]; + SmallString<64> Str; + raw_svector_ostream O(Str); + O << "\t.gnu_attribute 8, " << (HasVectorFeature ? "2" : "1"); + auto *ReadOnlySection = OutContext.getObjectFileInfo()->getReadOnlySection(); + OutStreamer->SwitchSection(ReadOnlySection); + OutStreamer->emitRawText(O.str()); + } +} + // Convert a SystemZ-specific constant pool modifier into the associated // MCSymbolRefExpr variant kind. static MCSymbolRefExpr::VariantKind @@ -746,6 +777,7 @@ } void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) { + emitGNUAttributes(M); emitStackMaps(SM); } Index: llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-00.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-00.ll @@ -0,0 +1,15 @@ +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=arch13 < %s | FileCheck %s +; +; Test the emission of a .gnu_attribute describing the vector abi. + +; Call to external function with vector arguments. +define internal void @fun() { +entry: + tail call void @foo(<4 x i32> zeroinitializer) + ret void +} + +declare void @foo(<4 x i32>) #0 +attributes #0 = { "has-vector-args" } + +; CHECK: .gnu_attribute 8, 2 Index: llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-01.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-01.ll @@ -0,0 +1,17 @@ +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=arch10 < %s | FileCheck %s +; +; Test the emission of a .gnu_attribute describing the vector abi. + +; Call to external function with vector arguments. +define internal void @fun() { +entry: + %indirect-arg-temp = alloca <4 x i32>, align 16 + store <4 x i32> zeroinitializer, <4 x i32>* %indirect-arg-temp + call void @foo(<4 x i32>* nonnull %indirect-arg-temp) + ret void +} + +declare void @foo(<4 x i32>*) #0 +attributes #0 = { "has-vector-args" } + +; CHECK: .gnu_attribute 8, 1 Index: llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-02.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-02.ll @@ -0,0 +1,16 @@ +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=zEC12 < %s | FileCheck %s --check-prefix=ARCH10 +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=arch13 < %s | FileCheck %s --check-prefix=ARCH13 +; +; Test the emission of a .gnu_attribute describing the vector abi. + +; Call to external function *without* Vector arguments. +define internal void @fun() { +entry: + tail call void @foo(i64 0) + ret void +} + +declare void @foo(i64) + +; ARCH10-NOT: .gnu_attribute 8 +; ARCH13-NOT: .gnu_attribute 8 Index: llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-03.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-03.ll @@ -0,0 +1,13 @@ +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=arch13 < %s | FileCheck %s +; +; Test the emission of a .gnu_attribute describing the vector abi. + +; Defining globally visible function with vector arguments. +define <4 x i32> @fun(<4 x i32> %Arg) #0 { +entry: + ret <4 x i32> %Arg +} + +attributes #0 = { "has-vector-args" } + +; CHECK: .gnu_attribute 8, 2 Index: llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-04.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-04.ll @@ -0,0 +1,15 @@ +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=arch10 < %s | FileCheck %s +; +; Test the emission of a .gnu_attribute describing the vector abi. + +; Defining globally visible function with vector arguments. +define void @fun(<4 x i32>* noalias nocapture sret(<4 x i32>) align 16 %agg.result, <4 x i32>* nocapture readonly %0) #0 { +entry: + %v1 = load <4 x i32>, <4 x i32>* %0 + store <4 x i32> %v1, <4 x i32>* %agg.result + ret void +} + +attributes #0 = { "has-vector-args" } + +; CHECK: .gnu_attribute 8, 1 Index: llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-05.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-05.ll @@ -0,0 +1,15 @@ +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=arch13 < %s | FileCheck %s +; +; Test the emission of a .gnu_attribute describing the vector abi. + +; Calling globally visible function with vector parameter. +define void @fun() { +entry: + tail call void @foo(<4 x i32> zeroinitializer) + ret void +} + +declare void @foo(<4 x i32>) #0 +attributes #0 = { "has-vector-args" } + +; CHECK: .gnu_attribute 8, 2 Index: llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-06.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-06.ll @@ -0,0 +1,17 @@ +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=arch10 < %s | FileCheck %s +; +; Test the emission of a .gnu_attribute describing the vector abi. + +; Calling globally visible function with vector parameter. +define void @fun() { +entry: + %indirect-arg-temp = alloca <4 x i32> + store <4 x i32> zeroinitializer, <4 x i32>* %indirect-arg-temp + call void @foo(<4 x i32>* nonnull %indirect-arg-temp) + ret void +} + +declare dso_local void @foo(<4 x i32>*) #0 +attributes #0 = { "has-vector-args" } + +; CHECK: .gnu_attribute 8, 1 Index: llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-07.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-07.ll @@ -0,0 +1,10 @@ +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=zEC12 < %s | FileCheck %s --check-prefix=ARCH10 +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=arch13 < %s | FileCheck %s --check-prefix=ARCH13 +; +; Test the emission of a .gnu_attribute describing the vector abi. + +; Globally visible vector variable. +@VisibleVector = global <4 x i32> zeroinitializer + +; ARCH10: .gnu_attribute 8, 1 +; ARCH13: .gnu_attribute 8, 2 Index: llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-08.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-08.ll @@ -0,0 +1,16 @@ +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=zEC12 < %s | FileCheck %s --check-prefix=ARCH10 +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=arch13 < %s | FileCheck %s --check-prefix=ARCH13 +; +; Test the emission of a .gnu_attribute describing the vector abi. + +; Using external vector variable. +@ExtVector = external global <4 x i32> + +define void @fun() { +entry: + store <4 x i32> zeroinitializer, <4 x i32>* @ExtVector + ret void +} + +; ARCH10: .gnu_attribute 8, 1 +; ARCH13: .gnu_attribute 8, 2 Index: llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-09.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-09.ll @@ -0,0 +1,16 @@ +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=zEC12 < %s | FileCheck %s --check-prefix=ARCH10 +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=arch13 < %s | FileCheck %s --check-prefix=ARCH13 +; +; Test the emission of a .gnu_attribute describing the vector abi. + +; Using local vector variable. +@LocVector = internal global <4 x i32> zeroinitializer + +define void @fun() { +entry: + store volatile <4 x i32> zeroinitializer, <4 x i32>* @LocVector + ret void +} + +; ARCH10-NOT: .gnu_attribute 8 +; ARCH13-NOT: .gnu_attribute 8 Index: llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-10.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-10.ll @@ -0,0 +1,16 @@ +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=arch13 < %s | FileCheck %s +; +; Test the emission of a .gnu_attribute describing the vector abi. + +; Calling local function with vector return value. +define void @fun() { +entry: + tail call void @foo(<4 x i32> zeroinitializer) + ret void +} + +define internal void @foo(<4 x i32>) #0 { ret void } +attributes #0 = { "has-vector-args" } + +; CHECK-LABEL: fun: +; CHECK-NOT: .gnu_attribute 8 Index: llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-11.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/SystemZ/vec-abi-gnuattr-11.ll @@ -0,0 +1,18 @@ +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=arch10 < %s | FileCheck %s +; +; Test the emission of a .gnu_attribute describing the vector abi. + +; Calling local function with vector return value. +define void @fun() { +entry: + %indirect-arg-temp = alloca <4 x i32>, align 16 + store <4 x i32> zeroinitializer, <4 x i32>* %indirect-arg-temp + call void @foo(<4 x i32>* nonnull %indirect-arg-temp) + ret void +} + +define internal void @foo(<4 x i32>*) #0 { ret void } +attributes #0 = { "has-vector-args" } + +; CHECK-LABEL: fun: +; CHECK-NOT: .gnu_attribute 8