[llvm] [InstCombine] Don't convert a compare+select into a minnum/maxnum intrinsic that can't be lowered back to a compare+select (PR #177821)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 25 12:28:31 PST 2026
https://github.com/valadaptive updated https://github.com/llvm/llvm-project/pull/177821
>From df0ae1e7306228464dcdae4e4b7ee59ed836548f Mon Sep 17 00:00:00 2001
From: valadaptive <valadaptive at protonmail.com>
Date: Sat, 24 Jan 2026 22:30:27 -0500
Subject: [PATCH 1/5] [InstCombine] Don't convert a compare+select to a
minnum/maxnum without nnan
---
.../InstCombine/InstCombineSelect.cpp | 18 +-
.../InstCombine/fcmp-fadd-select.ll | 199 ++++++++++--------
.../Transforms/InstCombine/fcmp-select.ll | 8 +-
llvm/test/Transforms/InstCombine/fmul-bool.ll | 18 +-
llvm/test/Transforms/InstCombine/fneg.ll | 4 +-
llvm/test/Transforms/InstCombine/minmax-fp.ll | 20 +-
.../Transforms/InstCombine/select_meta.ll | 3 +-
.../InstCombine/unordered-fcmp-select.ll | 10 +-
8 files changed, 156 insertions(+), 124 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 6ead1fd52403d..64d629ad4ab1c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -4357,7 +4357,21 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
// Canonicalize select of FP values where NaN and -0.0 are not valid as
// minnum/maxnum intrinsics.
- if (SIFPOp->hasNoNaNs() &&
+ if (FCmp && SIFPOp->hasNoNaNs() &&
+ // In order to preserve the nnan flag on the generated intrinsic call,
+ // the nnan flag must be present on both the compare *and* the select
+ // (for poison propagation reasons).
+ //
+ // Some targets don't have a floating point minimum/maximum instruction
+ // with the same semantics as our minnum/maxnum intrinsics. If the
+ // nnan+nsz flags are present on the intrinsic call, those targets can
+ // lower it to a select, or to a simpler instruction. If either flag is
+ // absent then they must lower it to a routine, or even worse, a
+ // libcall. That makes things way slower, and there are other reasons to
+ // avoid introducing libcalls where none previously existed (see
+ // https://github.com/llvm/llvm-project/issues/54554). So, if we can't
+ // preserve the nnan flag, don't bother with the transformation.
+ FCmp->hasNoNaNs() &&
(SIFPOp->hasNoSignedZeros() ||
(SIFPOp->hasOneUse() &&
canIgnoreSignBitOfZero(*SIFPOp->use_begin())))) {
@@ -4366,7 +4380,6 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
Value *BinIntr =
Builder.CreateBinaryIntrinsic(Intrinsic::maxnum, X, Y, &SI);
if (auto *BinIntrInst = dyn_cast<Instruction>(BinIntr)) {
- BinIntrInst->setHasNoNaNs(FCmp->hasNoNaNs());
BinIntrInst->setHasNoInfs(FCmp->hasNoInfs());
}
return replaceInstUsesWith(SI, BinIntr);
@@ -4376,7 +4389,6 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
Value *BinIntr =
Builder.CreateBinaryIntrinsic(Intrinsic::minnum, X, Y, &SI);
if (auto *BinIntrInst = dyn_cast<Instruction>(BinIntr)) {
- BinIntrInst->setHasNoNaNs(FCmp->hasNoNaNs());
BinIntrInst->setHasNoInfs(FCmp->hasNoInfs());
}
return replaceInstUsesWith(SI, BinIntr);
diff --git a/llvm/test/Transforms/InstCombine/fcmp-fadd-select.ll b/llvm/test/Transforms/InstCombine/fcmp-fadd-select.ll
index ffc8183d07b2d..aabeff5ada469 100644
--- a/llvm/test/Transforms/InstCombine/fcmp-fadd-select.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp-fadd-select.ll
@@ -6,11 +6,11 @@
define float @test_fcmp_ogt_fadd_select_constant(float %in) {
; CHECK-LABEL: define float @test_fcmp_ogt_fadd_select_constant(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ogt float %in, 0.000000e+00
+ %cmp1 = fcmp nnan ogt float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -19,11 +19,11 @@ define float @test_fcmp_ogt_fadd_select_constant(float %in) {
define float @test_fcmp_ogt_fadd_select_constant_swapped(float %in) {
; CHECK-LABEL: define float @test_fcmp_ogt_fadd_select_constant_swapped(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ogt float %in, 0.000000e+00
+ %cmp1 = fcmp nnan ogt float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
ret float %sel
@@ -32,11 +32,11 @@ define float @test_fcmp_ogt_fadd_select_constant_swapped(float %in) {
define float @test_fcmp_ogt_fadd_select_neg_constant(float %in) {
; CHECK-LABEL: define float @test_fcmp_ogt_fadd_select_neg_constant(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ogt float %in, -0.000000e+00
+ %cmp1 = fcmp nnan ogt float %in, -0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -45,11 +45,11 @@ define float @test_fcmp_ogt_fadd_select_neg_constant(float %in) {
define float @test_fcmp_ogt_fadd_select_fastmath_preserve(float %in) {
; CHECK-LABEL: define float @test_fcmp_ogt_fadd_select_fastmath_preserve(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ogt float %in, 0.000000e+00
+ %cmp1 = fcmp nnan ogt float %in, 0.000000e+00
%add = fadd nnan float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -58,11 +58,11 @@ define float @test_fcmp_ogt_fadd_select_fastmath_preserve(float %in) {
define <2 x float> @test_fcmp_ogt_fadd_select_constant_vectors(<2 x float> %in) {
; CHECK-LABEL: define <2 x float> @test_fcmp_ogt_fadd_select_constant_vectors(
; CHECK-SAME: <2 x float> [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz <2 x float> @llvm.maxnum.v2f32(<2 x float> [[IN]], <2 x float> zeroinitializer)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz <2 x float> @llvm.maxnum.v2f32(<2 x float> [[IN]], <2 x float> zeroinitializer)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
; CHECK-NEXT: ret <2 x float> [[ADD_NEW]]
;
- %cmp1 = fcmp ogt <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
+ %cmp1 = fcmp nnan ogt <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
%add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
%sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
ret <2 x float> %sel
@@ -74,11 +74,11 @@ define <2 x float> @test_fcmp_ogt_fadd_select_constant_vectors(<2 x float> %in)
define float @test_fcmp_olt_fadd_select_constant(float %in) {
; CHECK-LABEL: define float @test_fcmp_olt_fadd_select_constant(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp olt float %in, 0.000000e+00
+ %cmp1 = fcmp nnan olt float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -87,11 +87,11 @@ define float @test_fcmp_olt_fadd_select_constant(float %in) {
define float @test_fcmp_olt_fadd_select_constant_swapped(float %in) {
; CHECK-LABEL: define float @test_fcmp_olt_fadd_select_constant_swapped(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp olt float %in, 0.000000e+00
+ %cmp1 = fcmp nnan olt float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
ret float %sel
@@ -100,11 +100,11 @@ define float @test_fcmp_olt_fadd_select_constant_swapped(float %in) {
define float @test_fcmp_olt_fadd_select_neg_constant(float %in) {
; CHECK-LABEL: define float @test_fcmp_olt_fadd_select_neg_constant(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp olt float %in, -0.000000e+00
+ %cmp1 = fcmp nnan olt float %in, -0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -113,11 +113,11 @@ define float @test_fcmp_olt_fadd_select_neg_constant(float %in) {
define float @test_fcmp_olt_fadd_select_fastmath_preserve(float %in) {
; CHECK-LABEL: define float @test_fcmp_olt_fadd_select_fastmath_preserve(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp olt float %in, 0.000000e+00
+ %cmp1 = fcmp nnan olt float %in, 0.000000e+00
%add = fadd nnan float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -126,11 +126,11 @@ define float @test_fcmp_olt_fadd_select_fastmath_preserve(float %in) {
define <2 x float> @test_fcmp_olt_fadd_select_constant_vectors(<2 x float> %in) {
; CHECK-LABEL: define <2 x float> @test_fcmp_olt_fadd_select_constant_vectors(
; CHECK-SAME: <2 x float> [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz <2 x float> @llvm.minnum.v2f32(<2 x float> [[IN]], <2 x float> zeroinitializer)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz <2 x float> @llvm.minnum.v2f32(<2 x float> [[IN]], <2 x float> zeroinitializer)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
; CHECK-NEXT: ret <2 x float> [[ADD_NEW]]
;
- %cmp1 = fcmp olt <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
+ %cmp1 = fcmp nnan olt <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
%add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
%sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
ret <2 x float> %sel
@@ -142,11 +142,11 @@ define <2 x float> @test_fcmp_olt_fadd_select_constant_vectors(<2 x float> %in)
define float @test_fcmp_oge_fadd_select_constant(float %in) {
; CHECK-LABEL: define float @test_fcmp_oge_fadd_select_constant(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp oge float %in, 0.000000e+00
+ %cmp1 = fcmp nnan oge float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -155,11 +155,11 @@ define float @test_fcmp_oge_fadd_select_constant(float %in) {
define float @test_fcmp_oge_fadd_select_constant_swapped(float %in) {
; CHECK-LABEL: define float @test_fcmp_oge_fadd_select_constant_swapped(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp oge float %in, 0.000000e+00
+ %cmp1 = fcmp nnan oge float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
ret float %sel
@@ -168,11 +168,11 @@ define float @test_fcmp_oge_fadd_select_constant_swapped(float %in) {
define float @test_fcmp_oge_fadd_select_neg_constant(float %in) {
; CHECK-LABEL: define float @test_fcmp_oge_fadd_select_neg_constant(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp oge float %in, -0.000000e+00
+ %cmp1 = fcmp nnan oge float %in, -0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -181,11 +181,11 @@ define float @test_fcmp_oge_fadd_select_neg_constant(float %in) {
define float @test_fcmp_oge_fadd_select_fastmath_preserve(float %in) {
; CHECK-LABEL: define float @test_fcmp_oge_fadd_select_fastmath_preserve(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp oge float %in, 0.000000e+00
+ %cmp1 = fcmp nnan oge float %in, 0.000000e+00
%add = fadd nnan float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -194,11 +194,11 @@ define float @test_fcmp_oge_fadd_select_fastmath_preserve(float %in) {
define <2 x float> @test_fcmp_oge_fadd_select_constant_vectors(<2 x float> %in) {
; CHECK-LABEL: define <2 x float> @test_fcmp_oge_fadd_select_constant_vectors(
; CHECK-SAME: <2 x float> [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz <2 x float> @llvm.maxnum.v2f32(<2 x float> [[IN]], <2 x float> zeroinitializer)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz <2 x float> @llvm.maxnum.v2f32(<2 x float> [[IN]], <2 x float> zeroinitializer)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
; CHECK-NEXT: ret <2 x float> [[ADD_NEW]]
;
- %cmp1 = fcmp oge <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
+ %cmp1 = fcmp nnan oge <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
%add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
%sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
ret <2 x float> %sel
@@ -210,11 +210,11 @@ define <2 x float> @test_fcmp_oge_fadd_select_constant_vectors(<2 x float> %in)
define float @test_fcmp_ole_fadd_select_constant(float %in) {
; CHECK-LABEL: define float @test_fcmp_ole_fadd_select_constant(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ole float %in, 0.000000e+00
+ %cmp1 = fcmp nnan ole float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -223,11 +223,11 @@ define float @test_fcmp_ole_fadd_select_constant(float %in) {
define float @test_fcmp_ole_fadd_select_constant_swapped(float %in) {
; CHECK-LABEL: define float @test_fcmp_ole_fadd_select_constant_swapped(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ole float %in, 0.000000e+00
+ %cmp1 = fcmp nnan ole float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
ret float %sel
@@ -236,11 +236,11 @@ define float @test_fcmp_ole_fadd_select_constant_swapped(float %in) {
define float @test_fcmp_ole_fadd_select_neg_constant(float %in) {
; CHECK-LABEL: define float @test_fcmp_ole_fadd_select_neg_constant(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ole float %in, -0.000000e+00
+ %cmp1 = fcmp nnan ole float %in, -0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -249,11 +249,11 @@ define float @test_fcmp_ole_fadd_select_neg_constant(float %in) {
define float @test_fcmp_ole_fadd_select_fastmath_preserve(float %in) {
; CHECK-LABEL: define float @test_fcmp_ole_fadd_select_fastmath_preserve(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ole float %in, 0.000000e+00
+ %cmp1 = fcmp nnan ole float %in, 0.000000e+00
%add = fadd nnan float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -262,11 +262,11 @@ define float @test_fcmp_ole_fadd_select_fastmath_preserve(float %in) {
define <2 x float> @test_fcmp_ole_fadd_select_constant_vectors(<2 x float> %in) {
; CHECK-LABEL: define <2 x float> @test_fcmp_ole_fadd_select_constant_vectors(
; CHECK-SAME: <2 x float> [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz <2 x float> @llvm.minnum.v2f32(<2 x float> [[IN]], <2 x float> zeroinitializer)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz <2 x float> @llvm.minnum.v2f32(<2 x float> [[IN]], <2 x float> zeroinitializer)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
; CHECK-NEXT: ret <2 x float> [[ADD_NEW]]
;
- %cmp1 = fcmp ole <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
+ %cmp1 = fcmp nnan ole <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
%add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
%sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
ret <2 x float> %sel
@@ -278,11 +278,11 @@ define <2 x float> @test_fcmp_ole_fadd_select_constant_vectors(<2 x float> %in)
define float @test_fcmp_ugt_fadd_select_constant(float %in) {
; CHECK-LABEL: define float @test_fcmp_ugt_fadd_select_constant(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ugt float %in, 0.000000e+00
+ %cmp1 = fcmp nnan ugt float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -291,11 +291,11 @@ define float @test_fcmp_ugt_fadd_select_constant(float %in) {
define float @test_fcmp_ugt_fadd_select_constant_swapped(float %in) {
; CHECK-LABEL: define float @test_fcmp_ugt_fadd_select_constant_swapped(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ugt float %in, 0.000000e+00
+ %cmp1 = fcmp nnan ugt float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
ret float %sel
@@ -304,11 +304,11 @@ define float @test_fcmp_ugt_fadd_select_constant_swapped(float %in) {
define float @test_fcmp_ugt_fadd_select_neg_constant(float %in) {
; CHECK-LABEL: define float @test_fcmp_ugt_fadd_select_neg_constant(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ugt float %in, -0.000000e+00
+ %cmp1 = fcmp nnan ugt float %in, -0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -317,11 +317,11 @@ define float @test_fcmp_ugt_fadd_select_neg_constant(float %in) {
define float @test_fcmp_ugt_fadd_select_fastmath_preserve(float %in) {
; CHECK-LABEL: define float @test_fcmp_ugt_fadd_select_fastmath_preserve(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ugt float %in, 0.000000e+00
+ %cmp1 = fcmp nnan ugt float %in, 0.000000e+00
%add = fadd nnan float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -330,11 +330,11 @@ define float @test_fcmp_ugt_fadd_select_fastmath_preserve(float %in) {
define <2 x float> @test_fcmp_ugt_fadd_select_constant_vectors(<2 x float> %in) {
; CHECK-LABEL: define <2 x float> @test_fcmp_ugt_fadd_select_constant_vectors(
; CHECK-SAME: <2 x float> [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz <2 x float> @llvm.maxnum.v2f32(<2 x float> [[IN]], <2 x float> zeroinitializer)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz <2 x float> @llvm.maxnum.v2f32(<2 x float> [[IN]], <2 x float> zeroinitializer)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
; CHECK-NEXT: ret <2 x float> [[ADD_NEW]]
;
- %cmp1 = fcmp ugt <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
+ %cmp1 = fcmp nnan ugt <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
%add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
%sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
ret <2 x float> %sel
@@ -346,11 +346,11 @@ define <2 x float> @test_fcmp_ugt_fadd_select_constant_vectors(<2 x float> %in)
define float @test_fcmp_uge_fadd_select_constant(float %in) {
; CHECK-LABEL: define float @test_fcmp_uge_fadd_select_constant(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp uge float %in, 0.000000e+00
+ %cmp1 = fcmp nnan uge float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -359,11 +359,11 @@ define float @test_fcmp_uge_fadd_select_constant(float %in) {
define float @test_fcmp_uge_fadd_select_constant_swapped(float %in) {
; CHECK-LABEL: define float @test_fcmp_uge_fadd_select_constant_swapped(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp uge float %in, 0.000000e+00
+ %cmp1 = fcmp nnan uge float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
ret float %sel
@@ -372,11 +372,11 @@ define float @test_fcmp_uge_fadd_select_constant_swapped(float %in) {
define float @test_fcmp_uge_fadd_select_neg_constant(float %in) {
; CHECK-LABEL: define float @test_fcmp_uge_fadd_select_neg_constant(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp uge float %in, -0.000000e+00
+ %cmp1 = fcmp nnan uge float %in, -0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -385,11 +385,11 @@ define float @test_fcmp_uge_fadd_select_neg_constant(float %in) {
define float @test_fcmp_uge_fadd_select_fastmath_preserve(float %in) {
; CHECK-LABEL: define float @test_fcmp_uge_fadd_select_fastmath_preserve(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp uge float %in, 0.000000e+00
+ %cmp1 = fcmp nnan uge float %in, 0.000000e+00
%add = fadd nnan float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -398,11 +398,11 @@ define float @test_fcmp_uge_fadd_select_fastmath_preserve(float %in) {
define <2 x float> @test_fcmp_uge_fadd_select_constant_vectors(<2 x float> %in) {
; CHECK-LABEL: define <2 x float> @test_fcmp_uge_fadd_select_constant_vectors(
; CHECK-SAME: <2 x float> [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz <2 x float> @llvm.maxnum.v2f32(<2 x float> [[IN]], <2 x float> zeroinitializer)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz <2 x float> @llvm.maxnum.v2f32(<2 x float> [[IN]], <2 x float> zeroinitializer)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
; CHECK-NEXT: ret <2 x float> [[ADD_NEW]]
;
- %cmp1 = fcmp uge <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
+ %cmp1 = fcmp nnan uge <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
%add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
%sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
ret <2 x float> %sel
@@ -414,11 +414,11 @@ define <2 x float> @test_fcmp_uge_fadd_select_constant_vectors(<2 x float> %in)
define float @test_fcmp_ult_fadd_select_constant(float %in) {
; CHECK-LABEL: define float @test_fcmp_ult_fadd_select_constant(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ult float %in, 0.000000e+00
+ %cmp1 = fcmp nnan ult float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -427,11 +427,11 @@ define float @test_fcmp_ult_fadd_select_constant(float %in) {
define float @test_fcmp_ult_fadd_select_constant_swapped(float %in) {
; CHECK-LABEL: define float @test_fcmp_ult_fadd_select_constant_swapped(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ult float %in, 0.000000e+00
+ %cmp1 = fcmp nnan ult float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
ret float %sel
@@ -440,11 +440,11 @@ define float @test_fcmp_ult_fadd_select_constant_swapped(float %in) {
define float @test_fcmp_ult_fadd_select_neg_constant(float %in) {
; CHECK-LABEL: define float @test_fcmp_ult_fadd_select_neg_constant(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ult float %in, -0.000000e+00
+ %cmp1 = fcmp nnan ult float %in, -0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -453,11 +453,11 @@ define float @test_fcmp_ult_fadd_select_neg_constant(float %in) {
define float @test_fcmp_ult_fadd_select_fastmath_preserve(float %in) {
; CHECK-LABEL: define float @test_fcmp_ult_fadd_select_fastmath_preserve(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ult float %in, 0.000000e+00
+ %cmp1 = fcmp nnan ult float %in, 0.000000e+00
%add = fadd nnan float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -466,11 +466,11 @@ define float @test_fcmp_ult_fadd_select_fastmath_preserve(float %in) {
define <2 x float> @test_fcmp_ult_fadd_select_constant_vectors(<2 x float> %in) {
; CHECK-LABEL: define <2 x float> @test_fcmp_ult_fadd_select_constant_vectors(
; CHECK-SAME: <2 x float> [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz <2 x float> @llvm.minnum.v2f32(<2 x float> [[IN]], <2 x float> zeroinitializer)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz <2 x float> @llvm.minnum.v2f32(<2 x float> [[IN]], <2 x float> zeroinitializer)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
; CHECK-NEXT: ret <2 x float> [[ADD_NEW]]
;
- %cmp1 = fcmp ult <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
+ %cmp1 = fcmp nnan ult <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
%add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
%sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
ret <2 x float> %sel
@@ -482,11 +482,11 @@ define <2 x float> @test_fcmp_ult_fadd_select_constant_vectors(<2 x float> %in)
define float @test_fcmp_ule_fadd_select_constant(float %in) {
; CHECK-LABEL: define float @test_fcmp_ule_fadd_select_constant(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ule float %in, 0.000000e+00
+ %cmp1 = fcmp nnan ule float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -495,11 +495,11 @@ define float @test_fcmp_ule_fadd_select_constant(float %in) {
define float @test_fcmp_ule_fadd_select_constant_swapped(float %in) {
; CHECK-LABEL: define float @test_fcmp_ule_fadd_select_constant_swapped(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ule float %in, 0.000000e+00
+ %cmp1 = fcmp nnan ule float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
ret float %sel
@@ -508,11 +508,11 @@ define float @test_fcmp_ule_fadd_select_constant_swapped(float %in) {
define float @test_fcmp_ule_fadd_select_neg_constant(float %in) {
; CHECK-LABEL: define float @test_fcmp_ule_fadd_select_neg_constant(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ule float %in, -0.000000e+00
+ %cmp1 = fcmp nnan ule float %in, -0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -521,11 +521,11 @@ define float @test_fcmp_ule_fadd_select_neg_constant(float %in) {
define float @test_fcmp_ule_fadd_select_fastmath_preserve(float %in) {
; CHECK-LABEL: define float @test_fcmp_ule_fadd_select_fastmath_preserve(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ule float %in, 0.000000e+00
+ %cmp1 = fcmp nnan ule float %in, 0.000000e+00
%add = fadd nnan float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -534,11 +534,11 @@ define float @test_fcmp_ule_fadd_select_fastmath_preserve(float %in) {
define <2 x float> @test_fcmp_ule_fadd_select_constant_vectors(<2 x float> %in) {
; CHECK-LABEL: define <2 x float> @test_fcmp_ule_fadd_select_constant_vectors(
; CHECK-SAME: <2 x float> [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz <2 x float> @llvm.minnum.v2f32(<2 x float> [[IN]], <2 x float> zeroinitializer)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz <2 x float> @llvm.minnum.v2f32(<2 x float> [[IN]], <2 x float> zeroinitializer)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
; CHECK-NEXT: ret <2 x float> [[ADD_NEW]]
;
- %cmp1 = fcmp ule <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
+ %cmp1 = fcmp nnan ule <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
%add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
%sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
ret <2 x float> %sel
@@ -551,27 +551,42 @@ define <2 x float> @test_fcmp_ule_fadd_select_constant_vectors(<2 x float> %in)
define float @test_select_without_nnan_nsz(float %in) {
; CHECK-LABEL: define float @test_select_without_nnan_nsz(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[CMP1:%.*]] = fcmp ogt float [[IN]], 0.000000e+00
+; CHECK-NEXT: [[CMP1:%.*]] = fcmp nnan ogt float [[IN]], 0.000000e+00
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[IN]], 1.000000e+00
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], float [[ADD]], float 1.000000e+00
; CHECK-NEXT: ret float [[SEL]]
;
- %cmp1 = fcmp ogt float %in, 0.000000e+00
+ %cmp1 = fcmp nnan ogt float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
}
+; fcmp instruction doesn't give nnan guarantee.
+define float @test_fcmp_without_nnan_nsz(float %in) {
+; CHECK-LABEL: define float @test_fcmp_without_nnan_nsz(
+; CHECK-SAME: float [[IN:%.*]]) {
+; CHECK-NEXT: [[CMP1:%.*]] = fcmp ogt float [[IN]], 0.000000e+00
+; CHECK-NEXT: [[SEL:%.*]] = select nnan nsz i1 [[CMP1]], float [[IN]], float 0.000000e+00
+; CHECK-NEXT: [[ADD:%.*]] = fadd nnan nsz float [[SEL]], 1.000000e+00
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %cmp1 = fcmp ogt float %in, 0.000000e+00
+ %add = fadd float %in, 1.000000e+00
+ %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
+ ret float %sel
+}
+
; fcmp arg doesn't match with fadd's. This won't be converted to maxnum/minnum.
define float @test_fcmp_fadd_arg_mismatch(float %in, float %in2) {
; CHECK-LABEL: define float @test_fcmp_fadd_arg_mismatch(
; CHECK-SAME: float [[IN:%.*]], float [[IN2:%.*]]) {
-; CHECK-NEXT: [[CMP1:%.*]] = fcmp ogt float [[IN2]], 0.000000e+00
+; CHECK-NEXT: [[CMP1:%.*]] = fcmp nnan ogt float [[IN2]], 0.000000e+00
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[IN]], 1.000000e+00
; CHECK-NEXT: [[SEL:%.*]] = select nnan nsz i1 [[CMP1]], float [[ADD]], float 1.000000e+00
; CHECK-NEXT: ret float [[SEL]]
;
- %cmp1 = fcmp ogt float %in2, 0.000000e+00
+ %cmp1 = fcmp nnan ogt float %in2, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -581,12 +596,12 @@ define float @test_fcmp_fadd_arg_mismatch(float %in, float %in2) {
define float @test_fcmp_arg_non_zero(float %in) {
; CHECK-LABEL: define float @test_fcmp_arg_non_zero(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[CMP1:%.*]] = fcmp ogt float [[IN]], 1.000000e+00
+; CHECK-NEXT: [[CMP1:%.*]] = fcmp nnan ogt float [[IN]], 1.000000e+00
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[IN]], 1.000000e+00
; CHECK-NEXT: [[SEL:%.*]] = select nnan nsz i1 [[CMP1]], float [[ADD]], float 1.000000e+00
; CHECK-NEXT: ret float [[SEL]]
;
- %cmp1 = fcmp ogt float %in, 1.000000e+00
+ %cmp1 = fcmp nnan ogt float %in, 1.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -596,7 +611,7 @@ define float @test_fcmp_arg_non_zero(float %in) {
define float @test_fcmp_multiple_uses(float %in) {
; CHECK-LABEL: define float @test_fcmp_multiple_uses(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[CMP1:%.*]] = fcmp ogt float [[IN]], 0.000000e+00
+; CHECK-NEXT: [[CMP1:%.*]] = fcmp nnan ogt float [[IN]], 0.000000e+00
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[IN]], 1.000000e+00
; CHECK-NEXT: [[ADD_2:%.*]] = fadd float [[IN]], 1.000000e+00
; CHECK-NEXT: [[SEL_1:%.*]] = select nnan nsz i1 [[CMP1]], float [[ADD]], float 1.000000e+00
@@ -604,7 +619,7 @@ define float @test_fcmp_multiple_uses(float %in) {
; CHECK-NEXT: [[RES:%.*]] = fadd float [[SEL_1]], [[SEL_2]]
; CHECK-NEXT: ret float [[RES]]
;
- %cmp1 = fcmp ogt float %in, 0.000000e+00
+ %cmp1 = fcmp nnan ogt float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%add.2 = fadd float %in, 1.000000e+00
%sel.1 = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
@@ -617,11 +632,11 @@ define float @test_fcmp_multiple_uses(float %in) {
define float @test_fcmp_ogt_fadd_select_rewrite_flags1(float %in) {
; CHECK-LABEL: define float @test_fcmp_ogt_fadd_select_rewrite_flags1(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call reassoc nsz arcp contract afn float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call reassoc nnan nsz arcp contract afn float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd reassoc nnan nsz arcp contract afn float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ogt float %in, 0.000000e+00
+ %cmp1 = fcmp nnan ogt float %in, 0.000000e+00
%add = fadd reassoc afn arcp contract float %in, 1.000000e+00
%sel = select nnan nsz reassoc afn arcp contract i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
@@ -630,11 +645,11 @@ define float @test_fcmp_ogt_fadd_select_rewrite_flags1(float %in) {
define float @test_fcmp_ogt_fadd_select_rewrite_flags2(float %in) {
; CHECK-LABEL: define float @test_fcmp_ogt_fadd_select_rewrite_flags2(
; CHECK-SAME: float [[IN:%.*]]) {
-; CHECK-NEXT: [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
+; CHECK-NEXT: [[SEL_NEW:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
- %cmp1 = fcmp ogt float %in, 0.000000e+00
+ %cmp1 = fcmp nnan ogt float %in, 0.000000e+00
%add = fadd reassoc float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
diff --git a/llvm/test/Transforms/InstCombine/fcmp-select.ll b/llvm/test/Transforms/InstCombine/fcmp-select.ll
index bb41f18c74f5f..05d4c1c3b90eb 100644
--- a/llvm/test/Transforms/InstCombine/fcmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp-select.ll
@@ -219,13 +219,13 @@ define double @test_fcmp_select_clamp(double %x) {
define double @test_fcmp_select_maxnum(double %x) {
; CHECK-LABEL: @test_fcmp_select_maxnum(
-; CHECK-NEXT: [[SEL1:%.*]] = call nsz double @llvm.maxnum.f64(double [[X:%.*]], double 1.000000e+00)
-; CHECK-NEXT: [[SEL2:%.*]] = call nsz double @llvm.minnum.f64(double [[SEL1]], double 2.550000e+02)
+; CHECK-NEXT: [[SEL1:%.*]] = call nnan nsz double @llvm.maxnum.f64(double [[X:%.*]], double 1.000000e+00)
+; CHECK-NEXT: [[SEL2:%.*]] = call nnan nsz double @llvm.minnum.f64(double [[SEL1]], double 2.550000e+02)
; CHECK-NEXT: ret double [[SEL2]]
;
- %cmp1 = fcmp ogt double %x, 1.0
+ %cmp1 = fcmp nnan ogt double %x, 1.0
%sel1 = select nnan nsz i1 %cmp1, double %x, double 1.0
- %cmp2 = fcmp olt double %sel1, 255.0
+ %cmp2 = fcmp nnan olt double %sel1, 255.0
%sel2 = select nnan nsz i1 %cmp2, double %sel1, double 255.0
ret double %sel2
}
diff --git a/llvm/test/Transforms/InstCombine/fmul-bool.ll b/llvm/test/Transforms/InstCombine/fmul-bool.ll
index 263ca539669bb..a686801e50352 100644
--- a/llvm/test/Transforms/InstCombine/fmul-bool.ll
+++ b/llvm/test/Transforms/InstCombine/fmul-bool.ll
@@ -1,10 +1,12 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
; X * Y (when Y is a boolean) --> Y ? X : 0
define float @fmul_bool(float %x, i1 %y) {
-; CHECK-LABEL: @fmul_bool(
-; CHECK-NEXT: [[M:%.*]] = select nnan nsz i1 [[Y:%.*]], float [[X:%.*]], float 0.000000e+00
+; CHECK-LABEL: define float @fmul_bool(
+; CHECK-SAME: float [[X:%.*]], i1 [[Y:%.*]]) {
+; CHECK-NEXT: [[M:%.*]] = select nnan nsz i1 [[Y]], float [[X]], float 0.000000e+00
; CHECK-NEXT: ret float [[M]]
;
%z = uitofp i1 %y to float
@@ -13,8 +15,9 @@ define float @fmul_bool(float %x, i1 %y) {
}
define <2 x float> @fmul_bool_vec(<2 x float> %x, <2 x i1> %y) {
-; CHECK-LABEL: @fmul_bool_vec(
-; CHECK-NEXT: [[M:%.*]] = select nnan nsz <2 x i1> [[Y:%.*]], <2 x float> [[X:%.*]], <2 x float> zeroinitializer
+; CHECK-LABEL: define <2 x float> @fmul_bool_vec(
+; CHECK-SAME: <2 x float> [[X:%.*]], <2 x i1> [[Y:%.*]]) {
+; CHECK-NEXT: [[M:%.*]] = select nnan nsz <2 x i1> [[Y]], <2 x float> [[X]], <2 x float> zeroinitializer
; CHECK-NEXT: ret <2 x float> [[M]]
;
%z = uitofp <2 x i1> %y to <2 x float>
@@ -23,9 +26,10 @@ define <2 x float> @fmul_bool_vec(<2 x float> %x, <2 x i1> %y) {
}
define <2 x float> @fmul_bool_vec_commute(<2 x float> %px, <2 x i1> %y) {
-; CHECK-LABEL: @fmul_bool_vec_commute(
-; CHECK-NEXT: [[X:%.*]] = fmul nnan nsz <2 x float> [[PX:%.*]], [[PX]]
-; CHECK-NEXT: [[M:%.*]] = select nnan nsz <2 x i1> [[Y:%.*]], <2 x float> [[X]], <2 x float> zeroinitializer
+; CHECK-LABEL: define <2 x float> @fmul_bool_vec_commute(
+; CHECK-SAME: <2 x float> [[PX:%.*]], <2 x i1> [[Y:%.*]]) {
+; CHECK-NEXT: [[X:%.*]] = fmul nnan nsz <2 x float> [[PX]], [[PX]]
+; CHECK-NEXT: [[M:%.*]] = select nnan nsz <2 x i1> [[Y]], <2 x float> [[X]], <2 x float> zeroinitializer
; CHECK-NEXT: ret <2 x float> [[M]]
;
%x = fmul nnan nsz <2 x float> %px, %px ; thwart complexity-based canonicalization
diff --git a/llvm/test/Transforms/InstCombine/fneg.ll b/llvm/test/Transforms/InstCombine/fneg.ll
index 39117f56fa4e1..4e6477f804314 100644
--- a/llvm/test/Transforms/InstCombine/fneg.ll
+++ b/llvm/test/Transforms/InstCombine/fneg.ll
@@ -1100,11 +1100,11 @@ define float @test_fneg_select_constant_var_multiuse(i1 %cond, float %x) {
define float @test_fneg_select_maxnum(float %x) {
; CHECK-LABEL: @test_fneg_select_maxnum(
-; CHECK-NEXT: [[SEL1:%.*]] = call nsz float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
+; CHECK-NEXT: [[SEL1:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
; CHECK-NEXT: [[NEG:%.*]] = fneg float [[SEL1]]
; CHECK-NEXT: ret float [[NEG]]
;
- %cmp1 = fcmp ogt float %x, 1.0
+ %cmp1 = fcmp nnan ogt float %x, 1.0
%sel1 = select nnan nsz i1 %cmp1, float %x, float 1.0
%neg = fneg float %sel1
ret float %neg
diff --git a/llvm/test/Transforms/InstCombine/minmax-fp.ll b/llvm/test/Transforms/InstCombine/minmax-fp.ll
index b0af1c7b89838..fb0d52e2a26d8 100644
--- a/llvm/test/Transforms/InstCombine/minmax-fp.ll
+++ b/llvm/test/Transforms/InstCombine/minmax-fp.ll
@@ -322,20 +322,20 @@ define double @fneg_fmin(double %x, double %y) {
define float @maxnum_ogt_fmf_on_select(float %a, float %b) {
; CHECK-LABEL: @maxnum_ogt_fmf_on_select(
-; CHECK-NEXT: [[F:%.*]] = call nsz float @llvm.maxnum.f32(float [[A:%.*]], float [[B:%.*]])
+; CHECK-NEXT: [[F:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[A:%.*]], float [[B:%.*]])
; CHECK-NEXT: ret float [[F]]
;
- %cond = fcmp ogt float %a, %b
+ %cond = fcmp nnan ogt float %a, %b
%f = select nnan nsz i1 %cond, float %a, float %b
ret float %f
}
define <2 x float> @maxnum_oge_fmf_on_select(<2 x float> %a, <2 x float> %b) {
; CHECK-LABEL: @maxnum_oge_fmf_on_select(
-; CHECK-NEXT: [[F:%.*]] = call nsz <2 x float> @llvm.maxnum.v2f32(<2 x float> [[A:%.*]], <2 x float> [[B:%.*]])
+; CHECK-NEXT: [[F:%.*]] = call nnan nsz <2 x float> @llvm.maxnum.v2f32(<2 x float> [[A:%.*]], <2 x float> [[B:%.*]])
; CHECK-NEXT: ret <2 x float> [[F]]
;
- %cond = fcmp oge <2 x float> %a, %b
+ %cond = fcmp nnan oge <2 x float> %a, %b
%f = select ninf nnan nsz <2 x i1> %cond, <2 x float> %a, <2 x float> %b
ret <2 x float> %f
}
@@ -386,30 +386,30 @@ define float @maxnum_no_nnan(float %a, float %b) {
define float @minnum_olt_fmf_on_select_both_ninf(float %a, float %b) {
; CHECK-LABEL: @minnum_olt_fmf_on_select_both_ninf(
-; CHECK-NEXT: [[F:%.*]] = call ninf nsz float @llvm.minnum.f32(float [[A:%.*]], float [[B:%.*]])
+; CHECK-NEXT: [[F:%.*]] = call nnan ninf nsz float @llvm.minnum.f32(float [[A:%.*]], float [[B:%.*]])
; CHECK-NEXT: ret float [[F]]
;
- %cond = fcmp ninf olt float %a, %b
+ %cond = fcmp nnan ninf olt float %a, %b
%f = select nnan ninf nsz i1 %cond, float %a, float %b
ret float %f
}
define float @minnum_olt_fmf_on_select(float %a, float %b) {
; CHECK-LABEL: @minnum_olt_fmf_on_select(
-; CHECK-NEXT: [[F:%.*]] = call nsz float @llvm.minnum.f32(float [[A:%.*]], float [[B:%.*]])
+; CHECK-NEXT: [[F:%.*]] = call nnan nsz float @llvm.minnum.f32(float [[A:%.*]], float [[B:%.*]])
; CHECK-NEXT: ret float [[F]]
;
- %cond = fcmp olt float %a, %b
+ %cond = fcmp nnan olt float %a, %b
%f = select nnan nsz i1 %cond, float %a, float %b
ret float %f
}
define <2 x float> @minnum_ole_fmf_on_select(<2 x float> %a, <2 x float> %b) {
; CHECK-LABEL: @minnum_ole_fmf_on_select(
-; CHECK-NEXT: [[F:%.*]] = call nsz <2 x float> @llvm.minnum.v2f32(<2 x float> [[A:%.*]], <2 x float> [[B:%.*]])
+; CHECK-NEXT: [[F:%.*]] = call nnan nsz <2 x float> @llvm.minnum.v2f32(<2 x float> [[A:%.*]], <2 x float> [[B:%.*]])
; CHECK-NEXT: ret <2 x float> [[F]]
;
- %cond = fcmp ole <2 x float> %a, %b
+ %cond = fcmp nnan ole <2 x float> %a, %b
%f = select ninf nnan nsz <2 x i1> %cond, <2 x float> %a, <2 x float> %b
ret <2 x float> %f
}
diff --git a/llvm/test/Transforms/InstCombine/select_meta.ll b/llvm/test/Transforms/InstCombine/select_meta.ll
index f22b5a4fd3c5f..601870493d92e 100644
--- a/llvm/test/Transforms/InstCombine/select_meta.ll
+++ b/llvm/test/Transforms/InstCombine/select_meta.ll
@@ -386,7 +386,8 @@ define <2 x float> @select_fdiv(i1 %cond, <2 x float> %x, <2 x float> %y) {
;.
; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind }
-; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
+; CHECK: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
;.
; CHECK: [[PROF0]] = !{!"branch_weights", i32 2, i32 10}
; CHECK: [[PROF1]] = !{!"branch_weights", i32 10, i32 2}
diff --git a/llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll b/llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll
index ad86f2ed2fa59..a7267851ea011 100644
--- a/llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll
@@ -36,10 +36,10 @@ define float @select_min_ugt(float %a, float %b) {
define float @select_min_uge(float %a, float %b) {
; CHECK-LABEL: @select_min_uge(
-; CHECK-NEXT: [[SEL:%.*]] = call reassoc nsz arcp contract afn float @llvm.minnum.f32(float [[A:%.*]], float [[B:%.*]])
+; CHECK-NEXT: [[SEL:%.*]] = call reassoc nnan nsz arcp contract afn float @llvm.minnum.f32(float [[A:%.*]], float [[B:%.*]])
; CHECK-NEXT: ret float [[SEL]]
;
- %cmp = fcmp nsz uge float %a, %b
+ %cmp = fcmp nnan nsz uge float %a, %b
%sel = select fast i1 %cmp, float %b, float %a
ret float %sel
}
@@ -67,10 +67,10 @@ define float @select_max_ule(float %a, float %b) {
define float @select_min_ult(float %a, float %b) {
; CHECK-LABEL: @select_min_ult(
-; CHECK-NEXT: [[SEL:%.*]] = call reassoc nsz arcp contract afn float @llvm.minnum.f32(float [[A:%.*]], float [[B:%.*]])
+; CHECK-NEXT: [[SEL:%.*]] = call reassoc nnan nsz arcp contract afn float @llvm.minnum.f32(float [[A:%.*]], float [[B:%.*]])
; CHECK-NEXT: ret float [[SEL]]
;
- %cmp = fcmp nsz ult float %a, %b
+ %cmp = fcmp nnan nsz ult float %a, %b
%sel = select fast i1 %cmp, float %a, float %b
ret float %sel
}
@@ -114,7 +114,7 @@ define float @select_max_ugt_2_use_cmp(float %a, float %b) {
; CHECK-LABEL: @select_max_ugt_2_use_cmp(
; CHECK-NEXT: [[CMP:%.*]] = fcmp reassoc ugt float [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: call void @foo(i1 [[CMP]])
-; CHECK-NEXT: [[SEL:%.*]] = call reassoc nsz arcp contract afn float @llvm.maxnum.f32(float [[A]], float [[B]])
+; CHECK-NEXT: [[SEL:%.*]] = select fast i1 [[CMP]], float [[A]], float [[B]]
; CHECK-NEXT: ret float [[SEL]]
;
%cmp = fcmp reassoc ugt float %a, %b
>From a00e34d22e6a6139b362887b6e1998202271af53 Mon Sep 17 00:00:00 2001
From: valadaptive <valadaptive at protonmail.com>
Date: Sat, 24 Jan 2026 22:33:39 -0500
Subject: [PATCH 2/5] [InstCombine] Always add nsz to generated minnum/maxnum
---
llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | 5 +++++
llvm/test/Transforms/InstCombine/minmax-fp.ll | 4 ++--
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 64d629ad4ab1c..521ab4bd8710c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -4381,6 +4381,10 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
Builder.CreateBinaryIntrinsic(Intrinsic::maxnum, X, Y, &SI);
if (auto *BinIntrInst = dyn_cast<Instruction>(BinIntr)) {
BinIntrInst->setHasNoInfs(FCmp->hasNoInfs());
+ // If we're flowing into a use which doesn't care about the sign bit
+ // of zero, ensure the nsz flag is added to the min/max operation,
+ // even if it wasn't on the select.
+ BinIntrInst->setHasNoSignedZeros(true);
}
return replaceInstUsesWith(SI, BinIntr);
}
@@ -4390,6 +4394,7 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
Builder.CreateBinaryIntrinsic(Intrinsic::minnum, X, Y, &SI);
if (auto *BinIntrInst = dyn_cast<Instruction>(BinIntr)) {
BinIntrInst->setHasNoInfs(FCmp->hasNoInfs());
+ BinIntrInst->setHasNoSignedZeros(true);
}
return replaceInstUsesWith(SI, BinIntr);
}
diff --git a/llvm/test/Transforms/InstCombine/minmax-fp.ll b/llvm/test/Transforms/InstCombine/minmax-fp.ll
index fb0d52e2a26d8..34498a8a39019 100644
--- a/llvm/test/Transforms/InstCombine/minmax-fp.ll
+++ b/llvm/test/Transforms/InstCombine/minmax-fp.ll
@@ -160,7 +160,7 @@ define i8 @t9(float %a) {
; Either operand could be NaN, but fast modifier applied.
define i8 @t11(float %a, float %b) {
; CHECK-LABEL: @t11(
-; CHECK-NEXT: [[DOTV:%.*]] = call nnan ninf float @llvm.minnum.f32(float [[B:%.*]], float [[A:%.*]])
+; CHECK-NEXT: [[DOTV:%.*]] = call nnan ninf nsz float @llvm.minnum.f32(float [[B:%.*]], float [[A:%.*]])
; CHECK-NEXT: [[TMP1:%.*]] = fptosi float [[DOTV]] to i8
; CHECK-NEXT: ret i8 [[TMP1]]
;
@@ -174,7 +174,7 @@ define i8 @t11(float %a, float %b) {
; Either operand could be NaN, but nnan modifier applied.
define i8 @t12(float %a, float %b) {
; CHECK-LABEL: @t12(
-; CHECK-NEXT: [[DOTV:%.*]] = call nnan float @llvm.minnum.f32(float [[B:%.*]], float [[A:%.*]])
+; CHECK-NEXT: [[DOTV:%.*]] = call nnan nsz float @llvm.minnum.f32(float [[B:%.*]], float [[A:%.*]])
; CHECK-NEXT: [[TMP1:%.*]] = fptosi float [[DOTV]] to i8
; CHECK-NEXT: ret i8 [[TMP1]]
;
>From d29bb581370a1f638daa801087b5c6c0c0944418 Mon Sep 17 00:00:00 2001
From: valadaptive <valadaptive at protonmail.com>
Date: Sun, 25 Jan 2026 00:44:39 -0500
Subject: [PATCH 3/5] [InstCombine] Fix a test case
---
llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll b/llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll
index a7267851ea011..8afcaa1c1a822 100644
--- a/llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll
@@ -112,12 +112,12 @@ declare void @foo(i1)
define float @select_max_ugt_2_use_cmp(float %a, float %b) {
; CHECK-LABEL: @select_max_ugt_2_use_cmp(
-; CHECK-NEXT: [[CMP:%.*]] = fcmp reassoc ugt float [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[CMP:%.*]] = fcmp reassoc nnan ugt float [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: call void @foo(i1 [[CMP]])
-; CHECK-NEXT: [[SEL:%.*]] = select fast i1 [[CMP]], float [[A]], float [[B]]
+; CHECK-NEXT: [[SEL:%.*]] = call reassoc nnan nsz arcp contract afn float @llvm.maxnum.f32(float [[A]], float [[B]])
; CHECK-NEXT: ret float [[SEL]]
;
- %cmp = fcmp reassoc ugt float %a, %b
+ %cmp = fcmp nnan reassoc ugt float %a, %b
call void @foo(i1 %cmp)
%sel = select fast i1 %cmp, float %a, float %b
ret float %sel
>From d9df7da7e26e76481ee326a23d33ee930a601aae Mon Sep 17 00:00:00 2001
From: valadaptive <valadaptive at protonmail.com>
Date: Sun, 25 Jan 2026 00:45:46 -0500
Subject: [PATCH 4/5] [InstCombine] Revert irrelevant test changes
---
llvm/test/Transforms/InstCombine/fmul-bool.ll | 18 +++++++-----------
.../test/Transforms/InstCombine/select_meta.ll | 3 +--
2 files changed, 8 insertions(+), 13 deletions(-)
diff --git a/llvm/test/Transforms/InstCombine/fmul-bool.ll b/llvm/test/Transforms/InstCombine/fmul-bool.ll
index a686801e50352..263ca539669bb 100644
--- a/llvm/test/Transforms/InstCombine/fmul-bool.ll
+++ b/llvm/test/Transforms/InstCombine/fmul-bool.ll
@@ -1,12 +1,10 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
; X * Y (when Y is a boolean) --> Y ? X : 0
define float @fmul_bool(float %x, i1 %y) {
-; CHECK-LABEL: define float @fmul_bool(
-; CHECK-SAME: float [[X:%.*]], i1 [[Y:%.*]]) {
-; CHECK-NEXT: [[M:%.*]] = select nnan nsz i1 [[Y]], float [[X]], float 0.000000e+00
+; CHECK-LABEL: @fmul_bool(
+; CHECK-NEXT: [[M:%.*]] = select nnan nsz i1 [[Y:%.*]], float [[X:%.*]], float 0.000000e+00
; CHECK-NEXT: ret float [[M]]
;
%z = uitofp i1 %y to float
@@ -15,9 +13,8 @@ define float @fmul_bool(float %x, i1 %y) {
}
define <2 x float> @fmul_bool_vec(<2 x float> %x, <2 x i1> %y) {
-; CHECK-LABEL: define <2 x float> @fmul_bool_vec(
-; CHECK-SAME: <2 x float> [[X:%.*]], <2 x i1> [[Y:%.*]]) {
-; CHECK-NEXT: [[M:%.*]] = select nnan nsz <2 x i1> [[Y]], <2 x float> [[X]], <2 x float> zeroinitializer
+; CHECK-LABEL: @fmul_bool_vec(
+; CHECK-NEXT: [[M:%.*]] = select nnan nsz <2 x i1> [[Y:%.*]], <2 x float> [[X:%.*]], <2 x float> zeroinitializer
; CHECK-NEXT: ret <2 x float> [[M]]
;
%z = uitofp <2 x i1> %y to <2 x float>
@@ -26,10 +23,9 @@ define <2 x float> @fmul_bool_vec(<2 x float> %x, <2 x i1> %y) {
}
define <2 x float> @fmul_bool_vec_commute(<2 x float> %px, <2 x i1> %y) {
-; CHECK-LABEL: define <2 x float> @fmul_bool_vec_commute(
-; CHECK-SAME: <2 x float> [[PX:%.*]], <2 x i1> [[Y:%.*]]) {
-; CHECK-NEXT: [[X:%.*]] = fmul nnan nsz <2 x float> [[PX]], [[PX]]
-; CHECK-NEXT: [[M:%.*]] = select nnan nsz <2 x i1> [[Y]], <2 x float> [[X]], <2 x float> zeroinitializer
+; CHECK-LABEL: @fmul_bool_vec_commute(
+; CHECK-NEXT: [[X:%.*]] = fmul nnan nsz <2 x float> [[PX:%.*]], [[PX]]
+; CHECK-NEXT: [[M:%.*]] = select nnan nsz <2 x i1> [[Y:%.*]], <2 x float> [[X]], <2 x float> zeroinitializer
; CHECK-NEXT: ret <2 x float> [[M]]
;
%x = fmul nnan nsz <2 x float> %px, %px ; thwart complexity-based canonicalization
diff --git a/llvm/test/Transforms/InstCombine/select_meta.ll b/llvm/test/Transforms/InstCombine/select_meta.ll
index 601870493d92e..f22b5a4fd3c5f 100644
--- a/llvm/test/Transforms/InstCombine/select_meta.ll
+++ b/llvm/test/Transforms/InstCombine/select_meta.ll
@@ -386,8 +386,7 @@ define <2 x float> @select_fdiv(i1 %cond, <2 x float> %x, <2 x float> %y) {
;.
; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind }
-; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
-; CHECK: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
;.
; CHECK: [[PROF0]] = !{!"branch_weights", i32 2, i32 10}
; CHECK: [[PROF1]] = !{!"branch_weights", i32 10, i32 2}
>From 82bf42340beb8276f94f5f64fa647021771bc023 Mon Sep 17 00:00:00 2001
From: valadaptive <valadaptive at protonmail.com>
Date: Sun, 25 Jan 2026 15:28:16 -0500
Subject: [PATCH 5/5] [InstCombine] Only require nnan on fcmp
---
.../InstCombine/InstCombineSelect.cpp | 43 +++++++++++--------
.../Transforms/InstCombine/fcmp-select.ll | 4 +-
llvm/test/Transforms/InstCombine/minmax-fp.ll | 26 +++++------
3 files changed, 40 insertions(+), 33 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 521ab4bd8710c..00f4118d538d8 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -4357,21 +4357,20 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
// Canonicalize select of FP values where NaN and -0.0 are not valid as
// minnum/maxnum intrinsics.
- if (FCmp && SIFPOp->hasNoNaNs() &&
- // In order to preserve the nnan flag on the generated intrinsic call,
- // the nnan flag must be present on both the compare *and* the select
- // (for poison propagation reasons).
- //
- // Some targets don't have a floating point minimum/maximum instruction
- // with the same semantics as our minnum/maxnum intrinsics. If the
- // nnan+nsz flags are present on the intrinsic call, those targets can
- // lower it to a select, or to a simpler instruction. If either flag is
- // absent then they must lower it to a routine, or even worse, a
- // libcall. That makes things way slower, and there are other reasons to
- // avoid introducing libcalls where none previously existed (see
- // https://github.com/llvm/llvm-project/issues/54554). So, if we can't
- // preserve the nnan flag, don't bother with the transformation.
- FCmp->hasNoNaNs() &&
+ //
+ // Note that the `nnan` flag is propagated from the comparison, not from the
+ // select. While it's technically possible to transform a `fcmp` + `select
+ // nnan` to a `minnum`/`maxnum` call *without* an `nnan`, that would be a
+ // pessimization in practice. Many targets can't map `minnum`/`maxnum` to a
+ // single instruction, and if they cannot prove the absence of NaN, must
+ // lower it to a routine or a libcall. There are additional reasons besides
+ // performance to avoid introducing libcalls where none existed before
+ // (https://github.com/llvm/llvm-project/issues/54554).
+ //
+ // As such, we want to ensure that the generated `minnum`/`maxnum` intrinsic
+ // has the `nnan nsz` flags, which allow it to be lowered *back* to a
+ // fcmp+select if that's the best way to express it on the target.
+ if (FCmp && FCmp->hasNoNaNs() &&
(SIFPOp->hasNoSignedZeros() ||
(SIFPOp->hasOneUse() &&
canIgnoreSignBitOfZero(*SIFPOp->use_begin())))) {
@@ -4380,11 +4379,18 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
Value *BinIntr =
Builder.CreateBinaryIntrinsic(Intrinsic::maxnum, X, Y, &SI);
if (auto *BinIntrInst = dyn_cast<Instruction>(BinIntr)) {
+ // `ninf` must be propagated from the comparison too, rather than the
+ // select: https://github.com/llvm/llvm-project/pull/136433
BinIntrInst->setHasNoInfs(FCmp->hasNoInfs());
- // If we're flowing into a use which doesn't care about the sign bit
- // of zero, ensure the nsz flag is added to the min/max operation,
- // even if it wasn't on the select.
+ // The `nsz` flag is a precondition, so let's ensure it's always added
+ // to the min/max operation, even if it wasn't on the select. This
+ // could happen if `canIgnoreSignBitOfZero` is true--for instance, if
+ // the select doesn't have `nsz`, but the result is being used in an
+ // operation that doesn't care about signed zero.
BinIntrInst->setHasNoSignedZeros(true);
+ // As mentioned above, `nnan` is also a precondition, so we always set
+ // the flag.
+ BinIntrInst->setHasNoNaNs(true);
}
return replaceInstUsesWith(SI, BinIntr);
}
@@ -4395,6 +4401,7 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
if (auto *BinIntrInst = dyn_cast<Instruction>(BinIntr)) {
BinIntrInst->setHasNoInfs(FCmp->hasNoInfs());
BinIntrInst->setHasNoSignedZeros(true);
+ BinIntrInst->setHasNoNaNs(true);
}
return replaceInstUsesWith(SI, BinIntr);
}
diff --git a/llvm/test/Transforms/InstCombine/fcmp-select.ll b/llvm/test/Transforms/InstCombine/fcmp-select.ll
index 05d4c1c3b90eb..268cd4675c6cc 100644
--- a/llvm/test/Transforms/InstCombine/fcmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp-select.ll
@@ -224,9 +224,9 @@ define double @test_fcmp_select_maxnum(double %x) {
; CHECK-NEXT: ret double [[SEL2]]
;
%cmp1 = fcmp nnan ogt double %x, 1.0
- %sel1 = select nnan nsz i1 %cmp1, double %x, double 1.0
+ %sel1 = select nsz i1 %cmp1, double %x, double 1.0
%cmp2 = fcmp nnan olt double %sel1, 255.0
- %sel2 = select nnan nsz i1 %cmp2, double %sel1, double 255.0
+ %sel2 = select nsz i1 %cmp2, double %sel1, double 255.0
ret double %sel2
}
diff --git a/llvm/test/Transforms/InstCombine/minmax-fp.ll b/llvm/test/Transforms/InstCombine/minmax-fp.ll
index 34498a8a39019..15fc42f4bc97a 100644
--- a/llvm/test/Transforms/InstCombine/minmax-fp.ll
+++ b/llvm/test/Transforms/InstCombine/minmax-fp.ll
@@ -326,7 +326,7 @@ define float @maxnum_ogt_fmf_on_select(float %a, float %b) {
; CHECK-NEXT: ret float [[F]]
;
%cond = fcmp nnan ogt float %a, %b
- %f = select nnan nsz i1 %cond, float %a, float %b
+ %f = select nsz i1 %cond, float %a, float %b
ret float %f
}
@@ -336,7 +336,7 @@ define <2 x float> @maxnum_oge_fmf_on_select(<2 x float> %a, <2 x float> %b) {
; CHECK-NEXT: ret <2 x float> [[F]]
;
%cond = fcmp nnan oge <2 x float> %a, %b
- %f = select ninf nnan nsz <2 x i1> %cond, <2 x float> %a, <2 x float> %b
+ %f = select nsz <2 x i1> %cond, <2 x float> %a, <2 x float> %b
ret <2 x float> %f
}
@@ -364,12 +364,12 @@ define <2 x float> @maxnum_oge_fmf_on_fcmp(<2 x float> %a, <2 x float> %b) {
define float @maxnum_no_nsz(float %a, float %b) {
; CHECK-LABEL: @maxnum_no_nsz(
-; CHECK-NEXT: [[COND:%.*]] = fcmp ogt float [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[F:%.*]] = select nnan i1 [[COND]], float [[A]], float [[B]]
+; CHECK-NEXT: [[COND:%.*]] = fcmp nnan ogt float [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[F:%.*]] = select i1 [[COND]], float [[A]], float [[B]]
; CHECK-NEXT: ret float [[F]]
;
- %cond = fcmp ogt float %a, %b
- %f = select nnan i1 %cond, float %a, float %b
+ %cond = fcmp nnan ogt float %a, %b
+ %f = select i1 %cond, float %a, float %b
ret float %f
}
@@ -390,7 +390,7 @@ define float @minnum_olt_fmf_on_select_both_ninf(float %a, float %b) {
; CHECK-NEXT: ret float [[F]]
;
%cond = fcmp nnan ninf olt float %a, %b
- %f = select nnan ninf nsz i1 %cond, float %a, float %b
+ %f = select ninf nsz i1 %cond, float %a, float %b
ret float %f
}
@@ -400,7 +400,7 @@ define float @minnum_olt_fmf_on_select(float %a, float %b) {
; CHECK-NEXT: ret float [[F]]
;
%cond = fcmp nnan olt float %a, %b
- %f = select nnan nsz i1 %cond, float %a, float %b
+ %f = select nsz i1 %cond, float %a, float %b
ret float %f
}
@@ -410,7 +410,7 @@ define <2 x float> @minnum_ole_fmf_on_select(<2 x float> %a, <2 x float> %b) {
; CHECK-NEXT: ret <2 x float> [[F]]
;
%cond = fcmp nnan ole <2 x float> %a, %b
- %f = select ninf nnan nsz <2 x i1> %cond, <2 x float> %a, <2 x float> %b
+ %f = select ninf nsz <2 x i1> %cond, <2 x float> %a, <2 x float> %b
ret <2 x float> %f
}
@@ -438,12 +438,12 @@ define <2 x float> @minnum_ole_fmf_on_fcmp(<2 x float> %a, <2 x float> %b) {
define float @minnum_no_nsz(float %a, float %b) {
; CHECK-LABEL: @minnum_no_nsz(
-; CHECK-NEXT: [[COND:%.*]] = fcmp olt float [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[F:%.*]] = select nnan i1 [[COND]], float [[A]], float [[B]]
+; CHECK-NEXT: [[COND:%.*]] = fcmp nnan olt float [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[F:%.*]] = select i1 [[COND]], float [[A]], float [[B]]
; CHECK-NEXT: ret float [[F]]
;
- %cond = fcmp olt float %a, %b
- %f = select nnan i1 %cond, float %a, float %b
+ %cond = fcmp nnan olt float %a, %b
+ %f = select i1 %cond, float %a, float %b
ret float %f
}
More information about the llvm-commits
mailing list