[llvm] InstCombine: Add baseline tests for broken snan handling (PR #179243)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 2 06:48:50 PST 2026


https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/179243

SimplifyDemandedFPClass doesn't correctly account for possible
quieting in all cases.

>From 742d87b2ed1d35f055e577e2870dbb10b5f95318 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Mon, 2 Feb 2026 15:18:01 +0100
Subject: [PATCH] InstCombine: Add baseline tests for broken snan handling

SimplifyDemandedFPClass doesn't correctly account for possible
quieting in all cases.
---
 .../simplify-demanded-fpclass-canonicalize.ll | 14 +++
 .../simplify-demanded-fpclass-exp.ll          | 15 +++
 .../simplify-demanded-fpclass-fadd.ll         | 43 +++++++++
 .../simplify-demanded-fpclass-fdiv.ll         | 27 ++++++
 .../simplify-demanded-fpclass-fma.ll          | 63 ++++++++++++-
 .../simplify-demanded-fpclass-fmul.ll         | 40 ++++++++
 .../simplify-demanded-fpclass-fpext.ll        | 14 +++
 ...simplify-demanded-fpclass-fptrunc-round.ll | 14 +++
 .../simplify-demanded-fpclass-fptrunc.ll      | 14 +++
 .../simplify-demanded-fpclass-frexp.ll        | 14 +++
 .../simplify-demanded-fpclass-fsub.ll         | 29 ++++++
 .../simplify-demanded-fpclass-log.ll          | 15 +++
 .../simplify-demanded-fpclass-maximum.ll      | 27 ++++++
 .../simplify-demanded-fpclass-maximumnum.ll   | 29 ++++++
 .../simplify-demanded-fpclass-maxnum.ll       | 29 ++++++
 .../simplify-demanded-fpclass-minimum.ll      | 28 ++++++
 .../simplify-demanded-fpclass-minimumnum.ll   | 29 ++++++
 .../simplify-demanded-fpclass-minnum.ll       | 29 ++++++
 ...fy-demanded-fpclass-rounding-intrinsics.ll | 93 +++++++++++++++++++
 .../simplify-demanded-fpclass-sqrt.ll         | 15 ++-
 20 files changed, 579 insertions(+), 2 deletions(-)

diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-canonicalize.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-canonicalize.ll
index 4cd51c8b36f46..ffc8a4438cddd 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-canonicalize.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-canonicalize.ll
@@ -586,6 +586,20 @@ define nofpclass(nan) float @ret_nofpclass_nan__canonicalize_drop_noundef(float
   ret float %canon
 }
 
+define nofpclass(snan) float @qnan_result_demands_snan_src(i1 %cond, float %unknown) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_src(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[SNAN]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.canonicalize.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown
+  %result = call float @llvm.canonicalize.f32(float %select)
+  ret float %result
+}
+
 attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }
 attributes #1 = { "denormal-fp-math"="dynamic,dynamic" }
 attributes #2 = { "denormal-fp-math"="positive-zero,positive-zero" }
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-exp.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-exp.ll
index f3c8abddda115..3569bd8db4325 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-exp.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-exp.ll
@@ -1,6 +1,8 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 6
 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
 
+declare nofpclass(qnan inf norm sub zero) float @returns_snan()
+
 define nofpclass(pinf) float @ret_nofpclass_pinf__exp2_select_maybe_inf_or_not_pinf(i1 %cond, float %maybe.inf, float nofpclass(pinf) %not.pinf) {
 ; CHECK-LABEL: define nofpclass(pinf) float @ret_nofpclass_pinf__exp2_select_maybe_inf_or_not_pinf(
 ; CHECK-SAME: i1 [[COND:%.*]], float [[MAYBE_INF:%.*]], float nofpclass(pinf) [[NOT_PINF:%.*]]) {
@@ -603,6 +605,19 @@ define nofpclass(nan inf) float @ret_no_inf_no_nan__exp__no_inf(float nofpclass(
   ret float %exp
 }
 
+define nofpclass(snan) float @qnan_result_demands_snan_src(i1 %cond, float %unknown) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_src(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.exp.f32(float [[UNKNOWN]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown
+  %result = call float @llvm.exp.f32(float %select)
+  ret float %result
+}
+
 !0 = !{!"function_entry_count", i64 1000}
 ;.
 ; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fadd.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fadd.ll
index ea75dcd33c9c4..7f69b15c96b16 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fadd.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fadd.ll
@@ -20,6 +20,7 @@ declare nofpclass(nan ninf nzero nsub nnorm) half @returns_positive()
 declare nofpclass(nan pinf pzero psub pnorm) half @returns_negative()
 
 declare nofpclass(inf zero sub norm) half @returns_nan()
+declare nofpclass(qnan inf zero sub norm) half @returns_snan()
 
 declare nofpclass(nan inf zero sub) half @returns_norm()
 declare nofpclass(nan inf zero sub pnorm) half @returns_nnorm()
@@ -2043,6 +2044,48 @@ define nofpclass(snan) half @inf_or_nan__fadd__not_nan(half nofpclass(nan) %not.
   ret half %result
 }
 
+define nofpclass(snan) half @qnan_result_self_demands_snan(i1 noundef %cond, half noundef %unknown) {
+; CHECK-LABEL: define nofpclass(snan) half @qnan_result_self_demands_snan(
+; CHECK-SAME: i1 noundef [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call noundef half @returns_snan()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], half [[SNAN]], half [[UNKNOWN]]
+; CHECK-NEXT:    [[RESULT:%.*]] = fadd half [[UNKNOWN]], [[SELECT]]
+; CHECK-NEXT:    ret half [[RESULT]]
+;
+  %snan = call noundef half @returns_snan()
+  %select = select i1 %cond, half %snan, half %unknown
+  %result = fadd half %select, %select
+  ret half %result
+}
+
+define nofpclass(snan) half @qnan_result_demands_snan_lhs(i1 %cond, half %unknown0, half %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) half @qnan_result_demands_snan_lhs(
+; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call half @returns_snan()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], half [[SNAN]], half [[UNKNOWN0]]
+; CHECK-NEXT:    [[RESULT:%.*]] = fadd half [[SELECT]], [[UNKNOWN1]]
+; CHECK-NEXT:    ret half [[RESULT]]
+;
+  %snan = call half @returns_snan()
+  %select = select i1 %cond, half %snan, half %unknown0
+  %result = fadd half %select, %unknown1
+  ret half %result
+}
+
+define nofpclass(snan) half @qnan_result_demands_snan_rhs(i1 %cond, half %unknown0, half %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) half @qnan_result_demands_snan_rhs(
+; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call half @returns_snan()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], half [[SNAN]], half [[UNKNOWN0]]
+; CHECK-NEXT:    [[RESULT:%.*]] = fadd half [[UNKNOWN1]], [[SELECT]]
+; CHECK-NEXT:    ret half [[RESULT]]
+;
+  %snan = call half @returns_snan()
+  %select = select i1 %cond, half %snan, half %unknown0
+  %result = fadd half %unknown1, %select
+  ret half %result
+}
+
 attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }
 attributes #1 = { "denormal-fp-math"="dynamic,dynamic" }
 attributes #2 = { "denormal-fp-math"="ieee,preserve-sign" }
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fdiv.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fdiv.ll
index ea06ccb4a3fb7..c4c4da56701a5 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fdiv.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fdiv.ll
@@ -11,6 +11,7 @@ declare nofpclass(nan inf norm nsub zero) half @returns_psub()
 declare nofpclass(nan inf norm psub zero) half @returns_nsub()
 declare nofpclass(nan inf sub zero) half @returns_norm()
 declare nofpclass(nan norm sub zero) half @returns_inf()
+declare nofpclass(qnan inf norm sub zero) half @returns_snan()
 declare void @use(half)
 
 define nofpclass(pinf) half @ret_nofpclass_pinf__fdiv_unknown_or_pinf(i1 %cond, half %x, half %y) {
@@ -2295,6 +2296,32 @@ define nofpclass(inf norm sub zero) half @nan_result_demands_subnorm_rhs__dynami
   ret half %div
 }
 
+define nofpclass(snan) half @qnan_result_demands_snan_src_lhs(i1 %cond, half %unknown0, half %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) half @qnan_result_demands_snan_src_lhs(
+; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call half @returns_snan()
+; CHECK-NEXT:    [[MUL:%.*]] = fdiv half [[UNKNOWN0]], [[UNKNOWN1]]
+; CHECK-NEXT:    ret half [[MUL]]
+;
+  %snan = call half @returns_snan()
+  %select = select i1 %cond, half %snan, half %unknown0
+  %div = fdiv half %select, %unknown1
+  ret half %div
+}
+
+define nofpclass(snan) half @qnan_result_demands_snan_src_rhs(i1 %cond, half %unknown0, half %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) half @qnan_result_demands_snan_src_rhs(
+; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call half @returns_snan()
+; CHECK-NEXT:    [[MUL:%.*]] = fdiv half [[UNKNOWN1]], [[UNKNOWN0]]
+; CHECK-NEXT:    ret half [[MUL]]
+;
+  %snan = call half @returns_snan()
+  %select = select i1 %cond, half %snan, half %unknown0
+  %div = fdiv half %unknown1, %select
+  ret half %div
+}
+
 attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }
 attributes #1 = { "denormal-fp-math"="dynamic,dynamic" }
 attributes #2 = { "denormal-fp-math"="ieee,preserve-sign" }
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fma.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fma.ll
index 4837856cfb18b..88f2d0fb02f4c 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fma.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fma.ll
@@ -2,6 +2,7 @@
 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
 
 declare nofpclass(inf norm sub zero) half @returns_nan()
+declare nofpclass(qnan inf norm sub zero) half @returns_snan()
 
 define nofpclass(inf norm sub zero) half @ret_only_nan(half %x, half %y, half %z) {
 ; CHECK-LABEL: define nofpclass(inf zero sub norm) half @ret_only_nan(
@@ -292,9 +293,69 @@ define nofpclass(nan inf) half @ret_nonan_noinf__fma_square__no_nan_no_inf_all_s
   ret half %result
 }
 
+define nofpclass(snan) half @qnan_result_demands_snan_square_src0(i1 noundef %cond, half noundef %unknown0, half noundef %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) half @qnan_result_demands_snan_square_src0(
+; CHECK-SAME: i1 noundef [[COND:%.*]], half noundef [[UNKNOWN0:%.*]], half noundef [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call half @returns_snan()
+; CHECK-NEXT:    [[RESULT:%.*]] = call half @llvm.fma.f16(half [[UNKNOWN0]], half [[UNKNOWN0]], half [[UNKNOWN1]])
+; CHECK-NEXT:    ret half [[RESULT]]
+;
+  %snan = call half @returns_snan()
+  %select = select i1 %cond, half %snan, half %unknown0
+  %result = call half @llvm.fma.f16(half %select, half %select, half %unknown1)
+  ret half %result
+}
 
-!0 = !{}
+define nofpclass(snan) half @qnan_result_demands_snan_square_src1(i1 noundef %cond, half noundef %unknown0, half noundef %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) half @qnan_result_demands_snan_square_src1(
+; CHECK-SAME: i1 noundef [[COND:%.*]], half noundef [[UNKNOWN0:%.*]], half noundef [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call half @returns_snan()
+; CHECK-NEXT:    [[RESULT:%.*]] = call half @llvm.fma.f16(half [[UNKNOWN1]], half [[UNKNOWN1]], half [[UNKNOWN0]])
+; CHECK-NEXT:    ret half [[RESULT]]
+;
+  %snan = call half @returns_snan()
+  %select = select i1 %cond, half %snan, half %unknown0
+  %result = call half @llvm.fma.f16(half %unknown1, half %unknown1, half %select)
+  ret half %result
+}
 
+define nofpclass(snan) half @qnan_result_demands_snan_src0(i1 %cond, half %unknown0, half %unknown1, half %unknown2) {
+; CHECK-LABEL: define nofpclass(snan) half @qnan_result_demands_snan_src0(
+; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]], half [[UNKNOWN2:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call half @returns_snan()
+; CHECK-NEXT:    [[RESULT:%.*]] = call half @llvm.fma.f16(half [[UNKNOWN0]], half [[UNKNOWN1]], half [[UNKNOWN2]])
+; CHECK-NEXT:    ret half [[RESULT]]
+;
+  %snan = call half @returns_snan()
+  %select = select i1 %cond, half %snan, half %unknown0
+  %result = call half @llvm.fma.f16(half %select, half %unknown1, half %unknown2)
+  ret half %result
+}
 
+define nofpclass(snan) half @qnan_result_demands_snan_src1(i1 %cond, half %unknown0, half %unknown1, half %unknown2) {
+; CHECK-LABEL: define nofpclass(snan) half @qnan_result_demands_snan_src1(
+; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]], half [[UNKNOWN2:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call half @returns_snan()
+; CHECK-NEXT:    [[RESULT:%.*]] = call half @llvm.fma.f16(half [[UNKNOWN1]], half [[UNKNOWN0]], half [[UNKNOWN2]])
+; CHECK-NEXT:    ret half [[RESULT]]
+;
+  %snan = call half @returns_snan()
+  %select = select i1 %cond, half %snan, half %unknown0
+  %result = call half @llvm.fma.f16(half %unknown1, half %select, half %unknown2)
+  ret half %result
+}
 
+define nofpclass(snan) half @qnan_result_demands_snan_src2(i1 %cond, half %unknown0, half %unknown1, half %unknown2) {
+; CHECK-LABEL: define nofpclass(snan) half @qnan_result_demands_snan_src2(
+; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]], half [[UNKNOWN2:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call half @returns_snan()
+; CHECK-NEXT:    [[RESULT:%.*]] = call half @llvm.fma.f16(half [[UNKNOWN1]], half [[UNKNOWN2]], half [[UNKNOWN0]])
+; CHECK-NEXT:    ret half [[RESULT]]
+;
+  %snan = call half @returns_snan()
+  %select = select i1 %cond, half %snan, half %unknown0
+  %result = call half @llvm.fma.f16(half %unknown1, half %unknown2, half %select)
+  ret half %result
+}
 
+!0 = !{}
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll
index c40200f819e7d..805085504b9bb 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll
@@ -7,6 +7,7 @@ declare nofpclass(nan inf pzero sub norm) float @returns_nzero()
 declare nofpclass(nan inf zero sub nnorm) float @returns_pnorm()
 declare nofpclass(nan inf norm zero) float @returns_sub()
 declare nofpclass(nan inf sub zero) float @returns_norm()
+declare nofpclass(qnan inf norm sub zero) float @returns_snan()
 declare void @use(float)
 
 ; No inf result implies no inf inputs.
@@ -1402,5 +1403,44 @@ define nofpclass(nan inf sub zero) float @norm_result_demands_sub_source_rhs(i1
   ret float %mul
 }
 
+define nofpclass(snan) float @qnan_result_square_demands_snan(i1 noundef %cond, float noundef %unknown0) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_square_demands_snan(
+; CHECK-SAME: i1 noundef [[COND:%.*]], float noundef [[UNKNOWN0:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call noundef float @returns_snan()
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[UNKNOWN0]], [[UNKNOWN0]]
+; CHECK-NEXT:    ret float [[MUL]]
+;
+  %snan = call noundef float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown0
+  %mul = fmul float %select, %select
+  ret float %mul
+}
+
+define nofpclass(snan) float @qnan_result_demands_snan_lhs(i1 %cond, float %unknown0, float %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_lhs(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[UNKNOWN0]], [[UNKNOWN1]]
+; CHECK-NEXT:    ret float [[MUL]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown0
+  %mul = fmul float %select, %unknown1
+  ret float %mul
+}
+
+define nofpclass(snan) float @qnan_result_demands_snan_rhs(i1 %cond, float %unknown0, float %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_rhs(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[UNKNOWN1]], [[UNKNOWN0]]
+; CHECK-NEXT:    ret float [[MUL]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown0
+  %mul = fmul float %unknown1, %select
+  ret float %mul
+}
+
 attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }
 attributes #1 = { "denormal-fp-math"="dynamic,dynamic" }
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fpext.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fpext.ll
index d138885efd0e6..9de2450bce494 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fpext.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fpext.ll
@@ -2,6 +2,7 @@
 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
 
 declare nofpclass(inf norm sub zero) half @returns_nan_f16()
+declare nofpclass(qnan inf norm sub zero) half @returns_snan_f16()
 declare nofpclass(nan ninf norm sub zero) half @returns_pinf_f16()
 declare nofpclass(nan pinf norm sub zero) half @returns_ninf_f16()
 declare nofpclass(nan norm sub zero) half @returns_inf_f16()
@@ -470,3 +471,16 @@ define nofpclass(zero) float @ret_no_zero__fpext__select_zero_or_unknown(i1 %con
   %result = fpext half %select to float
   ret float %result
 }
+
+define nofpclass(snan) float @qnan_result_demands_snan_src(i1 %cond, half %unknown) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_src(
+; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call half @returns_snan_f16()
+; CHECK-NEXT:    [[RESULT:%.*]] = fpext half [[UNKNOWN]] to float
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call half @returns_snan_f16()
+  %select = select i1 %cond, half %snan, half %unknown
+  %result = fpext half %select to float
+  ret float %result
+}
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fptrunc-round.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fptrunc-round.ll
index 7ec16b0d9dc96..21726a29668f8 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fptrunc-round.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fptrunc-round.ll
@@ -2,6 +2,7 @@
 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
 
 declare nofpclass(inf norm sub zero) float @returns_nan_f32()
+declare nofpclass(qnan inf norm sub zero) float @returns_snan_f32()
 declare nofpclass(nan ninf norm sub zero) float @returns_pinf_f32()
 declare nofpclass(nan pinf norm sub zero) float @returns_ninf_f32()
 declare nofpclass(nan norm sub zero) float @returns_inf_f32()
@@ -617,3 +618,16 @@ define nofpclass(nan) half @ret_no_nan__fptrunc_drop_noundef(float %x) {
   %result = call noundef half @llvm.fptrunc.round.f16.f32(float %x, metadata !"round.downward"), !unknown.md !{}
   ret half %result
 }
+
+define nofpclass(snan) half @qnan_result_demands_snan_src2(i1 %cond, float %unknown0) {
+; CHECK-LABEL: define nofpclass(snan) half @qnan_result_demands_snan_src2(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan_f32()
+; CHECK-NEXT:    [[RESULT:%.*]] = call half @llvm.fptrunc.round.f16.f32(float [[UNKNOWN0]], metadata !"round.downward")
+; CHECK-NEXT:    ret half [[RESULT]]
+;
+  %snan = call float @returns_snan_f32()
+  %select = select i1 %cond, float %snan, float %unknown0
+  %result = call half @llvm.fptrunc.round.f16.f32(float %select, metadata !"round.downward")
+  ret half %result
+}
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fptrunc.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fptrunc.ll
index c06e190728a3f..744ec58af2fd8 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fptrunc.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fptrunc.ll
@@ -2,6 +2,7 @@
 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
 
 declare nofpclass(inf norm sub zero) float @returns_nan_f32()
+declare nofpclass(qnan inf norm sub zero) float @returns_snan_f32()
 declare nofpclass(nan ninf norm sub zero) float @returns_pinf_f32()
 declare nofpclass(nan pinf norm sub zero) float @returns_ninf_f32()
 declare nofpclass(nan norm sub zero) float @returns_inf_f32()
@@ -605,3 +606,16 @@ define nofpclass(inf norm sub) half @zero_demands_norm_source(i1 %cond, float %u
   %result = fptrunc float %select to half
   ret half %result
 }
+
+define nofpclass(snan) half @qnan_result_demands_snan_src2(i1 %cond, float %unknown0) {
+; CHECK-LABEL: define nofpclass(snan) half @qnan_result_demands_snan_src2(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan_f32()
+; CHECK-NEXT:    [[RESULT:%.*]] = fptrunc float [[UNKNOWN0]] to half
+; CHECK-NEXT:    ret half [[RESULT]]
+;
+  %snan = call float @returns_snan_f32()
+  %select = select i1 %cond, float %snan, float %unknown0
+  %result = fptrunc float %select to half
+  ret half %result
+}
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll
index 5cebd6ccd2c10..ee431d216b41f 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll
@@ -610,3 +610,17 @@ define nofpclass(inf) half @multiple_extract_uses(i1 %cond, half %unknown, ptr n
   store half %frexp.mant2, ptr %ptr
   ret half %frexp.mant
 }
+
+define nofpclass(snan) half @qnan_result_demands_snan_src(i1 %cond, half %unknown, half nofpclass(qnan inf norm sub zero) %only.snan) {
+; CHECK-LABEL: define nofpclass(snan) half @qnan_result_demands_snan_src(
+; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]], half nofpclass(qnan inf zero sub norm) [[ONLY_SNAN:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_SNAN]]
+; CHECK-NEXT:    [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]])
+; CHECK-NEXT:    [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0
+; CHECK-NEXT:    ret half [[FREXP_MANT]]
+;
+  %select = select i1 %cond, half %unknown, half %only.snan
+  %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select)
+  %frexp.mant = extractvalue { half, i32 } %frexp, 0
+  ret half %frexp.mant
+}
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fsub.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fsub.ll
index c5ed839b08aaa..68978c6e45821 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fsub.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fsub.ll
@@ -20,6 +20,7 @@ declare nofpclass(nan ninf nzero nsub nnorm) half @returns_positive()
 declare nofpclass(nan pinf pzero psub pnorm) half @returns_negative()
 
 declare nofpclass(inf zero sub norm) half @returns_nan()
+declare nofpclass(qnan inf zero sub norm) half @returns_snan()
 
 declare nofpclass(nan inf zero sub) half @returns_norm()
 declare nofpclass(nan inf zero sub pnorm) half @returns_nnorm()
@@ -1204,5 +1205,33 @@ define nofpclass(snan) half @ret_no_snan__known_negative__fsub__known_positive()
   ret half %result
 }
 
+define nofpclass(snan) half @qnan_result_demands_snan_lhs(i1 %cond, half %unknown0, half %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) half @qnan_result_demands_snan_lhs(
+; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call half @returns_snan()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], half [[SNAN]], half [[UNKNOWN0]]
+; CHECK-NEXT:    [[RESULT:%.*]] = fsub half [[SELECT]], [[UNKNOWN1]]
+; CHECK-NEXT:    ret half [[RESULT]]
+;
+  %snan = call half @returns_snan()
+  %select = select i1 %cond, half %snan, half %unknown0
+  %result = fsub half %select, %unknown1
+  ret half %result
+}
+
+define nofpclass(snan) half @qnan_result_demands_snan_rhs(i1 %cond, half %unknown0, half %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) half @qnan_result_demands_snan_rhs(
+; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call half @returns_snan()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], half [[SNAN]], half [[UNKNOWN0]]
+; CHECK-NEXT:    [[RESULT:%.*]] = fsub half [[UNKNOWN1]], [[SELECT]]
+; CHECK-NEXT:    ret half [[RESULT]]
+;
+  %snan = call half @returns_snan()
+  %select = select i1 %cond, half %snan, half %unknown0
+  %result = fsub half %unknown1, %select
+  ret half %result
+}
+
 attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }
 attributes #1 = { "denormal-fp-math"="dynamic,dynamic" }
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-log.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-log.ll
index e3bbab6d2d53c..61d3b4f11472f 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-log.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-log.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 nofpclass(qnan inf norm sub zero) float @returns_snan()
+
 ; -> qnan, canonicalizing
 define nofpclass(inf norm sub zero) float @ret_nofpclass_only_nan__log(float %unknown) {
 ; CHECK-LABEL: define nofpclass(inf zero sub norm) float @ret_nofpclass_only_nan__log(
@@ -351,6 +353,19 @@ define nofpclass(inf nan) float @add_flags_log__drop_noundef(float nofpclass(inf
   ret float %result
 }
 
+define nofpclass(snan) float @qnan_result_demands_snan_src(i1 %cond, float %unknown) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_src(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[UNKNOWN]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown
+  %result = call float @llvm.log.f32(float %select)
+  ret float %result
+}
+
 attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }
 attributes #1 = { "denormal-fp-math"="dynamic,dynamic" }
 
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximum.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximum.ll
index b6a6e63af8acb..a3b135ae51444 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximum.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximum.ll
@@ -20,6 +20,7 @@ declare nofpclass(inf sub norm pzero) float @returns_nzero_or_nan()
 declare nofpclass(inf sub norm nan nzero) float @returns_pzero()
 declare nofpclass(inf sub norm nzero) float @returns_pzero_or_nan()
 declare nofpclass(inf norm sub zero) float @returns_nan()
+declare nofpclass(qnan inf norm sub zero) float @returns_snan()
 
 declare nofpclass(ninf norm sub zero nan) float @returns_pinf()
 declare nofpclass(ninf norm sub zero) float @returns_pinf_or_nan()
@@ -2159,6 +2160,32 @@ define nofpclass(snan) float @cannot_fold_negative_or_zero__positive_or_zero_1__
   ret float %result
 }
 
+define nofpclass(snan) float @qnan_result_demands_snan_lhs(i1 %cond, float %unknown0, float %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_lhs(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.maximum.f32(float [[UNKNOWN0]], float [[UNKNOWN1]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown0
+  %result = call float @llvm.maximum.f32(float %select, float %unknown1)
+  ret float %result
+}
+
+define nofpclass(snan) float @qnan_result_demands_snan_rhs(i1 %cond, float %unknown0, float %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_rhs(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.maximum.f32(float [[UNKNOWN1]], float [[UNKNOWN0]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown0
+  %result = call float @llvm.maximum.f32(float %unknown1, float %select)
+  ret float %result
+}
+
 !0 = !{}
 
 attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximumnum.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximumnum.ll
index 2589d80a256d6..fc211328bcaa6 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximumnum.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximumnum.ll
@@ -20,6 +20,7 @@ declare nofpclass(inf sub norm pzero) float @returns_nzero_or_nan()
 declare nofpclass(inf sub norm nan nzero) float @returns_pzero()
 declare nofpclass(inf sub norm nzero) float @returns_pzero_or_nan()
 declare nofpclass(inf norm sub zero) float @returns_nan()
+declare nofpclass(qnan inf norm sub zero) float @returns_snan()
 
 declare nofpclass(ninf norm sub zero nan) float @returns_pinf()
 declare nofpclass(ninf norm sub zero) float @returns_pinf_or_nan()
@@ -2164,6 +2165,34 @@ define nofpclass(snan) float @cannot_fold_negative_or_zero__positive_or_zero_1__
   ret float %result
 }
 
+define nofpclass(snan) float @qnan_result_demands_snan_lhs(i1 %cond, float %unknown0, float %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_lhs(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[SNAN]], float [[UNKNOWN0]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.maximumnum.f32(float [[SELECT]], float [[UNKNOWN1]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown0
+  %result = call float @llvm.maximumnum.f32(float %select, float %unknown1)
+  ret float %result
+}
+
+define nofpclass(snan) float @qnan_result_demands_snan_rhs(i1 %cond, float %unknown0, float %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_rhs(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[SNAN]], float [[UNKNOWN0]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.maximumnum.f32(float [[UNKNOWN1]], float [[SELECT]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown0
+  %result = call float @llvm.maximumnum.f32(float %unknown1, float %select)
+  ret float %result
+}
+
 !0 = !{}
 
 attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maxnum.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maxnum.ll
index 62fb47646365f..0fcca06f08210 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maxnum.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maxnum.ll
@@ -20,6 +20,7 @@ declare nofpclass(inf sub norm pzero) float @returns_nzero_or_nan()
 declare nofpclass(inf sub norm nan nzero) float @returns_pzero()
 declare nofpclass(inf sub norm nzero) float @returns_pzero_or_nan()
 declare nofpclass(inf norm sub zero) float @returns_nan()
+declare nofpclass(qnan inf norm sub zero) float @returns_snan()
 
 declare nofpclass(ninf norm sub zero nan) float @returns_pinf()
 declare nofpclass(ninf norm sub zero) float @returns_pinf_or_nan()
@@ -2223,6 +2224,34 @@ define nofpclass(snan) float @cannot_fold_negative_or_zero__positive_or_zero_1__
   ret float %result
 }
 
+define nofpclass(snan) float @qnan_result_demands_snan_lhs(i1 %cond, float %unknown0, float %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_lhs(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[SNAN]], float [[UNKNOWN0]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.maxnum.f32(float [[SELECT]], float [[UNKNOWN1]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown0
+  %result = call float @llvm.maxnum.f32(float %select, float %unknown1)
+  ret float %result
+}
+
+define nofpclass(snan) float @qnan_result_demands_snan_rhs(i1 %cond, float %unknown0, float %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_rhs(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[SNAN]], float [[UNKNOWN0]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.maxnum.f32(float [[UNKNOWN1]], float [[SELECT]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown0
+  %result = call float @llvm.maxnum.f32(float %unknown1, float %select)
+  ret float %result
+}
+
 !0 = !{}
 
 attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimum.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimum.ll
index fba6e9c45da4d..92053ad003443 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimum.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimum.ll
@@ -20,6 +20,7 @@ declare nofpclass(inf sub norm pzero) float @returns_nzero_or_nan()
 declare nofpclass(inf sub norm nan nzero) float @returns_pzero()
 declare nofpclass(inf sub norm nzero) float @returns_pzero_or_nan()
 declare nofpclass(inf norm sub zero) float @returns_nan()
+declare nofpclass(qnan inf norm sub zero) float @returns_snan()
 
 declare nofpclass(ninf norm sub zero nan) float @returns_pinf()
 declare nofpclass(ninf norm sub zero) float @returns_pinf_or_nan()
@@ -2147,6 +2148,33 @@ define nofpclass(snan) float @cannot_fold_negative_or_zero__positive_or_zero_1__
   ret float %result
 }
 
+
+define nofpclass(snan) float @qnan_result_demands_snan_lhs(i1 %cond, float %unknown0, float %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_lhs(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.minimum.f32(float [[UNKNOWN0]], float [[UNKNOWN1]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown0
+  %result = call float @llvm.minimum.f32(float %select, float %unknown1)
+  ret float %result
+}
+
+define nofpclass(snan) float @qnan_result_demands_snan_rhs(i1 %cond, float %unknown0, float %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_rhs(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.minimum.f32(float [[UNKNOWN1]], float [[UNKNOWN0]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown0
+  %result = call float @llvm.minimum.f32(float %unknown1, float %select)
+  ret float %result
+}
+
 !0 = !{}
 
 attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimumnum.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimumnum.ll
index b67077cb7dbd9..597a90e6fe8b8 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimumnum.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minimumnum.ll
@@ -20,6 +20,7 @@ declare nofpclass(inf sub norm pzero) float @returns_nzero_or_nan()
 declare nofpclass(inf sub norm nan nzero) float @returns_pzero()
 declare nofpclass(inf sub norm nzero) float @returns_pzero_or_nan()
 declare nofpclass(inf norm sub zero) float @returns_nan()
+declare nofpclass(qnan inf norm sub zero) float @returns_snan()
 
 declare nofpclass(ninf norm sub zero nan) float @returns_pinf()
 declare nofpclass(ninf norm sub zero) float @returns_pinf_or_nan()
@@ -2155,6 +2156,34 @@ define nofpclass(snan) float @cannot_fold_negative_or_zero__positive_or_zero_1__
   ret float %result
 }
 
+define nofpclass(snan) float @qnan_result_demands_snan_lhs(i1 %cond, float %unknown0, float %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_lhs(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[SNAN]], float [[UNKNOWN0]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[SELECT]], float [[UNKNOWN1]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown0
+  %result = call float @llvm.minimumnum.f32(float %select, float %unknown1)
+  ret float %result
+}
+
+define nofpclass(snan) float @qnan_result_demands_snan_rhs(i1 %cond, float %unknown0, float %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_rhs(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[SNAN]], float [[UNKNOWN0]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[UNKNOWN1]], float [[SELECT]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown0
+  %result = call float @llvm.minimumnum.f32(float %unknown1, float %select)
+  ret float %result
+}
+
 !0 = !{}
 
 attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minnum.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minnum.ll
index bf16957ea8d44..a765d24c60e04 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minnum.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-minnum.ll
@@ -20,6 +20,7 @@ declare nofpclass(inf sub norm pzero) float @returns_nzero_or_nan()
 declare nofpclass(inf sub norm nan nzero) float @returns_pzero()
 declare nofpclass(inf sub norm nzero) float @returns_pzero_or_nan()
 declare nofpclass(inf norm sub zero) float @returns_nan()
+declare nofpclass(qnan inf norm sub zero) float @returns_snan()
 
 declare nofpclass(ninf norm sub zero nan) float @returns_pinf()
 declare nofpclass(ninf norm sub zero) float @returns_pinf_or_nan()
@@ -2222,6 +2223,34 @@ define nofpclass(snan) float @cannot_fold_negative_or_zero__positive_or_zero_1__
   ret float %result
 }
 
+define nofpclass(snan) float @qnan_result_demands_snan_lhs(i1 %cond, float %unknown0, float %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_lhs(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[SNAN]], float [[UNKNOWN0]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.minnum.f32(float [[SELECT]], float [[UNKNOWN1]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown0
+  %result = call float @llvm.minnum.f32(float %select, float %unknown1)
+  ret float %result
+}
+
+define nofpclass(snan) float @qnan_result_demands_snan_rhs(i1 %cond, float %unknown0, float %unknown1) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_rhs(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[SNAN]], float [[UNKNOWN0]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.minnum.f32(float [[UNKNOWN1]], float [[SELECT]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown0
+  %result = call float @llvm.minnum.f32(float %unknown1, float %select)
+  ret float %result
+}
+
 !0 = !{}
 
 attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-rounding-intrinsics.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-rounding-intrinsics.ll
index fda9300c3bd1c..c000ce8458229 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-rounding-intrinsics.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-rounding-intrinsics.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 nofpclass(qnan inf norm sub zero) float @returns_snan()
+
 define nofpclass(snan) float @ret_no_snan__floor_no_snan(float nofpclass(nan) %x) {
 ; CHECK-LABEL: define nofpclass(snan) float @ret_no_snan__floor_no_snan(
 ; CHECK-SAME: float nofpclass(nan) [[X:%.*]]) {
@@ -1241,3 +1243,94 @@ define nofpclass(nan) float @ret_non_nan__floor__drop_noundef(float %x) {
   %result = call noundef float @llvm.floor.f32(float %x), !unknown.md !{}
   ret float %result
 }
+
+define nofpclass(snan) float @qnan_result_demands_snan_src__trunc(i1 %cond, float %unknown) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_src__trunc(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.trunc.f32(float [[UNKNOWN]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown
+  %result = call float @llvm.trunc.f32(float %select)
+  ret float %result
+}
+
+define nofpclass(snan) float @qnan_result_demands_snan_src__floor(i1 %cond, float %unknown) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_src__floor(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.floor.f32(float [[UNKNOWN]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown
+  %result = call float @llvm.floor.f32(float %select)
+  ret float %result
+}
+
+define nofpclass(snan) float @qnan_result_demands_snan_src__ceil(i1 %cond, float %unknown) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_src__ceil(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.ceil.f32(float [[UNKNOWN]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown
+  %result = call float @llvm.ceil.f32(float %select)
+  ret float %result
+}
+
+define nofpclass(snan) float @qnan_result_demands_snan_src__rint(i1 %cond, float %unknown) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_src__rint(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.rint.f32(float [[UNKNOWN]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown
+  %result = call float @llvm.rint.f32(float %select)
+  ret float %result
+}
+
+define nofpclass(snan) float @qnan_result_demands_snan_src__nearbyint(i1 %cond, float %unknown) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_src__nearbyint(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.nearbyint.f32(float [[UNKNOWN]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown
+  %result = call float @llvm.nearbyint.f32(float %select)
+  ret float %result
+}
+
+define nofpclass(snan) float @qnan_result_demands_snan_src__round(i1 %cond, float %unknown) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_src__round(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.round.f32(float [[UNKNOWN]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown
+  %result = call float @llvm.round.f32(float %select)
+  ret float %result
+}
+
+define nofpclass(snan) float @qnan_result_demands_snan_src__roundeven(i1 %cond, float %unknown) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_src__roundeven(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.roundeven.f32(float [[UNKNOWN]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown
+  %result = call float @llvm.roundeven.f32(float %select)
+  ret float %result
+}
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
index 7a05e27d88184..74f972907a0dc 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
@@ -12,7 +12,7 @@ declare nofpclass(pinf pnorm psub pzero) float @returns_negative_or_nan()
 declare nofpclass(pinf pnorm psub zero nan) float @returns_negative_nonzero()
 declare nofpclass(pinf pnorm psub zero nan) <2 x float> @returns_negative_nonzero_vec()
 declare nofpclass(pinf pnorm psub zero) float @returns_negative_nonzero_or_nan()
-
+declare nofpclass(qnan inf norm sub zero) float @returns_snan()
 
 ; -> qnan
 define nofpclass(inf norm sub zero) float @ret_only_nan_sqrt(float %x) {
@@ -345,5 +345,18 @@ define nofpclass(nan) float @ret_no_nan__sqrt__no_inf_inputs(float nofpclass(inf
   ret float %result
 }
 
+define nofpclass(snan) float @qnan_result_demands_snan_src(i1 %cond, float %unknown) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_src(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[UNKNOWN]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown
+  %result = call float @llvm.sqrt.f32(float %select)
+  ret float %result
+}
+
 attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }
 attributes #1 = { "denormal-fp-math"="dynamic,dynamic" }



More information about the llvm-commits mailing list