From 3682fdabefdb263b1b928a76e94729bce01897c5 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Tue, 22 Apr 2014 16:42:00 +0000 Subject: [PATCH] R600: Emit error instead of unreachable on function call git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206904 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/R600/AMDGPUISelLowering.cpp | 59 ++++++++++++++++++++++++++ lib/Target/R600/AMDGPUISelLowering.h | 5 +-- test/CodeGen/R600/call.ll | 33 ++++++++++++++ 3 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 test/CodeGen/R600/call.ll diff --git a/lib/Target/R600/AMDGPUISelLowering.cpp b/lib/Target/R600/AMDGPUISelLowering.cpp index 7379bbaed4f..948533bc09f 100644 --- a/lib/Target/R600/AMDGPUISelLowering.cpp +++ b/lib/Target/R600/AMDGPUISelLowering.cpp @@ -28,8 +28,50 @@ #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/DiagnosticPrinter.h" using namespace llvm; + +namespace { + +/// Diagnostic information for unimplemented or unsupported feature reporting. +class DiagnosticInfoUnsupported : public DiagnosticInfo { +private: + const Twine &Description; + const Function &Fn; + + static int KindID; + + static int getKindID() { + if (KindID == 0) + KindID = llvm::getNextAvailablePluginDiagnosticKind(); + return KindID; + } + +public: + DiagnosticInfoUnsupported(const Function &Fn, const Twine &Desc, + DiagnosticSeverity Severity = DS_Error) + : DiagnosticInfo(getKindID(), Severity), + Description(Desc), + Fn(Fn) { } + + const Function &getFunction() const { return Fn; } + const Twine &getDescription() const { return Description; } + + void print(DiagnosticPrinter &DP) const override { + DP << "unsupported " << getDescription() << " in " << Fn.getName(); + } + + static bool classof(const DiagnosticInfo *DI) { + return DI->getKind() == getKindID(); + } +}; + +int DiagnosticInfoUnsupported::KindID = 0; +} + + static bool allocateStack(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State) { @@ -311,6 +353,23 @@ SDValue AMDGPUTargetLowering::LowerReturn( // Target specific lowering //===---------------------------------------------------------------------===// +SDValue AMDGPUTargetLowering::LowerCall(CallLoweringInfo &CLI, + SmallVectorImpl &InVals) const { + SDValue Callee = CLI.Callee; + SelectionDAG &DAG = CLI.DAG; + + const Function &Fn = *DAG.getMachineFunction().getFunction(); + + StringRef FuncName(""); + + if (const GlobalAddressSDNode *G = dyn_cast(Callee)) + FuncName = G->getGlobal()->getName(); + + DiagnosticInfoUnsupported NoCalls(Fn, "call to function " + FuncName); + DAG.getContext()->diagnose(NoCalls); + return SDValue(); +} + SDValue AMDGPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { switch (Op.getOpcode()) { diff --git a/lib/Target/R600/AMDGPUISelLowering.h b/lib/Target/R600/AMDGPUISelLowering.h index 421a4b7a892..2537a850126 100644 --- a/lib/Target/R600/AMDGPUISelLowering.h +++ b/lib/Target/R600/AMDGPUISelLowering.h @@ -98,10 +98,7 @@ public: const SmallVectorImpl &OutVals, SDLoc DL, SelectionDAG &DAG) const; virtual SDValue LowerCall(CallLoweringInfo &CLI, - SmallVectorImpl &InVals) const { - CLI.Callee.dump(); - llvm_unreachable("Undefined function"); - } + SmallVectorImpl &InVals) const; virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const; virtual void ReplaceNodeResults(SDNode * N, diff --git a/test/CodeGen/R600/call.ll b/test/CodeGen/R600/call.ll new file mode 100644 index 00000000000..c8350b85f44 --- /dev/null +++ b/test/CodeGen/R600/call.ll @@ -0,0 +1,33 @@ +; RUN: not llc -march=r600 -mcpu=SI < %s 2>&1 | FileCheck %s +; RUN: not llc -march=r600 -mcpu=cypress < %s 2>&1 | FileCheck %s + +; CHECK: error: unsupported call to function defined_function in test_call + + +declare i32 @external_function(i32) nounwind + +define i32 @defined_function(i32 %x) nounwind noinline { + %y = add i32 %x, 8 + ret i32 %y +} + +define void @test_call(i32 addrspace(1)* %out, i32 addrspace(1)* %in) { + %b_ptr = getelementptr i32 addrspace(1)* %in, i32 1 + %a = load i32 addrspace(1)* %in + %b = load i32 addrspace(1)* %b_ptr + %c = call i32 @defined_function(i32 %b) nounwind + %result = add i32 %a, %c + store i32 %result, i32 addrspace(1)* %out + ret void +} + +define void @test_call_external(i32 addrspace(1)* %out, i32 addrspace(1)* %in) { + %b_ptr = getelementptr i32 addrspace(1)* %in, i32 1 + %a = load i32 addrspace(1)* %in + %b = load i32 addrspace(1)* %b_ptr + %c = call i32 @external_function(i32 %b) nounwind + %result = add i32 %a, %c + store i32 %result, i32 addrspace(1)* %out + ret void +} + -- 2.34.1