[llvm] InstCombine: Add baseline SimplifyDemandedFPClass ldexp tests (PR #180702)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 10 00:32:18 PST 2026


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

None

>From 81d3f7fcca7cdbf3251e6c82e410f77c91a31be4 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Mon, 2 Feb 2026 14:47:26 +0100
Subject: [PATCH] InstCombine: Add baseline SimplifyDemandedFPClass ldexp tests

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

diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-ldexp.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-ldexp.ll
new file mode 100644
index 0000000000000..72d687375e946
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-ldexp.ll
@@ -0,0 +1,506 @@
+; 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(nan inf sub norm) float @returns_zero()
+declare nofpclass(nan inf nzero sub norm) float @returns_pzero()
+declare nofpclass(nan inf pzero sub norm) float @returns_nzero()
+declare nofpclass(nan inf norm zero) float @returns_sub()
+declare nofpclass(nan inf norm psub zero) float @returns_nsub()
+declare nofpclass(nan inf norm nsub zero) float @returns_psub()
+declare nofpclass(nan inf sub zero) float @returns_norm()
+declare nofpclass(nan inf pnorm sub zero) float @returns_nnorm()
+declare nofpclass(nan inf nnorm sub zero) float @returns_pnorm()
+declare nofpclass(inf norm sub zero) float @returns_nan()
+declare nofpclass(inf norm sub zero) <2 x float> @returns_nan_vec()
+declare nofpclass(qnan inf norm sub zero) float @returns_snan()
+declare nofpclass(nan norm sub zero) float @returns_inf()
+
+declare nofpclass(ninf nnorm nsub nzero nan) float @returns_positive()
+declare nofpclass(ninf nnorm nsub nzero) float @returns_positive_or_nan()
+
+declare nofpclass(pinf pnorm psub pzero nan) float @returns_negative()
+declare nofpclass(pinf pnorm psub pzero) float @returns_negative_or_nan()
+
+define nofpclass(qnan inf norm sub zero) float @ret_only_snan__ldexp(float %x, i32 %exp) {
+; CHECK-LABEL: define nofpclass(qnan inf zero sub norm) float @ret_only_snan__ldexp(
+; CHECK-SAME: float [[X:%.*]], i32 [[EXP:%.*]]) {
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[EXP]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp)
+  ret float %ldexp
+}
+
+define nofpclass(snan inf norm sub zero) float @ret_only_qnan__ldexp(float %x, i32 %exp) {
+; CHECK-LABEL: define nofpclass(snan inf zero sub norm) float @ret_only_qnan__ldexp(
+; CHECK-SAME: float [[X:%.*]], i32 [[EXP:%.*]]) {
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[EXP]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp)
+  ret float %ldexp
+}
+
+define nofpclass(inf norm sub zero) float @ret_only_nan__ldexp(float %x, i32 %exp) {
+; CHECK-LABEL: define nofpclass(inf zero sub norm) float @ret_only_nan__ldexp(
+; CHECK-SAME: float [[X:%.*]], i32 [[EXP:%.*]]) {
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[EXP]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp)
+  ret float %ldexp
+}
+
+define nofpclass(nan norm sub zero) float @ret_only_inf__ldexp(float %x, i32 %exp) {
+; CHECK-LABEL: define nofpclass(nan zero sub norm) float @ret_only_inf__ldexp(
+; CHECK-SAME: float [[X:%.*]], i32 [[EXP:%.*]]) {
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[EXP]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp)
+  ret float %ldexp
+}
+
+define nofpclass(nan ninf norm sub zero) float @ret_only_pinf__ldexp(float %x, i32 %exp) {
+; CHECK-LABEL: define nofpclass(nan ninf zero sub norm) float @ret_only_pinf__ldexp(
+; CHECK-SAME: float [[X:%.*]], i32 [[EXP:%.*]]) {
+; CHECK-NEXT:    ret float 0x7FF0000000000000
+;
+  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp)
+  ret float %ldexp
+}
+
+define nofpclass(nan pinf norm sub zero) float @ret_only_ninf__ldexp(float %x, i32 %exp) {
+; CHECK-LABEL: define nofpclass(nan pinf zero sub norm) float @ret_only_ninf__ldexp(
+; CHECK-SAME: float [[X:%.*]], i32 [[EXP:%.*]]) {
+; CHECK-NEXT:    ret float 0xFFF0000000000000
+;
+  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp)
+  ret float %ldexp
+}
+
+define nofpclass(inf nan norm sub) float @ret_only_zero__ldexp(float %x, i32 %exp) {
+; CHECK-LABEL: define nofpclass(nan inf sub norm) float @ret_only_zero__ldexp(
+; CHECK-SAME: float [[X:%.*]], i32 [[EXP:%.*]]) {
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[EXP]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp)
+  ret float %ldexp
+}
+
+define nofpclass(inf nan norm sub nzero) float @ret_only_pzero__ldexp(float %x, i32 %exp) {
+; CHECK-LABEL: define nofpclass(nan inf nzero sub norm) float @ret_only_pzero__ldexp(
+; CHECK-SAME: float [[X:%.*]], i32 [[EXP:%.*]]) {
+; CHECK-NEXT:    ret float 0.000000e+00
+;
+  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp)
+  ret float %ldexp
+}
+
+define nofpclass(inf nan norm sub pzero) float @ret_only_nzero__ldexp(float %x, i32 %exp) {
+; CHECK-LABEL: define nofpclass(nan inf pzero sub norm) float @ret_only_nzero__ldexp(
+; CHECK-SAME: float [[X:%.*]], i32 [[EXP:%.*]]) {
+; CHECK-NEXT:    ret float -0.000000e+00
+;
+  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp)
+  ret float %ldexp
+}
+
+define nofpclass(snan) float @ret_nofpclass_snan__ldexp_unknown_unknown(float %x, i32 %exp) {
+; CHECK-LABEL: define nofpclass(snan) float @ret_nofpclass_snan__ldexp_unknown_unknown(
+; CHECK-SAME: float [[X:%.*]], i32 [[EXP:%.*]]) {
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[EXP]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp)
+  ret float %ldexp
+}
+
+define nofpclass(snan) float @ret_nofpclass_snan__ldexp_no_snan_unknown(float nofpclass(snan) %x, i32 %exp) {
+; CHECK-LABEL: define nofpclass(snan) float @ret_nofpclass_snan__ldexp_no_snan_unknown(
+; CHECK-SAME: float nofpclass(snan) [[X:%.*]], i32 [[EXP:%.*]]) {
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[EXP]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp)
+  ret float %ldexp
+}
+
+define nofpclass(nan) float @ret_nofpclass_nan__ldexp_select_nan_or_unknown__unknown(i1 %cond, float %unknown, i32 %exp) {
+; CHECK-LABEL: define nofpclass(nan) float @ret_nofpclass_nan__ldexp_select_nan_or_unknown__unknown(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[EXP:%.*]]) {
+; CHECK-NEXT:    [[NAN:%.*]] = call float @returns_nan()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[NAN]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[EXP]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %nan = call float @returns_nan()
+  %select = select i1 %cond, float %nan, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %exp)
+  ret float %ldexp
+}
+
+define nofpclass(nan) <2 x float> @ret_nofpclass_nan__ldexp_select_nan_or_unknown__unknown_vec(i1 %cond, <2 x float> %unknown, <2 x i32> %exp) {
+; CHECK-LABEL: define nofpclass(nan) <2 x float> @ret_nofpclass_nan__ldexp_select_nan_or_unknown__unknown_vec(
+; CHECK-SAME: i1 [[COND:%.*]], <2 x float> [[UNKNOWN:%.*]], <2 x i32> [[EXP:%.*]]) {
+; CHECK-NEXT:    [[NAN:%.*]] = call <2 x float> @returns_nan_vec()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], <2 x float> [[NAN]], <2 x float> [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[SELECT]], <2 x i32> [[EXP]])
+; CHECK-NEXT:    ret <2 x float> [[LDEXP]]
+;
+  %nan = call <2 x float> @returns_nan_vec()
+  %select = select i1 %cond, <2 x float> %nan, <2 x float> %unknown
+  %ldexp = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %select, <2 x i32> %exp)
+  ret <2 x float> %ldexp
+}
+
+define nofpclass(inf) float @ret_nofpclass_inf__ldexp_select_inf_or_unknown__unknown(i1 %cond, float %unknown, i32 %exp) {
+; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__ldexp_select_inf_or_unknown__unknown(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[EXP:%.*]]) {
+; CHECK-NEXT:    [[INF:%.*]] = call float @returns_inf()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[INF]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[EXP]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %inf = call float @returns_inf()
+  %select = select i1 %cond, float %inf, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %exp)
+  ret float %ldexp
+}
+
+define nofpclass(nan inf norm sub) float @zero_result_demands_sub_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(nan inf sub norm) float @zero_result_demands_sub_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[SUB:%.*]] = call float @returns_sub()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[SUB]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %sub = call float @returns_sub()
+  %select = select i1 %cond, float %sub, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(inf norm psub nzero) float @pzero_result_demands_psub_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(inf nzero psub norm) float @pzero_result_demands_psub_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[PSUB:%.*]] = call float @returns_psub()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[PSUB]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %psub = call float @returns_psub()
+  %select = select i1 %cond, float %psub, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(inf norm nsub pzero) float @nzero_result_demands_nsub_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(inf pzero nsub norm) float @nzero_result_demands_nsub_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[NSUB:%.*]] = call float @returns_nsub()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[NSUB]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %nsub = call float @returns_nsub()
+  %select = select i1 %cond, float %nsub, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(inf norm psub nzero) float @pzero_result_demands_pnorm_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(inf nzero psub norm) float @pzero_result_demands_pnorm_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[PNORM:%.*]] = call float @returns_pnorm()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[PNORM]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %pnorm = call float @returns_pnorm()
+  %select = select i1 %cond, float %pnorm, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(inf norm psub pzero) float @nzero_result_demands_nnorm_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(inf pzero psub norm) float @nzero_result_demands_nnorm_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[NNORM:%.*]] = call float @returns_nnorm()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[NNORM]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %nnorm = call float @returns_nnorm()
+  %select = select i1 %cond, float %nnorm, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(inf norm nsub nzero) float @pzero_result_no_demand_nnorm_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(inf nzero nsub norm) float @pzero_result_no_demand_nnorm_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[NNORM:%.*]] = call float @returns_nnorm()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[NNORM]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %nnorm = call float @returns_nnorm()
+  %select = select i1 %cond, float %nnorm, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(inf norm psub pzero) float @nzero_result_no_demand_pnorm_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(inf pzero psub norm) float @nzero_result_no_demand_pnorm_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[PNORM:%.*]] = call float @returns_pnorm()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[PNORM]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %pnorm = call float @returns_pnorm()
+  %select = select i1 %cond, float %pnorm, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(inf norm sub nzero) float @pzero_result_no_demand_nsub_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(inf nzero sub norm) float @pzero_result_no_demand_nsub_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[NSUB:%.*]] = call float @returns_nsub()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[NSUB]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %nsub = call float @returns_nsub()
+  %select = select i1 %cond, float %nsub, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(inf norm sub pzero) float @nzero_result_no_demand_psub_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(inf pzero sub norm) float @nzero_result_no_demand_psub_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[PSUB:%.*]] = call float @returns_psub()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[PSUB]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %psub = call float @returns_psub()
+  %select = select i1 %cond, float %psub, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(nan inf norm sub) float @zero_result_demands_norm_source_lhs(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(nan inf sub norm) float @zero_result_demands_norm_source_lhs(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[NORM:%.*]] = call float @returns_norm()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[NORM]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %norm = call float @returns_norm()
+  %select = select i1 %cond, float %norm, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(nan inf sub zero) float @norm_result_demands_sub_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(nan inf zero sub) float @norm_result_demands_sub_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[SUB:%.*]] = call float @returns_sub()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[SUB]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %sub = call float @returns_sub()
+  %select = select i1 %cond, float %sub, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(nan norm sub) float @inf_result_demands_sub_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(nan sub norm) float @inf_result_demands_sub_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[SUB:%.*]] = call float @returns_sub()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[SUB]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %sub = call float @returns_sub()
+  %select = select i1 %cond, float %sub, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(nan norm sub) float @inf_result_demands_norm_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(nan sub norm) float @inf_result_demands_norm_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[NORM:%.*]] = call float @returns_norm()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[NORM]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %norm = call float @returns_norm()
+  %select = select i1 %cond, float %norm, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(nan norm sub) float @inf_result_demands_inf_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(nan sub norm) float @inf_result_demands_inf_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[INF:%.*]] = call float @returns_inf()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[INF]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %inf = call float @returns_inf()
+  %select = select i1 %cond, float %inf, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(nan inf sub zero) float @zero_result_no_zero_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(nan inf zero sub) float @zero_result_no_zero_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[ZERO:%.*]] = call float @returns_zero()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[ZERO]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %zero = call float @returns_zero()
+  %select = select i1 %cond, float %zero, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(pinf pnorm psub pzero) float @negative_result_implies_no_positive_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @negative_result_implies_no_positive_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[POS:%.*]] = call float @returns_positive()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[POS]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %pos = call float @returns_positive()
+  %select = select i1 %cond, float %pos, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(ninf nnorm nsub nzero) float @positive_result_implies_no_negative_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @positive_result_implies_no_negative_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[NEG:%.*]] = call float @returns_negative()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[NEG]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %neg = call float @returns_negative()
+  %select = select i1 %cond, float %neg, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(nan pinf pnorm psub pzero) float @negative_nonan_result_implies_no_positive_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(nan pinf pzero psub pnorm) float @negative_nonan_result_implies_no_positive_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[POS_OR_NAN:%.*]] = call float @returns_positive_or_nan()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[POS_OR_NAN]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %pos.or.nan = call float @returns_positive_or_nan()
+  %select = select i1 %cond, float %pos.or.nan, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(nan ninf nnorm nsub nzero) float @positive_nonan_result_implies_no_negative_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @positive_nonan_result_implies_no_negative_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[NEG_OR_NAN:%.*]] = call float @returns_negative_or_nan()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[NEG_OR_NAN]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %neg.or.nan = call float @returns_negative_or_nan()
+  %select = select i1 %cond, float %neg.or.nan, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(nan inf norm sub) float @zero_result_select_inf_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(nan inf sub norm) float @zero_result_select_inf_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[INF:%.*]] = call float @returns_inf()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[INF]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %inf = call float @returns_inf()
+  %select = select i1 %cond, float %inf, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(nan inf norm zero) float @sub_result_select_inf_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(nan inf zero norm) float @sub_result_select_inf_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[INF:%.*]] = call float @returns_inf()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[INF]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %inf = call float @returns_inf()
+  %select = select i1 %cond, float %inf, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(nan inf sub zero) float @norm_result_select_inf_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(nan inf zero sub) float @norm_result_select_inf_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[INF:%.*]] = call float @returns_inf()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[INF]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %inf = call float @returns_inf()
+  %select = select i1 %cond, float %inf, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(nan inf norm sub) float @zero_result_select_zero_source(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(nan inf sub norm) float @zero_result_select_zero_source(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[ZERO:%.*]] = call float @returns_zero()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[ZERO]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %zero = call float @returns_zero()
+  %select = select i1 %cond, float %zero, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}
+
+define nofpclass(snan) float @qnan_result_demands_snan_src(i1 %cond, float %unknown, i32 %unknown.int) {
+; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_src(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) {
+; CHECK-NEXT:    [[SNAN:%.*]] = call float @returns_snan()
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[SNAN]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %snan = call float @returns_snan()
+  %select = select i1 %cond, float %snan, float %unknown
+  %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int)
+  ret float %ldexp
+}



More information about the llvm-commits mailing list