[llvm] [SystemZ] Support pseudo fmin/fmax (PR #209178)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 13 06:30:09 PDT 2026
https://github.com/nikic created https://github.com/llvm/llvm-project/pull/209178
s390x supports the pseudo fmin/fmax operations (x < y ? x : y and x > y ? x : y) as mode 2 in vfmin/vfmax. As such, we should lower PSEUDO_FMIN/FMAX to those. Also disable formation of minnum/maxnum in SDAGBuilder, as it's not useful if we have native support for this operation.
>From e0e05c32c3a68319fbc1fba65431ce18f21316d2 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Thu, 9 Jul 2026 17:06:59 +0200
Subject: [PATCH] [SystemZ] Support pseudo fmin/fmax
s390x supports the pseudo fmin/fmax operations (x < y ? x : y and
x > y ? x : y) as mode 2 in vfmin/vfmax. As such, we should lower
PSEUDO_FMIN/FMAX to those. Also disable formation of minnum/maxnum
in SDAGBuilder, as it's not useful if we have native support for
this operation.
---
llvm/lib/Target/SystemZ/SystemZISelLowering.cpp | 2 ++
llvm/lib/Target/SystemZ/SystemZISelLowering.h | 6 ++++++
llvm/lib/Target/SystemZ/SystemZInstrVector.td | 2 ++
llvm/test/CodeGen/SystemZ/vec-max-05.ll | 6 +++---
llvm/test/CodeGen/SystemZ/vec-max-min-zerosplat.ll | 8 ++++----
llvm/test/CodeGen/SystemZ/vec-min-05.ll | 6 +++---
6 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index 42d100cd4f574..913ddee6637c9 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -698,9 +698,11 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::FMAXNUM, Type, Legal);
setOperationAction(ISD::FMAXIMUM, Type, Legal);
setOperationAction(ISD::FMAXIMUMNUM, Type, Legal);
+ setOperationAction(ISD::PSEUDO_FMAX, Type, Legal);
setOperationAction(ISD::FMINNUM, Type, Legal);
setOperationAction(ISD::FMINIMUM, Type, Legal);
setOperationAction(ISD::FMINIMUMNUM, Type, Legal);
+ setOperationAction(ISD::PSEUDO_FMIN, Type, Legal);
}
// Handle constrained floating-point operations.
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.h b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
index a4c38d41b4880..6af2019b2ce22 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.h
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
@@ -156,6 +156,12 @@ class SystemZTargetLowering : public TargetLowering {
return true;
}
+ bool isProfitableToCombineMinNumMaxNum(EVT VT) const override {
+ // We have instructions for pseudo min/max, no need to convert them to
+ // minnum/maxnum.
+ return false;
+ }
+
// This function currently returns cost for srl/ipm/cc sequence for merging.
CondMergingParams
getJumpConditionMergingParams(Instruction::BinaryOps Opc, const Value *Lhs,
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrVector.td b/llvm/lib/Target/SystemZ/SystemZInstrVector.td
index 1dbbb1b9222cc..503a55dfe717b 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrVector.td
+++ b/llvm/lib/Target/SystemZ/SystemZInstrVector.td
@@ -1626,6 +1626,7 @@ let Predicates = [FeatureVector] in {
def : FPMinMax<insn, any_fmaxnum, tr, 4>;
def : FPMinMax<insn, fmaximumnum, tr, 4>;
def : FPMinMax<insn, any_fmaximum, tr, 1>;
+ def : FPMinMax<insn, pseudo_fmax, tr, 2>;
}
let Predicates = [FeatureVectorEnhancements1] in {
let Uses = [FPC], mayRaiseFPException = 1, isCommutable = 1 in {
@@ -1653,6 +1654,7 @@ let Predicates = [FeatureVector] in {
def : FPMinMax<insn, any_fminnum, tr, 4>;
def : FPMinMax<insn, fminimumnum, tr, 4>;
def : FPMinMax<insn, any_fminimum, tr, 1>;
+ def : FPMinMax<insn, pseudo_fmin, tr, 2>;
}
let Predicates = [FeatureVectorEnhancements1] in {
let Uses = [FPC], mayRaiseFPException = 1, isCommutable = 1 in {
diff --git a/llvm/test/CodeGen/SystemZ/vec-max-05.ll b/llvm/test/CodeGen/SystemZ/vec-max-05.ll
index b1b0679306a90..7d653088382e3 100644
--- a/llvm/test/CodeGen/SystemZ/vec-max-05.ll
+++ b/llvm/test/CodeGen/SystemZ/vec-max-05.ll
@@ -61,7 +61,7 @@ define double @f4(double %dummy, double %val) {
; CHECK-LABEL: f4:
; CHECK: # %bb.0:
; CHECK-NEXT: lzdr %f0
-; CHECK-NEXT: wfmaxdb %f0, %f2, %f0, 4
+; CHECK-NEXT: wfmaxdb %f0, %f2, %f0, 2
; CHECK-NEXT: br %r14
%cmp = fcmp ogt double %val, 0.0
%ret = select i1 %cmp, double %val, double 0.0
@@ -172,7 +172,7 @@ define float @f14(float %dummy, float %val) {
; CHECK-LABEL: f14:
; CHECK: # %bb.0:
; CHECK-NEXT: lzer %f0
-; CHECK-NEXT: wfmaxsb %f0, %f2, %f0, 4
+; CHECK-NEXT: wfmaxsb %f0, %f2, %f0, 2
; CHECK-NEXT: br %r14
%cmp = fcmp ogt float %val, 0.0
%ret = select i1 %cmp, float %val, float 0.0
@@ -280,7 +280,7 @@ define void @f24(ptr %ptr, ptr %dst) {
; CHECK: # %bb.0:
; CHECK-NEXT: vl %v0, 0(%r2), 3
; CHECK-NEXT: vzero %v1
-; CHECK-NEXT: wfmaxxb %v0, %v0, %v1, 4
+; CHECK-NEXT: wfmaxxb %v0, %v0, %v1, 2
; CHECK-NEXT: vst %v0, 0(%r3), 3
; CHECK-NEXT: br %r14
%val = load fp128, ptr %ptr
diff --git a/llvm/test/CodeGen/SystemZ/vec-max-min-zerosplat.ll b/llvm/test/CodeGen/SystemZ/vec-max-min-zerosplat.ll
index 10f9f28e599f8..8fb2cc6d5cd2b 100644
--- a/llvm/test/CodeGen/SystemZ/vec-max-min-zerosplat.ll
+++ b/llvm/test/CodeGen/SystemZ/vec-max-min-zerosplat.ll
@@ -8,7 +8,7 @@ define <2 x double> @f1(<2 x double> %val) {
; CHECK-LABEL: f1:
; CHECK: # %bb.0:
; CHECK-NEXT: vgbm %v0, 0
-; CHECK-NEXT: vfmaxdb %v24, %v24, %v0, 4
+; CHECK-NEXT: vfmaxdb %v24, %v24, %v0, 2
; CHECK-NEXT: br %r14
%cmp = fcmp ogt <2 x double> %val, zeroinitializer
%ret = select <2 x i1> %cmp, <2 x double> %val, <2 x double> zeroinitializer
@@ -19,7 +19,7 @@ define <2 x double> @f2(<2 x double> %val) {
; CHECK-LABEL: f2:
; CHECK: # %bb.0:
; CHECK-NEXT: vgbm %v0, 0
-; CHECK-NEXT: vfmindb %v24, %v24, %v0, 4
+; CHECK-NEXT: vfmindb %v24, %v24, %v0, 2
; CHECK-NEXT: br %r14
%cmp = fcmp olt <2 x double> %val, zeroinitializer
%ret = select <2 x i1> %cmp, <2 x double> %val, <2 x double> zeroinitializer
@@ -30,7 +30,7 @@ define <4 x float> @f3(<4 x float> %val) {
; CHECK-LABEL: f3:
; CHECK: # %bb.0:
; CHECK-NEXT: vgbm %v0, 0
-; CHECK-NEXT: vfmaxsb %v24, %v24, %v0, 4
+; CHECK-NEXT: vfmaxsb %v24, %v24, %v0, 2
; CHECK-NEXT: br %r14
%cmp = fcmp ogt <4 x float> %val, zeroinitializer
%ret = select <4 x i1> %cmp, <4 x float> %val, <4 x float> zeroinitializer
@@ -41,7 +41,7 @@ define <4 x float> @f4(<4 x float> %val) {
; CHECK-LABEL: f4:
; CHECK: # %bb.0:
; CHECK-NEXT: vgbm %v0, 0
-; CHECK-NEXT: vfminsb %v24, %v24, %v0, 4
+; CHECK-NEXT: vfminsb %v24, %v24, %v0, 2
; CHECK-NEXT: br %r14
%cmp = fcmp olt <4 x float> %val, zeroinitializer
%ret = select <4 x i1> %cmp, <4 x float> %val, <4 x float> zeroinitializer
diff --git a/llvm/test/CodeGen/SystemZ/vec-min-05.ll b/llvm/test/CodeGen/SystemZ/vec-min-05.ll
index dca5fcd60e0ce..a1eb199c0c1c2 100644
--- a/llvm/test/CodeGen/SystemZ/vec-min-05.ll
+++ b/llvm/test/CodeGen/SystemZ/vec-min-05.ll
@@ -61,7 +61,7 @@ define double @f4(double %dummy, double %val) {
; CHECK-LABEL: f4:
; CHECK: # %bb.0:
; CHECK-NEXT: lzdr %f0
-; CHECK-NEXT: wfmindb %f0, %f2, %f0, 4
+; CHECK-NEXT: wfmindb %f0, %f2, %f0, 2
; CHECK-NEXT: br %r14
%cmp = fcmp olt double %val, 0.0
%ret = select i1 %cmp, double %val, double 0.0
@@ -172,7 +172,7 @@ define float @f14(float %dummy, float %val) {
; CHECK-LABEL: f14:
; CHECK: # %bb.0:
; CHECK-NEXT: lzer %f0
-; CHECK-NEXT: wfminsb %f0, %f2, %f0, 4
+; CHECK-NEXT: wfminsb %f0, %f2, %f0, 2
; CHECK-NEXT: br %r14
%cmp = fcmp olt float %val, 0.0
%ret = select i1 %cmp, float %val, float 0.0
@@ -280,7 +280,7 @@ define void @f24(ptr %ptr, ptr %dst) {
; CHECK: # %bb.0:
; CHECK-NEXT: vl %v0, 0(%r2), 3
; CHECK-NEXT: vzero %v1
-; CHECK-NEXT: wfminxb %v0, %v0, %v1, 4
+; CHECK-NEXT: wfminxb %v0, %v0, %v1, 2
; CHECK-NEXT: vst %v0, 0(%r3), 3
; CHECK-NEXT: br %r14
%val = load fp128, ptr %ptr
More information about the llvm-commits
mailing list