[llvm] [SystemZ] Simplify handling of AtomicRMW instructions. (PR #74789)
Jonas Paulsson via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 7 16:22:35 PST 2023
https://github.com/JonPsson1 created https://github.com/llvm/llvm-project/pull/74789
Let the AtomicExpand pass do more of the job of expanding AtomicRMWInst:s in order to simplify the handling in the backend.
The only cases that the backend needs to handle itself are those of subword size (8/16 bits) and those directly corresponding to a target instruction.
Tests updated with some codegen changes for z10 that are hopefully ok. The min/max and nand tests are not run for later cpus and should also be relevant for them. One thing noted is that the IfConverter now fails to produce a CondReturn in the min/max tests. Some tests that seemed to test different immediate instructions now get a different codegen which should be correct,
even though perhaps some of the testing done is now redundant.
>From 47f96cbeb2c2c654ae790c31b3db92d9dc64f863 Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <paulson1 at linux.ibm.com>
Date: Thu, 7 Dec 2023 17:20:17 -0600
Subject: [PATCH] First attempt
---
.../Target/SystemZ/SystemZISelLowering.cpp | 408 +++++-------------
llvm/lib/Target/SystemZ/SystemZISelLowering.h | 5 +-
.../lib/Target/SystemZ/SystemZInstrFormats.td | 24 --
llvm/lib/Target/SystemZ/SystemZInstrInfo.td | 83 ----
llvm/test/CodeGen/SystemZ/atomicrmw-add-04.ll | 61 +--
llvm/test/CodeGen/SystemZ/atomicrmw-and-03.ll | 2 +-
llvm/test/CodeGen/SystemZ/atomicrmw-and-04.ll | 9 +-
.../CodeGen/SystemZ/atomicrmw-minmax-03.ll | 304 +++++++++----
.../CodeGen/SystemZ/atomicrmw-minmax-04.ll | 245 ++++++++---
.../test/CodeGen/SystemZ/atomicrmw-nand-03.ll | 22 +-
.../test/CodeGen/SystemZ/atomicrmw-nand-04.ll | 94 ++--
llvm/test/CodeGen/SystemZ/atomicrmw-or-04.ll | 11 +-
llvm/test/CodeGen/SystemZ/atomicrmw-sub-04.ll | 61 +--
.../test/CodeGen/SystemZ/atomicrmw-xchg-03.ll | 2 +-
.../test/CodeGen/SystemZ/atomicrmw-xchg-04.ll | 2 +-
llvm/test/CodeGen/SystemZ/atomicrmw-xor-04.ll | 9 +-
16 files changed, 646 insertions(+), 696 deletions(-)
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index 873994c2e333b..454791a77cd2a 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -872,13 +872,21 @@ bool SystemZTargetLowering::hasInlineStackProbe(const MachineFunction &MF) const
TargetLowering::AtomicExpansionKind
SystemZTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const {
- // TODO: expand them all here instead of in backend.
- return (RMW->isFloatingPointOperation() ||
- RMW->getOperation() == AtomicRMWInst::UIncWrap ||
- RMW->getOperation() == AtomicRMWInst::UDecWrap ||
- RMW->getType()->isIntegerTy(128))
- ? AtomicExpansionKind::CmpXChg
- : AtomicExpansionKind::None;
+ // Don't expand subword operations as they require special treatment.
+ if (RMW->getType()->isIntegerTy(8) || RMW->getType()->isIntegerTy(16))
+ return AtomicExpansionKind::None;
+
+ // Don't expand if there is a target instruction available.
+ if (Subtarget.hasInterlockedAccess1() &&
+ (RMW->getType()->isIntegerTy(32) || RMW->getType()->isIntegerTy(64)) &&
+ (RMW->getOperation() == AtomicRMWInst::BinOp::Add ||
+ RMW->getOperation() == AtomicRMWInst::BinOp::Sub ||
+ RMW->getOperation() == AtomicRMWInst::BinOp::And ||
+ RMW->getOperation() == AtomicRMWInst::BinOp::Or ||
+ RMW->getOperation() == AtomicRMWInst::BinOp::Xor))
+ return AtomicExpansionKind::None;
+
+ return AtomicExpansionKind::CmpXChg;
}
bool SystemZTargetLowering::isLegalICmpImmediate(int64_t Imm) const {
@@ -4350,6 +4358,31 @@ SDValue SystemZTargetLowering::lowerATOMIC_STORE(SDValue Op,
return Chain;
}
+// Prepare for a Compare And Swap for a subword operation. This needs to be
+// done in memory with 4 bytes at natural alignment.
+static void getCSAddressAndShifts(SDValue Addr, SelectionDAG &DAG, SDLoc DL,
+ SDValue &AlignedAddr, SDValue &BitShift,
+ SDValue &NegBitShift) {
+ EVT PtrVT = Addr.getValueType();
+ EVT WideVT = MVT::i32;
+
+ // Get the address of the containing word.
+ AlignedAddr = DAG.getNode(ISD::AND, DL, PtrVT, Addr,
+ DAG.getConstant(-4, DL, PtrVT));
+
+ // Get the number of bits that the word must be rotated left in order
+ // to bring the field to the top bits of a GR32.
+ BitShift = DAG.getNode(ISD::SHL, DL, PtrVT, Addr,
+ DAG.getConstant(3, DL, PtrVT));
+ BitShift = DAG.getNode(ISD::TRUNCATE, DL, WideVT, BitShift);
+
+ // Get the complementing shift amount, for rotating a field in the top
+ // bits back to its proper position.
+ NegBitShift = DAG.getNode(ISD::SUB, DL, WideVT,
+ DAG.getConstant(0, DL, WideVT), BitShift);
+
+}
+
// Op is an 8-, 16-bit or 32-bit ATOMIC_LOAD_* operation. Lower the first
// two into the fullword ATOMIC_LOADW_* operation given by Opcode.
SDValue SystemZTargetLowering::lowerATOMIC_LOAD_OP(SDValue Op,
@@ -4357,7 +4390,7 @@ SDValue SystemZTargetLowering::lowerATOMIC_LOAD_OP(SDValue Op,
unsigned Opcode) const {
auto *Node = cast<AtomicSDNode>(Op.getNode());
- // 32-bit operations need no code outside the main loop.
+ // 32-bit operations need no special handling.
EVT NarrowVT = Node->getMemoryVT();
EVT WideVT = MVT::i32;
if (NarrowVT == WideVT)
@@ -4369,7 +4402,6 @@ SDValue SystemZTargetLowering::lowerATOMIC_LOAD_OP(SDValue Op,
SDValue Src2 = Node->getVal();
MachineMemOperand *MMO = Node->getMemOperand();
SDLoc DL(Node);
- EVT PtrVT = Addr.getValueType();
// Convert atomic subtracts of constants into additions.
if (Opcode == SystemZISD::ATOMIC_LOADW_SUB)
@@ -4378,20 +4410,8 @@ SDValue SystemZTargetLowering::lowerATOMIC_LOAD_OP(SDValue Op,
Src2 = DAG.getConstant(-Const->getSExtValue(), DL, Src2.getValueType());
}
- // Get the address of the containing word.
- SDValue AlignedAddr = DAG.getNode(ISD::AND, DL, PtrVT, Addr,
- DAG.getConstant(-4, DL, PtrVT));
-
- // Get the number of bits that the word must be rotated left in order
- // to bring the field to the top bits of a GR32.
- SDValue BitShift = DAG.getNode(ISD::SHL, DL, PtrVT, Addr,
- DAG.getConstant(3, DL, PtrVT));
- BitShift = DAG.getNode(ISD::TRUNCATE, DL, WideVT, BitShift);
-
- // Get the complementing shift amount, for rotating a field in the top
- // bits back to its proper position.
- SDValue NegBitShift = DAG.getNode(ISD::SUB, DL, WideVT,
- DAG.getConstant(0, DL, WideVT), BitShift);
+ SDValue AlignedAddr, BitShift, NegBitShift;
+ getCSAddressAndShifts(Addr, DAG, DL, AlignedAddr, BitShift, NegBitShift);
// Extend the source operand to 32 bits and prepare it for the inner loop.
// ATOMIC_SWAPW uses RISBG to rotate the field left, but all other
@@ -4423,38 +4443,24 @@ SDValue SystemZTargetLowering::lowerATOMIC_LOAD_OP(SDValue Op,
return DAG.getMergeValues(RetOps, DL);
}
-// Op is an ATOMIC_LOAD_SUB operation. Lower 8- and 16-bit operations
-// into ATOMIC_LOADW_SUBs and decide whether to convert 32- and 64-bit
-// operations into additions.
+// Op is an ATOMIC_LOAD_SUB operation. Lower 8- and 16-bit operations into
+// ATOMIC_LOADW_SUBs and convert 32- and 64-bit operations into additions.
SDValue SystemZTargetLowering::lowerATOMIC_LOAD_SUB(SDValue Op,
SelectionDAG &DAG) const {
auto *Node = cast<AtomicSDNode>(Op.getNode());
EVT MemVT = Node->getMemoryVT();
if (MemVT == MVT::i32 || MemVT == MVT::i64) {
- // A full-width operation.
+ // A full-width operation: negate and use LAA(G).
assert(Op.getValueType() == MemVT && "Mismatched VTs");
+ assert(Subtarget.hasInterlockedAccess1() &&
+ "Should have been expanded by AtomicExpand pass.");
SDValue Src2 = Node->getVal();
- SDValue NegSrc2;
SDLoc DL(Src2);
-
- if (auto *Op2 = dyn_cast<ConstantSDNode>(Src2)) {
- // Use an addition if the operand is constant and either LAA(G) is
- // available or the negative value is in the range of A(G)FHI.
- int64_t Value = (-Op2->getAPIntValue()).getSExtValue();
- if (isInt<32>(Value) || Subtarget.hasInterlockedAccess1())
- NegSrc2 = DAG.getConstant(Value, DL, MemVT);
- } else if (Subtarget.hasInterlockedAccess1())
- // Use LAA(G) if available.
- NegSrc2 = DAG.getNode(ISD::SUB, DL, MemVT, DAG.getConstant(0, DL, MemVT),
- Src2);
-
- if (NegSrc2.getNode())
- return DAG.getAtomic(ISD::ATOMIC_LOAD_ADD, DL, MemVT,
- Node->getChain(), Node->getBasePtr(), NegSrc2,
- Node->getMemOperand());
-
- // Use the node as-is.
- return Op;
+ SDValue NegSrc2 =
+ DAG.getNode(ISD::SUB, DL, MemVT, DAG.getConstant(0, DL, MemVT), Src2);
+ return DAG.getAtomic(ISD::ATOMIC_LOAD_ADD, DL, MemVT,
+ Node->getChain(), Node->getBasePtr(), NegSrc2,
+ Node->getMemOperand());
}
return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_LOADW_SUB);
@@ -4492,22 +4498,9 @@ SDValue SystemZTargetLowering::lowerATOMIC_CMP_SWAP(SDValue Op,
// Convert 8-bit and 16-bit compare and swap to a loop, implemented
// via a fullword ATOMIC_CMP_SWAPW operation.
int64_t BitSize = NarrowVT.getSizeInBits();
- EVT PtrVT = Addr.getValueType();
-
- // Get the address of the containing word.
- SDValue AlignedAddr = DAG.getNode(ISD::AND, DL, PtrVT, Addr,
- DAG.getConstant(-4, DL, PtrVT));
- // Get the number of bits that the word must be rotated left in order
- // to bring the field to the top bits of a GR32.
- SDValue BitShift = DAG.getNode(ISD::SHL, DL, PtrVT, Addr,
- DAG.getConstant(3, DL, PtrVT));
- BitShift = DAG.getNode(ISD::TRUNCATE, DL, WideVT, BitShift);
-
- // Get the complementing shift amount, for rotating a field in the top
- // bits back to its proper position.
- SDValue NegBitShift = DAG.getNode(ISD::SUB, DL, WideVT,
- DAG.getConstant(0, DL, WideVT), BitShift);
+ SDValue AlignedAddr, BitShift, NegBitShift;
+ getCSAddressAndShifts(Addr, DAG, DL, AlignedAddr, BitShift, NegBitShift);
// Construct the ATOMIC_CMP_SWAPW node.
SDVTList VTList = DAG.getVTList(WideVT, MVT::i32, MVT::Other);
@@ -7951,20 +7944,17 @@ MachineBasicBlock *SystemZTargetLowering::emitCondStore(MachineInstr &MI,
return JoinMBB;
}
-// Implement EmitInstrWithCustomInserter for pseudo ATOMIC_LOAD{,W}_*
-// or ATOMIC_SWAP{,W} instruction MI. BinOpcode is the instruction that
-// performs the binary operation elided by "*", or 0 for ATOMIC_SWAP{,W}.
-// BitSize is the width of the field in bits, or 0 if this is a partword
-// ATOMIC_LOADW_* or ATOMIC_SWAPW instruction, in which case the bitsize
-// is one of the operands. Invert says whether the field should be
-// inverted after performing BinOpcode (e.g. for NAND).
+// Implement EmitInstrWithCustomInserter for subword pseudo ATOMIC_LOADW_* or
+// ATOMIC_SWAPW instruction MI. BinOpcode is the instruction that performs
+// the binary operation elided by "*", or 0 for ATOMIC_SWAPW. Invert says
+// whether the field should be inverted after performing BinOpcode (e.g. for
+// NAND).
MachineBasicBlock *SystemZTargetLowering::emitAtomicLoadBinary(
MachineInstr &MI, MachineBasicBlock *MBB, unsigned BinOpcode,
- unsigned BitSize, bool Invert) const {
+ bool Invert) const {
MachineFunction &MF = *MBB->getParent();
const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
MachineRegisterInfo &MRI = MF.getRegInfo();
- bool IsSubWord = (BitSize < 32);
// Extract the operands. Base can be a register or a frame index.
// Src2 can be a register or immediate.
@@ -7972,31 +7962,22 @@ MachineBasicBlock *SystemZTargetLowering::emitAtomicLoadBinary(
MachineOperand Base = earlyUseOperand(MI.getOperand(1));
int64_t Disp = MI.getOperand(2).getImm();
MachineOperand Src2 = earlyUseOperand(MI.getOperand(3));
- Register BitShift = IsSubWord ? MI.getOperand(4).getReg() : Register();
- Register NegBitShift = IsSubWord ? MI.getOperand(5).getReg() : Register();
+ Register BitShift = MI.getOperand(4).getReg();
+ Register NegBitShift = MI.getOperand(5).getReg();
+ unsigned BitSize = MI.getOperand(6).getImm();
DebugLoc DL = MI.getDebugLoc();
- if (IsSubWord)
- BitSize = MI.getOperand(6).getImm();
-
- // Subword operations use 32-bit registers.
- const TargetRegisterClass *RC = (BitSize <= 32 ?
- &SystemZ::GR32BitRegClass :
- &SystemZ::GR64BitRegClass);
- unsigned LOpcode = BitSize <= 32 ? SystemZ::L : SystemZ::LG;
- unsigned CSOpcode = BitSize <= 32 ? SystemZ::CS : SystemZ::CSG;
// Get the right opcodes for the displacement.
- LOpcode = TII->getOpcodeForOffset(LOpcode, Disp);
- CSOpcode = TII->getOpcodeForOffset(CSOpcode, Disp);
+ unsigned LOpcode = TII->getOpcodeForOffset(SystemZ::L, Disp);
+ unsigned CSOpcode = TII->getOpcodeForOffset(SystemZ::CS, Disp);
assert(LOpcode && CSOpcode && "Displacement out of range");
// Create virtual registers for temporary results.
- Register OrigVal = MRI.createVirtualRegister(RC);
- Register OldVal = MRI.createVirtualRegister(RC);
- Register NewVal = (BinOpcode || IsSubWord ?
- MRI.createVirtualRegister(RC) : Src2.getReg());
- Register RotatedOldVal = (IsSubWord ? MRI.createVirtualRegister(RC) : OldVal);
- Register RotatedNewVal = (IsSubWord ? MRI.createVirtualRegister(RC) : NewVal);
+ Register OrigVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
+ Register OldVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
+ Register NewVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
+ Register RotatedOldVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
+ Register RotatedNewVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
// Insert a basic block for the main loop.
MachineBasicBlock *StartMBB = MBB;
@@ -8023,39 +8004,28 @@ MachineBasicBlock *SystemZTargetLowering::emitAtomicLoadBinary(
BuildMI(MBB, DL, TII->get(SystemZ::PHI), OldVal)
.addReg(OrigVal).addMBB(StartMBB)
.addReg(Dest).addMBB(LoopMBB);
- if (IsSubWord)
- BuildMI(MBB, DL, TII->get(SystemZ::RLL), RotatedOldVal)
- .addReg(OldVal).addReg(BitShift).addImm(0);
+ BuildMI(MBB, DL, TII->get(SystemZ::RLL), RotatedOldVal)
+ .addReg(OldVal).addReg(BitShift).addImm(0);
if (Invert) {
// Perform the operation normally and then invert every bit of the field.
- Register Tmp = MRI.createVirtualRegister(RC);
+ Register Tmp = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
BuildMI(MBB, DL, TII->get(BinOpcode), Tmp).addReg(RotatedOldVal).add(Src2);
- if (BitSize <= 32)
- // XILF with the upper BitSize bits set.
- BuildMI(MBB, DL, TII->get(SystemZ::XILF), RotatedNewVal)
- .addReg(Tmp).addImm(-1U << (32 - BitSize));
- else {
- // Use LCGR and add -1 to the result, which is more compact than
- // an XILF, XILH pair.
- Register Tmp2 = MRI.createVirtualRegister(RC);
- BuildMI(MBB, DL, TII->get(SystemZ::LCGR), Tmp2).addReg(Tmp);
- BuildMI(MBB, DL, TII->get(SystemZ::AGHI), RotatedNewVal)
- .addReg(Tmp2).addImm(-1);
- }
+ // XILF with the upper BitSize bits set.
+ BuildMI(MBB, DL, TII->get(SystemZ::XILF), RotatedNewVal)
+ .addReg(Tmp).addImm(-1U << (32 - BitSize));
} else if (BinOpcode)
// A simply binary operation.
BuildMI(MBB, DL, TII->get(BinOpcode), RotatedNewVal)
.addReg(RotatedOldVal)
.add(Src2);
- else if (IsSubWord)
+ else
// Use RISBG to rotate Src2 into position and use it to replace the
// field in RotatedOldVal.
BuildMI(MBB, DL, TII->get(SystemZ::RISBG32), RotatedNewVal)
.addReg(RotatedOldVal).addReg(Src2.getReg())
.addImm(32).addImm(31 + BitSize).addImm(32 - BitSize);
- if (IsSubWord)
- BuildMI(MBB, DL, TII->get(SystemZ::RLL), NewVal)
- .addReg(RotatedNewVal).addReg(NegBitShift).addImm(0);
+ BuildMI(MBB, DL, TII->get(SystemZ::RLL), NewVal)
+ .addReg(RotatedNewVal).addReg(NegBitShift).addImm(0);
BuildMI(MBB, DL, TII->get(CSOpcode), Dest)
.addReg(OldVal)
.addReg(NewVal)
@@ -8070,50 +8040,40 @@ MachineBasicBlock *SystemZTargetLowering::emitAtomicLoadBinary(
return DoneMBB;
}
-// Implement EmitInstrWithCustomInserter for pseudo
-// ATOMIC_LOAD{,W}_{,U}{MIN,MAX} instruction MI. CompareOpcode is the
+// Implement EmitInstrWithCustomInserter for subword pseudo
+// ATOMIC_LOADW_{,U}{MIN,MAX} instruction MI. CompareOpcode is the
// instruction that should be used to compare the current field with the
// minimum or maximum value. KeepOldMask is the BRC condition-code mask
-// for when the current field should be kept. BitSize is the width of
-// the field in bits, or 0 if this is a partword ATOMIC_LOADW_* instruction.
+// for when the current field should be kept.
MachineBasicBlock *SystemZTargetLowering::emitAtomicLoadMinMax(
MachineInstr &MI, MachineBasicBlock *MBB, unsigned CompareOpcode,
- unsigned KeepOldMask, unsigned BitSize) const {
+ unsigned KeepOldMask) const {
MachineFunction &MF = *MBB->getParent();
const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
MachineRegisterInfo &MRI = MF.getRegInfo();
- bool IsSubWord = (BitSize < 32);
// Extract the operands. Base can be a register or a frame index.
Register Dest = MI.getOperand(0).getReg();
MachineOperand Base = earlyUseOperand(MI.getOperand(1));
int64_t Disp = MI.getOperand(2).getImm();
Register Src2 = MI.getOperand(3).getReg();
- Register BitShift = (IsSubWord ? MI.getOperand(4).getReg() : Register());
- Register NegBitShift = (IsSubWord ? MI.getOperand(5).getReg() : Register());
+ Register BitShift = MI.getOperand(4).getReg();
+ Register NegBitShift = MI.getOperand(5).getReg();
+ unsigned BitSize = MI.getOperand(6).getImm();
DebugLoc DL = MI.getDebugLoc();
- if (IsSubWord)
- BitSize = MI.getOperand(6).getImm();
-
- // Subword operations use 32-bit registers.
- const TargetRegisterClass *RC = (BitSize <= 32 ?
- &SystemZ::GR32BitRegClass :
- &SystemZ::GR64BitRegClass);
- unsigned LOpcode = BitSize <= 32 ? SystemZ::L : SystemZ::LG;
- unsigned CSOpcode = BitSize <= 32 ? SystemZ::CS : SystemZ::CSG;
// Get the right opcodes for the displacement.
- LOpcode = TII->getOpcodeForOffset(LOpcode, Disp);
- CSOpcode = TII->getOpcodeForOffset(CSOpcode, Disp);
+ unsigned LOpcode = TII->getOpcodeForOffset(SystemZ::L, Disp);
+ unsigned CSOpcode = TII->getOpcodeForOffset(SystemZ::CS, Disp);
assert(LOpcode && CSOpcode && "Displacement out of range");
// Create virtual registers for temporary results.
- Register OrigVal = MRI.createVirtualRegister(RC);
- Register OldVal = MRI.createVirtualRegister(RC);
- Register NewVal = MRI.createVirtualRegister(RC);
- Register RotatedOldVal = (IsSubWord ? MRI.createVirtualRegister(RC) : OldVal);
- Register RotatedAltVal = (IsSubWord ? MRI.createVirtualRegister(RC) : Src2);
- Register RotatedNewVal = (IsSubWord ? MRI.createVirtualRegister(RC) : NewVal);
+ Register OrigVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
+ Register OldVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
+ Register NewVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
+ Register RotatedOldVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
+ Register RotatedAltVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
+ Register RotatedNewVal = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
// Insert 3 basic blocks for the loop.
MachineBasicBlock *StartMBB = MBB;
@@ -8139,9 +8099,8 @@ MachineBasicBlock *SystemZTargetLowering::emitAtomicLoadMinMax(
BuildMI(MBB, DL, TII->get(SystemZ::PHI), OldVal)
.addReg(OrigVal).addMBB(StartMBB)
.addReg(Dest).addMBB(UpdateMBB);
- if (IsSubWord)
- BuildMI(MBB, DL, TII->get(SystemZ::RLL), RotatedOldVal)
- .addReg(OldVal).addReg(BitShift).addImm(0);
+ BuildMI(MBB, DL, TII->get(SystemZ::RLL), RotatedOldVal)
+ .addReg(OldVal).addReg(BitShift).addImm(0);
BuildMI(MBB, DL, TII->get(CompareOpcode))
.addReg(RotatedOldVal).addReg(Src2);
BuildMI(MBB, DL, TII->get(SystemZ::BRC))
@@ -8153,10 +8112,9 @@ MachineBasicBlock *SystemZTargetLowering::emitAtomicLoadMinMax(
// %RotatedAltVal = RISBG %RotatedOldVal, %Src2, 32, 31 + BitSize, 0
// # fall through to UpdateMBB
MBB = UseAltMBB;
- if (IsSubWord)
- BuildMI(MBB, DL, TII->get(SystemZ::RISBG32), RotatedAltVal)
- .addReg(RotatedOldVal).addReg(Src2)
- .addImm(32).addImm(31 + BitSize).addImm(0);
+ BuildMI(MBB, DL, TII->get(SystemZ::RISBG32), RotatedAltVal)
+ .addReg(RotatedOldVal).addReg(Src2)
+ .addImm(32).addImm(31 + BitSize).addImm(0);
MBB->addSuccessor(UpdateMBB);
// UpdateMBB:
@@ -8170,9 +8128,8 @@ MachineBasicBlock *SystemZTargetLowering::emitAtomicLoadMinMax(
BuildMI(MBB, DL, TII->get(SystemZ::PHI), RotatedNewVal)
.addReg(RotatedOldVal).addMBB(LoopMBB)
.addReg(RotatedAltVal).addMBB(UseAltMBB);
- if (IsSubWord)
- BuildMI(MBB, DL, TII->get(SystemZ::RLL), NewVal)
- .addReg(RotatedNewVal).addReg(NegBitShift).addImm(0);
+ BuildMI(MBB, DL, TII->get(SystemZ::RLL), NewVal)
+ .addReg(RotatedNewVal).addReg(NegBitShift).addImm(0);
BuildMI(MBB, DL, TII->get(CSOpcode), Dest)
.addReg(OldVal)
.addReg(NewVal)
@@ -8187,7 +8144,7 @@ MachineBasicBlock *SystemZTargetLowering::emitAtomicLoadMinMax(
return DoneMBB;
}
-// Implement EmitInstrWithCustomInserter for pseudo ATOMIC_CMP_SWAPW
+// Implement EmitInstrWithCustomInserter for subword pseudo ATOMIC_CMP_SWAPW
// instruction MI.
MachineBasicBlock *
SystemZTargetLowering::emitAtomicCmpSwapW(MachineInstr &MI,
@@ -9004,171 +8961,44 @@ MachineBasicBlock *SystemZTargetLowering::EmitInstrWithCustomInserter(
return emitExt128(MI, MBB, true);
case SystemZ::ATOMIC_SWAPW:
- return emitAtomicLoadBinary(MI, MBB, 0, 0);
- case SystemZ::ATOMIC_SWAP_32:
- return emitAtomicLoadBinary(MI, MBB, 0, 32);
- case SystemZ::ATOMIC_SWAP_64:
- return emitAtomicLoadBinary(MI, MBB, 0, 64);
+ return emitAtomicLoadBinary(MI, MBB, 0);
case SystemZ::ATOMIC_LOADW_AR:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::AR, 0);
+ return emitAtomicLoadBinary(MI, MBB, SystemZ::AR);
case SystemZ::ATOMIC_LOADW_AFI:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::AFI, 0);
- case SystemZ::ATOMIC_LOAD_AR:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::AR, 32);
- case SystemZ::ATOMIC_LOAD_AHI:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::AHI, 32);
- case SystemZ::ATOMIC_LOAD_AFI:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::AFI, 32);
- case SystemZ::ATOMIC_LOAD_AGR:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::AGR, 64);
- case SystemZ::ATOMIC_LOAD_AGHI:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::AGHI, 64);
- case SystemZ::ATOMIC_LOAD_AGFI:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::AGFI, 64);
+ return emitAtomicLoadBinary(MI, MBB, SystemZ::AFI);
case SystemZ::ATOMIC_LOADW_SR:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::SR, 0);
- case SystemZ::ATOMIC_LOAD_SR:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::SR, 32);
- case SystemZ::ATOMIC_LOAD_SGR:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::SGR, 64);
+ return emitAtomicLoadBinary(MI, MBB, SystemZ::SR);
case SystemZ::ATOMIC_LOADW_NR:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NR, 0);
+ return emitAtomicLoadBinary(MI, MBB, SystemZ::NR);
case SystemZ::ATOMIC_LOADW_NILH:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH, 0);
- case SystemZ::ATOMIC_LOAD_NR:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NR, 32);
- case SystemZ::ATOMIC_LOAD_NILL:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NILL, 32);
- case SystemZ::ATOMIC_LOAD_NILH:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH, 32);
- case SystemZ::ATOMIC_LOAD_NILF:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NILF, 32);
- case SystemZ::ATOMIC_LOAD_NGR:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NGR, 64);
- case SystemZ::ATOMIC_LOAD_NILL64:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NILL64, 64);
- case SystemZ::ATOMIC_LOAD_NILH64:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH64, 64);
- case SystemZ::ATOMIC_LOAD_NIHL64:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHL64, 64);
- case SystemZ::ATOMIC_LOAD_NIHH64:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHH64, 64);
- case SystemZ::ATOMIC_LOAD_NILF64:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NILF64, 64);
- case SystemZ::ATOMIC_LOAD_NIHF64:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHF64, 64);
+ return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH);
case SystemZ::ATOMIC_LOADW_OR:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::OR, 0);
+ return emitAtomicLoadBinary(MI, MBB, SystemZ::OR);
case SystemZ::ATOMIC_LOADW_OILH:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::OILH, 0);
- case SystemZ::ATOMIC_LOAD_OR:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::OR, 32);
- case SystemZ::ATOMIC_LOAD_OILL:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::OILL, 32);
- case SystemZ::ATOMIC_LOAD_OILH:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::OILH, 32);
- case SystemZ::ATOMIC_LOAD_OILF:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::OILF, 32);
- case SystemZ::ATOMIC_LOAD_OGR:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::OGR, 64);
- case SystemZ::ATOMIC_LOAD_OILL64:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::OILL64, 64);
- case SystemZ::ATOMIC_LOAD_OILH64:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::OILH64, 64);
- case SystemZ::ATOMIC_LOAD_OIHL64:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::OIHL64, 64);
- case SystemZ::ATOMIC_LOAD_OIHH64:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::OIHH64, 64);
- case SystemZ::ATOMIC_LOAD_OILF64:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::OILF64, 64);
- case SystemZ::ATOMIC_LOAD_OIHF64:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::OIHF64, 64);
+ return emitAtomicLoadBinary(MI, MBB, SystemZ::OILH);
case SystemZ::ATOMIC_LOADW_XR:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::XR, 0);
+ return emitAtomicLoadBinary(MI, MBB, SystemZ::XR);
case SystemZ::ATOMIC_LOADW_XILF:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::XILF, 0);
- case SystemZ::ATOMIC_LOAD_XR:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::XR, 32);
- case SystemZ::ATOMIC_LOAD_XILF:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::XILF, 32);
- case SystemZ::ATOMIC_LOAD_XGR:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::XGR, 64);
- case SystemZ::ATOMIC_LOAD_XILF64:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::XILF64, 64);
- case SystemZ::ATOMIC_LOAD_XIHF64:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::XIHF64, 64);
+ return emitAtomicLoadBinary(MI, MBB, SystemZ::XILF);
case SystemZ::ATOMIC_LOADW_NRi:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NR, 0, true);
+ return emitAtomicLoadBinary(MI, MBB, SystemZ::NR, true);
case SystemZ::ATOMIC_LOADW_NILHi:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH, 0, true);
- case SystemZ::ATOMIC_LOAD_NRi:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NR, 32, true);
- case SystemZ::ATOMIC_LOAD_NILLi:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NILL, 32, true);
- case SystemZ::ATOMIC_LOAD_NILHi:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH, 32, true);
- case SystemZ::ATOMIC_LOAD_NILFi:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NILF, 32, true);
- case SystemZ::ATOMIC_LOAD_NGRi:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NGR, 64, true);
- case SystemZ::ATOMIC_LOAD_NILL64i:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NILL64, 64, true);
- case SystemZ::ATOMIC_LOAD_NILH64i:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH64, 64, true);
- case SystemZ::ATOMIC_LOAD_NIHL64i:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHL64, 64, true);
- case SystemZ::ATOMIC_LOAD_NIHH64i:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHH64, 64, true);
- case SystemZ::ATOMIC_LOAD_NILF64i:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NILF64, 64, true);
- case SystemZ::ATOMIC_LOAD_NIHF64i:
- return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHF64, 64, true);
+ return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH, true);
case SystemZ::ATOMIC_LOADW_MIN:
- return emitAtomicLoadMinMax(MI, MBB, SystemZ::CR,
- SystemZ::CCMASK_CMP_LE, 0);
- case SystemZ::ATOMIC_LOAD_MIN_32:
- return emitAtomicLoadMinMax(MI, MBB, SystemZ::CR,
- SystemZ::CCMASK_CMP_LE, 32);
- case SystemZ::ATOMIC_LOAD_MIN_64:
- return emitAtomicLoadMinMax(MI, MBB, SystemZ::CGR,
- SystemZ::CCMASK_CMP_LE, 64);
-
+ return emitAtomicLoadMinMax(MI, MBB, SystemZ::CR, SystemZ::CCMASK_CMP_LE);
case SystemZ::ATOMIC_LOADW_MAX:
- return emitAtomicLoadMinMax(MI, MBB, SystemZ::CR,
- SystemZ::CCMASK_CMP_GE, 0);
- case SystemZ::ATOMIC_LOAD_MAX_32:
- return emitAtomicLoadMinMax(MI, MBB, SystemZ::CR,
- SystemZ::CCMASK_CMP_GE, 32);
- case SystemZ::ATOMIC_LOAD_MAX_64:
- return emitAtomicLoadMinMax(MI, MBB, SystemZ::CGR,
- SystemZ::CCMASK_CMP_GE, 64);
-
+ return emitAtomicLoadMinMax(MI, MBB, SystemZ::CR, SystemZ::CCMASK_CMP_GE);
case SystemZ::ATOMIC_LOADW_UMIN:
- return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLR,
- SystemZ::CCMASK_CMP_LE, 0);
- case SystemZ::ATOMIC_LOAD_UMIN_32:
- return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLR,
- SystemZ::CCMASK_CMP_LE, 32);
- case SystemZ::ATOMIC_LOAD_UMIN_64:
- return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLGR,
- SystemZ::CCMASK_CMP_LE, 64);
-
+ return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLR, SystemZ::CCMASK_CMP_LE);
case SystemZ::ATOMIC_LOADW_UMAX:
- return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLR,
- SystemZ::CCMASK_CMP_GE, 0);
- case SystemZ::ATOMIC_LOAD_UMAX_32:
- return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLR,
- SystemZ::CCMASK_CMP_GE, 32);
- case SystemZ::ATOMIC_LOAD_UMAX_64:
- return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLGR,
- SystemZ::CCMASK_CMP_GE, 64);
+ return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLR, SystemZ::CCMASK_CMP_GE);
case SystemZ::ATOMIC_CMP_SWAPW:
return emitAtomicCmpSwapW(MI, MBB);
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.h b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
index 40fe433f816fa..1e2887cff8164 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.h
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
@@ -748,13 +748,12 @@ class SystemZTargetLowering : public TargetLowering {
bool ClearEven) const;
MachineBasicBlock *emitAtomicLoadBinary(MachineInstr &MI,
MachineBasicBlock *BB,
- unsigned BinOpcode, unsigned BitSize,
+ unsigned BinOpcode,
bool Invert = false) const;
MachineBasicBlock *emitAtomicLoadMinMax(MachineInstr &MI,
MachineBasicBlock *MBB,
unsigned CompareOpcode,
- unsigned KeepOldMask,
- unsigned BitSize) const;
+ unsigned KeepOldMask) const;
MachineBasicBlock *emitAtomicCmpSwapW(MachineInstr &MI,
MachineBasicBlock *BB) const;
MachineBasicBlock *emitMemMemWrapper(MachineInstr &MI, MachineBasicBlock *BB,
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td
index a25719f80ad07..2e5ff4a1df673 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td
+++ b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td
@@ -5327,30 +5327,6 @@ multiclass CondStores<RegisterOperand cls, SDPatternOperator store,
}
}
-// OPERATOR is ATOMIC_SWAP or an ATOMIC_LOAD_* operation. PAT and OPERAND
-// describe the second (non-memory) operand.
-class AtomicLoadBinary<SDPatternOperator operator, RegisterOperand cls,
- dag pat, DAGOperand operand>
- : Pseudo<(outs cls:$dst), (ins bdaddr20only:$ptr, operand:$src2),
- [(set cls:$dst, (operator bdaddr20only:$ptr, pat))]> {
- let Defs = [CC];
- let Has20BitOffset = 1;
- let mayLoad = 1;
- let mayStore = 1;
- let usesCustomInserter = 1;
- let hasNoSchedulingInfo = 1;
-}
-
-// Specializations of AtomicLoadWBinary.
-class AtomicLoadBinaryReg32<SDPatternOperator operator>
- : AtomicLoadBinary<operator, GR32, (i32 GR32:$src2), GR32>;
-class AtomicLoadBinaryImm32<SDPatternOperator operator, ImmOpWithPattern imm>
- : AtomicLoadBinary<operator, GR32, (i32 imm:$src2), imm>;
-class AtomicLoadBinaryReg64<SDPatternOperator operator>
- : AtomicLoadBinary<operator, GR64, (i64 GR64:$src2), GR64>;
-class AtomicLoadBinaryImm64<SDPatternOperator operator, ImmOpWithPattern imm>
- : AtomicLoadBinary<operator, GR64, (i64 imm:$src2), imm>;
-
// OPERATOR is ATOMIC_SWAPW or an ATOMIC_LOADW_* operation. PAT and OPERAND
// describe the second (non-memory) operand.
class AtomicLoadWBinary<SDPatternOperator operator, dag pat,
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
index 87eb3838aec41..210e6a51b6dcb 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
+++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
@@ -1746,112 +1746,29 @@ let Predicates = [FeatureInterlockedAccess1], Defs = [CC] in {
}
def ATOMIC_SWAPW : AtomicLoadWBinaryReg<z_atomic_swapw>;
-def ATOMIC_SWAP_32 : AtomicLoadBinaryReg32<atomic_swap_32>;
-def ATOMIC_SWAP_64 : AtomicLoadBinaryReg64<atomic_swap_64>;
def ATOMIC_LOADW_AR : AtomicLoadWBinaryReg<z_atomic_loadw_add>;
def ATOMIC_LOADW_AFI : AtomicLoadWBinaryImm<z_atomic_loadw_add, simm32>;
-let Predicates = [FeatureNoInterlockedAccess1] in {
- def ATOMIC_LOAD_AR : AtomicLoadBinaryReg32<atomic_load_add_32>;
- def ATOMIC_LOAD_AHI : AtomicLoadBinaryImm32<atomic_load_add_32, imm32sx16>;
- def ATOMIC_LOAD_AFI : AtomicLoadBinaryImm32<atomic_load_add_32, simm32>;
- def ATOMIC_LOAD_AGR : AtomicLoadBinaryReg64<atomic_load_add_64>;
- def ATOMIC_LOAD_AGHI : AtomicLoadBinaryImm64<atomic_load_add_64, imm64sx16>;
- def ATOMIC_LOAD_AGFI : AtomicLoadBinaryImm64<atomic_load_add_64, imm64sx32>;
-}
def ATOMIC_LOADW_SR : AtomicLoadWBinaryReg<z_atomic_loadw_sub>;
-def ATOMIC_LOAD_SR : AtomicLoadBinaryReg32<atomic_load_sub_32>;
-def ATOMIC_LOAD_SGR : AtomicLoadBinaryReg64<atomic_load_sub_64>;
def ATOMIC_LOADW_NR : AtomicLoadWBinaryReg<z_atomic_loadw_and>;
def ATOMIC_LOADW_NILH : AtomicLoadWBinaryImm<z_atomic_loadw_and, imm32lh16c>;
-let Predicates = [FeatureNoInterlockedAccess1] in {
- def ATOMIC_LOAD_NR : AtomicLoadBinaryReg32<atomic_load_and_32>;
- def ATOMIC_LOAD_NILL : AtomicLoadBinaryImm32<atomic_load_and_32,
- imm32ll16c>;
- def ATOMIC_LOAD_NILH : AtomicLoadBinaryImm32<atomic_load_and_32,
- imm32lh16c>;
- def ATOMIC_LOAD_NILF : AtomicLoadBinaryImm32<atomic_load_and_32, uimm32>;
- def ATOMIC_LOAD_NGR : AtomicLoadBinaryReg64<atomic_load_and_64>;
- def ATOMIC_LOAD_NILL64 : AtomicLoadBinaryImm64<atomic_load_and_64,
- imm64ll16c>;
- def ATOMIC_LOAD_NILH64 : AtomicLoadBinaryImm64<atomic_load_and_64,
- imm64lh16c>;
- def ATOMIC_LOAD_NIHL64 : AtomicLoadBinaryImm64<atomic_load_and_64,
- imm64hl16c>;
- def ATOMIC_LOAD_NIHH64 : AtomicLoadBinaryImm64<atomic_load_and_64,
- imm64hh16c>;
- def ATOMIC_LOAD_NILF64 : AtomicLoadBinaryImm64<atomic_load_and_64,
- imm64lf32c>;
- def ATOMIC_LOAD_NIHF64 : AtomicLoadBinaryImm64<atomic_load_and_64,
- imm64hf32c>;
-}
def ATOMIC_LOADW_OR : AtomicLoadWBinaryReg<z_atomic_loadw_or>;
def ATOMIC_LOADW_OILH : AtomicLoadWBinaryImm<z_atomic_loadw_or, imm32lh16>;
-let Predicates = [FeatureNoInterlockedAccess1] in {
- def ATOMIC_LOAD_OR : AtomicLoadBinaryReg32<atomic_load_or_32>;
- def ATOMIC_LOAD_OILL : AtomicLoadBinaryImm32<atomic_load_or_32, imm32ll16>;
- def ATOMIC_LOAD_OILH : AtomicLoadBinaryImm32<atomic_load_or_32, imm32lh16>;
- def ATOMIC_LOAD_OILF : AtomicLoadBinaryImm32<atomic_load_or_32, uimm32>;
- def ATOMIC_LOAD_OGR : AtomicLoadBinaryReg64<atomic_load_or_64>;
- def ATOMIC_LOAD_OILL64 : AtomicLoadBinaryImm64<atomic_load_or_64, imm64ll16>;
- def ATOMIC_LOAD_OILH64 : AtomicLoadBinaryImm64<atomic_load_or_64, imm64lh16>;
- def ATOMIC_LOAD_OIHL64 : AtomicLoadBinaryImm64<atomic_load_or_64, imm64hl16>;
- def ATOMIC_LOAD_OIHH64 : AtomicLoadBinaryImm64<atomic_load_or_64, imm64hh16>;
- def ATOMIC_LOAD_OILF64 : AtomicLoadBinaryImm64<atomic_load_or_64, imm64lf32>;
- def ATOMIC_LOAD_OIHF64 : AtomicLoadBinaryImm64<atomic_load_or_64, imm64hf32>;
-}
def ATOMIC_LOADW_XR : AtomicLoadWBinaryReg<z_atomic_loadw_xor>;
def ATOMIC_LOADW_XILF : AtomicLoadWBinaryImm<z_atomic_loadw_xor, uimm32>;
-let Predicates = [FeatureNoInterlockedAccess1] in {
- def ATOMIC_LOAD_XR : AtomicLoadBinaryReg32<atomic_load_xor_32>;
- def ATOMIC_LOAD_XILF : AtomicLoadBinaryImm32<atomic_load_xor_32, uimm32>;
- def ATOMIC_LOAD_XGR : AtomicLoadBinaryReg64<atomic_load_xor_64>;
- def ATOMIC_LOAD_XILF64 : AtomicLoadBinaryImm64<atomic_load_xor_64, imm64lf32>;
- def ATOMIC_LOAD_XIHF64 : AtomicLoadBinaryImm64<atomic_load_xor_64, imm64hf32>;
-}
def ATOMIC_LOADW_NRi : AtomicLoadWBinaryReg<z_atomic_loadw_nand>;
def ATOMIC_LOADW_NILHi : AtomicLoadWBinaryImm<z_atomic_loadw_nand,
imm32lh16c>;
-def ATOMIC_LOAD_NRi : AtomicLoadBinaryReg32<atomic_load_nand_32>;
-def ATOMIC_LOAD_NILLi : AtomicLoadBinaryImm32<atomic_load_nand_32,
- imm32ll16c>;
-def ATOMIC_LOAD_NILHi : AtomicLoadBinaryImm32<atomic_load_nand_32,
- imm32lh16c>;
-def ATOMIC_LOAD_NILFi : AtomicLoadBinaryImm32<atomic_load_nand_32, uimm32>;
-def ATOMIC_LOAD_NGRi : AtomicLoadBinaryReg64<atomic_load_nand_64>;
-def ATOMIC_LOAD_NILL64i : AtomicLoadBinaryImm64<atomic_load_nand_64,
- imm64ll16c>;
-def ATOMIC_LOAD_NILH64i : AtomicLoadBinaryImm64<atomic_load_nand_64,
- imm64lh16c>;
-def ATOMIC_LOAD_NIHL64i : AtomicLoadBinaryImm64<atomic_load_nand_64,
- imm64hl16c>;
-def ATOMIC_LOAD_NIHH64i : AtomicLoadBinaryImm64<atomic_load_nand_64,
- imm64hh16c>;
-def ATOMIC_LOAD_NILF64i : AtomicLoadBinaryImm64<atomic_load_nand_64,
- imm64lf32c>;
-def ATOMIC_LOAD_NIHF64i : AtomicLoadBinaryImm64<atomic_load_nand_64,
- imm64hf32c>;
def ATOMIC_LOADW_MIN : AtomicLoadWBinaryReg<z_atomic_loadw_min>;
-def ATOMIC_LOAD_MIN_32 : AtomicLoadBinaryReg32<atomic_load_min_32>;
-def ATOMIC_LOAD_MIN_64 : AtomicLoadBinaryReg64<atomic_load_min_64>;
-
def ATOMIC_LOADW_MAX : AtomicLoadWBinaryReg<z_atomic_loadw_max>;
-def ATOMIC_LOAD_MAX_32 : AtomicLoadBinaryReg32<atomic_load_max_32>;
-def ATOMIC_LOAD_MAX_64 : AtomicLoadBinaryReg64<atomic_load_max_64>;
-
def ATOMIC_LOADW_UMIN : AtomicLoadWBinaryReg<z_atomic_loadw_umin>;
-def ATOMIC_LOAD_UMIN_32 : AtomicLoadBinaryReg32<atomic_load_umin_32>;
-def ATOMIC_LOAD_UMIN_64 : AtomicLoadBinaryReg64<atomic_load_umin_64>;
-
def ATOMIC_LOADW_UMAX : AtomicLoadWBinaryReg<z_atomic_loadw_umax>;
-def ATOMIC_LOAD_UMAX_32 : AtomicLoadBinaryReg32<atomic_load_umax_32>;
-def ATOMIC_LOAD_UMAX_64 : AtomicLoadBinaryReg64<atomic_load_umax_64>;
def ATOMIC_CMP_SWAPW
: Pseudo<(outs GR32:$dst), (ins bdaddr20only:$addr, GR32:$cmp, GR32:$swap,
diff --git a/llvm/test/CodeGen/SystemZ/atomicrmw-add-04.ll b/llvm/test/CodeGen/SystemZ/atomicrmw-add-04.ll
index 50d3eec15dbe8..4af3793191b67 100644
--- a/llvm/test/CodeGen/SystemZ/atomicrmw-add-04.ll
+++ b/llvm/test/CodeGen/SystemZ/atomicrmw-add-04.ll
@@ -16,13 +16,12 @@ define i64 @f1(i64 %dummy, ptr %src, i64 %b) {
ret i64 %res
}
-; Check addition of 1, which can use AGHI.
+; Check addition of 1.
define i64 @f2(i64 %dummy, ptr %src) {
; CHECK-LABEL: f2:
; CHECK: lg %r2, 0(%r3)
; CHECK: [[LABEL:\.[^:]*]]:
-; CHECK: lgr %r0, %r2
-; CHECK: aghi %r0, 1
+; CHECK: la %r0, 1(%r2)
; CHECK: csg %r2, %r0, 0(%r3)
; CHECK: jl [[LABEL]]
; CHECK: br %r14
@@ -30,82 +29,64 @@ define i64 @f2(i64 %dummy, ptr %src) {
ret i64 %res
}
-; Check the high end of the AGHI range.
+; Check use of LAY.
define i64 @f3(i64 %dummy, ptr %src) {
; CHECK-LABEL: f3:
-; CHECK: aghi %r0, 32767
+; CHECK: lay %r0, 32767(%r2)
; CHECK: br %r14
%res = atomicrmw add ptr %src, i64 32767 seq_cst
ret i64 %res
}
-; Check the next value up, which must use AGFI.
+; Check the high end of the AGFI range.
define i64 @f4(i64 %dummy, ptr %src) {
; CHECK-LABEL: f4:
-; CHECK: agfi %r0, 32768
+; CHECK: agfi %r0, 2147483647
; CHECK: br %r14
- %res = atomicrmw add ptr %src, i64 32768 seq_cst
+ %res = atomicrmw add ptr %src, i64 2147483647 seq_cst
ret i64 %res
}
-; Check the high end of the AGFI range.
+; Check the next value up, which uses an ALGFI.
define i64 @f5(i64 %dummy, ptr %src) {
; CHECK-LABEL: f5:
-; CHECK: agfi %r0, 2147483647
+; CHECK: algfi %r0, 2147483648
; CHECK: br %r14
- %res = atomicrmw add ptr %src, i64 2147483647 seq_cst
+ %res = atomicrmw add ptr %src, i64 2147483648 seq_cst
ret i64 %res
}
-; Check the next value up, which must use a register addition.
+; Check addition of -1, which can use LAY.
define i64 @f6(i64 %dummy, ptr %src) {
; CHECK-LABEL: f6:
-; CHECK: agr
+; CHECK: lay %r0, -1(%r2)
; CHECK: br %r14
- %res = atomicrmw add ptr %src, i64 2147483648 seq_cst
+ %res = atomicrmw add ptr %src, i64 -1 seq_cst
ret i64 %res
}
-; Check addition of -1, which can use AGHI.
+; LAY still OK.
define i64 @f7(i64 %dummy, ptr %src) {
; CHECK-LABEL: f7:
-; CHECK: aghi %r0, -1
-; CHECK: br %r14
- %res = atomicrmw add ptr %src, i64 -1 seq_cst
- ret i64 %res
-}
-
-; Check the low end of the AGHI range.
-define i64 @f8(i64 %dummy, ptr %src) {
-; CHECK-LABEL: f8:
-; CHECK: aghi %r0, -32768
-; CHECK: br %r14
- %res = atomicrmw add ptr %src, i64 -32768 seq_cst
- ret i64 %res
-}
-
-; Check the next value down, which must use AGFI instead.
-define i64 @f9(i64 %dummy, ptr %src) {
-; CHECK-LABEL: f9:
-; CHECK: agfi %r0, -32769
+; CHECK: lay %r0, -32769(%r2)
; CHECK: br %r14
%res = atomicrmw add ptr %src, i64 -32769 seq_cst
ret i64 %res
}
; Check the low end of the AGFI range.
-define i64 @f10(i64 %dummy, ptr %src) {
-; CHECK-LABEL: f10:
+define i64 @f8(i64 %dummy, ptr %src) {
+; CHECK-LABEL: f8:
; CHECK: agfi %r0, -2147483648
; CHECK: br %r14
%res = atomicrmw add ptr %src, i64 -2147483648 seq_cst
ret i64 %res
}
-; Check the next value down, which must use a register addition.
-define i64 @f11(i64 %dummy, ptr %src) {
-; CHECK-LABEL: f11:
-; CHECK: agr
+; Check the next value down, which uses an SLGFI.
+define i64 @f9(i64 %dummy, ptr %src) {
+; CHECK-LABEL: f9:
+; CHECK: slgfi %r0, 2147483649
; CHECK: br %r14
%res = atomicrmw add ptr %src, i64 -2147483649 seq_cst
ret i64 %res
diff --git a/llvm/test/CodeGen/SystemZ/atomicrmw-and-03.ll b/llvm/test/CodeGen/SystemZ/atomicrmw-and-03.ll
index 03ed2404dcc17..96c82e6b1eaec 100644
--- a/llvm/test/CodeGen/SystemZ/atomicrmw-and-03.ll
+++ b/llvm/test/CodeGen/SystemZ/atomicrmw-and-03.ll
@@ -33,7 +33,7 @@ define i32 @f2(i32 %dummy, ptr %src) {
; Check ANDs of the low end of the NILH range.
define i32 @f3(i32 %dummy, ptr %src) {
; CHECK-LABEL: f3:
-; CHECK: nilh %r0, 0
+; CHECK: llhr %r0, %r2
; CHECK: br %r14
%res = atomicrmw and ptr %src, i32 65535 seq_cst
ret i32 %res
diff --git a/llvm/test/CodeGen/SystemZ/atomicrmw-and-04.ll b/llvm/test/CodeGen/SystemZ/atomicrmw-and-04.ll
index 00b6fd93ad5bb..9647548c842bf 100644
--- a/llvm/test/CodeGen/SystemZ/atomicrmw-and-04.ll
+++ b/llvm/test/CodeGen/SystemZ/atomicrmw-and-04.ll
@@ -16,11 +16,10 @@ define i64 @f1(i64 %dummy, ptr %src, i64 %b) {
ret i64 %res
}
-; Check ANDs of 1, which are done using a register. (We could use RISBG
-; instead, but that isn't implemented yet.)
+; Check ANDs of 1, which are done using a register.
define i64 @f2(i64 %dummy, ptr %src) {
; CHECK-LABEL: f2:
-; CHECK: ngr
+; CHECK: risbg
; CHECK: br %r14
%res = atomicrmw and ptr %src, i64 1 seq_cst
ret i64 %res
@@ -56,7 +55,7 @@ define i64 @f4(i64 %dummy, ptr %src) {
; Check the next value up, which must use a register.
define i64 @f5(i64 %dummy, ptr %src) {
; CHECK-LABEL: f5:
-; CHECK: ngr
+; CHECK: risbg
; CHECK: br %r14
%res = atomicrmw and ptr %src, i64 12884901888 seq_cst
ret i64 %res
@@ -74,7 +73,7 @@ define i64 @f6(i64 %dummy, ptr %src) {
; Check the next value up, which must use a register.
define i64 @f7(i64 %dummy, ptr %src) {
; CHECK-LABEL: f7:
-; CHECK: ngr
+; CHECK: risbg
; CHECK: br %r14
%res = atomicrmw and ptr %src, i64 281474976710656 seq_cst
ret i64 %res
diff --git a/llvm/test/CodeGen/SystemZ/atomicrmw-minmax-03.ll b/llvm/test/CodeGen/SystemZ/atomicrmw-minmax-03.ll
index d633c2d74e3a6..d107e5d1dc2e5 100644
--- a/llvm/test/CodeGen/SystemZ/atomicrmw-minmax-03.ll
+++ b/llvm/test/CodeGen/SystemZ/atomicrmw-minmax-03.ll
@@ -1,21 +1,31 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
; Test 32-bit atomic minimum and maximum. Here we match the z10 versions,
; which can't use LOCR.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
+; Todo: If-converter no longer producing CondReturns (with AtomicExpand pass).
+
; Check signed minimum.
define i32 @f1(i32 %dummy, ptr %src, i32 %b) {
; CHECK-LABEL: f1:
-; CHECK: l %r2, 0(%r3)
-; CHECK: j [[LOOP:\.[^:]*]]
-; CHECK: [[BB1:\.[^:]*]]:
-; CHECK: cs %r2, [[NEW:%r[0-9]+]], 0(%r3)
-; CHECK: ber %r14
-; CHECK: [[LOOP]]:
-; CHECK: lr [[NEW]], %r2
-; CHECK: crjle %r2, %r4, [[KEEP:\..*]]
-; CHECK: lr [[NEW]], %r4
-; CHECK: j [[BB1]]
+; CHECK: # %bb.0:
+; CHECK-NEXT: l %r2, 0(%r3)
+; CHECK-NEXT: j .LBB0_2
+; CHECK-NEXT: .LBB0_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB0_2 Depth=1
+; CHECK-NEXT: cs %r2, %r0, 0(%r3)
+; CHECK-NEXT: je .LBB0_4
+; CHECK-NEXT: .LBB0_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lr %r0, %r2
+; CHECK-NEXT: crjle %r2, %r4, .LBB0_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB0_2 Depth=1
+; CHECK-NEXT: lr %r0, %r4
+; CHECK-NEXT: j .LBB0_1
+; CHECK-NEXT: .LBB0_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%res = atomicrmw min ptr %src, i32 %b seq_cst
ret i32 %res
}
@@ -23,16 +33,23 @@ define i32 @f1(i32 %dummy, ptr %src, i32 %b) {
; Check signed maximum.
define i32 @f2(i32 %dummy, ptr %src, i32 %b) {
; CHECK-LABEL: f2:
-; CHECK: l %r2, 0(%r3)
-; CHECK: j [[LOOP:\.[^:]*]]
-; CHECK: [[BB1:\.[^:]*]]:
-; CHECK: cs %r2, [[NEW:%r[0-9]+]], 0(%r3)
-; CHECK: ber %r14
-; CHECK: [[LOOP]]:
-; CHECK: lr [[NEW]], %r2
-; CHECK: crjhe %r2, %r4, [[KEEP:\..*]]
-; CHECK: lr [[NEW]], %r4
-; CHECK: j [[BB1]]
+; CHECK: # %bb.0:
+; CHECK-NEXT: l %r2, 0(%r3)
+; CHECK-NEXT: j .LBB1_2
+; CHECK-NEXT: .LBB1_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB1_2 Depth=1
+; CHECK-NEXT: cs %r2, %r0, 0(%r3)
+; CHECK-NEXT: je .LBB1_4
+; CHECK-NEXT: .LBB1_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lr %r0, %r2
+; CHECK-NEXT: crjh %r2, %r4, .LBB1_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB1_2 Depth=1
+; CHECK-NEXT: lr %r0, %r4
+; CHECK-NEXT: j .LBB1_1
+; CHECK-NEXT: .LBB1_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%res = atomicrmw max ptr %src, i32 %b seq_cst
ret i32 %res
}
@@ -40,16 +57,23 @@ define i32 @f2(i32 %dummy, ptr %src, i32 %b) {
; Check unsigned minimum.
define i32 @f3(i32 %dummy, ptr %src, i32 %b) {
; CHECK-LABEL: f3:
-; CHECK: l %r2, 0(%r3)
-; CHECK: j [[LOOP:\.[^:]*]]
-; CHECK: [[BB1:\.[^:]*]]:
-; CHECK: cs %r2, [[NEW:%r[0-9]+]], 0(%r3)
-; CHECK: ber %r14
-; CHECK: [[LOOP]]:
-; CHECK: lr [[NEW]], %r2
-; CHECK: clrjle %r2, %r4, [[KEEP:\..*]]
-; CHECK: lr [[NEW]], %r4
-; CHECK: j [[BB1]]
+; CHECK: # %bb.0:
+; CHECK-NEXT: l %r2, 0(%r3)
+; CHECK-NEXT: j .LBB2_2
+; CHECK-NEXT: .LBB2_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB2_2 Depth=1
+; CHECK-NEXT: cs %r2, %r0, 0(%r3)
+; CHECK-NEXT: je .LBB2_4
+; CHECK-NEXT: .LBB2_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lr %r0, %r2
+; CHECK-NEXT: clrjle %r2, %r4, .LBB2_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB2_2 Depth=1
+; CHECK-NEXT: lr %r0, %r4
+; CHECK-NEXT: j .LBB2_1
+; CHECK-NEXT: .LBB2_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%res = atomicrmw umin ptr %src, i32 %b seq_cst
ret i32 %res
}
@@ -57,16 +81,23 @@ define i32 @f3(i32 %dummy, ptr %src, i32 %b) {
; Check unsigned maximum.
define i32 @f4(i32 %dummy, ptr %src, i32 %b) {
; CHECK-LABEL: f4:
-; CHECK: l %r2, 0(%r3)
-; CHECK: j [[LOOP:\.[^:]*]]
-; CHECK: [[BB1:\.[^:]*]]:
-; CHECK: cs %r2, [[NEW:%r[0-9]+]], 0(%r3)
-; CHECK: ber %r14
-; CHECK: [[LOOP]]:
-; CHECK: lr [[NEW]], %r2
-; CHECK: clrjhe %r2, %r4, [[KEEP:\..*]]
-; CHECK: lr [[NEW]], %r4
-; CHECK: j [[BB1]]
+; CHECK: # %bb.0:
+; CHECK-NEXT: l %r2, 0(%r3)
+; CHECK-NEXT: j .LBB3_2
+; CHECK-NEXT: .LBB3_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB3_2 Depth=1
+; CHECK-NEXT: cs %r2, %r0, 0(%r3)
+; CHECK-NEXT: je .LBB3_4
+; CHECK-NEXT: .LBB3_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lr %r0, %r2
+; CHECK-NEXT: clrjh %r2, %r4, .LBB3_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB3_2 Depth=1
+; CHECK-NEXT: lr %r0, %r4
+; CHECK-NEXT: j .LBB3_1
+; CHECK-NEXT: .LBB3_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%res = atomicrmw umax ptr %src, i32 %b seq_cst
ret i32 %res
}
@@ -74,9 +105,23 @@ define i32 @f4(i32 %dummy, ptr %src, i32 %b) {
; Check the high end of the aligned CS range.
define i32 @f5(i32 %dummy, ptr %src, i32 %b) {
; CHECK-LABEL: f5:
-; CHECK: l %r2, 4092(%r3)
-; CHECK: cs %r2, {{%r[0-9]+}}, 4092(%r3)
-; CHECK: ber %r14
+; CHECK: # %bb.0:
+; CHECK-NEXT: l %r2, 4092(%r3)
+; CHECK-NEXT: j .LBB4_2
+; CHECK-NEXT: .LBB4_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB4_2 Depth=1
+; CHECK-NEXT: cs %r2, %r0, 4092(%r3)
+; CHECK-NEXT: je .LBB4_4
+; CHECK-NEXT: .LBB4_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lr %r0, %r2
+; CHECK-NEXT: crjle %r2, %r4, .LBB4_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB4_2 Depth=1
+; CHECK-NEXT: lr %r0, %r4
+; CHECK-NEXT: j .LBB4_1
+; CHECK-NEXT: .LBB4_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%ptr = getelementptr i32, ptr %src, i64 1023
%res = atomicrmw min ptr %ptr, i32 %b seq_cst
ret i32 %res
@@ -85,9 +130,23 @@ define i32 @f5(i32 %dummy, ptr %src, i32 %b) {
; Check the next word up, which requires CSY.
define i32 @f6(i32 %dummy, ptr %src, i32 %b) {
; CHECK-LABEL: f6:
-; CHECK: ly %r2, 4096(%r3)
-; CHECK: csy %r2, {{%r[0-9]+}}, 4096(%r3)
-; CHECK: ber %r14
+; CHECK: # %bb.0:
+; CHECK-NEXT: ly %r2, 4096(%r3)
+; CHECK-NEXT: j .LBB5_2
+; CHECK-NEXT: .LBB5_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB5_2 Depth=1
+; CHECK-NEXT: csy %r2, %r0, 4096(%r3)
+; CHECK-NEXT: je .LBB5_4
+; CHECK-NEXT: .LBB5_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lr %r0, %r2
+; CHECK-NEXT: crjle %r2, %r4, .LBB5_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB5_2 Depth=1
+; CHECK-NEXT: lr %r0, %r4
+; CHECK-NEXT: j .LBB5_1
+; CHECK-NEXT: .LBB5_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%ptr = getelementptr i32, ptr %src, i64 1024
%res = atomicrmw min ptr %ptr, i32 %b seq_cst
ret i32 %res
@@ -96,9 +155,23 @@ define i32 @f6(i32 %dummy, ptr %src, i32 %b) {
; Check the high end of the aligned CSY range.
define i32 @f7(i32 %dummy, ptr %src, i32 %b) {
; CHECK-LABEL: f7:
-; CHECK: ly %r2, 524284(%r3)
-; CHECK: csy %r2, {{%r[0-9]+}}, 524284(%r3)
-; CHECK: ber %r14
+; CHECK: # %bb.0:
+; CHECK-NEXT: ly %r2, 524284(%r3)
+; CHECK-NEXT: j .LBB6_2
+; CHECK-NEXT: .LBB6_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB6_2 Depth=1
+; CHECK-NEXT: csy %r2, %r0, 524284(%r3)
+; CHECK-NEXT: je .LBB6_4
+; CHECK-NEXT: .LBB6_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lr %r0, %r2
+; CHECK-NEXT: crjle %r2, %r4, .LBB6_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB6_2 Depth=1
+; CHECK-NEXT: lr %r0, %r4
+; CHECK-NEXT: j .LBB6_1
+; CHECK-NEXT: .LBB6_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%ptr = getelementptr i32, ptr %src, i64 131071
%res = atomicrmw min ptr %ptr, i32 %b seq_cst
ret i32 %res
@@ -107,10 +180,24 @@ define i32 @f7(i32 %dummy, ptr %src, i32 %b) {
; Check the next word up, which needs separate address logic.
define i32 @f8(i32 %dummy, ptr %src, i32 %b) {
; CHECK-LABEL: f8:
-; CHECK: agfi %r3, 524288
-; CHECK: l %r2, 0(%r3)
-; CHECK: cs %r2, {{%r[0-9]+}}, 0(%r3)
-; CHECK: ber %r14
+; CHECK: # %bb.0:
+; CHECK-NEXT: agfi %r3, 524288
+; CHECK-NEXT: l %r2, 0(%r3)
+; CHECK-NEXT: j .LBB7_2
+; CHECK-NEXT: .LBB7_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB7_2 Depth=1
+; CHECK-NEXT: cs %r2, %r0, 0(%r3)
+; CHECK-NEXT: je .LBB7_4
+; CHECK-NEXT: .LBB7_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lr %r0, %r2
+; CHECK-NEXT: crjle %r2, %r4, .LBB7_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB7_2 Depth=1
+; CHECK-NEXT: lr %r0, %r4
+; CHECK-NEXT: j .LBB7_1
+; CHECK-NEXT: .LBB7_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%ptr = getelementptr i32, ptr %src, i64 131072
%res = atomicrmw min ptr %ptr, i32 %b seq_cst
ret i32 %res
@@ -119,9 +206,23 @@ define i32 @f8(i32 %dummy, ptr %src, i32 %b) {
; Check the high end of the negative aligned CSY range.
define i32 @f9(i32 %dummy, ptr %src, i32 %b) {
; CHECK-LABEL: f9:
-; CHECK: ly %r2, -4(%r3)
-; CHECK: csy %r2, {{%r[0-9]+}}, -4(%r3)
-; CHECK: ber %r14
+; CHECK: # %bb.0:
+; CHECK-NEXT: ly %r2, -4(%r3)
+; CHECK-NEXT: j .LBB8_2
+; CHECK-NEXT: .LBB8_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB8_2 Depth=1
+; CHECK-NEXT: csy %r2, %r0, -4(%r3)
+; CHECK-NEXT: je .LBB8_4
+; CHECK-NEXT: .LBB8_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lr %r0, %r2
+; CHECK-NEXT: crjle %r2, %r4, .LBB8_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB8_2 Depth=1
+; CHECK-NEXT: lr %r0, %r4
+; CHECK-NEXT: j .LBB8_1
+; CHECK-NEXT: .LBB8_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%ptr = getelementptr i32, ptr %src, i64 -1
%res = atomicrmw min ptr %ptr, i32 %b seq_cst
ret i32 %res
@@ -130,9 +231,23 @@ define i32 @f9(i32 %dummy, ptr %src, i32 %b) {
; Check the low end of the CSY range.
define i32 @f10(i32 %dummy, ptr %src, i32 %b) {
; CHECK-LABEL: f10:
-; CHECK: ly %r2, -524288(%r3)
-; CHECK: csy %r2, {{%r[0-9]+}}, -524288(%r3)
-; CHECK: ber %r14
+; CHECK: # %bb.0:
+; CHECK-NEXT: ly %r2, -524288(%r3)
+; CHECK-NEXT: j .LBB9_2
+; CHECK-NEXT: .LBB9_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB9_2 Depth=1
+; CHECK-NEXT: csy %r2, %r0, -524288(%r3)
+; CHECK-NEXT: je .LBB9_4
+; CHECK-NEXT: .LBB9_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lr %r0, %r2
+; CHECK-NEXT: crjle %r2, %r4, .LBB9_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB9_2 Depth=1
+; CHECK-NEXT: lr %r0, %r4
+; CHECK-NEXT: j .LBB9_1
+; CHECK-NEXT: .LBB9_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%ptr = getelementptr i32, ptr %src, i64 -131072
%res = atomicrmw min ptr %ptr, i32 %b seq_cst
ret i32 %res
@@ -141,10 +256,24 @@ define i32 @f10(i32 %dummy, ptr %src, i32 %b) {
; Check the next word down, which needs separate address logic.
define i32 @f11(i32 %dummy, ptr %src, i32 %b) {
; CHECK-LABEL: f11:
-; CHECK: agfi %r3, -524292
-; CHECK: l %r2, 0(%r3)
-; CHECK: cs %r2, {{%r[0-9]+}}, 0(%r3)
-; CHECK: ber %r14
+; CHECK: # %bb.0:
+; CHECK-NEXT: agfi %r3, -524292
+; CHECK-NEXT: l %r2, 0(%r3)
+; CHECK-NEXT: j .LBB10_2
+; CHECK-NEXT: .LBB10_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB10_2 Depth=1
+; CHECK-NEXT: cs %r2, %r0, 0(%r3)
+; CHECK-NEXT: je .LBB10_4
+; CHECK-NEXT: .LBB10_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lr %r0, %r2
+; CHECK-NEXT: crjle %r2, %r4, .LBB10_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB10_2 Depth=1
+; CHECK-NEXT: lr %r0, %r4
+; CHECK-NEXT: j .LBB10_1
+; CHECK-NEXT: .LBB10_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%ptr = getelementptr i32, ptr %src, i64 -131073
%res = atomicrmw min ptr %ptr, i32 %b seq_cst
ret i32 %res
@@ -153,10 +282,24 @@ define i32 @f11(i32 %dummy, ptr %src, i32 %b) {
; Check that indexed addresses are not allowed.
define i32 @f12(i32 %dummy, i64 %base, i64 %index, i32 %b) {
; CHECK-LABEL: f12:
-; CHECK: agr %r3, %r4
-; CHECK: l %r2, 0(%r3)
-; CHECK: cs %r2, {{%r[0-9]+}}, 0(%r3)
-; CHECK: ber %r14
+; CHECK: # %bb.0:
+; CHECK-NEXT: l %r2, 0(%r4,%r3)
+; CHECK-NEXT: agr %r3, %r4
+; CHECK-NEXT: j .LBB11_2
+; CHECK-NEXT: .LBB11_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB11_2 Depth=1
+; CHECK-NEXT: cs %r2, %r0, 0(%r3)
+; CHECK-NEXT: je .LBB11_4
+; CHECK-NEXT: .LBB11_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lr %r0, %r2
+; CHECK-NEXT: crjle %r2, %r5, .LBB11_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB11_2 Depth=1
+; CHECK-NEXT: lr %r0, %r5
+; CHECK-NEXT: j .LBB11_1
+; CHECK-NEXT: .LBB11_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%add = add i64 %base, %index
%ptr = inttoptr i64 %add to ptr
%res = atomicrmw min ptr %ptr, i32 %b seq_cst
@@ -166,16 +309,23 @@ define i32 @f12(i32 %dummy, i64 %base, i64 %index, i32 %b) {
; Check that constants are handled.
define i32 @f13(i32 %dummy, ptr %ptr) {
; CHECK-LABEL: f13:
-; CHECK: lhi [[LIMIT:%r[0-9]+]], 42
-; CHECK: j [[LOOP:\.[^:]*]]
-; CHECK: [[BB1:\.[^:]*]]:
-; CHECK: cs %r2, [[NEW:%r[0-9]+]], 0(%r3)
-; CHECK: ber %r14
-; CHECK: [[LOOP]]:
-; CHECK: lr [[NEW]], %r2
-; CHECK: crjle %r2, [[LIMIT]], [[KEEP:\..*]]
-; CHECK: lhi [[NEW]], 42
-; CHECK: j [[BB1]]
+; CHECK: # %bb.0:
+; CHECK-NEXT: l %r2, 0(%r3)
+; CHECK-NEXT: j .LBB12_2
+; CHECK-NEXT: .LBB12_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB12_2 Depth=1
+; CHECK-NEXT: cs %r2, %r0, 0(%r3)
+; CHECK-NEXT: je .LBB12_4
+; CHECK-NEXT: .LBB12_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lr %r0, %r2
+; CHECK-NEXT: cijl %r2, 43, .LBB12_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB12_2 Depth=1
+; CHECK-NEXT: lhi %r0, 42
+; CHECK-NEXT: j .LBB12_1
+; CHECK-NEXT: .LBB12_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%res = atomicrmw min ptr %ptr, i32 42 seq_cst
ret i32 %res
}
diff --git a/llvm/test/CodeGen/SystemZ/atomicrmw-minmax-04.ll b/llvm/test/CodeGen/SystemZ/atomicrmw-minmax-04.ll
index 64e76e0a90eaf..9352118a32f8a 100644
--- a/llvm/test/CodeGen/SystemZ/atomicrmw-minmax-04.ll
+++ b/llvm/test/CodeGen/SystemZ/atomicrmw-minmax-04.ll
@@ -1,21 +1,31 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
; Test 64-bit atomic minimum and maximum. Here we match the z10 versions,
; which can't use LOCGR.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
+; Todo: If-converter no longer producing CondReturns (with AtomicExpand pass).
+
; Check signed minimum.
define i64 @f1(i64 %dummy, ptr %src, i64 %b) {
; CHECK-LABEL: f1:
-; CHECK: lg %r2, 0(%r3)
-; CHECK: j [[LOOP:\.[^:]*]]
-; CHECK: [[BB1:\.[^:]*]]:
-; CHECK: csg %r2, [[NEW:%r[0-9]+]], 0(%r3)
-; CHECK: ber %r14
-; CHECK: [[LOOP:\.[^:]*]]:
-; CHECK: lgr [[NEW:%r[0-9]+]], %r2
-; CHECK: cgrjle %r2, %r4, [[KEEP:\..*]]
-; CHECK: lgr [[NEW]], %r4
-; CHECK: j [[BB1]]
+; CHECK: # %bb.0:
+; CHECK-NEXT: lg %r2, 0(%r3)
+; CHECK-NEXT: j .LBB0_2
+; CHECK-NEXT: .LBB0_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB0_2 Depth=1
+; CHECK-NEXT: csg %r2, %r0, 0(%r3)
+; CHECK-NEXT: je .LBB0_4
+; CHECK-NEXT: .LBB0_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lgr %r0, %r2
+; CHECK-NEXT: cgrjle %r2, %r4, .LBB0_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB0_2 Depth=1
+; CHECK-NEXT: lgr %r0, %r4
+; CHECK-NEXT: j .LBB0_1
+; CHECK-NEXT: .LBB0_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%res = atomicrmw min ptr %src, i64 %b seq_cst
ret i64 %res
}
@@ -23,16 +33,23 @@ define i64 @f1(i64 %dummy, ptr %src, i64 %b) {
; Check signed maximum.
define i64 @f2(i64 %dummy, ptr %src, i64 %b) {
; CHECK-LABEL: f2:
-; CHECK: lg %r2, 0(%r3)
-; CHECK: j [[LOOP:\.[^:]*]]
-; CHECK: [[BB1:\.[^:]*]]:
-; CHECK: csg %r2, [[NEW:%r[0-9]+]], 0(%r3)
-; CHECK: ber %r14
-; CHECK: [[LOOP:\.[^:]*]]:
-; CHECK: lgr [[NEW:%r[0-9]+]], %r2
-; CHECK: cgrjhe %r2, %r4, [[KEEP:\..*]]
-; CHECK: lgr [[NEW]], %r4
-; CHECK: j [[BB1]]
+; CHECK: # %bb.0:
+; CHECK-NEXT: lg %r2, 0(%r3)
+; CHECK-NEXT: j .LBB1_2
+; CHECK-NEXT: .LBB1_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB1_2 Depth=1
+; CHECK-NEXT: csg %r2, %r0, 0(%r3)
+; CHECK-NEXT: je .LBB1_4
+; CHECK-NEXT: .LBB1_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lgr %r0, %r2
+; CHECK-NEXT: cgrjh %r2, %r4, .LBB1_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB1_2 Depth=1
+; CHECK-NEXT: lgr %r0, %r4
+; CHECK-NEXT: j .LBB1_1
+; CHECK-NEXT: .LBB1_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%res = atomicrmw max ptr %src, i64 %b seq_cst
ret i64 %res
}
@@ -40,16 +57,23 @@ define i64 @f2(i64 %dummy, ptr %src, i64 %b) {
; Check unsigned minimum.
define i64 @f3(i64 %dummy, ptr %src, i64 %b) {
; CHECK-LABEL: f3:
-; CHECK: lg %r2, 0(%r3)
-; CHECK: j [[LOOP:\.[^:]*]]
-; CHECK: [[BB1:\.[^:]*]]:
-; CHECK: csg %r2, [[NEW:%r[0-9]+]], 0(%r3)
-; CHECK: ber %r14
-; CHECK: [[LOOP:\.[^:]*]]:
-; CHECK: lgr [[NEW:%r[0-9]+]], %r2
-; CHECK: clgrjle %r2, %r4, [[KEEP:\..*]]
-; CHECK: lgr [[NEW]], %r4
-; CHECK: j [[BB1]]
+; CHECK: # %bb.0:
+; CHECK-NEXT: lg %r2, 0(%r3)
+; CHECK-NEXT: j .LBB2_2
+; CHECK-NEXT: .LBB2_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB2_2 Depth=1
+; CHECK-NEXT: csg %r2, %r0, 0(%r3)
+; CHECK-NEXT: je .LBB2_4
+; CHECK-NEXT: .LBB2_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lgr %r0, %r2
+; CHECK-NEXT: clgrjle %r2, %r4, .LBB2_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB2_2 Depth=1
+; CHECK-NEXT: lgr %r0, %r4
+; CHECK-NEXT: j .LBB2_1
+; CHECK-NEXT: .LBB2_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%res = atomicrmw umin ptr %src, i64 %b seq_cst
ret i64 %res
}
@@ -57,16 +81,23 @@ define i64 @f3(i64 %dummy, ptr %src, i64 %b) {
; Check unsigned maximum.
define i64 @f4(i64 %dummy, ptr %src, i64 %b) {
; CHECK-LABEL: f4:
-; CHECK: lg %r2, 0(%r3)
-; CHECK: j [[LOOP:\.[^:]*]]
-; CHECK: [[BB1:\.[^:]*]]:
-; CHECK: csg %r2, [[NEW:%r[0-9]+]], 0(%r3)
-; CHECK: ber %r14
-; CHECK: [[LOOP:\.[^:]*]]:
-; CHECK: lgr [[NEW:%r[0-9]+]], %r2
-; CHECK: clgrjhe %r2, %r4, [[KEEP:\..*]]
-; CHECK: lgr [[NEW]], %r4
-; CHECK: j [[BB1]]
+; CHECK: # %bb.0:
+; CHECK-NEXT: lg %r2, 0(%r3)
+; CHECK-NEXT: j .LBB3_2
+; CHECK-NEXT: .LBB3_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB3_2 Depth=1
+; CHECK-NEXT: csg %r2, %r0, 0(%r3)
+; CHECK-NEXT: je .LBB3_4
+; CHECK-NEXT: .LBB3_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lgr %r0, %r2
+; CHECK-NEXT: clgrjh %r2, %r4, .LBB3_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB3_2 Depth=1
+; CHECK-NEXT: lgr %r0, %r4
+; CHECK-NEXT: j .LBB3_1
+; CHECK-NEXT: .LBB3_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%res = atomicrmw umax ptr %src, i64 %b seq_cst
ret i64 %res
}
@@ -74,9 +105,23 @@ define i64 @f4(i64 %dummy, ptr %src, i64 %b) {
; Check the high end of the aligned CSG range.
define i64 @f5(i64 %dummy, ptr %src, i64 %b) {
; CHECK-LABEL: f5:
-; CHECK: lg %r2, 524280(%r3)
-; CHECK: csg %r2, {{%r[0-9]+}}, 524280(%r3)
-; CHECK: ber %r14
+; CHECK: # %bb.0:
+; CHECK-NEXT: lg %r2, 524280(%r3)
+; CHECK-NEXT: j .LBB4_2
+; CHECK-NEXT: .LBB4_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB4_2 Depth=1
+; CHECK-NEXT: csg %r2, %r0, 524280(%r3)
+; CHECK-NEXT: je .LBB4_4
+; CHECK-NEXT: .LBB4_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lgr %r0, %r2
+; CHECK-NEXT: cgrjle %r2, %r4, .LBB4_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB4_2 Depth=1
+; CHECK-NEXT: lgr %r0, %r4
+; CHECK-NEXT: j .LBB4_1
+; CHECK-NEXT: .LBB4_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%ptr = getelementptr i64, ptr %src, i64 65535
%res = atomicrmw min ptr %ptr, i64 %b seq_cst
ret i64 %res
@@ -85,10 +130,24 @@ define i64 @f5(i64 %dummy, ptr %src, i64 %b) {
; Check the next doubleword up, which requires separate address logic.
define i64 @f6(i64 %dummy, ptr %src, i64 %b) {
; CHECK-LABEL: f6:
-; CHECK: agfi %r3, 524288
-; CHECK: lg %r2, 0(%r3)
-; CHECK: csg %r2, {{%r[0-9]+}}, 0(%r3)
-; CHECK: ber %r14
+; CHECK: # %bb.0:
+; CHECK-NEXT: agfi %r3, 524288
+; CHECK-NEXT: lg %r2, 0(%r3)
+; CHECK-NEXT: j .LBB5_2
+; CHECK-NEXT: .LBB5_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB5_2 Depth=1
+; CHECK-NEXT: csg %r2, %r0, 0(%r3)
+; CHECK-NEXT: je .LBB5_4
+; CHECK-NEXT: .LBB5_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lgr %r0, %r2
+; CHECK-NEXT: cgrjle %r2, %r4, .LBB5_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB5_2 Depth=1
+; CHECK-NEXT: lgr %r0, %r4
+; CHECK-NEXT: j .LBB5_1
+; CHECK-NEXT: .LBB5_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%ptr = getelementptr i64, ptr %src, i64 65536
%res = atomicrmw min ptr %ptr, i64 %b seq_cst
ret i64 %res
@@ -97,9 +156,23 @@ define i64 @f6(i64 %dummy, ptr %src, i64 %b) {
; Check the low end of the CSG range.
define i64 @f7(i64 %dummy, ptr %src, i64 %b) {
; CHECK-LABEL: f7:
-; CHECK: lg %r2, -524288(%r3)
-; CHECK: csg %r2, {{%r[0-9]+}}, -524288(%r3)
-; CHECK: ber %r14
+; CHECK: # %bb.0:
+; CHECK-NEXT: lg %r2, -524288(%r3)
+; CHECK-NEXT: j .LBB6_2
+; CHECK-NEXT: .LBB6_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB6_2 Depth=1
+; CHECK-NEXT: csg %r2, %r0, -524288(%r3)
+; CHECK-NEXT: je .LBB6_4
+; CHECK-NEXT: .LBB6_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lgr %r0, %r2
+; CHECK-NEXT: cgrjle %r2, %r4, .LBB6_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB6_2 Depth=1
+; CHECK-NEXT: lgr %r0, %r4
+; CHECK-NEXT: j .LBB6_1
+; CHECK-NEXT: .LBB6_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%ptr = getelementptr i64, ptr %src, i64 -65536
%res = atomicrmw min ptr %ptr, i64 %b seq_cst
ret i64 %res
@@ -108,10 +181,24 @@ define i64 @f7(i64 %dummy, ptr %src, i64 %b) {
; Check the next doubleword down, which requires separate address logic.
define i64 @f8(i64 %dummy, ptr %src, i64 %b) {
; CHECK-LABEL: f8:
-; CHECK: agfi %r3, -524296
-; CHECK: lg %r2, 0(%r3)
-; CHECK: csg %r2, {{%r[0-9]+}}, 0(%r3)
-; CHECK: ber %r14
+; CHECK: # %bb.0:
+; CHECK-NEXT: agfi %r3, -524296
+; CHECK-NEXT: lg %r2, 0(%r3)
+; CHECK-NEXT: j .LBB7_2
+; CHECK-NEXT: .LBB7_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB7_2 Depth=1
+; CHECK-NEXT: csg %r2, %r0, 0(%r3)
+; CHECK-NEXT: je .LBB7_4
+; CHECK-NEXT: .LBB7_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lgr %r0, %r2
+; CHECK-NEXT: cgrjle %r2, %r4, .LBB7_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB7_2 Depth=1
+; CHECK-NEXT: lgr %r0, %r4
+; CHECK-NEXT: j .LBB7_1
+; CHECK-NEXT: .LBB7_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%ptr = getelementptr i64, ptr %src, i64 -65537
%res = atomicrmw min ptr %ptr, i64 %b seq_cst
ret i64 %res
@@ -120,10 +207,24 @@ define i64 @f8(i64 %dummy, ptr %src, i64 %b) {
; Check that indexed addresses are not allowed.
define i64 @f9(i64 %dummy, i64 %base, i64 %index, i64 %b) {
; CHECK-LABEL: f9:
-; CHECK: agr %r3, %r4
-; CHECK: lg %r2, 0(%r3)
-; CHECK: csg %r2, {{%r[0-9]+}}, 0(%r3)
-; CHECK: ber %r14
+; CHECK: # %bb.0:
+; CHECK-NEXT: lg %r2, 0(%r4,%r3)
+; CHECK-NEXT: agr %r3, %r4
+; CHECK-NEXT: j .LBB8_2
+; CHECK-NEXT: .LBB8_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB8_2 Depth=1
+; CHECK-NEXT: csg %r2, %r0, 0(%r3)
+; CHECK-NEXT: je .LBB8_4
+; CHECK-NEXT: .LBB8_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lgr %r0, %r2
+; CHECK-NEXT: cgrjle %r2, %r5, .LBB8_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB8_2 Depth=1
+; CHECK-NEXT: lgr %r0, %r5
+; CHECK-NEXT: j .LBB8_1
+; CHECK-NEXT: .LBB8_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%add = add i64 %base, %index
%ptr = inttoptr i64 %add to ptr
%res = atomicrmw min ptr %ptr, i64 %b seq_cst
@@ -133,17 +234,23 @@ define i64 @f9(i64 %dummy, i64 %base, i64 %index, i64 %b) {
; Check that constants are handled.
define i64 @f10(i64 %dummy, ptr %ptr) {
; CHECK-LABEL: f10:
-; CHECK-DAG: lghi [[LIMIT:%r[0-9]+]], 42
-; CHECK-DAG: lg %r2, 0(%r3)
-; CHECK: j [[LOOP:\.[^:]*]]
-; CHECK: [[BB1:\.[^:]*]]:
-; CHECK: csg %r2, [[NEW:%r[0-9]+]], 0(%r3)
-; CHECK: ber %r14
-; CHECK: [[LOOP:\.[^:]*]]:
-; CHECK: lgr [[NEW:%r[0-9]+]], %r2
-; CHECK: cgrjle %r2, [[LIMIT]], [[KEEP:\..*]]
-; CHECK: lghi [[NEW]], 42
-; CHECK: j [[BB1]]
+; CHECK: # %bb.0:
+; CHECK-NEXT: lg %r2, 0(%r3)
+; CHECK-NEXT: j .LBB9_2
+; CHECK-NEXT: .LBB9_1: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB9_2 Depth=1
+; CHECK-NEXT: csg %r2, %r0, 0(%r3)
+; CHECK-NEXT: je .LBB9_4
+; CHECK-NEXT: .LBB9_2: # %atomicrmw.start
+; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: lgr %r0, %r2
+; CHECK-NEXT: cgijl %r2, 43, .LBB9_1
+; CHECK-NEXT: # %bb.3: # %atomicrmw.start
+; CHECK-NEXT: # in Loop: Header=BB9_2 Depth=1
+; CHECK-NEXT: lghi %r0, 42
+; CHECK-NEXT: j .LBB9_1
+; CHECK-NEXT: .LBB9_4: # %atomicrmw.end
+; CHECK-NEXT: br %r14
%res = atomicrmw min ptr %ptr, i64 42 seq_cst
ret i64 %res
}
diff --git a/llvm/test/CodeGen/SystemZ/atomicrmw-nand-03.ll b/llvm/test/CodeGen/SystemZ/atomicrmw-nand-03.ll
index 323eafb3e5b3a..8e9870f13013f 100644
--- a/llvm/test/CodeGen/SystemZ/atomicrmw-nand-03.ll
+++ b/llvm/test/CodeGen/SystemZ/atomicrmw-nand-03.ll
@@ -17,14 +17,14 @@ define i32 @f1(i32 %dummy, ptr %src, i32 %b) {
ret i32 %res
}
-; Check NANDs of 1.
+; Check NANDs with different constant operands.
define i32 @f2(i32 %dummy, ptr %src) {
; CHECK-LABEL: f2:
; CHECK: l %r2, 0(%r3)
; CHECK: [[LABEL:\.[^ ]*]]:
; CHECK: lr %r0, %r2
-; CHECK: nilf %r0, 1
; CHECK: xilf %r0, 4294967295
+; CHECK: oilf %r0, 4294967294
; CHECK: cs %r2, %r0, 0(%r3)
; CHECK: jl [[LABEL]]
; CHECK: br %r14
@@ -32,61 +32,55 @@ define i32 @f2(i32 %dummy, ptr %src) {
ret i32 %res
}
-; Check NANDs of the low end of the NILH range.
define i32 @f3(i32 %dummy, ptr %src) {
; CHECK-LABEL: f3:
-; CHECK: nilh %r0, 0
; CHECK: xilf %r0, 4294967295
+; CHECK: oilh %r0, 65535
; CHECK: br %r14
%res = atomicrmw nand ptr %src, i32 65535 seq_cst
ret i32 %res
}
-; Check the next value up, which must use NILF.
define i32 @f4(i32 %dummy, ptr %src) {
; CHECK-LABEL: f4:
-; CHECK: nilf %r0, 65536
; CHECK: xilf %r0, 4294967295
+; CHECK: oilf %r0, 4294901759
; CHECK: br %r14
%res = atomicrmw nand ptr %src, i32 65536 seq_cst
ret i32 %res
}
-; Check the largest useful NILL value.
define i32 @f5(i32 %dummy, ptr %src) {
; CHECK-LABEL: f5:
-; CHECK: nill %r0, 65534
; CHECK: xilf %r0, 4294967295
+; CHECK: oill %r0, 1
; CHECK: br %r14
%res = atomicrmw nand ptr %src, i32 -2 seq_cst
ret i32 %res
}
-; Check the low end of the NILL range.
define i32 @f6(i32 %dummy, ptr %src) {
; CHECK-LABEL: f6:
-; CHECK: nill %r0, 0
; CHECK: xilf %r0, 4294967295
+; CHECK: oill %r0, 65535
; CHECK: br %r14
%res = atomicrmw nand ptr %src, i32 -65536 seq_cst
ret i32 %res
}
-; Check the largest useful NILH value, which is one less than the above.
define i32 @f7(i32 %dummy, ptr %src) {
; CHECK-LABEL: f7:
-; CHECK: nilh %r0, 65534
; CHECK: xilf %r0, 4294967295
+; CHECK: oilh %r0, 1
; CHECK: br %r14
%res = atomicrmw nand ptr %src, i32 -65537 seq_cst
ret i32 %res
}
-; Check the highest useful NILF value, which is one less than the above.
define i32 @f8(i32 %dummy, ptr %src) {
; CHECK-LABEL: f8:
-; CHECK: nilf %r0, 4294901758
; CHECK: xilf %r0, 4294967295
+; CHECK: oilf %r0, 65537
; CHECK: br %r14
%res = atomicrmw nand ptr %src, i32 -65538 seq_cst
ret i32 %res
diff --git a/llvm/test/CodeGen/SystemZ/atomicrmw-nand-04.ll b/llvm/test/CodeGen/SystemZ/atomicrmw-nand-04.ll
index b37030255d7cc..98056c9c9a012 100644
--- a/llvm/test/CodeGen/SystemZ/atomicrmw-nand-04.ll
+++ b/llvm/test/CodeGen/SystemZ/atomicrmw-nand-04.ll
@@ -9,8 +9,8 @@ define i64 @f1(i64 %dummy, ptr %src, i64 %b) {
; CHECK: [[LABEL:\.[^:]*]]:
; CHECK: lgr %r0, %r2
; CHECK: ngr %r0, %r4
-; CHECK: lcgr %r0, %r0
-; CHECK: aghi %r0, -1
+; CHECK: xihf %r0, 4294967295
+; CHECK: xilf %r0, 4294967295
; CHECK: csg %r2, %r0, 0(%r3)
; CHECK: jl [[LABEL]]
; CHECK: br %r14
@@ -18,40 +18,39 @@ define i64 @f1(i64 %dummy, ptr %src, i64 %b) {
ret i64 %res
}
-; Check NANDs of 1, which are done using a register. (We could use RISBG
-; instead, but that isn't implemented yet.)
+; Check NANDs of 1, which are done using a register.
define i64 @f2(i64 %dummy, ptr %src) {
; CHECK-LABEL: f2:
-; CHECK: ngr
+; CHECK: xihf %r0, 4294967295
+; CHECK: xilf %r0, 4294967295
+; CHECK: oihf %r0, 4294967295
+; CHECK: oilf %r0, 4294967294
; CHECK: br %r14
%res = atomicrmw nand ptr %src, i64 1 seq_cst
ret i64 %res
}
-; Check the equivalent of NIHF with 1, which can use RISBG instead.
define i64 @f3(i64 %dummy, ptr %src) {
; CHECK-LABEL: f3:
; CHECK: lg %r2, 0(%r3)
; CHECK: [[LABEL:\.[^:]*]]:
-; CHECK: risbg %r0, %r2, 31, 191, 0
-; CHECK: lcgr %r0, %r0
-; CHECK: aghi %r0, -1
-; CHECK: csg %r2, %r0, 0(%r3)
+; CHECK: xihf %r0, 4294967295
+; CHECK: xilf %r0, 4294967295
+; CHECK: oihf %r0, 4294967294
; CHECK: jl [[LABEL]]
; CHECK: br %r14
%res = atomicrmw nand ptr %src, i64 8589934591 seq_cst
ret i64 %res
}
-; Check the lowest NIHF value outside the range of RISBG.
define i64 @f4(i64 %dummy, ptr %src) {
; CHECK-LABEL: f4:
; CHECK: lg %r2, 0(%r3)
; CHECK: [[LABEL:\.[^:]*]]:
; CHECK: lgr %r0, %r2
-; CHECK: nihf %r0, 2
-; CHECK: lcgr %r0, %r0
-; CHECK: aghi %r0, -1
+; CHECK: xihf %r0, 4294967295
+; CHECK: xilf %r0, 4294967295
+; CHECK: oihf %r0, 4294967293
; CHECK: csg %r2, %r0, 0(%r3)
; CHECK: jl [[LABEL]]
; CHECK: br %r14
@@ -59,118 +58,133 @@ define i64 @f4(i64 %dummy, ptr %src) {
ret i64 %res
}
-; Check the next value up, which must use a register.
define i64 @f5(i64 %dummy, ptr %src) {
; CHECK-LABEL: f5:
-; CHECK: ngr
+; CHECK: xihf %r0, 4294967295
+; CHECK: xilf %r0, 4294967295
+; CHECK: oihf %r0, 4294967292
+; CHECK: oilf %r0, 4294967295
; CHECK: br %r14
%res = atomicrmw nand ptr %src, i64 12884901888 seq_cst
ret i64 %res
}
-; Check the lowest NIHH value outside the range of RISBG.
define i64 @f6(i64 %dummy, ptr %src) {
; CHECK-LABEL: f6:
-; CHECK: nihh {{%r[0-5]}}, 2
+; CHECK: xihf %r0, 4294967295
+; CHECK: xilf %r0, 4294967295
+; CHECK: oihh %r0, 65533
; CHECK: br %r14
%res = atomicrmw nand ptr %src, i64 844424930131967 seq_cst
ret i64 %res
}
-; Check the next value up, which must use a register.
define i64 @f7(i64 %dummy, ptr %src) {
; CHECK-LABEL: f7:
-; CHECK: ngr
+; CHECK: xihf %r0, 4294967295
+; CHECK: xilf %r0, 4294967295
+; CHECK: oihf %r0, 4294901759
+; CHECK: oilf %r0, 4294967295
; CHECK: br %r14
%res = atomicrmw nand ptr %src, i64 281474976710656 seq_cst
ret i64 %res
}
-; Check the highest NILL value outside the range of RISBG.
define i64 @f8(i64 %dummy, ptr %src) {
; CHECK-LABEL: f8:
-; CHECK: nill {{%r[0-5]}}, 65530
+; CHECK: xihf %r0, 4294967295
+; CHECK: xilf %r0, 4294967295
+; CHECK: oill %r0, 5
; CHECK: br %r14
%res = atomicrmw nand ptr %src, i64 -6 seq_cst
ret i64 %res
}
-; Check the lowest NILL value outside the range of RISBG.
define i64 @f9(i64 %dummy, ptr %src) {
; CHECK-LABEL: f9:
-; CHECK: nill {{%r[0-5]}}, 2
+; CHECK: xihf %r0, 4294967295
+; CHECK: xilf %r0, 4294967295
+; CHECK: oill %r0, 65533
; CHECK: br %r14
%res = atomicrmw nand ptr %src, i64 -65534 seq_cst
ret i64 %res
}
-; Check the highest useful NILF value.
define i64 @f10(i64 %dummy, ptr %src) {
; CHECK-LABEL: f10:
-; CHECK: nilf {{%r[0-5]}}, 4294901758
+; CHECK: xihf %r0, 4294967295
+; CHECK: xilf %r0, 4294967295
+; CHECK: oilf %r0, 65537
; CHECK: br %r14
%res = atomicrmw nand ptr %src, i64 -65538 seq_cst
ret i64 %res
}
-; Check the highest NILH value outside the range of RISBG.
define i64 @f11(i64 %dummy, ptr %src) {
; CHECK-LABEL: f11:
-; CHECK: nilh {{%r[0-5]}}, 65530
+; CHECK: xihf %r0, 4294967295
+; CHECK: xilf %r0, 4294967295
+; CHECK: oilh %r0, 5
; CHECK: br %r14
%res = atomicrmw nand ptr %src, i64 -327681 seq_cst
ret i64 %res
}
-; Check the lowest NILH value outside the range of RISBG.
define i64 @f12(i64 %dummy, ptr %src) {
; CHECK-LABEL: f12:
-; CHECK: nilh {{%r[0-5]}}, 2
+; CHECK: xihf %r0, 4294967295
+; CHECK: xilf %r0, 4294967295
+; CHECK: oilh %r0, 65533
; CHECK: br %r14
%res = atomicrmw nand ptr %src, i64 -4294770689 seq_cst
ret i64 %res
}
-; Check the lowest NILF value outside the range of RISBG.
define i64 @f13(i64 %dummy, ptr %src) {
; CHECK-LABEL: f13:
-; CHECK: nilf {{%r[0-5]}}, 2
+; CHECK: xihf %r0, 4294967295
+; CHECK: xilf %r0, 4294967295
+; CHECK: oilf %r0, 4294967293
; CHECK: br %r14
%res = atomicrmw nand ptr %src, i64 -4294967294 seq_cst
ret i64 %res
}
-; Check the highest NIHL value outside the range of RISBG.
define i64 @f14(i64 %dummy, ptr %src) {
; CHECK-LABEL: f14:
-; CHECK: nihl {{%r[0-5]}}, 65530
+; CHECK: xihf %r0, 4294967295
+; CHECK: xilf %r0, 4294967295
+; CHECK: oihl %r0, 5
; CHECK: br %r14
%res = atomicrmw nand ptr %src, i64 -21474836481 seq_cst
ret i64 %res
}
-; Check the lowest NIHL value outside the range of RISBG.
define i64 @f15(i64 %dummy, ptr %src) {
; CHECK-LABEL: f15:
-; CHECK: nihl {{%r[0-5]}}, 2
+; CHECK: xihf %r0, 4294967295
+; CHECK: xilf %r0, 4294967295
+; CHECK: oihl %r0, 65533
; CHECK: br %r14
%res = atomicrmw nand ptr %src, i64 -281462091808769 seq_cst
ret i64 %res
}
-; Check the highest NIHH value outside the range of RISBG.
define i64 @f16(i64 %dummy, ptr %src) {
; CHECK-LABEL: f16:
-; CHECK: nihh {{%r[0-5]}}, 65530
+; CHECK: xihf %r0, 4294967295
+; CHECK: xilf %r0, 4294967295
+; CHECK: oihh %r0, 5
; CHECK: br %r14
%res = atomicrmw nand ptr %src, i64 -1407374883553281 seq_cst
ret i64 %res
}
-; Check the highest useful NIHF value.
define i64 @f17(i64 %dummy, ptr %src) {
; CHECK-LABEL: f17:
-; CHECK: nihf {{%r[0-5]}}, 4294901758
+; CHECK: xihf %r0, 4294967295
+; CHECK: xilf %r0, 4294967295
+; CHECK: oihf %r0, 65537
; CHECK: br %r14
%res = atomicrmw nand ptr %src, i64 -281479271677953 seq_cst
ret i64 %res
diff --git a/llvm/test/CodeGen/SystemZ/atomicrmw-or-04.ll b/llvm/test/CodeGen/SystemZ/atomicrmw-or-04.ll
index a1322df49dbf8..e29097b10e169 100644
--- a/llvm/test/CodeGen/SystemZ/atomicrmw-or-04.ll
+++ b/llvm/test/CodeGen/SystemZ/atomicrmw-or-04.ll
@@ -93,11 +93,11 @@ define i64 @f9(i64 %dummy, ptr %src) {
ret i64 %res
}
-; Check the next value up, which must use a register. (We could use
-; combinations of OIH* and OIL* instead, but that isn't implemented.)
+; Check the next value up, which must use a register.
define i64 @f10(i64 %dummy, ptr %src) {
; CHECK-LABEL: f10:
-; CHECK: ogr
+; CHECK: oihl %r0, 1
+; CHECK: oill %r0, 1
; CHECK: br %r14
%res = atomicrmw or ptr %src, i64 4294967297 seq_cst
ret i64 %res
@@ -139,10 +139,11 @@ define i64 @f14(i64 %dummy, ptr %src) {
ret i64 %res
}
-; Check the next value up, which must use a register.
+; Check the next value up.
define i64 @f15(i64 %dummy, ptr %src) {
; CHECK-LABEL: f15:
-; CHECK: ogr
+; CHECK: oihh %r0, 65535
+; CHECK: oill %r0, 1
; CHECK: br %r14
%res = atomicrmw or ptr %src, i64 18446462598732840961 seq_cst
ret i64 %res
diff --git a/llvm/test/CodeGen/SystemZ/atomicrmw-sub-04.ll b/llvm/test/CodeGen/SystemZ/atomicrmw-sub-04.ll
index 5d23d4e9ca155..d18c72f3b41e7 100644
--- a/llvm/test/CodeGen/SystemZ/atomicrmw-sub-04.ll
+++ b/llvm/test/CodeGen/SystemZ/atomicrmw-sub-04.ll
@@ -16,13 +16,12 @@ define i64 @f1(i64 %dummy, ptr %src, i64 %b) {
ret i64 %res
}
-; Check subtraction of 1, which can use AGHI.
+; Check subtraction of 1.
define i64 @f2(i64 %dummy, ptr %src) {
; CHECK-LABEL: f2:
; CHECK: lg %r2, 0(%r3)
; CHECK: [[LABEL:\.[^:]*]]:
-; CHECK: lgr %r0, %r2
-; CHECK: aghi %r0, -1
+; CHECK: lay %r0, -1(%r2)
; CHECK: csg %r2, %r0, 0(%r3)
; CHECK: jl [[LABEL]]
; CHECK: br %r14
@@ -30,82 +29,64 @@ define i64 @f2(i64 %dummy, ptr %src) {
ret i64 %res
}
-; Check the low end of the AGHI range.
+; Check use of LAY.
define i64 @f3(i64 %dummy, ptr %src) {
; CHECK-LABEL: f3:
-; CHECK: aghi %r0, -32768
+; CHECK: lay %r0, -32768(%r2)
; CHECK: br %r14
%res = atomicrmw sub ptr %src, i64 32768 seq_cst
ret i64 %res
}
-; Check the next value up, which must use AGFI.
+; Check the low end of the AGFI range.
define i64 @f4(i64 %dummy, ptr %src) {
; CHECK-LABEL: f4:
-; CHECK: agfi %r0, -32769
+; CHECK: agfi %r0, -2147483648
; CHECK: br %r14
- %res = atomicrmw sub ptr %src, i64 32769 seq_cst
+ %res = atomicrmw sub ptr %src, i64 2147483648 seq_cst
ret i64 %res
}
-; Check the low end of the AGFI range.
+; Check the next value up, which uses an SLGFI.
define i64 @f5(i64 %dummy, ptr %src) {
; CHECK-LABEL: f5:
-; CHECK: agfi %r0, -2147483648
+; CHECK: slgfi
; CHECK: br %r14
- %res = atomicrmw sub ptr %src, i64 2147483648 seq_cst
+ %res = atomicrmw sub ptr %src, i64 2147483649 seq_cst
ret i64 %res
}
-; Check the next value up, which must use a register operation.
+; Check subtraction of -1, which can use LA.
define i64 @f6(i64 %dummy, ptr %src) {
; CHECK-LABEL: f6:
-; CHECK: sgr
+; CHECK: la %r0, 1(%r2)
; CHECK: br %r14
- %res = atomicrmw sub ptr %src, i64 2147483649 seq_cst
+ %res = atomicrmw sub ptr %src, i64 -1 seq_cst
ret i64 %res
}
-; Check subtraction of -1, which can use AGHI.
+; Check use of LAY.
define i64 @f7(i64 %dummy, ptr %src) {
; CHECK-LABEL: f7:
-; CHECK: aghi %r0, 1
-; CHECK: br %r14
- %res = atomicrmw sub ptr %src, i64 -1 seq_cst
- ret i64 %res
-}
-
-; Check the high end of the AGHI range.
-define i64 @f8(i64 %dummy, ptr %src) {
-; CHECK-LABEL: f8:
-; CHECK: aghi %r0, 32767
+; CHECK: lay %r0, 32767(%r2)
; CHECK: br %r14
%res = atomicrmw sub ptr %src, i64 -32767 seq_cst
ret i64 %res
}
-; Check the next value down, which must use AGFI instead.
-define i64 @f9(i64 %dummy, ptr %src) {
-; CHECK-LABEL: f9:
-; CHECK: agfi %r0, 32768
-; CHECK: br %r14
- %res = atomicrmw sub ptr %src, i64 -32768 seq_cst
- ret i64 %res
-}
-
; Check the high end of the AGFI range.
-define i64 @f10(i64 %dummy, ptr %src) {
-; CHECK-LABEL: f10:
+define i64 @f8(i64 %dummy, ptr %src) {
+; CHECK-LABEL: f8:
; CHECK: agfi %r0, 2147483647
; CHECK: br %r14
%res = atomicrmw sub ptr %src, i64 -2147483647 seq_cst
ret i64 %res
}
-; Check the next value down, which must use a register operation.
-define i64 @f11(i64 %dummy, ptr %src) {
-; CHECK-LABEL: f11:
-; CHECK: sgr
+; Check the next value down, which must use an ALGFI.
+define i64 @f9(i64 %dummy, ptr %src) {
+; CHECK-LABEL: f9:
+; CHECK: algfi
; CHECK: br %r14
%res = atomicrmw sub ptr %src, i64 -2147483648 seq_cst
ret i64 %res
diff --git a/llvm/test/CodeGen/SystemZ/atomicrmw-xchg-03.ll b/llvm/test/CodeGen/SystemZ/atomicrmw-xchg-03.ll
index cf366b9f2e29a..d991997245089 100644
--- a/llvm/test/CodeGen/SystemZ/atomicrmw-xchg-03.ll
+++ b/llvm/test/CodeGen/SystemZ/atomicrmw-xchg-03.ll
@@ -96,8 +96,8 @@ define i32 @f8(i32 %dummy, ptr %src, i32 %b) {
; Check that indexed addresses are not allowed.
define i32 @f9(i32 %dummy, i64 %base, i64 %index, i32 %b) {
; CHECK-LABEL: f9:
+; CHECK: l %r2, 0(%r4,%r3)
; CHECK: agr %r3, %r4
-; CHECK: l %r2, 0(%r3)
; CHECK: cs %r2, {{%r[0-9]+}}, 0(%r3)
; CHECK: br %r14
%add = add i64 %base, %index
diff --git a/llvm/test/CodeGen/SystemZ/atomicrmw-xchg-04.ll b/llvm/test/CodeGen/SystemZ/atomicrmw-xchg-04.ll
index 9a493cb7fd8c7..4797c5cf06798 100644
--- a/llvm/test/CodeGen/SystemZ/atomicrmw-xchg-04.ll
+++ b/llvm/test/CodeGen/SystemZ/atomicrmw-xchg-04.ll
@@ -63,8 +63,8 @@ define i64 @f5(i64 %dummy, ptr %src, i64 %b) {
; Check that indexed addresses are not allowed.
define i64 @f6(i64 %dummy, i64 %base, i64 %index, i64 %b) {
; CHECK-LABEL: f6:
+; CHECK: lg %r2, 0(%r4,%r3)
; CHECK: agr %r3, %r4
-; CHECK: lg %r2, 0(%r3)
; CHECK: csg %r2, {{%r[0-9]+}}, 0(%r3)
; CHECK: br %r14
%add = add i64 %base, %index
diff --git a/llvm/test/CodeGen/SystemZ/atomicrmw-xor-04.ll b/llvm/test/CodeGen/SystemZ/atomicrmw-xor-04.ll
index 6cf1b80b8d0cd..ee5fc1cf415dc 100644
--- a/llvm/test/CodeGen/SystemZ/atomicrmw-xor-04.ll
+++ b/llvm/test/CodeGen/SystemZ/atomicrmw-xor-04.ll
@@ -48,11 +48,11 @@ define i64 @f4(i64 %dummy, ptr %src) {
ret i64 %res
}
-; Check the next value up, which must use a register. (We could use
-; combinations of XIH* and XIL* instead, but that isn't implemented.)
+; Check the next value up.
define i64 @f5(i64 %dummy, ptr %src) {
; CHECK-LABEL: f5:
-; CHECK: xgr
+; CHECK: xihf %r0, 1
+; CHECK: xilf %r0, 1
; CHECK: br %r14
%res = atomicrmw xor ptr %src, i64 4294967297 seq_cst
ret i64 %res
@@ -70,7 +70,8 @@ define i64 @f6(i64 %dummy, ptr %src) {
; Check the next value up, which must use a register.
define i64 @f7(i64 %dummy, ptr %src) {
; CHECK-LABEL: f7:
-; CHECK: xgr
+; CHECK: xihf %r0, 4294967295
+; CHECK: xilf %r0, 1
; CHECK: br %r14
%res = atomicrmw xor ptr %src, i64 -4294967295 seq_cst
ret i64 %res
More information about the llvm-commits
mailing list