diff --git a/llvm/lib/Target/BPF/BPFISelLowering.h b/llvm/lib/Target/BPF/BPFISelLowering.h --- a/llvm/lib/Target/BPF/BPFISelLowering.h +++ b/llvm/lib/Target/BPF/BPFISelLowering.h @@ -66,6 +66,8 @@ MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override; + void finalizeLowering(MachineFunction &MF) const override; + private: // Control Instruction Selection Features bool HasAlu32; @@ -73,6 +75,11 @@ bool HasJmpExt; bool HasMovsx; + mutable bool HasError = false; + + void fail(const SDLoc &DL, SelectionDAG &DAG, const Twine &Msg, + SDValue Val) const; + SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const; SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; diff --git a/llvm/lib/Target/BPF/BPFISelLowering.cpp b/llvm/lib/Target/BPF/BPFISelLowering.cpp --- a/llvm/lib/Target/BPF/BPFISelLowering.cpp +++ b/llvm/lib/Target/BPF/BPFISelLowering.cpp @@ -37,8 +37,9 @@ cl::Hidden, cl::init(false), cl::desc("Expand memcpy into load/store pairs in order")); -static void fail(const SDLoc &DL, SelectionDAG &DAG, const Twine &Msg, - SDValue Val = {}) { +void BPFTargetLowering::fail(const SDLoc &DL, SelectionDAG &DAG, + const Twine &Msg, SDValue Val = {}) const { + HasError = true; std::string Str; if (Val) { raw_string_ostream OS(Str); @@ -883,6 +884,13 @@ return (getHasAlu32() && VT == MVT::i32) ? MVT::i32 : MVT::i64; } +void BPFTargetLowering::finalizeLowering(MachineFunction &MF) const { + if (HasError) { + report_fatal_error("failed to generate BPF instructions, see diagnostics"); + } + TargetLowering::finalizeLowering(MF); +} + bool BPFTargetLowering::isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, diff --git a/llvm/test/CodeGen/BPF/byval.ll b/llvm/test/CodeGen/BPF/byval.ll --- a/llvm/test/CodeGen/BPF/byval.ll +++ b/llvm/test/CodeGen/BPF/byval.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=bpf < %s 2> %t1 +; RUN: not --crash llc -march=bpf < %s 2> %t1 ; RUN: FileCheck %s < %t1 ; CHECK: by value not supported diff --git a/llvm/test/CodeGen/BPF/many_args1.ll b/llvm/test/CodeGen/BPF/many_args1.ll --- a/llvm/test/CodeGen/BPF/many_args1.ll +++ b/llvm/test/CodeGen/BPF/many_args1.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=bpf < %s 2> %t1 +; RUN: not --crash llc -march=bpf < %s 2> %t1 ; RUN: FileCheck %s < %t1 ; CHECK: error: :0:0: in function foo i32 (i32, i32, i32): {{t10|0x[0-f]+}}: i64 = GlobalAddress 0 too many arguments diff --git a/llvm/test/CodeGen/BPF/many_args2.ll b/llvm/test/CodeGen/BPF/many_args2.ll --- a/llvm/test/CodeGen/BPF/many_args2.ll +++ b/llvm/test/CodeGen/BPF/many_args2.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=bpf < %s 2> %t1 +; RUN: not --crash llc -march=bpf < %s 2> %t1 ; RUN: FileCheck %s < %t1 ; CHECK: error: :0:0: in function bar i32 (i32, i32, i32, i32, i32, i32): stack arguments are not supported diff --git a/llvm/test/CodeGen/BPF/struct_ret1.ll b/llvm/test/CodeGen/BPF/struct_ret1.ll --- a/llvm/test/CodeGen/BPF/struct_ret1.ll +++ b/llvm/test/CodeGen/BPF/struct_ret1.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=bpf < %s 2> %t1 +; RUN: not --crash llc -march=bpf < %s 2> %t1 ; RUN: FileCheck %s < %t1 ; CHECK: error: :0:0: in function bar { i64, i32 } (i32, i32, i32, i32, i32): aggregate returns are not supported @@ -15,13 +15,3 @@ %.fca.1.insert = insertvalue { i64, i32 } %.fca.0.insert, i32 %retval.sroa.2.0.copyload, 1 ret { i64, i32 } %.fca.1.insert } - -; CHECK: error: :0:0: in function baz void (ptr): aggregate returns are not supported - -%struct.B = type { [100 x i64] } - -; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) -define dso_local void @baz(ptr noalias nocapture sret(%struct.B) align 8 %agg.result) local_unnamed_addr #0 { -entry: - ret void -} diff --git a/llvm/test/CodeGen/BPF/struct_ret2.ll b/llvm/test/CodeGen/BPF/struct_ret2.ll --- a/llvm/test/CodeGen/BPF/struct_ret2.ll +++ b/llvm/test/CodeGen/BPF/struct_ret2.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=bpf < %s 2> %t1 +; RUN: not --crash llc -march=bpf < %s 2> %t1 ; RUN: FileCheck %s < %t1 ; CHECK: only small returns diff --git a/llvm/test/CodeGen/BPF/struct_ret3.ll b/llvm/test/CodeGen/BPF/struct_ret3.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/struct_ret3.ll @@ -0,0 +1,11 @@ +; RUN: not --crash llc -march=bpf < %s 2> %t1 +; RUN: FileCheck %s < %t1 +; CHECK: error: :0:0: in function baz void (ptr): aggregate returns are not supported + +%struct.B = type { [100 x i64] } + +; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +define dso_local void @baz(ptr noalias nocapture sret(%struct.B) align 8 %agg.result) local_unnamed_addr #0 { +entry: + ret void +} diff --git a/llvm/test/CodeGen/BPF/vararg1.ll b/llvm/test/CodeGen/BPF/vararg1.ll --- a/llvm/test/CodeGen/BPF/vararg1.ll +++ b/llvm/test/CodeGen/BPF/vararg1.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=bpf < %s 2> %t1 +; RUN: not --crash llc -march=bpf < %s 2> %t1 ; RUN: FileCheck %s < %t1 ; CHECK: error: :0:0: in function foo void (i32, ...): variadic functions are not supported diff --git a/llvm/test/CodeGen/BPF/warn-call.ll b/llvm/test/CodeGen/BPF/warn-call.ll --- a/llvm/test/CodeGen/BPF/warn-call.ll +++ b/llvm/test/CodeGen/BPF/warn-call.ll @@ -1,4 +1,4 @@ -; RUN: not llc -march=bpfel < %s 2>&1 >/dev/null | FileCheck %s +; RUN: not --crash llc -march=bpfel < %s 2>&1 >/dev/null | FileCheck %s ; CHECK: error: warn_call.c ; CHECK: built-in function 'memcpy'