[llvm] [DAG] - computeKnownFPClass - ISD::FMAXIMUM/ISD::FMINIMUM + ISD::FMAXIMUMNUM/ISD::FMINIMUMNUM (PR #190465)
Kartik Ohlan via llvm-commits
llvm-commits at lists.llvm.org
Sat Apr 18 20:58:02 PDT 2026
https://github.com/Ko496-glitch updated https://github.com/llvm/llvm-project/pull/190465
>From e21ace3e12b12a9a56ee8a24eb5ff33164c3fcd7 Mon Sep 17 00:00:00 2001
From: kartikohlan <kartik7ohlan at gmail.com>
Date: Sat, 4 Apr 2026 11:22:01 -0400
Subject: [PATCH 1/4] Added (early out and exit and enum style block
---
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 40 +++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 137922aa62557..6f4540a81f237 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6106,6 +6106,46 @@ KnownFPClass SelectionDAG::computeKnownFPClass(SDValue Op,
Known.fabs();
break;
}
+ case ISD::FMAXNUM:
+ case ISD::FMINNUM:
+ case ISD::FMAXIMUM:
+ case ISD::FMINIMUM:
+ case ISD::FMAXIMUMNUM:
+ case ISD::FMINIMUMNUM: {
+ KnownFPClass KnownRHS = computeKnownFPClass(Op.getOperand(1), DemandedElts,
+ InterestedClasses, Depth + 1);
+ if (KnownRHS.isUnknown()) {
+ break;
+ }
+ KnownFPClass KnownLHS = computeKnownFPClass(Op.getOperand(0), DemandedElts,
+ InterestedClasses, Depth + 1);
+ KnownFPClass::MinMaxKind Kind;
+ switch (Opcode) {
+ case ISD::FMAXNUM:
+ Kind = KnownFPClass::MinMaxKind::maxnum;
+ break;
+ case ISD::FMINNUM:
+ Kind = KnownFPClass::MinMaxKind::minnum;
+ break;
+ case ISD::FMAXIMUM:
+ Kind = KnownFPClass::MinMaxKind::maximum;
+ break;
+ case ISD::FMINIMUM:
+ Kind = KnownFPClass::MinMaxKind::minimum;
+ break;
+ case ISD::FMAXIMUMNUM:
+ Kind = KnownFPClass::MinMaxKind::maximumnum;
+ break;
+ case ISD::FMINIMUMNUM:
+ Kind = KnownFPClass::MinMaxKind::minimumnum;
+ break;
+ default:
+ llvm_unreachable("Illegal FP min/max opcode");
+ }
+ DenormalMode Mode = getDenormalMode(VT);
+ Known = KnownFPClass::minMaxLike(KnownLHS, KnownRHS, Kind, Mode);
+ break;
+ }
default:
if (Opcode >= ISD::BUILTIN_OP_END || Opcode == ISD::INTRINSIC_WO_CHAIN ||
Opcode == ISD::INTRINSIC_W_CHAIN || Opcode == ISD::INTRINSIC_VOID) {
>From 0dc57d5c9c22717134e62a263e5dc9621747e0bf Mon Sep 17 00:00:00 2001
From: kartikohlan <kartik7ohlan at gmail.com>
Date: Sun, 5 Apr 2026 12:56:01 -0400
Subject: [PATCH 2/4] Refactor the block code and added the tests
---
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 25 ++-
...s-minimum-maximum-minimumnum-maximumnum.ll | 212 ++++++++++++++++++
2 files changed, 228 insertions(+), 9 deletions(-)
create mode 100644 llvm/test/Transforms/Attributor/nofpclass-minimum-maximum-minimumnum-maximumnum.ll
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 6f4540a81f237..e7523c0675a55 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6030,6 +6030,20 @@ KnownFPClass SelectionDAG::computeKnownFPClass(SDValue Op,
const APInt &DemandedElts,
FPClassTest InterestedClasses,
unsigned Depth) const {
+
+ auto GetMinMaxKnownFPClass = [&](SDValue LHS, SDValue RHS,
+ KnownFPClass::MinMaxKind Kind) {
+ KnownFPClass KnownRHS =
+ computeKnownFPClass(RHS, DemandedElts, InterestedClasses, Depth + 1);
+ if (KnownRHS.isUnknown())
+ return KnownRHS;
+ KnownFPClass KnownLHS =
+ computeKnownFPClass(LHS, DemandedElts, InterestedClasses, Depth + 1);
+
+ return KnownFPClass::minMaxLike(KnownLHS, KnownRHS, Kind,
+ getDenormalMode(Op.getValueType()));
+ };
+
KnownFPClass Known;
if (const auto *CFP = dyn_cast<ConstantFPSDNode>(Op))
@@ -6112,13 +6126,7 @@ KnownFPClass SelectionDAG::computeKnownFPClass(SDValue Op,
case ISD::FMINIMUM:
case ISD::FMAXIMUMNUM:
case ISD::FMINIMUMNUM: {
- KnownFPClass KnownRHS = computeKnownFPClass(Op.getOperand(1), DemandedElts,
- InterestedClasses, Depth + 1);
- if (KnownRHS.isUnknown()) {
- break;
- }
- KnownFPClass KnownLHS = computeKnownFPClass(Op.getOperand(0), DemandedElts,
- InterestedClasses, Depth + 1);
+
KnownFPClass::MinMaxKind Kind;
switch (Opcode) {
case ISD::FMAXNUM:
@@ -6142,8 +6150,7 @@ KnownFPClass SelectionDAG::computeKnownFPClass(SDValue Op,
default:
llvm_unreachable("Illegal FP min/max opcode");
}
- DenormalMode Mode = getDenormalMode(VT);
- Known = KnownFPClass::minMaxLike(KnownLHS, KnownRHS, Kind, Mode);
+ Known = GetMinMaxKnownFPClass(Op.getOperand(0), Op.getOperand(1), Kind);
break;
}
default:
diff --git a/llvm/test/Transforms/Attributor/nofpclass-minimum-maximum-minimumnum-maximumnum.ll b/llvm/test/Transforms/Attributor/nofpclass-minimum-maximum-minimumnum-maximumnum.ll
new file mode 100644
index 0000000000000..0ce31464fe3d0
--- /dev/null
+++ b/llvm/test/Transforms/Attributor/nofpclass-minimum-maximum-minimumnum-maximumnum.ll
@@ -0,0 +1,212 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
+; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
+
+define float @ret_minimum(float %arg0, float %arg1) #0 {
+; CHECK-LABEL: define float @ret_minimum
+; CHECK-SAME: (float [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR1:[0-9]+]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR7:[0-9]+]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_minimum_noinf__noinf(float nofpclass(inf) %arg0, float nofpclass(inf) %arg1) #0 {
+; CHECK-LABEL: define float @ret_minimum_noinf__noinf
+; CHECK-SAME: (float nofpclass(inf) [[ARG0:%.*]], float nofpclass(inf) [[ARG1:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(inf) [[ARG0]], float nofpclass(inf) [[ARG1]]) #[[ATTR7]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_minimum_noinf__nonan(float nofpclass(inf) %arg0, float nofpclass(nan) %arg1) #0 {
+; CHECK-LABEL: define float @ret_minimum_noinf__nonan
+; CHECK-SAME: (float nofpclass(inf) [[ARG0:%.*]], float nofpclass(nan) [[ARG1:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(inf) [[ARG0]], float nofpclass(nan) [[ARG1]]) #[[ATTR7]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_minimum_nonan__noinf(float nofpclass(nan) %arg0, float nofpclass(inf) %arg1) #0 {
+; CHECK-LABEL: define float @ret_minimum_nonan__noinf
+; CHECK-SAME: (float nofpclass(nan) [[ARG0:%.*]], float nofpclass(inf) [[ARG1:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(nan) [[ARG0]], float nofpclass(inf) [[ARG1]]) #[[ATTR7]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_minimum_norm_zero__norm_sub(float nofpclass(norm zero) %arg0, float nofpclass(norm sub) %arg1) #0 {
+; CHECK-LABEL: define float @ret_minimum_norm_zero__norm_sub
+; CHECK-SAME: (float nofpclass(zero norm) [[ARG0:%.*]], float nofpclass(sub norm) [[ARG1:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(zero norm) [[ARG0]], float nofpclass(sub norm) [[ARG1]]) #[[ATTR7]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_minimum_daz_daz(float %arg0, float %arg1) #1 {
+; CHECK-LABEL: define float @ret_minimum_daz_daz
+; CHECK-SAME: (float [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR2:[0-9]+]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR7]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_minimum_dynamic_dynamic(float %arg0, float %arg1) #3 {
+; CHECK-LABEL: define float @ret_minimum_dynamic_dynamic
+; CHECK-SAME: (float [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR3:[0-9]+]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR7]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_minimum_noinf_nozero__noinf_nozero(float nofpclass(inf zero) %arg0, float nofpclass(inf zero) %arg1) #1 {
+; CHECK-LABEL: define float @ret_minimum_noinf_nozero__noinf_nozero
+; CHECK-SAME: (float nofpclass(inf zero) [[ARG0:%.*]], float nofpclass(inf zero) [[ARG1:%.*]]) #[[ATTR2]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(inf zero) [[ARG0]], float nofpclass(inf zero) [[ARG1]]) #[[ATTR7]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
+ ret float %call
+}
+
+define <2 x float> @ret_minimum_noinf_nozero__noinf_nozero_v2f32(<2 x float> nofpclass(inf zero) %arg0, <2 x float> nofpclass(inf zero) %arg1) #1 {
+; CHECK-LABEL: define <2 x float> @ret_minimum_noinf_nozero__noinf_nozero_v2f32
+; CHECK-SAME: (<2 x float> nofpclass(inf zero) [[ARG0:%.*]], <2 x float> nofpclass(inf zero) [[ARG1:%.*]]) #[[ATTR2]] {
+; CHECK-NEXT: [[CALL:%.*]] = call <2 x float> @llvm.minimum.v2f32(<2 x float> nofpclass(inf zero) [[ARG0]], <2 x float> nofpclass(inf zero) [[ARG1]]) #[[ATTR7]]
+; CHECK-NEXT: ret <2 x float> [[CALL]]
+;
+ %call = call <2 x float> @llvm.minimum.v2f32(<2 x float> %arg0, <2 x float> %arg1)
+ ret <2 x float> %call
+}
+
+define float @ret_minimum_daz_daz_nozero__nozero(float nofpclass(zero) %arg0, float nofpclass(zero) %arg1) #1 {
+; CHECK-LABEL: define float @ret_minimum_daz_daz_nozero__nozero
+; CHECK-SAME: (float nofpclass(zero) [[ARG0:%.*]], float nofpclass(zero) [[ARG1:%.*]]) #[[ATTR2]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(zero) [[ARG0]], float nofpclass(zero) [[ARG1]]) #[[ATTR7]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_minimum_daz_daz_nozero_nosub__nozero_nosub(float nofpclass(zero sub) %arg0, float nofpclass(zero sub) %arg1) #1 {
+; CHECK-LABEL: define float @ret_minimum_daz_daz_nozero_nosub__nozero_nosub
+; CHECK-SAME: (float nofpclass(zero sub) [[ARG0:%.*]], float nofpclass(zero sub) [[ARG1:%.*]]) #[[ATTR2]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(zero sub) [[ARG0]], float nofpclass(zero sub) [[ARG1]]) #[[ATTR7]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_minimum_dynamic_dynamic_nozero__nozero(float nofpclass(zero) %arg0, float nofpclass(zero) %arg1) #3 {
+; CHECK-LABEL: define float @ret_minimum_dynamic_dynamic_nozero__nozero
+; CHECK-SAME: (float nofpclass(zero) [[ARG0:%.*]], float nofpclass(zero) [[ARG1:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(zero) [[ARG0]], float nofpclass(zero) [[ARG1]]) #[[ATTR7]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_minimum_dynamic_dynamic_nozero_nosub__nozero_nosub(float nofpclass(zero sub) %arg0, float nofpclass(zero sub) %arg1) #3 {
+; CHECK-LABEL: define float @ret_minimum_dynamic_dynamic_nozero_nosub__nozero_nosub
+; CHECK-SAME: (float nofpclass(zero sub) [[ARG0:%.*]], float nofpclass(zero sub) [[ARG1:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(zero sub) [[ARG0]], float nofpclass(zero sub) [[ARG1]]) #[[ATTR7]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_minimum_dapz_dapz_nozero__nozero(float nofpclass(zero) %arg0, float nofpclass(zero) %arg1) #2 {
+; CHECK-LABEL: define float @ret_minimum_dapz_dapz_nozero__nozero
+; CHECK-SAME: (float nofpclass(zero) [[ARG0:%.*]], float nofpclass(zero) [[ARG1:%.*]]) #[[ATTR4:[0-9]+]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(zero) [[ARG0]], float nofpclass(zero) [[ARG1]]) #[[ATTR7]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_minimum_dapz_dapz_nopzero_nopsub__nopzero_nopsub(float nofpclass(pzero psub) %arg0, float nofpclass(pzero psub) %arg1) #2 {
+; CHECK-LABEL: define float @ret_minimum_dapz_dapz_nopzero_nopsub__nopzero_nopsub
+; CHECK-SAME: (float nofpclass(pzero psub) [[ARG0:%.*]], float nofpclass(pzero psub) [[ARG1:%.*]]) #[[ATTR4]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(pzero psub) [[ARG0]], float nofpclass(pzero psub) [[ARG1]]) #[[ATTR7]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_minimum_ieee_daz_nozero__nozero(float nofpclass(zero) %arg0, float nofpclass(zero) %arg1) #4 {
+; CHECK-LABEL: define float @ret_minimum_ieee_daz_nozero__nozero
+; CHECK-SAME: (float nofpclass(zero) [[ARG0:%.*]], float nofpclass(zero) [[ARG1:%.*]]) #[[ATTR5:[0-9]+]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(zero) [[ARG0]], float nofpclass(zero) [[ARG1]]) #[[ATTR7]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_minimum_daz_ieee_nozero__nozero(float nofpclass(zero) %arg0, float nofpclass(zero) %arg1) #5 {
+; CHECK-LABEL: define float @ret_minimum_daz_ieee_nozero__nozero
+; CHECK-SAME: (float nofpclass(zero) [[ARG0:%.*]], float nofpclass(zero) [[ARG1:%.*]]) #[[ATTR6:[0-9]+]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(zero) [[ARG0]], float nofpclass(zero) [[ARG1]]) #[[ATTR7]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_minimum_noneg_nan__any(float nofpclass(ninf nsub nnorm nan) %arg0, float %arg1) #3 {
+; CHECK-LABEL: define float @ret_minimum_noneg_nan__any
+; CHECK-SAME: (float nofpclass(nan ninf nsub nnorm) [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(nan ninf nsub nnorm) [[ARG0]], float [[ARG1]]) #[[ATTR7]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_minimum_any__noneg_nan(float %arg0, float nofpclass(ninf nsub nnorm nan) %arg1) #3 {
+; CHECK-LABEL: define float @ret_minimum_any__noneg_nan
+; CHECK-SAME: (float [[ARG0:%.*]], float nofpclass(nan ninf nsub nnorm) [[ARG1:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float [[ARG0]], float nofpclass(nan ninf nsub nnorm) [[ARG1]]) #[[ATTR7]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_minimum_nopos_nan__any(float nofpclass(pinf psub pnorm nan) %arg0, float %arg1) #3 {
+; CHECK-LABEL: define float @ret_minimum_nopos_nan__any
+; CHECK-SAME: (float nofpclass(nan pinf psub pnorm) [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(nan pinf psub pnorm) [[ARG0]], float [[ARG1]]) #[[ATTR7]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_minimum_any__nopos_nan(float %arg0, float nofpclass(pinf psub pnorm nan) %arg1) #3 {
+; CHECK-LABEL: define float @ret_minimum_any__nopos_nan
+; CHECK-SAME: (float [[ARG0:%.*]], float nofpclass(nan pinf psub pnorm) [[ARG1:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float [[ARG0]], float nofpclass(nan pinf psub pnorm) [[ARG1]]) #[[ATTR7]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
+ ret float %call
+}
>From 02f98ab8ea429f73e9af31437dfe2dfa2b758076 Mon Sep 17 00:00:00 2001
From: kartikohlan <kartik7ohlan at gmail.com>
Date: Wed, 8 Apr 2026 00:24:08 -0400
Subject: [PATCH 3/4] Refactored the code and inverted the handling for switch
opcodes
---
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 46 +++++++++----------
1 file changed, 21 insertions(+), 25 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index e7523c0675a55..7f5a636ec1b1e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6026,6 +6026,25 @@ KnownFPClass SelectionDAG::computeKnownFPClass(SDValue Op,
return computeKnownFPClass(Op, DemandedElts, InterestedClasses, Depth);
}
+static KnownFPClass::MinMaxKind getMinMaxKindForFPOpcode(unsigned Opcode) {
+ switch (Opcode) {
+ case ISD::FMAXNUM:
+ return KnownFPClass::MinMaxKind::maxnum;
+ case ISD::FMINNUM:
+ return KnownFPClass::MinMaxKind::minnum;
+ case ISD::FMAXIMUM:
+ return KnownFPClass::MinMaxKind::maximum;
+ case ISD::FMINIMUM:
+ return KnownFPClass::MinMaxKind::minimum;
+ case ISD::FMAXIMUMNUM:
+ return KnownFPClass::MinMaxKind::maximumnum;
+ case ISD::FMINIMUMNUM:
+ return KnownFPClass::MinMaxKind::minimumnum;
+ default:
+ llvm_unreachable("Illegal FP min/max opcode");
+ }
+}
+
KnownFPClass SelectionDAG::computeKnownFPClass(SDValue Op,
const APInt &DemandedElts,
FPClassTest InterestedClasses,
@@ -6126,31 +6145,8 @@ KnownFPClass SelectionDAG::computeKnownFPClass(SDValue Op,
case ISD::FMINIMUM:
case ISD::FMAXIMUMNUM:
case ISD::FMINIMUMNUM: {
-
- KnownFPClass::MinMaxKind Kind;
- switch (Opcode) {
- case ISD::FMAXNUM:
- Kind = KnownFPClass::MinMaxKind::maxnum;
- break;
- case ISD::FMINNUM:
- Kind = KnownFPClass::MinMaxKind::minnum;
- break;
- case ISD::FMAXIMUM:
- Kind = KnownFPClass::MinMaxKind::maximum;
- break;
- case ISD::FMINIMUM:
- Kind = KnownFPClass::MinMaxKind::minimum;
- break;
- case ISD::FMAXIMUMNUM:
- Kind = KnownFPClass::MinMaxKind::maximumnum;
- break;
- case ISD::FMINIMUMNUM:
- Kind = KnownFPClass::MinMaxKind::minimumnum;
- break;
- default:
- llvm_unreachable("Illegal FP min/max opcode");
- }
- Known = GetMinMaxKnownFPClass(Op.getOperand(0), Op.getOperand(1), Kind);
+ Known = GetMinMaxKnownFPClass(Op.getOperand(0), Op.getOperand(1),
+ getMinMaxKindForFPOpcode(Opcode));
break;
}
default:
>From 61e3ddaa78dda74f35cd9aeeb6fd06321c69c9a0 Mon Sep 17 00:00:00 2001
From: Kartik Ohlan <kartik7ohlan at gmail.com>
Date: Sat, 18 Apr 2026 23:21:53 -0400
Subject: [PATCH 4/4] Fixed some format space
---
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 66 +++---
.../AMDGPU/fminimum-fmaximum-nofpclass.ll | 172 ++++++++++++++
...s-minimum-maximum-minimumnum-maximumnum.ll | 212 ------------------
3 files changed, 202 insertions(+), 248 deletions(-)
create mode 100644 llvm/test/CodeGen/AMDGPU/fminimum-fmaximum-nofpclass.ll
delete mode 100644 llvm/test/Transforms/Attributor/nofpclass-minimum-maximum-minimumnum-maximumnum.ll
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 7f5a636ec1b1e..f1ace017b70b8 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6026,43 +6026,10 @@ KnownFPClass SelectionDAG::computeKnownFPClass(SDValue Op,
return computeKnownFPClass(Op, DemandedElts, InterestedClasses, Depth);
}
-static KnownFPClass::MinMaxKind getMinMaxKindForFPOpcode(unsigned Opcode) {
- switch (Opcode) {
- case ISD::FMAXNUM:
- return KnownFPClass::MinMaxKind::maxnum;
- case ISD::FMINNUM:
- return KnownFPClass::MinMaxKind::minnum;
- case ISD::FMAXIMUM:
- return KnownFPClass::MinMaxKind::maximum;
- case ISD::FMINIMUM:
- return KnownFPClass::MinMaxKind::minimum;
- case ISD::FMAXIMUMNUM:
- return KnownFPClass::MinMaxKind::maximumnum;
- case ISD::FMINIMUMNUM:
- return KnownFPClass::MinMaxKind::minimumnum;
- default:
- llvm_unreachable("Illegal FP min/max opcode");
- }
-}
-
KnownFPClass SelectionDAG::computeKnownFPClass(SDValue Op,
const APInt &DemandedElts,
FPClassTest InterestedClasses,
- unsigned Depth) const {
-
- auto GetMinMaxKnownFPClass = [&](SDValue LHS, SDValue RHS,
- KnownFPClass::MinMaxKind Kind) {
- KnownFPClass KnownRHS =
- computeKnownFPClass(RHS, DemandedElts, InterestedClasses, Depth + 1);
- if (KnownRHS.isUnknown())
- return KnownRHS;
- KnownFPClass KnownLHS =
- computeKnownFPClass(LHS, DemandedElts, InterestedClasses, Depth + 1);
-
- return KnownFPClass::minMaxLike(KnownLHS, KnownRHS, Kind,
- getDenormalMode(Op.getValueType()));
- };
-
+ unsigned Depth) const {
KnownFPClass Known;
if (const auto *CFP = dyn_cast<ConstantFPSDNode>(Op))
@@ -6145,8 +6112,35 @@ KnownFPClass SelectionDAG::computeKnownFPClass(SDValue Op,
case ISD::FMINIMUM:
case ISD::FMAXIMUMNUM:
case ISD::FMINIMUMNUM: {
- Known = GetMinMaxKnownFPClass(Op.getOperand(0), Op.getOperand(1),
- getMinMaxKindForFPOpcode(Opcode));
+ KnownFPClass KnownRHS = computeKnownFPClass(Op.getOperand(1), DemandedElts,
+ InterestedClasses, Depth + 1);
+ if (KnownRHS.isUnknown())
+ break;
+ KnownFPClass KnownLHS = computeKnownFPClass(Op.getOperand(0), DemandedElts,
+ InterestedClasses, Depth + 1);
+ KnownFPClass::MinMaxKind Kind;
+ switch (Opcode) {
+ case ISD::FMAXNUM:
+ Kind = KnownFPClass::MinMaxKind::maxnum;
+ break;
+ case ISD::FMINNUM:
+ Kind = KnownFPClass::MinMaxKind::minnum;
+ break;
+ case ISD::FMAXIMUM:
+ Kind = KnownFPClass::MinMaxKind::maximum;
+ break;
+ case ISD::FMINIMUM:
+ Kind = KnownFPClass::MinMaxKind::minimum;
+ break;
+ case ISD::FMAXIMUMNUM:
+ Kind = KnownFPClass::MinMaxKind::maximumnum;
+ break;
+ default:
+ Kind = KnownFPClass::MinMaxKind::minimumnum;
+ break;
+ }
+ Known = KnownFPClass::minMaxLike(KnownLHS, KnownRHS, Kind,
+ getDenormalMode(Op.getValueType()));
break;
}
default:
diff --git a/llvm/test/CodeGen/AMDGPU/fminimum-fmaximum-nofpclass.ll b/llvm/test/CodeGen/AMDGPU/fminimum-fmaximum-nofpclass.ll
new file mode 100644
index 0000000000000..5f8765b9512f7
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/fminimum-fmaximum-nofpclass.ll
@@ -0,0 +1,172 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=fiji -global-isel=0 < %s | FileCheck %s --check-prefixes=GCN,GFX8
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -global-isel=0 < %s | FileCheck %s --check-prefixes=GCN,GFX9
+
+
+define float @v_test_known_not_snan_maxnum_input_fmed3_r_i_i_f32(float %a, float %b) #0 {
+; GCN-LABEL: v_test_known_not_snan_maxnum_input_fmed3_r_i_i_f32:
+; GCN: ; %bb.0:
+; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT: v_rcp_f32_e32 v0, v0
+; GCN-NEXT: v_add_f32_e32 v1, 1.0, v1
+; GCN-NEXT: v_max_f32_e32 v0, v0, v1
+; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
+; GCN-NEXT: s_setpc_b64 s[30:31]
+ %a.nnan.add = fdiv nnan float 1.0, %a, !fpmath !0
+ %b.nnan.add = fadd nnan float %b, 1.0
+ %known.not.snan = call float @llvm.maxnum.f32(float %a.nnan.add, float %b.nnan.add)
+ %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
+ %med = call float @llvm.minnum.f32(float %max, float 4.0)
+ ret float %med
+}
+
+define float @v_maxnum_possible_nan_lhs_input_fmed3_r_i_i_f32(float %a, float %b) #0 {
+; GFX8-LABEL: v_maxnum_possible_nan_lhs_input_fmed3_r_i_i_f32:
+; GFX8: ; %bb.0:
+; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8-NEXT: v_add_f32_e32 v1, 1.0, v1
+; GFX8-NEXT: v_mul_f32_e32 v0, 1.0, v0
+; GFX8-NEXT: v_max_f32_e32 v0, v0, v1
+; GFX8-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
+; GFX8-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: v_maxnum_possible_nan_lhs_input_fmed3_r_i_i_f32:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT: v_add_f32_e32 v1, 1.0, v1
+; GFX9-NEXT: v_max_f32_e32 v0, v0, v0
+; GFX9-NEXT: v_max_f32_e32 v0, v0, v1
+; GFX9-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
+; GFX9-NEXT: s_setpc_b64 s[30:31]
+ %b.nnan.add = fadd nnan float %b, 1.0
+ %known.not.snan = call float @llvm.maxnum.f32(float %a, float %b.nnan.add)
+ %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
+ %med = call float @llvm.minnum.f32(float %max, float 4.0)
+ ret float %med
+}
+
+define float @v_maxnum_possible_nan_rhs_input_fmed3_r_i_i_f32(float %a, float %b) #0 {
+; GFX8-LABEL: v_maxnum_possible_nan_rhs_input_fmed3_r_i_i_f32:
+; GFX8: ; %bb.0:
+; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8-NEXT: v_rcp_f32_e32 v0, v0
+; GFX8-NEXT: v_mul_f32_e32 v1, 1.0, v1
+; GFX8-NEXT: v_max_f32_e32 v0, v0, v1
+; GFX8-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
+; GFX8-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: v_maxnum_possible_nan_rhs_input_fmed3_r_i_i_f32:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT: v_rcp_f32_e32 v0, v0
+; GFX9-NEXT: v_max_f32_e32 v1, v1, v1
+; GFX9-NEXT: v_max_f32_e32 v0, v0, v1
+; GFX9-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
+; GFX9-NEXT: s_setpc_b64 s[30:31]
+ %a.nnan.add = fdiv nnan float 1.0, %a, !fpmath !0
+ %known.not.snan = call float @llvm.maxnum.f32(float %a.nnan.add, float %b)
+ %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
+ %med = call float @llvm.minnum.f32(float %max, float 4.0)
+ ret float %med
+}
+
+define amdgpu_kernel void @v_nnan_inputs_med3_f32_pat0(ptr addrspace(1) %out, ptr addrspace(1) %aptr, ptr addrspace(1) %bptr, ptr addrspace(1) %cptr) {
+; GFX8-LABEL: v_nnan_inputs_med3_f32_pat0:
+; GFX8: ; %bb.0:
+; GFX8-NEXT: s_load_dwordx8 s[0:7], s[8:9], 0x0
+; GFX8-NEXT: v_lshlrev_b32_e32 v6, 2, v0
+; GFX8-NEXT: s_add_i32 s12, s12, s17
+; GFX8-NEXT: s_mov_b32 flat_scratch_lo, s13
+; GFX8-NEXT: s_lshr_b32 flat_scratch_hi, s12, 8
+; GFX8-NEXT: s_waitcnt lgkmcnt(0)
+; GFX8-NEXT: v_mov_b32_e32 v1, s3
+; GFX8-NEXT: v_add_u32_e32 v0, vcc, s2, v6
+; GFX8-NEXT: v_addc_u32_e32 v1, vcc, 0, v1, vcc
+; GFX8-NEXT: v_mov_b32_e32 v3, s5
+; GFX8-NEXT: v_add_u32_e32 v2, vcc, s4, v6
+; GFX8-NEXT: v_addc_u32_e32 v3, vcc, 0, v3, vcc
+; GFX8-NEXT: v_mov_b32_e32 v5, s7
+; GFX8-NEXT: v_add_u32_e32 v4, vcc, s6, v6
+; GFX8-NEXT: v_addc_u32_e32 v5, vcc, 0, v5, vcc
+; GFX8-NEXT: flat_load_dword v7, v[0:1] glc
+; GFX8-NEXT: s_waitcnt vmcnt(0)
+; GFX8-NEXT: flat_load_dword v2, v[2:3] glc
+; GFX8-NEXT: s_waitcnt vmcnt(0)
+; GFX8-NEXT: flat_load_dword v3, v[4:5] glc
+; GFX8-NEXT: s_waitcnt vmcnt(0)
+; GFX8-NEXT: v_mov_b32_e32 v1, s1
+; GFX8-NEXT: v_add_u32_e32 v0, vcc, s0, v6
+; GFX8-NEXT: v_addc_u32_e32 v1, vcc, 0, v1, vcc
+; GFX8-NEXT: v_add_f32_e32 v4, 1.0, v7
+; GFX8-NEXT: v_add_f32_e32 v2, 2.0, v2
+; GFX8-NEXT: v_add_f32_e32 v3, 4.0, v3
+; GFX8-NEXT: v_med3_f32 v2, v4, v2, v3
+; GFX8-NEXT: flat_store_dword v[0:1], v2
+; GFX8-NEXT: s_endpgm
+;
+; GFX9-LABEL: v_nnan_inputs_med3_f32_pat0:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_load_dwordx8 s[0:7], s[8:9], 0x0
+; GFX9-NEXT: v_lshlrev_b32_e32 v0, 2, v0
+; GFX9-NEXT: s_waitcnt lgkmcnt(0)
+; GFX9-NEXT: global_load_dword v1, v0, s[2:3] glc
+; GFX9-NEXT: s_waitcnt vmcnt(0)
+; GFX9-NEXT: global_load_dword v2, v0, s[4:5] glc
+; GFX9-NEXT: s_waitcnt vmcnt(0)
+; GFX9-NEXT: global_load_dword v3, v0, s[6:7] glc
+; GFX9-NEXT: s_waitcnt vmcnt(0)
+; GFX9-NEXT: v_add_f32_e32 v1, 1.0, v1
+; GFX9-NEXT: v_add_f32_e32 v2, 2.0, v2
+; GFX9-NEXT: v_add_f32_e32 v3, 4.0, v3
+; GFX9-NEXT: v_med3_f32 v1, v1, v2, v3
+; GFX9-NEXT: global_store_dword v0, v1, s[0:1]
+; GFX9-NEXT: s_endpgm
+ %tid = call i32 @llvm.amdgcn.workitem.id.x()
+ %gep0 = getelementptr float, ptr addrspace(1) %aptr, i32 %tid
+ %gep1 = getelementptr float, ptr addrspace(1) %bptr, i32 %tid
+ %gep2 = getelementptr float, ptr addrspace(1) %cptr, i32 %tid
+ %outgep = getelementptr float, ptr addrspace(1) %out, i32 %tid
+ %a = load volatile float, ptr addrspace(1) %gep0
+ %b = load volatile float, ptr addrspace(1) %gep1
+ %c = load volatile float, ptr addrspace(1) %gep2
+
+ %a.nnan = fadd nnan float %a, 1.0
+ %b.nnan = fadd nnan float %b, 2.0
+ %c.nnan = fadd nnan float %c, 4.0
+
+ %tmp0 = call float @llvm.minnum.f32(float %a.nnan, float %b.nnan)
+ %tmp1 = call float @llvm.maxnum.f32(float %a.nnan, float %b.nnan)
+ %tmp2 = call float @llvm.minnum.f32(float %tmp1, float %c.nnan)
+ %med3 = call float @llvm.maxnum.f32(float %tmp0, float %tmp2)
+ store float %med3, ptr addrspace(1) %outgep
+ ret void
+}
+
+
+
+define float @v_test_nnan_input_fmed3_r_i_i_f32_maximum_minimum(float %a) {
+; GCN-LABEL: v_test_nnan_input_fmed3_r_i_i_f32_maximum_minimum:
+; GCN: ; %bb.0:
+; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT: v_add_f32_e32 v0, 1.0, v0
+; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
+; GCN-NEXT: s_setpc_b64 s[30:31]
+ %a.add = fadd nnan float %a, 1.0
+ %max = call float @llvm.maximum.f32(float %a.add, float 2.0)
+ %med = call float @llvm.minimum.f32(float %max, float 4.0)
+ ret float %med
+}
+
+declare float @llvm.maxnum.f32(float, float) #1
+declare float @llvm.minnum.f32(float, float) #1
+declare float @llvm.maximum.f32(float, float) #1
+declare float @llvm.minimum.f32(float, float) #1
+declare i32 @llvm.amdgcn.workitem.id.x() #1
+
+attributes #0 = { nounwind denormal_fpenv(float: preservesign) }
+attributes #1 = { nounwind readnone speculatable }
+
+!0 = !{float 2.500000e+00}
+
+
+
diff --git a/llvm/test/Transforms/Attributor/nofpclass-minimum-maximum-minimumnum-maximumnum.ll b/llvm/test/Transforms/Attributor/nofpclass-minimum-maximum-minimumnum-maximumnum.ll
deleted file mode 100644
index 0ce31464fe3d0..0000000000000
--- a/llvm/test/Transforms/Attributor/nofpclass-minimum-maximum-minimumnum-maximumnum.ll
+++ /dev/null
@@ -1,212 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
-; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
-
-define float @ret_minimum(float %arg0, float %arg1) #0 {
-; CHECK-LABEL: define float @ret_minimum
-; CHECK-SAME: (float [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR1:[0-9]+]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR7:[0-9]+]]
-; CHECK-NEXT: ret float [[CALL]]
-;
- %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
- ret float %call
-}
-
-define float @ret_minimum_noinf__noinf(float nofpclass(inf) %arg0, float nofpclass(inf) %arg1) #0 {
-; CHECK-LABEL: define float @ret_minimum_noinf__noinf
-; CHECK-SAME: (float nofpclass(inf) [[ARG0:%.*]], float nofpclass(inf) [[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(inf) [[ARG0]], float nofpclass(inf) [[ARG1]]) #[[ATTR7]]
-; CHECK-NEXT: ret float [[CALL]]
-;
- %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
- ret float %call
-}
-
-define float @ret_minimum_noinf__nonan(float nofpclass(inf) %arg0, float nofpclass(nan) %arg1) #0 {
-; CHECK-LABEL: define float @ret_minimum_noinf__nonan
-; CHECK-SAME: (float nofpclass(inf) [[ARG0:%.*]], float nofpclass(nan) [[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(inf) [[ARG0]], float nofpclass(nan) [[ARG1]]) #[[ATTR7]]
-; CHECK-NEXT: ret float [[CALL]]
-;
- %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
- ret float %call
-}
-
-define float @ret_minimum_nonan__noinf(float nofpclass(nan) %arg0, float nofpclass(inf) %arg1) #0 {
-; CHECK-LABEL: define float @ret_minimum_nonan__noinf
-; CHECK-SAME: (float nofpclass(nan) [[ARG0:%.*]], float nofpclass(inf) [[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(nan) [[ARG0]], float nofpclass(inf) [[ARG1]]) #[[ATTR7]]
-; CHECK-NEXT: ret float [[CALL]]
-;
- %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
- ret float %call
-}
-
-define float @ret_minimum_norm_zero__norm_sub(float nofpclass(norm zero) %arg0, float nofpclass(norm sub) %arg1) #0 {
-; CHECK-LABEL: define float @ret_minimum_norm_zero__norm_sub
-; CHECK-SAME: (float nofpclass(zero norm) [[ARG0:%.*]], float nofpclass(sub norm) [[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(zero norm) [[ARG0]], float nofpclass(sub norm) [[ARG1]]) #[[ATTR7]]
-; CHECK-NEXT: ret float [[CALL]]
-;
- %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
- ret float %call
-}
-
-define float @ret_minimum_daz_daz(float %arg0, float %arg1) #1 {
-; CHECK-LABEL: define float @ret_minimum_daz_daz
-; CHECK-SAME: (float [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR2:[0-9]+]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR7]]
-; CHECK-NEXT: ret float [[CALL]]
-;
- %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
- ret float %call
-}
-
-define float @ret_minimum_dynamic_dynamic(float %arg0, float %arg1) #3 {
-; CHECK-LABEL: define float @ret_minimum_dynamic_dynamic
-; CHECK-SAME: (float [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR3:[0-9]+]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float [[ARG0]], float [[ARG1]]) #[[ATTR7]]
-; CHECK-NEXT: ret float [[CALL]]
-;
- %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
- ret float %call
-}
-
-define float @ret_minimum_noinf_nozero__noinf_nozero(float nofpclass(inf zero) %arg0, float nofpclass(inf zero) %arg1) #1 {
-; CHECK-LABEL: define float @ret_minimum_noinf_nozero__noinf_nozero
-; CHECK-SAME: (float nofpclass(inf zero) [[ARG0:%.*]], float nofpclass(inf zero) [[ARG1:%.*]]) #[[ATTR2]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(inf zero) [[ARG0]], float nofpclass(inf zero) [[ARG1]]) #[[ATTR7]]
-; CHECK-NEXT: ret float [[CALL]]
-;
- %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
- ret float %call
-}
-
-define <2 x float> @ret_minimum_noinf_nozero__noinf_nozero_v2f32(<2 x float> nofpclass(inf zero) %arg0, <2 x float> nofpclass(inf zero) %arg1) #1 {
-; CHECK-LABEL: define <2 x float> @ret_minimum_noinf_nozero__noinf_nozero_v2f32
-; CHECK-SAME: (<2 x float> nofpclass(inf zero) [[ARG0:%.*]], <2 x float> nofpclass(inf zero) [[ARG1:%.*]]) #[[ATTR2]] {
-; CHECK-NEXT: [[CALL:%.*]] = call <2 x float> @llvm.minimum.v2f32(<2 x float> nofpclass(inf zero) [[ARG0]], <2 x float> nofpclass(inf zero) [[ARG1]]) #[[ATTR7]]
-; CHECK-NEXT: ret <2 x float> [[CALL]]
-;
- %call = call <2 x float> @llvm.minimum.v2f32(<2 x float> %arg0, <2 x float> %arg1)
- ret <2 x float> %call
-}
-
-define float @ret_minimum_daz_daz_nozero__nozero(float nofpclass(zero) %arg0, float nofpclass(zero) %arg1) #1 {
-; CHECK-LABEL: define float @ret_minimum_daz_daz_nozero__nozero
-; CHECK-SAME: (float nofpclass(zero) [[ARG0:%.*]], float nofpclass(zero) [[ARG1:%.*]]) #[[ATTR2]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(zero) [[ARG0]], float nofpclass(zero) [[ARG1]]) #[[ATTR7]]
-; CHECK-NEXT: ret float [[CALL]]
-;
- %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
- ret float %call
-}
-
-define float @ret_minimum_daz_daz_nozero_nosub__nozero_nosub(float nofpclass(zero sub) %arg0, float nofpclass(zero sub) %arg1) #1 {
-; CHECK-LABEL: define float @ret_minimum_daz_daz_nozero_nosub__nozero_nosub
-; CHECK-SAME: (float nofpclass(zero sub) [[ARG0:%.*]], float nofpclass(zero sub) [[ARG1:%.*]]) #[[ATTR2]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(zero sub) [[ARG0]], float nofpclass(zero sub) [[ARG1]]) #[[ATTR7]]
-; CHECK-NEXT: ret float [[CALL]]
-;
- %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
- ret float %call
-}
-
-define float @ret_minimum_dynamic_dynamic_nozero__nozero(float nofpclass(zero) %arg0, float nofpclass(zero) %arg1) #3 {
-; CHECK-LABEL: define float @ret_minimum_dynamic_dynamic_nozero__nozero
-; CHECK-SAME: (float nofpclass(zero) [[ARG0:%.*]], float nofpclass(zero) [[ARG1:%.*]]) #[[ATTR3]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(zero) [[ARG0]], float nofpclass(zero) [[ARG1]]) #[[ATTR7]]
-; CHECK-NEXT: ret float [[CALL]]
-;
- %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
- ret float %call
-}
-
-define float @ret_minimum_dynamic_dynamic_nozero_nosub__nozero_nosub(float nofpclass(zero sub) %arg0, float nofpclass(zero sub) %arg1) #3 {
-; CHECK-LABEL: define float @ret_minimum_dynamic_dynamic_nozero_nosub__nozero_nosub
-; CHECK-SAME: (float nofpclass(zero sub) [[ARG0:%.*]], float nofpclass(zero sub) [[ARG1:%.*]]) #[[ATTR3]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(zero sub) [[ARG0]], float nofpclass(zero sub) [[ARG1]]) #[[ATTR7]]
-; CHECK-NEXT: ret float [[CALL]]
-;
- %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
- ret float %call
-}
-
-define float @ret_minimum_dapz_dapz_nozero__nozero(float nofpclass(zero) %arg0, float nofpclass(zero) %arg1) #2 {
-; CHECK-LABEL: define float @ret_minimum_dapz_dapz_nozero__nozero
-; CHECK-SAME: (float nofpclass(zero) [[ARG0:%.*]], float nofpclass(zero) [[ARG1:%.*]]) #[[ATTR4:[0-9]+]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(zero) [[ARG0]], float nofpclass(zero) [[ARG1]]) #[[ATTR7]]
-; CHECK-NEXT: ret float [[CALL]]
-;
- %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
- ret float %call
-}
-
-define float @ret_minimum_dapz_dapz_nopzero_nopsub__nopzero_nopsub(float nofpclass(pzero psub) %arg0, float nofpclass(pzero psub) %arg1) #2 {
-; CHECK-LABEL: define float @ret_minimum_dapz_dapz_nopzero_nopsub__nopzero_nopsub
-; CHECK-SAME: (float nofpclass(pzero psub) [[ARG0:%.*]], float nofpclass(pzero psub) [[ARG1:%.*]]) #[[ATTR4]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(pzero psub) [[ARG0]], float nofpclass(pzero psub) [[ARG1]]) #[[ATTR7]]
-; CHECK-NEXT: ret float [[CALL]]
-;
- %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
- ret float %call
-}
-
-define float @ret_minimum_ieee_daz_nozero__nozero(float nofpclass(zero) %arg0, float nofpclass(zero) %arg1) #4 {
-; CHECK-LABEL: define float @ret_minimum_ieee_daz_nozero__nozero
-; CHECK-SAME: (float nofpclass(zero) [[ARG0:%.*]], float nofpclass(zero) [[ARG1:%.*]]) #[[ATTR5:[0-9]+]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(zero) [[ARG0]], float nofpclass(zero) [[ARG1]]) #[[ATTR7]]
-; CHECK-NEXT: ret float [[CALL]]
-;
- %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
- ret float %call
-}
-
-define float @ret_minimum_daz_ieee_nozero__nozero(float nofpclass(zero) %arg0, float nofpclass(zero) %arg1) #5 {
-; CHECK-LABEL: define float @ret_minimum_daz_ieee_nozero__nozero
-; CHECK-SAME: (float nofpclass(zero) [[ARG0:%.*]], float nofpclass(zero) [[ARG1:%.*]]) #[[ATTR6:[0-9]+]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(zero) [[ARG0]], float nofpclass(zero) [[ARG1]]) #[[ATTR7]]
-; CHECK-NEXT: ret float [[CALL]]
-;
- %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
- ret float %call
-}
-
-define float @ret_minimum_noneg_nan__any(float nofpclass(ninf nsub nnorm nan) %arg0, float %arg1) #3 {
-; CHECK-LABEL: define float @ret_minimum_noneg_nan__any
-; CHECK-SAME: (float nofpclass(nan ninf nsub nnorm) [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR3]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(nan ninf nsub nnorm) [[ARG0]], float [[ARG1]]) #[[ATTR7]]
-; CHECK-NEXT: ret float [[CALL]]
-;
- %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
- ret float %call
-}
-
-define float @ret_minimum_any__noneg_nan(float %arg0, float nofpclass(ninf nsub nnorm nan) %arg1) #3 {
-; CHECK-LABEL: define float @ret_minimum_any__noneg_nan
-; CHECK-SAME: (float [[ARG0:%.*]], float nofpclass(nan ninf nsub nnorm) [[ARG1:%.*]]) #[[ATTR3]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float [[ARG0]], float nofpclass(nan ninf nsub nnorm) [[ARG1]]) #[[ATTR7]]
-; CHECK-NEXT: ret float [[CALL]]
-;
- %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
- ret float %call
-}
-
-define float @ret_minimum_nopos_nan__any(float nofpclass(pinf psub pnorm nan) %arg0, float %arg1) #3 {
-; CHECK-LABEL: define float @ret_minimum_nopos_nan__any
-; CHECK-SAME: (float nofpclass(nan pinf psub pnorm) [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR3]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float nofpclass(nan pinf psub pnorm) [[ARG0]], float [[ARG1]]) #[[ATTR7]]
-; CHECK-NEXT: ret float [[CALL]]
-;
- %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
- ret float %call
-}
-
-define float @ret_minimum_any__nopos_nan(float %arg0, float nofpclass(pinf psub pnorm nan) %arg1) #3 {
-; CHECK-LABEL: define float @ret_minimum_any__nopos_nan
-; CHECK-SAME: (float [[ARG0:%.*]], float nofpclass(nan pinf psub pnorm) [[ARG1:%.*]]) #[[ATTR3]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.minimum.f32(float [[ARG0]], float nofpclass(nan pinf psub pnorm) [[ARG1]]) #[[ATTR7]]
-; CHECK-NEXT: ret float [[CALL]]
-;
- %call = call float @llvm.minimum.f32(float %arg0, float %arg1)
- ret float %call
-}
More information about the llvm-commits
mailing list