[llvm] [InstCombine] Enable factorizeMinMaxTree for floating-point values (PR #193195)
Thomas Fry via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 21 04:21:26 PDT 2026
https://github.com/thofry created https://github.com/llvm/llvm-project/pull/193195
This patch extends `factorizeMinMaxTree` to floating point types by introducing handling for fast math flags.
The test coverage was copied from the integer case with additional tests for the handling of fast math flags
## Proofs
Proof of base case (times out but runs in <5 mins locally): https://alive2.llvm.org/ce/z/vt-Kxf
FMF proofs timed out after 12 hours
Manual proof for the `nnan` fast math flag special handling:
Assume WLOG the optimisation is `m1(m2(a, b), m3(c, b)) -> m4(m2(a, b), c)`
- `minimum/maximum`
`m1` is marked `nnan`
=> results of `m2` and `m3 ` are not `NaN`
=> `a`, `b`, and `c` are not `NaN` as minimum and maximum return `NaN` when either argument is `NaN`
=> neither of the arguments to `m4` nor the result can be `NaN`
=> `m4` can be marked `nnan`
Therefore `m4` can safely copy `nnan` from `m1`
- `minnum/minimumnum/maxnum/maximumnum`
`m3` is marked `nnan`
=> `b` and `c` are not `NaN`
=> the result of `m2` is not `NaN` as it has at least one non-`NaN` argument
=> neither of the arguments to `m4` nor the result can be `NaN`
=> `m4` can be marked `nnan`
Therefore `m4` can safely copy `nnan` from `m3`
>From e9894a926480ca5f82d4d0af5ecfcb82a76ed8d0 Mon Sep 17 00:00:00 2001
From: Thomas Fry <thomas.fry at arm.com>
Date: Mon, 20 Apr 2026 13:09:54 +0200
Subject: [PATCH 1/2] Precommit tests
---
llvm/test/Transforms/InstCombine/maximum.ll | 125 +++++++++++++++-
.../test/Transforms/InstCombine/maximumnum.ll | 133 +++++++++++++++++-
llvm/test/Transforms/InstCombine/maxnum.ll | 125 +++++++++++++++-
llvm/test/Transforms/InstCombine/minimum.ll | 123 ++++++++++++++++
.../test/Transforms/InstCombine/minimumnum.ll | 132 +++++++++++++++++
llvm/test/Transforms/InstCombine/minnum.ll | 123 ++++++++++++++++
6 files changed, 758 insertions(+), 3 deletions(-)
diff --git a/llvm/test/Transforms/InstCombine/maximum.ll b/llvm/test/Transforms/InstCombine/maximum.ll
index c79449472235b..296a231c7b86a 100644
--- a/llvm/test/Transforms/InstCombine/maximum.ll
+++ b/llvm/test/Transforms/InstCombine/maximum.ll
@@ -8,6 +8,8 @@ declare <4 x float> @llvm.maximum.v4f32(<4 x float>, <4 x float>)
declare double @llvm.maximum.f64(double, double)
declare <2 x double> @llvm.maximum.v2f64(<2 x double>, <2 x double>)
+declare void @use(float)
+
define float @constant_fold_maximum_f32() {
; CHECK-LABEL: @constant_fold_maximum_f32(
; CHECK-NEXT: ret float 2.000000e+00
@@ -238,6 +240,128 @@ define float @maximum4(float %x, float %y, float %z, float %w) {
ret float %c
}
+define float @maximum_common_op(float %x, float %y, float %z) {
+; CHECK-LABEL: @maximum_common_op(
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Z:%.*]])
+; CHECK-NEXT: [[Y:%.*]] = call float @llvm.maximum.f32(float [[X]], float [[Z1:%.*]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximum.f32(float [[M2]], float [[Y]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maximum.f32(float %x, float %y)
+ %m2 = call float @llvm.maximum.f32(float %x, float %z)
+ %m3 = call float @llvm.maximum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @maximum_reuse_lhs(float %x, float %y, float %z) {
+; CHECK-LABEL: @maximum_reuse_lhs(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: call void @use(float [[M1]])
+; CHECK-NEXT: [[Z:%.*]] = call float @llvm.maximum.f32(float [[Z1:%.*]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximum.f32(float [[M1]], float [[Z]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maximum.f32(float %x, float %y)
+ call void @use(float %m1)
+ %m2 = call float @llvm.maximum.f32(float %z, float %x)
+ %m3 = call float @llvm.maximum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @maximum_reuse_rhs(float %x, float %y, float %z) {
+; CHECK-LABEL: @maximum_reuse_rhs(
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maximum.f32(float [[Z:%.*]], float [[X:%.*]])
+; CHECK-NEXT: [[Y:%.*]] = call float @llvm.maximum.f32(float [[Z1:%.*]], float [[X]])
+; CHECK-NEXT: call void @use(float [[Y]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximum.f32(float [[M2]], float [[Y]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maximum.f32(float %y, float %x)
+ %m2 = call float @llvm.maximum.f32(float %z, float %x)
+ call void @use(float %m2)
+ %m3 = call float @llvm.maximum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @maximum_reuse_lhs_nnan(float %x, float %y, float %z) {
+; CHECK-LABEL: @maximum_reuse_lhs_nnan(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: call void @use(float [[M1]])
+; CHECK-NEXT: [[Z:%.*]] = call float @llvm.maximum.f32(float [[Z1:%.*]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call nnan float @llvm.maximum.f32(float [[M1]], float [[Z]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maximum.f32(float %x, float %y)
+ call void @use(float %m1)
+ %m2 = call float @llvm.maximum.f32(float %z, float %x)
+ %m3 = call nnan float @llvm.maximum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @maximum_reuse_lhs_nnan_folded_only(float %x, float %y, float %z) {
+; CHECK-LABEL: @maximum_reuse_lhs_nnan_folded_only(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: call void @use(float [[M1]])
+; CHECK-NEXT: [[Z:%.*]] = call nnan float @llvm.maximum.f32(float [[Z1:%.*]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximum.f32(float [[M1]], float [[Z]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maximum.f32(float %x, float %y)
+ call void @use(float %m1)
+ %m2 = call nnan float @llvm.maximum.f32(float %z, float %x)
+ %m3 = call float @llvm.maximum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @maximum_reuse_lhs_fmf_intersection(float %x, float %y, float %z) {
+; CHECK-LABEL: @maximum_reuse_lhs_fmf_intersection(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: call void @use(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call ninf afn float @llvm.maximum.f32(float [[Z:%.*]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call ninf arcp float @llvm.maximum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maximum.f32(float %x, float %y)
+ call void @use(float %m1)
+ %m2 = call afn ninf float @llvm.maximum.f32(float %z, float %x)
+ %m3 = call arcp ninf float @llvm.maximum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+; Negative test - too many uses.
+
+define float @maximum_common_op_uses(float %x, float %y, float %z) {
+; CHECK-LABEL: @maximum_common_op_uses(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: call void @use(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maximum.f32(float [[X]], float [[Z:%.*]])
+; CHECK-NEXT: call void @use(float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maximum.f32(float %x, float %y)
+ call void @use(float %m1)
+ %m2 = call float @llvm.maximum.f32(float %x, float %z)
+ call void @use(float %m2)
+ %m3 = call float @llvm.maximum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+; Negative test - must have common operand.
+
+define float @maximum_no_common_op(float %x, float %y, float %z, float %w) {
+; CHECK-LABEL: @maximum_no_common_op(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maximum.f32(float [[W:%.*]], float [[Z:%.*]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maximum.f32(float %x, float %y)
+ %m2 = call float @llvm.maximum.f32(float %w, float %z)
+ %m3 = call float @llvm.maximum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
; PR37404 - https://bugs.llvm.org/show_bug.cgi?id=37404
define <2 x float> @neg_neg(<2 x float> %x, <2 x float> %y) {
@@ -293,7 +417,6 @@ define float @unary_neg_neg_vec_fmf(float %x, float %y) {
; 1 extra use of an intermediate value should still allow the fold,
; but 2 would require more instructions than we started with.
-declare void @use(float)
define float @neg_neg_extra_use_x(float %x, float %y) {
; CHECK-LABEL: @neg_neg_extra_use_x(
; CHECK-NEXT: [[NEGX:%.*]] = fneg float [[X:%.*]]
diff --git a/llvm/test/Transforms/InstCombine/maximumnum.ll b/llvm/test/Transforms/InstCombine/maximumnum.ll
index 0d20be9062e77..b405e2ea34360 100644
--- a/llvm/test/Transforms/InstCombine/maximumnum.ll
+++ b/llvm/test/Transforms/InstCombine/maximumnum.ll
@@ -1,6 +1,8 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+declare void @use(float)
+
define float @maximumnum_f32_1_maximumnum_val_p0(float %x) {
; CHECK-LABEL: define float @maximumnum_f32_1_maximumnum_val_p0(
; CHECK-SAME: float [[X:%.*]]) {
@@ -103,6 +105,136 @@ define float @maximumnum4(float %x, float %y, float %z, float %w) {
ret float %c
}
+define float @maximumnum_common_op(float %x, float %y, float %z) {
+; CHECK-LABEL: define float @maximumnum_common_op(
+; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximumnum.f32(float [[X]], float [[Y]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maximumnum.f32(float [[X]], float [[Z]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maximumnum.f32(float %x, float %y)
+ %m2 = call float @llvm.maximumnum.f32(float %x, float %z)
+ %m3 = call float @llvm.maximumnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @maximumnum_reuse_lhs(float %x, float %y, float %z) {
+; CHECK-LABEL: define float @maximumnum_reuse_lhs(
+; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximumnum.f32(float [[X]], float [[Y]])
+; CHECK-NEXT: call void @use(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maximumnum.f32(float [[Z]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maximumnum.f32(float %x, float %y)
+ call void @use(float %m1)
+ %m2 = call float @llvm.maximumnum.f32(float %z, float %x)
+ %m3 = call float @llvm.maximumnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @maximumnum_reuse_rhs(float %x, float %y, float %z) {
+; CHECK-LABEL: define float @maximumnum_reuse_rhs(
+; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximumnum.f32(float [[Y]], float [[X]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maximumnum.f32(float [[Z]], float [[X]])
+; CHECK-NEXT: call void @use(float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maximumnum.f32(float %y, float %x)
+ %m2 = call float @llvm.maximumnum.f32(float %z, float %x)
+ call void @use(float %m2)
+ %m3 = call float @llvm.maximumnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @maximumnum_reuse_lhs_nnan(float %x, float %y, float %z) {
+; CHECK-LABEL: define float @maximumnum_reuse_lhs_nnan(
+; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximumnum.f32(float [[X]], float [[Y]])
+; CHECK-NEXT: call void @use(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maximumnum.f32(float [[Z]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call nnan float @llvm.maximumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maximumnum.f32(float %x, float %y)
+ call void @use(float %m1)
+ %m2 = call float @llvm.maximumnum.f32(float %z, float %x)
+ %m3 = call nnan float @llvm.maximumnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @maximumnum_reuse_lhs_nnan_folded_only(float %x, float %y, float %z) {
+; CHECK-LABEL: define float @maximumnum_reuse_lhs_nnan_folded_only(
+; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximumnum.f32(float [[X]], float [[Y]])
+; CHECK-NEXT: call void @use(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call nnan float @llvm.maximumnum.f32(float [[Z]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maximumnum.f32(float %x, float %y)
+ call void @use(float %m1)
+ %m2 = call nnan float @llvm.maximumnum.f32(float %z, float %x)
+ %m3 = call float @llvm.maximumnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @maximumnum_reuse_lhs_fmf_intersection(float %x, float %y, float %z) {
+; CHECK-LABEL: define float @maximumnum_reuse_lhs_fmf_intersection(
+; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximumnum.f32(float [[X]], float [[Y]])
+; CHECK-NEXT: call void @use(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call ninf afn float @llvm.maximumnum.f32(float [[Z]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call ninf arcp float @llvm.maximumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maximumnum.f32(float %x, float %y)
+ call void @use(float %m1)
+ %m2 = call afn ninf float @llvm.maximumnum.f32(float %z, float %x)
+ %m3 = call arcp ninf float @llvm.maximumnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+; Negative test - too many uses.
+
+define float @maximumnum_common_op_uses(float %x, float %y, float %z) {
+; CHECK-LABEL: define float @maximumnum_common_op_uses(
+; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximumnum.f32(float [[X]], float [[Y]])
+; CHECK-NEXT: call void @use(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maximumnum.f32(float [[X]], float [[Z]])
+; CHECK-NEXT: call void @use(float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maximumnum.f32(float %x, float %y)
+ call void @use(float %m1)
+ %m2 = call float @llvm.maximumnum.f32(float %x, float %z)
+ call void @use(float %m2)
+ %m3 = call float @llvm.maximumnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+; Negative test - must have common operand.
+
+define float @maximumnum_no_common_op(float %x, float %y, float %z, float %w) {
+; CHECK-LABEL: define float @maximumnum_no_common_op(
+; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]], float [[W:%.*]]) {
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximumnum.f32(float [[X]], float [[Y]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maximumnum.f32(float [[W]], float [[Z]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maximumnum.f32(float %x, float %y)
+ %m2 = call float @llvm.maximumnum.f32(float %w, float %z)
+ %m3 = call float @llvm.maximumnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
; PR37404 - https://bugs.llvm.org/show_bug.cgi?id=37404
define <2 x float> @maximumnum_neg_neg(<2 x float> %x, <2 x float> %y) {
@@ -149,7 +281,6 @@ define float @maximumnum_unary_neg_neg_vec_fmf(float %x, float %y) {
; 1 extra use of an intermediate value should still allow the fold,
; but 2 would require more instructions than we started with.
-declare void @use(float)
define float @maximumnum_neg_neg_extra_use_x(float %x, float %y) {
; CHECK-LABEL: define float @maximumnum_neg_neg_extra_use_x(
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
diff --git a/llvm/test/Transforms/InstCombine/maxnum.ll b/llvm/test/Transforms/InstCombine/maxnum.ll
index 5e275627414cb..fa4e7e42951f8 100644
--- a/llvm/test/Transforms/InstCombine/maxnum.ll
+++ b/llvm/test/Transforms/InstCombine/maxnum.ll
@@ -8,6 +8,8 @@ declare <4 x float> @llvm.maxnum.v4f32(<4 x float>, <4 x float>)
declare double @llvm.maxnum.f64(double, double)
declare <2 x double> @llvm.maxnum.v2f64(<2 x double>, <2 x double>)
+declare void @use(float)
+
define float @constant_fold_maxnum_f32() {
; CHECK-LABEL: @constant_fold_maxnum_f32(
; CHECK-NEXT: ret float 2.000000e+00
@@ -238,6 +240,128 @@ define float @maxnum4(float %x, float %y, float %z, float %w) {
ret float %c
}
+define float @maxnum_common_op(float %x, float %y, float %z) {
+; CHECK-LABEL: @maxnum_common_op(
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Z:%.*]])
+; CHECK-NEXT: [[Y:%.*]] = call float @llvm.maxnum.f32(float [[X]], float [[Z1:%.*]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maxnum.f32(float [[M2]], float [[Y]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maxnum.f32(float %x, float %y)
+ %m2 = call float @llvm.maxnum.f32(float %x, float %z)
+ %m3 = call float @llvm.maxnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @maxnum_reuse_lhs(float %x, float %y, float %z) {
+; CHECK-LABEL: @maxnum_reuse_lhs(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: call void @use(float [[M1]])
+; CHECK-NEXT: [[Z:%.*]] = call float @llvm.maxnum.f32(float [[Z1:%.*]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maxnum.f32(float [[M1]], float [[Z]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maxnum.f32(float %x, float %y)
+ call void @use(float %m1)
+ %m2 = call float @llvm.maxnum.f32(float %z, float %x)
+ %m3 = call float @llvm.maxnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @maxnum_reuse_rhs(float %x, float %y, float %z) {
+; CHECK-LABEL: @maxnum_reuse_rhs(
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maxnum.f32(float [[Z:%.*]], float [[X:%.*]])
+; CHECK-NEXT: [[Y:%.*]] = call float @llvm.maxnum.f32(float [[Z1:%.*]], float [[X]])
+; CHECK-NEXT: call void @use(float [[Y]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maxnum.f32(float [[M2]], float [[Y]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maxnum.f32(float %y, float %x)
+ %m2 = call float @llvm.maxnum.f32(float %z, float %x)
+ call void @use(float %m2)
+ %m3 = call float @llvm.maxnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @maxnum_reuse_lhs_nnan(float %x, float %y, float %z) {
+; CHECK-LABEL: @maxnum_reuse_lhs_nnan(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: call void @use(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maxnum.f32(float [[Z:%.*]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call nnan float @llvm.maxnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maxnum.f32(float %x, float %y)
+ call void @use(float %m1)
+ %m2 = call float @llvm.maxnum.f32(float %z, float %x)
+ %m3 = call nnan float @llvm.maxnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @maxnum_reuse_lhs_nnan_folded_only(float %x, float %y, float %z) {
+; CHECK-LABEL: @maxnum_reuse_lhs_nnan_folded_only(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: call void @use(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call nnan float @llvm.maxnum.f32(float [[Z:%.*]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maxnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maxnum.f32(float %x, float %y)
+ call void @use(float %m1)
+ %m2 = call nnan float @llvm.maxnum.f32(float %z, float %x)
+ %m3 = call float @llvm.maxnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @maxnum_reuse_lhs_fmf_intersection(float %x, float %y, float %z) {
+; CHECK-LABEL: @maxnum_reuse_lhs_fmf_intersection(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: call void @use(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call ninf afn float @llvm.maxnum.f32(float [[Z:%.*]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call ninf arcp float @llvm.maxnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maxnum.f32(float %x, float %y)
+ call void @use(float %m1)
+ %m2 = call afn ninf float @llvm.maxnum.f32(float %z, float %x)
+ %m3 = call arcp ninf float @llvm.maxnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+; Negative test - too many uses.
+
+define float @maxnum_common_op_uses(float %x, float %y, float %z) {
+; CHECK-LABEL: @maxnum_common_op_uses(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: call void @use(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maxnum.f32(float [[X]], float [[Z:%.*]])
+; CHECK-NEXT: call void @use(float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maxnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maxnum.f32(float %x, float %y)
+ call void @use(float %m1)
+ %m2 = call float @llvm.maxnum.f32(float %x, float %z)
+ call void @use(float %m2)
+ %m3 = call float @llvm.maxnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+; Negative test - must have common operand.
+
+define float @maxnum_no_common_op(float %x, float %y, float %z, float %w) {
+; CHECK-LABEL: @maxnum_no_common_op(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maxnum.f32(float [[W:%.*]], float [[Z:%.*]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maxnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.maxnum.f32(float %x, float %y)
+ %m2 = call float @llvm.maxnum.f32(float %w, float %z)
+ %m3 = call float @llvm.maxnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
; PR37404 - https://bugs.llvm.org/show_bug.cgi?id=37404
define <2 x float> @neg_neg(<2 x float> %x, <2 x float> %y) {
@@ -281,7 +405,6 @@ define float @unary_neg_neg_vec_fmf(float %x, float %y) {
; 1 extra use of an intermediate value should still allow the fold,
; but 2 would require more instructions than we started with.
-declare void @use(float)
define float @neg_neg_extra_use_x(float %x, float %y) {
; CHECK-LABEL: @neg_neg_extra_use_x(
; CHECK-NEXT: [[NEGX:%.*]] = fneg float [[X:%.*]]
diff --git a/llvm/test/Transforms/InstCombine/minimum.ll b/llvm/test/Transforms/InstCombine/minimum.ll
index eb6eadf96e132..ab3375a0f4e2a 100644
--- a/llvm/test/Transforms/InstCombine/minimum.ll
+++ b/llvm/test/Transforms/InstCombine/minimum.ll
@@ -9,6 +9,7 @@ declare double @llvm.minimum.f64(double, double)
declare <2 x double> @llvm.minimum.v2f64(<2 x double>, <2 x double>)
declare float @llvm.maximum.f32(float, float)
+declare void @use.f32(float)
define float @constant_fold_minimum_f32() {
; CHECK-LABEL: @constant_fold_minimum_f32(
@@ -240,6 +241,128 @@ define float @minimum4(float %x, float %y, float %z, float %w) {
ret float %c
}
+define float @minimum_common_op(float %x, float %y, float %z) {
+; CHECK-LABEL: @minimum_common_op(
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Z:%.*]])
+; CHECK-NEXT: [[Y:%.*]] = call float @llvm.minimum.f32(float [[X]], float [[Z1:%.*]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimum.f32(float [[M2]], float [[Y]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minimum.f32(float %x, float %y)
+ %m2 = call float @llvm.minimum.f32(float %x, float %z)
+ %m3 = call float @llvm.minimum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @minimum_reuse_lhs(float %x, float %y, float %z) {
+; CHECK-LABEL: @minimum_reuse_lhs(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: call void @use.f32(float [[M1]])
+; CHECK-NEXT: [[Z:%.*]] = call float @llvm.minimum.f32(float [[Z1:%.*]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimum.f32(float [[M1]], float [[Z]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minimum.f32(float %x, float %y)
+ call void @use.f32(float %m1)
+ %m2 = call float @llvm.minimum.f32(float %z, float %x)
+ %m3 = call float @llvm.minimum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @minimum_reuse_rhs(float %x, float %y, float %z) {
+; CHECK-LABEL: @minimum_reuse_rhs(
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minimum.f32(float [[Z:%.*]], float [[X:%.*]])
+; CHECK-NEXT: [[Y:%.*]] = call float @llvm.minimum.f32(float [[Z1:%.*]], float [[X]])
+; CHECK-NEXT: call void @use.f32(float [[Y]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimum.f32(float [[M2]], float [[Y]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minimum.f32(float %y, float %x)
+ %m2 = call float @llvm.minimum.f32(float %z, float %x)
+ call void @use.f32(float %m2)
+ %m3 = call float @llvm.minimum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @minimum_reuse_lhs_nnan(float %x, float %y, float %z) {
+; CHECK-LABEL: @minimum_reuse_lhs_nnan(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: call void @use.f32(float [[M1]])
+; CHECK-NEXT: [[Z:%.*]] = call float @llvm.minimum.f32(float [[Z1:%.*]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call nnan float @llvm.minimum.f32(float [[M1]], float [[Z]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minimum.f32(float %x, float %y)
+ call void @use.f32(float %m1)
+ %m2 = call float @llvm.minimum.f32(float %z, float %x)
+ %m3 = call nnan float @llvm.minimum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @minimum_reuse_lhs_nnan_folded_only(float %x, float %y, float %z) {
+; CHECK-LABEL: @minimum_reuse_lhs_nnan_folded_only(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: call void @use.f32(float [[M1]])
+; CHECK-NEXT: [[Z:%.*]] = call nnan float @llvm.minimum.f32(float [[Z1:%.*]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimum.f32(float [[M1]], float [[Z]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minimum.f32(float %x, float %y)
+ call void @use.f32(float %m1)
+ %m2 = call nnan float @llvm.minimum.f32(float %z, float %x)
+ %m3 = call float @llvm.minimum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @minimum_reuse_lhs_fmf_intersection(float %x, float %y, float %z) {
+; CHECK-LABEL: @minimum_reuse_lhs_fmf_intersection(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: call void @use.f32(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call ninf afn float @llvm.minimum.f32(float [[Z:%.*]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call ninf arcp float @llvm.minimum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minimum.f32(float %x, float %y)
+ call void @use.f32(float %m1)
+ %m2 = call afn ninf float @llvm.minimum.f32(float %z, float %x)
+ %m3 = call arcp ninf float @llvm.minimum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+; Negative test - too many uses.
+
+define float @minimum_common_op_uses(float %x, float %y, float %z) {
+; CHECK-LABEL: @minimum_common_op_uses(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: call void @use.f32(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minimum.f32(float [[X]], float [[Z:%.*]])
+; CHECK-NEXT: call void @use.f32(float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minimum.f32(float %x, float %y)
+ call void @use.f32(float %m1)
+ %m2 = call float @llvm.minimum.f32(float %x, float %z)
+ call void @use.f32(float %m2)
+ %m3 = call float @llvm.minimum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+; Negative test - must have common operand.
+
+define float @minimum_no_common_op(float %x, float %y, float %z, float %w) {
+; CHECK-LABEL: @minimum_no_common_op(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minimum.f32(float [[W:%.*]], float [[Z:%.*]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minimum.f32(float %x, float %y)
+ %m2 = call float @llvm.minimum.f32(float %w, float %z)
+ %m3 = call float @llvm.minimum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
define float @minimum_x_maximum_x_y(float %x, float %y) {
; CHECK-LABEL: @minimum_x_maximum_x_y(
; CHECK-NEXT: [[A:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
diff --git a/llvm/test/Transforms/InstCombine/minimumnum.ll b/llvm/test/Transforms/InstCombine/minimumnum.ll
index 9262a71939158..9117c69bc07df 100644
--- a/llvm/test/Transforms/InstCombine/minimumnum.ll
+++ b/llvm/test/Transforms/InstCombine/minimumnum.ll
@@ -1,6 +1,8 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+declare void @use.f32(float)
+
define float @minimumnum_f32_1_minimumnum_val_p0(float %x) {
; CHECK-LABEL: define float @minimumnum_f32_1_minimumnum_val_p0(
; CHECK-SAME: float [[X:%.*]]) {
@@ -103,6 +105,136 @@ define float @minimumnum4(float %x, float %y, float %z, float %w) {
ret float %c
}
+define float @minimumnum_common_op(float %x, float %y, float %z) {
+; CHECK-LABEL: define float @minimumnum_common_op(
+; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Z]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minimumnum.f32(float %x, float %y)
+ %m2 = call float @llvm.minimumnum.f32(float %x, float %z)
+ %m3 = call float @llvm.minimumnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @minimumnum_reuse_lhs(float %x, float %y, float %z) {
+; CHECK-LABEL: define float @minimumnum_reuse_lhs(
+; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]])
+; CHECK-NEXT: call void @use.f32(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minimumnum.f32(float [[Z]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minimumnum.f32(float %x, float %y)
+ call void @use.f32(float %m1)
+ %m2 = call float @llvm.minimumnum.f32(float %z, float %x)
+ %m3 = call float @llvm.minimumnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @minimumnum_reuse_rhs(float %x, float %y, float %z) {
+; CHECK-LABEL: define float @minimumnum_reuse_rhs(
+; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimumnum.f32(float [[Y]], float [[X]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minimumnum.f32(float [[Z]], float [[X]])
+; CHECK-NEXT: call void @use.f32(float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minimumnum.f32(float %y, float %x)
+ %m2 = call float @llvm.minimumnum.f32(float %z, float %x)
+ call void @use.f32(float %m2)
+ %m3 = call float @llvm.minimumnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @minimumnum_reuse_lhs_nnan(float %x, float %y, float %z) {
+; CHECK-LABEL: define float @minimumnum_reuse_lhs_nnan(
+; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]])
+; CHECK-NEXT: call void @use.f32(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minimumnum.f32(float [[Z]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call nnan float @llvm.minimumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minimumnum.f32(float %x, float %y)
+ call void @use.f32(float %m1)
+ %m2 = call float @llvm.minimumnum.f32(float %z, float %x)
+ %m3 = call nnan float @llvm.minimumnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @minimumnum_reuse_lhs_nnan_folded_only(float %x, float %y, float %z) {
+; CHECK-LABEL: define float @minimumnum_reuse_lhs_nnan_folded_only(
+; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]])
+; CHECK-NEXT: call void @use.f32(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call nnan float @llvm.minimumnum.f32(float [[Z]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minimumnum.f32(float %x, float %y)
+ call void @use.f32(float %m1)
+ %m2 = call nnan float @llvm.minimumnum.f32(float %z, float %x)
+ %m3 = call float @llvm.minimumnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @minimumnum_reuse_lhs_fmf_intersection(float %x, float %y, float %z) {
+; CHECK-LABEL: define float @minimumnum_reuse_lhs_fmf_intersection(
+; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]])
+; CHECK-NEXT: call void @use.f32(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call ninf afn float @llvm.minimumnum.f32(float [[Z]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call ninf arcp float @llvm.minimumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minimumnum.f32(float %x, float %y)
+ call void @use.f32(float %m1)
+ %m2 = call afn ninf float @llvm.minimumnum.f32(float %z, float %x)
+ %m3 = call arcp ninf float @llvm.minimumnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+; Negative test - too many uses.
+
+define float @minimumnum_common_op_uses(float %x, float %y, float %z) {
+; CHECK-LABEL: define float @minimumnum_common_op_uses(
+; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]])
+; CHECK-NEXT: call void @use.f32(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Z]])
+; CHECK-NEXT: call void @use.f32(float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minimumnum.f32(float %x, float %y)
+ call void @use.f32(float %m1)
+ %m2 = call float @llvm.minimumnum.f32(float %x, float %z)
+ call void @use.f32(float %m2)
+ %m3 = call float @llvm.minimumnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+; Negative test - must have common operand.
+
+define float @minimumnum_no_common_op(float %x, float %y, float %z, float %w) {
+; CHECK-LABEL: define float @minimumnum_no_common_op(
+; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]], float [[W:%.*]]) {
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minimumnum.f32(float [[W]], float [[Z]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minimumnum.f32(float %x, float %y)
+ %m2 = call float @llvm.minimumnum.f32(float %w, float %z)
+ %m3 = call float @llvm.minimumnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
define float @minimumnum_x_maximumnum_x_y(float %x, float %y) {
; CHECK-LABEL: define float @minimumnum_x_maximumnum_x_y(
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
diff --git a/llvm/test/Transforms/InstCombine/minnum.ll b/llvm/test/Transforms/InstCombine/minnum.ll
index 7ac83bf91163e..ebc9d6320ab5c 100644
--- a/llvm/test/Transforms/InstCombine/minnum.ll
+++ b/llvm/test/Transforms/InstCombine/minnum.ll
@@ -9,6 +9,7 @@ declare double @llvm.minnum.f64(double, double)
declare <2 x double> @llvm.minnum.v2f64(<2 x double>, <2 x double>)
declare float @llvm.maxnum.f32(float, float)
+declare void @use.f32(float)
define float @constant_fold_minnum_f32() {
; CHECK-LABEL: @constant_fold_minnum_f32(
@@ -240,6 +241,128 @@ define float @minnum4(float %x, float %y, float %z, float %w) {
ret float %c
}
+define float @minnum_common_op(float %x, float %y, float %z) {
+; CHECK-LABEL: @minnum_common_op(
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Z:%.*]])
+; CHECK-NEXT: [[Y:%.*]] = call float @llvm.minnum.f32(float [[X]], float [[Z1:%.*]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minnum.f32(float [[M2]], float [[Y]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minnum.f32(float %x, float %y)
+ %m2 = call float @llvm.minnum.f32(float %x, float %z)
+ %m3 = call float @llvm.minnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @minnum_reuse_lhs(float %x, float %y, float %z) {
+; CHECK-LABEL: @minnum_reuse_lhs(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: call void @use.f32(float [[M1]])
+; CHECK-NEXT: [[Z:%.*]] = call float @llvm.minnum.f32(float [[Z1:%.*]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minnum.f32(float [[M1]], float [[Z]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minnum.f32(float %x, float %y)
+ call void @use.f32(float %m1)
+ %m2 = call float @llvm.minnum.f32(float %z, float %x)
+ %m3 = call float @llvm.minnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @minnum_reuse_rhs(float %x, float %y, float %z) {
+; CHECK-LABEL: @minnum_reuse_rhs(
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minnum.f32(float [[Z:%.*]], float [[X:%.*]])
+; CHECK-NEXT: [[Y:%.*]] = call float @llvm.minnum.f32(float [[Z1:%.*]], float [[X]])
+; CHECK-NEXT: call void @use.f32(float [[Y]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minnum.f32(float [[M2]], float [[Y]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minnum.f32(float %y, float %x)
+ %m2 = call float @llvm.minnum.f32(float %z, float %x)
+ call void @use.f32(float %m2)
+ %m3 = call float @llvm.minnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @minnum_reuse_lhs_nnan(float %x, float %y, float %z) {
+; CHECK-LABEL: @minnum_reuse_lhs_nnan(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: call void @use.f32(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minnum.f32(float [[Z:%.*]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call nnan float @llvm.minnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minnum.f32(float %x, float %y)
+ call void @use.f32(float %m1)
+ %m2 = call float @llvm.minnum.f32(float %z, float %x)
+ %m3 = call nnan float @llvm.minnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @minnum_reuse_lhs_nnan_folded_only(float %x, float %y, float %z) {
+; CHECK-LABEL: @minnum_reuse_lhs_nnan_folded_only(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: call void @use.f32(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call nnan float @llvm.minnum.f32(float [[Z:%.*]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minnum.f32(float %x, float %y)
+ call void @use.f32(float %m1)
+ %m2 = call nnan float @llvm.minnum.f32(float %z, float %x)
+ %m3 = call float @llvm.minnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+define float @minnum_reuse_lhs_fmf_intersection(float %x, float %y, float %z) {
+; CHECK-LABEL: @minnum_reuse_lhs_fmf_intersection(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: call void @use.f32(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call ninf afn float @llvm.minnum.f32(float [[Z:%.*]], float [[X]])
+; CHECK-NEXT: [[M3:%.*]] = call ninf arcp float @llvm.minnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minnum.f32(float %x, float %y)
+ call void @use.f32(float %m1)
+ %m2 = call afn ninf float @llvm.minnum.f32(float %z, float %x)
+ %m3 = call arcp ninf float @llvm.minnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+; Negative test - too many uses.
+
+define float @minnum_common_op_uses(float %x, float %y, float %z) {
+; CHECK-LABEL: @minnum_common_op_uses(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: call void @use.f32(float [[M1]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minnum.f32(float [[X]], float [[Z:%.*]])
+; CHECK-NEXT: call void @use.f32(float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minnum.f32(float %x, float %y)
+ call void @use.f32(float %m1)
+ %m2 = call float @llvm.minnum.f32(float %x, float %z)
+ call void @use.f32(float %m2)
+ %m3 = call float @llvm.minnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
+; Negative test - must have common operand.
+
+define float @minnum_no_common_op(float %x, float %y, float %z, float %w) {
+; CHECK-LABEL: @minnum_no_common_op(
+; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minnum.f32(float [[W:%.*]], float [[Z:%.*]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: ret float [[M3]]
+;
+ %m1 = call float @llvm.minnum.f32(float %x, float %y)
+ %m2 = call float @llvm.minnum.f32(float %w, float %z)
+ %m3 = call float @llvm.minnum.f32(float %m1, float %m2)
+ ret float %m3
+}
+
define float @minnum_x_maxnum_x_y(float %x, float %y) {
; CHECK-LABEL: @minnum_x_maxnum_x_y(
; CHECK-NEXT: [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
>From 0c9bd594daefa070f8fd1111ab2fd3285f835573 Mon Sep 17 00:00:00 2001
From: Thomas Fry <thomas.fry at arm.com>
Date: Mon, 20 Apr 2026 13:09:54 +0200
Subject: [PATCH 2/2] [InstCombine] Enable factorizeMinMaxTree for
floating-point values
---
.../InstCombine/InstCombineCalls.cpp | 21 +++++++++++++++++-
llvm/test/Transforms/InstCombine/maximum.ll | 22 +++++++------------
.../test/Transforms/InstCombine/maximumnum.ll | 18 +++++----------
llvm/test/Transforms/InstCombine/maxnum.ll | 22 +++++++------------
llvm/test/Transforms/InstCombine/minimum.ll | 22 +++++++------------
.../test/Transforms/InstCombine/minimumnum.ll | 18 +++++----------
llvm/test/Transforms/InstCombine/minnum.ll | 22 +++++++------------
7 files changed, 64 insertions(+), 81 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index d97c66025cee7..7188fbc0de6dd 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1481,7 +1481,23 @@ static Instruction *factorizeMinMaxTree(IntrinsicInst *II) {
Module *Mod = II->getModule();
Function *MinMax =
Intrinsic::getOrInsertDeclaration(Mod, MinMaxID, II->getType());
- return CallInst::Create(MinMax, { MinMaxOp, ThirdOp });
+ Instruction *RetI = CallInst::Create(MinMax, {MinMaxOp, ThirdOp});
+ if (isa<FPMathOperator>(II)) {
+ FastMathFlags IIFMF = II->getFastMathFlags();
+ FastMathFlags FoldedOpFMF =
+ (MinMaxOp == LHS ? RHS : LHS)->getFastMathFlags();
+ FastMathFlags RetFMF = IIFMF & FoldedOpFMF;
+ // Different intrinsics handle NaN propagation differently. For maximum and
+ // minimum, nnan does not rely on the folded instruction's flags. For the
+ // others, it does not rely on II's flags
+ if (MinMaxID == Intrinsic::maximum || MinMaxID == Intrinsic::minimum)
+ RetFMF.setNoNaNs(IIFMF.noNaNs());
+ if (MinMaxID == Intrinsic::maxnum || MinMaxID == Intrinsic::minnum ||
+ MinMaxID == Intrinsic::maximumnum || MinMaxID == Intrinsic::minimumnum)
+ RetFMF.setNoNaNs(FoldedOpFMF.noNaNs());
+ RetI->setFastMathFlags(RetFMF);
+ }
+ return RetI;
}
/// If all arguments of the intrinsic are unary shuffles with the same mask,
@@ -2861,6 +2877,9 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
return FNeg;
}
+ if (Instruction *NewMinMax = factorizeMinMaxTree(II))
+ return NewMinMax;
+
// m(m(X, C2), C1) -> m(X, C)
const APFloat *C1, *C2;
if (auto *M = dyn_cast<IntrinsicInst>(Arg0)) {
diff --git a/llvm/test/Transforms/InstCombine/maximum.ll b/llvm/test/Transforms/InstCombine/maximum.ll
index 296a231c7b86a..906a6644ba3d5 100644
--- a/llvm/test/Transforms/InstCombine/maximum.ll
+++ b/llvm/test/Transforms/InstCombine/maximum.ll
@@ -242,9 +242,8 @@ define float @maximum4(float %x, float %y, float %z, float %w) {
define float @maximum_common_op(float %x, float %y, float %z) {
; CHECK-LABEL: @maximum_common_op(
-; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Z:%.*]])
-; CHECK-NEXT: [[Y:%.*]] = call float @llvm.maximum.f32(float [[X]], float [[Z1:%.*]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximum.f32(float [[M2]], float [[Y]])
+; CHECK-NEXT: [[Y:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Z1:%.*]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximum.f32(float [[Y]], float [[Y1:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.maximum.f32(float %x, float %y)
@@ -257,8 +256,7 @@ define float @maximum_reuse_lhs(float %x, float %y, float %z) {
; CHECK-LABEL: @maximum_reuse_lhs(
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
; CHECK-NEXT: call void @use(float [[M1]])
-; CHECK-NEXT: [[Z:%.*]] = call float @llvm.maximum.f32(float [[Z1:%.*]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximum.f32(float [[M1]], float [[Z]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximum.f32(float [[M1]], float [[Z:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.maximum.f32(float %x, float %y)
@@ -270,10 +268,9 @@ define float @maximum_reuse_lhs(float %x, float %y, float %z) {
define float @maximum_reuse_rhs(float %x, float %y, float %z) {
; CHECK-LABEL: @maximum_reuse_rhs(
-; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maximum.f32(float [[Z:%.*]], float [[X:%.*]])
-; CHECK-NEXT: [[Y:%.*]] = call float @llvm.maximum.f32(float [[Z1:%.*]], float [[X]])
+; CHECK-NEXT: [[Y:%.*]] = call float @llvm.maximum.f32(float [[Z1:%.*]], float [[X:%.*]])
; CHECK-NEXT: call void @use(float [[Y]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximum.f32(float [[M2]], float [[Y]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximum.f32(float [[Y]], float [[Y1:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.maximum.f32(float %y, float %x)
@@ -287,8 +284,7 @@ define float @maximum_reuse_lhs_nnan(float %x, float %y, float %z) {
; CHECK-LABEL: @maximum_reuse_lhs_nnan(
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
; CHECK-NEXT: call void @use(float [[M1]])
-; CHECK-NEXT: [[Z:%.*]] = call float @llvm.maximum.f32(float [[Z1:%.*]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call nnan float @llvm.maximum.f32(float [[M1]], float [[Z]])
+; CHECK-NEXT: [[M3:%.*]] = call nnan float @llvm.maximum.f32(float [[M1]], float [[Z:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.maximum.f32(float %x, float %y)
@@ -302,8 +298,7 @@ define float @maximum_reuse_lhs_nnan_folded_only(float %x, float %y, float %z) {
; CHECK-LABEL: @maximum_reuse_lhs_nnan_folded_only(
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
; CHECK-NEXT: call void @use(float [[M1]])
-; CHECK-NEXT: [[Z:%.*]] = call nnan float @llvm.maximum.f32(float [[Z1:%.*]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximum.f32(float [[M1]], float [[Z]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximum.f32(float [[M1]], float [[Z:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.maximum.f32(float %x, float %y)
@@ -317,8 +312,7 @@ define float @maximum_reuse_lhs_fmf_intersection(float %x, float %y, float %z) {
; CHECK-LABEL: @maximum_reuse_lhs_fmf_intersection(
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximum.f32(float [[X:%.*]], float [[Y:%.*]])
; CHECK-NEXT: call void @use(float [[M1]])
-; CHECK-NEXT: [[M2:%.*]] = call ninf afn float @llvm.maximum.f32(float [[Z:%.*]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call ninf arcp float @llvm.maximum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call ninf float @llvm.maximum.f32(float [[M1]], float [[Z:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.maximum.f32(float %x, float %y)
diff --git a/llvm/test/Transforms/InstCombine/maximumnum.ll b/llvm/test/Transforms/InstCombine/maximumnum.ll
index b405e2ea34360..5860e75fadda3 100644
--- a/llvm/test/Transforms/InstCombine/maximumnum.ll
+++ b/llvm/test/Transforms/InstCombine/maximumnum.ll
@@ -108,9 +108,8 @@ define float @maximumnum4(float %x, float %y, float %z, float %w) {
define float @maximumnum_common_op(float %x, float %y, float %z) {
; CHECK-LABEL: define float @maximumnum_common_op(
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
-; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximumnum.f32(float [[X]], float [[Y]])
; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maximumnum.f32(float [[X]], float [[Z]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximumnum.f32(float [[M2]], float [[Y]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.maximumnum.f32(float %x, float %y)
@@ -124,8 +123,7 @@ define float @maximumnum_reuse_lhs(float %x, float %y, float %z) {
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximumnum.f32(float [[X]], float [[Y]])
; CHECK-NEXT: call void @use(float [[M1]])
-; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maximumnum.f32(float [[Z]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximumnum.f32(float [[M1]], float [[Z]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.maximumnum.f32(float %x, float %y)
@@ -138,10 +136,9 @@ define float @maximumnum_reuse_lhs(float %x, float %y, float %z) {
define float @maximumnum_reuse_rhs(float %x, float %y, float %z) {
; CHECK-LABEL: define float @maximumnum_reuse_rhs(
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
-; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximumnum.f32(float [[Y]], float [[X]])
; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maximumnum.f32(float [[Z]], float [[X]])
; CHECK-NEXT: call void @use(float [[M2]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximumnum.f32(float [[M2]], float [[Y]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.maximumnum.f32(float %y, float %x)
@@ -156,8 +153,7 @@ define float @maximumnum_reuse_lhs_nnan(float %x, float %y, float %z) {
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximumnum.f32(float [[X]], float [[Y]])
; CHECK-NEXT: call void @use(float [[M1]])
-; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maximumnum.f32(float [[Z]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call nnan float @llvm.maximumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximumnum.f32(float [[M1]], float [[Z]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.maximumnum.f32(float %x, float %y)
@@ -172,8 +168,7 @@ define float @maximumnum_reuse_lhs_nnan_folded_only(float %x, float %y, float %z
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximumnum.f32(float [[X]], float [[Y]])
; CHECK-NEXT: call void @use(float [[M1]])
-; CHECK-NEXT: [[M2:%.*]] = call nnan float @llvm.maximumnum.f32(float [[Z]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maximumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call nnan float @llvm.maximumnum.f32(float [[M1]], float [[Z]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.maximumnum.f32(float %x, float %y)
@@ -188,8 +183,7 @@ define float @maximumnum_reuse_lhs_fmf_intersection(float %x, float %y, float %z
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maximumnum.f32(float [[X]], float [[Y]])
; CHECK-NEXT: call void @use(float [[M1]])
-; CHECK-NEXT: [[M2:%.*]] = call ninf afn float @llvm.maximumnum.f32(float [[Z]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call ninf arcp float @llvm.maximumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call ninf float @llvm.maximumnum.f32(float [[M1]], float [[Z]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.maximumnum.f32(float %x, float %y)
diff --git a/llvm/test/Transforms/InstCombine/maxnum.ll b/llvm/test/Transforms/InstCombine/maxnum.ll
index fa4e7e42951f8..94e8c3a4af5a2 100644
--- a/llvm/test/Transforms/InstCombine/maxnum.ll
+++ b/llvm/test/Transforms/InstCombine/maxnum.ll
@@ -242,9 +242,8 @@ define float @maxnum4(float %x, float %y, float %z, float %w) {
define float @maxnum_common_op(float %x, float %y, float %z) {
; CHECK-LABEL: @maxnum_common_op(
-; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Z:%.*]])
-; CHECK-NEXT: [[Y:%.*]] = call float @llvm.maxnum.f32(float [[X]], float [[Z1:%.*]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maxnum.f32(float [[M2]], float [[Y]])
+; CHECK-NEXT: [[Y:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Z1:%.*]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maxnum.f32(float [[Y]], float [[Y1:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.maxnum.f32(float %x, float %y)
@@ -257,8 +256,7 @@ define float @maxnum_reuse_lhs(float %x, float %y, float %z) {
; CHECK-LABEL: @maxnum_reuse_lhs(
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
; CHECK-NEXT: call void @use(float [[M1]])
-; CHECK-NEXT: [[Z:%.*]] = call float @llvm.maxnum.f32(float [[Z1:%.*]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maxnum.f32(float [[M1]], float [[Z]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maxnum.f32(float [[M1]], float [[Z:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.maxnum.f32(float %x, float %y)
@@ -270,10 +268,9 @@ define float @maxnum_reuse_lhs(float %x, float %y, float %z) {
define float @maxnum_reuse_rhs(float %x, float %y, float %z) {
; CHECK-LABEL: @maxnum_reuse_rhs(
-; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maxnum.f32(float [[Z:%.*]], float [[X:%.*]])
-; CHECK-NEXT: [[Y:%.*]] = call float @llvm.maxnum.f32(float [[Z1:%.*]], float [[X]])
+; CHECK-NEXT: [[Y:%.*]] = call float @llvm.maxnum.f32(float [[Z1:%.*]], float [[X:%.*]])
; CHECK-NEXT: call void @use(float [[Y]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maxnum.f32(float [[M2]], float [[Y]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maxnum.f32(float [[Y]], float [[Y1:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.maxnum.f32(float %y, float %x)
@@ -287,8 +284,7 @@ define float @maxnum_reuse_lhs_nnan(float %x, float %y, float %z) {
; CHECK-LABEL: @maxnum_reuse_lhs_nnan(
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
; CHECK-NEXT: call void @use(float [[M1]])
-; CHECK-NEXT: [[M2:%.*]] = call float @llvm.maxnum.f32(float [[Z:%.*]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call nnan float @llvm.maxnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maxnum.f32(float [[M1]], float [[Z:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.maxnum.f32(float %x, float %y)
@@ -302,8 +298,7 @@ define float @maxnum_reuse_lhs_nnan_folded_only(float %x, float %y, float %z) {
; CHECK-LABEL: @maxnum_reuse_lhs_nnan_folded_only(
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
; CHECK-NEXT: call void @use(float [[M1]])
-; CHECK-NEXT: [[M2:%.*]] = call nnan float @llvm.maxnum.f32(float [[Z:%.*]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.maxnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call nnan float @llvm.maxnum.f32(float [[M1]], float [[Z:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.maxnum.f32(float %x, float %y)
@@ -317,8 +312,7 @@ define float @maxnum_reuse_lhs_fmf_intersection(float %x, float %y, float %z) {
; CHECK-LABEL: @maxnum_reuse_lhs_fmf_intersection(
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
; CHECK-NEXT: call void @use(float [[M1]])
-; CHECK-NEXT: [[M2:%.*]] = call ninf afn float @llvm.maxnum.f32(float [[Z:%.*]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call ninf arcp float @llvm.maxnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call ninf float @llvm.maxnum.f32(float [[M1]], float [[Z:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.maxnum.f32(float %x, float %y)
diff --git a/llvm/test/Transforms/InstCombine/minimum.ll b/llvm/test/Transforms/InstCombine/minimum.ll
index ab3375a0f4e2a..c0ea78d9d59de 100644
--- a/llvm/test/Transforms/InstCombine/minimum.ll
+++ b/llvm/test/Transforms/InstCombine/minimum.ll
@@ -243,9 +243,8 @@ define float @minimum4(float %x, float %y, float %z, float %w) {
define float @minimum_common_op(float %x, float %y, float %z) {
; CHECK-LABEL: @minimum_common_op(
-; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Z:%.*]])
-; CHECK-NEXT: [[Y:%.*]] = call float @llvm.minimum.f32(float [[X]], float [[Z1:%.*]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimum.f32(float [[M2]], float [[Y]])
+; CHECK-NEXT: [[Y:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Z1:%.*]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimum.f32(float [[Y]], float [[Y1:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.minimum.f32(float %x, float %y)
@@ -258,8 +257,7 @@ define float @minimum_reuse_lhs(float %x, float %y, float %z) {
; CHECK-LABEL: @minimum_reuse_lhs(
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
; CHECK-NEXT: call void @use.f32(float [[M1]])
-; CHECK-NEXT: [[Z:%.*]] = call float @llvm.minimum.f32(float [[Z1:%.*]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimum.f32(float [[M1]], float [[Z]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimum.f32(float [[M1]], float [[Z:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.minimum.f32(float %x, float %y)
@@ -271,10 +269,9 @@ define float @minimum_reuse_lhs(float %x, float %y, float %z) {
define float @minimum_reuse_rhs(float %x, float %y, float %z) {
; CHECK-LABEL: @minimum_reuse_rhs(
-; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minimum.f32(float [[Z:%.*]], float [[X:%.*]])
-; CHECK-NEXT: [[Y:%.*]] = call float @llvm.minimum.f32(float [[Z1:%.*]], float [[X]])
+; CHECK-NEXT: [[Y:%.*]] = call float @llvm.minimum.f32(float [[Z1:%.*]], float [[X:%.*]])
; CHECK-NEXT: call void @use.f32(float [[Y]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimum.f32(float [[M2]], float [[Y]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimum.f32(float [[Y]], float [[Y1:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.minimum.f32(float %y, float %x)
@@ -288,8 +285,7 @@ define float @minimum_reuse_lhs_nnan(float %x, float %y, float %z) {
; CHECK-LABEL: @minimum_reuse_lhs_nnan(
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
; CHECK-NEXT: call void @use.f32(float [[M1]])
-; CHECK-NEXT: [[Z:%.*]] = call float @llvm.minimum.f32(float [[Z1:%.*]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call nnan float @llvm.minimum.f32(float [[M1]], float [[Z]])
+; CHECK-NEXT: [[M3:%.*]] = call nnan float @llvm.minimum.f32(float [[M1]], float [[Z:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.minimum.f32(float %x, float %y)
@@ -303,8 +299,7 @@ define float @minimum_reuse_lhs_nnan_folded_only(float %x, float %y, float %z) {
; CHECK-LABEL: @minimum_reuse_lhs_nnan_folded_only(
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
; CHECK-NEXT: call void @use.f32(float [[M1]])
-; CHECK-NEXT: [[Z:%.*]] = call nnan float @llvm.minimum.f32(float [[Z1:%.*]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimum.f32(float [[M1]], float [[Z]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimum.f32(float [[M1]], float [[Z:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.minimum.f32(float %x, float %y)
@@ -318,8 +313,7 @@ define float @minimum_reuse_lhs_fmf_intersection(float %x, float %y, float %z) {
; CHECK-LABEL: @minimum_reuse_lhs_fmf_intersection(
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y:%.*]])
; CHECK-NEXT: call void @use.f32(float [[M1]])
-; CHECK-NEXT: [[M2:%.*]] = call ninf afn float @llvm.minimum.f32(float [[Z:%.*]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call ninf arcp float @llvm.minimum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call ninf float @llvm.minimum.f32(float [[M1]], float [[Z:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.minimum.f32(float %x, float %y)
diff --git a/llvm/test/Transforms/InstCombine/minimumnum.ll b/llvm/test/Transforms/InstCombine/minimumnum.ll
index 9117c69bc07df..d06464edd53a5 100644
--- a/llvm/test/Transforms/InstCombine/minimumnum.ll
+++ b/llvm/test/Transforms/InstCombine/minimumnum.ll
@@ -108,9 +108,8 @@ define float @minimumnum4(float %x, float %y, float %z, float %w) {
define float @minimumnum_common_op(float %x, float %y, float %z) {
; CHECK-LABEL: define float @minimumnum_common_op(
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
-; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]])
; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Z]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimumnum.f32(float [[M2]], float [[Y]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.minimumnum.f32(float %x, float %y)
@@ -124,8 +123,7 @@ define float @minimumnum_reuse_lhs(float %x, float %y, float %z) {
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]])
; CHECK-NEXT: call void @use.f32(float [[M1]])
-; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minimumnum.f32(float [[Z]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimumnum.f32(float [[M1]], float [[Z]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.minimumnum.f32(float %x, float %y)
@@ -138,10 +136,9 @@ define float @minimumnum_reuse_lhs(float %x, float %y, float %z) {
define float @minimumnum_reuse_rhs(float %x, float %y, float %z) {
; CHECK-LABEL: define float @minimumnum_reuse_rhs(
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
-; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimumnum.f32(float [[Y]], float [[X]])
; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minimumnum.f32(float [[Z]], float [[X]])
; CHECK-NEXT: call void @use.f32(float [[M2]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimumnum.f32(float [[M2]], float [[Y]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.minimumnum.f32(float %y, float %x)
@@ -156,8 +153,7 @@ define float @minimumnum_reuse_lhs_nnan(float %x, float %y, float %z) {
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]])
; CHECK-NEXT: call void @use.f32(float [[M1]])
-; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minimumnum.f32(float [[Z]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call nnan float @llvm.minimumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimumnum.f32(float [[M1]], float [[Z]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.minimumnum.f32(float %x, float %y)
@@ -172,8 +168,7 @@ define float @minimumnum_reuse_lhs_nnan_folded_only(float %x, float %y, float %z
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]])
; CHECK-NEXT: call void @use.f32(float [[M1]])
-; CHECK-NEXT: [[M2:%.*]] = call nnan float @llvm.minimumnum.f32(float [[Z]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minimumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call nnan float @llvm.minimumnum.f32(float [[M1]], float [[Z]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.minimumnum.f32(float %x, float %y)
@@ -188,8 +183,7 @@ define float @minimumnum_reuse_lhs_fmf_intersection(float %x, float %y, float %z
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) {
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]])
; CHECK-NEXT: call void @use.f32(float [[M1]])
-; CHECK-NEXT: [[M2:%.*]] = call ninf afn float @llvm.minimumnum.f32(float [[Z]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call ninf arcp float @llvm.minimumnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call ninf float @llvm.minimumnum.f32(float [[M1]], float [[Z]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.minimumnum.f32(float %x, float %y)
diff --git a/llvm/test/Transforms/InstCombine/minnum.ll b/llvm/test/Transforms/InstCombine/minnum.ll
index ebc9d6320ab5c..193c07f4a29c4 100644
--- a/llvm/test/Transforms/InstCombine/minnum.ll
+++ b/llvm/test/Transforms/InstCombine/minnum.ll
@@ -243,9 +243,8 @@ define float @minnum4(float %x, float %y, float %z, float %w) {
define float @minnum_common_op(float %x, float %y, float %z) {
; CHECK-LABEL: @minnum_common_op(
-; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Z:%.*]])
-; CHECK-NEXT: [[Y:%.*]] = call float @llvm.minnum.f32(float [[X]], float [[Z1:%.*]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minnum.f32(float [[M2]], float [[Y]])
+; CHECK-NEXT: [[Y:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Z1:%.*]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minnum.f32(float [[Y]], float [[Y1:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.minnum.f32(float %x, float %y)
@@ -258,8 +257,7 @@ define float @minnum_reuse_lhs(float %x, float %y, float %z) {
; CHECK-LABEL: @minnum_reuse_lhs(
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
; CHECK-NEXT: call void @use.f32(float [[M1]])
-; CHECK-NEXT: [[Z:%.*]] = call float @llvm.minnum.f32(float [[Z1:%.*]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minnum.f32(float [[M1]], float [[Z]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minnum.f32(float [[M1]], float [[Z:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.minnum.f32(float %x, float %y)
@@ -271,10 +269,9 @@ define float @minnum_reuse_lhs(float %x, float %y, float %z) {
define float @minnum_reuse_rhs(float %x, float %y, float %z) {
; CHECK-LABEL: @minnum_reuse_rhs(
-; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minnum.f32(float [[Z:%.*]], float [[X:%.*]])
-; CHECK-NEXT: [[Y:%.*]] = call float @llvm.minnum.f32(float [[Z1:%.*]], float [[X]])
+; CHECK-NEXT: [[Y:%.*]] = call float @llvm.minnum.f32(float [[Z1:%.*]], float [[X:%.*]])
; CHECK-NEXT: call void @use.f32(float [[Y]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minnum.f32(float [[M2]], float [[Y]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minnum.f32(float [[Y]], float [[Y1:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.minnum.f32(float %y, float %x)
@@ -288,8 +285,7 @@ define float @minnum_reuse_lhs_nnan(float %x, float %y, float %z) {
; CHECK-LABEL: @minnum_reuse_lhs_nnan(
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
; CHECK-NEXT: call void @use.f32(float [[M1]])
-; CHECK-NEXT: [[M2:%.*]] = call float @llvm.minnum.f32(float [[Z:%.*]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call nnan float @llvm.minnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minnum.f32(float [[M1]], float [[Z:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.minnum.f32(float %x, float %y)
@@ -303,8 +299,7 @@ define float @minnum_reuse_lhs_nnan_folded_only(float %x, float %y, float %z) {
; CHECK-LABEL: @minnum_reuse_lhs_nnan_folded_only(
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
; CHECK-NEXT: call void @use.f32(float [[M1]])
-; CHECK-NEXT: [[M2:%.*]] = call nnan float @llvm.minnum.f32(float [[Z:%.*]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call float @llvm.minnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call nnan float @llvm.minnum.f32(float [[M1]], float [[Z:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.minnum.f32(float %x, float %y)
@@ -318,8 +313,7 @@ define float @minnum_reuse_lhs_fmf_intersection(float %x, float %y, float %z) {
; CHECK-LABEL: @minnum_reuse_lhs_fmf_intersection(
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
; CHECK-NEXT: call void @use.f32(float [[M1]])
-; CHECK-NEXT: [[M2:%.*]] = call ninf afn float @llvm.minnum.f32(float [[Z:%.*]], float [[X]])
-; CHECK-NEXT: [[M3:%.*]] = call ninf arcp float @llvm.minnum.f32(float [[M1]], float [[M2]])
+; CHECK-NEXT: [[M3:%.*]] = call ninf float @llvm.minnum.f32(float [[M1]], float [[Z:%.*]])
; CHECK-NEXT: ret float [[M3]]
;
%m1 = call float @llvm.minnum.f32(float %x, float %y)
More information about the llvm-commits
mailing list