From 379d9088480730d31e8afdf6d2313cfed72ba905 Mon Sep 17 00:00:00 2001 From: Yonghong Song Date: Thu, 11 Mar 2021 12:28:04 -0800 Subject: [PATCH] BPF: provide better error message for unsupported atomic operations Currently, BPF backend does not support all variants of atomic_load_{add,and,or,xor}, atomic_swap and atomic_cmp_swap For example, it only supports 32bit (with alu32 mode) and 64bit operations for atomic_load_{and,or,xor}, atomic_swap and atomic_cmp_swap. Due to historical reason, atomic_load_add is always supported with 32bit and 64bit. If user used an unsupported atomic operation, currently, codegen selectiondag cannot find bpf support and will issue a fatal error. This is not user friendly as user may mistakenly think this is a compiler bug. This patch added Custom rule for unsupported atomic operations and will emit better error message during ReplaceNodeResults() callback. The following is an example output. $ cat t.c short sync(short *p) { return __sync_val_compare_and_swap (p, 2, 3); } $ clang -target bpf -O2 -g -c t.c t.c:2:11: error: Unsupported atomic operations, please use 64 bit version return __sync_val_compare_and_swap (p, 2, 3); ^ fatal error: error in backend: Cannot select: t19: i64,ch = AtomicCmpSwap<(load store seq_cst seq_cst 2 on %ir.p)> t0, t2, Constant:i64<2>, Constant:i64<3>, t.c:2:11 t2: i64,ch = CopyFromReg t0, Register:i64 %0 t1: i64 = Register %0 t11: i64 = Constant<2> t10: i64 = Constant<3> In function: sync PLEASE submit a bug report ... Fatal error will still happen since we did not really do proper lowering for these unsupported atomic operations. But we do get a much better error message. Differential Revision: https://reviews.llvm.org/D98471 --- llvm/lib/Target/BPF/BPFISelLowering.cpp | 42 +++++++++++++++++++++++++ llvm/lib/Target/BPF/BPFISelLowering.h | 3 ++ 2 files changed, 45 insertions(+) diff --git a/llvm/lib/Target/BPF/BPFISelLowering.cpp b/llvm/lib/Target/BPF/BPFISelLowering.cpp index 3322b8d93b3a..8b16e0d3a23d 100644 --- a/llvm/lib/Target/BPF/BPFISelLowering.cpp +++ b/llvm/lib/Target/BPF/BPFISelLowering.cpp @@ -78,6 +78,24 @@ BPFTargetLowering::BPFTargetLowering(const TargetMachine &TM, 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 @@ BPFTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 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: diff --git a/llvm/lib/Target/BPF/BPFISelLowering.h b/llvm/lib/Target/BPF/BPFISelLowering.h index eaad22831400..51e59f39036c 100644 --- a/llvm/lib/Target/BPF/BPFISelLowering.h +++ b/llvm/lib/Target/BPF/BPFISelLowering.h @@ -99,6 +99,9 @@ private: 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;