Author: Bidhan Date: 2026-06-10T17:46:45Z New Revision: 761b9134dd9beda6f133fdc19a42b148834cb06b
URL: https://github.com/llvm/llvm-project/commit/761b9134dd9beda6f133fdc19a42b148834cb06b DIFF: https://github.com/llvm/llvm-project/commit/761b9134dd9beda6f133fdc19a42b148834cb06b.diff LOG: [BPF] treat compiler fence as codegen no-op (#196734) The BPF backend has no instruction-selection pattern for `ISD::ATOMIC_FENCE`, so LLVM IR containing a fence instruction crashes with `Cannot select: AtomicFence...`. **Rust code snippet** ``` #[unsafe(no_mangle)] pub fn entrypoint(_input: *mut u8) -> u64 { core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst); 0 } ``` **LLVM IR** ``` ; ModuleID = 'linked_module' source_filename = "linked_module" target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128" target triple = "bpfel" ; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn define dso_local noundef i64 @entrypoint(ptr noundef readnone captures(none) %0) unnamed_addr #0 { fence syncscope("singlethread") seq_cst ret i64 0 } attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn "target-cpu"="generic" } !llvm.ident = !{!0} !0 = !{!"rustc version 1.97.0-nightly (f53b654a8 2026-04-30)"} ``` **Error** ``` LLVM ERROR: Cannot select: 0x7fcf7701a1c0: ch = AtomicFence 0x7fcf75718df8, TargetConstant:i64<7>, TargetConstant:i64<0> In function: entrypoint Stack dump: 0. Running pass 'Function Pass Manager' on module 'linked_module'. 1. Running pass 'BPF DAG->DAG Pattern Instruction Selection' on function '@entrypoint' ``` ----- **Fix** This patch lowers single-thread (compiler) fences to `ISD::MEMBARRIER` (no-op) and produces an error for cross-thread (runtime) fences. Added: llvm/test/CodeGen/BPF/fence-singlethread.ll Modified: llvm/lib/Target/BPF/BPFISelLowering.cpp llvm/lib/Target/BPF/BPFISelLowering.h Removed: ################################################################################ diff --git a/llvm/lib/Target/BPF/BPFISelLowering.cpp b/llvm/lib/Target/BPF/BPFISelLowering.cpp index 5c03776dd6653..faf3af0918d54 100644 --- a/llvm/lib/Target/BPF/BPFISelLowering.cpp +++ b/llvm/lib/Target/BPF/BPFISelLowering.cpp @@ -110,6 +110,8 @@ BPFTargetLowering::BPFTargetLowering(const TargetMachine &TM, setOperationAction(ISD::ATOMIC_STORE, VT, Custom); } + setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom); + for (auto VT : { MVT::i32, MVT::i64 }) { if (VT == MVT::i32 && !STI.getHasAlu32()) continue; @@ -368,6 +370,8 @@ SDValue BPFTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { case ISD::ATOMIC_LOAD: case ISD::ATOMIC_STORE: return LowerATOMIC_LOAD_STORE(Op, DAG); + case ISD::ATOMIC_FENCE: + return LowerATOMIC_FENCE(Op, DAG); case ISD::TRAP: return LowerTRAP(Op, DAG); } @@ -772,6 +776,19 @@ SDValue BPFTargetLowering::LowerATOMIC_LOAD_STORE(SDValue Op, return Op; } +SDValue BPFTargetLowering::LowerATOMIC_FENCE(SDValue Op, + SelectionDAG &DAG) const { + SDLoc DL(Op); + SyncScope::ID FenceSSID = + static_cast<SyncScope::ID>(Op.getConstantOperandVal(2)); + + if (FenceSSID == SyncScope::SingleThread) + // MEMBARRIER is a compiler barrier; it codegens to a no-op. + return DAG.getNode(ISD::MEMBARRIER, DL, MVT::Other, Op.getOperand(0)); + + report_fatal_error("Runtime fence is not supported at the moment"); +} + static Function *createBPFUnreachable(Module *M) { if (auto *Fn = M->getFunction(BPF_TRAP)) return Fn; diff --git a/llvm/lib/Target/BPF/BPFISelLowering.h b/llvm/lib/Target/BPF/BPFISelLowering.h index 8607e4f8c9e69..df1e2d8114ae1 100644 --- a/llvm/lib/Target/BPF/BPFISelLowering.h +++ b/llvm/lib/Target/BPF/BPFISelLowering.h @@ -73,6 +73,7 @@ class BPFTargetLowering : public TargetLowering { SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const; SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; SDValue LowerATOMIC_LOAD_STORE(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const; SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; SDValue LowerTRAP(SDValue Op, SelectionDAG &DAG) const; diff --git a/llvm/test/CodeGen/BPF/fence-singlethread.ll b/llvm/test/CodeGen/BPF/fence-singlethread.ll new file mode 100644 index 0000000000000..91ea38db8b8c8 --- /dev/null +++ b/llvm/test/CodeGen/BPF/fence-singlethread.ll @@ -0,0 +1,14 @@ +; RUN: llc < %s -mtriple=bpfel | FileCheck %s +; RUN: llc < %s -mtriple=bpfeb | FileCheck %s + +; CHECK-LABEL: fence_singlethread: +; CHECK-COUNT-4: #MEMBARRIER +; CHECK-NEXT: exit +define void @fence_singlethread() nounwind { +entry: + fence syncscope("singlethread") acquire + fence syncscope("singlethread") release + fence syncscope("singlethread") acq_rel + fence syncscope("singlethread") seq_cst + ret void +} _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
