Skip to content

Commit 4af249f

Browse files
authored
Add usub_cond and usub_sat operations to atomicrmw (#105568)
These both perform conditional subtraction, returning the minuend and zero respectively, if the difference is negative.
1 parent 109cd11 commit 4af249f

Some content is hidden

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

48 files changed

+3955
-72
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 unsigned 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
@@ -54,6 +54,8 @@ Changes to the LLVM IR
5454
the standard vector type ``<1 x i64>`` in bitcode upgrade.
5555
* Renamed ``llvm.experimental.stepvector`` intrinsic to ``llvm.stepvector``.
5656

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

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, with clamping to zero if the unsigned subtraction would overflow.
1661+
/// 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 no unsigned overflow.
755+
/// *p = (old u>= v) ? old - v : old
756+
USubCond,
757+
758+
/// *p = usub.sat(old, v)
759+
/// \p usub.sat matches the behavior of \p llvm.usub.sat.*.
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
@@ -422,12 +422,14 @@ HANDLE_TARGET_OPCODE(G_ATOMICRMW_FMAX)
422422
HANDLE_TARGET_OPCODE(G_ATOMICRMW_FMIN)
423423
HANDLE_TARGET_OPCODE(G_ATOMICRMW_UINC_WRAP)
424424
HANDLE_TARGET_OPCODE(G_ATOMICRMW_UDEC_WRAP)
425+
HANDLE_TARGET_OPCODE(G_ATOMICRMW_USUB_COND)
426+
HANDLE_TARGET_OPCODE(G_ATOMICRMW_USUB_SAT)
425427

426428
// Marker for start of Generic AtomicRMW opcodes
427429
HANDLE_TARGET_OPCODE_MARKER(GENERIC_ATOMICRMW_OP_START, G_ATOMICRMW_XCHG)
428430

429431
// Marker for end of Generic AtomicRMW opcodes
430-
HANDLE_TARGET_OPCODE_MARKER(GENERIC_ATOMICRMW_OP_END, G_ATOMICRMW_UDEC_WRAP)
432+
HANDLE_TARGET_OPCODE_MARKER(GENERIC_ATOMICRMW_OP_END, G_ATOMICRMW_USUB_SAT)
431433

432434
// Generic atomic fence
433435
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
@@ -260,6 +260,8 @@ def : GINodeEquiv<G_ATOMICRMW_FMAX, atomic_load_fmax>;
260260
def : GINodeEquiv<G_ATOMICRMW_FMIN, atomic_load_fmin>;
261261
def : GINodeEquiv<G_ATOMICRMW_UINC_WRAP, atomic_load_uinc_wrap>;
262262
def : GINodeEquiv<G_ATOMICRMW_UDEC_WRAP, atomic_load_udec_wrap>;
263+
def : GINodeEquiv<G_ATOMICRMW_USUB_COND, atomic_load_usub_cond>;
264+
def : GINodeEquiv<G_ATOMICRMW_USUB_SAT, atomic_load_usub_sat>;
263265
def : GINodeEquiv<G_FENCE, atomic_fence>;
264266
def : GINodeEquiv<G_PREFETCH, prefetch>;
265267
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
@@ -758,6 +758,10 @@ def atomic_load_uinc_wrap : SDNode<"ISD::ATOMIC_LOAD_UINC_WRAP", SDTAtomic2,
758758
[SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
759759
def atomic_load_udec_wrap : SDNode<"ISD::ATOMIC_LOAD_UDEC_WRAP", SDTAtomic2,
760760
[SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
761+
def atomic_load_usub_cond : SDNode<"ISD::ATOMIC_LOAD_USUB_COND", SDTAtomic2,
762+
[SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
763+
def atomic_load_usub_sat : SDNode<"ISD::ATOMIC_LOAD_USUB_SAT", SDTAtomic2,
764+
[SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
761765

762766
def atomic_load : SDNode<"ISD::ATOMIC_LOAD", SDTAtomicLoad,
763767
[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
@@ -8357,6 +8357,12 @@ int LLParser::parseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) {
83578357
case lltok::kw_udec_wrap:
83588358
Operation = AtomicRMWInst::UDecWrap;
83598359
break;
8360+
case lltok::kw_usub_cond:
8361+
Operation = AtomicRMWInst::USubCond;
8362+
break;
8363+
case lltok::kw_usub_sat:
8364+
Operation = AtomicRMWInst::USubSat;
8365+
break;
83608366
case lltok::kw_fadd:
83618367
Operation = AtomicRMWInst::FAdd;
83628368
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: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -901,7 +901,9 @@ static Value *performMaskedAtomicOp(AtomicRMWInst::BinOp Op,
901901
case AtomicRMWInst::FMin:
902902
case AtomicRMWInst::FMax:
903903
case AtomicRMWInst::UIncWrap:
904-
case AtomicRMWInst::UDecWrap: {
904+
case AtomicRMWInst::UDecWrap:
905+
case AtomicRMWInst::USubCond:
906+
case AtomicRMWInst::USubSat: {
905907
// Finally, other ops will operate on the full value, so truncate down to
906908
// the original size, and expand out again after doing the
907909
// operation. Bitcasts will be inserted for FP values.
@@ -1816,7 +1818,9 @@ static ArrayRef<RTLIB::Libcall> GetRMWLibcall(AtomicRMWInst::BinOp Op) {
18161818
case AtomicRMWInst::FSub:
18171819
case AtomicRMWInst::UIncWrap:
18181820
case AtomicRMWInst::UDecWrap:
1819-
// No atomic libcalls are available for max/min/umax/umin.
1821+
case AtomicRMWInst::USubCond:
1822+
case AtomicRMWInst::USubSat:
1823+
// No atomic libcalls are available for these.
18201824
return {};
18211825
}
18221826
llvm_unreachable("Unexpected AtomicRMW operation.");

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3308,6 +3308,12 @@ bool IRTranslator::translateAtomicRMW(const User &U,
33083308
case AtomicRMWInst::UDecWrap:
33093309
Opcode = TargetOpcode::G_ATOMICRMW_UDEC_WRAP;
33103310
break;
3311+
case AtomicRMWInst::USubCond:
3312+
Opcode = TargetOpcode::G_ATOMICRMW_USUB_COND;
3313+
break;
3314+
case AtomicRMWInst::USubSat:
3315+
Opcode = TargetOpcode::G_ATOMICRMW_USUB_SAT;
3316+
break;
33113317
}
33123318

33133319
MIRBuilder.buildAtomicRMW(

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8755,24 +8755,18 @@ SDValue SelectionDAG::getAtomicCmpSwap(unsigned Opcode, const SDLoc &dl,
87558755
SDValue SelectionDAG::getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT,
87568756
SDValue Chain, SDValue Ptr, SDValue Val,
87578757
MachineMemOperand *MMO) {
8758-
assert((Opcode == ISD::ATOMIC_LOAD_ADD ||
8759-
Opcode == ISD::ATOMIC_LOAD_SUB ||
8760-
Opcode == ISD::ATOMIC_LOAD_AND ||
8761-
Opcode == ISD::ATOMIC_LOAD_CLR ||
8762-
Opcode == ISD::ATOMIC_LOAD_OR ||
8763-
Opcode == ISD::ATOMIC_LOAD_XOR ||
8764-
Opcode == ISD::ATOMIC_LOAD_NAND ||
8765-
Opcode == ISD::ATOMIC_LOAD_MIN ||
8766-
Opcode == ISD::ATOMIC_LOAD_MAX ||
8767-
Opcode == ISD::ATOMIC_LOAD_UMIN ||
8768-
Opcode == ISD::ATOMIC_LOAD_UMAX ||
8769-
Opcode == ISD::ATOMIC_LOAD_FADD ||
8770-
Opcode == ISD::ATOMIC_LOAD_FSUB ||
8771-
Opcode == ISD::ATOMIC_LOAD_FMAX ||
8758+
assert((Opcode == ISD::ATOMIC_LOAD_ADD || Opcode == ISD::ATOMIC_LOAD_SUB ||
8759+
Opcode == ISD::ATOMIC_LOAD_AND || Opcode == ISD::ATOMIC_LOAD_CLR ||
8760+
Opcode == ISD::ATOMIC_LOAD_OR || Opcode == ISD::ATOMIC_LOAD_XOR ||
8761+
Opcode == ISD::ATOMIC_LOAD_NAND || Opcode == ISD::ATOMIC_LOAD_MIN ||
8762+
Opcode == ISD::ATOMIC_LOAD_MAX || Opcode == ISD::ATOMIC_LOAD_UMIN ||
8763+
Opcode == ISD::ATOMIC_LOAD_UMAX || Opcode == ISD::ATOMIC_LOAD_FADD ||
8764+
Opcode == ISD::ATOMIC_LOAD_FSUB || Opcode == ISD::ATOMIC_LOAD_FMAX ||
87728765
Opcode == ISD::ATOMIC_LOAD_FMIN ||
87738766
Opcode == ISD::ATOMIC_LOAD_UINC_WRAP ||
87748767
Opcode == ISD::ATOMIC_LOAD_UDEC_WRAP ||
8775-
Opcode == ISD::ATOMIC_SWAP ||
8768+
Opcode == ISD::ATOMIC_LOAD_USUB_COND ||
8769+
Opcode == ISD::ATOMIC_LOAD_USUB_SAT || Opcode == ISD::ATOMIC_SWAP ||
87768770
Opcode == ISD::ATOMIC_STORE) &&
87778771
"Invalid Atomic Op");
87788772

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5112,6 +5112,12 @@ void SelectionDAGBuilder::visitAtomicRMW(const AtomicRMWInst &I) {
51125112
case AtomicRMWInst::UDecWrap:
51135113
NT = ISD::ATOMIC_LOAD_UDEC_WRAP;
51145114
break;
5115+
case AtomicRMWInst::USubCond:
5116+
NT = ISD::ATOMIC_LOAD_USUB_COND;
5117+
break;
5118+
case AtomicRMWInst::USubSat:
5119+
NT = ISD::ATOMIC_LOAD_USUB_SAT;
5120+
break;
51155121
}
51165122
AtomicOrdering Ordering = I.getOrdering();
51175123
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
@@ -7936,6 +7936,8 @@ Value *OpenMPIRBuilder::emitRMWOpAsInstruction(Value *Src1, Value *Src2,
79367936
case AtomicRMWInst::FMin:
79377937
case AtomicRMWInst::UIncWrap:
79387938
case AtomicRMWInst::UDecWrap:
7939+
case AtomicRMWInst::USubCond:
7940+
case AtomicRMWInst::USubSat:
79397941
llvm_unreachable("Unsupported atomic update operation");
79407942
}
79417943
llvm_unreachable("Unsupported atomic update operation");

0 commit comments

Comments
 (0)