[llvm] [AMDGPU] Prefer packed minimum/maximum ops for two-input ops (PR #215449)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 10 19:40:29 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-amdgpu
Author: Yaxun (Sam) Liu (yxsamliu)
<details>
<summary>Changes</summary>
[AMDGPU] Prefer packed minimum/maximum ops for two-input ops
A two-input f16 fminimum or fmaximum operation should translate to a
packed two-input minimum/maximum instruction when the target supports
one.
It currently can be selected through the minimum3/maximum3 fallback
pattern instead. That emits a three-input instruction with one input
operand duplicated.
Keep the fallback for nested min/max expressions that can use the real
three-input instruction. Add a higher-priority direct pattern for
non-nested two-input operations on targets with packed IEEE
minimum/maximum opcodes.
---
Full diff: https://github.com/llvm/llvm-project/pull/215449.diff
2 Files Affected:
- (modified) llvm/lib/Target/AMDGPU/VOP3PInstructions.td (+24)
- (added) llvm/test/CodeGen/AMDGPU/packed-minimum-maximum-f16.ll (+23)
``````````diff
diff --git a/llvm/lib/Target/AMDGPU/VOP3PInstructions.td b/llvm/lib/Target/AMDGPU/VOP3PInstructions.td
index 6af74a3a7e1c4..c31368d4f5f19 100644
--- a/llvm/lib/Target/AMDGPU/VOP3PInstructions.td
+++ b/llvm/lib/Target/AMDGPU/VOP3PInstructions.td
@@ -444,6 +444,30 @@ class MinimumMaximumByMinimum3Maximum3VOP3P<SDPatternOperator node,
(inst $src0_mods, $src0, $src1_mods, $src1, $src1_mods, $src1)
>;
+class MinimumMaximumVOP3P<SDPatternOperator node,
+ Instruction inst> : GCNPat<
+ (v2f16 (node (VOP3PMods v2f16:$src0, i32:$src0_mods), (VOP3PMods v2f16:$src1, i32:$src1_mods))),
+ (inst $src0_mods, $src0, $src1_mods, $src1)
+>;
+
+def fminimum_not_nested : PatFrag<
+ (ops node:$src0, node:$src1), (fminimum $src0, $src1), [{
+ return N->getOperand(0).getOpcode() != ISD::FMINIMUM &&
+ N->getOperand(1).getOpcode() != ISD::FMINIMUM;
+}]>;
+
+def fmaximum_not_nested : PatFrag<
+ (ops node:$src0, node:$src1), (fmaximum $src0, $src1), [{
+ return N->getOperand(0).getOpcode() != ISD::FMAXIMUM &&
+ N->getOperand(1).getOpcode() != ISD::FMAXIMUM;
+}]>;
+
+let SubtargetPredicate = HasIEEEMinimumMaximumInsts,
+ AddedComplexity = 1 in {
+def : MinimumMaximumVOP3P<fminimum_not_nested, V_PK_MINIMUM_F16>;
+def : MinimumMaximumVOP3P<fmaximum_not_nested, V_PK_MAXIMUM_F16>;
+}
+
let SubtargetPredicate = HasMinimum3Maximum3PKF16 in {
def : MinimumMaximumByMinimum3Maximum3VOP3P<fminimum, V_PK_MINIMUM3_F16>;
def : MinimumMaximumByMinimum3Maximum3VOP3P<fmaximum, V_PK_MAXIMUM3_F16>;
diff --git a/llvm/test/CodeGen/AMDGPU/packed-minimum-maximum-f16.ll b/llvm/test/CodeGen/AMDGPU/packed-minimum-maximum-f16.ll
new file mode 100644
index 0000000000000..846eec6aed07d
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/packed-minimum-maximum-f16.ll
@@ -0,0 +1,23 @@
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx950 < %s | FileCheck -check-prefix=GFX950 %s
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1250 < %s | FileCheck -check-prefix=GFX1250 %s
+
+define <2 x half> @maximum_v2f16(<2 x half> %src0, <2 x half> %src1) {
+; GFX950-LABEL: maximum_v2f16:
+; GFX950: v_pk_maximum3_f16 v0, v0, v1, v1
+; GFX1250-LABEL: maximum_v2f16:
+; GFX1250: v_pk_maximum_f16 v0, v0, v1
+ %max = call <2 x half> @llvm.maximum.v2f16(<2 x half> %src0, <2 x half> %src1)
+ ret <2 x half> %max
+}
+
+define <2 x half> @minimum_v2f16(<2 x half> %src0, <2 x half> %src1) {
+; GFX950-LABEL: minimum_v2f16:
+; GFX950: v_pk_minimum3_f16 v0, v0, v1, v1
+; GFX1250-LABEL: minimum_v2f16:
+; GFX1250: v_pk_minimum_f16 v0, v0, v1
+ %min = call <2 x half> @llvm.minimum.v2f16(<2 x half> %src0, <2 x half> %src1)
+ ret <2 x half> %min
+}
+
+declare <2 x half> @llvm.maximum.v2f16(<2 x half>, <2 x half>)
+declare <2 x half> @llvm.minimum.v2f16(<2 x half>, <2 x half>)
``````````
</details>
https://github.com/llvm/llvm-project/pull/215449
More information about the llvm-commits
mailing list