llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Matt Arsenault (arsenm)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/173881.diff


6 Files Affected:

- (modified) llvm/include/llvm/ADT/FloatingPointMode.h (+5) 
- (modified) llvm/include/llvm/Support/KnownFPClass.h (+4) 
- (modified) llvm/lib/Analysis/ValueTracking.cpp (+3-15) 
- (modified) llvm/lib/Support/KnownFPClass.cpp (+17) 
- (modified) llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp 
(+37) 
- (modified) llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-log.ll 
(+12-23) 


``````````diff
diff --git a/llvm/include/llvm/ADT/FloatingPointMode.h 
b/llvm/include/llvm/ADT/FloatingPointMode.h
index a9702c65e631f..0605e0b4f4cf9 100644
--- a/llvm/include/llvm/ADT/FloatingPointMode.h
+++ b/llvm/include/llvm/ADT/FloatingPointMode.h
@@ -153,6 +153,11 @@ struct DenormalMode {
            Input == DenormalModeKind::PositiveZero;
   }
 
+  /// Return true if input denormals may be implicitly treated as 0.
+  constexpr bool inputsMayBeZero() const {
+    return inputsAreZero() || Input == DenormalMode::Dynamic;
+  }
+
   /// Return true if output denormals should be flushed to 0.
   constexpr bool outputsAreZero() const {
     return Output == DenormalModeKind::PreserveSign ||
diff --git a/llvm/include/llvm/Support/KnownFPClass.h 
b/llvm/include/llvm/Support/KnownFPClass.h
index 62df87ad8a67e..07d74f2867089 100644
--- a/llvm/include/llvm/Support/KnownFPClass.h
+++ b/llvm/include/llvm/Support/KnownFPClass.h
@@ -263,6 +263,10 @@ struct KnownFPClass {
   LLVM_ABI void propagateCanonicalizingSrc(const KnownFPClass &Src,
                                            DenormalMode Mode);
 
+  /// Propagate known class for log/log2/log10
+  static LLVM_ABI KnownFPClass
+  log(const KnownFPClass &Src, DenormalMode Mode = DenormalMode::getDynamic());
+
   void resetAll() { *this = KnownFPClass(); }
 };
 
diff --git a/llvm/lib/Analysis/ValueTracking.cpp 
b/llvm/lib/Analysis/ValueTracking.cpp
index cddd6f9c25074..bac863cb3c67c 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5391,22 +5391,10 @@ void computeKnownFPClass(const Value *V, const APInt 
&DemandedElts,
       computeKnownFPClass(II->getArgOperand(0), DemandedElts, InterestedSrcs,
                           KnownSrc, Q, Depth + 1);
 
-      if (KnownSrc.isKnownNeverPosInfinity())
-        Known.knownNot(fcPosInf);
-
-      if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
-        Known.knownNot(fcNan);
-
       const Function *F = II->getFunction();
-      if (!F)
-        break;
-
-      const fltSemantics &FltSem = EltTy->getFltSemantics();
-      DenormalMode Mode = F->getDenormalMode(FltSem);
-
-      if (KnownSrc.isKnownNeverLogicalZero(Mode))
-        Known.knownNot(fcNegInf);
-
+      DenormalMode Mode = F ? F->getDenormalMode(EltTy->getFltSemantics())
+                            : DenormalMode::getDynamic();
+      Known = KnownFPClass::log(KnownSrc, Mode);
       break;
     }
     case Intrinsic::powi: {
diff --git a/llvm/lib/Support/KnownFPClass.cpp 
b/llvm/lib/Support/KnownFPClass.cpp
index 125bee00c38ff..ff98908fdb2c4 100644
--- a/llvm/lib/Support/KnownFPClass.cpp
+++ b/llvm/lib/Support/KnownFPClass.cpp
@@ -226,3 +226,20 @@ void KnownFPClass::propagateCanonicalizingSrc(const 
KnownFPClass &Src,
   propagateDenormal(Src, Mode);
   propagateNaN(Src, /*PreserveSign=*/true);
 }
+
+KnownFPClass KnownFPClass::log(const KnownFPClass &KnownSrc,
+                               DenormalMode Mode) {
+  KnownFPClass Known;
+  Known.knownNot(fcNegZero);
+
+  if (KnownSrc.isKnownNeverPosInfinity())
+    Known.knownNot(fcPosInf);
+
+  if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
+    Known.knownNot(fcNan);
+
+  if (KnownSrc.isKnownNeverLogicalZero(Mode))
+    Known.knownNot(fcNegInf);
+
+  return Known;
+}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 33ece6c2b69d8..3cb4c629b9108 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2202,6 +2202,43 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Value *V,
       Known = KnownFPClass::exp(KnownSrc);
       break;
     }
+    case Intrinsic::log:
+    case Intrinsic::log2:
+    case Intrinsic::log10: {
+      FPClassTest DemandedSrcMask = DemandedMask & (fcNan | fcPosInf);
+
+      Type *EltTy = VTy->getScalarType();
+      DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
+
+      // log(x < 0) = nan
+      if (DemandedMask & fcNan)
+        DemandedSrcMask |= (fcNegative & ~fcNegZero);
+
+      // log(0) = -inf
+      if (DemandedMask & fcNegInf) {
+        DemandedSrcMask |= fcZero;
+
+        // No value produces subnormal result.
+        if (Mode.inputsMayBeZero())
+          DemandedSrcMask |= fcSubnormal;
+      }
+
+      if (DemandedMask & fcNormal)
+        DemandedSrcMask |= fcNormal | fcSubnormal;
+
+      // log(1) = 0
+      if (DemandedMask & fcZero)
+        DemandedSrcMask |= fcPosNormal;
+
+      KnownFPClass KnownSrc;
+      if (SimplifyDemandedFPClass(I, 0, DemandedSrcMask, KnownSrc, Depth + 1))
+        return I;
+
+      Known = KnownFPClass::log(KnownSrc, Mode);
+
+      FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+      return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+    }
     case Intrinsic::canonicalize: {
       Type *EltTy = VTy->getScalarType();
 
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-log.ll 
b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-log.ll
index d6f2cab6687ab..87973fa36b478 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-log.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-log.ll
@@ -5,8 +5,7 @@
 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]]
+; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %result = call float @llvm.log.f32(float %unknown)
   ret float %result
@@ -16,8 +15,7 @@ define nofpclass(inf norm sub zero) float 
@ret_nofpclass_only_nan__log(float %un
 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]]
+; CHECK-NEXT:    ret float 0.000000e+00
 ;
   %result = call float @llvm.log.f32(float %unknown)
   ret float %result
@@ -57,7 +55,7 @@ define nofpclass(nan pinf norm sub zero) float 
@ret_nofpclass_only_ninf__log(flo
 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
+; CHECK-NEXT:    ret float poison
 ;
   %result = call float @llvm.log.f32(float %unknown)
   ret float %result
@@ -87,8 +85,7 @@ define nofpclass(norm sub zero) float 
@ret_nofpclass_only_inf_nan__log(float %un
 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:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[X]])
 ; CHECK-NEXT:    ret float [[RESULT]]
 ;
   %select = select i1 %cond, float 0.0, float %x
@@ -100,8 +97,7 @@ define nofpclass(ninf) float @ret_nofpclass_ninf_log(i1 
%cond, float %x) {
 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:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[UNKNOWN]])
 ; CHECK-NEXT:    ret float [[RESULT]]
 ;
   %select = select i1 %cond, float 0x7ff0000000000000, float %unknown
@@ -113,8 +109,7 @@ define nofpclass(pinf) float 
@ret_nofpclass_pinf_log_select_inf_or_unknown(i1 %c
 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:    [[RESULT:%.*]] = call float @llvm.log2.f32(float [[UNKNOWN]])
 ; CHECK-NEXT:    ret float [[RESULT]]
 ;
   %select = select i1 %cond, float 0x7ff0000000000000, float %unknown
@@ -126,8 +121,7 @@ define nofpclass(pinf) float 
@ret_nofpclass_pinf_log2_select_inf_or_unknown(i1 %
 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:    [[RESULT:%.*]] = call float @llvm.log10.f32(float [[UNKNOWN]])
 ; CHECK-NEXT:    ret float [[RESULT]]
 ;
   %select = select i1 %cond, float 0x7ff0000000000000, float %unknown
@@ -139,8 +133,7 @@ define nofpclass(pinf) float 
@ret_nofpclass_pinf_log10_select_inf_or_unknown(i1
 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:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[UNKNOWN]])
 ; CHECK-NEXT:    ret float [[RESULT]]
 ;
   %select = select i1 %cond, float %must.be.finite.positive, float %unknown
@@ -165,8 +158,7 @@ define nofpclass(ninf norm zero) float 
@ret_nofpclass_nan_or_sub__log_select__fi
 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:    [[RESULT:%.*]] = call float @llvm.log.f32(float 
[[MUST_BE_PINF_OR_SUB_OR_ZERO]])
 ; CHECK-NEXT:    ret float [[RESULT]]
 ;
   %select = select i1 %cond, float %must.be.pinf.or.sub.or.zero, float 
%not.zero
@@ -204,8 +196,7 @@ define nofpclass(pinf nan norm zero) float 
@ret_ninf_or_sub__log_select__pinf_or
 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:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[UNKNOWN]])
 ; CHECK-NEXT:    ret float [[RESULT]]
 ;
   %select = select i1 %cond, float %unknown, float %b
@@ -217,8 +208,7 @@ define nofpclass(inf nan pnorm sub zero) float 
@ret_only_nnorm__log__select_unkn
 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:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[UNKNOWN]])
 ; CHECK-NEXT:    ret float [[RESULT]]
 ;
   %select = select i1 %cond, float %unknown, float %b
@@ -243,8 +233,7 @@ define nofpclass(nan inf norm) float 
@ret_only_zero_sub__log__select_pnormnan_or
 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:    [[RESULT:%.*]] = call float @llvm.log.f32(float [[B]])
 ; CHECK-NEXT:    ret float [[RESULT]]
 ;
   %select = select i1 %cond, float %nnorm.or.nan, float %b

``````````

</details>


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

Reply via email to