[clang] [llvm] [BPF] Add load-acquire and store-release instructions under -mcpu=v5 (PR #108636)

Peilin Ye via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 20 22:09:49 PDT 2024


peilin-ye wrote:

@eddyz87,

Thanks!  I didn't know about `XXXISelLowering.cpp`.

> But there should be a way to tweak existing `fail` function to stop after errors are reported.

Can we `exit(1)` ? :-)

`fail()` calls `LLVMContext::diagnose()`, which already `exit(1)` when there's no "report handler", if "severity" is `DS_Error` :

```cpp
  if (DI.getSeverity() == DS_Error)
    exit(1);
}
```
`fail()` uses `DiagnosticInfoUnsupported`, whose "severity" \_is\_ `DS_Error`, but our "report handler" (`pImpl->DiagHandler->handleDiagnostics()`) doesn't call `exit()` ...
- - -
I tried, based on your diff (`__ATOMIC_ACQ_REL` is illegal for `__atomic_{load,store}{,_n}()`, so we only need to handle `AtomicOrdering::SequentiallyConsistent`) :

```diff
--- a/llvm/lib/Target/BPF/BPFISelLowering.cpp
+++ b/llvm/lib/Target/BPF/BPFISelLowering.cpp
@@ -93,6 +93,9 @@ BPFTargetLowering::BPFTargetLowering(const TargetMachine &TM,
     setOperationAction(ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS, VT, Custom);
   }
 
+  for (auto VT : {MVT::i8, MVT::i16, MVT::i32, MVT::i64})
+    setOperationAction(ISD::ATOMIC_LOAD, VT, Custom);
+
   for (auto VT : { MVT::i32, MVT::i64 }) {
     if (VT == MVT::i32 && !STI.getHasAlu32())
       continue;
@@ -291,6 +294,8 @@ void BPFTargetLowering::ReplaceNodeResults(
     else
       Msg = "unsupported atomic operation, please use 64 bit version";
     break;
+  case ISD::ATOMIC_LOAD:
+    return;
   }
 
   SDLoc DL(N);
@@ -316,6 +321,8 @@ SDValue BPFTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
     return LowerSDIVSREM(Op, DAG);
   case ISD::DYNAMIC_STACKALLOC:
     return LowerDYNAMIC_STACKALLOC(Op, DAG);
+  case ISD::ATOMIC_LOAD:
+    return LowerATOMIC_LOAD(Op, DAG);
   }
 }
 
@@ -703,6 +710,22 @@ SDValue BPFTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
   return DAG.getNode(BPFISD::SELECT_CC, DL, VTs, Ops);
 }
 
+SDValue BPFTargetLowering::LowerATOMIC_LOAD(SDValue Op,
+                                            SelectionDAG &DAG) const {
+  const char *Msg =
+      "sequentially consistent (seq_cst) atomic load is not supported";
+  SDNode *N = Op.getNode();
+  SDLoc DL(N);
+
+  if (cast<AtomicSDNode>(N)->getMergedOrdering() ==
+      AtomicOrdering::SequentiallyConsistent) {
+    fail(DL, DAG, Msg);
+    exit(1);
+  }
+
+  return Op;
+}
+
 const char *BPFTargetLowering::getTargetNodeName(unsigned Opcode) const {
   switch ((BPFISD::NodeType)Opcode) {
   case BPFISD::FIRST_NUMBER:
```
```diff
--- a/llvm/lib/Target/BPF/BPFISelLowering.h
+++ b/llvm/lib/Target/BPF/BPFISelLowering.h
@@ -77,7 +77,7 @@ private:
   SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
-
+  SDValue LowerATOMIC_LOAD(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
 
```
which seems to work nicely:
```
$ cat bar.c
char foo(char *ptr) { return __atomic_load_n(ptr, __ATOMIC_SEQ_CST); }
$
$ clang --target=bpf -mcpu=v5 -g bar.c > /dev/null
bar.c:1:6: error: sequentially consistent (seq_cst) atomic load is not supported
    1 | char foo(char *ptr) { return __atomic_load_n(ptr, __ATOMIC_SEQ_CST); }
      |      ^
$
```



https://github.com/llvm/llvm-project/pull/108636


More information about the cfe-commits mailing list