[Mlir-commits] [llvm] [mlir] [atomicrmw] fminimumnum/fmaximumnum support (PR #187030)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Mar 17 12:47:46 PDT 2026
https://github.com/gonzalobg updated https://github.com/llvm/llvm-project/pull/187030
>From a0c99409ec2973ef1f01926f522a504e10908ca7 Mon Sep 17 00:00:00 2001
From: Gonzalo Brito Gadeschi <gonzalob at nvidia.com>
Date: Tue, 17 Mar 2026 07:25:48 -0700
Subject: [PATCH 1/3] [atomicrmw] fminimumnum/fmaximumnum support
---
llvm/docs/LangRef.rst | 6 +-
llvm/include/llvm-c/Core.h | 6 ++
llvm/include/llvm/AsmParser/LLToken.h | 2 +
llvm/include/llvm/Bitcode/LLVMBitCodes.h | 2 +
llvm/include/llvm/CodeGen/ISDOpcodes.h | 2 +
llvm/include/llvm/IR/Instructions.h | 10 +++
llvm/include/llvm/Support/TargetOpcodes.def | 2 +
llvm/include/llvm/Target/GenericOpcodes.td | 2 +
llvm/lib/AsmParser/LLLexer.cpp | 2 +
llvm/lib/AsmParser/LLParser.cpp | 8 ++
llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 4 +
llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 4 +
llvm/lib/CodeGen/AtomicExpandPass.cpp | 4 +
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 6 ++
.../SelectionDAG/SelectionDAGBuilder.cpp | 6 ++
llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp | 2 +
llvm/lib/IR/Core.cpp | 8 ++
llvm/lib/IR/Instructions.cpp | 4 +
.../AMDGPU/AMDGPULowerBufferFatPointers.cpp | 12 +++
llvm/lib/Transforms/Utils/LowerAtomic.cpp | 4 +
llvm/test/Assembler/atomic.ll | 18 ++++
llvm/test/Bitcode/compatibility.ll | 6 ++
.../GlobalISel/legalizer-info-validation.mir | 6 ++
.../AtomicExpand/AArch64/atomicrmw-fp.ll | 84 +++++++++++++++++++
24 files changed, 209 insertions(+), 1 deletion(-)
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 45a22f416dce1..13883883d3981 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -12128,6 +12128,8 @@ operation. The operation must be one of the following keywords:
- fmin
- fmaximum
- fminimum
+- fmaximumnum
+- fminimumnum
- uinc_wrap
- udec_wrap
- usub_cond
@@ -12137,7 +12139,7 @@ For most of these operations, the type of '<value>' must be an integer
type whose bit width is a power of two greater than or equal to eight.
For xchg, this
may also be a floating point or a pointer type with the same size constraints
-as integers. For fadd/fsub/fmax/fmin/fmaximum/fminimum, this must be a floating-point
+as integers. For fadd/fsub/fmax/fmin/fmaximum/fminimum/fmaximumnum/fminimumnum, this must be a floating-point
or fixed vector of floating-point type. The type of the '``<pointer>``'
operand must be a pointer to that type. If the ``atomicrmw`` is marked
as ``volatile``, then the optimizer is not allowed to modify the
@@ -12182,6 +12184,8 @@ operation argument:
- fmin: ``*ptr = minnum(*ptr, val)`` (match the `llvm.minnum.*` intrinsic)
- fmaximum: ``*ptr = maximum(*ptr, val)`` (match the `llvm.maximum.*` intrinsic)
- fminimum: ``*ptr = minimum(*ptr, val)`` (match the `llvm.minimum.*` intrinsic)
+- fmaximumnum: ``*ptr = maximumnum(*ptr, val)`` (match the `llvm.maximumnum.*` intrinsic)
+- fminimumnum: ``*ptr = minimumnum(*ptr, val)`` (match the `llvm.minimumnum.*` intrinsic)
- uinc_wrap: ``*ptr = (*ptr u>= val) ? 0 : (*ptr + 1)`` (increment value with wraparound to zero when incremented above input value)
- udec_wrap: ``*ptr = ((*ptr == 0) || (*ptr u> val)) ? val : (*ptr - 1)`` (decrement with wraparound to input value when decremented below zero).
- usub_cond: ``*ptr = (*ptr u>= val) ? *ptr - val : *ptr`` (subtract only if no unsigned overflow).
diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index 9dba8a905753a..ca71f4a90b41b 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -405,6 +405,12 @@ typedef enum {
LLVMAtomicRMWBinOpFMinimum, /**< Sets the value if it's smaller than the
original using an floating point comparison and
return the old one */
+ LLVMAtomicRMWBinOpFMaximumNum, /**< Sets the value if it's greater than the
+ original using an floating point comparison and
+ return the old one */
+ LLVMAtomicRMWBinOpFMinimumNum, /**< Sets the value if it's smaller than the
+ original using an floating point comparison and
+ return the old one */
} LLVMAtomicRMWBinOp;
typedef enum {
diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h
index 6c92c82188f1a..d0827c9f5b8e9 100644
--- a/llvm/include/llvm/AsmParser/LLToken.h
+++ b/llvm/include/llvm/AsmParser/LLToken.h
@@ -291,6 +291,8 @@ enum Kind {
kw_fmin,
kw_fmaximum,
kw_fminimum,
+ kw_fmaximumnum,
+ kw_fminimumnum,
kw_uinc_wrap,
kw_udec_wrap,
kw_usub_cond,
diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index 4ac3029175d0d..d9614bce54503 100644
--- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -520,6 +520,8 @@ enum RMWOperations {
RMW_USUB_SAT = 18,
RMW_FMAXIMUM = 19,
RMW_FMINIMUM = 20,
+ RMW_FMAXIMUMNUM = 21,
+ RMW_FMINIMUMNUM = 22,
};
/// OverflowingBinaryOperatorOptionalFlags - Flags for serializing
diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h
index fa578f733d4e8..eac6faceafd0c 100644
--- a/llvm/include/llvm/CodeGen/ISDOpcodes.h
+++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -1411,6 +1411,8 @@ enum NodeType {
ATOMIC_LOAD_FMIN,
ATOMIC_LOAD_FMAXIMUM,
ATOMIC_LOAD_FMINIMUM,
+ ATOMIC_LOAD_FMAXIMUMNUM,
+ ATOMIC_LOAD_FMINIMUMNUM,
ATOMIC_LOAD_UINC_WRAP,
ATOMIC_LOAD_UDEC_WRAP,
ATOMIC_LOAD_USUB_COND,
diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h
index 170b2899bcc4d..692dfe6dd19c4 100644
--- a/llvm/include/llvm/IR/Instructions.h
+++ b/llvm/include/llvm/IR/Instructions.h
@@ -765,6 +765,14 @@ class AtomicRMWInst : public Instruction {
/// \p minimum matches the behavior of \p llvm.minimum.*.
FMinimum,
+ /// *p = maximumnum(old, v)
+ /// \p maximumnum matches the behavior of \p llvm.maximumnum.*.
+ FMaximumNum,
+
+ /// *p = minimumnum(old, v)
+ /// \p minimumnum matches the behavior of \p llvm.minimumnum.*.
+ FMinimumNum,
+
/// Increment one up to a maximum value.
/// *p = (old u>= v) ? 0 : (old + 1)
UIncWrap,
@@ -829,6 +837,8 @@ class AtomicRMWInst : public Instruction {
case AtomicRMWInst::FMin:
case AtomicRMWInst::FMaximum:
case AtomicRMWInst::FMinimum:
+ case AtomicRMWInst::FMaximumNum:
+ case AtomicRMWInst::FMinimumNum:
return true;
default:
return false;
diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def
index e1809e364ad83..6bfda3122141f 100644
--- a/llvm/include/llvm/Support/TargetOpcodes.def
+++ b/llvm/include/llvm/Support/TargetOpcodes.def
@@ -448,6 +448,8 @@ HANDLE_TARGET_OPCODE(G_ATOMICRMW_FMAX)
HANDLE_TARGET_OPCODE(G_ATOMICRMW_FMIN)
HANDLE_TARGET_OPCODE(G_ATOMICRMW_FMAXIMUM)
HANDLE_TARGET_OPCODE(G_ATOMICRMW_FMINIMUM)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_FMAXIMUMNUM)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_FMINIMUMNUM)
HANDLE_TARGET_OPCODE(G_ATOMICRMW_UINC_WRAP)
HANDLE_TARGET_OPCODE(G_ATOMICRMW_UDEC_WRAP)
HANDLE_TARGET_OPCODE(G_ATOMICRMW_USUB_COND)
diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td
index b785847b53f0f..1ff6d0de3d8c4 100644
--- a/llvm/include/llvm/Target/GenericOpcodes.td
+++ b/llvm/include/llvm/Target/GenericOpcodes.td
@@ -1442,6 +1442,8 @@ def G_ATOMICRMW_FMAX : G_ATOMICRMW_OP;
def G_ATOMICRMW_FMIN : G_ATOMICRMW_OP;
def G_ATOMICRMW_FMAXIMUM : G_ATOMICRMW_OP;
def G_ATOMICRMW_FMINIMUM : G_ATOMICRMW_OP;
+def G_ATOMICRMW_FMAXIMUMNUM : G_ATOMICRMW_OP;
+def G_ATOMICRMW_FMINIMUMNUM : G_ATOMICRMW_OP;
def G_ATOMICRMW_UINC_WRAP : G_ATOMICRMW_OP;
def G_ATOMICRMW_UDEC_WRAP : G_ATOMICRMW_OP;
def G_ATOMICRMW_USUB_COND : G_ATOMICRMW_OP;
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index bfc5f64a78838..320c230469573 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -778,6 +778,8 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(umin); KEYWORD(fmax); KEYWORD(fmin);
KEYWORD(fmaximum);
KEYWORD(fminimum);
+ KEYWORD(fmaximumnum);
+ KEYWORD(fminimumnum);
KEYWORD(uinc_wrap);
KEYWORD(udec_wrap);
KEYWORD(usub_cond);
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 09b893b33786d..0c4e0a2996fce 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -9009,6 +9009,14 @@ int LLParser::parseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) {
Operation = AtomicRMWInst::FMinimum;
IsFP = true;
break;
+ case lltok::kw_fmaximumnum:
+ Operation = AtomicRMWInst::FMaximumNum;
+ IsFP = true;
+ break;
+ case lltok::kw_fminimumnum:
+ Operation = AtomicRMWInst::FMinimumNum;
+ IsFP = true;
+ break;
}
Lex.Lex(); // Eat the operation.
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index d6d28ca7b5ae7..073c1f5916089 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1386,6 +1386,10 @@ static AtomicRMWInst::BinOp getDecodedRMWOperation(unsigned Val) {
return AtomicRMWInst::FMaximum;
case bitc::RMW_FMINIMUM:
return AtomicRMWInst::FMinimum;
+ case bitc::RMW_FMAXIMUMNUM:
+ return AtomicRMWInst::FMaximumNum;
+ case bitc::RMW_FMINIMUMNUM:
+ return AtomicRMWInst::FMinimumNum;
case bitc::RMW_UINC_WRAP:
return AtomicRMWInst::UIncWrap;
case bitc::RMW_UDEC_WRAP:
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index ce7449354ba8e..cdc6b2af9501a 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -712,6 +712,10 @@ static unsigned getEncodedRMWOperation(AtomicRMWInst::BinOp Op) {
return bitc::RMW_FMAXIMUM;
case AtomicRMWInst::FMinimum:
return bitc::RMW_FMINIMUM;
+ case AtomicRMWInst::FMaximumNum:
+ return bitc::RMW_FMAXIMUMNUM;
+ case AtomicRMWInst::FMinimumNum:
+ return bitc::RMW_FMINIMUMNUM;
case AtomicRMWInst::UIncWrap:
return bitc::RMW_UINC_WRAP;
case AtomicRMWInst::UDecWrap:
diff --git a/llvm/lib/CodeGen/AtomicExpandPass.cpp b/llvm/lib/CodeGen/AtomicExpandPass.cpp
index 341a4618dbb47..2bcd7fb3f62e7 100644
--- a/llvm/lib/CodeGen/AtomicExpandPass.cpp
+++ b/llvm/lib/CodeGen/AtomicExpandPass.cpp
@@ -967,6 +967,8 @@ static Value *performMaskedAtomicOp(AtomicRMWInst::BinOp Op,
case AtomicRMWInst::FMax:
case AtomicRMWInst::FMaximum:
case AtomicRMWInst::FMinimum:
+ case AtomicRMWInst::FMaximumNum:
+ case AtomicRMWInst::FMinimumNum:
case AtomicRMWInst::UIncWrap:
case AtomicRMWInst::UDecWrap:
case AtomicRMWInst::USubCond:
@@ -1881,6 +1883,8 @@ static ArrayRef<RTLIB::Libcall> GetRMWLibcall(AtomicRMWInst::BinOp Op) {
case AtomicRMWInst::FMin:
case AtomicRMWInst::FMaximum:
case AtomicRMWInst::FMinimum:
+ case AtomicRMWInst::FMaximumNum:
+ case AtomicRMWInst::FMinimumNum:
case AtomicRMWInst::FAdd:
case AtomicRMWInst::FSub:
case AtomicRMWInst::UIncWrap:
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index a7603dd272a92..346c37b04ac66 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -3598,6 +3598,12 @@ bool IRTranslator::translateAtomicRMW(const User &U,
case AtomicRMWInst::FMinimum:
Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUM;
break;
+ case AtomicRMWInst::FMaximumNum:
+ Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUMNUM;
+ break;
+ case AtomicRMWInst::FMinimumNum:
+ Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUMNUM;
+ break;
case AtomicRMWInst::UIncWrap:
Opcode = TargetOpcode::G_ATOMICRMW_UINC_WRAP;
break;
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index eb55a68eaba84..04b17b56b3d49 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -5251,6 +5251,12 @@ void SelectionDAGBuilder::visitAtomicRMW(const AtomicRMWInst &I) {
case AtomicRMWInst::FMinimum:
NT = ISD::ATOMIC_LOAD_FMINIMUM;
break;
+ case AtomicRMWInst::FMaximumNum:
+ NT = ISD::ATOMIC_LOAD_FMAXIMUMNUM;
+ break;
+ case AtomicRMWInst::FMinimumNum:
+ NT = ISD::ATOMIC_LOAD_FMINIMUMNUM;
+ break;
case AtomicRMWInst::UIncWrap:
NT = ISD::ATOMIC_LOAD_UINC_WRAP;
break;
diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
index 8148e113195cc..a1a25075f3703 100644
--- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -10445,6 +10445,8 @@ Value *OpenMPIRBuilder::emitRMWOpAsInstruction(Value *Src1, Value *Src2,
case AtomicRMWInst::FMin:
case AtomicRMWInst::FMaximum:
case AtomicRMWInst::FMinimum:
+ case AtomicRMWInst::FMaximumNum:
+ case AtomicRMWInst::FMinimumNum:
case AtomicRMWInst::UIncWrap:
case AtomicRMWInst::UDecWrap:
case AtomicRMWInst::USubCond:
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index f91439f410eaa..375fdc68d4e45 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -4102,6 +4102,10 @@ static AtomicRMWInst::BinOp mapFromLLVMRMWBinOp(LLVMAtomicRMWBinOp BinOp) {
return AtomicRMWInst::FMaximum;
case LLVMAtomicRMWBinOpFMinimum:
return AtomicRMWInst::FMinimum;
+ case LLVMAtomicRMWBinOpFMaximumNum:
+ return AtomicRMWInst::FMaximumNum;
+ case LLVMAtomicRMWBinOpFMinimumNum:
+ return AtomicRMWInst::FMinimumNum;
case LLVMAtomicRMWBinOpUIncWrap:
return AtomicRMWInst::UIncWrap;
case LLVMAtomicRMWBinOpUDecWrap:
@@ -4136,6 +4140,10 @@ static LLVMAtomicRMWBinOp mapToLLVMRMWBinOp(AtomicRMWInst::BinOp BinOp) {
return LLVMAtomicRMWBinOpFMaximum;
case AtomicRMWInst::FMinimum:
return LLVMAtomicRMWBinOpFMinimum;
+ case AtomicRMWInst::FMaximumNum:
+ return LLVMAtomicRMWBinOpFMaximumNum;
+ case AtomicRMWInst::FMinimumNum:
+ return LLVMAtomicRMWBinOpFMinimumNum;
case AtomicRMWInst::UIncWrap:
return LLVMAtomicRMWBinOpUIncWrap;
case AtomicRMWInst::UDecWrap:
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index 0485af358e2c4..516bcee843b3b 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -1493,6 +1493,10 @@ StringRef AtomicRMWInst::getOperationName(BinOp Op) {
return "fmaximum";
case AtomicRMWInst::FMinimum:
return "fminimum";
+ case AtomicRMWInst::FMaximumNum:
+ return "fmaximumnum";
+ case AtomicRMWInst::FMinimumNum:
+ return "fminimumnum";
case AtomicRMWInst::UIncWrap:
return "uinc_wrap";
case AtomicRMWInst::UDecWrap:
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp
index 3ab23562ff1f9..4c1fd1ee660de 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp
@@ -1774,6 +1774,18 @@ Value *SplitPtrStructs::handleMemoryInst(Instruction *I, Value *Arg, Value *Ptr,
"buffer resources and should've been expanded away");
break;
}
+ case AtomicRMWInst::FMaximumNum: {
+ reportFatalUsageError(
+ "atomic floating point fmaximumnum not supported for "
+ "buffer resources and should've been expanded away");
+ break;
+ }
+ case AtomicRMWInst::FMinimumNum: {
+ reportFatalUsageError(
+ "atomic floating point fminimumnum not supported for "
+ "buffer resources and should've been expanded away");
+ break;
+ }
case AtomicRMWInst::Nand:
reportFatalUsageError(
"atomic nand not supported for buffer resources and "
diff --git a/llvm/lib/Transforms/Utils/LowerAtomic.cpp b/llvm/lib/Transforms/Utils/LowerAtomic.cpp
index e8b06415d4062..d4c0602f6ce52 100644
--- a/llvm/lib/Transforms/Utils/LowerAtomic.cpp
+++ b/llvm/lib/Transforms/Utils/LowerAtomic.cpp
@@ -92,6 +92,10 @@ Value *llvm::buildAtomicRMWValue(AtomicRMWInst::BinOp Op,
return Builder.CreateMaximum(Loaded, Val);
case AtomicRMWInst::FMinimum:
return Builder.CreateMinimum(Loaded, Val);
+ case AtomicRMWInst::FMaximumNum:
+ return Builder.CreateMaximumNum(Loaded, Val);
+ case AtomicRMWInst::FMinimumNum:
+ return Builder.CreateMinimumNum(Loaded, Val);
case AtomicRMWInst::UIncWrap: {
Constant *One = ConstantInt::get(Loaded->getType(), 1);
Value *Inc = Builder.CreateAdd(Loaded, One);
diff --git a/llvm/test/Assembler/atomic.ll b/llvm/test/Assembler/atomic.ll
index 6609edc2953cc..0ed34f0ad98ef 100644
--- a/llvm/test/Assembler/atomic.ll
+++ b/llvm/test/Assembler/atomic.ll
@@ -111,6 +111,18 @@ define void @fp_atomics(ptr %x) {
; CHECK: atomicrmw volatile fminimum ptr %x, float 1.000000e+00 seq_cst
atomicrmw volatile fminimum ptr %x, float 1.0 seq_cst
+ ; CHECK: atomicrmw fmaximumnum ptr %x, float 1.000000e+00 seq_cst
+ atomicrmw fmaximumnum ptr %x, float 1.0 seq_cst
+
+ ; CHECK: atomicrmw volatile fmaximumnum ptr %x, float 1.000000e+00 seq_cst
+ atomicrmw volatile fmaximumnum ptr %x, float 1.0 seq_cst
+
+ ; CHECK: atomicrmw fminimumnum ptr %x, float 1.000000e+00 seq_cst
+ atomicrmw fminimumnum ptr %x, float 1.0 seq_cst
+
+ ; CHECK: atomicrmw volatile fminimumnum ptr %x, float 1.000000e+00 seq_cst
+ atomicrmw volatile fminimumnum ptr %x, float 1.0 seq_cst
+
ret void
}
@@ -133,5 +145,11 @@ define void @fp_vector_atomicrmw(ptr %x, <2 x half> %val) {
; CHECK: %atomic.fminimum = atomicrmw fminimum ptr %x, <2 x half> %val seq_cst
%atomic.fminimum = atomicrmw fminimum ptr %x, <2 x half> %val seq_cst
+ ; CHECK: %atomic.fmaximumnum = atomicrmw fmaximumnum ptr %x, <2 x half> %val seq_cst
+ %atomic.fmaximumnum = atomicrmw fmaximumnum ptr %x, <2 x half> %val seq_cst
+
+ ; CHECK: %atomic.fminimumnum = atomicrmw fminimumnum ptr %x, <2 x half> %val seq_cst
+ %atomic.fminimumnum = atomicrmw fminimumnum ptr %x, <2 x half> %val seq_cst
+
ret void
}
diff --git a/llvm/test/Bitcode/compatibility.ll b/llvm/test/Bitcode/compatibility.ll
index 06e7fc0096a53..c87159fe960f3 100644
--- a/llvm/test/Bitcode/compatibility.ll
+++ b/llvm/test/Bitcode/compatibility.ll
@@ -955,6 +955,12 @@ define void @fp_atomics(ptr %word) {
; CHECK: %atomicrmw.fminimum = atomicrmw fminimum ptr %word, float 1.000000e+00 monotonic
%atomicrmw.fminimum = atomicrmw fminimum ptr %word, float 1.0 monotonic
+; CHECK: %atomicrmw.fmaximumnum = atomicrmw fmaximumnum ptr %word, float 1.000000e+00 monotonic
+ %atomicrmw.fmaximumnum = atomicrmw fmaximumnum ptr %word, float 1.0 monotonic
+
+; CHECK: %atomicrmw.fminimumnum = atomicrmw fminimumnum ptr %word, float 1.000000e+00 monotonic
+ %atomicrmw.fminimumnum = atomicrmw fminimumnum ptr %word, float 1.0 monotonic
+
ret void
}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
index 655e793f55c59..cbda65862d4c4 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
@@ -295,6 +295,12 @@
# DEBUG-NEXT: G_ATOMICRMW_FMINIMUM (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: G_ATOMICRMW_FMAXIMUMNUM (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
+# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: G_ATOMICRMW_FMINIMUMNUM (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
+# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: G_ATOMICRMW_UINC_WRAP (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
diff --git a/llvm/test/Transforms/AtomicExpand/AArch64/atomicrmw-fp.ll b/llvm/test/Transforms/AtomicExpand/AArch64/atomicrmw-fp.ll
index 3e7468a2c8f38..c8395738177ea 100644
--- a/llvm/test/Transforms/AtomicExpand/AArch64/atomicrmw-fp.ll
+++ b/llvm/test/Transforms/AtomicExpand/AArch64/atomicrmw-fp.ll
@@ -337,6 +337,90 @@ define <2 x half> @atomicrmw_fminimum_2_x_half(ptr %ptr, <2 x half> %val) {
ret <2 x half> %res
}
+define float @atomicrmw_fmaximumnum_float(ptr %ptr, float %value) {
+; CHECK-LABEL: @atomicrmw_fmaximumnum_float(
+; CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[PTR:%.*]], align 4
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[TMP2:%.*]] = call float @llvm.maximumnum.f32(float [[LOADED]], float [[VALUE:%.*]])
+; CHECK-NEXT: [[TMP3:%.*]] = bitcast float [[TMP2]] to i32
+; CHECK-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32
+; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[PTR]], i32 [[TMP4]], i32 [[TMP3]] seq_cst seq_cst, align 4
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
+; CHECK-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0
+; CHECK-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: ret float [[TMP6]]
+;
+ %res = atomicrmw fmaximumnum ptr %ptr, float %value seq_cst
+ ret float %res
+}
+
+define float @atomicrmw_fminimumnum_float(ptr %ptr, float %value) {
+; CHECK-LABEL: @atomicrmw_fminimumnum_float(
+; CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[PTR:%.*]], align 4
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[TMP2:%.*]] = call float @llvm.minimumnum.f32(float [[LOADED]], float [[VALUE:%.*]])
+; CHECK-NEXT: [[TMP3:%.*]] = bitcast float [[TMP2]] to i32
+; CHECK-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32
+; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[PTR]], i32 [[TMP4]], i32 [[TMP3]] seq_cst seq_cst, align 4
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
+; CHECK-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0
+; CHECK-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: ret float [[TMP6]]
+;
+ %res = atomicrmw fminimumnum ptr %ptr, float %value seq_cst
+ ret float %res
+}
+
+define double @atomicrmw_fmaximumnum_double(ptr %ptr, double %value) {
+; CHECK-LABEL: @atomicrmw_fmaximumnum_double(
+; CHECK-NEXT: [[TMP1:%.*]] = load double, ptr [[PTR:%.*]], align 8
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.maximumnum.f64(double [[LOADED]], double [[VALUE:%.*]])
+; CHECK-NEXT: [[TMP3:%.*]] = bitcast double [[TMP2]] to i64
+; CHECK-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64
+; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[PTR]], i64 [[TMP4]], i64 [[TMP3]] seq_cst seq_cst, align 8
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1
+; CHECK-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0
+; CHECK-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to double
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: ret double [[TMP6]]
+;
+ %res = atomicrmw fmaximumnum ptr %ptr, double %value seq_cst
+ ret double %res
+}
+
+define double @atomicrmw_fminimumnum_double(ptr %ptr, double %value) {
+; CHECK-LABEL: @atomicrmw_fminimumnum_double(
+; CHECK-NEXT: [[TMP1:%.*]] = load double, ptr [[PTR:%.*]], align 8
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.minimumnum.f64(double [[LOADED]], double [[VALUE:%.*]])
+; CHECK-NEXT: [[TMP3:%.*]] = bitcast double [[TMP2]] to i64
+; CHECK-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64
+; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[PTR]], i64 [[TMP4]], i64 [[TMP3]] seq_cst seq_cst, align 8
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1
+; CHECK-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0
+; CHECK-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to double
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: ret double [[TMP6]]
+;
+ %res = atomicrmw fminimumnum ptr %ptr, double %value seq_cst
+ ret double %res
+}
+
!0 = !{!"function_entry_count", i64 1000}
;.
; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
>From cca958b3c4516fef004128835f5e7bffb42ba7f3 Mon Sep 17 00:00:00 2001
From: Gonzalo Brito Gadeschi <gonzalob at nvidia.com>
Date: Tue, 17 Mar 2026 12:08:54 -0700
Subject: [PATCH 2/3] fix tests and add vector tests
---
.../GlobalISel/legalizer-info-validation.mir | 6 +
.../match-table-cxx.td | 132 +++++++++---------
.../GlobalISelEmitter/GlobalISelEmitter.td | 2 +-
.../AtomicExpand/AArch64/atomicrmw-fp.ll | 126 +++++++++++++++++
4 files changed, 199 insertions(+), 67 deletions(-)
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
index 43ef36da6a11a..c34f2b217139c 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
@@ -287,6 +287,12 @@
# DEBUG-NEXT: G_ATOMICRMW_FMINIMUM (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: G_ATOMICRMW_FMAXIMUMNUM (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
+# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: G_ATOMICRMW_FMINIMUMNUM (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
+# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: G_ATOMICRMW_UINC_WRAP (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
diff --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-cxx.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-cxx.td
index 28017700a0448..ab8763eea81f4 100644
--- a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-cxx.td
+++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-cxx.td
@@ -96,71 +96,71 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK: const uint8_t *GenMyCombiner::getMatchTable() const {
// CHECK-NEXT: constexpr static uint8_t MatchTable0[] = {
-// CHECK-NEXT: /* 0 */ GIM_SwitchOpcode, /*MI*/0, /*[*/GIMT_Encode2(105), GIMT_Encode2(217), /*)*//*default:*//*Label 5*/ GIMT_Encode4(524),
-// CHECK-NEXT: /* 10 */ /*TargetOpcode::G_STORE*//*Label 0*/ GIMT_Encode4(458), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0),
-// CHECK-NEXT: /* 182 */ /*TargetOpcode::G_SEXT*//*Label 1*/ GIMT_Encode4(476), GIMT_Encode4(0),
-// CHECK-NEXT: /* 190 */ /*TargetOpcode::G_ZEXT*//*Label 2*/ GIMT_Encode4(488), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0),
-// CHECK-NEXT: /* 418 */ /*TargetOpcode::G_FNEG*//*Label 3*/ GIMT_Encode4(500), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0),
-// CHECK-NEXT: /* 454 */ /*TargetOpcode::G_FABS*//*Label 4*/ GIMT_Encode4(512),
-// CHECK-NEXT: /* 458 */ // Label 0: @458
-// CHECK-NEXT: /* 458 */ GIM_Try, /*On fail goto*//*Label 6*/ GIMT_Encode4(475), // Rule ID 2 //
-// CHECK-NEXT: /* 463 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule2Enabled),
-// CHECK-NEXT: /* 466 */ // MIs[0] x
-// CHECK-NEXT: /* 466 */ // No operand predicates
-// CHECK-NEXT: /* 466 */ // MIs[0] y
-// CHECK-NEXT: /* 466 */ // No operand predicates
-// CHECK-NEXT: /* 466 */ GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_GICombiner0),
-// CHECK-NEXT: /* 470 */ GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_GICombiner1),
-// CHECK-NEXT: /* 474 */ // Combiner Rule #2: TwoMatchNoApply
-// CHECK-NEXT: /* 474 */ GIR_EraseRootFromParent_Done,
-// CHECK-NEXT: /* 475 */ // Label 6: @475
-// CHECK-NEXT: /* 475 */ GIM_Reject,
-// CHECK-NEXT: /* 476 */ // Label 1: @476
-// CHECK-NEXT: /* 476 */ GIM_Try, /*On fail goto*//*Label 7*/ GIMT_Encode4(487), // Rule ID 3 //
-// CHECK-NEXT: /* 481 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule3Enabled),
-// CHECK-NEXT: /* 484 */ // MIs[0] a
-// CHECK-NEXT: /* 484 */ // No operand predicates
-// CHECK-NEXT: /* 484 */ // MIs[0] y
-// CHECK-NEXT: /* 484 */ // No operand predicates
-// CHECK-NEXT: /* 484 */ // Combiner Rule #3: NoMatchTwoApply
-// CHECK-NEXT: /* 484 */ GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner2),
-// CHECK-NEXT: /* 487 */ // Label 7: @487
-// CHECK-NEXT: /* 487 */ GIM_Reject,
-// CHECK-NEXT: /* 488 */ // Label 2: @488
-// CHECK-NEXT: /* 488 */ GIM_Try, /*On fail goto*//*Label 8*/ GIMT_Encode4(499), // Rule ID 4 //
-// CHECK-NEXT: /* 493 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule4Enabled),
-// CHECK-NEXT: /* 496 */ // MIs[0] a
-// CHECK-NEXT: /* 496 */ // No operand predicates
-// CHECK-NEXT: /* 496 */ // MIs[0] y
-// CHECK-NEXT: /* 496 */ // No operand predicates
-// CHECK-NEXT: /* 496 */ // Combiner Rule #4: CombineCXXOrder
-// CHECK-NEXT: /* 496 */ GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner3),
-// CHECK-NEXT: /* 499 */ // Label 8: @499
-// CHECK-NEXT: /* 499 */ GIM_Reject,
-// CHECK-NEXT: /* 500 */ // Label 3: @500
-// CHECK-NEXT: /* 500 */ GIM_Try, /*On fail goto*//*Label 9*/ GIMT_Encode4(511), // Rule ID 1 //
-// CHECK-NEXT: /* 505 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule1Enabled),
-// CHECK-NEXT: /* 508 */ // MIs[0] a
-// CHECK-NEXT: /* 508 */ // No operand predicates
-// CHECK-NEXT: /* 508 */ // MIs[0] b
-// CHECK-NEXT: /* 508 */ // No operand predicates
-// CHECK-NEXT: /* 508 */ // Combiner Rule #1: TwoMatchTwoApply
-// CHECK-NEXT: /* 508 */ GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner1),
-// CHECK-NEXT: /* 511 */ // Label 9: @511
-// CHECK-NEXT: /* 511 */ GIM_Reject,
-// CHECK-NEXT: /* 512 */ // Label 4: @512
-// CHECK-NEXT: /* 512 */ GIM_Try, /*On fail goto*//*Label 10*/ GIMT_Encode4(523), // Rule ID 0 //
-// CHECK-NEXT: /* 517 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
-// CHECK-NEXT: /* 520 */ // MIs[0] a
-// CHECK-NEXT: /* 520 */ // No operand predicates
-// CHECK-NEXT: /* 520 */ // MIs[0] b
-// CHECK-NEXT: /* 520 */ // No operand predicates
-// CHECK-NEXT: /* 520 */ // Combiner Rule #0: OneMatchOneApply
-// CHECK-NEXT: /* 520 */ GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0),
-// CHECK-NEXT: /* 523 */ // Label 10: @523
-// CHECK-NEXT: /* 523 */ GIM_Reject,
-// CHECK-NEXT: /* 524 */ // Label 5: @524
-// CHECK-NEXT: /* 524 */ GIM_Reject,
-// CHECK-NEXT: /* 525 */ }; // Size: 525 bytes
+// CHECK-NEXT: /* 0 */ GIM_SwitchOpcode, /*MI*/0, /*[*/GIMT_Encode2(105), GIMT_Encode2(219), /*)*//*default:*//*Label 5*/ GIMT_Encode4(532),
+// CHECK-NEXT: /* 10 */ /*TargetOpcode::G_STORE*//*Label 0*/ GIMT_Encode4(466), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0),
+// CHECK-NEXT: /* 190 */ /*TargetOpcode::G_SEXT*//*Label 1*/ GIMT_Encode4(484), GIMT_Encode4(0),
+// CHECK-NEXT: /* 198 */ /*TargetOpcode::G_ZEXT*//*Label 2*/ GIMT_Encode4(496), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0),
+// CHECK-NEXT: /* 426 */ /*TargetOpcode::G_FNEG*//*Label 3*/ GIMT_Encode4(508), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0),
+// CHECK-NEXT: /* 462 */ /*TargetOpcode::G_FABS*//*Label 4*/ GIMT_Encode4(520),
+// CHECK-NEXT: /* 466 */ // Label 0: @466
+// CHECK-NEXT: /* 466 */ GIM_Try, /*On fail goto*//*Label 6*/ GIMT_Encode4(483), // Rule ID 2 //
+// CHECK-NEXT: /* 471 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule2Enabled),
+// CHECK-NEXT: /* 474 */ // MIs[0] x
+// CHECK-NEXT: /* 474 */ // No operand predicates
+// CHECK-NEXT: /* 474 */ // MIs[0] y
+// CHECK-NEXT: /* 474 */ // No operand predicates
+// CHECK-NEXT: /* 474 */ GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_GICombiner0),
+// CHECK-NEXT: /* 478 */ GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_GICombiner1),
+// CHECK-NEXT: /* 482 */ // Combiner Rule #2: TwoMatchNoApply
+// CHECK-NEXT: /* 482 */ GIR_EraseRootFromParent_Done,
+// CHECK-NEXT: /* 483 */ // Label 6: @483
+// CHECK-NEXT: /* 483 */ GIM_Reject,
+// CHECK-NEXT: /* 484 */ // Label 1: @484
+// CHECK-NEXT: /* 484 */ GIM_Try, /*On fail goto*//*Label 7*/ GIMT_Encode4(495), // Rule ID 3 //
+// CHECK-NEXT: /* 489 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule3Enabled),
+// CHECK-NEXT: /* 492 */ // MIs[0] a
+// CHECK-NEXT: /* 492 */ // No operand predicates
+// CHECK-NEXT: /* 492 */ // MIs[0] y
+// CHECK-NEXT: /* 492 */ // No operand predicates
+// CHECK-NEXT: /* 492 */ // Combiner Rule #3: NoMatchTwoApply
+// CHECK-NEXT: /* 492 */ GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner2),
+// CHECK-NEXT: /* 495 */ // Label 7: @495
+// CHECK-NEXT: /* 495 */ GIM_Reject,
+// CHECK-NEXT: /* 496 */ // Label 2: @496
+// CHECK-NEXT: /* 496 */ GIM_Try, /*On fail goto*//*Label 8*/ GIMT_Encode4(507), // Rule ID 4 //
+// CHECK-NEXT: /* 501 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule4Enabled),
+// CHECK-NEXT: /* 504 */ // MIs[0] a
+// CHECK-NEXT: /* 504 */ // No operand predicates
+// CHECK-NEXT: /* 504 */ // MIs[0] y
+// CHECK-NEXT: /* 504 */ // No operand predicates
+// CHECK-NEXT: /* 504 */ // Combiner Rule #4: CombineCXXOrder
+// CHECK-NEXT: /* 504 */ GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner3),
+// CHECK-NEXT: /* 507 */ // Label 8: @507
+// CHECK-NEXT: /* 507 */ GIM_Reject,
+// CHECK-NEXT: /* 508 */ // Label 3: @508
+// CHECK-NEXT: /* 508 */ GIM_Try, /*On fail goto*//*Label 9*/ GIMT_Encode4(519), // Rule ID 1 //
+// CHECK-NEXT: /* 513 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule1Enabled),
+// CHECK-NEXT: /* 516 */ // MIs[0] a
+// CHECK-NEXT: /* 516 */ // No operand predicates
+// CHECK-NEXT: /* 516 */ // MIs[0] b
+// CHECK-NEXT: /* 516 */ // No operand predicates
+// CHECK-NEXT: /* 516 */ // Combiner Rule #1: TwoMatchTwoApply
+// CHECK-NEXT: /* 516 */ GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner1),
+// CHECK-NEXT: /* 519 */ // Label 9: @519
+// CHECK-NEXT: /* 519 */ GIM_Reject,
+// CHECK-NEXT: /* 520 */ // Label 4: @520
+// CHECK-NEXT: /* 520 */ GIM_Try, /*On fail goto*//*Label 10*/ GIMT_Encode4(531), // Rule ID 0 //
+// CHECK-NEXT: /* 525 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
+// CHECK-NEXT: /* 528 */ // MIs[0] a
+// CHECK-NEXT: /* 528 */ // No operand predicates
+// CHECK-NEXT: /* 528 */ // MIs[0] b
+// CHECK-NEXT: /* 528 */ // No operand predicates
+// CHECK-NEXT: /* 528 */ // Combiner Rule #0: OneMatchOneApply
+// CHECK-NEXT: /* 528 */ GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0),
+// CHECK-NEXT: /* 531 */ // Label 10: @531
+// CHECK-NEXT: /* 531 */ GIM_Reject,
+// CHECK-NEXT: /* 532 */ // Label 5: @532
+// CHECK-NEXT: /* 532 */ GIM_Reject,
+// CHECK-NEXT: /* 533 */ }; // Size: 533 bytes
// CHECK-NEXT: return MatchTable0;
// CHECK-NEXT: }
diff --git a/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td b/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td
index 9d386cdc8f05b..3ee4a2b6dce45 100644
--- a/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td
+++ b/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td
@@ -540,7 +540,7 @@ def : Pat<(frag GPR32:$src1, complex:$src2, complex:$src3),
// R00O-NEXT: GIM_Reject,
// R00O: // Label [[DEFAULT_NUM]]: @[[DEFAULT]]
// R00O-NEXT: GIM_Reject,
-// R00O-NEXT: }; // Size: 1918 bytes
+// R00O-NEXT: }; // Size: 1926 bytes
def INSNBOB : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3, GPR32:$src4),
[(set GPR32:$dst,
diff --git a/llvm/test/Transforms/AtomicExpand/AArch64/atomicrmw-fp.ll b/llvm/test/Transforms/AtomicExpand/AArch64/atomicrmw-fp.ll
index c8395738177ea..66f1a9b5439f2 100644
--- a/llvm/test/Transforms/AtomicExpand/AArch64/atomicrmw-fp.ll
+++ b/llvm/test/Transforms/AtomicExpand/AArch64/atomicrmw-fp.ll
@@ -337,6 +337,48 @@ define <2 x half> @atomicrmw_fminimum_2_x_half(ptr %ptr, <2 x half> %val) {
ret <2 x half> %res
}
+define <2 x half> @atomicrmw_fmaximumnum_2_x_half(ptr %ptr, <2 x half> %val) {
+; CHECK-LABEL: @atomicrmw_fmaximumnum_2_x_half(
+; CHECK-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[PTR:%.*]], align 4
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi <2 x half> [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[TMP2:%.*]] = call <2 x half> @llvm.maximumnum.v2f16(<2 x half> [[LOADED]], <2 x half> [[VAL:%.*]])
+; CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x half> [[TMP2]] to i32
+; CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x half> [[LOADED]] to i32
+; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[PTR]], i32 [[TMP4]], i32 [[TMP3]] seq_cst seq_cst, align 4
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
+; CHECK-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0
+; CHECK-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to <2 x half>
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: ret <2 x half> [[TMP6]]
+;
+ %res = atomicrmw fmaximumnum ptr %ptr, <2 x half> %val seq_cst
+ ret <2 x half> %res
+}
+
+define <2 x half> @atomicrmw_fminimumnum_2_x_half(ptr %ptr, <2 x half> %val) {
+; CHECK-LABEL: @atomicrmw_fminimumnum_2_x_half(
+; CHECK-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[PTR:%.*]], align 4
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi <2 x half> [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[TMP2:%.*]] = call <2 x half> @llvm.minimumnum.v2f16(<2 x half> [[LOADED]], <2 x half> [[VAL:%.*]])
+; CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x half> [[TMP2]] to i32
+; CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x half> [[LOADED]] to i32
+; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[PTR]], i32 [[TMP4]], i32 [[TMP3]] seq_cst seq_cst, align 4
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
+; CHECK-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0
+; CHECK-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to <2 x half>
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: ret <2 x half> [[TMP6]]
+;
+ %res = atomicrmw fminimumnum ptr %ptr, <2 x half> %val seq_cst
+ ret <2 x half> %res
+}
+
define float @atomicrmw_fmaximumnum_float(ptr %ptr, float %value) {
; CHECK-LABEL: @atomicrmw_fmaximumnum_float(
; CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[PTR:%.*]], align 4
@@ -421,6 +463,90 @@ define double @atomicrmw_fminimumnum_double(ptr %ptr, double %value) {
ret double %res
}
+define <2 x float> @atomicrmw_fmaximumnum_2_x_float(ptr %ptr, <2 x float> %val) {
+; CHECK-LABEL: @atomicrmw_fmaximumnum_2_x_float(
+; CHECK-NEXT: [[TMP1:%.*]] = load <2 x float>, ptr [[PTR:%.*]], align 8
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi <2 x float> [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[TMP2:%.*]] = call <2 x float> @llvm.maximumnum.v2f32(<2 x float> [[LOADED]], <2 x float> [[VAL:%.*]])
+; CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x float> [[TMP2]] to i64
+; CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x float> [[LOADED]] to i64
+; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[PTR]], i64 [[TMP4]], i64 [[TMP3]] seq_cst seq_cst, align 8
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1
+; CHECK-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0
+; CHECK-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to <2 x float>
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: ret <2 x float> [[TMP6]]
+;
+ %res = atomicrmw fmaximumnum ptr %ptr, <2 x float> %val seq_cst
+ ret <2 x float> %res
+}
+
+define <2 x float> @atomicrmw_fminimumnum_2_x_float(ptr %ptr, <2 x float> %val) {
+; CHECK-LABEL: @atomicrmw_fminimumnum_2_x_float(
+; CHECK-NEXT: [[TMP1:%.*]] = load <2 x float>, ptr [[PTR:%.*]], align 8
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi <2 x float> [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[TMP2:%.*]] = call <2 x float> @llvm.minimumnum.v2f32(<2 x float> [[LOADED]], <2 x float> [[VAL:%.*]])
+; CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x float> [[TMP2]] to i64
+; CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x float> [[LOADED]] to i64
+; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[PTR]], i64 [[TMP4]], i64 [[TMP3]] seq_cst seq_cst, align 8
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1
+; CHECK-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0
+; CHECK-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to <2 x float>
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: ret <2 x float> [[TMP6]]
+;
+ %res = atomicrmw fminimumnum ptr %ptr, <2 x float> %val seq_cst
+ ret <2 x float> %res
+}
+
+define <2 x double> @atomicrmw_fmaximumnum_2_x_double(ptr %ptr, <2 x double> %val) {
+; CHECK-LABEL: @atomicrmw_fmaximumnum_2_x_double(
+; CHECK-NEXT: [[TMP1:%.*]] = load <2 x double>, ptr [[PTR:%.*]], align 16
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi <2 x double> [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[TMP2:%.*]] = call <2 x double> @llvm.maximumnum.v2f64(<2 x double> [[LOADED]], <2 x double> [[VAL:%.*]])
+; CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x double> [[TMP2]] to i128
+; CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x double> [[LOADED]] to i128
+; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[PTR]], i128 [[TMP4]], i128 [[TMP3]] seq_cst seq_cst, align 16
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP5]], 1
+; CHECK-NEXT: [[NEWLOADED:%.*]] = extractvalue { i128, i1 } [[TMP5]], 0
+; CHECK-NEXT: [[TMP6]] = bitcast i128 [[NEWLOADED]] to <2 x double>
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: ret <2 x double> [[TMP6]]
+;
+ %res = atomicrmw fmaximumnum ptr %ptr, <2 x double> %val seq_cst
+ ret <2 x double> %res
+}
+
+define <2 x double> @atomicrmw_fminimumnum_2_x_double(ptr %ptr, <2 x double> %val) {
+; CHECK-LABEL: @atomicrmw_fminimumnum_2_x_double(
+; CHECK-NEXT: [[TMP1:%.*]] = load <2 x double>, ptr [[PTR:%.*]], align 16
+; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]]
+; CHECK: atomicrmw.start:
+; CHECK-NEXT: [[LOADED:%.*]] = phi <2 x double> [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
+; CHECK-NEXT: [[TMP2:%.*]] = call <2 x double> @llvm.minimumnum.v2f64(<2 x double> [[LOADED]], <2 x double> [[VAL:%.*]])
+; CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x double> [[TMP2]] to i128
+; CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x double> [[LOADED]] to i128
+; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[PTR]], i128 [[TMP4]], i128 [[TMP3]] seq_cst seq_cst, align 16
+; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i128, i1 } [[TMP5]], 1
+; CHECK-NEXT: [[NEWLOADED:%.*]] = extractvalue { i128, i1 } [[TMP5]], 0
+; CHECK-NEXT: [[TMP6]] = bitcast i128 [[NEWLOADED]] to <2 x double>
+; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
+; CHECK: atomicrmw.end:
+; CHECK-NEXT: ret <2 x double> [[TMP6]]
+;
+ %res = atomicrmw fminimumnum ptr %ptr, <2 x double> %val seq_cst
+ ret <2 x double> %res
+}
+
!0 = !{!"function_entry_count", i64 1000}
;.
; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
>From 8af15df9ca5acc1a3f9a66e270414b456955526d Mon Sep 17 00:00:00 2001
From: Gonzalo Brito Gadeschi <gonzalob at nvidia.com>
Date: Tue, 17 Mar 2026 12:47:24 -0700
Subject: [PATCH 3/3] fix mlir
---
mlir/include/mlir/Dialect/LLVMIR/LLVMEnums.td | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMEnums.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMEnums.td
index 6125ac0e328dd..51ac465000341 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMEnums.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMEnums.td
@@ -112,6 +112,8 @@ def AtomicBinOpUSubSat : LLVM_EnumAttrCase<"usub_sat",
"usub_sat", "USubSat", 18>;
def AtomicBinOpFMaximum : LLVM_EnumAttrCase<"fmaximum", "fmaximum", "FMaximum", 19>;
def AtomicBinOpFMinimum : LLVM_EnumAttrCase<"fminimum", "fminimum", "FMinimum", 20>;
+def AtomicBinOpFMaximumNum : LLVM_EnumAttrCase<"fmaximumnum", "fmaximumnum", "FMaximumNum", 21>;
+def AtomicBinOpFMinimumNum : LLVM_EnumAttrCase<"fminimumnum", "fminimumnum", "FMinimumNum", 22>;
// A sentinel value that has no MLIR counterpart.
def AtomicBadBinOp : LLVM_EnumAttrCase<"", "", "BAD_BINOP", 0>;
@@ -125,7 +127,8 @@ def AtomicBinOp : LLVM_EnumAttr<
AtomicBinOpMin, AtomicBinOpUMax, AtomicBinOpUMin, AtomicBinOpFAdd,
AtomicBinOpFSub, AtomicBinOpFMax, AtomicBinOpFMin, AtomicBinOpUIncWrap,
AtomicBinOpUDecWrap, AtomicBinOpUSubCond, AtomicBinOpUSubSat,
- AtomicBinOpFMaximum, AtomicBinOpFMinimum],
+ AtomicBinOpFMaximum, AtomicBinOpFMinimum, AtomicBinOpFMaximumNum,
+ AtomicBinOpFMinimumNum],
[AtomicBadBinOp]> {
let cppNamespace = "::mlir::LLVM";
}
More information about the Mlir-commits
mailing list