[llvm] Set MaxAtomicSizeInBitsSupported for remaining targets. (PR #75703)

James Y Knight via llvm-commits llvm-commits at lists.llvm.org
Sat Dec 16 08:00:39 PST 2023


https://github.com/jyknight created https://github.com/llvm/llvm-project/pull/75703

Targets affected:

- NVPTX and BPF: set to 64 bits.
- ARC, Lanai, and MSP430: set to 0 (they don't implement atomics).

Those which didn't yet add AtomicExpandPass to their pass pipeline now do so.

This will result in larger atomic operations getting expanded to `__atomic_*` libcalls via AtomicExpandPass. On all these targets, this now matches what Clang already does in the frontend.

The only targets which do not configure AtomicExpandPass now are:
- DirectX and SPIRV: they aren't normal backends.
- AVR: a single-cpu architecture with no privileged/user divide, which implements all atomics by disabling/enabling interrupts. Thus, typical constraints on size and alignment aren't necessary.

>From e98a5ff683ee35c8aba745f21dece22dc48beaaa Mon Sep 17 00:00:00 2001
From: James Y Knight <jyknight at google.com>
Date: Sat, 16 Dec 2023 10:55:49 -0500
Subject: [PATCH] Set MaxAtomicSizeInBitsSupported for remaining targets.

Targets affected:

- NVPTX and BPF: set to 64 bits.

- ARC, Lanai, and MSP430: set to 0 (they don't implement atomics).

Those which didn't yet add AtomicExpandPass to their pass pipeline now
do so.

This will result in larger atomic operations getting expanded to
`__atomic_*` libcalls via AtomicExpandPass. On all these targets, this
now matches what Clang already does in the frontend.

The only targets which do not configure AtomicExpandPass now are:

- DirectX and SPIRV: they aren't normal backends.

- AVR: a single-cpu architecture with no privileged/user divide, which
  implements all atomics by disabling/enabling interrupts. Thus,
  typical constraints on size and alignment aren't necessary.
---
 llvm/lib/Target/ARC/ARCISelLowering.cpp       |  2 +
 llvm/lib/Target/ARC/ARCTargetMachine.cpp      |  7 +++
 llvm/lib/Target/BPF/BPFISelLowering.cpp       |  1 +
 llvm/lib/Target/BPF/BPFTargetMachine.cpp      |  2 +
 llvm/lib/Target/Lanai/LanaiISelLowering.cpp   |  2 +
 llvm/lib/Target/Lanai/LanaiTargetMachine.cpp  |  7 +++
 llvm/lib/Target/MSP430/MSP430ISelLowering.cpp |  1 +
 .../lib/Target/MSP430/MSP430TargetMachine.cpp |  7 +++
 llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp   |  1 +
 llvm/test/CodeGen/ARC/atomic-oversize.ll      | 11 +++++
 llvm/test/CodeGen/BPF/atomic-oversize.ll      | 12 +++++
 llvm/test/CodeGen/Lanai/atomic-oversize.ll    | 11 +++++
 llvm/test/CodeGen/MSP430/atomic-oversize.ll   | 11 +++++
 llvm/test/CodeGen/NVPTX/atomicrmw-expand.ll   | 48 ++++++++++---------
 14 files changed, 101 insertions(+), 22 deletions(-)
 create mode 100644 llvm/test/CodeGen/ARC/atomic-oversize.ll
 create mode 100644 llvm/test/CodeGen/BPF/atomic-oversize.ll
 create mode 100644 llvm/test/CodeGen/Lanai/atomic-oversize.ll
 create mode 100644 llvm/test/CodeGen/MSP430/atomic-oversize.ll

diff --git a/llvm/lib/Target/ARC/ARCISelLowering.cpp b/llvm/lib/Target/ARC/ARCISelLowering.cpp
index 5d9a366f5ed540..fb1a42440498a1 100644
--- a/llvm/lib/Target/ARC/ARCISelLowering.cpp
+++ b/llvm/lib/Target/ARC/ARCISelLowering.cpp
@@ -174,6 +174,8 @@ ARCTargetLowering::ARCTargetLowering(const TargetMachine &TM,
   setOperationAction(ISD::READCYCLECOUNTER, MVT::i32, Legal);
   setOperationAction(ISD::READCYCLECOUNTER, MVT::i64,
                      isTypeLegal(MVT::i64) ? Legal : Custom);
+
+  setMaxAtomicSizeInBitsSupported(0);
 }
 
 const char *ARCTargetLowering::getTargetNodeName(unsigned Opcode) const {
diff --git a/llvm/lib/Target/ARC/ARCTargetMachine.cpp b/llvm/lib/Target/ARC/ARCTargetMachine.cpp
index d4ae3255b32abf..4f612ae623b986 100644
--- a/llvm/lib/Target/ARC/ARCTargetMachine.cpp
+++ b/llvm/lib/Target/ARC/ARCTargetMachine.cpp
@@ -57,6 +57,7 @@ class ARCPassConfig : public TargetPassConfig {
     return getTM<ARCTargetMachine>();
   }
 
+  void addIRPasses() override;
   bool addInstSelector() override;
   void addPreEmitPass() override;
   void addPreRegAlloc() override;
@@ -68,6 +69,12 @@ TargetPassConfig *ARCTargetMachine::createPassConfig(PassManagerBase &PM) {
   return new ARCPassConfig(*this, PM);
 }
 
+void ARCPassConfig::addIRPasses() {
+  addPass(createAtomicExpandPass());
+
+  TargetPassConfig::addIRPasses();
+}
+
 bool ARCPassConfig::addInstSelector() {
   addPass(createARCISelDag(getARCTargetMachine(), getOptLevel()));
   return false;
diff --git a/llvm/lib/Target/BPF/BPFISelLowering.cpp b/llvm/lib/Target/BPF/BPFISelLowering.cpp
index 2fe86e75ddae8f..4d8ace7c1ece02 100644
--- a/llvm/lib/Target/BPF/BPFISelLowering.cpp
+++ b/llvm/lib/Target/BPF/BPFISelLowering.cpp
@@ -151,6 +151,7 @@ BPFTargetLowering::BPFTargetLowering(const TargetMachine &TM,
   }
 
   setBooleanContents(ZeroOrOneBooleanContent);
+  setMaxAtomicSizeInBitsSupported(64);
 
   // Function alignments
   setMinFunctionAlignment(Align(8));
diff --git a/llvm/lib/Target/BPF/BPFTargetMachine.cpp b/llvm/lib/Target/BPF/BPFTargetMachine.cpp
index ab0db576f7f72d..7c83225c5d9345 100644
--- a/llvm/lib/Target/BPF/BPFTargetMachine.cpp
+++ b/llvm/lib/Target/BPF/BPFTargetMachine.cpp
@@ -148,7 +148,9 @@ void BPFTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
 }
 
 void BPFPassConfig::addIRPasses() {
+  addPass(createAtomicExpandPass());
   addPass(createBPFCheckAndAdjustIR());
+
   TargetPassConfig::addIRPasses();
 }
 
diff --git a/llvm/lib/Target/Lanai/LanaiISelLowering.cpp b/llvm/lib/Target/Lanai/LanaiISelLowering.cpp
index cbb5c2b998e27a..7e6235942619cf 100644
--- a/llvm/lib/Target/Lanai/LanaiISelLowering.cpp
+++ b/llvm/lib/Target/Lanai/LanaiISelLowering.cpp
@@ -166,6 +166,8 @@ LanaiTargetLowering::LanaiTargetLowering(const TargetMachine &TM,
 
   // Booleans always contain 0 or 1.
   setBooleanContents(ZeroOrOneBooleanContent);
+
+  setMaxAtomicSizeInBitsSupported(0);
 }
 
 SDValue LanaiTargetLowering::LowerOperation(SDValue Op,
diff --git a/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp b/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp
index 039182b3ffe60b..33479720183b43 100644
--- a/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp
+++ b/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp
@@ -93,6 +93,7 @@ class LanaiPassConfig : public TargetPassConfig {
     return getTM<LanaiTargetMachine>();
   }
 
+  void addIRPasses() override;
   bool addInstSelector() override;
   void addPreSched2() override;
   void addPreEmitPass() override;
@@ -104,6 +105,12 @@ LanaiTargetMachine::createPassConfig(PassManagerBase &PassManager) {
   return new LanaiPassConfig(*this, &PassManager);
 }
 
+void LanaiPassConfig::addIRPasses() {
+  addPass(createAtomicExpandPass());
+
+  TargetPassConfig::addIRPasses();
+}
+
 // Install an instruction selector pass.
 bool LanaiPassConfig::addInstSelector() {
   addPass(createLanaiISelDag(getLanaiTargetMachine()));
diff --git a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
index ee7762c296bf50..9422bcca2299ed 100644
--- a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
+++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
@@ -333,6 +333,7 @@ MSP430TargetLowering::MSP430TargetLowering(const TargetMachine &TM,
 
   setMinFunctionAlignment(Align(2));
   setPrefFunctionAlignment(Align(2));
+  setMaxAtomicSizeInBitsSupported(0);
 }
 
 SDValue MSP430TargetLowering::LowerOperation(SDValue Op,
diff --git a/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp b/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp
index 39e0658eb70dd5..283de46e57d5c4 100644
--- a/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp
+++ b/llvm/lib/Target/MSP430/MSP430TargetMachine.cpp
@@ -65,6 +65,7 @@ class MSP430PassConfig : public TargetPassConfig {
     return getTM<MSP430TargetMachine>();
   }
 
+  void addIRPasses() override;
   bool addInstSelector() override;
   void addPreEmitPass() override;
 };
@@ -81,6 +82,12 @@ MachineFunctionInfo *MSP430TargetMachine::createMachineFunctionInfo(
                                                                       F, STI);
 }
 
+void MSP430PassConfig::addIRPasses() {
+  addPass(createAtomicExpandPass());
+
+  TargetPassConfig::addIRPasses();
+}
+
 bool MSP430PassConfig::addInstSelector() {
   // Install an instruction selector.
   addPass(createMSP430ISelDag(getMSP430TargetMachine(), getOptLevel()));
diff --git a/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp b/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
index e8f36bf50a1b08..de6de3214521e2 100644
--- a/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
@@ -854,6 +854,7 @@ NVPTXTargetLowering::NVPTXTargetLowering(const NVPTXTargetMachine &TM,
   computeRegisterProperties(STI.getRegisterInfo());
 
   setMinCmpXchgSizeInBits(32);
+  setMaxAtomicSizeInBitsSupported(64);
 }
 
 const char *NVPTXTargetLowering::getTargetNodeName(unsigned Opcode) const {
diff --git a/llvm/test/CodeGen/ARC/atomic-oversize.ll b/llvm/test/CodeGen/ARC/atomic-oversize.ll
new file mode 100644
index 00000000000000..678c1ae649c6a8
--- /dev/null
+++ b/llvm/test/CodeGen/ARC/atomic-oversize.ll
@@ -0,0 +1,11 @@
+; RUN: llc -mtriple=arc < %s | FileCheck %s
+
+; Native atomics are unsupported, so all are oversize.
+define void @test(ptr %a) nounwind {
+; CHECK-LABEL: test:
+; CHECK: bl @__atomic_load_1
+; CHECK: bl @__atomic_store_1
+  %1 = load atomic i8, ptr %a seq_cst, align 16
+  store atomic i8 %1, ptr %a seq_cst, align 16
+  ret void
+}
diff --git a/llvm/test/CodeGen/BPF/atomic-oversize.ll b/llvm/test/CodeGen/BPF/atomic-oversize.ll
new file mode 100644
index 00000000000000..187f0964d4fb83
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/atomic-oversize.ll
@@ -0,0 +1,12 @@
+; RUN: llc -mtriple=bpf < %s | FileCheck %s
+; XFAIL: *
+; Doesn't currently build, with error 'only small returns supported'.
+
+define void @test(ptr %a) nounwind {
+; CHECK-LABEL: test:
+; CHECK: call __atomic_load_16
+; CHECK: call __atomic_store_16
+  %1 = load atomic i128, ptr %a monotonic, align 16
+  store atomic i128 %1, ptr %a monotonic, align 16
+  ret void
+}
diff --git a/llvm/test/CodeGen/Lanai/atomic-oversize.ll b/llvm/test/CodeGen/Lanai/atomic-oversize.ll
new file mode 100644
index 00000000000000..93307ac8184d08
--- /dev/null
+++ b/llvm/test/CodeGen/Lanai/atomic-oversize.ll
@@ -0,0 +1,11 @@
+; RUN: llc -mtriple=lanai < %s | FileCheck %s
+
+; Native atomics are unsupported, so all are oversize.
+define void @test(ptr %a) nounwind {
+; CHECK-LABEL: test:
+; CHECK: bt __atomic_load_1
+; CHECK: bt __atomic_store_1
+  %1 = load atomic i8, ptr %a monotonic, align 16
+  store atomic i8 %1, ptr %a monotonic, align 16
+  ret void
+}
diff --git a/llvm/test/CodeGen/MSP430/atomic-oversize.ll b/llvm/test/CodeGen/MSP430/atomic-oversize.ll
new file mode 100644
index 00000000000000..53b668ab25b569
--- /dev/null
+++ b/llvm/test/CodeGen/MSP430/atomic-oversize.ll
@@ -0,0 +1,11 @@
+; RUN: llc -mtriple=msp430 < %s | FileCheck %s
+
+; Native atomics are unsupported, so all are oversize.
+define void @test(ptr %a) nounwind {
+; CHECK-LABEL: test:
+; CHECK: call #__atomic_load_1
+; CHECK: call #__atomic_store_1
+  %1 = load atomic i8, ptr %a monotonic, align 16
+  store atomic i8 %1, ptr %a monotonic, align 16
+  ret void
+}
diff --git a/llvm/test/CodeGen/NVPTX/atomicrmw-expand.ll b/llvm/test/CodeGen/NVPTX/atomicrmw-expand.ll
index d4fd620592048c..b65c281092dd72 100644
--- a/llvm/test/CodeGen/NVPTX/atomicrmw-expand.ll
+++ b/llvm/test/CodeGen/NVPTX/atomicrmw-expand.ll
@@ -140,26 +140,30 @@ entry:
   ret void
 }
 
-; TODO: We might still want to test other types, such as i128. Currently the
-; backend doesn't support them. Atomic expand only supports expansion to cas of
-; the same bitwidth, which means even after expansion, the back end still
-; doesn't support the instruction. Here we still put the tests. Remove the
-; comment once we have proper support, either from atomic expand or backend.
-
-; define void @bitwise_i128(ptr %0, i128 %1) {
-; entry:
-;   %2 = atomicrmw and ptr %0, i128 %1 monotonic, align 16
-;   %3 = atomicrmw or ptr %0, i128 %1 monotonic, align 16
-;   %4 = atomicrmw xor ptr %0, i128 %1 monotonic, align 16
-;   %5 = atomicrmw xchg ptr %0, i128 %1 monotonic, align 16
-;   ret void
-; }
+; CHECK-LABEL: bitwise_i128
+define void @bitwise_i128(ptr %0, i128 %1) {
+entry:
+  ; ALL: __atomic_fetch_and_16
+  %2 = atomicrmw and ptr %0, i128 %1 monotonic, align 16
+  ; ALL: __atomic_fetch_or_16
+  %3 = atomicrmw or ptr %0, i128 %1 monotonic, align 16
+  ; ALL: __atomic_fetch_xor_16
+  %4 = atomicrmw xor ptr %0, i128 %1 monotonic, align 16
+  ; ALL: __atomic_exchange_16
+  %5 = atomicrmw xchg ptr %0, i128 %1 monotonic, align 16
+  ret void
+}
 
-; define void @minmax_i128(ptr %0, i128 %1) {
-; entry:
-;   %2 = atomicrmw min ptr %0, i128 %1 monotonic, align 16
-;   %3 = atomicrmw max ptr %0, i128 %1 monotonic, align 16
-;   %4 = atomicrmw umin ptr %0, i128 %1 monotonic, align 16
-;   %5 = atomicrmw umax ptr %0, i128 %1 monotonic, align 16
-;   ret void
-; }
+; CHECK-LABEL: minmax_i128
+define void @minmax_i128(ptr %0, i128 %1) {
+entry:
+  ; ALL: __atomic_compare_exchange_16
+  %2 = atomicrmw min ptr %0, i128 %1 monotonic, align 16
+  ; ALL: __atomic_compare_exchange_16
+  %3 = atomicrmw max ptr %0, i128 %1 monotonic, align 16
+  ; ALL: __atomic_compare_exchange_16
+  %4 = atomicrmw umin ptr %0, i128 %1 monotonic, align 16
+  ; ALL: __atomic_compare_exchange_16
+  %5 = atomicrmw umax ptr %0, i128 %1 monotonic, align 16
+  ret void
+}



More information about the llvm-commits mailing list