diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp index c3842519008..24383109d57 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -777,6 +777,24 @@ bool SystemZTargetLowering::mayBeEmittedAsTailCall(CallInst *CI) const { return true; } +// We do not yet support 128-bit single-element vector types. If the user +// attempts to use such types as function argument or return type, prefer +// to error out instead of emitting code violating the ABI. +static void VerifyVectorType(MVT VT, EVT ArgVT) { + if (ArgVT.isVector() && !VT.isVector()) + report_fatal_error("Unsupported vector argument or return type"); +} + +static void VerifyVectorTypes(const SmallVectorImpl &Ins) { + for (unsigned i = 0; i < Ins.size(); ++i) + VerifyVectorType(Ins[i].VT, Ins[i].ArgVT); +} + +static void VerifyVectorTypes(const SmallVectorImpl &Outs) { + for (unsigned i = 0; i < Outs.size(); ++i) + VerifyVectorType(Outs[i].VT, Outs[i].ArgVT); +} + // Value is a value that has been passed to us in the location described by VA // (and so has type VA.getLocVT()). Convert Value to VA.getValVT(), chaining // any loads onto Chain. @@ -850,6 +868,10 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, auto *TFL = static_cast(Subtarget.getFrameLowering()); + // Detect unsupported vector argument types. + if (Subtarget.hasVector()) + VerifyVectorTypes(Ins); + // Assign locations to all of the incoming arguments. SmallVector ArgLocs; SystemZCCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext()); @@ -997,6 +1019,12 @@ SystemZTargetLowering::LowerCall(CallLoweringInfo &CLI, MachineFunction &MF = DAG.getMachineFunction(); EVT PtrVT = getPointerTy(); + // Detect unsupported vector argument and return types. + if (Subtarget.hasVector()) { + VerifyVectorTypes(Outs); + VerifyVectorTypes(Ins); + } + // Analyze the operands of the call, assigning locations to each operand. SmallVector ArgLocs; SystemZCCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext()); @@ -1151,6 +1179,10 @@ SystemZTargetLowering::LowerReturn(SDValue Chain, SDLoc DL, SelectionDAG &DAG) const { MachineFunction &MF = DAG.getMachineFunction(); + // Detect unsupported vector return types. + if (Subtarget.hasVector()) + VerifyVectorTypes(Outs); + // Assign locations to each returned value. SmallVector RetLocs; CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, *DAG.getContext()); diff --git a/test/CodeGen/SystemZ/vec-args-error-01.ll b/test/CodeGen/SystemZ/vec-args-error-01.ll new file mode 100644 index 00000000000..e2f53794959 --- /dev/null +++ b/test/CodeGen/SystemZ/vec-args-error-01.ll @@ -0,0 +1,9 @@ +; Verify that we detect unsupported single-element vector types. + +; RUN: not llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 2>&1 | FileCheck %s + +define void @foo(<1 x i128>) { + ret void +} + +; CHECK: LLVM ERROR: Unsupported vector argument or return type diff --git a/test/CodeGen/SystemZ/vec-args-error-02.ll b/test/CodeGen/SystemZ/vec-args-error-02.ll new file mode 100644 index 00000000000..a5ae1102a74 --- /dev/null +++ b/test/CodeGen/SystemZ/vec-args-error-02.ll @@ -0,0 +1,9 @@ +; Verify that we detect unsupported single-element vector types. + +; RUN: not llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 2>&1 | FileCheck %s + +define <1 x i128> @foo() { + ret <1 x i128> +} + +; CHECK: LLVM ERROR: Unsupported vector argument or return type diff --git a/test/CodeGen/SystemZ/vec-args-error-03.ll b/test/CodeGen/SystemZ/vec-args-error-03.ll new file mode 100644 index 00000000000..14698aae43b --- /dev/null +++ b/test/CodeGen/SystemZ/vec-args-error-03.ll @@ -0,0 +1,12 @@ +; Verify that we detect unsupported single-element vector types. + +; RUN: not llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 2>&1 | FileCheck %s + +declare void @bar(<1 x i128>) + +define void @foo() { + call void @bar (<1 x i128> ) + ret void +} + +; CHECK: LLVM ERROR: Unsupported vector argument or return type diff --git a/test/CodeGen/SystemZ/vec-args-error-04.ll b/test/CodeGen/SystemZ/vec-args-error-04.ll new file mode 100644 index 00000000000..a54ee90022c --- /dev/null +++ b/test/CodeGen/SystemZ/vec-args-error-04.ll @@ -0,0 +1,12 @@ +; Verify that we detect unsupported single-element vector types. + +; RUN: not llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 2>&1 | FileCheck %s + +declare <1 x i128> @bar() + +define void @foo() { + %res = call <1 x i128> @bar () + ret void +} + +; CHECK: LLVM ERROR: Unsupported vector argument or return type diff --git a/test/CodeGen/SystemZ/vec-args-error-05.ll b/test/CodeGen/SystemZ/vec-args-error-05.ll new file mode 100644 index 00000000000..067deb1c88b --- /dev/null +++ b/test/CodeGen/SystemZ/vec-args-error-05.ll @@ -0,0 +1,9 @@ +; Verify that we detect unsupported single-element vector types. + +; RUN: not llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 2>&1 | FileCheck %s + +define void @foo(<1 x fp128>) { + ret void +} + +; CHECK: LLVM ERROR: Unsupported vector argument or return type diff --git a/test/CodeGen/SystemZ/vec-args-error-06.ll b/test/CodeGen/SystemZ/vec-args-error-06.ll new file mode 100644 index 00000000000..a9184d73575 --- /dev/null +++ b/test/CodeGen/SystemZ/vec-args-error-06.ll @@ -0,0 +1,9 @@ +; Verify that we detect unsupported single-element vector types. + +; RUN: not llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 2>&1 | FileCheck %s + +define <1 x fp128> @foo() { + ret <1 x fp128> +} + +; CHECK: LLVM ERROR: Unsupported vector argument or return type diff --git a/test/CodeGen/SystemZ/vec-args-error-07.ll b/test/CodeGen/SystemZ/vec-args-error-07.ll new file mode 100644 index 00000000000..4e914009391 --- /dev/null +++ b/test/CodeGen/SystemZ/vec-args-error-07.ll @@ -0,0 +1,12 @@ +; Verify that we detect unsupported single-element vector types. + +; RUN: not llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 2>&1 | FileCheck %s + +declare void @bar(<1 x fp128>) + +define void @foo() { + call void @bar (<1 x fp128> ) + ret void +} + +; CHECK: LLVM ERROR: Unsupported vector argument or return type diff --git a/test/CodeGen/SystemZ/vec-args-error-08.ll b/test/CodeGen/SystemZ/vec-args-error-08.ll new file mode 100644 index 00000000000..7b16b9f46e3 --- /dev/null +++ b/test/CodeGen/SystemZ/vec-args-error-08.ll @@ -0,0 +1,12 @@ +; Verify that we detect unsupported single-element vector types. + +; RUN: not llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 2>&1 | FileCheck %s + +declare <1 x fp128> @bar() + +define void @foo() { + %res = call <1 x fp128> @bar () + ret void +} + +; CHECK: LLVM ERROR: Unsupported vector argument or return type