Skip to content

Commit 379d908

Browse files
committed
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
1 parent c578508 commit 379d908

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

llvm/lib/Target/BPF/BPFISelLowering.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,24 @@ BPFTargetLowering::BPFTargetLowering(const TargetMachine &TM,
7878
setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
7979
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
8080

81+
// Set unsupported atomic operations as Custom so
82+
// we can emit better error messages than fatal error
83+
// from selectiondag.
84+
for (auto VT : {MVT::i8, MVT::i16, MVT::i32}) {
85+
if (VT == MVT::i32) {
86+
if (STI.getHasAlu32())
87+
continue;
88+
} else {
89+
setOperationAction(ISD::ATOMIC_LOAD_ADD, VT, Custom);
90+
}
91+
92+
setOperationAction(ISD::ATOMIC_LOAD_AND, VT, Custom);
93+
setOperationAction(ISD::ATOMIC_LOAD_OR, VT, Custom);
94+
setOperationAction(ISD::ATOMIC_LOAD_XOR, VT, Custom);
95+
setOperationAction(ISD::ATOMIC_SWAP, VT, Custom);
96+
setOperationAction(ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS, VT, Custom);
97+
}
98+
8199
for (auto VT : { MVT::i32, MVT::i64 }) {
82100
if (VT == MVT::i32 && !STI.getHasAlu32())
83101
continue;
@@ -218,6 +236,30 @@ BPFTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
218236
return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
219237
}
220238

239+
void BPFTargetLowering::ReplaceNodeResults(
240+
SDNode *N, SmallVectorImpl<SDValue> &Results, SelectionDAG &DAG) const {
241+
const char *err_msg;
242+
uint32_t Opcode = N->getOpcode();
243+
switch (Opcode) {
244+
default:
245+
report_fatal_error("Unhandled custom legalization");
246+
case ISD::ATOMIC_LOAD_ADD:
247+
case ISD::ATOMIC_LOAD_AND:
248+
case ISD::ATOMIC_LOAD_OR:
249+
case ISD::ATOMIC_LOAD_XOR:
250+
case ISD::ATOMIC_SWAP:
251+
case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS:
252+
if (HasAlu32 || Opcode == ISD::ATOMIC_LOAD_ADD)
253+
err_msg = "Unsupported atomic operations, please use 32/64 bit version";
254+
else
255+
err_msg = "Unsupported atomic operations, please use 64 bit version";
256+
break;
257+
}
258+
259+
SDLoc DL(N);
260+
fail(DL, DAG, err_msg);
261+
}
262+
221263
SDValue BPFTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
222264
switch (Op.getOpcode()) {
223265
case ISD::BR_CC:

llvm/lib/Target/BPF/BPFISelLowering.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ class BPFTargetLowering : public TargetLowering {
9999
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
100100
SelectionDAG &DAG) const override;
101101

102+
void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
103+
SelectionDAG &DAG) const override;
104+
102105
EVT getOptimalMemOpType(const MemOp &Op,
103106
const AttributeList &FuncAttributes) const override {
104107
return Op.size() >= 8 ? MVT::i64 : MVT::i32;

0 commit comments

Comments
 (0)