[llvm] SelectionDAG: Expand fminimumnum/fmaximumnum for promote (PR #135614)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 14 03:44:49 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64
Author: YunQiang Su (wzssyqa)
<details>
<summary>Changes</summary>
In SelectionDAG/TargetLowering.cpp, if backend set ISD::MAXNUM and ISD::MINNUM for VT as Promated, we can expand it to:
FP_EXTEND
FP_EXTEND
MAXNUM_IEEE/MINNUM_IEEE
FP_ROUND
And here we set MAXNUM_IEEE, MINNUM_IEEE as Promote for f16 on AArch64.
---
Full diff: https://github.com/llvm/llvm-project/pull/135614.diff
3 Files Affected:
- (modified) llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp (+11)
- (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.cpp (+2)
- (added) llvm/test/CodeGen/AArch64/fminmax-f16-promote.ll (+28)
``````````diff
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 89f806d8b1c30..9050b5a57541b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -8645,6 +8645,17 @@ SDValue TargetLowering::expandFMINIMUMNUM_FMAXIMUMNUM(SDNode *Node,
return DAG.getNode(NewOp, DL, VT, LHS, RHS, Flags);
}
+ if (getOperationAction(NewOp, VT) == Promote) {
+ MVT PromoteVT = getTypeToPromoteTo(NewOp, VT.getSimpleVT());
+ if (isOperationLegal(NewOp, PromoteVT)) {
+ LHS = DAG.getNode(ISD::FP_EXTEND, DL, PromoteVT, LHS);
+ RHS = DAG.getNode(ISD::FP_EXTEND, DL, PromoteVT, RHS);
+ SDValue Result = DAG.getNode(NewOp, DL, PromoteVT, LHS, RHS, Flags);
+ return DAG.getNode(ISD::FP_ROUND, DL, VT, Result,
+ DAG.getIntPtrConstant(0, DL, /*isTarget=*/true));
+ }
+ }
+
// We can use FMINIMUM/FMAXIMUM if there is no NaN, since it has
// same behaviors for all of other cases: +0.0 vs -0.0 included.
if (Flags.hasNoNaNs() ||
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 830ec6886e6bc..c6bbfa4c12698 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -885,6 +885,8 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
// AArch64 has implementations of a lot of rounding-like FP operations.
// clang-format off
+ for (auto Op : {ISD::FMINNUM_IEEE, ISD::FMAXNUM_IEEE})
+ setOperationAction(Op, MVT::f16, Promote);
for (auto Op :
{ISD::FFLOOR, ISD::FNEARBYINT, ISD::FCEIL,
ISD::FRINT, ISD::FTRUNC, ISD::FROUND,
diff --git a/llvm/test/CodeGen/AArch64/fminmax-f16-promote.ll b/llvm/test/CodeGen/AArch64/fminmax-f16-promote.ll
new file mode 100644
index 0000000000000..abd0a8e6591ec
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/fminmax-f16-promote.ll
@@ -0,0 +1,28 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=aarch64 -verify-machineinstrs %s -o - | FileCheck %s
+
+define half @min(half noundef %a, half noundef %b) {
+; CHECK-LABEL: min:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: fcvt s1, h1
+; CHECK-NEXT: fcvt s0, h0
+; CHECK-NEXT: fminnm s0, s0, s1
+; CHECK-NEXT: fcvt h0, s0
+; CHECK-NEXT: ret
+entry:
+ %0 = tail call half @llvm.minimumnum.f16(half %a, half %b)
+ ret half %0
+}
+
+define half @max(half noundef %a, half noundef %b) {
+; CHECK-LABEL: max:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: fcvt s1, h1
+; CHECK-NEXT: fcvt s0, h0
+; CHECK-NEXT: fmaxnm s0, s0, s1
+; CHECK-NEXT: fcvt h0, s0
+; CHECK-NEXT: ret
+entry:
+ %0 = tail call half @llvm.maximumnum.f16(half %a, half %b)
+ ret half %0
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/135614
More information about the llvm-commits
mailing list