[PATCH] R600: Emit error instead of unreachable on function call
Tom Stellard
tom at stellard.net
Tue Apr 22 07:05:01 PDT 2014
On Tue, Apr 22, 2014 at 12:39:44AM -0700, Matt Arsenault wrote:
> http://reviews.llvm.org/D3446
>
LGTM.
> Files:
> lib/Target/R600/AMDGPUISelLowering.cpp
> lib/Target/R600/AMDGPUISelLowering.h
> test/CodeGen/R600/call.ll
> Index: lib/Target/R600/AMDGPUISelLowering.cpp
> ===================================================================
> --- lib/Target/R600/AMDGPUISelLowering.cpp
> +++ 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 @@
> // Target specific lowering
> //===---------------------------------------------------------------------===//
>
> +SDValue AMDGPUTargetLowering::LowerCall(CallLoweringInfo &CLI,
> + SmallVectorImpl<SDValue> &InVals) const {
> + SDValue Callee = CLI.Callee;
> + SelectionDAG &DAG = CLI.DAG;
> +
> + const Function &Fn = *DAG.getMachineFunction().getFunction();
> +
> + StringRef FuncName("<unknown>");
> +
> + if (const GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(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()) {
> Index: lib/Target/R600/AMDGPUISelLowering.h
> ===================================================================
> --- lib/Target/R600/AMDGPUISelLowering.h
> +++ lib/Target/R600/AMDGPUISelLowering.h
> @@ -98,10 +98,7 @@
> const SmallVectorImpl<SDValue> &OutVals,
> SDLoc DL, SelectionDAG &DAG) const;
> virtual SDValue LowerCall(CallLoweringInfo &CLI,
> - SmallVectorImpl<SDValue> &InVals) const {
> - CLI.Callee.dump();
> - llvm_unreachable("Undefined function");
> - }
> + SmallVectorImpl<SDValue> &InVals) const;
>
> virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
> virtual void ReplaceNodeResults(SDNode * N,
> Index: test/CodeGen/R600/call.ll
> ===================================================================
> --- /dev/null
> +++ 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
> +}
> +
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list