Skip to content

Commit 15868eb

Browse files
committed
Add usub_cond and usub_sat operations to atomicrmw
These both perform conditional subtraction, returning the minuend and zero respectively, if the difference is negative. AMDGPU has instructions for these. Currently we use target intrinsics for these, but those do not carry the ordering and syncscope. Add these to atomicrmw so we can carry these and benefit from the regular legalization processes.
1 parent 933f722 commit 15868eb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+4448
-71
lines changed

llvm/bindings/ocaml/llvm/llvm.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,8 @@ module AtomicRMWBinOp = struct
300300
| FMin
301301
| UInc_Wrap
302302
| UDec_Wrap
303+
| USub_Cond
304+
| USub_Sat
303305
end
304306

305307
module ValueKind = struct

llvm/bindings/ocaml/llvm/llvm.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,8 @@ module AtomicRMWBinOp : sig
335335
| FMin
336336
| UInc_Wrap
337337
| UDec_Wrap
338+
| USub_Cond
339+
| USub_Sat
338340
end
339341

340342
(** The kind of an [llvalue], the result of [classify_value v].

llvm/docs/GlobalISel/GenericOpcode.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,9 @@ operands.
863863
G_ATOMICRMW_MIN, G_ATOMICRMW_UMAX,
864864
G_ATOMICRMW_UMIN, G_ATOMICRMW_FADD,
865865
G_ATOMICRMW_FSUB, G_ATOMICRMW_FMAX,
866-
G_ATOMICRMW_FMIN
866+
G_ATOMICRMW_FMIN, G_ATOMICRMW_UINC_WRAP,
867+
G_ATOMICRMW_UDEC_WRAP, G_ATOMICRMW_USUB_COND,
868+
G_ATOMICRMW_USUB_SAT
867869

868870
Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
869871
operands.

llvm/docs/LangRef.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11241,6 +11241,8 @@ operation. The operation must be one of the following keywords:
1124111241
- fmin
1124211242
- uinc_wrap
1124311243
- udec_wrap
11244+
- usub_cond
11245+
- usub_sat
1124411246

1124511247
For most of these operations, the type of '<value>' must be an integer
1124611248
type whose bit width is a power of two greater than or equal to eight
@@ -11291,6 +11293,8 @@ operation argument:
1129111293
- fmin: ``*ptr = minnum(*ptr, val)`` (match the `llvm.minnum.*`` intrinsic)
1129211294
- uinc_wrap: ``*ptr = (*ptr u>= val) ? 0 : (*ptr + 1)`` (increment value with wraparound to zero when incremented above input value)
1129311295
- udec_wrap: ``*ptr = ((*ptr == 0) || (*ptr u> val)) ? val : (*ptr - 1)`` (decrement with wraparound to input value when decremented below zero).
11296+
- usub_cond: ``*ptr = (*ptr u>= val) ? *ptr - val : *ptr`` (subtract only if no unsigned overflow).
11297+
- usub_sat: ``*ptr = (*ptr u>= val) ? *ptr - val : 0`` (subtract with clamping to zero).
1129411298

1129511299

1129611300
Example:

llvm/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ Changes to the LLVM IR
5353
* The ``x86_mmx`` IR type has been removed. It will be translated to
5454
the standard vector type ``<1 x i64>`` in bitcode upgrade.
5555

56+
* Added ``usub_cond`` and ``usub_sat`` operations to ``atomicrmw``.
57+
5658
Changes to LLVM infrastructure
5759
------------------------------
5860

llvm/include/llvm/AsmParser/LLToken.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,8 @@ enum Kind {
268268
kw_fmin,
269269
kw_uinc_wrap,
270270
kw_udec_wrap,
271+
kw_usub_cond,
272+
kw_usub_sat,
271273

272274
// Instruction Opcodes (Opcode in UIntVal).
273275
kw_fneg,

llvm/include/llvm/Bitcode/LLVMBitCodes.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,9 @@ enum RMWOperations {
485485
RMW_FMAX = 13,
486486
RMW_FMIN = 14,
487487
RMW_UINC_WRAP = 15,
488-
RMW_UDEC_WRAP = 16
488+
RMW_UDEC_WRAP = 16,
489+
RMW_USUB_COND = 17,
490+
RMW_USUB_SAT = 18
489491
};
490492

491493
/// OverflowingBinaryOperatorOptionalFlags - Flags for serializing

llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1636,6 +1636,41 @@ class MachineIRBuilder {
16361636
const DstOp &OldValRes, const SrcOp &Addr, const SrcOp &Val,
16371637
MachineMemOperand &MMO);
16381638

1639+
/// Build and insert `OldValRes<def> = G_ATOMICRMW_USUB_COND Addr, Val, MMO`.
1640+
///
1641+
/// Atomically replace the value at \p Addr with the original value minus \p
1642+
/// Val if the original value is greater than or equal to \p Val, or leaves it
1643+
/// unchanged otherwise. Puts the original value from \p Addr in \p OldValRes.
1644+
///
1645+
/// \pre setBasicBlock or setMI must have been called.
1646+
/// \pre \p OldValRes must be a generic virtual register.
1647+
/// \pre \p Addr must be a generic virtual register with pointer type.
1648+
/// \pre \p OldValRes, and \p Val must be generic virtual registers of the
1649+
/// same type.
1650+
///
1651+
/// \return a MachineInstrBuilder for the newly created instruction.
1652+
MachineInstrBuilder buildAtomicRMWUSubCond(const DstOp &OldValRes,
1653+
const SrcOp &Addr,
1654+
const SrcOp &Val,
1655+
MachineMemOperand &MMO);
1656+
1657+
/// Build and insert `OldValRes<def> = G_ATOMICRMW_USUB_SAT Addr, Val, MMO`.
1658+
///
1659+
/// Atomically replace the value at \p Addr with the original value minus \p
1660+
/// Val if the original value is greater than or equal to \p Val, or with zero
1661+
/// otherwise. Puts the original value from \p Addr in \p OldValRes.
1662+
///
1663+
/// \pre setBasicBlock or setMI must have been called.
1664+
/// \pre \p OldValRes must be a generic virtual register.
1665+
/// \pre \p Addr must be a generic virtual register with pointer type.
1666+
/// \pre \p OldValRes, and \p Val must be generic virtual registers of the
1667+
/// same type.
1668+
///
1669+
/// \return a MachineInstrBuilder for the newly created instruction.
1670+
MachineInstrBuilder buildAtomicRMWUSubSat(const DstOp &OldValRes,
1671+
const SrcOp &Addr, const SrcOp &Val,
1672+
MachineMemOperand &MMO);
1673+
16391674
/// Build and insert `G_FENCE Ordering, Scope`.
16401675
MachineInstrBuilder buildFence(unsigned Ordering, unsigned Scope);
16411676

llvm/include/llvm/CodeGen/ISDOpcodes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,6 +1345,8 @@ enum NodeType {
13451345
ATOMIC_LOAD_FMIN,
13461346
ATOMIC_LOAD_UINC_WRAP,
13471347
ATOMIC_LOAD_UDEC_WRAP,
1348+
ATOMIC_LOAD_USUB_COND,
1349+
ATOMIC_LOAD_USUB_SAT,
13481350

13491351
/// Masked load and store - consecutive vector load and store operations
13501352
/// with additional mask operand that prevents memory accesses to the

llvm/include/llvm/CodeGen/SelectionDAGNodes.h

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,6 +1484,8 @@ class MemSDNode : public SDNode {
14841484
case ISD::ATOMIC_LOAD_FMIN:
14851485
case ISD::ATOMIC_LOAD_UINC_WRAP:
14861486
case ISD::ATOMIC_LOAD_UDEC_WRAP:
1487+
case ISD::ATOMIC_LOAD_USUB_COND:
1488+
case ISD::ATOMIC_LOAD_USUB_SAT:
14871489
case ISD::ATOMIC_LOAD:
14881490
case ISD::ATOMIC_STORE:
14891491
case ISD::MLOAD:
@@ -1550,27 +1552,29 @@ class AtomicSDNode : public MemSDNode {
15501552

15511553
// Methods to support isa and dyn_cast
15521554
static bool classof(const SDNode *N) {
1553-
return N->getOpcode() == ISD::ATOMIC_CMP_SWAP ||
1555+
return N->getOpcode() == ISD::ATOMIC_CMP_SWAP ||
15541556
N->getOpcode() == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS ||
1555-
N->getOpcode() == ISD::ATOMIC_SWAP ||
1556-
N->getOpcode() == ISD::ATOMIC_LOAD_ADD ||
1557-
N->getOpcode() == ISD::ATOMIC_LOAD_SUB ||
1558-
N->getOpcode() == ISD::ATOMIC_LOAD_AND ||
1559-
N->getOpcode() == ISD::ATOMIC_LOAD_CLR ||
1560-
N->getOpcode() == ISD::ATOMIC_LOAD_OR ||
1561-
N->getOpcode() == ISD::ATOMIC_LOAD_XOR ||
1562-
N->getOpcode() == ISD::ATOMIC_LOAD_NAND ||
1563-
N->getOpcode() == ISD::ATOMIC_LOAD_MIN ||
1564-
N->getOpcode() == ISD::ATOMIC_LOAD_MAX ||
1565-
N->getOpcode() == ISD::ATOMIC_LOAD_UMIN ||
1566-
N->getOpcode() == ISD::ATOMIC_LOAD_UMAX ||
1567-
N->getOpcode() == ISD::ATOMIC_LOAD_FADD ||
1568-
N->getOpcode() == ISD::ATOMIC_LOAD_FSUB ||
1569-
N->getOpcode() == ISD::ATOMIC_LOAD_FMAX ||
1570-
N->getOpcode() == ISD::ATOMIC_LOAD_FMIN ||
1557+
N->getOpcode() == ISD::ATOMIC_SWAP ||
1558+
N->getOpcode() == ISD::ATOMIC_LOAD_ADD ||
1559+
N->getOpcode() == ISD::ATOMIC_LOAD_SUB ||
1560+
N->getOpcode() == ISD::ATOMIC_LOAD_AND ||
1561+
N->getOpcode() == ISD::ATOMIC_LOAD_CLR ||
1562+
N->getOpcode() == ISD::ATOMIC_LOAD_OR ||
1563+
N->getOpcode() == ISD::ATOMIC_LOAD_XOR ||
1564+
N->getOpcode() == ISD::ATOMIC_LOAD_NAND ||
1565+
N->getOpcode() == ISD::ATOMIC_LOAD_MIN ||
1566+
N->getOpcode() == ISD::ATOMIC_LOAD_MAX ||
1567+
N->getOpcode() == ISD::ATOMIC_LOAD_UMIN ||
1568+
N->getOpcode() == ISD::ATOMIC_LOAD_UMAX ||
1569+
N->getOpcode() == ISD::ATOMIC_LOAD_FADD ||
1570+
N->getOpcode() == ISD::ATOMIC_LOAD_FSUB ||
1571+
N->getOpcode() == ISD::ATOMIC_LOAD_FMAX ||
1572+
N->getOpcode() == ISD::ATOMIC_LOAD_FMIN ||
15711573
N->getOpcode() == ISD::ATOMIC_LOAD_UINC_WRAP ||
15721574
N->getOpcode() == ISD::ATOMIC_LOAD_UDEC_WRAP ||
1573-
N->getOpcode() == ISD::ATOMIC_LOAD ||
1575+
N->getOpcode() == ISD::ATOMIC_LOAD_USUB_COND ||
1576+
N->getOpcode() == ISD::ATOMIC_LOAD_USUB_SAT ||
1577+
N->getOpcode() == ISD::ATOMIC_LOAD ||
15741578
N->getOpcode() == ISD::ATOMIC_STORE;
15751579
}
15761580
};

llvm/include/llvm/IR/Instructions.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -751,8 +751,16 @@ class AtomicRMWInst : public Instruction {
751751
/// *p = ((old == 0) || (old u> v)) ? v : (old - 1)
752752
UDecWrap,
753753

754+
/// Subtract only if result would be positive.
755+
/// *p = (old u>= v) ? old - v : old
756+
USubCond,
757+
758+
/// Subtract with clamping of negative results to zero.
759+
/// *p = (old u>= v) ? old - v : 0
760+
USubSat,
761+
754762
FIRST_BINOP = Xchg,
755-
LAST_BINOP = UDecWrap,
763+
LAST_BINOP = USubSat,
756764
BAD_BINOP
757765
};
758766

llvm/include/llvm/Support/TargetOpcodes.def

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,12 +414,14 @@ HANDLE_TARGET_OPCODE(G_ATOMICRMW_FMAX)
414414
HANDLE_TARGET_OPCODE(G_ATOMICRMW_FMIN)
415415
HANDLE_TARGET_OPCODE(G_ATOMICRMW_UINC_WRAP)
416416
HANDLE_TARGET_OPCODE(G_ATOMICRMW_UDEC_WRAP)
417+
HANDLE_TARGET_OPCODE(G_ATOMICRMW_USUB_COND)
418+
HANDLE_TARGET_OPCODE(G_ATOMICRMW_USUB_SAT)
417419

418420
// Marker for start of Generic AtomicRMW opcodes
419421
HANDLE_TARGET_OPCODE_MARKER(GENERIC_ATOMICRMW_OP_START, G_ATOMICRMW_XCHG)
420422

421423
// Marker for end of Generic AtomicRMW opcodes
422-
HANDLE_TARGET_OPCODE_MARKER(GENERIC_ATOMICRMW_OP_END, G_ATOMICRMW_UDEC_WRAP)
424+
HANDLE_TARGET_OPCODE_MARKER(GENERIC_ATOMICRMW_OP_END, G_ATOMICRMW_USUB_SAT)
423425

424426
// Generic atomic fence
425427
HANDLE_TARGET_OPCODE(G_FENCE)

llvm/include/llvm/Target/GenericOpcodes.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,6 +1311,8 @@ def G_ATOMICRMW_FMAX : G_ATOMICRMW_OP;
13111311
def G_ATOMICRMW_FMIN : G_ATOMICRMW_OP;
13121312
def G_ATOMICRMW_UINC_WRAP : G_ATOMICRMW_OP;
13131313
def G_ATOMICRMW_UDEC_WRAP : G_ATOMICRMW_OP;
1314+
def G_ATOMICRMW_USUB_COND : G_ATOMICRMW_OP;
1315+
def G_ATOMICRMW_USUB_SAT : G_ATOMICRMW_OP;
13141316

13151317
def G_FENCE : GenericInstruction {
13161318
let OutOperandList = (outs);

llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@ def : GINodeEquiv<G_ATOMICRMW_FMAX, atomic_load_fmax>;
259259
def : GINodeEquiv<G_ATOMICRMW_FMIN, atomic_load_fmin>;
260260
def : GINodeEquiv<G_ATOMICRMW_UINC_WRAP, atomic_load_uinc_wrap>;
261261
def : GINodeEquiv<G_ATOMICRMW_UDEC_WRAP, atomic_load_udec_wrap>;
262+
def : GINodeEquiv<G_ATOMICRMW_USUB_COND, atomic_load_usub_cond>;
263+
def : GINodeEquiv<G_ATOMICRMW_USUB_SAT, atomic_load_usub_sat>;
262264
def : GINodeEquiv<G_FENCE, atomic_fence>;
263265
def : GINodeEquiv<G_PREFETCH, prefetch>;
264266
def : GINodeEquiv<G_TRAP, trap>;

llvm/include/llvm/Target/TargetSelectionDAG.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,10 @@ def atomic_load_uinc_wrap : SDNode<"ISD::ATOMIC_LOAD_UINC_WRAP", SDTAtomic2,
753753
[SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
754754
def atomic_load_udec_wrap : SDNode<"ISD::ATOMIC_LOAD_UDEC_WRAP", SDTAtomic2,
755755
[SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
756+
def atomic_load_usub_cond : SDNode<"ISD::ATOMIC_LOAD_USUB_COND", SDTAtomic2,
757+
[SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
758+
def atomic_load_usub_sat : SDNode<"ISD::ATOMIC_LOAD_USUB_SAT", SDTAtomic2,
759+
[SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
756760

757761
def atomic_load : SDNode<"ISD::ATOMIC_LOAD", SDTAtomicLoad,
758762
[SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;

llvm/lib/AsmParser/LLLexer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,8 @@ lltok::Kind LLLexer::LexIdentifier() {
704704
KEYWORD(umin); KEYWORD(fmax); KEYWORD(fmin);
705705
KEYWORD(uinc_wrap);
706706
KEYWORD(udec_wrap);
707+
KEYWORD(usub_cond);
708+
KEYWORD(usub_sat);
707709

708710
KEYWORD(splat);
709711
KEYWORD(vscale);

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8352,6 +8352,12 @@ int LLParser::parseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) {
83528352
case lltok::kw_udec_wrap:
83538353
Operation = AtomicRMWInst::UDecWrap;
83548354
break;
8355+
case lltok::kw_usub_cond:
8356+
Operation = AtomicRMWInst::USubCond;
8357+
break;
8358+
case lltok::kw_usub_sat:
8359+
Operation = AtomicRMWInst::USubSat;
8360+
break;
83558361
case lltok::kw_fadd:
83568362
Operation = AtomicRMWInst::FAdd;
83578363
IsFP = true;

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,6 +1349,10 @@ static AtomicRMWInst::BinOp getDecodedRMWOperation(unsigned Val) {
13491349
return AtomicRMWInst::UIncWrap;
13501350
case bitc::RMW_UDEC_WRAP:
13511351
return AtomicRMWInst::UDecWrap;
1352+
case bitc::RMW_USUB_COND:
1353+
return AtomicRMWInst::USubCond;
1354+
case bitc::RMW_USUB_SAT:
1355+
return AtomicRMWInst::USubSat;
13521356
}
13531357
}
13541358

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,10 @@ static unsigned getEncodedRMWOperation(AtomicRMWInst::BinOp Op) {
668668
return bitc::RMW_UINC_WRAP;
669669
case AtomicRMWInst::UDecWrap:
670670
return bitc::RMW_UDEC_WRAP;
671+
case AtomicRMWInst::USubCond:
672+
return bitc::RMW_USUB_COND;
673+
case AtomicRMWInst::USubSat:
674+
return bitc::RMW_USUB_SAT;
671675
}
672676
}
673677

llvm/lib/CodeGen/AtomicExpandPass.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -888,7 +888,9 @@ static Value *performMaskedAtomicOp(AtomicRMWInst::BinOp Op,
888888
case AtomicRMWInst::FMin:
889889
case AtomicRMWInst::FMax:
890890
case AtomicRMWInst::UIncWrap:
891-
case AtomicRMWInst::UDecWrap: {
891+
case AtomicRMWInst::UDecWrap:
892+
case AtomicRMWInst::USubCond:
893+
case AtomicRMWInst::USubSat: {
892894
// Finally, other ops will operate on the full value, so truncate down to
893895
// the original size, and expand out again after doing the
894896
// operation. Bitcasts will be inserted for FP values.
@@ -1562,6 +1564,8 @@ bool AtomicExpandImpl::isIdempotentRMW(AtomicRMWInst *RMWI) {
15621564
case AtomicRMWInst::Sub:
15631565
case AtomicRMWInst::Or:
15641566
case AtomicRMWInst::Xor:
1567+
case AtomicRMWInst::USubCond:
1568+
case AtomicRMWInst::USubSat:
15651569
return C->isZero();
15661570
case AtomicRMWInst::And:
15671571
return C->isMinusOne();
@@ -1803,6 +1807,8 @@ static ArrayRef<RTLIB::Libcall> GetRMWLibcall(AtomicRMWInst::BinOp Op) {
18031807
case AtomicRMWInst::FSub:
18041808
case AtomicRMWInst::UIncWrap:
18051809
case AtomicRMWInst::UDecWrap:
1810+
case AtomicRMWInst::USubCond:
1811+
case AtomicRMWInst::USubSat:
18061812
// No atomic libcalls are available for max/min/umax/umin.
18071813
return {};
18081814
}

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3301,6 +3301,12 @@ bool IRTranslator::translateAtomicRMW(const User &U,
33013301
case AtomicRMWInst::UDecWrap:
33023302
Opcode = TargetOpcode::G_ATOMICRMW_UDEC_WRAP;
33033303
break;
3304+
case AtomicRMWInst::USubCond:
3305+
Opcode = TargetOpcode::G_ATOMICRMW_USUB_COND;
3306+
break;
3307+
case AtomicRMWInst::USubSat:
3308+
Opcode = TargetOpcode::G_ATOMICRMW_USUB_SAT;
3309+
break;
33043310
}
33053311

33063312
MIRBuilder.buildAtomicRMW(

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8712,24 +8712,18 @@ SDValue SelectionDAG::getAtomicCmpSwap(unsigned Opcode, const SDLoc &dl,
87128712
SDValue SelectionDAG::getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT,
87138713
SDValue Chain, SDValue Ptr, SDValue Val,
87148714
MachineMemOperand *MMO) {
8715-
assert((Opcode == ISD::ATOMIC_LOAD_ADD ||
8716-
Opcode == ISD::ATOMIC_LOAD_SUB ||
8717-
Opcode == ISD::ATOMIC_LOAD_AND ||
8718-
Opcode == ISD::ATOMIC_LOAD_CLR ||
8719-
Opcode == ISD::ATOMIC_LOAD_OR ||
8720-
Opcode == ISD::ATOMIC_LOAD_XOR ||
8721-
Opcode == ISD::ATOMIC_LOAD_NAND ||
8722-
Opcode == ISD::ATOMIC_LOAD_MIN ||
8723-
Opcode == ISD::ATOMIC_LOAD_MAX ||
8724-
Opcode == ISD::ATOMIC_LOAD_UMIN ||
8725-
Opcode == ISD::ATOMIC_LOAD_UMAX ||
8726-
Opcode == ISD::ATOMIC_LOAD_FADD ||
8727-
Opcode == ISD::ATOMIC_LOAD_FSUB ||
8728-
Opcode == ISD::ATOMIC_LOAD_FMAX ||
8715+
assert((Opcode == ISD::ATOMIC_LOAD_ADD || Opcode == ISD::ATOMIC_LOAD_SUB ||
8716+
Opcode == ISD::ATOMIC_LOAD_AND || Opcode == ISD::ATOMIC_LOAD_CLR ||
8717+
Opcode == ISD::ATOMIC_LOAD_OR || Opcode == ISD::ATOMIC_LOAD_XOR ||
8718+
Opcode == ISD::ATOMIC_LOAD_NAND || Opcode == ISD::ATOMIC_LOAD_MIN ||
8719+
Opcode == ISD::ATOMIC_LOAD_MAX || Opcode == ISD::ATOMIC_LOAD_UMIN ||
8720+
Opcode == ISD::ATOMIC_LOAD_UMAX || Opcode == ISD::ATOMIC_LOAD_FADD ||
8721+
Opcode == ISD::ATOMIC_LOAD_FSUB || Opcode == ISD::ATOMIC_LOAD_FMAX ||
87298722
Opcode == ISD::ATOMIC_LOAD_FMIN ||
87308723
Opcode == ISD::ATOMIC_LOAD_UINC_WRAP ||
87318724
Opcode == ISD::ATOMIC_LOAD_UDEC_WRAP ||
8732-
Opcode == ISD::ATOMIC_SWAP ||
8725+
Opcode == ISD::ATOMIC_LOAD_USUB_COND ||
8726+
Opcode == ISD::ATOMIC_LOAD_USUB_SAT || Opcode == ISD::ATOMIC_SWAP ||
87338727
Opcode == ISD::ATOMIC_STORE) &&
87348728
"Invalid Atomic Op");
87358729

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5111,6 +5111,12 @@ void SelectionDAGBuilder::visitAtomicRMW(const AtomicRMWInst &I) {
51115111
case AtomicRMWInst::UDecWrap:
51125112
NT = ISD::ATOMIC_LOAD_UDEC_WRAP;
51135113
break;
5114+
case AtomicRMWInst::USubCond:
5115+
NT = ISD::ATOMIC_LOAD_USUB_COND;
5116+
break;
5117+
case AtomicRMWInst::USubSat:
5118+
NT = ISD::ATOMIC_LOAD_USUB_SAT;
5119+
break;
51145120
}
51155121
AtomicOrdering Ordering = I.getOrdering();
51165122
SyncScope::ID SSID = I.getSyncScopeID();

llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
103103
return "AtomicLoadUIncWrap";
104104
case ISD::ATOMIC_LOAD_UDEC_WRAP:
105105
return "AtomicLoadUDecWrap";
106+
case ISD::ATOMIC_LOAD_USUB_COND:
107+
return "AtomicLoadUSubCond";
108+
case ISD::ATOMIC_LOAD_USUB_SAT:
109+
return "AtomicLoadUSubSat";
106110
case ISD::ATOMIC_LOAD: return "AtomicLoad";
107111
case ISD::ATOMIC_STORE: return "AtomicStore";
108112
case ISD::PCMARKER: return "PCMarker";

llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7896,6 +7896,8 @@ Value *OpenMPIRBuilder::emitRMWOpAsInstruction(Value *Src1, Value *Src2,
78967896
case AtomicRMWInst::FMin:
78977897
case AtomicRMWInst::UIncWrap:
78987898
case AtomicRMWInst::UDecWrap:
7899+
case AtomicRMWInst::USubCond:
7900+
case AtomicRMWInst::USubSat:
78997901
llvm_unreachable("Unsupported atomic update operation");
79007902
}
79017903
llvm_unreachable("Unsupported atomic update operation");

0 commit comments

Comments
 (0)