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

None

>From 61a27d9fc529bb533b4c723a6820e9ce21c19526 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <[email protected]>
Date: Mon, 22 Dec 2025 23:01:19 +0100
Subject: [PATCH] InstCombine: Add baseline test for SimplifyDemandedFPClass
 log handling

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

diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-log.ll 
b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-log.ll
new file mode 100644
index 0000000000000..d6f2cab6687ab
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-log.ll
@@ -0,0 +1,269 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 
UTC_ARGS: --version 6
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+
+; -> 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(
+; CHECK-SAME: float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[UNKNOWN]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %result = call float @llvm.log.f32(float %unknown)
+  ret float %result
+}
+
+; -> +0
+define nofpclass(nan inf norm sub) float @ret_nofpclass_only_zero__log(float 
%unknown) {
+; CHECK-LABEL: define nofpclass(nan inf sub norm) float 
@ret_nofpclass_only_zero__log(
+; CHECK-SAME: float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[UNKNOWN]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %result = call float @llvm.log.f32(float %unknown)
+  ret float %result
+}
+
+; -> +0
+define nofpclass(nan inf norm sub nzero) float 
@ret_nofpclass_only_pzero__log(float %unknown) {
+; CHECK-LABEL: define nofpclass(nan inf nzero sub norm) float 
@ret_nofpclass_only_pzero__log(
+; CHECK-SAME: float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    ret float 0.000000e+00
+;
+  %result = call float @llvm.log.f32(float %unknown)
+  ret float %result
+}
+
+; -> pinf
+define nofpclass(nan ninf norm sub zero) float 
@ret_nofpclass_only_pinf__log(float %unknown) {
+; CHECK-LABEL: define nofpclass(nan ninf zero sub norm) float 
@ret_nofpclass_only_pinf__log(
+; CHECK-SAME: float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    ret float 0x7FF0000000000000
+;
+  %result = call float @llvm.log.f32(float %unknown)
+  ret float %result
+}
+
+; -> ninf
+define nofpclass(nan pinf norm sub zero) float 
@ret_nofpclass_only_ninf__log(float %unknown) {
+; CHECK-LABEL: define nofpclass(nan pinf zero sub norm) float 
@ret_nofpclass_only_ninf__log(
+; CHECK-SAME: float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    ret float 0xFFF0000000000000
+;
+  %result = call float @llvm.log.f32(float %unknown)
+  ret float %result
+}
+
+; log cannot return -0, -> poison
+define nofpclass(nan inf norm sub pzero) float 
@ret_nofpclass_only_nzero__log(float %unknown) {
+; CHECK-LABEL: define nofpclass(nan inf pzero sub norm) float 
@ret_nofpclass_only_nzero__log(
+; CHECK-SAME: float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    ret float -0.000000e+00
+;
+  %result = call float @llvm.log.f32(float %unknown)
+  ret float %result
+}
+
+define nofpclass(nan norm sub zero) float @ret_nofpclass_only_inf__log(float 
%unknown) {
+; CHECK-LABEL: define nofpclass(nan zero sub norm) float 
@ret_nofpclass_only_inf__log(
+; CHECK-SAME: float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[UNKNOWN]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %result = call float @llvm.log.f32(float %unknown)
+  ret float %result
+}
+
+define nofpclass(norm sub zero) float @ret_nofpclass_only_inf_nan__log(float 
%unknown) {
+; CHECK-LABEL: define nofpclass(zero sub norm) float 
@ret_nofpclass_only_inf_nan__log(
+; CHECK-SAME: float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[UNKNOWN]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %result = call float @llvm.log.f32(float %unknown)
+  ret float %result
+}
+
+; Return implies argument cannot be 0, fold to just log
+define nofpclass(ninf) float @ret_nofpclass_ninf_log(i1 %cond, float %x) {
+; CHECK-LABEL: define nofpclass(ninf) float @ret_nofpclass_ninf_log(
+; CHECK-SAME: i1 [[COND:%.*]], float [[X:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float 0.000000e+00, 
float [[X]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %select = select i1 %cond, float 0.0, float %x
+  %result = call float @llvm.log.f32(float %select)
+  ret float %result
+}
+
+; -> only log
+define nofpclass(pinf) float @ret_nofpclass_pinf_log_select_inf_or_unknown(i1 
%cond, float %unknown) {
+; CHECK-LABEL: define nofpclass(pinf) float 
@ret_nofpclass_pinf_log_select_inf_or_unknown(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float 
0x7FF0000000000000, float [[UNKNOWN]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %select = select i1 %cond, float 0x7ff0000000000000, float %unknown
+  %result = call float @llvm.log.f32(float %select)
+  ret float %result
+}
+
+; Check log2 is handled, -> only log2
+define nofpclass(pinf) float @ret_nofpclass_pinf_log2_select_inf_or_unknown(i1 
%cond, float %unknown) {
+; CHECK-LABEL: define nofpclass(pinf) float 
@ret_nofpclass_pinf_log2_select_inf_or_unknown(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float 
0x7FF0000000000000, float [[UNKNOWN]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.log2.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %select = select i1 %cond, float 0x7ff0000000000000, float %unknown
+  %result = call float @llvm.log2.f32(float %select)
+  ret float %result
+}
+
+; Check log10 is handled, -> only log10
+define nofpclass(pinf) float 
@ret_nofpclass_pinf_log10_select_inf_or_unknown(i1 %cond, float %unknown) {
+; CHECK-LABEL: define nofpclass(pinf) float 
@ret_nofpclass_pinf_log10_select_inf_or_unknown(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float 
0x7FF0000000000000, float [[UNKNOWN]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.log10.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %select = select i1 %cond, float 0x7ff0000000000000, float %unknown
+  %result = call float @llvm.log10.f32(float %select)
+  ret float %result
+}
+
+; -> only log
+define nofpclass(ninf norm zero) float 
@ret_nofpclass_nan_or_sub__log_select__finite_positive__unknown(i1 %cond, float 
nofpclass(inf nnorm nsub nan) %must.be.finite.positive, float %unknown) {
+; CHECK-LABEL: define nofpclass(ninf zero norm) float 
@ret_nofpclass_nan_or_sub__log_select__finite_positive__unknown(
+; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan inf nsub nnorm) 
[[MUST_BE_FINITE_POSITIVE:%.*]], float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float 
[[MUST_BE_FINITE_POSITIVE]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %select = select i1 %cond, float %must.be.finite.positive, float %unknown
+  %result = call float @llvm.log.f32(float %select)
+  ret float %result
+}
+
+; Cannot fold out due to subnormal input on first argument
+define nofpclass(ninf norm zero) float 
@ret_nofpclass_nan_or_sub__log_select__finite_positive_or_sub__unknown(i1 
%cond, float nofpclass(inf nnorm nan) %must.be.finite.positive.or.sub, float 
%unknown) {
+; CHECK-LABEL: define nofpclass(ninf zero norm) float 
@ret_nofpclass_nan_or_sub__log_select__finite_positive_or_sub__unknown(
+; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan inf nnorm) 
[[MUST_BE_FINITE_POSITIVE_OR_SUB:%.*]], float [[UNKNOWN:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float 
[[MUST_BE_FINITE_POSITIVE_OR_SUB]], float [[UNKNOWN]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %select = select i1 %cond, float %must.be.finite.positive.or.sub, float 
%unknown
+  %result = call float @llvm.log.f32(float %select)
+  ret float %result
+}
+
+; Fold out select
+define nofpclass(pinf nan norm zero) float 
@ret_ninf_or_sub__log_select__pinf_or_sub_orzero__else_not0__ieee(i1 %cond, 
float nofpclass(ninf norm nan) %must.be.pinf.or.sub.or.zero, float 
nofpclass(zero) %not.zero) {
+; CHECK-LABEL: define nofpclass(nan pinf zero norm) float 
@ret_ninf_or_sub__log_select__pinf_or_sub_orzero__else_not0__ieee(
+; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan ninf norm) 
[[MUST_BE_PINF_OR_SUB_OR_ZERO:%.*]], float nofpclass(zero) [[NOT_ZERO:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float 
[[MUST_BE_PINF_OR_SUB_OR_ZERO]], float [[NOT_ZERO]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %select = select i1 %cond, float %must.be.pinf.or.sub.or.zero, float 
%not.zero
+  %result = call float @llvm.log.f32(float %select)
+  ret float %result
+}
+
+; Must keep select
+define nofpclass(pinf nan norm zero) float 
@ret_ninf_or_sub__log_select__pinf_or_sub_orzero__else_not0__daz(i1 %cond, 
float nofpclass(ninf norm nan) %must.be.pinf.or.sub.or.zero, float 
nofpclass(zero) %not.zero) #0 {
+; CHECK-LABEL: define nofpclass(nan pinf zero norm) float 
@ret_ninf_or_sub__log_select__pinf_or_sub_orzero__else_not0__daz(
+; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan ninf norm) 
[[MUST_BE_PINF_OR_SUB_OR_ZERO:%.*]], float nofpclass(zero) [[NOT_ZERO:%.*]]) 
#[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float 
[[MUST_BE_PINF_OR_SUB_OR_ZERO]], float [[NOT_ZERO]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %select = select i1 %cond, float %must.be.pinf.or.sub.or.zero, float 
%not.zero
+  %result = call float @llvm.log.f32(float %select)
+  ret float %result
+}
+
+; Must keep select
+define nofpclass(pinf nan norm zero) float 
@ret_ninf_or_sub__log_select__pinf_or_sub_orzero__else_not0__dynamic(i1 %cond, 
float nofpclass(ninf norm nan) %must.be.pinf.or.sub.or.zero, float 
nofpclass(zero) %not.zero) #1 {
+; CHECK-LABEL: define nofpclass(nan pinf zero norm) float 
@ret_ninf_or_sub__log_select__pinf_or_sub_orzero__else_not0__dynamic(
+; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan ninf norm) 
[[MUST_BE_PINF_OR_SUB_OR_ZERO:%.*]], float nofpclass(zero) [[NOT_ZERO:%.*]]) 
#[[ATTR1:[0-9]+]] {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float 
[[MUST_BE_PINF_OR_SUB_OR_ZERO]], float [[NOT_ZERO]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %select = select i1 %cond, float %must.be.pinf.or.sub.or.zero, float 
%not.zero
+  %result = call float @llvm.log.f32(float %select)
+  ret float %result
+}
+
+; Fold to select unknown
+define nofpclass(inf nan pnorm sub zero) float 
@ret_only_nnorm__log__select_unknown_or_infnan(i1 %cond, float %unknown, float 
nofpclass(norm sub zero) %b) {
+; CHECK-LABEL: define nofpclass(nan inf zero sub pnorm) float 
@ret_only_nnorm__log__select_unknown_or_infnan(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], float nofpclass(zero sub 
norm) [[B:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[UNKNOWN]], float 
[[B]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %select = select i1 %cond, float %unknown, float %b
+  %result = call float @llvm.log.f32(float %select)
+  ret float %result
+}
+
+; Fold to select unknown
+define nofpclass(inf nan nnorm sub zero) float 
@ret_only_pnorm__log__select_unknown_or_infnan(i1 %cond, float %unknown, float 
nofpclass(norm sub zero) %b) {
+; CHECK-LABEL: define nofpclass(nan inf zero sub nnorm) float 
@ret_only_pnorm__log__select_unknown_or_infnan(
+; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], float nofpclass(zero sub 
norm) [[B:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[UNKNOWN]], float 
[[B]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %select = select i1 %cond, float %unknown, float %b
+  %result = call float @llvm.log.f32(float %select)
+  ret float %result
+}
+
+; Keep select
+define nofpclass(nan inf norm) float 
@ret_only_zero_sub__log__select_pnormnan_or_unknown(i1 %cond, float 
nofpclass(inf sub zero nnorm) %pnorm.or.nan, float %b) {
+; CHECK-LABEL: define nofpclass(nan inf norm) float 
@ret_only_zero_sub__log__select_pnormnan_or_unknown(
+; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(inf zero sub nnorm) 
[[PNORM_OR_NAN:%.*]], float [[B:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[PNORM_OR_NAN]], 
float [[B]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %select = select i1 %cond, float %pnorm.or.nan, float %b
+  %result = call float @llvm.log.f32(float %select)
+  ret float %result
+}
+
+; Keep select
+define nofpclass(nan inf norm) float 
@ret_only_zero_sub__log__select_nnormnan_or_unknown(i1 %cond, float 
nofpclass(inf sub zero pnorm) %nnorm.or.nan, float %b) {
+; CHECK-LABEL: define nofpclass(nan inf norm) float 
@ret_only_zero_sub__log__select_nnormnan_or_unknown(
+; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(inf zero sub pnorm) 
[[NNORM_OR_NAN:%.*]], float [[B:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[NNORM_OR_NAN]], 
float [[B]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %select = select i1 %cond, float %nnorm.or.nan, float %b
+  %result = call float @llvm.log.f32(float %select)
+  ret float %result
+}
+
+; Keep select, 0 result implies it could be 1
+define nofpclass(inf norm sub) float 
@ret_only_zero_nan__log__select_maybe_pnorm__else_negative_or_zero(i1 %cond, 
float nofpclass(nan inf sub zero nnorm) %maybe.pnorm, float nofpclass(nan pinf 
pnorm psub) %negative.or.zero) {
+; CHECK-LABEL: define nofpclass(inf sub norm) float 
@ret_only_zero_nan__log__select_maybe_pnorm__else_negative_or_zero(
+; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan inf zero sub nnorm) 
[[MAYBE_PNORM:%.*]], float nofpclass(nan pinf psub pnorm) 
[[NEGATIVE_OR_ZERO:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[MAYBE_PNORM]], 
float [[NEGATIVE_OR_ZERO]]
+; CHECK-NEXT:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[SELECT]])
+; CHECK-NEXT:    ret float [[RESULT]]
+;
+  %select = select i1 %cond, float %maybe.pnorm, float %negative.or.zero
+  %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" }

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

Reply via email to