[Mlir-commits] [mlir] [mlir][arith] Add minimumnumf and maximumnumf operations (PR #221658)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon Sep 7 00:04:14 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-linalg
@llvm/pr-subscribers-mlir
Author: lorenzo chelini (chelini)
<details>
<summary>Changes</summary>
Add `arith.minimumnumf` and `arith.maximumnumf`, following `minimumNumber` and `maximumNumber` from IEEE 754-2019 and the `llvm.minimumnum`/`llvm.maximumnum` intrinsics. They differ from the existing `arith.minnumf`/`arith.maxnumf` only in their treatment of signaling NaNs: the new ops deterministically return the non-NaN operand, whereas minnumf/maxnumf may return either NaN or the other operand.
---
Patch is 31.39 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/221658.diff
17 Files Affected:
- (modified) mlir/include/mlir/Dialect/Arith/IR/ArithOps.td (+52)
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td (+4)
- (modified) mlir/include/mlir/Dialect/Vector/IR/VectorAttributes.td (+4-1)
- (modified) mlir/lib/Conversion/ArithToLLVM/ArithToLLVM.cpp (+10)
- (modified) mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp (+26)
- (modified) mlir/lib/Dialect/Arith/IR/ArithOps.cpp (+34)
- (modified) mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp (+4)
- (modified) mlir/lib/Dialect/Vector/IR/VectorOps.cpp (+12)
- (modified) mlir/lib/Dialect/Vector/Transforms/LowerVectorContract.cpp (+3-1)
- (modified) mlir/lib/Dialect/Vector/Transforms/LowerVectorScan.cpp (+2)
- (modified) mlir/lib/Dialect/XeGPU/Utils/XeGPUUtils.cpp (+2)
- (modified) mlir/test/Conversion/ArithToLLVM/arith-to-llvm.mlir (+53-4)
- (modified) mlir/test/Conversion/VectorToLLVM/vector-to-llvm-interface.mlir (+24)
- (modified) mlir/test/Dialect/Arith/ops.mlir (+6-1)
- (modified) mlir/test/Dialect/Vector/ops.mlir (+4)
- (modified) mlir/test/Target/LLVMIR/Import/intrinsic.ll (+28)
- (modified) mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir (+22)
``````````diff
diff --git a/mlir/include/mlir/Dialect/Arith/IR/ArithOps.td b/mlir/include/mlir/Dialect/Arith/IR/ArithOps.td
index 39d6838ae1ab4..219fb12ab4ed1 100644
--- a/mlir/include/mlir/Dialect/Arith/IR/ArithOps.td
+++ b/mlir/include/mlir/Dialect/Arith/IR/ArithOps.td
@@ -1190,6 +1190,32 @@ def Arith_MaxNumFOp : Arith_FloatBinaryOp<"maxnumf", [Commutative]> {
let hasFolder = 1;
}
+//===----------------------------------------------------------------------===//
+// MaximumNumFOp
+//===----------------------------------------------------------------------===//
+
+def Arith_MaximumNumFOp : Arith_FloatBinaryOp<"maximumnumf", [Commutative]> {
+ let summary = "floating-point maximumNumber operation";
+ let description = [{
+ Returns the maximum of the two arguments, not propagating NaNs and treating
+ -0.0 as less than +0.0.
+
+ If both operands are NaNs, returns a NaN. If one operand is NaN and the
+ other operand is a number, returns the number. Otherwise, returns the
+ greater of the two arguments. -0.0 is considered to be less than +0.0 for
+ this operation.
+
+ If the `nsz` flag is specified, `arith.maximumnumf` with one +0.0 and one
+ -0.0 operand may non-deterministically return either operand. Unlike the
+ usual `nsz` semantics, if both zero operands have the same sign, the result
+ must retain that sign. For example, `maximumnumf(+0.0, +0.0)` with `nsz`
+ must return +0.0, while `maximumnumf(-0.0, +0.0)` may return either zero.
+
+ This operation follows the semantics of `maximumNumber` in IEEE 754-2019.
+ }];
+ let hasFolder = 1;
+}
+
//===----------------------------------------------------------------------===//
// MaxSIOp
@@ -1252,6 +1278,32 @@ def Arith_MinNumFOp : Arith_FloatBinaryOp<"minnumf", [Commutative]> {
let hasFolder = 1;
}
+//===----------------------------------------------------------------------===//
+// MinimumNumFOp
+//===----------------------------------------------------------------------===//
+
+def Arith_MinimumNumFOp : Arith_FloatBinaryOp<"minimumnumf", [Commutative]> {
+ let summary = "floating-point minimumNumber operation";
+ let description = [{
+ Returns the minimum of the two arguments, not propagating NaNs and treating
+ -0.0 as less than +0.0.
+
+ If both operands are NaNs, returns a NaN. If one operand is NaN and the
+ other operand is a number, returns the number. Otherwise, returns the
+ lesser of the two arguments. -0.0 is considered to be less than +0.0 for
+ this operation.
+
+ If the `nsz` flag is specified, `arith.minimumnumf` with one +0.0 and one
+ -0.0 operand may non-deterministically return either operand. Unlike the
+ usual `nsz` semantics, if both zero operands have the same sign, the result
+ must retain that sign. For example, `minimumnumf(-0.0, -0.0)` with `nsz`
+ must return -0.0, while `minimumnumf(-0.0, +0.0)` may return either zero.
+
+ This operation follows the semantics of `minimumNumber` in IEEE 754-2019.
+ }];
+ let hasFolder = 1;
+}
+
//===----------------------------------------------------------------------===//
// MinSIOp
//===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
index f40f3f5ebda93..41ad8f0746820 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
@@ -183,6 +183,8 @@ def LLVM_MaxNumOp : LLVM_BinarySameArgsIntrOpF<"maxnum">;
def LLVM_MinNumOp : LLVM_BinarySameArgsIntrOpF<"minnum">;
def LLVM_MaximumOp : LLVM_BinarySameArgsIntrOpF<"maximum">;
def LLVM_MinimumOp : LLVM_BinarySameArgsIntrOpF<"minimum">;
+def LLVM_MaximumNumOp : LLVM_BinarySameArgsIntrOpF<"maximumnum">;
+def LLVM_MinimumNumOp : LLVM_BinarySameArgsIntrOpF<"minimumnum">;
def LLVM_SMaxOp : LLVM_BinarySameArgsIntrOpI<"smax">;
def LLVM_SMinOp : LLVM_BinarySameArgsIntrOpI<"smin">;
def LLVM_UMaxOp : LLVM_BinarySameArgsIntrOpI<"umax">;
@@ -1232,6 +1234,8 @@ def LLVM_vector_reduce_fmax : LLVM_VecReductionF<"fmax">;
def LLVM_vector_reduce_fmin : LLVM_VecReductionF<"fmin">;
def LLVM_vector_reduce_fmaximum : LLVM_VecReductionF<"fmaximum">;
def LLVM_vector_reduce_fminimum : LLVM_VecReductionF<"fminimum">;
+def LLVM_vector_reduce_fmaximumnum : LLVM_VecReductionF<"fmaximumnum">;
+def LLVM_vector_reduce_fminimumnum : LLVM_VecReductionF<"fminimumnum">;
def LLVM_vector_reduce_fadd : LLVM_VecReductionAccF<"fadd">;
def LLVM_vector_reduce_fmul : LLVM_VecReductionAccF<"fmul">;
diff --git a/mlir/include/mlir/Dialect/Vector/IR/VectorAttributes.td b/mlir/include/mlir/Dialect/Vector/IR/VectorAttributes.td
index 58e18a15e9409..27a64ee2df0c6 100644
--- a/mlir/include/mlir/Dialect/Vector/IR/VectorAttributes.td
+++ b/mlir/include/mlir/Dialect/Vector/IR/VectorAttributes.td
@@ -30,6 +30,8 @@ def COMBINING_KIND_OR : I32EnumAttrCase<"OR", 9, "or">;
def COMBINING_KIND_XOR : I32EnumAttrCase<"XOR", 10, "xor">;
def COMBINING_KIND_MINIMUMF : I32EnumAttrCase<"MINIMUMF", 11, "minimumf">;
def COMBINING_KIND_MAXIMUMF : I32EnumAttrCase<"MAXIMUMF", 12, "maximumf">;
+def COMBINING_KIND_MINIMUMNUMF : I32EnumAttrCase<"MINIMUMNUMF", 13, "minimumnumf">;
+def COMBINING_KIND_MAXIMUMNUMF : I32EnumAttrCase<"MAXIMUMNUMF", 14, "maximumnumf">;
def CombiningKind : I32EnumAttr<
"CombiningKind",
@@ -38,7 +40,8 @@ def CombiningKind : I32EnumAttr<
COMBINING_KIND_MINSI, COMBINING_KIND_MINNUMF, COMBINING_KIND_MAXUI,
COMBINING_KIND_MAXSI, COMBINING_KIND_MAXNUMF, COMBINING_KIND_AND,
COMBINING_KIND_OR, COMBINING_KIND_XOR,
- COMBINING_KIND_MAXIMUMF, COMBINING_KIND_MINIMUMF]> {
+ COMBINING_KIND_MAXIMUMF, COMBINING_KIND_MINIMUMF,
+ COMBINING_KIND_MAXIMUMNUMF, COMBINING_KIND_MINIMUMNUMF]> {
let cppNamespace = "::mlir::vector";
let genSpecializedAttr = 0;
}
diff --git a/mlir/lib/Conversion/ArithToLLVM/ArithToLLVM.cpp b/mlir/lib/Conversion/ArithToLLVM/ArithToLLVM.cpp
index 982b1e5e9a8d1..198b1490f0046 100644
--- a/mlir/lib/Conversion/ArithToLLVM/ArithToLLVM.cpp
+++ b/mlir/lib/Conversion/ArithToLLVM/ArithToLLVM.cpp
@@ -139,6 +139,10 @@ using MaxNumFOpLowering =
VectorConvertToLLVMPattern<arith::MaxNumFOp, LLVM::MaxNumOp,
arith::AttrConvertFastMathToLLVM,
/*FailOnUnsupportedFP=*/true>;
+using MaximumNumFOpLowering =
+ VectorConvertToLLVMPattern<arith::MaximumNumFOp, LLVM::MaximumNumOp,
+ arith::AttrConvertFastMathToLLVM,
+ /*FailOnUnsupportedFP=*/true>;
using MaxSIOpLowering =
VectorConvertToLLVMPattern<arith::MaxSIOp, LLVM::SMaxOp>;
using MaxUIOpLowering =
@@ -151,6 +155,10 @@ using MinNumFOpLowering =
VectorConvertToLLVMPattern<arith::MinNumFOp, LLVM::MinNumOp,
arith::AttrConvertFastMathToLLVM,
/*FailOnUnsupportedFP=*/true>;
+using MinimumNumFOpLowering =
+ VectorConvertToLLVMPattern<arith::MinimumNumFOp, LLVM::MinimumNumOp,
+ arith::AttrConvertFastMathToLLVM,
+ /*FailOnUnsupportedFP=*/true>;
using MinSIOpLowering =
VectorConvertToLLVMPattern<arith::MinSIOp, LLVM::SMinOp>;
using MinUIOpLowering =
@@ -884,10 +892,12 @@ void mlir::arith::populateArithToLLVMConversionPatterns(
IndexCastOpUILowering,
MaximumFOpLowering,
MaxNumFOpLowering,
+ MaximumNumFOpLowering,
MaxSIOpLowering,
MaxUIOpLowering,
MinimumFOpLowering,
MinNumFOpLowering,
+ MinimumNumFOpLowering,
MinSIOpLowering,
MinUIOpLowering,
MulFOpLowering,
diff --git a/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp b/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp
index 152c45b695cee..0c2d1d5fc7732 100644
--- a/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp
+++ b/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp
@@ -674,6 +674,14 @@ template <>
struct VectorToScalarMapper<LLVM::vector_reduce_fmin> {
using Type = LLVM::MinNumOp;
};
+template <>
+struct VectorToScalarMapper<LLVM::vector_reduce_fmaximumnum> {
+ using Type = LLVM::MaximumNumOp;
+};
+template <>
+struct VectorToScalarMapper<LLVM::vector_reduce_fminimumnum> {
+ using Type = LLVM::MinimumNumOp;
+};
} // namespace
template <class LLVMRedIntrinOp>
@@ -909,6 +917,14 @@ class VectorReductionOpConversion
} else if (kind == vector::CombiningKind::MAXNUMF) {
result = createFPReductionComparisonOpLowering<LLVM::vector_reduce_fmax>(
rewriter, loc, llvmType, operand, acc, fmf);
+ } else if (kind == vector::CombiningKind::MAXIMUMNUMF) {
+ result = createFPReductionComparisonOpLowering<
+ LLVM::vector_reduce_fmaximumnum>(rewriter, loc, llvmType, operand,
+ acc, fmf);
+ } else if (kind == vector::CombiningKind::MINIMUMNUMF) {
+ result = createFPReductionComparisonOpLowering<
+ LLVM::vector_reduce_fminimumnum>(rewriter, loc, llvmType, operand,
+ acc, fmf);
} else {
return failure();
}
@@ -1044,6 +1060,16 @@ class MaskedReductionOpConversion
MaskNeutralFMinimum>(
rewriter, loc, llvmType, operand, acc, maskOp.getMask(), fmf);
break;
+ case CombiningKind::MAXIMUMNUMF:
+ result = lowerMaskedReductionWithRegular<LLVM::vector_reduce_fmaximumnum,
+ MaskNeutralFMaximum>(
+ rewriter, loc, llvmType, operand, acc, maskOp.getMask(), fmf);
+ break;
+ case CombiningKind::MINIMUMNUMF:
+ result = lowerMaskedReductionWithRegular<LLVM::vector_reduce_fminimumnum,
+ MaskNeutralFMinimum>(
+ rewriter, loc, llvmType, operand, acc, maskOp.getMask(), fmf);
+ break;
}
// Replace `vector.mask` operation altogether.
diff --git a/mlir/lib/Dialect/Arith/IR/ArithOps.cpp b/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
index a3fea3373ab84..69e6a4018f9c1 100644
--- a/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
+++ b/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
@@ -1437,6 +1437,22 @@ OpFoldResult arith::MaxNumFOp::fold(FoldAdaptor adaptor) {
return constFoldBinaryOp<FloatAttr>(adaptor.getOperands(), llvm::maxnum);
}
+//===----------------------------------------------------------------------===//
+// MaximumNumFOp
+//===----------------------------------------------------------------------===//
+
+OpFoldResult arith::MaximumNumFOp::fold(FoldAdaptor adaptor) {
+ // maximumnumf(x,x) -> x
+ if (getLhs() == getRhs())
+ return getRhs();
+
+ // maximumnumf(x, NaN) -> x
+ if (matchPattern(adaptor.getRhs(), m_NaNFloat()))
+ return getLhs();
+
+ return constFoldBinaryOp<FloatAttr>(adaptor.getOperands(), llvm::maximumnum);
+}
+
//===----------------------------------------------------------------------===//
// MaxSIOp
//===----------------------------------------------------------------------===//
@@ -1515,6 +1531,22 @@ OpFoldResult arith::MinNumFOp::fold(FoldAdaptor adaptor) {
return constFoldBinaryOp<FloatAttr>(adaptor.getOperands(), llvm::minnum);
}
+//===----------------------------------------------------------------------===//
+// MinimumNumFOp
+//===----------------------------------------------------------------------===//
+
+OpFoldResult arith::MinimumNumFOp::fold(FoldAdaptor adaptor) {
+ // minimumnumf(x,x) -> x
+ if (getLhs() == getRhs())
+ return getRhs();
+
+ // minimumnumf(x, NaN) -> x
+ if (matchPattern(adaptor.getRhs(), m_NaNFloat()))
+ return getLhs();
+
+ return constFoldBinaryOp<FloatAttr>(adaptor.getOperands(), llvm::minimumnum);
+}
+
//===----------------------------------------------------------------------===//
// MinSIOp
//===----------------------------------------------------------------------===//
@@ -2068,8 +2100,10 @@ void arith::TruncFOp::getCanonicalizationPatterns(RewritePatternSet &patterns,
MLIRContext *context) {
patterns.add<NarrowExtremum<TruncFOp, ExtFOp, MaximumFOp>,
NarrowExtremum<TruncFOp, ExtFOp, MaxNumFOp>,
+ NarrowExtremum<TruncFOp, ExtFOp, MaximumNumFOp>,
NarrowExtremum<TruncFOp, ExtFOp, MinimumFOp>,
NarrowExtremum<TruncFOp, ExtFOp, MinNumFOp>,
+ NarrowExtremum<TruncFOp, ExtFOp, MinimumNumFOp>,
TruncFSIToFPToSIToFP, TruncFUIToFPToUIToFP>(context);
}
diff --git a/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp b/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp
index e19f59f0e4478..85352602181c4 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp
@@ -650,10 +650,12 @@ mlir::linalg::getCombinerOpKind(Operation *combinerOp) {
.Case([&](arith::MaxUIOp op) { return CombiningKind::MAXUI; })
.Case([&](arith::MaximumFOp op) { return CombiningKind::MAXIMUMF; })
.Case([&](arith::MaxNumFOp op) { return CombiningKind::MAXNUMF; })
+ .Case([&](arith::MaximumNumFOp op) { return CombiningKind::MAXIMUMNUMF; })
.Case([&](arith::MinSIOp op) { return CombiningKind::MINSI; })
.Case([&](arith::MinUIOp op) { return CombiningKind::MINUI; })
.Case([&](arith::MinimumFOp op) { return CombiningKind::MINIMUMF; })
.Case([&](arith::MinNumFOp op) { return CombiningKind::MINNUMF; })
+ .Case([&](arith::MinimumNumFOp op) { return CombiningKind::MINIMUMNUMF; })
.Case<arith::MulIOp, arith::MulFOp>(
[&](auto op) { return CombiningKind::MUL; })
.Case([&](arith::OrIOp op) { return CombiningKind::OR; })
@@ -2205,10 +2207,12 @@ static bool isSupportedPoolKind(vector::CombiningKind kind) {
case vector::CombiningKind::ADD:
case vector::CombiningKind::MAXNUMF:
case vector::CombiningKind::MAXIMUMF:
+ case vector::CombiningKind::MAXIMUMNUMF:
case vector::CombiningKind::MAXSI:
case vector::CombiningKind::MAXUI:
case vector::CombiningKind::MINNUMF:
case vector::CombiningKind::MINIMUMF:
+ case vector::CombiningKind::MINIMUMNUMF:
case vector::CombiningKind::MINSI:
case vector::CombiningKind::MINUI:
return true;
diff --git a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
index f8f3deb2e4789..05e21bedbcc9c 100644
--- a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
+++ b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
@@ -152,6 +152,8 @@ static bool isSupportedCombiningKind(CombiningKind combiningKind,
case CombiningKind::MAXNUMF:
case CombiningKind::MINIMUMF:
case CombiningKind::MAXIMUMF:
+ case CombiningKind::MINIMUMNUMF:
+ case CombiningKind::MAXIMUMNUMF:
return llvm::isa<FloatType>(elementType);
}
return false;
@@ -8280,6 +8282,11 @@ Value mlir::vector::makeArithReduction(OpBuilder &b, Location loc,
"expected float values");
result = b.createOrFold<arith::MaxNumFOp>(loc, v1, acc, fastmath);
break;
+ case CombiningKind::MAXIMUMNUMF:
+ assert(llvm::isa<FloatType>(t1) && llvm::isa<FloatType>(tAcc) &&
+ "expected float values");
+ result = b.createOrFold<arith::MaximumNumFOp>(loc, v1, acc, fastmath);
+ break;
case CombiningKind::MAXIMUMF:
assert(llvm::isa<FloatType>(t1) && llvm::isa<FloatType>(tAcc) &&
"expected float values");
@@ -8290,6 +8297,11 @@ Value mlir::vector::makeArithReduction(OpBuilder &b, Location loc,
"expected float values");
result = b.createOrFold<arith::MinNumFOp>(loc, v1, acc, fastmath);
break;
+ case CombiningKind::MINIMUMNUMF:
+ assert(llvm::isa<FloatType>(t1) && llvm::isa<FloatType>(tAcc) &&
+ "expected float values");
+ result = b.createOrFold<arith::MinimumNumFOp>(loc, v1, acc, fastmath);
+ break;
case CombiningKind::MINIMUMF:
assert(llvm::isa<FloatType>(t1) && llvm::isa<FloatType>(tAcc) &&
"expected float values");
diff --git a/mlir/lib/Dialect/Vector/Transforms/LowerVectorContract.cpp b/mlir/lib/Dialect/Vector/Transforms/LowerVectorContract.cpp
index f6fff0ffe323a..27189c58eac27 100644
--- a/mlir/lib/Dialect/Vector/Transforms/LowerVectorContract.cpp
+++ b/mlir/lib/Dialect/Vector/Transforms/LowerVectorContract.cpp
@@ -148,7 +148,9 @@ createContractArithOp(Location loc, Value x, Value y, Value acc,
if (isInt) {
if (kind == CombiningKind::MINNUMF || kind == CombiningKind::MAXNUMF ||
- kind == CombiningKind::MINIMUMF || kind == CombiningKind::MAXIMUMF)
+ kind == CombiningKind::MINIMUMF || kind == CombiningKind::MAXIMUMF ||
+ kind == CombiningKind::MINIMUMNUMF ||
+ kind == CombiningKind::MAXIMUMNUMF)
// Only valid for floating point types.
return std::nullopt;
mul = arith::MulIOp::create(rewriter, loc, x, y);
diff --git a/mlir/lib/Dialect/Vector/Transforms/LowerVectorScan.cpp b/mlir/lib/Dialect/Vector/Transforms/LowerVectorScan.cpp
index f3e239bedb7f7..c3ea8de30357e 100644
--- a/mlir/lib/Dialect/Vector/Transforms/LowerVectorScan.cpp
+++ b/mlir/lib/Dialect/Vector/Transforms/LowerVectorScan.cpp
@@ -38,6 +38,8 @@ static bool isValidKind(bool isInt, vector::CombiningKind kind) {
case CombiningKind::MINIMUMF:
case CombiningKind::MAXNUMF:
case CombiningKind::MAXIMUMF:
+ case CombiningKind::MAXIMUMNUMF:
+ case CombiningKind::MINIMUMNUMF:
type = KindType::FLOAT;
break;
case CombiningKind::MINUI:
diff --git a/mlir/lib/Dialect/XeGPU/Utils/XeGPUUtils.cpp b/mlir/lib/Dialect/XeGPU/Utils/XeGPUUtils.cpp
index bd2fe1e7f1a6b..1a3d412a752a3 100644
--- a/mlir/lib/Dialect/XeGPU/Utils/XeGPUUtils.cpp
+++ b/mlir/lib/Dialect/XeGPU/Utils/XeGPUUtils.cpp
@@ -765,6 +765,7 @@ Value xegpu::createReductionNeutralValue(OpBuilder &builder, Location loc,
case vector::CombiningKind::MINNUMF:
case vector::CombiningKind::MINIMUMF:
+ case vector::CombiningKind::MINIMUMNUMF:
if (auto floatTy = dyn_cast<FloatType>(elemTy))
return makeConst(builder.getFloatAttr(
elemTy, APFloat::getInf(floatTy.getFloatSemantics())));
@@ -772,6 +773,7 @@ Value xegpu::createReductionNeutralValue(OpBuilder &builder, Location loc,
case vector::CombiningKind::MAXNUMF:
case vector::CombiningKind::MAXIMUMF:
+ case vector::CombiningKind::MAXIMUMNUMF:
if (auto floatTy = dyn_cast<FloatType>(elemTy))
return makeConst(builder.getFloatAttr(
elemTy, APFloat::getInf(floatTy.getFloatSemantics(), true)));
diff --git a/mlir/test/Conversion/ArithToLLVM/arith-to-llvm.mlir b/mlir/test/Conversion/ArithToLLVM/arith-to-llvm.mlir
index c21e967976e4c..677eacd6a92cf 100644
--- a/mlir/test/Conversion/ArithToLLVM/arith-to-llvm.mlir
+++ b/mlir/test/Conversion/ArithToLLVM/arith-to-llvm.mlir
@@ -838,11 +838,56 @@ func.func @minmaxf(%arg0 : f32, %arg1 : f32) -> f32 {
%2 = arith.minnumf %arg0, %arg1 : f32
// CHECK: = llvm.intr.maxnum(%arg0, %arg1) : (f32, f32) -> f32
%3 = arith.maxnumf %arg0, %arg1 : f32
+ // CHECK: = llvm.intr.minimumnum(%arg0, %arg1) : (f32, f32) -> f32
+ %4 = arith.minimumnumf %arg0, %arg1 : f32
+ // CHECK: = llvm.intr.maximumnum(%arg0, %arg1) : (f32, f32) -> f32
+ %5 = arith.maximumnumf %arg0, %arg1 : f32
return %0 : f32
}
// -----
+// CHECK-LABEL: @minmaxnumf_float_widths
+func.func @minmaxnumf_float_widths(%arg0 : f16, %arg1 : f16, %arg2 : bf16,
+ %arg3 : bf16, %arg4 : f64, %arg5 : f64) {
+ // CHECK: = llvm.intr.minimumnum(%arg0, %arg1) : (f16, f16) -> f16
+ %0 = arith.minimumnumf %arg0, %arg1 : f16
+ // CHECK: = llvm.intr.maximumnum(%arg0, %arg1) : (f16, f16) -> f16
+ %1 = arith.maximumnumf %arg0, %arg1 : f16
+ // CHECK: = llvm.intr.minimumnum(%arg2, %arg3) : (bf16, bf16) -> bf16
+ %2 = arith.minimumnumf %arg2, %arg3 : bf16
+ // CHECK: = llvm.intr.maximumnum(%arg2, %arg3) : (bf16, bf16) -> bf16
+ %3 = arith.maximumnumf %arg2, %arg3 : bf16
+ // CHECK: = llvm.intr.minimumnum(%arg4, %arg5) : (f64, f64) -> f64
+ %4 = arith.minimumnumf %arg4, %arg5 : f64
+ // CHECK: = llvm.intr.maximumnum(%arg4, %arg5) : (f64, f64) -> f64
+ %5 = arith.maximumnumf %arg4, %arg5 : f64
+ return
+}
+
+// -----
+
+// CHECK-LABEL: @minmaxnumf_vector
+func.func @minmaxnumf_vector(%arg0 : vector<4xf32>, %arg1 : vector<4xf32>) {
+ // CHECK: = llvm.intr.minimumnum(%arg0, %arg1) : (vector<4xf32>, vector<4xf32>...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/221658
More information about the Mlir-commits
mailing list