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

Try to restrict the known range of the exponent result of llvm.frexp
based on dominating conditions. Identify comparisons that imply the
incoming value cannot introduce an overflow in a downstream ldexp
use. This pattern appears in the implementation of some complex math
functions and allows finite only math to prune out more edge case
paths.

One attributor test for ldexp regresses due to the switch from
computeKnownBits to computeConstantRange. computeConstantRange
does not try to handle non-splat vector constants for the binary
operators.

As a side effect, this also improves knowing that ldexp can't
introduce overflow for the 0 case.

>From 6c01d0862d475620ef035555cc8074cca5ed8e9f Mon Sep 17 00:00:00 2001
From: Matt Arsenault <[email protected]>
Date: Sun, 12 Apr 2026 14:14:27 +0200
Subject: [PATCH] ValueTracking: Improve frexp known range from dominating
 conditions

Try to restrict the known range of the exponent result of llvm.frexp
based on dominating conditions. Identify comparisons that imply the
incoming value cannot introduce an overflow in a downstream ldexp
use. This pattern appears in the implementation of some complex math
functions and allows finite only math to prune out more edge case
paths.

One attributor test for ldexp regresses due to the switch from
computeKnownBits to computeConstantRange. computeConstantRange
does not try to handle non-splat vector constants for the binary
operators.

As a side effect, this also improves knowing that ldexp can't
introduce overflow for the 0 case.
---
 llvm/include/llvm/Support/KnownFPClass.h      |  14 ++-
 llvm/lib/Analysis/ValueTracking.cpp           |  71 +++++++++--
 llvm/lib/Support/KnownFPClass.cpp             |  19 ++-
 .../Transforms/Attributor/nofpclass-ldexp.ll  |  29 ++++-
 ...ed-exponent-range-dominating-conditions.ll | 112 +++++-------------
 5 files changed, 140 insertions(+), 105 deletions(-)

diff --git a/llvm/include/llvm/Support/KnownFPClass.h 
b/llvm/include/llvm/Support/KnownFPClass.h
index 7e018d25d2d1d..0b948e799f6c5 100644
--- a/llvm/include/llvm/Support/KnownFPClass.h
+++ b/llvm/include/llvm/Support/KnownFPClass.h
@@ -448,10 +448,16 @@ struct KnownFPClass {
   static LLVM_ABI KnownFPClass frexp_mant(
       const KnownFPClass &Src, DenormalMode Mode = DenormalMode::getDynamic());
 
-  /// Propagate known class for ldexp
-  static LLVM_ABI KnownFPClass
-  ldexp(const KnownFPClass &Src, const KnownBits &N, const fltSemantics &Flt,
-        DenormalMode Mode = DenormalMode::getDynamic());
+  /// Propagate known class for ldexp, assuming the exponent is known to be
+  /// within [\p ConstantRangeMin, \p ConstantRangeMax]
+  ///
+  // TODO: This really ought to use ConstantRange, but it's in IR not Support.
+  static LLVM_ABI KnownFPClass ldexp(
+      const KnownFPClass &Src, int ConstantRangeMin, int ConstantRangeMax,
+      const fltSemantics &Flt, DenormalMode Mode = DenormalMode::getDynamic());
+  static LLVM_ABI KnownFPClass ldexp(
+      const KnownFPClass &Src, const KnownBits &ExpBits,
+      const fltSemantics &Flt, DenormalMode Mode = DenormalMode::getDynamic());
 
   /// Propagate known class for powi
   static LLVM_ABI KnownFPClass powi(const KnownFPClass &Src,
diff --git a/llvm/lib/Analysis/ValueTracking.cpp 
b/llvm/lib/Analysis/ValueTracking.cpp
index 5cbf9f628867f..97948a15f9384 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4867,6 +4867,50 @@ static void computeKnownFPClassFromCond(const Value *V, 
Value *Cond,
   }
 }
 
+/// Compute the minimum and maximum values (inclusive) for the exponent of \p 
V,
+/// assuming it is not nan.
+static std::pair<int, int>
+computeKnownExponentRangeFromContext(const Value *V, const SimplifyQuery &Q) {
+  if (!Q.CxtI || !Q.DC || !Q.DT)
+    return {APFloat::IEK_NaN, APFloat::IEK_Inf};
+
+  for (CondBrInst *BI : Q.DC->conditionsFor(V)) {
+    const Value *A;
+    CmpPredicate Pred;
+    const APFloat *LimitC;
+    if (!match(BI->getCondition(),
+               m_FCmp(Pred, m_FAbs(m_Value(A)), m_Finite(LimitC))))
+      continue;
+
+    if (Pred == FCmpInst::FCMP_ORD || Pred == FCmpInst::FCMP_UNO ||
+        Pred == FCmpInst::FCMP_TRUE || Pred == FCmpInst::FCMP_FALSE)
+      continue;
+
+    APFloat::cmpResult CmpOne =
+        LimitC->compare(APFloat::getOne(LimitC->getSemantics()));
+    if (CmpOne > APFloat::cmpEqual)
+      continue;
+
+    // If fabs(x) <= K, K <= 1.0 => exponent min exp range
+    // if fabs(x) >= K, K <= 1.0 swap the successor
+    bool IsLessEqual =
+        Pred == FCmpInst::FCMP_OLT || Pred == FCmpInst::FCMP_OLE ||
+        Pred == FCmpInst::FCMP_ULT || Pred == FCmpInst::FCMP_ULE ||
+        Pred == FCmpInst::FCMP_OEQ || Pred == FCmpInst::FCMP_UEQ;
+
+    BasicBlockEdge Edge1(BI->getParent(),
+                         BI->getSuccessor(IsLessEqual ? 0 : 1));
+    if (Q.DT->dominates(Edge1, Q.CxtI->getParent())) {
+      int Exp = ilogb(*LimitC);
+
+      // TODO: Figure out lower bound to detect no-underflow.
+      return {APFloat::IEK_NaN, Exp};
+    }
+  }
+
+  return {APFloat::IEK_NaN, APFloat::IEK_Inf};
+}
+
 static KnownFPClass computeKnownFPClassFromContext(const Value *V,
                                                    const SimplifyQuery &Q) {
   KnownFPClass KnownFromContext;
@@ -4990,6 +5034,7 @@ static constexpr KnownFPClass::MinMaxKind 
getMinMaxKind(Intrinsic::ID IID) {
 static bool isAbsoluteValueULEOne(const Value *V) {
   // TODO: Handle frexp
   // TODO: Other rounding intrinsics?
+  // TODO: Try computeKnownExponentRangeFromContext
 
   // fabs(x - floor(x)) <= 1
   const Value *SubFloorX;
@@ -5507,11 +5552,11 @@ void computeKnownFPClass(const Value *V, const APInt 
&DemandedElts,
       // Can refine inf/zero handling based on the exponent operand.
       const FPClassTest ExpInfoMask = fcZero | fcSubnormal | fcInf;
 
-      KnownBits ExpBits;
-      if ((KnownSrc.KnownFPClasses & ExpInfoMask) != fcNone) {
-        const Value *ExpArg = II->getArgOperand(1);
-        ExpBits = computeKnownBits(ExpArg, DemandedElts, Q, Depth + 1);
-      }
+      const Value *ExpArg = II->getArgOperand(1);
+      ConstantRange ExpKnownRange =
+          ((KnownSrc.KnownFPClasses & ExpInfoMask) != fcNone)
+              ? computeConstantRange(ExpArg, /*ForSigned=*/true, Q, Depth + 1)
+              : 
ConstantRange::getFull(ExpArg->getType()->getIntegerBitWidth());
 
       const fltSemantics &Flt =
           II->getType()->getScalarType()->getFltSemantics();
@@ -5520,7 +5565,9 @@ void computeKnownFPClass(const Value *V, const APInt 
&DemandedElts,
       DenormalMode Mode =
           F ? F->getDenormalMode(Flt) : DenormalMode::getDynamic();
 
-      Known = KnownFPClass::ldexp(KnownSrc, ExpBits, Flt, Mode);
+      Known = KnownFPClass::ldexp(
+          KnownSrc, ExpKnownRange.getSignedMin().getSExtValue(),
+          ExpKnownRange.getSignedMax().getSExtValue(), Flt, Mode);
       break;
     }
     case Intrinsic::arithmetic_fence: {
@@ -10473,9 +10520,17 @@ ConstantRange llvm::computeConstantRange(const Value 
*V, bool ForSigned,
           MinExp -= (APFloat::semanticsPrecision(FltSem) - 1);
 
         int MaxExp = APFloat::semanticsMaxExponent(FltSem) + 1;
+
+        auto [AdjustedMin, AdjustedMax] =
+            computeKnownExponentRangeFromContext(FrexpSrc, SQ);
+
+        MinExp = std::max(AdjustedMin, MinExp);
+        MaxExp = std::min(AdjustedMax, MaxExp);
+
         CR = ConstantRange::getNonEmpty(
-            APInt(BitWidth, MinExp, /*isSigned=*/true),
-            APInt(BitWidth, MaxExp + 1, /*isSigned=*/true));
+            APInt(BitWidth, static_cast<int64_t>(MinExp), /*isSigned=*/true),
+            APInt(BitWidth, static_cast<int64_t>(MaxExp) + 1,
+                  /*isSigned=*/true));
       }
     }
   }
diff --git a/llvm/lib/Support/KnownFPClass.cpp 
b/llvm/lib/Support/KnownFPClass.cpp
index 38762f05d74ac..c9f081482390b 100644
--- a/llvm/lib/Support/KnownFPClass.cpp
+++ b/llvm/lib/Support/KnownFPClass.cpp
@@ -789,7 +789,8 @@ KnownFPClass KnownFPClass::frexp_mant(const KnownFPClass 
&KnownSrc,
 }
 
 KnownFPClass KnownFPClass::ldexp(const KnownFPClass &KnownSrc,
-                                 const KnownBits &ExpBits,
+                                 int ConstantRangeExpMin,
+                                 int ConstantRangeExpMax,
                                  const fltSemantics &Flt, DenormalMode Mode) {
   KnownFPClass Known;
   Known.propagateNaN(KnownSrc, /*PropagateSign=*/true);
@@ -807,20 +808,19 @@ KnownFPClass KnownFPClass::ldexp(const KnownFPClass 
&KnownSrc,
 
   unsigned Precision = APFloat::semanticsPrecision(Flt);
   const int MantissaBits = Precision - 1;
-
-  if (ExpBits.getSignedMinValue().sge(static_cast<int64_t>(MantissaBits)))
+  if (ConstantRangeExpMin >= MantissaBits)
     Known.knownNot(fcSubnormal);
 
-  if (ExpBits.isConstant() && ExpBits.getConstant().isZero()) {
+  if (ConstantRangeExpMin == 0 && ConstantRangeExpMax == 0) {
     // ldexp(x, 0) -> x, so propagate everything.
     Known.propagateCanonicalizingSrc(KnownSrc, Mode);
-  } else if (ExpBits.isNegative()) {
+  } else if (ConstantRangeExpMax <= 0) {
     // If we know the power is <= 0, can't introduce inf
     if (KnownSrc.isKnownNeverPosInfinity())
       Known.knownNot(fcPosInf);
     if (KnownSrc.isKnownNeverNegInfinity())
       Known.knownNot(fcNegInf);
-  } else if (ExpBits.isNonNegative()) {
+  } else if (ConstantRangeExpMin >= 0) {
     // If we know the power is >= 0, can't introduce subnormal or zero
     if (KnownSrc.isKnownNeverPosSubnormal())
       Known.knownNot(fcPosSubnormal);
@@ -835,6 +835,13 @@ KnownFPClass KnownFPClass::ldexp(const KnownFPClass 
&KnownSrc,
   return Known;
 }
 
+KnownFPClass KnownFPClass::ldexp(const KnownFPClass &KnownSrc,
+                                 const KnownBits &ExpBits,
+                                 const fltSemantics &Flt, DenormalMode Mode) {
+  return ldexp(KnownSrc, ExpBits.getSignedMinValue().getSExtValue(),
+               ExpBits.getSignedMaxValue().getSExtValue(), Flt, Mode);
+}
+
 KnownFPClass KnownFPClass::powi(const KnownFPClass &KnownSrc,
                                 const KnownBits &ExponentKnownBits) {
   KnownFPClass Known;
diff --git a/llvm/test/Transforms/Attributor/nofpclass-ldexp.ll 
b/llvm/test/Transforms/Attributor/nofpclass-ldexp.ll
index 1d8c7af63c4fe..630e510a12d72 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-ldexp.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-ldexp.ll
@@ -701,12 +701,25 @@ define <2 x float> 
@ret_ldexp_v2f32_known_pos_exp_noinf(<2 x float> nofpclass(in
   ret <2 x float> %call
 }
 
-define <2 x float> @ret_ldexp_v2f32_known_neg_exp_noinf(<2 x float> 
nofpclass(inf) %arg0, <2 x i32> %arg1) #0 {
-; CHECK-LABEL: define nofpclass(inf) <2 x float> 
@ret_ldexp_v2f32_known_neg_exp_noinf
+define <2 x float> @ret_ldexp_v2f32_known_neg_exp_noinf_splat(<2 x float> 
nofpclass(inf) %arg0, <2 x i32> %arg1) #0 {
+; CHECK-LABEL: define nofpclass(inf) <2 x float> 
@ret_ldexp_v2f32_known_neg_exp_noinf_splat
 ; CHECK-SAME: (<2 x float> nofpclass(inf) [[ARG0:%.*]], <2 x i32> 
[[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT:    [[OR_ARG1:%.*]] = or <2 x i32> [[ARG1]], <i32 -16, i32 -32>
+; CHECK-NEXT:    [[OR_ARG1:%.*]] = or <2 x i32> [[ARG1]], splat (i32 -32)
 ; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(inf) <2 x float> 
@llvm.ldexp.v2f32.v2i32(<2 x float> nofpclass(inf) [[ARG0]], <2 x i32> 
[[OR_ARG1]]) #[[ATTR10]]
 ; CHECK-NEXT:    ret <2 x float> [[CALL]]
+;
+  %or.arg1 = or <2 x i32> %arg1, splat (i32 -32)
+  %call = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %arg0, <2 x 
i32> %or.arg1)
+  ret <2 x float> %call
+}
+
+; TODO: computeConstantRange does not handle non-splat operator constants.
+define <2 x float> @ret_ldexp_v2f32_known_neg_exp_noinf_nonsplat(<2 x float> 
nofpclass(inf) %arg0, <2 x i32> %arg1) #0 {
+; CHECK-LABEL: define <2 x float> @ret_ldexp_v2f32_known_neg_exp_noinf_nonsplat
+; CHECK-SAME: (<2 x float> nofpclass(inf) [[ARG0:%.*]], <2 x i32> 
[[ARG1:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[OR_ARG1:%.*]] = or <2 x i32> [[ARG1]], <i32 -16, i32 -32>
+; CHECK-NEXT:    [[CALL:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x 
float> nofpclass(inf) [[ARG0]], <2 x i32> [[OR_ARG1]]) #[[ATTR10]]
+; CHECK-NEXT:    ret <2 x float> [[CALL]]
 ;
   %or.arg1 = or <2 x i32> %arg1, <i32 -16, i32 -32>
   %call = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %arg0, <2 x 
i32> %or.arg1)
@@ -1035,6 +1048,16 @@ define float @ret_ldexp_f32_neg127(float %arg0) #0 {
   ret float %call
 }
 
+define float @ret_ldexp_f32_noinf_exp_known_neg_or_0(float nofpclass(inf) 
%arg0, i32 range(i32 -256, 1) %arg1) #0 {
+; CHECK-LABEL: define nofpclass(inf) float 
@ret_ldexp_f32_noinf_exp_known_neg_or_0
+; CHECK-SAME: (float nofpclass(inf) [[ARG0:%.*]], i32 range(i32 -256, 1) 
[[ARG1:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(inf) float 
@llvm.ldexp.f32.i32(float nofpclass(inf) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
+  ret float %call
+}
+
 attributes #0 = { denormal_fpenv(ieee|ieee) }
 attributes #1 = { denormal_fpenv(preservesign) }
 attributes #2 = { denormal_fpenv(positivezero|positivezero) }
diff --git 
a/llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll
 
b/llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll
index fda131f421c99..e1e2576b7aa10 100644
--- 
a/llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll
+++ 
b/llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll
@@ -17,9 +17,7 @@ define float @frexp_fcmp_ogt_1(float %x, float nofpclass(inf) 
%not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -49,9 +47,7 @@ define float @frexp_fcmp_oge_1(float %x, float nofpclass(inf) 
%not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -81,9 +77,7 @@ define float @frexp_fcmp_ugt_1(float %x, float nofpclass(inf) 
%not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -113,9 +107,7 @@ define float @frexp_fcmp_uge_1(float %x, float 
nofpclass(inf) %not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -145,9 +137,7 @@ define float @frexp_fcmp_olt_1(float %x, float 
nofpclass(inf) %not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -177,9 +167,7 @@ define float @frexp_fcmp_ole_1(float %x, float 
nofpclass(inf) %not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -210,9 +198,7 @@ define float @frexp_fcmp_ult_1(float %x, float 
nofpclass(inf) %not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -242,9 +228,7 @@ define float @frexp_fcmp_ule_1(float %x, float 
nofpclass(inf) %not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -274,9 +258,7 @@ define float @frexp_cmp_ugt_0.5(float %x, float 
nofpclass(inf) %not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -306,9 +288,7 @@ define float @frexp_cmp_uge_0.5(float %x, float 
nofpclass(inf) %not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -338,9 +318,7 @@ define float @frexp_fcmp_ult_0.5(float %x, float 
nofpclass(inf) %not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -370,9 +348,7 @@ define float @frexp_fcmp_ule_0.5(float %x, float 
nofpclass(inf) %not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -402,9 +378,7 @@ define float @frexp_fcmp_ugt_0.5(float %x, float 
nofpclass(inf) %not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -434,9 +408,7 @@ define float @frexp_fcmp_uge_0.5(float %x, float 
nofpclass(inf) %not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -466,9 +438,7 @@ define float @frexp_fcmp_oeq_1(float %x, float 
nofpclass(inf) %not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -498,9 +468,7 @@ define float @frexp_fcmp_ueq_1(float %x, float 
nofpclass(inf) %not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -530,9 +498,7 @@ define float @frexp_fcmp_one_1(float %x, float 
nofpclass(inf) %not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -562,9 +528,7 @@ define float @frexp_fcmp_une_1(float %x, float 
nofpclass(inf) %not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -594,9 +558,7 @@ define float @frexp_fcmp_oeq_0.5(float %x, float 
nofpclass(inf) %not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -626,9 +588,7 @@ define float @frexp_fcmp_ueq_0.5(float %x, float 
nofpclass(inf) %not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -658,9 +618,7 @@ define float @frexp_fcmp_one_0.5(float %x, float 
nofpclass(inf) %not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -690,9 +648,7 @@ define float @frexp_fcmp_une_0.5(float %x, float 
nofpclass(inf) %not.inf) {
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -906,9 +862,7 @@ define float @frexp_fcmp_ogt_nextdown1(float %x, float 
nofpclass(inf) %not.inf)
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -939,9 +893,7 @@ define float @frexp_fcmp_ole_nextdown1(float %x, float 
nofpclass(inf) %not.inf)
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[LARGE]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -1074,9 +1026,7 @@ define float 
@frexp_fcmp_olt_1_multiple_conditions_wrong_constant(float %x, floa
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[EXIT]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -1115,9 +1065,7 @@ define float 
@frexp_fcmp_olt_1_multiple_conditions_nonfinite_constant(float %x,
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[EXIT]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -1154,9 +1102,7 @@ define float 
@frexp_fcmp_olt_1_multiple_conditions_edge_case_compare(float %x, f
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[EXIT]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
@@ -1194,9 +1140,7 @@ define float 
@frexp_fcmp_olt_1_multiple_conditions_other(float %x, float nofpcla
 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 
[[X]])
 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float 
[[NOT_INF]], i32 [[EXP]])
-; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, 
float [[SCALED]]
-; CHECK-NEXT:    ret float [[SELECT]]
+; CHECK-NEXT:    ret float [[SCALED]]
 ; CHECK:       [[EXIT]]:
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;

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

Reply via email to