diff --git a/llvm/lib/Target/ARC/ARCISelLowering.cpp b/llvm/lib/Target/ARC/ARCISelLowering.cpp index 5d9a366f5ed54..fb1a42440498a 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 d4ae3255b32ab..4f612ae623b98 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(); } + 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 2fe86e75ddae8..4d8ace7c1ece0 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 ab0db576f7f72..7c83225c5d934 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 cbb5c2b998e27..7e6235942619c 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 039182b3ffe60..33479720183b4 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(); } + 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 ee7762c296bf5..9422bcca2299e 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 39e0658eb70dd..283de46e57d5c 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(); } + 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 e8f36bf50a1b0..de6de3214521e 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 0000000000000..678c1ae649c6a --- /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 0000000000000..187f0964d4fb8 --- /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 0000000000000..93307ac8184d0 --- /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 0000000000000..53b668ab25b56 --- /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 d4fd620592048..b65c281092dd7 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 +}