[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