https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/173431

>From 5bc2f968e2b9f1634cbf65793a9aa9e8c2d9e099 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <[email protected]>
Date: Sat, 20 Dec 2025 21:30:35 +0100
Subject: [PATCH] InstCombine: Add baseline tests for exp
 SimplifyDemandedFPClass

---
 .../simplify-demanded-fpclass-exp.ll          | 502 ++++++++++++++++++
 1 file changed, 502 insertions(+)
 create mode 100644 
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-exp.ll

diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-exp.ll 
b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-exp.ll
new file mode 100644
index 0000000000000..7706d2de68f16
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-exp.ll
@@ -0,0 +1,502 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 
UTC_ARGS: --version 6
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+
+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:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[MAYBE_INF]], 
float [[NOT_PINF]]
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %select = select i1 %cond, float %maybe.inf, float %not.pinf
+  %exp = call float @llvm.exp2.f32(float %select)
+  ret float %exp
+}
+
+define nofpclass(ninf) float 
@ret_nofpclass_ninf__exp2_select_maybe_inf_or_not_pinf(i1 %cond, float 
%maybe.inf, float nofpclass(pinf) %not.pinf) {
+; CHECK-LABEL: define nofpclass(ninf) float 
@ret_nofpclass_ninf__exp2_select_maybe_inf_or_not_pinf(
+; CHECK-SAME: i1 [[COND:%.*]], float [[MAYBE_INF:%.*]], float nofpclass(pinf) 
[[NOT_PINF:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[MAYBE_INF]], 
float [[NOT_PINF]]
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %select = select i1 %cond, float %maybe.inf, float %not.pinf
+  %exp = call float @llvm.exp2.f32(float %select)
+  ret float %exp
+}
+
+define nofpclass(ninf) float 
@ret_nofpclass_ninf__exp2_select_maybe_inf_or_not_ninf(i1 %cond, float 
%maybe.inf, float nofpclass(ninf) %not.ninf) {
+; CHECK-LABEL: define nofpclass(ninf) float 
@ret_nofpclass_ninf__exp2_select_maybe_inf_or_not_ninf(
+; CHECK-SAME: i1 [[COND:%.*]], float [[MAYBE_INF:%.*]], float nofpclass(ninf) 
[[NOT_NINF:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[MAYBE_INF]], 
float [[NOT_NINF]]
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %select = select i1 %cond, float %maybe.inf, float %not.ninf
+  %exp = call float @llvm.exp2.f32(float %select)
+  ret float %exp
+}
+
+; Negative test
+define nofpclass(nan) float 
@ret_nofpclass_nan__exp2_select_maybe_inf_or_not_nan(i1 %cond, float 
%maybe.nan, float nofpclass(nan) %not.nan) {
+; CHECK-LABEL: define nofpclass(nan) float 
@ret_nofpclass_nan__exp2_select_maybe_inf_or_not_nan(
+; CHECK-SAME: i1 [[COND:%.*]], float [[MAYBE_NAN:%.*]], float nofpclass(nan) 
[[NOT_NAN:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[MAYBE_NAN]], 
float [[NOT_NAN]]
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %select = select i1 %cond, float %maybe.nan, float %not.nan
+  %exp = call float @llvm.exp2.f32(float %select)
+  ret float %exp
+}
+
+; Fold to only exp2
+define nofpclass(nan) float 
@ret_nofpclass_nan__exp2_select_maybe_inf_or_nan(i1 %cond, float %maybe.nan, 
float nofpclass(inf zero sub norm) %only.nan) {
+; CHECK-LABEL: define nofpclass(nan) float 
@ret_nofpclass_nan__exp2_select_maybe_inf_or_nan(
+; CHECK-SAME: i1 [[COND:%.*]], float [[MAYBE_NAN:%.*]], float nofpclass(inf 
zero sub norm) [[ONLY_NAN:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[MAYBE_NAN]], 
float [[ONLY_NAN]]
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %select = select i1 %cond, float %maybe.nan, float %only.nan
+  %exp = call float @llvm.exp2.f32(float %select)
+  ret float %exp
+}
+
+; Only need to propagate nan inputs, so fold to ret %x
+define nofpclass(pinf zero psub pnorm) float 
@ret_nofpclass_no_positives__exp2(float %x) {
+; CHECK-LABEL: define nofpclass(pinf zero psub pnorm) float 
@ret_nofpclass_no_positives__exp2(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float [[X]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %x)
+  ret float %exp
+}
+
+; No positive results or nans, so fold to poison.
+define nofpclass(nan pinf zero psub pnorm) float 
@ret_nofpclass_no_positives_no_nan__exp2(float %x) {
+; CHECK-LABEL: define nofpclass(nan pinf zero psub pnorm) float 
@ret_nofpclass_no_positives_no_nan__exp2(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT:    ret float poison
+;
+  %exp = call float @llvm.exp2.f32(float %x)
+  ret float %exp
+}
+
+; Can fold this for nan propagation, don't need -0
+define nofpclass(pzero pinf psub pnorm) float 
@ret_nofpclass_no_positives_except_neg0__exp2(float %x) {
+; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float 
@ret_nofpclass_no_positives_except_neg0__exp2(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float [[X]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %x)
+  ret float %exp
+}
+
+; -0 isn't returnable, fold to poison
+define nofpclass(pzero pinf psub pnorm nan) float 
@ret_nofpclass_no_positives_except_neg0_no_nan__exp2(float %x) {
+; CHECK-LABEL: define nofpclass(nan pinf pzero psub pnorm) float 
@ret_nofpclass_no_positives_except_neg0_no_nan__exp2(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT:    ret float poison
+;
+  %exp = call float @llvm.exp2.f32(float %x)
+  ret float %exp
+}
+
+; Can't fold this, values near 0 return 1.
+define nofpclass(nzero pinf psub pnorm) float 
@ret_nofpclass_no_positives_except_pos0__exp2(float %x) {
+; CHECK-LABEL: define nofpclass(pinf nzero psub pnorm) float 
@ret_nofpclass_no_positives_except_pos0__exp2(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float [[X]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %x)
+  ret float %exp
+}
+
+; Can't fold this, values near 0 return 1.
+define nofpclass(pinf psub pnorm) float 
@ret_nofpclass_no_positives_except_0__exp2(float %x) {
+; CHECK-LABEL: define nofpclass(pinf psub pnorm) float 
@ret_nofpclass_no_positives_except_0__exp2(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float [[X]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %x)
+  ret float %exp
+}
+
+; check exp intrinsic is handled
+define nofpclass(nan) float @handle_exp(i1 %cond, float %maybe.nan, float 
nofpclass(inf zero sub norm) %only.nan) {
+; CHECK-LABEL: define nofpclass(nan) float @handle_exp(
+; CHECK-SAME: i1 [[COND:%.*]], float [[MAYBE_NAN:%.*]], float nofpclass(inf 
zero sub norm) [[ONLY_NAN:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[MAYBE_NAN]], 
float [[ONLY_NAN]]
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %select = select i1 %cond, float %maybe.nan, float %only.nan
+  %exp = call float @llvm.exp.f32(float %select)
+  ret float %exp
+}
+
+; check exp10 intrinsic is handled
+define nofpclass(nan) float @handle_exp10(i1 %cond, float %maybe.nan, float 
nofpclass(inf zero sub norm) %only.nan) {
+; CHECK-LABEL: define nofpclass(nan) float @handle_exp10(
+; CHECK-SAME: i1 [[COND:%.*]], float [[MAYBE_NAN:%.*]], float nofpclass(inf 
zero sub norm) [[ONLY_NAN:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[MAYBE_NAN]], 
float [[ONLY_NAN]]
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp10.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %select = select i1 %cond, float %maybe.nan, float %only.nan
+  %exp = call float @llvm.exp10.f32(float %select)
+  ret float %exp
+}
+
+; zero or sub result implies the input must be normal, so excludes the
+; second select source.
+define nofpclass(inf norm nan) float 
@ret_nofpclass_only_subzero__exp2_select_unknown_or_not_norm(i1 %cond, float 
%unknown, float nofpclass(norm) %not.norm) {
+; CHECK-LABEL: define nofpclass(nan inf norm) float 
@ret_nofpclass_only_subzero__exp2_select_unknown_or_not_norm(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], float nofpclass(norm) 
[[NOT_NORM:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[UNKNOWN]], float 
[[NOT_NORM]]
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %select = select i1 %cond, float %unknown, float %not.norm
+  %exp = call float @llvm.exp2.f32(float %select)
+  ret float %exp
+}
+
+define nofpclass(inf norm nan zero) float 
@ret_nofpclass_only_sub__exp2_select_unknown_or_not_norm(i1 %cond, float 
%unknown, float nofpclass(norm) %not.norm) {
+; CHECK-LABEL: define nofpclass(nan inf zero norm) float 
@ret_nofpclass_only_sub__exp2_select_unknown_or_not_norm(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], float nofpclass(norm) 
[[NOT_NORM:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[UNKNOWN]], float 
[[NOT_NORM]]
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %select = select i1 %cond, float %unknown, float %not.norm
+  %exp = call float @llvm.exp2.f32(float %select)
+  ret float %exp
+}
+
+define nofpclass(inf norm nan sub) float 
@ret_nofpclass_only_zero__exp2_select_unknown_or_not_norm(i1 %cond, float 
%unknown, float nofpclass(norm) %not.norm) {
+; CHECK-LABEL: define nofpclass(nan inf sub norm) float 
@ret_nofpclass_only_zero__exp2_select_unknown_or_not_norm(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], float nofpclass(norm) 
[[NOT_NORM:%.*]]) {
+; CHECK-NEXT:    ret float 0.000000e+00
+;
+  %select = select i1 %cond, float %unknown, float %not.norm
+  %exp = call float @llvm.exp2.f32(float %select)
+  ret float %exp
+}
+
+; Result only permits +inf or nan. The source value forbids pinf, but
+; the possible pnorm value could overflow, so this should not fold to
+; return poison.
+define nofpclass(ninf norm zero sub) float 
@pinf_result_implies_pnorm_source(float nofpclass(pinf nan) %maybe.pnorm) {
+; CHECK-LABEL: define nofpclass(ninf zero sub norm) float 
@pinf_result_implies_pnorm_source(
+; CHECK-SAME: float nofpclass(nan pinf) [[MAYBE_PNORM:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float [[MAYBE_PNORM]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %maybe.pnorm)
+  ret float %exp
+}
+
+define nofpclass(ninf norm zero sub) float 
@pinf_result_implies_pnorm_source_nan(float nofpclass(pinf) 
%maybe.pnorm.or.nan) {
+; CHECK-LABEL: define nofpclass(ninf zero sub norm) float 
@pinf_result_implies_pnorm_source_nan(
+; CHECK-SAME: float nofpclass(pinf) [[MAYBE_PNORM_OR_NAN:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float 
[[MAYBE_PNORM_OR_NAN]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %maybe.pnorm.or.nan)
+  ret float %exp
+}
+
+define nofpclass(pinf norm zero sub) float @ninf_result_implies_poison(float 
nofpclass(ninf nan) %maybe.nnorm) {
+; CHECK-LABEL: define nofpclass(pinf zero sub norm) float 
@ninf_result_implies_poison(
+; CHECK-SAME: float nofpclass(nan ninf) [[MAYBE_NNORM:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float [[MAYBE_NNORM]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %maybe.nnorm)
+  ret float %exp
+}
+
+; Cannot fold to poison
+define nofpclass(inf norm nan sub) float 
@zero_result_implies_nnorm_source_valid(float nofpclass(pnorm sub nan) 
%maybe.nnorm) {
+; CHECK-LABEL: define nofpclass(nan inf sub norm) float 
@zero_result_implies_nnorm_source_valid(
+; CHECK-SAME: float nofpclass(nan sub pnorm) [[MAYBE_NNORM:%.*]]) {
+; CHECK-NEXT:    ret float 0.000000e+00
+;
+  %exp = call float @llvm.exp2.f32(float %maybe.nnorm)
+  ret float %exp
+}
+
+define nofpclass(inf norm nan sub) float 
@zero_result_implies_nnorm_source_valid_nan(float nofpclass(pnorm sub) 
%maybe.nnorm.or.nan) {
+; CHECK-LABEL: define nofpclass(nan inf sub norm) float 
@zero_result_implies_nnorm_source_valid_nan(
+; CHECK-SAME: float nofpclass(sub pnorm) [[MAYBE_NNORM_OR_NAN:%.*]]) {
+; CHECK-NEXT:    ret float 0.000000e+00
+;
+  %exp = call float @llvm.exp2.f32(float %maybe.nnorm.or.nan)
+  ret float %exp
+}
+
+; Cannot fold to poison
+define nofpclass(inf norm nan sub) float 
@zero_result_implies_nsub_source_valid(float nofpclass(norm psub nan) 
%maybe.nsub) {
+; CHECK-LABEL: define nofpclass(nan inf sub norm) float 
@zero_result_implies_nsub_source_valid(
+; CHECK-SAME: float nofpclass(nan psub norm) [[MAYBE_NSUB:%.*]]) {
+; CHECK-NEXT:    ret float 0.000000e+00
+;
+  %exp = call float @llvm.exp2.f32(float %maybe.nsub)
+  ret float %exp
+}
+
+define nofpclass(inf norm nan sub) float 
@zero_result_implies_nsub_source_valid_nan(float nofpclass(norm psub) 
%maybe.nsub.or.nan) {
+; CHECK-LABEL: define nofpclass(nan inf sub norm) float 
@zero_result_implies_nsub_source_valid_nan(
+; CHECK-SAME: float nofpclass(psub norm) [[MAYBE_NSUB_OR_NAN:%.*]]) {
+; CHECK-NEXT:    ret float 0.000000e+00
+;
+  %exp = call float @llvm.exp2.f32(float %maybe.nsub.or.nan)
+  ret float %exp
+}
+
+; Cannot fold to poison
+define nofpclass(inf norm nan zero) float 
@sub_result_implies_nnorm_source_valid(float nofpclass(pnorm sub nan) 
%maybe.nnorm) {
+; CHECK-LABEL: define nofpclass(nan inf zero norm) float 
@sub_result_implies_nnorm_source_valid(
+; CHECK-SAME: float nofpclass(nan sub pnorm) [[MAYBE_NNORM:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float [[MAYBE_NNORM]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %maybe.nnorm)
+  ret float %exp
+}
+
+; Cannot fold to poison
+define nofpclass(inf norm nan zero) float 
@sub_result_implies_nsub_source_valid(float nofpclass(norm psub nan) 
%maybe.nsub) {
+; CHECK-LABEL: define nofpclass(nan inf zero norm) float 
@sub_result_implies_nsub_source_valid(
+; CHECK-SAME: float nofpclass(nan psub norm) [[MAYBE_NSUB:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float [[MAYBE_NSUB]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %maybe.nsub)
+  ret float %exp
+}
+
+define nofpclass(inf norm nan sub) float 
@zero_result_implies_pnorm_source_valid(float nofpclass(nnorm sub nan) 
%maybe.pnorm) {
+; CHECK-LABEL: define nofpclass(nan inf sub norm) float 
@zero_result_implies_pnorm_source_valid(
+; CHECK-SAME: float nofpclass(nan sub nnorm) [[MAYBE_PNORM:%.*]]) {
+; CHECK-NEXT:    ret float 0.000000e+00
+;
+  %exp = call float @llvm.exp2.f32(float %maybe.pnorm)
+  ret float %exp
+}
+
+define nofpclass(inf norm nan sub) float 
@zero_result_implies_pnorm_source_valid_nan(float nofpclass(nnorm sub) 
%maybe.pnorm.or.nan) {
+; CHECK-LABEL: define nofpclass(nan inf sub norm) float 
@zero_result_implies_pnorm_source_valid_nan(
+; CHECK-SAME: float nofpclass(sub nnorm) [[MAYBE_PNORM_OR_NAN:%.*]]) {
+; CHECK-NEXT:    ret float 0.000000e+00
+;
+  %exp = call float @llvm.exp2.f32(float %maybe.pnorm.or.nan)
+  ret float %exp
+}
+
+define nofpclass(inf norm nan zero) float 
@sub_result_implies_pnorm_source_valid(float nofpclass(pnorm sub nan) 
%maybe.pnorm) {
+; CHECK-LABEL: define nofpclass(nan inf zero norm) float 
@sub_result_implies_pnorm_source_valid(
+; CHECK-SAME: float nofpclass(nan sub pnorm) [[MAYBE_PNORM:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float [[MAYBE_PNORM]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %maybe.pnorm)
+  ret float %exp
+}
+
+define nofpclass(inf nnorm nan zero) float 
@pnorm_result_implies_possible_0_source(float nofpclass(pnorm sub) 
%maybe.zero.or.nan) {
+; CHECK-LABEL: define nofpclass(nan inf zero nnorm) float 
@pnorm_result_implies_possible_0_source(
+; CHECK-SAME: float nofpclass(sub pnorm) [[MAYBE_ZERO_OR_NAN:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float 
[[MAYBE_ZERO_OR_NAN]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %maybe.zero.or.nan)
+  ret float %exp
+}
+
+define nofpclass(inf nnorm nan zero sub) float 
@pnorm_result_implies_possible_0_source_no_inf(float nofpclass(inf norm sub) 
%maybe.zero.or.nan) {
+; CHECK-LABEL: define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_implies_possible_0_source_no_inf(
+; CHECK-SAME: float nofpclass(inf sub norm) [[MAYBE_ZERO_OR_NAN:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float 
[[MAYBE_ZERO_OR_NAN]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %maybe.zero.or.nan)
+  ret float %exp
+}
+
+define nofpclass(inf nnorm nan zero sub) float 
@pnorm_result_implies_possible_sub_source(float nofpclass(inf norm zero) 
%maybe.sub.or.nan) {
+; CHECK-LABEL: define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_implies_possible_sub_source(
+; CHECK-SAME: float nofpclass(inf zero norm) [[MAYBE_SUB_OR_NAN:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float 
[[MAYBE_SUB_OR_NAN]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %maybe.sub.or.nan)
+  ret float %exp
+}
+
+; FIXME: Does not happen unless nofpclass set on return value.
+define nofpclass(pzero) float @source_is_known_zero(float nofpclass(nan inf 
norm sub) %must.be.zero) {
+; CHECK-LABEL: define nofpclass(pzero) float @source_is_known_zero(
+; CHECK-SAME: float nofpclass(nan inf sub norm) [[MUST_BE_ZERO:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float 
[[MUST_BE_ZERO]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %must.be.zero)
+  ret float %exp
+}
+
+define nofpclass(pzero) <2 x float> @source_is_known_zero_vec(<2 x float> 
nofpclass(nan inf norm sub) %must.be.zero) {
+; CHECK-LABEL: define nofpclass(pzero) <2 x float> @source_is_known_zero_vec(
+; CHECK-SAME: <2 x float> nofpclass(nan inf sub norm) [[MUST_BE_ZERO:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> 
[[MUST_BE_ZERO]])
+; CHECK-NEXT:    ret <2 x float> [[EXP]]
+;
+  %exp = call <2 x float> @llvm.exp2.v2f32(<2 x float> %must.be.zero)
+  ret <2 x float> %exp
+}
+
+define nofpclass(pzero) float @source_is_known_pzero(float nofpclass(nan inf 
norm sub nzero) %must.be.pzero) {
+; CHECK-LABEL: define nofpclass(pzero) float @source_is_known_pzero(
+; CHECK-SAME: float nofpclass(nan inf nzero sub norm) [[MUST_BE_PZERO:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float 
[[MUST_BE_PZERO]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %must.be.pzero)
+  ret float %exp
+}
+
+define nofpclass(pzero) float @source_is_known_nzero(float nofpclass(nan inf 
norm sub pzero) %must.be.nzero) {
+; CHECK-LABEL: define nofpclass(pzero) float @source_is_known_nzero(
+; CHECK-SAME: float nofpclass(nan inf pzero sub norm) [[MUST_BE_NZERO:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float 
[[MUST_BE_NZERO]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %must.be.nzero)
+  ret float %exp
+}
+
+define nofpclass(nzero) float @source_is_known_inf(float nofpclass(nan norm 
sub zero) %must.be.inf) {
+; CHECK-LABEL: define nofpclass(nzero) float @source_is_known_inf(
+; CHECK-SAME: float nofpclass(nan zero sub norm) [[MUST_BE_INF:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float [[MUST_BE_INF]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %must.be.inf)
+  ret float %exp
+}
+
+define nofpclass(nzero) <2 x float> @source_is_known_inf_vec(<2 x float> 
nofpclass(nan norm sub zero) %must.be.inf) {
+; CHECK-LABEL: define nofpclass(nzero) <2 x float> @source_is_known_inf_vec(
+; CHECK-SAME: <2 x float> nofpclass(nan zero sub norm) [[MUST_BE_INF:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> 
[[MUST_BE_INF]])
+; CHECK-NEXT:    ret <2 x float> [[EXP]]
+;
+  %exp = call <2 x float> @llvm.exp2.v2f32(<2 x float> %must.be.inf)
+  ret <2 x float> %exp
+}
+
+define nofpclass(nzero) float @source_is_known_pinf(float nofpclass(ninf nan 
norm sub zero) %must.be.pinf) {
+; CHECK-LABEL: define nofpclass(nzero) float @source_is_known_pinf(
+; CHECK-SAME: float nofpclass(nan ninf zero sub norm) [[MUST_BE_PINF:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float 
[[MUST_BE_PINF]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %must.be.pinf)
+  ret float %exp
+}
+
+define nofpclass(nzero) float @source_is_known_ninf(float nofpclass(pinf nan 
norm sub zero) %must.be.ninf) {
+; CHECK-LABEL: define nofpclass(nzero) float @source_is_known_ninf(
+; CHECK-SAME: float nofpclass(nan pinf zero sub norm) [[MUST_BE_NINF:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float 
[[MUST_BE_NINF]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %must.be.ninf)
+  ret float %exp
+}
+
+define nofpclass(nzero) float @source_is_known_nan(float nofpclass(inf norm 
sub zero) %must.be.nan) {
+; CHECK-LABEL: define nofpclass(nzero) float @source_is_known_nan(
+; CHECK-SAME: float nofpclass(inf zero sub norm) [[MUST_BE_NAN:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float [[MUST_BE_NAN]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %must.be.nan)
+  ret float %exp
+}
+
+define nofpclass(nzero) float @source_is_known_inf_or_nan(float nofpclass(norm 
sub zero) %must.be.inf.or.nan) {
+; CHECK-LABEL: define nofpclass(nzero) float @source_is_known_inf_or_nan(
+; CHECK-SAME: float nofpclass(zero sub norm) [[MUST_BE_INF_OR_NAN:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float 
[[MUST_BE_INF_OR_NAN]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %must.be.inf.or.nan)
+  ret float %exp
+}
+
+define nofpclass(nzero nan) float 
@source_is_known_inf_or_nan__nnan_result(float nofpclass(norm sub zero) 
%must.be.inf.or.nan) {
+; CHECK-LABEL: define nofpclass(nan nzero) float 
@source_is_known_inf_or_nan__nnan_result(
+; CHECK-SAME: float nofpclass(zero sub norm) [[MUST_BE_INF_OR_NAN:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float 
[[MUST_BE_INF_OR_NAN]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %must.be.inf.or.nan)
+  ret float %exp
+}
+
+define nofpclass(pzero) float @source_is_known_zero_or_nan(float nofpclass(inf 
norm sub) %must.be.zero.or.nan) {
+; CHECK-LABEL: define nofpclass(pzero) float @source_is_known_zero_or_nan(
+; CHECK-SAME: float nofpclass(inf sub norm) [[MUST_BE_ZERO_OR_NAN:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float 
[[MUST_BE_ZERO_OR_NAN]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %must.be.zero.or.nan)
+  ret float %exp
+}
+
+define nofpclass(pzero) <2 x float> @source_is_known_zero_or_nan_vec(<2 x 
float> nofpclass(inf norm sub) %must.be.zero.or.nan) {
+; CHECK-LABEL: define nofpclass(pzero) <2 x float> 
@source_is_known_zero_or_nan_vec(
+; CHECK-SAME: <2 x float> nofpclass(inf sub norm) [[MUST_BE_ZERO_OR_NAN:%.*]]) 
{
+; CHECK-NEXT:    [[EXP:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> 
[[MUST_BE_ZERO_OR_NAN]])
+; CHECK-NEXT:    ret <2 x float> [[EXP]]
+;
+  %exp = call <2 x float> @llvm.exp2.v2f32(<2 x float> %must.be.zero.or.nan)
+  ret <2 x float> %exp
+}
+
+define nofpclass(nzero) float @source_is_known_snan(float nofpclass(inf norm 
sub zero qnan) %must.be.snan) {
+; CHECK-LABEL: define nofpclass(nzero) float @source_is_known_snan(
+; CHECK-SAME: float nofpclass(qnan inf zero sub norm) [[MUST_BE_SNAN:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float 
[[MUST_BE_SNAN]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %must.be.snan)
+  ret float %exp
+}
+
+define nofpclass(nzero) float @source_is_known_qnan(float nofpclass(inf norm 
sub zero snan) %must.be.qnan) {
+; CHECK-LABEL: define nofpclass(nzero) float @source_is_known_qnan(
+; CHECK-SAME: float nofpclass(snan inf zero sub norm) [[MUST_BE_QNAN:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float 
[[MUST_BE_QNAN]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %must.be.qnan)
+  ret float %exp
+}
+
+define nofpclass(pzero nan) float 
@source_is_known_zero_or_nan__nnan_result(float nofpclass(inf norm sub) 
%must.be.zero.or.nan) {
+; CHECK-LABEL: define nofpclass(nan pzero) float 
@source_is_known_zero_or_nan__nnan_result(
+; CHECK-SAME: float nofpclass(inf sub norm) [[MUST_BE_ZERO_OR_NAN:%.*]]) {
+; CHECK-NEXT:    [[EXP:%.*]] = call float @llvm.exp2.f32(float 
[[MUST_BE_ZERO_OR_NAN]])
+; CHECK-NEXT:    ret float [[EXP]]
+;
+  %exp = call float @llvm.exp2.f32(float %must.be.zero.or.nan)
+  ret float %exp
+}

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to