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 @@ -99,6 +99,9 @@ const SmallVectorImpl &OutVals, const SDLoc &DL, SelectionDAG &DAG) const override; + void ReplaceNodeResults(SDNode *N, SmallVectorImpl &Results, + SelectionDAG &DAG) const override; + EVT getOptimalMemOpType(const MemOp &Op, const AttributeList &FuncAttributes) const override { return Op.size() >= 8 ? MVT::i64 : MVT::i32; 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 @@ -78,6 +78,24 @@ setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); + // Set unsupported atomic operations as Custom so + // we can emit better error messages than fatal error + // from selectiondag. + for (auto VT : {MVT::i8, MVT::i16, MVT::i32}) { + if (VT == MVT::i32) { + if (STI.getHasAlu32()) + continue; + } else { + setOperationAction(ISD::ATOMIC_LOAD_ADD, VT, Custom); + } + + setOperationAction(ISD::ATOMIC_LOAD_AND, VT, Custom); + setOperationAction(ISD::ATOMIC_LOAD_OR, VT, Custom); + setOperationAction(ISD::ATOMIC_LOAD_XOR, VT, Custom); + setOperationAction(ISD::ATOMIC_SWAP, VT, Custom); + setOperationAction(ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS, VT, Custom); + } + for (auto VT : { MVT::i32, MVT::i64 }) { if (VT == MVT::i32 && !STI.getHasAlu32()) continue; @@ -218,6 +236,30 @@ return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); } +void BPFTargetLowering::ReplaceNodeResults( + SDNode *N, SmallVectorImpl &Results, SelectionDAG &DAG) const { + const char *err_msg; + uint32_t Opcode = N->getOpcode(); + switch (Opcode) { + default: + report_fatal_error("Unhandled custom legalization"); + case ISD::ATOMIC_LOAD_ADD: + case ISD::ATOMIC_LOAD_AND: + case ISD::ATOMIC_LOAD_OR: + case ISD::ATOMIC_LOAD_XOR: + case ISD::ATOMIC_SWAP: + case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS: + if (HasAlu32 || Opcode == ISD::ATOMIC_LOAD_ADD) + err_msg = "Unsupported atomic operations, please use 32/64 bit version"; + else + err_msg = "Unsupported atomic operations, please use 64 bit version"; + break; + } + + SDLoc DL(N); + fail(DL, DAG, err_msg); +} + SDValue BPFTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { switch (Op.getOpcode()) { case ISD::BR_CC: