← Back

Agent Trajectory

Conversation timeline with tool traces and model turns
Total Rounds
17
Phase 1 Analyze
10
Phase 2 Validate
7
Total Tokens
1,327,946
Tool Call Distribution
read250 x 9grep250 x 4difftest x 2langref x 2tests_manager x 2verify x 2report x 1stop x 1

SYSTEM

You are an LLVM compiler expert specializing in test case generation and bug detection. You are conducting LLVM code review now.

## Context
Maintainers provided a patch, but patches often have edge cases or introduce new issues.

## Your Task
You will work in two phases:
- Phase 1: Analyze the fix to identify potential issues, gaps, and edge cases. Propose test strategies.
- Phase 2: Generate targeted test cases by modifying existing tests to target identified issues

## You Will Receive
- Original patch description and related test case(s)
- The code region that was modified (the patch)
- Information about the optimization pass and component involved

## Tools You Can Use

You have multiple tools for each phase, but you should try to avoid using them with same inputs repeatedly to reduce redundant calls.

**CRITICAL**: You MUST use tool call every action in Phase 1 and Phase 2.

USER

# Phase 1: Analyze the Fix

This is a patch for ValueTracking:

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.
diff --git a/llvm/include/llvm/Support/KnownFPClass.h b/llvm/include/llvm/Support/KnownFPClass.h
index 7e018d25d2d1d..956141b9449a2 100644
--- a/llvm/include/llvm/Support/KnownFPClass.h
+++ b/llvm/include/llvm/Support/KnownFPClass.h
@@ -20,6 +20,7 @@
 
 namespace llvm {
 class APFloat;
+class APInt;
 struct fltSemantics;
 struct KnownBits;
 
@@ -448,10 +449,17 @@ struct KnownFPClass {
   static LLVM_ABI KnownFPClass frexp_mant(
       const KnownFPClass &Src, DenormalMode Mode = DenormalMode::getDynamic());
 
-  /// Propagate known class for ldexp
+  /// 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, const KnownBits &N, const fltSemantics &Flt,
+  ldexp(const KnownFPClass &Src, const APInt &ConstantRangeMin,
+        const APInt &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 7dd23f24dfcc7..5869ab28c6226 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4867,6 +4867,49 @@ 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)) {
+    CmpPredicate Pred;
+    const APFloat *LimitC;
+    if (!match(BI->getCondition(),
+               m_FCmp(Pred, m_FAbs(m_Specific(V)), 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 +5033,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 +5551,12 @@ 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()->getScalarSizeInBits());
 
       const fltSemantics &Flt =
           II->getType()->getScalarType()->getFltSemantics();
@@ -5520,7 +5565,8 @@ 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(),
+                                  ExpKnownRange.getSignedMax(), Flt, Mode);
       break;
     }
     case Intrinsic::arithmetic_fence: {
@@ -10474,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..4fb1d4cd4723e 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,
+                                 const APInt &ConstantRangeExpMin,
+                                 const APInt &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.sge(MantissaBits))
     Known.knownNot(fcSubnormal);
 
-  if (ExpBits.isConstant() && ExpBits.getConstant().isZero()) {
+  if (ConstantRangeExpMin.isZero() && ConstantRangeExpMax.isZero()) {
     // ldexp(x, 0) -> x, so propagate everything.
     Known.propagateCanonicalizingSrc(KnownSrc, Mode);
-  } else if (ExpBits.isNegative()) {
+  } else if (ConstantRangeExpMax.isNonPositive()) {
     // 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.isNonNegative()) {
     // 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(),
+               ExpBits.getSignedMaxValue(), Flt, Mode);
+}
+
 KnownFPClass KnownFPClass::powi(const KnownFPClass &KnownSrc,
                                 const KnownBits &ExponentKnownBits) {
   KnownFPClass Known;


---

## Subsystem Knowledge for ValueTracking

For reference, here are some key points about the ValueTracking you should consider (but do not limit to these) in your analysis:

# Subsystem Knowledge for ValueTracking

## Elements Frequently Missed

*   **Poison-Generating Flags on Instructions**: Flags that can generate poison values (such as `samesign`, `nsw`, `nnan`, `ninf`) are frequently overlooked when they are attached directly to instructions like `icmp`, `phi`, or `sub`. The analysis often mistakenly assumes an instruction's result is safe solely because its incoming operands are safe, ignoring the flags.
*   **Mismatched Flags Between Paired Instructions**: When analyzing instruction pairs (e.g., an `fcmp` followed by a `select`), the compiler frequently misses discrepancies in Fast-Math Flags (FMF) or poison-generating flags between the two instructions. It incorrectly applies the relaxed semantics of one instruction to the entire pattern.
*   **IEEE-754 Floating-Point Edge Cases**: Specific floating-point behaviors are frequently missed during value tracking and constant folding, including:
    *   **NaN Dropping Semantics**: Operations like `minnum` and `maxnum` discard NaN operands, meaning the sign bit of a NaN operand does not propagate to the result.
    *   **Signed Zeros**: The distinction between `+0.0` and `-0.0` is ignored during strict vs. non-strict inequality transformations, even when the `nsz` (no signed zeros) flag is absent.
    *   **Division by Negative Zero**: Dividing a positive number by `-0.0` yields `-Inf` (a strictly negative value), which is missed when analyzing the signs of the operands.
    *   **Zero Multiplied by Infinity**: The cross-operand scenario where one operand is `0` and the other is `Inf` results in `NaN`, which is missed if the compiler only checks operands individually.
*   **Poison Elements in Vector Constants**: Partially poisonous vector constants (e.g., `<0, poison>`) are frequently treated as perfectly safe equivalent values (like a pure zero vector) during algebraic simplifications, leading to the unintended introduction of poison into well-defined execution paths.
*   **1-bit Integer Boundary Conditions**: The wrap-around behavior specific to 1-bit integers (`i1`) is missed during constant range calculations. Adding 1 to the maximum value of an `i1` wraps around to the lower bound, erroneously creating an empty range.
*   **Speculative Execution Safety Context**: The implicit properties that make an instruction safe to execute speculatively (e.g., a pointer being non-null, or a divisor being non-zero) are missed when the compiler substitutes operands based on conditional equivalence.

## Patterns Not Well Handled

### Pattern 1: Select-Based Min/Max and Conditional Pattern Matching
The optimization pass struggles to safely transform `select` instructions driven by comparisons (`icmp` or `fcmp`) into higher-level intrinsics like `minnum`, `maxnum`, `smin`, or `smax`. The pattern matching logic frequently fails to respect the strict semantics of the original `select` instruction. It improperly hoists fast-math flags from the comparison to the entire pattern, ignores mismatched signed zeros, and fails to preserve ordered/unordered predicates when NaNs are possible. Furthermore, it fails to recognize that a `select` instruction acts as a "poison shield" (conditionally ignoring poison values from unselected branches), whereas the resulting intrinsics evaluate unconditionally and propagate poison.

### Pattern 2: Poison and Undef Propagation in Control Flow and Simplification
Transformations that simplify control flow, invert logic, or eliminate defensive instructions (like `freeze`) do not handle poison propagation well. The compiler often assumes that if the inputs to an expression tree are well-defined, the output is well-defined. This high-level assumption breaks down when the compiler swaps `select` operands involving partially poisonous vectors, replaces conditional selects with logical `xor` operations without checking for mismatched poison-generating flags, or ignores poison-generating flags on `phi` nodes. These flawed transformations consistently result in optimized code that is "more poisonous" than the original IR.

### Pattern 3: Floating-Point Property Deduction
The compiler's ValueTracking subsystem poorly handles the deduction of floating-point properties (such as sign bits, NaN possibilities, and value ranges) when combining multiple operations. It attempts to apply standard algebraic rules to floating-point arithmetic without adequately accounting for IEEE-754 edge cases. For example, it incorrectly deduces that a multiplication cannot produce `NaN` if neither operand is *always* zero or infinity, missing the case where they dynamically evaluate to zero and infinity simultaneously. Similarly, it incorrectly assumes the result of a division cannot be negative if neither operand is strictly negative, failing to account for division by negative zero.

### Pattern 4: Context-Blind Operand Substitution in Speculative Execution
The optimization pass does not well handle the substitution of variables with constants in speculatively executed instructions. When the compiler identifies that a variable is equivalent to a constant (e.g., `ptr == null`) within a specific conditional branch, it attempts to substitute the constant into instructions that use that variable. However, it performs this substitution blindly on instructions that are executed unconditionally (speculatively) outside the branch. This pattern destroys the very properties (like dereferenceability) that made the speculative execution safe in the first place, immediately introducing Undefined Behavior into the optimized program.

**CRITICAL**: Subsystem knowledge is **ONLY** a reference for you to understand this component.
Do NOT start your analysis from these patterns. Start from the patch semantics. Use these **ONLY** to cross-check your reasoning.

## Your Task for Phase 1

In this phase, you will review and analyze the fix above carefully and identify potential issues, edge cases, or gaps that the fix might miss. According to the analysis, propose mutation strategies for exposing the issue. These strategies will be used in Phase 2 to mutate existing test cases to target the identified issues.

Follow this structured workflow:

### Step 1: Context Gathering
In this step, you should gather enough context to construct semantics model of this fix for future analysis. Your goal is to understand the complete flow of this optimization. To achieve this, you should look at the nearby code regions, or try to find similar code regions in the LLVM codebase to understand the semantics of this fix.

You can use search tools:
- Use the `find` and `list` tools to find relevant files in the LLVM code.
- Use the `read` and `grep` tools to understand the context of the fix.

### Step 2: Fix Segmentation and Analysis
Based on the model built for this fix, you should segment the fix into smaller parts and analyze the semantics of each part. Follow this structured workflow for segmentation and analysis:

- **Segmentation**: Break down the fix into smaller segments or key changes, especially focusing on code regions related to semantics changes.
- **Analysis**: For each segment, analyze the semantics and identify any assumptions or preconditions that the fix relies on.

#### Tips for this step
- You can use the `langref` tool to query the LLVM Language Reference Manual for specific instructions, semantics, or optimization details relevant to the fix.
- You can pay attention to the commit message and annotations in the code, such as comments or specific patterns that indicate important semantics or assumptions.

### Step 3: Formal Semantic Modeling
- Define the exact semantic contract that this fix claims to satisfy.
- Explicitly list the preconditions under which the contract is assumed to hold.
- Identify how these preconditions may be violated.

### Step 4: Identify Potential Issues and Propose Test Strategies
Based on your analysis, propose around 5 specific test strategies that can be used to expose the issue. When proposing test strategies, consider the following:
- **Focus**: Focus on the assumptions and preconditions you identified.
- **Scenarios**: Think about specific input characteristics or scenarios that could violate these assumptions.
- **Mutations**: Propose mutations that can be applied to existing test cases to create new test cases targeting these scenarios.

Once you have analyzed the fix and identified potential issues or edge cases, use the `stop` tool to specify proposed test strategies along with detailed reasoning. 
Follow this structure for reasoning:

### 1. Fix Understanding
- What optimization or transformation does this fix enable or correct?
- What are the key changes made in the patch?

### 2. Formal Semantic Modeling
- What is the exact semantic function before the fix?
- What is the exact semantic function after the fix?
- Under what conditions might they differ?
- Provide at least one concrete numerical instantiation to illustrate the difference.

### 3. Assumptions and Preconditions Identified
- What assumptions does the fix make about the input?
- What preconditions must hold for this fix to be correct?

### 4. Potential Cases to Break Assumptions
For each assumption and precondition identified, describe specific scenarios or input characteristics that could violate them. The potential cases should only focus on the semantics related to the analysis above.

### 5. Test Strategies
For each potential issue you identified, propose specific test strategies with the following structure:

- Name: [Name]
- Target: [What to mutate]
- Rationale: [Why this might expose an issue]
- Expected Issue: [What incorrect behavior might occur]

---

## Tools that you can use

- `findN`: Search for files in the LLVM codebase related to the component or optimization pass to understand the context of the fix and find relevant tests.
- `listN`: List files in the LLVM codebase to find relevant tests or code regions.
- `readN`: Read the content of a file in the LLVM codebase to understand existing tests or the fix.
- `grepN`: Search for specific patterns in the codebase to find relevant tests or code regions.
- `langref`: Query the LLVM Language Reference Manual for specific instructions, semantics, or optimization details relevant to the fix.
- `stop`: End Phase 1 by submitting the identified issues and proposed test strategies.

TOOL CALL: grep250

{"args":"-nRI 'computeKnownExponentRangeFromContext\\|KnownFPClass::ldexp\\|conditionsFor(V)\\|Intrinsic::frexp\\|Intrinsic::ldexp' llvm/lib llvm/include","k":1}

TOOL OUTPUT

llvm/include/llvm/CodeGen/BasicTTIImpl.h:2416:    case Intrinsic::ldexp:
llvm/include/llvm/IR/IRBuilder.h:1087:    return CreateIntrinsic(Intrinsic::ldexp, {Src->getType(), Exp->getType()},llvm/lib/Analysis/ConstantFolding.cpp:1858:  case Intrinsic::ldexp:
llvm/lib/Analysis/ConstantFolding.cpp:1861:  case Intrinsic::frexp:
llvm/lib/Analysis/ConstantFolding.cpp:3719:      case Intrinsic::ldexp: {
llvm/lib/Analysis/ConstantFolding.cpp:4590:  case Intrinsic::frexp: {
llvm/lib/Analysis/InstructionSimplify.cpp:7156:  case Intrinsic::ldexp:
llvm/lib/Analysis/ValueTracking.cpp:1043:    for (CondBrInst *BI : Q.DC->conditionsFor(V)) {
llvm/lib/Analysis/ValueTracking.cpp:10503:    } else if (match(I, m_ExtractValue<1>(m_Intrinsic<Intrinsic::frexp>(
llvm/lib/Analysis/ValueTracking.cpp:10525:              computeKnownExponentRangeFromContext(FrexpSrc, SQ);
llvm/lib/Analysis/ValueTracking.cpp:2683:    for (CondBrInst *BI : Q.DC->conditionsFor(V)) {
llvm/lib/Analysis/ValueTracking.cpp:4098:      for (CondBrInst *BI : Q.DC->conditionsFor(V)) {
llvm/lib/Analysis/ValueTracking.cpp:4873:computeKnownExponentRangeFromContext(const Value *V, const SimplifyQuery &Q) {
llvm/lib/Analysis/ValueTracking.cpp:4877:  for (CondBrInst *BI : Q.DC->conditionsFor(V)) {
llvm/lib/Analysis/ValueTracking.cpp:4926:    for (CondBrInst *BI : Q.DC->conditionsFor(V)) {
llvm/lib/Analysis/ValueTracking.cpp:5036:  // TODO: Try computeKnownExponentRangeFromContext
llvm/lib/Analysis/ValueTracking.cpp:5547:    case Intrinsic::ldexp: {
llvm/lib/Analysis/ValueTracking.cpp:5568:      Known = KnownFPClass::ldexp(KnownSrc, ExpKnownRange.getSignedMin(),
llvm/lib/Analysis/ValueTracking.cpp:6056:        case Intrinsic::frexp: {
llvm/lib/Analysis/ValueTracking.cpp:8237:  case Intrinsic::frexp:
llvm/lib/Analysis/VectorUtils.cpp:212:  case Intrinsic::ldexp:
llvm/lib/Analysis/VectorUtils.cpp:228:  case Intrinsic::frexp:
llvm/lib/Analysis/VectorUtils.cpp:90:  case Intrinsic::frexp:
llvm/lib/Analysis/VectorUtils.cpp:91:  case Intrinsic::ldexp:
llvm/lib/CodeGen/ExpandIRInsts.cpp:324:    Value *Frexp = B.CreateIntrinsic(Intrinsic::frexp, {Ty, ExTy}, Src);
llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp:1502:    Known = KnownFPClass::ldexp(KnownSrc, ExpBits, Flt, Mode);
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp:2020:    case Intrinsic::ldexp:
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp:2416:  case Intrinsic::frexp: {
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:7138:  case Intrinsic::ldexp:
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:7147:  case Intrinsic::frexp: {
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:7161:    case Intrinsic::frexp:
llvm/lib/IR/AutoUpgrade.cpp:1420:            F->getParent(), Intrinsic::ldexp,
llvm/lib/Support/KnownFPClass.cpp:791:KnownFPClass KnownFPClass::ldexp(const KnownFPClass &KnownSrc,
llvm/lib/Support/KnownFPClass.cpp:838:KnownFPClass KnownFPClass::ldexp(const KnownFPClass &KnownSrc,
llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp:140:        F.getParent(), Intrinsic::ldexp,
llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp:510:  Value *Frexp = Builder.CreateIntrinsic(Intrinsic::frexp,
llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp:711:          CI->getModule(), Intrinsic::ldexp,
llvm/lib/Transforms/Coroutines/MaterializationUtils.cpp:255:    case Intrinsic::ldexp:
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp:3133:    if (II->getIntrinsicID() == Intrinsic::ldexp) {
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp:3294:  case Intrinsic::ldexp: {
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp:3330:    if (match(Src, m_OneUse(m_Intrinsic<Intrinsic::ldexp>(
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp:4356:  case Intrinsic::frexp: {
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp:4361:              m_ExtractValue<0>(m_Intrinsic<Intrinsic::frexp>(m_Value())))) {
llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp:1130:                    m_AllowReassoc(m_OneUse(m_Intrinsic<Intrinsic::ldexp>(
llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp:1133:        I, Builder.CreateIntrinsic(Intrinsic::ldexp,
llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp:396:      if (TII->getIntrinsicID() == Intrinsic::ldexp) {
llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp:411:              TII->getType(), Intrinsic::ldexp, {SelectVal, SelectExp}, FMF);
llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp:3249:    case Intrinsic::ldexp: {
llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp:3281:      Known = KnownFPClass::ldexp(KnownSrc, KnownExpBits, FltSem, Mode);
llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp:3510:        case Intrinsic::frexp: {
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp:4767:  if (match(&EV, m_ExtractValue<0>(m_Intrinsic<Intrinsic::frexp>(m_Select(
llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp:2215:        return copyFlags(*Pow, B.CreateIntrinsic(Intrinsic::ldexp,
llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp:2515:        return copyFlags(*CI, B.CreateIntrinsic(Intrinsic::ldexp,

TOOL CALL: grep250

{"args":"-nRI 'frexp\\|ldexp' llvm/test | head","k":1}

TOOL OUTPUT

Error: llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:4:declare float @llvm.ldexp.f32.i32(float, i32)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:5:declare float @llvm.ldexp.f32.i64(float, i64)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:6:declare <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float>, <2 x i32>)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:7:declare double @llvm.ldexp.f64.i32(double, i32)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:8:declare half @llvm.ldexp.f16.i32(half, i32)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:9:declare bfloat @llvm.ldexp.bf16.i32(bfloat, i32)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:12:define float @ret_ldexp_f32(float %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:13:; CHECK-LABEL: define float @ret_ldexp_f32
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:15:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[ARG1]]) #[[ATTR10:[0-9]+]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:18:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:22:define float @ret_ldexp_f32_0(float %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:23:; CHECK-LABEL: define float @ret_ldexp_f32_0
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:25:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:28:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:32:define float @ret_ldexp_f32_0_nopsub(float nofpclass(psub) %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:33:; CHECK-LABEL: define nofpclass(psub) float @ret_ldexp_f32_0_nopsub
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:35:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(psub) float @llvm.ldexp.f32.i32(float nofpclass(psub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:38:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:42:define float @ret_ldexp_f32_0_nonsub(float nofpclass(nsub) %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:43:; CHECK-LABEL: define nofpclass(nsub) float @ret_ldexp_f32_0_nonsub
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:45:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nsub) float @llvm.ldexp.f32.i32(float nofpclass(nsub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:48:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:52:define float @ret_ldexp_f32_0_nosub(float nofpclass(sub) %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:53:; CHECK-LABEL: define nofpclass(sub) float @ret_ldexp_f32_0_nosub
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:55:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(sub) float @llvm.ldexp.f32.i32(float nofpclass(sub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:58:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:62:define float @ret_ldexp_f32_0_nosub_nosnan(float nofpclass(sub snan) %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:63:; CHECK-LABEL: define nofpclass(snan sub) float @ret_ldexp_f32_0_nosub_nosnan
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:65:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(snan sub) float @llvm.ldexp.f32.i32(float nofpclass(snan sub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:68:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:72:define float @ret_ldexp_f32_0_nopsub_nopzero(float nofpclass(psub pzero) %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:73:; CHECK-LABEL: define nofpclass(pzero psub) float @ret_ldexp_f32_0_nopsub_nopzero
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:75:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(pzero psub) float @llvm.ldexp.f32.i32(float nofpclass(pzero psub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:78:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:82:define float @ret_ldexp_f32_0_nonsub_nonzero(float nofpclass(nsub nzero) %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:83:; CHECK-LABEL: define nofpclass(nzero nsub) float @ret_ldexp_f32_0_nonsub_nonzero
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:85:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nzero nsub) float @llvm.ldexp.f32.i32(float nofpclass(nzero nsub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:88:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:92:define float @ret_ldexp_f32_0_nosub_nozero(float nofpclass(sub zero) %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:93:; CHECK-LABEL: define nofpclass(zero sub) float @ret_ldexp_f32_0_nosub_nozero
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:95:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(zero sub) float @llvm.ldexp.f32.i32(float nofpclass(zero sub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:98:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:102:define float @ret_ldexp_f32_0_nopsub_daz(float nofpclass(psub) %arg0) #1 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:103:; CHECK-LABEL: define nofpclass(psub) float @ret_ldexp_f32_0_nopsub_daz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:105:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(psub) float @llvm.ldexp.f32.i32(float nofpclass(psub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:108:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:112:define float @ret_ldexp_f32_0_nonsub_daz(float nofpclass(nsub) %arg0) #1 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:113:; CHECK-LABEL: define nofpclass(nsub) float @ret_ldexp_f32_0_nonsub_daz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:115:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nsub) float @llvm.ldexp.f32.i32(float nofpclass(nsub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:118:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:122:define float @ret_ldexp_f32_0_nosub_daz(float nofpclass(sub) %arg0) #1 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:123:; CHECK-LABEL: define nofpclass(sub) float @ret_ldexp_f32_0_nosub_daz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:125:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(sub) float @llvm.ldexp.f32.i32(float nofpclass(sub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:128:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:132:define float @ret_ldexp_f32_0_nosub_nosnan_daz(float nofpclass(sub snan) %arg0) #1 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:133:; CHECK-LABEL: define nofpclass(snan sub) float @ret_ldexp_f32_0_nosub_nosnan_daz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:135:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(snan sub) float @llvm.ldexp.f32.i32(float nofpclass(snan sub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:138:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:142:define float @ret_ldexp_f32_0_nopsub_nozero_daz(float nofpclass(psub pzero) %arg0) #1 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:143:; CHECK-LABEL: define nofpclass(pzero psub) float @ret_ldexp_f32_0_nopsub_nozero_daz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:145:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(pzero psub) float @llvm.ldexp.f32.i32(float nofpclass(pzero psub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:148:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:152:define float @ret_ldexp_f32_0_nonsub_nonzero_daz(float nofpclass(nsub nzero) %arg0) #1 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:153:; CHECK-LABEL: define nofpclass(nzero nsub) float @ret_ldexp_f32_0_nonsub_nonzero_daz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:155:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nzero nsub) float @llvm.ldexp.f32.i32(float nofpclass(nzero nsub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:158:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:162:define float @ret_ldexp_f32_0_nosub_nozero_daz(float nofpclass(sub zero) %arg0) #1 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:163:; CHECK-LABEL: define nofpclass(zero sub) float @ret_ldexp_f32_0_nosub_nozero_daz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:165:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(zero sub) float @llvm.ldexp.f32.i32(float nofpclass(zero sub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:168:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:172:define float @ret_ldexp_f32_0_nopsub_dapz(float nofpclass(psub) %arg0) #2 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:173:; CHECK-LABEL: define nofpclass(psub) float @ret_ldexp_f32_0_nopsub_dapz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:175:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(psub) float @llvm.ldexp.f32.i32(float nofpclass(psub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:178:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:182:define float @ret_ldexp_f32_0_nonsub_dapz(float nofpclass(nsub) %arg0) #2 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:183:; CHECK-LABEL: define nofpclass(nsub) float @ret_ldexp_f32_0_nonsub_dapz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:185:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nsub) float @llvm.ldexp.f32.i32(float nofpclass(nsub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:188:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:192:define float @ret_ldexp_f32_0_nosub_dapz(float nofpclass(sub) %arg0) #2 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:193:; CHECK-LABEL: define nofpclass(sub) float @ret_ldexp_f32_0_nosub_dapz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:195:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(sub) float @llvm.ldexp.f32.i32(float nofpclass(sub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:198:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:202:define float @ret_ldexp_f32_0_nopsub_nozero_dapz(float nofpclass(psub zero) %arg0) #2 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:203:; CHECK-LABEL: define nofpclass(nzero psub) float @ret_ldexp_f32_0_nopsub_nozero_dapz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:205:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nzero psub) float @llvm.ldexp.f32.i32(float nofpclass(zero psub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:208:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:212:define float @ret_ldexp_f32_0_nonsub_nonzero_dapz(float nofpclass(nsub nzero) %arg0) #2 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:213:; CHECK-LABEL: define nofpclass(nzero nsub) float @ret_ldexp_f32_0_nonsub_nonzero_dapz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:215:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nzero nsub) float @llvm.ldexp.f32.i32(float nofpclass(nzero nsub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:218:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:222:define float @ret_ldexp_f32_0_nosub_nozero_dapz(float nofpclass(sub zero) %arg0) #2 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:223:; CHECK-LABEL: define nofpclass(zero sub) float @ret_ldexp_f32_0_nosub_nozero_dapz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:225:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(zero sub) float @llvm.ldexp.f32.i32(float nofpclass(zero sub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:228:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:232:define float @ret_ldexp_f32_0_nopsub_nozero_dapz_dapz(float nofpclass(psub zero) %arg0) #2 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:233:; CHECK-LABEL: define nofpclass(nzero psub) float @ret_ldexp_f32_0_nopsub_nozero_dapz_dapz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:235:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nzero psub) float @llvm.ldexp.f32.i32(float nofpclass(zero psub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:238:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:242:define float @ret_ldexp_f32_0_nopsub_nozero_daz_ieee(float nofpclass(psub zero) %arg0) #3 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:243:; CHECK-LABEL: define nofpclass(pzero psub) float @ret_ldexp_f32_0_nopsub_nozero_daz_ieee
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:245:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(pzero psub) float @llvm.ldexp.f32.i32(float nofpclass(zero psub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:248:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:252:define float @ret_ldexp_f32_0_nopsub_nozero_daz_dynamic(float nofpclass(psub zero) %arg0) #4 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:253:; CHECK-LABEL: define nofpclass(psub) float @ret_ldexp_f32_0_nopsub_nozero_daz_dynamic
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:255:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(psub) float @llvm.ldexp.f32.i32(float nofpclass(zero psub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:258:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:262:define float @ret_ldexp_f32_0_nopsub_nozero_ieee_daz(float nofpclass(psub zero) %arg0) #5 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:263:; CHECK-LABEL: define nofpclass(pzero psub) float @ret_ldexp_f32_0_nopsub_nozero_ieee_daz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:265:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(pzero psub) float @llvm.ldexp.f32.i32(float nofpclass(zero psub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:268:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:272:define float @ret_ldexp_f32_0_nopsub_nozero_dynamic_daz(float nofpclass(psub zero) %arg0) #6 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:273:; CHECK-LABEL: define nofpclass(psub) float @ret_ldexp_f32_0_nopsub_nozero_dynamic_daz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:275:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(psub) float @llvm.ldexp.f32.i32(float nofpclass(zero psub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:278:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:282:define float @ret_ldexp_f32_0_nopsub_nozero_dynamic_dapz(float nofpclass(psub zero) %arg0) #7 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:283:; CHECK-LABEL: define nofpclass(psub) float @ret_ldexp_f32_0_nopsub_nozero_dynamic_dapz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:285:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(psub) float @llvm.ldexp.f32.i32(float nofpclass(zero psub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:288:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:292:define float @ret_ldexp_f32_0_nopsub_nozero_dapz_dynamic(float nofpclass(psub zero) %arg0) #8 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:293:; CHECK-LABEL: define nofpclass(psub) float @ret_ldexp_f32_0_nopsub_nozero_dapz_dynamic
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:295:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(psub) float @llvm.ldexp.f32.i32(float nofpclass(zero psub) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:298:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:302:define float @ret_ldexp_f32_0_nopnorm(float nofpclass(pnorm) %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:303:; CHECK-LABEL: define nofpclass(pnorm) float @ret_ldexp_f32_0_nopnorm
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:305:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(pnorm) float @llvm.ldexp.f32.i32(float nofpclass(pnorm) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:308:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:312:define float @ret_ldexp_f32_0_nnorm(float nofpclass(nnorm) %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:313:; CHECK-LABEL: define nofpclass(nnorm) float @ret_ldexp_f32_0_nnorm
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:315:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nnorm) float @llvm.ldexp.f32.i32(float nofpclass(nnorm) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:318:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:322:define float @ret_ldexp_f32_0_nopnorm_nonsub(float nofpclass(pnorm nsub) %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:323:; CHECK-LABEL: define nofpclass(nsub pnorm) float @ret_ldexp_f32_0_nopnorm_nonsub
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:325:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nsub pnorm) float @llvm.ldexp.f32.i32(float nofpclass(nsub pnorm) [[ARG0]], i32 noundef 0) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:328:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 0)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:332:define <2 x float> @ret_ldexp_v2f32_0(<2 x float> %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:333:; CHECK-LABEL: define <2 x float> @ret_ldexp_v2f32_0
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:335:; CHECK-NEXT:    [[CALL:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[ARG0]], <2 x i32> <i32 undef, i32 0>) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:338:  %call = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %arg0, <2 x i32> <i32 undef, i32 0>)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:342:define float @ret_ldexp_f32_i64(float %arg0, i64 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:343:; CHECK-LABEL: define float @ret_ldexp_f32_i64
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:345:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i64(float [[ARG0]], i64 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:348:  %call = call float @llvm.ldexp.f32.i64(float %arg0, i64 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:352:define <2 x float> @ret_ldexp_v2f32(<2 x float> %arg0, <2 x i32> %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:353:; CHECK-LABEL: define <2 x float> @ret_ldexp_v2f32
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:355:; CHECK-NEXT:    [[CALL:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[ARG0]], <2 x i32> [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:358:  %call = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %arg0, <2 x i32> %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:362:define float @ret_ldexp_f32_nonan(float nofpclass(nan) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:363:; CHECK-LABEL: define nofpclass(nan) float @ret_ldexp_f32_nonan
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:365:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan) float @llvm.ldexp.f32.i32(float nofpclass(nan) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:368:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:372:define float @ret_ldexp_f32_nosnan(float nofpclass(snan) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:373:; CHECK-LABEL: define nofpclass(snan) float @ret_ldexp_f32_nosnan
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:375:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(snan) float @llvm.ldexp.f32.i32(float nofpclass(snan) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:378:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:382:define float @ret_ldexp_f32_noqnan(float nofpclass(qnan) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:383:; CHECK-LABEL: define float @ret_ldexp_f32_noqnan
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:385:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float nofpclass(qnan) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:388:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:392:define float @ret_ldexp_f32_noneg(float nofpclass(ninf nsub nnorm) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:393:; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @ret_ldexp_f32_noneg
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:395:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(ninf nsub nnorm) float @llvm.ldexp.f32.i32(float nofpclass(ninf nsub nnorm) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:398:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:402:define float @ret_ldexp_f32_noneg_nonzero(float nofpclass(ninf nsub nnorm nzero) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:403:; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_ldexp_f32_noneg_nonzero
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:405:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.ldexp.f32.i32(float nofpclass(ninf nzero nsub nnorm) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:408:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:412:define float @ret_ldexp_f32_noneg_nozero(float nofpclass(ninf nsub nnorm) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:413:; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @ret_ldexp_f32_noneg_nozero
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:415:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(ninf nsub nnorm) float @llvm.ldexp.f32.i32(float nofpclass(ninf nsub nnorm) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:418:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:422:define float @ret_ldexp_f32_nonzero(float nofpclass(nzero) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:423:; CHECK-LABEL: define float @ret_ldexp_f32_nonzero
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:425:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float nofpclass(nzero) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:428:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:432:define float @ret_ldexp_f32_nopzero(float nofpclass(pzero) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:433:; CHECK-LABEL: define float @ret_ldexp_f32_nopzero
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:435:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float nofpclass(pzero) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:438:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:442:define float @ret_ldexp_f32_noneg_ftz_daz(float nofpclass(ninf nsub nnorm) %arg0, i32 %arg1) #1 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:443:; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @ret_ldexp_f32_noneg_ftz_daz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:445:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(ninf nsub nnorm) float @llvm.ldexp.f32.i32(float nofpclass(ninf nsub nnorm) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:448:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:452:define float @ret_ldexp_f32_noneg_nonzero_ftz_daz(float nofpclass(ninf nsub nnorm nzero) %arg0, i32 %arg1) #1 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:453:; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_ldexp_f32_noneg_nonzero_ftz_daz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:455:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.ldexp.f32.i32(float nofpclass(ninf nzero nsub nnorm) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:458:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:462:define float @ret_ldexp_f32_noneg_nonzero_ftpz_dapz(float nofpclass(ninf nsub nnorm nzero) %arg0, i32 %arg1) #2 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:463:; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_ldexp_f32_noneg_nonzero_ftpz_dapz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:465:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.ldexp.f32.i32(float nofpclass(ninf nzero nsub nnorm) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:468:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:472:define float @ret_ldexp_f32_noninf_nonnorm(float nofpclass(ninf nnorm) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:473:; CHECK-LABEL: define float @ret_ldexp_f32_noninf_nonnorm
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:475:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float nofpclass(ninf nnorm) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:478:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:482:define float @ret_ldexp_f32_noninf_nonnorm_ftz_daz(float nofpclass(ninf nnorm) %arg0, i32 %arg1) #1 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:483:; CHECK-LABEL: define float @ret_ldexp_f32_noninf_nonnorm_ftz_daz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:485:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float nofpclass(ninf nnorm) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:488:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:492:define float @ret_ldexp_f32_noneg_ftz_ieee(float nofpclass(ninf nsub nnorm) %arg0, i32 %arg1) #3 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:493:; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @ret_ldexp_f32_noneg_ftz_ieee
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:495:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(ninf nsub nnorm) float @llvm.ldexp.f32.i32(float nofpclass(ninf nsub nnorm) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:498:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:502:define float @ret_ldexp_f32_noneg_nonzero_ftz_ieee(float nofpclass(ninf nsub nnorm nzero) %arg0, i32 %arg1) #3 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:503:; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_ldexp_f32_noneg_nonzero_ftz_ieee
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:505:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.ldexp.f32.i32(float nofpclass(ninf nzero nsub nnorm) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:508:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:512:define float @ret_ldexp_f32_nopos(float nofpclass(pinf psub pnorm) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:513:; CHECK-LABEL: define nofpclass(pinf psub pnorm) float @ret_ldexp_f32_nopos
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:515:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(pinf psub pnorm) float @llvm.ldexp.f32.i32(float nofpclass(pinf psub pnorm) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:518:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:522:define float @ret_ldexp_f32_nopos_nopzero(float nofpclass(pinf psub pnorm pzero) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:523:; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @ret_ldexp_f32_nopos_nopzero
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:525:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(pinf pzero psub pnorm) float @llvm.ldexp.f32.i32(float nofpclass(pinf pzero psub pnorm) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:528:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:532:define float @ret_ldexp_f32_nopos_nozero(float nofpclass(pinf psub pnorm zero) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:533:; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @ret_ldexp_f32_nopos_nozero
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:535:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(pinf pzero psub pnorm) float @llvm.ldexp.f32.i32(float nofpclass(pinf zero psub pnorm) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:538:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:542:define float @ret_ldexp_f32_nozero(float nofpclass(zero) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:543:; CHECK-LABEL: define float @ret_ldexp_f32_nozero
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:545:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float nofpclass(zero) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:548:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:552:define float @ret_ldexp_f32_noinf(float nofpclass(inf) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:553:; CHECK-LABEL: define float @ret_ldexp_f32_noinf
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:555:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float nofpclass(inf) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:558:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:562:define float @ret_ldexp_f32_noinf_nonan(float nofpclass(inf nan) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:563:; CHECK-LABEL: define nofpclass(nan) float @ret_ldexp_f32_noinf_nonan
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:565:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan) float @llvm.ldexp.f32.i32(float nofpclass(nan inf) [[ARG0]], i32 [[ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:568:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:572:define float @ret_ldexp_f32_known_pos_exp(float %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:573:; CHECK-LABEL: define float @ret_ldexp_f32_known_pos_exp
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:576:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:580:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %and.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:584:define float @ret_ldexp_f32_known_neg_exp(float %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:585:; CHECK-LABEL: define float @ret_ldexp_f32_known_neg_exp
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:588:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[OR_ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:592:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %or.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:596:define float @ret_ldexp_f32_known_pos_exp_nosub(float nofpclass(sub) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:597:; CHECK-LABEL: define nofpclass(sub) float @ret_ldexp_f32_known_pos_exp_nosub
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:600:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(sub) float @llvm.ldexp.f32.i32(float nofpclass(sub) [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:604:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %and.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:608:define float @ret_ldexp_f32_known_neg_exp_nosub(float nofpclass(sub) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:609:; CHECK-LABEL: define float @ret_ldexp_f32_known_neg_exp_nosub
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:612:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float nofpclass(sub) [[ARG0]], i32 [[OR_ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:616:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %or.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:620:define float @ret_ldexp_f32_known_pos_exp_nopsub(float nofpclass(psub) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:621:; CHECK-LABEL: define nofpclass(psub) float @ret_ldexp_f32_known_pos_exp_nopsub
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:624:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(psub) float @llvm.ldexp.f32.i32(float nofpclass(psub) [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:628:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %and.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:632:define float @ret_ldexp_f32_known_neg_exp_nopsub(float nofpclass(psub) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:633:; CHECK-LABEL: define float @ret_ldexp_f32_known_neg_exp_nopsub
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:636:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float nofpclass(psub) [[ARG0]], i32 [[OR_ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:640:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %or.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:644:define float @ret_ldexp_f32_known_pos_exp_nonsub(float nofpclass(nsub) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:645:; CHECK-LABEL: define nofpclass(nsub) float @ret_ldexp_f32_known_pos_exp_nonsub
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:648:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nsub) float @llvm.ldexp.f32.i32(float nofpclass(nsub) [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:652:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %and.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:656:define float @ret_ldexp_f32_known_neg_exp_nonsub(float nofpclass(nsub) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:657:; CHECK-LABEL: define float @ret_ldexp_f32_known_neg_exp_nonsub
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:660:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float nofpclass(nsub) [[ARG0]], i32 [[OR_ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:664:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %or.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:668:define float @ret_ldexp_f32_known_pos_exp_noinf(float nofpclass(inf) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:669:; CHECK-LABEL: define float @ret_ldexp_f32_known_pos_exp_noinf
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:672:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float nofpclass(inf) [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:676:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %and.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:680:define float @ret_ldexp_f32_known_neg_exp_noinf(float nofpclass(inf) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:681:; CHECK-LABEL: define nofpclass(inf) float @ret_ldexp_f32_known_neg_exp_noinf
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:684:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(inf) float @llvm.ldexp.f32.i32(float nofpclass(inf) [[ARG0]], i32 [[OR_ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:688:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %or.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:692:define <2 x float> @ret_ldexp_v2f32_known_pos_exp_noinf(<2 x float> nofpclass(inf) %arg0, <2 x i32> %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:693:; CHECK-LABEL: define <2 x float> @ret_ldexp_v2f32_known_pos_exp_noinf
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:696:; CHECK-NEXT:    [[CALL:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> nofpclass(inf) [[ARG0]], <2 x i32> [[AND_ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:700:  %call = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %arg0, <2 x i32> %and.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:704:define <2 x float> @ret_ldexp_v2f32_known_neg_exp_noinf(<2 x float> nofpclass(inf) %arg0, <2 x i32> %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:705:; CHECK-LABEL: define nofpclass(inf) <2 x float> @ret_ldexp_v2f32_known_neg_exp_noinf
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:708:; 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]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:712:  %call = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %arg0, <2 x i32> %or.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:716:define float @ret_ldexp_f32_known_pos_exp_nopinf(float nofpclass(pinf) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:717:; CHECK-LABEL: define float @ret_ldexp_f32_known_pos_exp_nopinf
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:720:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float nofpclass(pinf) [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:724:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %and.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:728:define float @ret_ldexp_f32_known_neg_exp_nopinf(float nofpclass(pinf) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:729:; CHECK-LABEL: define nofpclass(pinf) float @ret_ldexp_f32_known_neg_exp_nopinf
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:732:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(pinf) float @llvm.ldexp.f32.i32(float nofpclass(pinf) [[ARG0]], i32 [[OR_ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:736:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %or.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:740:define float @ret_ldexp_f32_known_pos_exp_noninf(float nofpclass(ninf) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:741:; CHECK-LABEL: define float @ret_ldexp_f32_known_pos_exp_noninf
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:744:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float nofpclass(ninf) [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:748:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %and.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:752:define float @ret_ldexp_f32_known_neg_exp_noninf(float nofpclass(ninf) %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:753:; CHECK-LABEL: define nofpclass(ninf) float @ret_ldexp_f32_known_neg_exp_noninf
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:756:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(ninf) float @llvm.ldexp.f32.i32(float nofpclass(ninf) [[ARG0]], i32 [[OR_ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:760:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %or.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:764:define float @ret_ldexp_f32_known_pos_exp_nopsub_nopzero_daz(float nofpclass(psub pzero) %arg0, i32 %arg1) #1 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:765:; CHECK-LABEL: define nofpclass(pzero psub) float @ret_ldexp_f32_known_pos_exp_nopsub_nopzero_daz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:768:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(pzero psub) float @llvm.ldexp.f32.i32(float nofpclass(pzero psub) [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:772:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %and.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:776:define float @ret_ldexp_f32_known_neg_exp_nopsub_nopzero_daz(float nofpclass(psub pzero) %arg0, i32 %arg1) #1 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:777:; CHECK-LABEL: define float @ret_ldexp_f32_known_neg_exp_nopsub_nopzero_daz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:780:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float nofpclass(pzero psub) [[ARG0]], i32 [[OR_ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:784:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %or.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:788:define float @ret_ldexp_f32_known_pos_exp_nonsub_nonzero_daz(float nofpclass(nsub nzero) %arg0, i32 %arg1) #1 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:789:; CHECK-LABEL: define nofpclass(nzero nsub) float @ret_ldexp_f32_known_pos_exp_nonsub_nonzero_daz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:792:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nzero nsub) float @llvm.ldexp.f32.i32(float nofpclass(nzero nsub) [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:796:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %and.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:800:define float @ret_ldexp_f32_known_neg_exp_nonsub_nonzero_daz(float nofpclass(nsub nzero) %arg0, i32 %arg1) #1 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:801:; CHECK-LABEL: define float @ret_ldexp_f32_known_neg_exp_nonsub_nonzero_daz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:804:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float nofpclass(nzero nsub) [[ARG0]], i32 [[OR_ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:808:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %or.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:812:define float @ret_ldexp_f32_known_pos_exp_nosub_nozero_daz(float nofpclass(sub zero) %arg0, i32 %arg1) #1 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:813:; CHECK-LABEL: define nofpclass(zero sub) float @ret_ldexp_f32_known_pos_exp_nosub_nozero_daz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:816:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(zero sub) float @llvm.ldexp.f32.i32(float nofpclass(zero sub) [[ARG0]], i32 [[AND_ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:820:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %and.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:824:define float @ret_ldexp_f32_known_neg_exp_nosub_nozero_daz(float nofpclass(sub zero) %arg0, i32 %arg1) #1 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:825:; CHECK-LABEL: define float @ret_ldexp_f32_known_neg_exp_nosub_nozero_daz
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:828:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float nofpclass(zero sub) [[ARG0]], i32 [[OR_ARG1]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:832:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %or.arg1)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:836:define float @ret_ldexp_f32_22(float %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:837:; CHECK-LABEL: define float @ret_ldexp_f32_22
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:839:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 22) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:842:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 22)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:846:define float @ret_ldexp_f32_23(float %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:847:; CHECK-LABEL: define nofpclass(sub) float @ret_ldexp_f32_23
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:849:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(sub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 23) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:852:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 23)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:856:define float @ret_ldexp_f32_24(float %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:857:; CHECK-LABEL: define nofpclass(sub) float @ret_ldexp_f32_24
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:859:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(sub) float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef 24) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:862:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 24)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:866:define float @ret_ldexp_f32_min24(float %arg0, i32 %arg1) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:867:; CHECK-LABEL: define float @ret_ldexp_f32_min24
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:870:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 [[MIN]]) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:874:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 %min)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:878:define float @ret_ldexp_f32_23_nnan(float nofpclass(nan) %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:879:; CHECK-LABEL: define nofpclass(nan sub) float @ret_ldexp_f32_23_nnan
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:881:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan sub) float @llvm.ldexp.f32.i32(float nofpclass(nan) [[ARG0]], i32 noundef 23) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:884:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 23)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:888:define double @ret_ldexp_f64_24(double %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:889:; CHECK-LABEL: define double @ret_ldexp_f64_24
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:891:; CHECK-NEXT:    [[CALL:%.*]] = call double @llvm.ldexp.f64.i32(double [[ARG0]], i32 noundef 24) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:894:  %call = call double @llvm.ldexp.f64.i32(double %arg0, i32 24)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:898:define double @ret_ldexp_f64_51(double %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:899:; CHECK-LABEL: define double @ret_ldexp_f64_51
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:901:; CHECK-NEXT:    [[CALL:%.*]] = call double @llvm.ldexp.f64.i32(double [[ARG0]], i32 noundef 51) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:904:  %call = call double @llvm.ldexp.f64.i32(double %arg0, i32 51)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:908:define double @ret_ldexp_f64_52(double %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:909:; CHECK-LABEL: define nofpclass(sub) double @ret_ldexp_f64_52
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:911:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(sub) double @llvm.ldexp.f64.i32(double [[ARG0]], i32 noundef 52) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:914:  %call = call double @llvm.ldexp.f64.i32(double %arg0, i32 52)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:918:define double @ret_ldexp_f64_53(double %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:919:; CHECK-LABEL: define nofpclass(sub) double @ret_ldexp_f64_53
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:921:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(sub) double @llvm.ldexp.f64.i32(double [[ARG0]], i32 noundef 53) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:924:  %call = call double @llvm.ldexp.f64.i32(double %arg0, i32 53)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:928:define half @ret_ldexp_f16_8(half %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:929:; CHECK-LABEL: define half @ret_ldexp_f16_8
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:931:; CHECK-NEXT:    [[CALL:%.*]] = call half @llvm.ldexp.f16.i32(half [[ARG0]], i32 noundef 8) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:934:  %call = call half @llvm.ldexp.f16.i32(half %arg0, i32 8)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:938:define half @ret_ldexp_f16_9(half %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:939:; CHECK-LABEL: define half @ret_ldexp_f16_9
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:941:; CHECK-NEXT:    [[CALL:%.*]] = call half @llvm.ldexp.f16.i32(half [[ARG0]], i32 noundef 9) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:944:  %call = call half @llvm.ldexp.f16.i32(half %arg0, i32 9)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:948:define half @ret_ldexp_f16_10(half %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:949:; CHECK-LABEL: define nofpclass(sub) half @ret_ldexp_f16_10
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:951:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(sub) half @llvm.ldexp.f16.i32(half [[ARG0]], i32 noundef 10) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:954:  %call = call half @llvm.ldexp.f16.i32(half %arg0, i32 10)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:958:define bfloat @ret_ldexp_bf16_6(bfloat %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:959:; CHECK-LABEL: define bfloat @ret_ldexp_bf16_6
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:961:; CHECK-NEXT:    [[CALL:%.*]] = call bfloat @llvm.ldexp.bf16.i32(bfloat [[ARG0]], i32 noundef 6) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:964:  %call = call bfloat @llvm.ldexp.bf16.i32(bfloat %arg0, i32 6)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:968:define bfloat @ret_ldexp_bf16_7(bfloat %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:969:; CHECK-LABEL: define nofpclass(sub) bfloat @ret_ldexp_bf16_7
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:971:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(sub) bfloat @llvm.ldexp.bf16.i32(bfloat [[ARG0]], i32 noundef 7) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:974:  %call = call bfloat @llvm.ldexp.bf16.i32(bfloat %arg0, i32 7)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:978:define bfloat @ret_ldexp_bf16_8(bfloat %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:979:; CHECK-LABEL: define nofpclass(sub) bfloat @ret_ldexp_bf16_8
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:981:; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(sub) bfloat @llvm.ldexp.bf16.i32(bfloat [[ARG0]], i32 noundef 8) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:984:  %call = call bfloat @llvm.ldexp.bf16.i32(bfloat %arg0, i32 8)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:988:define float @ret_ldexp_f32_neg22(float %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:989:; CHECK-LABEL: define float @ret_ldexp_f32_neg22
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:991:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef -22) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:994:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 -22)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:998:define float @ret_ldexp_f32_neg23(float %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:999:; CHECK-LABEL: define float @ret_ldexp_f32_neg23
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:1001:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef -23) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:1004:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 -23)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:1008:define float @ret_ldexp_f32_neg24(float %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:1009:; CHECK-LABEL: define float @ret_ldexp_f32_neg24
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:1011:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef -24) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:1014:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 -24)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:1018:define float @ret_ldexp_f32_neg126(float %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:1019:; CHECK-LABEL: define float @ret_ldexp_f32_neg126
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:1021:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef -126) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:1024:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 -126)
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:1028:define float @ret_ldexp_f32_neg127(float %arg0) #0 {
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:1029:; CHECK-LABEL: define float @ret_ldexp_f32_neg127
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:1031:; CHECK-NEXT:    [[CALL:%.*]] = call float @llvm.ldexp.f32.i32(float [[ARG0]], i32 noundef -127) #[[ATTR10]]
llvm/test/Transforms/Attributor/nofpclass-ldexp.ll:1034:  %call = call float @llvm.ldexp.f32.i32(float %arg0, i32 -127)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:4:declare { float, i32 } @llvm.frexp.f32.i32(float)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:5:declare { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float>)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:6:declare { <4 x float>, <4 x i32> } @llvm.frexp.v4f32.v4i32(<4 x float>)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:8:define { float, i32 } @ret_frexp_f32(float %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:9:; CHECK-LABEL: define { float, i32 } @ret_frexp_f32
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:11:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[ARG0]]) #[[ATTR7:[0-9]+]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:14:  %call = call { float, i32 } @llvm.frexp.f32.i32(float %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:18:define { float, i32 } @ret_frexp_f32_nonan(float nofpclass(nan) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:19:; CHECK-LABEL: define { float, i32 } @ret_frexp_f32_nonan
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:21:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(nan) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:24:  %call = call { float, i32 } @llvm.frexp.f32.i32(float %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:28:define float @ret_frexp_f32_0_nonan(float nofpclass(nan) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:29:; CHECK-LABEL: define nofpclass(nan sub) float @ret_frexp_f32_0_nonan
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:31:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(nan) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:35:  %call = call { float, i32 } @llvm.frexp.f32.i32(float %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:40:define float @ret_frexp_f32_0_nosnan(float nofpclass(snan) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:41:; CHECK-LABEL: define nofpclass(snan sub) float @ret_frexp_f32_0_nosnan
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:43:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(snan) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:47:  %call = call { float, i32 } @llvm.frexp.f32.i32(float %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:52:define float @ret_frexp_f32_0_noqnan(float nofpclass(qnan) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:53:; CHECK-LABEL: define nofpclass(sub) float @ret_frexp_f32_0_noqnan
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:55:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(qnan) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:59:  %call = call { float, i32 } @llvm.frexp.f32.i32(float %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:64:define i32 @ret_frexp_f32_1_nonan(float nofpclass(nan) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:65:; CHECK-LABEL: define i32 @ret_frexp_f32_1_nonan
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:67:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(nan) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:71:  %call = call { float, i32 } @llvm.frexp.f32.i32(float %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:76:define <2 x float> @ret_frexp_v2f32_0_nonan(<2 x float> nofpclass(nan) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:77:; CHECK-LABEL: define nofpclass(nan sub) <2 x float> @ret_frexp_v2f32_0_nonan
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:79:; CHECK-NEXT:    [[CALL:%.*]] = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> nofpclass(nan) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:83:  %call = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:88:define <2 x i32> @ret_frexp_v2f32_1_nonan(<2 x float> nofpclass(nan) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:89:; CHECK-LABEL: define <2 x i32> @ret_frexp_v2f32_1_nonan
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:91:; CHECK-NEXT:    [[CALL:%.*]] = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> nofpclass(nan) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:95:  %call = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:100:define float @ret_frexp_v4f32_0_nonan_elt1(<4 x float> nofpclass(nan) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:101:; CHECK-LABEL: define nofpclass(nan sub) float @ret_frexp_v4f32_0_nonan_elt1
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:103:; CHECK-NEXT:    [[CALL:%.*]] = call { <4 x float>, <4 x i32> } @llvm.frexp.v4f32.v4i32(<4 x float> nofpclass(nan) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:108:  %call = call { <4 x float>, <4 x i32> } @llvm.frexp.v4f32.v4i32(<4 x float> %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:114:define float @ret_frexp_f32_0_nopos_nopzero(float nofpclass(pinf psub pnorm pzero) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:115:; CHECK-LABEL: define nofpclass(pinf pzero sub pnorm) float @ret_frexp_f32_0_nopos_nopzero
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:117:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(pinf pzero psub pnorm) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:121:  %call = call { float, i32 } @llvm.frexp.f32.i32(float %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:126:define float @ret_frexp_f32_0_nopos_nopzero_nonan(float nofpclass(pinf psub pnorm pzero nan) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:127:; CHECK-LABEL: define nofpclass(nan pinf pzero sub pnorm) float @ret_frexp_f32_0_nopos_nopzero_nonan
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:129:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(nan pinf pzero psub pnorm) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:133:  %call = call { float, i32 } @llvm.frexp.f32.i32(float %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:138:define float @ret_frexp_f32_0_nopos(float nofpclass(pinf psub pnorm) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:139:; CHECK-LABEL: define nofpclass(pinf sub) float @ret_frexp_f32_0_nopos
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:141:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(pinf psub pnorm) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:145:  %call = call { float, i32 } @llvm.frexp.f32.i32(float %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:150:define float @ret_frexp_f32_0_nopos_nonan(float nofpclass(pinf psub pnorm nan) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:151:; CHECK-LABEL: define nofpclass(nan pinf sub) float @ret_frexp_f32_0_nopos_nonan
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:153:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(nan pinf psub pnorm) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:157:  %call = call { float, i32 } @llvm.frexp.f32.i32(float %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:162:define float @ret_frexp_f32_0_nopos_nozero(float nofpclass(pinf psub pnorm zero) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:163:; CHECK-LABEL: define nofpclass(pinf zero sub pnorm) float @ret_frexp_f32_0_nopos_nozero
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:165:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(pinf zero psub pnorm) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:169:  %call = call { float, i32 } @llvm.frexp.f32.i32(float %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:174:define float @ret_frexp_f32_0_noneg_nonzero(float nofpclass(ninf nsub nnorm nzero) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:175:; CHECK-LABEL: define nofpclass(ninf nzero sub nnorm) float @ret_frexp_f32_0_noneg_nonzero
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:177:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(ninf nzero nsub nnorm) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:181:  %call = call { float, i32 } @llvm.frexp.f32.i32(float %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:186:define float @ret_frexp_f32_0_noneg_nonzero_nonan(float nofpclass(ninf nsub nnorm nzero nan) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:187:; CHECK-LABEL: define nofpclass(nan ninf nzero sub nnorm) float @ret_frexp_f32_0_noneg_nonzero_nonan
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:189:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(nan ninf nzero nsub nnorm) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:193:  %call = call { float, i32 } @llvm.frexp.f32.i32(float %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:198:define float @ret_frexp_f32_0_noneg(float nofpclass(ninf nsub nnorm) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:199:; CHECK-LABEL: define nofpclass(ninf sub) float @ret_frexp_f32_0_noneg
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:201:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(ninf nsub nnorm) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:205:  %call = call { float, i32 } @llvm.frexp.f32.i32(float %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:210:define float @ret_frexp_f32_0_noneg_nonan(float nofpclass(ninf nsub nnorm nan) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:211:; CHECK-LABEL: define nofpclass(nan ninf sub) float @ret_frexp_f32_0_noneg_nonan
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:213:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(nan ninf nsub nnorm) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:217:  %call = call { float, i32 } @llvm.frexp.f32.i32(float %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:222:define float @ret_frexp_f32_0_noneg_nozero(float nofpclass(ninf nsub nnorm nzero) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:223:; CHECK-LABEL: define nofpclass(ninf nzero sub nnorm) float @ret_frexp_f32_0_noneg_nozero
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:225:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(ninf nzero nsub nnorm) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:229:  %call = call { float, i32 } @llvm.frexp.f32.i32(float %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:234:define float @ret_frexp_f32_0_nopzero(float nofpclass(pzero) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:235:; CHECK-LABEL: define nofpclass(pzero sub) float @ret_frexp_f32_0_nopzero
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:237:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(pzero) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:241:  %call = call { float, i32 } @llvm.frexp.f32.i32(float %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:246:define float @ret_frexp_f32_0_nonzero(float nofpclass(nzero) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:247:; CHECK-LABEL: define nofpclass(nzero sub) float @ret_frexp_f32_0_nonzero
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:249:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(nzero) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:253:  %call = call { float, i32 } @llvm.frexp.f32.i32(float %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:258:define float @ret_frexp_f32_0_nozero(float nofpclass(zero) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:259:; CHECK-LABEL: define nofpclass(zero sub) float @ret_frexp_f32_0_nozero
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:261:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(zero) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:265:  %call = call { float, i32 } @llvm.frexp.f32.i32(float %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:270:define float @ret_frexp_f32_0_nopinf(float nofpclass(pinf) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:271:; CHECK-LABEL: define nofpclass(pinf sub) float @ret_frexp_f32_0_nopinf
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:273:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(pinf) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:277:  %call = call { float, i32 } @llvm.frexp.f32.i32(float %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:282:define float @ret_frexp_f32_0_noninf(float nofpclass(ninf) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:283:; CHECK-LABEL: define nofpclass(ninf sub) float @ret_frexp_f32_0_noninf
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:285:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(ninf) [[ARG0]]) #[[ATTR7]]
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:289:  %call = call { float, i32 } @llvm.frexp.f32.i32(float %arg0)
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:294:define float @ret_frexp_f32_0_noinf(float nofpclass(inf) %arg0) {
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:295:; CHECK-LABEL: define nofpclass(inf sub) float @ret_frexp_f32_0_noinf
llvm/test/Transforms/Attributor/nofpclass-frexp.ll:297:; CHECK-NEXT:    [[CALL:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float nofpclass(inf) [[ARG0]]) #[[ATTR7]]
... (truncated, total 29012 lines)

TOOL CALL: langref

{"inst":"llvm.frexp"}

TOOL OUTPUT

.. _int_frexp:

'``llvm.frexp.*``' Intrinsic
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Syntax:
"""""""

This is an overloaded intrinsic. You can use ``llvm.frexp`` on any
floating point or vector of floating point type. Not all targets support
all types however.

::

      declare { float, i32 }     @llvm.frexp.f32.i32(float %Val)
      declare { double, i32 }    @llvm.frexp.f64.i32(double %Val)
      declare { x86_fp80, i32 }  @llvm.frexp.f80.i32(x86_fp80 %Val)
      declare { fp128, i32 }     @llvm.frexp.f128.i32(fp128 %Val)
      declare { ppc_fp128, i32 } @llvm.frexp.ppcf128.i32(ppc_fp128 %Val)
      declare { <2 x float>, <2 x i32> }  @llvm.frexp.v2f32.v2i32(<2 x float> %Val)

Overview:
"""""""""

The '``llvm.frexp.*``' intrinsics perform the frexp function.

Arguments:
""""""""""

The argument is a :ref:`floating-point <t_floating>` or
:ref:`vector <t_vector>` of floating-point values. Returns two values
in a struct. The first struct field matches the argument type, and the
second field is an integer or a vector of integer values with the same
number of elements as the argument.

Semantics:
""""""""""

This intrinsic splits a floating point value into a normalized
fractional component and integral exponent.

For a non-zero argument, returns the argument multiplied by some power
of two such that the absolute value of the returned value is in the
range [0.5, 1.0), with the same sign as the argument. The second
result is an integer such that the first result raised to the power of
the second result is the input argument.

If the argument is a zero, returns a zero with the same sign and a 0
exponent.

If the argument is a NaN, a NaN is returned and the returned exponent
is unspecified.

If the argument is an infinity, returns an infinity with the same sign
and an unspecified exponent.

TOOL CALL: langref

{"inst":"llvm.ldexp"}

TOOL OUTPUT

.. _int_exp10:

'``llvm.exp10.*``' Intrinsic
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Syntax:
"""""""

This is an overloaded intrinsic. You can use ``llvm.exp10`` on any
floating-point or vector of floating-point type. Not all targets support
all types however.

::

      declare float     @llvm.exp10.f32(float  %Val)
      declare double    @llvm.exp10.f64(double %Val)
      declare x86_fp80  @llvm.exp10.f80(x86_fp80  %Val)
      declare fp128     @llvm.exp10.f128(fp128 %Val)
      declare ppc_fp128 @llvm.exp10.ppcf128(ppc_fp128  %Val)

Overview:
"""""""""

The '``llvm.exp10.*``' intrinsics compute the base-10 exponential of the
specified value.

Arguments:
""""""""""

The argument and return value are floating-point numbers of the same type.

Semantics:
""""""""""

Return the same value as a corresponding libm '``exp10``' function but without
trapping or setting ``errno``.

When specified with the fast-math-flag 'afn', the result may be approximated
using a less accurate calculation.


'``llvm.ldexp.*``' Intrinsic
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Syntax:
"""""""

This is an overloaded intrinsic. You can use ``llvm.ldexp`` on any
floating point or vector of floating point type. Not all targets support
all types however.

::

      declare float     @llvm.ldexp.f32.i32(float %Val, i32 %Exp)
      declare double    @llvm.ldexp.f64.i32(double %Val, i32 %Exp)
      declare x86_fp80  @llvm.ldexp.f80.i32(x86_fp80 %Val, i32 %Exp)
      declare fp128     @llvm.ldexp.f128.i32(fp128 %Val, i32 %Exp)
      declare ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128 %Val, i32 %Exp)
      declare <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %Val, <2 x i32> %Exp)

Overview:
"""""""""

The '``llvm.ldexp.*``' intrinsics perform the ldexp function.

Arguments:
""""""""""

The first argument and the return value are :ref:`floating-point
<t_floating>` or :ref:`vector <t_vector>` of floating-point values of
the same type. The second argument is an integer with the same number
of elements.

Semantics:
""""""""""

This function multiplies the first argument by 2 raised to the second
argument's power. If the first argument is NaN or infinite, the same
value is returned. If the result underflows a zero with the same sign
is returned. If the result overflows, the result is an infinity with
the same sign.

TOOL CALL: read250

{"file":"llvm/lib/Analysis/ValueTracking.cpp","position":1020}

TOOL OUTPUT

file: llvm/lib/Analysis/ValueTracking.cpp:1020-1270
---------------------------------------------------
1020     if (cast<TruncInst>(Cond)->hasNoUnsignedWrap()) {
1021       Known = Known.unionWith(DstKnown.zext(Known.getBitWidth()));
1022       return;
1023     }
1024     Known = Known.unionWith(DstKnown.anyext(Known.getBitWidth()));
1025     return;
1026   }
1027 
1028   if (Depth < MaxAnalysisRecursionDepth && match(Cond, m_Not(m_Value(A))))
1029     computeKnownBitsFromCond(V, A, Known, SQ, !Invert, Depth + 1);
1030 }
1031 
1032 void llvm::computeKnownBitsFromContext(const Value *V, KnownBits &Known,
1033                                        const SimplifyQuery &Q, unsigned Depth) {
1034   // Handle injected condition.
1035   if (Q.CC && Q.CC->AffectedValues.contains(V))
1036     computeKnownBitsFromCond(V, Q.CC->Cond, Known, Q, Q.CC->Invert, Depth);
1037 
1038   if (!Q.CxtI)
1039     return;
1040 
1041   if (Q.DC && Q.DT) {
1042     // Handle dominating conditions.
1043     for (CondBrInst *BI : Q.DC->conditionsFor(V)) {
1044       BasicBlockEdge Edge0(BI->getParent(), BI->getSuccessor(0));
1045       if (Q.DT->dominates(Edge0, Q.CxtI->getParent()))
1046         computeKnownBitsFromCond(V, BI->getCondition(), Known, Q,
1047                                  /*Invert*/ false, Depth);
1048 
1049       BasicBlockEdge Edge1(BI->getParent(), BI->getSuccessor(1));
1050       if (Q.DT->dominates(Edge1, Q.CxtI->getParent()))
1051         computeKnownBitsFromCond(V, BI->getCondition(), Known, Q,
1052                                  /*Invert*/ true, Depth);
1053     }
1054 
1055     if (Known.hasConflict())
1056       Known.resetAll();
1057   }
1058 
1059   if (!Q.AC)
1060     return;
1061 
1062   unsigned BitWidth = Known.getBitWidth();
1063 
1064   // Note that the patterns below need to be kept in sync with the code
1065   // in AssumptionCache::updateAffectedValues.
1066 
1067   for (AssumptionCache::ResultElem &Elem : Q.AC->assumptionsFor(V)) {
1068     if (!Elem.Assume)
1069       continue;
1070 
1071     AssumeInst *I = cast<AssumeInst>(Elem.Assume);
1072     assert(I->getParent()->getParent() == Q.CxtI->getParent()->getParent() &&
1073            "Got assumption for the wrong function!");
1074 
1075     if (Elem.Index != AssumptionCache::ExprResultIdx) {
1076       if (auto OBU = I->getOperandBundleAt(Elem.Index);
1077           getBundleAttrFromOBU(OBU) == BundleAttr::Align) {
1078         auto [Ptr, _, _2, Alignment, Offset] = getAssumeAlignInfo(OBU);
1079         if (Ptr == V && Alignment && Offset && isPowerOf2_64(*Alignment) &&
1080             isValidAssumeForContext(I, Q)) {
1081           Known.Zero |= (*Alignment - 1) & ~*Offset;
1082           Known.One |= (*Alignment - 1) & *Offset;
1083         }
1084       }
1085       continue;
1086     }
1087 
1088     // Warning: This loop can end up being somewhat performance sensitive.
1089     // We're running this loop for once for each value queried resulting in a
1090     // runtime of ~O(#assumes * #values).
1091 
1092     Value *Arg = I->getArgOperand(0);
1093 
1094     if (Arg == V && isValidAssumeForContext(I, Q)) {
1095       assert(BitWidth == 1 && "assume operand is not i1?");
1096       (void)BitWidth;
1097       Known.setAllOnes();
1098       return;
1099     }
1100     if (match(Arg, m_Not(m_Specific(V))) &&
1101         isValidAssumeForContext(I, Q)) {
1102       assert(BitWidth == 1 && "assume operand is not i1?");
1103       (void)BitWidth;
1104       Known.setAllZero();
1105       return;
1106     }
1107     auto *Trunc = dyn_cast<TruncInst>(Arg);
1108     if (Trunc && Trunc->getOperand(0) == V &&
1109         isValidAssumeForContext(I, Q)) {
1110       if (Trunc->hasNoUnsignedWrap()) {
1111         Known = KnownBits::makeConstant(APInt(BitWidth, 1));
1112         return;
1113       }
1114       Known.One.setBit(0);
1115       return;
1116     }
1117 
1118     // The remaining tests are all recursive, so bail out if we hit the limit.
1119     if (Depth == MaxAnalysisRecursionDepth)
1120       continue;
1121 
1122     ICmpInst *Cmp = dyn_cast<ICmpInst>(Arg);
1123     if (!Cmp)
1124       continue;
1125 
1126     if (!isValidAssumeForContext(I, Q))
1127       continue;
1128 
1129     computeKnownBitsFromICmpCond(V, Cmp, Known, Q, /*Invert=*/false);
1130   }
1131 
1132   // Conflicting assumption: Undefined behavior will occur on this execution
1133   // path.
1134   if (Known.hasConflict())
1135     Known.resetAll();
1136 }
1137 
1138 /// Compute known bits from a shift operator, including those with a
1139 /// non-constant shift amount. Known is the output of this function. Known2 is a
1140 /// pre-allocated temporary with the same bit width as Known and on return
1141 /// contains the known bit of the shift value source. KF is an
1142 /// operator-specific function that, given the known-bits and a shift amount,
1143 /// compute the implied known-bits of the shift operator's result respectively
1144 /// for that shift amount. The results from calling KF are conservatively
1145 /// combined for all permitted shift amounts.
1146 static void computeKnownBitsFromShiftOperator(
1147     const Operator *I, const APInt &DemandedElts, KnownBits &Known,
1148     KnownBits &Known2, const SimplifyQuery &Q, unsigned Depth,
1149     function_ref<KnownBits(const KnownBits &, const KnownBits &, bool)> KF) {
1150   computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q, Depth + 1);
1151   computeKnownBits(I->getOperand(1), DemandedElts, Known, Q, Depth + 1);
1152   // To limit compile-time impact, only query isKnownNonZero() if we know at
1153   // least something about the shift amount.
1154   bool ShAmtNonZero =
1155       Known.isNonZero() ||
1156       (Known.getMaxValue().ult(Known.getBitWidth()) &&
1157        isKnownNonZero(I->getOperand(1), DemandedElts, Q, Depth + 1));
1158   Known = KF(Known2, Known, ShAmtNonZero);
1159 }
1160 
1161 static KnownBits
1162 getKnownBitsFromAndXorOr(const Operator *I, const APInt &DemandedElts,
1163                          const KnownBits &KnownLHS, const KnownBits &KnownRHS,
1164                          const SimplifyQuery &Q, unsigned Depth) {
1165   unsigned BitWidth = KnownLHS.getBitWidth();
1166   KnownBits KnownOut(BitWidth);
1167   bool IsAnd = false;
1168   bool HasKnownOne = !KnownLHS.One.isZero() || !KnownRHS.One.isZero();
1169   Value *X = nullptr, *Y = nullptr;
1170 
1171   switch (I->getOpcode()) {
1172   case Instruction::And:
1173     KnownOut = KnownLHS & KnownRHS;
1174     IsAnd = true;
1175     // and(x, -x) is common idioms that will clear all but lowest set
1176     // bit. If we have a single known bit in x, we can clear all bits
1177     // above it.
1178     // TODO: instcombine often reassociates independent `and` which can hide
1179     // this pattern. Try to match and(x, and(-x, y)) / and(and(x, y), -x).
1180     if (HasKnownOne && match(I, m_c_And(m_Value(X), m_Neg(m_Deferred(X))))) {
1181       // -(-x) == x so using whichever (LHS/RHS) gets us a better result.
1182       if (KnownLHS.countMaxTrailingZeros() <= KnownRHS.countMaxTrailingZeros())
1183         KnownOut = KnownLHS.blsi();
1184       else
1185         KnownOut = KnownRHS.blsi();
1186     }
1187     break;
1188   case Instruction::Or:
1189     KnownOut = KnownLHS | KnownRHS;
1190     break;
1191   case Instruction::Xor:
1192     KnownOut = KnownLHS ^ KnownRHS;
1193     // xor(x, x-1) is common idioms that will clear all but lowest set
1194     // bit. If we have a single known bit in x, we can clear all bits
1195     // above it.
1196     // TODO: xor(x, x-1) is often rewritting as xor(x, x-C) where C !=
1197     // -1 but for the purpose of demanded bits (xor(x, x-C) &
1198     // Demanded) == (xor(x, x-1) & Demanded). Extend the xor pattern
1199     // to use arbitrary C if xor(x, x-C) as the same as xor(x, x-1).
1200     if (HasKnownOne &&
1201         match(I, m_c_Xor(m_Value(X), m_Add(m_Deferred(X), m_AllOnes())))) {
1202       const KnownBits &XBits = I->getOperand(0) == X ? KnownLHS : KnownRHS;
1203       KnownOut = XBits.blsmsk();
1204     }
1205     break;
1206   default:
1207     llvm_unreachable("Invalid Op used in 'analyzeKnownBitsFromAndXorOr'");
1208   }
1209 
1210   // and(x, add (x, -1)) is a common idiom that always clears the low bit;
1211   // xor/or(x, add (x, -1)) is an idiom that will always set the low bit.
1212   // here we handle the more general case of adding any odd number by
1213   // matching the form and/xor/or(x, add(x, y)) where y is odd.
1214   // TODO: This could be generalized to clearing any bit set in y where the
1215   // following bit is known to be unset in y.
1216   if (!KnownOut.Zero[0] && !KnownOut.One[0] &&
1217       (match(I, m_c_BinOp(m_Value(X), m_c_Add(m_Deferred(X), m_Value(Y)))) ||
1218        match(I, m_c_BinOp(m_Value(X), m_Sub(m_Deferred(X), m_Value(Y)))) ||
1219        match(I, m_c_BinOp(m_Value(X), m_Sub(m_Value(Y), m_Deferred(X)))))) {
1220     KnownBits KnownY(BitWidth);
1221     computeKnownBits(Y, DemandedElts, KnownY, Q, Depth + 1);
1222     if (KnownY.countMinTrailingOnes() > 0) {
1223       if (IsAnd)
1224         KnownOut.Zero.setBit(0);
1225       else
1226         KnownOut.One.setBit(0);
1227     }
1228   }
1229   return KnownOut;
1230 }
1231 
1232 static KnownBits computeKnownBitsForHorizontalOperation(
1233     const Operator *I, const APInt &DemandedElts, const SimplifyQuery &Q,
1234     unsigned Depth,
1235     const function_ref<KnownBits(const KnownBits &, const KnownBits &)>
1236         KnownBitsFunc) {
1237   APInt DemandedEltsLHS, DemandedEltsRHS;
1238   getHorizDemandedEltsForFirstOperand(Q.DL.getTypeSizeInBits(I->getType()),
1239                                       DemandedElts, DemandedEltsLHS,
1240                                       DemandedEltsRHS);
1241 
1242   const auto ComputeForSingleOpFunc =
1243       [Depth, &Q, KnownBitsFunc](const Value *Op, APInt &DemandedEltsOp) {
1244         return KnownBitsFunc(
1245             computeKnownBits(Op, DemandedEltsOp, Q, Depth + 1),
1246             computeKnownBits(Op, DemandedEltsOp << 1, Q, Depth + 1));
1247       };
1248 
1249   if (DemandedEltsRHS.isZero())
1250     return ComputeForSingleOpFunc(I->getOperand(0), DemandedEltsLHS);
1251   if (DemandedEltsLHS.isZero())
1252     return ComputeForSingleOpFunc(I->getOperand(1), DemandedEltsRHS);
1253 
1254   return ComputeForSingleOpFunc(I->getOperand(0), DemandedEltsLHS)
1255       .intersectWith(ComputeForSingleOpFunc(I->getOperand(1), DemandedEltsRHS));
1256 }
1257 
1258 // Public so this can be used in `SimplifyDemandedUseBits`.
1259 KnownBits llvm::analyzeKnownBitsFromAndXorOr(const Operator *I,
1260                                              const KnownBits &KnownLHS,
1261                                              const KnownBits &KnownRHS,
1262                                              const SimplifyQuery &SQ,
1263                                              unsigned Depth) {
1264   auto *FVTy = dyn_cast<FixedVectorType>(I->getType());
1265   APInt DemandedElts =
1266       FVTy ? APInt::getAllOnes(FVTy->getNumElements()) : APInt(1, 1);
1267 
1268   return getKnownBitsFromAndXorOr(I, DemandedElts, KnownLHS, KnownRHS, SQ,
1269                                   Depth);
---------------------------------------------------

TOOL CALL: read250

{"file":"llvm/lib/Analysis/ValueTracking.cpp","position":4840}

TOOL OUTPUT

file: llvm/lib/Analysis/ValueTracking.cpp:4840-5090
---------------------------------------------------
4840                                 Depth + 1);
4841     return;
4842   }
4843   CmpPredicate Pred;
4844   Value *LHS;
4845   uint64_t ClassVal = 0;
4846   const APFloat *CRHS;
4847   const APInt *RHS;
4848   if (match(Cond, m_FCmp(Pred, m_Value(LHS), m_APFloat(CRHS)))) {
4849     auto [CmpVal, MaskIfTrue, MaskIfFalse] = fcmpImpliesClass(
4850         Pred, *cast<Instruction>(Cond)->getParent()->getParent(), LHS, *CRHS,
4851         LHS != V);
4852     if (CmpVal == V)
4853       KnownFromContext.knownNot(~(CondIsTrue ? MaskIfTrue : MaskIfFalse));
4854   } else if (match(Cond, m_Intrinsic<Intrinsic::is_fpclass>(
4855                              m_Specific(V), m_ConstantInt(ClassVal)))) {
4856     FPClassTest Mask = static_cast<FPClassTest>(ClassVal);
4857     KnownFromContext.knownNot(CondIsTrue ? ~Mask : Mask);
4858   } else if (match(Cond, m_ICmp(Pred, m_ElementWiseBitCast(m_Specific(V)),
4859                                 m_APInt(RHS)))) {
4860     bool TrueIfSigned;
4861     if (!isSignBitCheck(Pred, *RHS, TrueIfSigned))
4862       return;
4863     if (TrueIfSigned == CondIsTrue)
4864       KnownFromContext.signBitMustBeOne();
4865     else
4866       KnownFromContext.signBitMustBeZero();
4867   }
4868 }
4869 
4870 /// Compute the minimum and maximum values (inclusive) for the exponent of \p V,
4871 /// assuming it is not nan.
4872 static std::pair<int, int>
4873 computeKnownExponentRangeFromContext(const Value *V, const SimplifyQuery &Q) {
4874   if (!Q.CxtI || !Q.DC || !Q.DT)
4875     return {APFloat::IEK_NaN, APFloat::IEK_Inf};
4876 
4877   for (CondBrInst *BI : Q.DC->conditionsFor(V)) {
4878     CmpPredicate Pred;
4879     const APFloat *LimitC;
4880     if (!match(BI->getCondition(),
4881                m_FCmp(Pred, m_FAbs(m_Specific(V)), m_Finite(LimitC))))
4882       continue;
4883 
4884     if (Pred == FCmpInst::FCMP_ORD || Pred == FCmpInst::FCMP_UNO ||
4885         Pred == FCmpInst::FCMP_TRUE || Pred == FCmpInst::FCMP_FALSE)
4886       continue;
4887 
4888     APFloat::cmpResult CmpOne =
4889         LimitC->compare(APFloat::getOne(LimitC->getSemantics()));
4890     if (CmpOne > APFloat::cmpEqual)
4891       continue;
4892 
4893     // If fabs(x) <= K, K <= 1.0 => exponent min exp range
4894     // if fabs(x) >= K, K <= 1.0 swap the successor
4895     bool IsLessEqual =
4896         Pred == FCmpInst::FCMP_OLT || Pred == FCmpInst::FCMP_OLE ||
4897         Pred == FCmpInst::FCMP_ULT || Pred == FCmpInst::FCMP_ULE ||
4898         Pred == FCmpInst::FCMP_OEQ || Pred == FCmpInst::FCMP_UEQ;
4899 
4900     BasicBlockEdge Edge1(BI->getParent(),
4901                          BI->getSuccessor(IsLessEqual ? 0 : 1));
4902     if (Q.DT->dominates(Edge1, Q.CxtI->getParent())) {
4903       int Exp = ilogb(*LimitC);
4904 
4905       // TODO: Figure out lower bound to detect no-underflow.
4906       return {APFloat::IEK_NaN, Exp};
4907     }
4908   }
4909 
4910   return {APFloat::IEK_NaN, APFloat::IEK_Inf};
4911 }
4912 
4913 static KnownFPClass computeKnownFPClassFromContext(const Value *V,
4914                                                    const SimplifyQuery &Q) {
4915   KnownFPClass KnownFromContext;
4916 
4917   if (Q.CC && Q.CC->AffectedValues.contains(V))
4918     computeKnownFPClassFromCond(V, Q.CC->Cond, !Q.CC->Invert, Q.CxtI,
4919                                 KnownFromContext);
4920 
4921   if (!Q.CxtI)
4922     return KnownFromContext;
4923 
4924   if (Q.DC && Q.DT) {
4925     // Handle dominating conditions.
4926     for (CondBrInst *BI : Q.DC->conditionsFor(V)) {
4927       Value *Cond = BI->getCondition();
4928 
4929       BasicBlockEdge Edge0(BI->getParent(), BI->getSuccessor(0));
4930       if (Q.DT->dominates(Edge0, Q.CxtI->getParent()))
4931         computeKnownFPClassFromCond(V, Cond, /*CondIsTrue=*/true, Q.CxtI,
4932                                     KnownFromContext);
4933 
4934       BasicBlockEdge Edge1(BI->getParent(), BI->getSuccessor(1));
4935       if (Q.DT->dominates(Edge1, Q.CxtI->getParent()))
4936         computeKnownFPClassFromCond(V, Cond, /*CondIsTrue=*/false, Q.CxtI,
4937                                     KnownFromContext);
4938     }
4939   }
4940 
4941   if (!Q.AC)
4942     return KnownFromContext;
4943 
4944   // Try to restrict the floating-point classes based on information from
4945   // assumptions.
4946   for (auto &AssumeVH : Q.AC->assumptionsFor(V)) {
4947     if (!AssumeVH)
4948       continue;
4949     CallInst *I = cast<CallInst>(AssumeVH);
4950 
4951     assert(I->getFunction() == Q.CxtI->getParent()->getParent() &&
4952            "Got assumption for the wrong function!");
4953     assert(I->getIntrinsicID() == Intrinsic::assume &&
4954            "must be an assume intrinsic");
4955 
4956     if (!isValidAssumeForContext(I, Q))
4957       continue;
4958 
4959     computeKnownFPClassFromCond(V, I->getArgOperand(0),
4960                                 /*CondIsTrue=*/true, Q.CxtI, KnownFromContext);
4961   }
4962 
4963   return KnownFromContext;
4964 }
4965 
4966 void llvm::adjustKnownFPClassForSelectArm(KnownFPClass &Known, Value *Cond,
4967                                           Value *Arm, bool Invert,
4968                                           const SimplifyQuery &SQ,
4969                                           unsigned Depth) {
4970 
4971   KnownFPClass KnownSrc;
4972   computeKnownFPClassFromCond(Arm, Cond,
4973                               /*CondIsTrue=*/!Invert, SQ.CxtI, KnownSrc,
4974                               Depth + 1);
4975   KnownSrc = KnownSrc.unionWith(Known);
4976   if (KnownSrc.isUnknown())
4977     return;
4978 
4979   if (isGuaranteedNotToBeUndef(Arm, SQ.AC, SQ.CxtI, SQ.DT, Depth + 1))
4980     Known = KnownSrc;
4981 }
4982 
4983 void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
4984                          FPClassTest InterestedClasses, KnownFPClass &Known,
4985                          const SimplifyQuery &Q, unsigned Depth);
4986 
4987 static void computeKnownFPClass(const Value *V, KnownFPClass &Known,
4988                                 FPClassTest InterestedClasses,
4989                                 const SimplifyQuery &Q, unsigned Depth) {
4990   auto *FVTy = dyn_cast<FixedVectorType>(V->getType());
4991   APInt DemandedElts =
4992       FVTy ? APInt::getAllOnes(FVTy->getNumElements()) : APInt(1, 1);
4993   computeKnownFPClass(V, DemandedElts, InterestedClasses, Known, Q, Depth);
4994 }
4995 
4996 static void computeKnownFPClassForFPTrunc(const Operator *Op,
4997                                           const APInt &DemandedElts,
4998                                           FPClassTest InterestedClasses,
4999                                           KnownFPClass &Known,
5000                                           const SimplifyQuery &Q,
5001                                           unsigned Depth) {
5002   if ((InterestedClasses &
5003        (KnownFPClass::OrderedLessThanZeroMask | fcNan)) == fcNone)
5004     return;
5005 
5006   KnownFPClass KnownSrc;
5007   computeKnownFPClass(Op->getOperand(0), DemandedElts, InterestedClasses,
5008                       KnownSrc, Q, Depth + 1);
5009   Known = KnownFPClass::fptrunc(KnownSrc);
5010 }
5011 
5012 static constexpr KnownFPClass::MinMaxKind getMinMaxKind(Intrinsic::ID IID) {
5013   switch (IID) {
5014   case Intrinsic::minimum:
5015     return KnownFPClass::MinMaxKind::minimum;
5016   case Intrinsic::maximum:
5017     return KnownFPClass::MinMaxKind::maximum;
5018   case Intrinsic::minimumnum:
5019     return KnownFPClass::MinMaxKind::minimumnum;
5020   case Intrinsic::maximumnum:
5021     return KnownFPClass::MinMaxKind::maximumnum;
5022   case Intrinsic::minnum:
5023     return KnownFPClass::MinMaxKind::minnum;
5024   case Intrinsic::maxnum:
5025     return KnownFPClass::MinMaxKind::maxnum;
5026   default:
5027     llvm_unreachable("not a floating-point min-max intrinsic");
5028   }
5029 }
5030 
5031 /// \return true if this is a floating point value that is known to have a
5032 /// magnitude smaller than 1. i.e., fabs(X) <= 1.0 or is nan.
5033 static bool isAbsoluteValueULEOne(const Value *V) {
5034   // TODO: Handle frexp
5035   // TODO: Other rounding intrinsics?
5036   // TODO: Try computeKnownExponentRangeFromContext
5037 
5038   // fabs(x - floor(x)) <= 1
5039   const Value *SubFloorX;
5040   if (match(V, m_FSub(m_Value(SubFloorX),
5041                       m_Intrinsic<Intrinsic::floor>(m_Deferred(SubFloorX)))))
5042     return true;
5043 
5044   return match(V, m_Intrinsic<Intrinsic::amdgcn_trig_preop>(m_Value())) ||
5045          match(V, m_Intrinsic<Intrinsic::amdgcn_fract>(m_Value()));
5046 }
5047 
5048 void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
5049                          FPClassTest InterestedClasses, KnownFPClass &Known,
5050                          const SimplifyQuery &Q, unsigned Depth) {
5051   assert(Known.isUnknown() && "should not be called with known information");
5052 
5053   if (!DemandedElts) {
5054     // No demanded elts, better to assume we don't know anything.
5055     Known.resetAll();
5056     return;
5057   }
5058 
5059   assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth");
5060 
5061   if (auto *CFP = dyn_cast<ConstantFP>(V)) {
5062     Known = KnownFPClass(CFP->getValueAPF());
5063     return;
5064   }
5065 
5066   if (isa<ConstantAggregateZero>(V)) {
5067     Known.KnownFPClasses = fcPosZero;
5068     Known.SignBit = false;
5069     return;
5070   }
5071 
5072   if (isa<PoisonValue>(V)) {
5073     Known.KnownFPClasses = fcNone;
5074     Known.SignBit = false;
5075     return;
5076   }
5077 
5078   // Try to handle fixed width vector constants
5079   auto *VFVTy = dyn_cast<FixedVectorType>(V->getType());
5080   const Constant *CV = dyn_cast<Constant>(V);
5081   if (VFVTy && CV) {
5082     Known.KnownFPClasses = fcNone;
5083     bool SignBitAllZero = true;
5084     bool SignBitAllOne = true;
5085 
5086     // For vectors, verify that each element is not NaN.
5087     unsigned NumElts = VFVTy->getNumElements();
5088     for (unsigned i = 0; i != NumElts; ++i) {
5089       if (!DemandedElts[i])
---------------------------------------------------

TOOL CALL: read250

{"file":"llvm/lib/Analysis/ValueTracking.cpp","position":10470}

TOOL OUTPUT

file: llvm/lib/Analysis/ValueTracking.cpp:10470-10720
-----------------------------------------------------
10470     setLimitsForBinOp(*BO, Lower, Upper, SQ.IIQ, ForSigned);
10471     CR = ConstantRange::getNonEmpty(Lower, Upper);
10472   } else if (auto *II = dyn_cast<IntrinsicInst>(V))
10473     CR = getRangeForIntrinsic(*II, SQ.IIQ.UseInstrInfo);
10474   else if (auto *SI = dyn_cast<SelectInst>(V)) {
10475     ConstantRange CRTrue =
10476         computeConstantRange(SI->getTrueValue(), ForSigned, SQ, Depth + 1);
10477     ConstantRange CRFalse =
10478         computeConstantRange(SI->getFalseValue(), ForSigned, SQ, Depth + 1);
10479     CR = CRTrue.unionWith(CRFalse);
10480     CR = CR.intersectWith(getRangeForSelectPattern(*SI, SQ.IIQ));
10481   } else if (auto *TI = dyn_cast<TruncInst>(V)) {
10482     ConstantRange SrcCR =
10483         computeConstantRange(TI->getOperand(0), ForSigned, SQ, Depth + 1);
10484     CR = SrcCR.truncate(BitWidth);
10485   } else if (isa<FPToUIInst>(V) || isa<FPToSIInst>(V)) {
10486     APInt Lower = APInt(BitWidth, 0);
10487     APInt Upper = APInt(BitWidth, 0);
10488     // TODO: Return ConstantRange.
10489     setLimitForFPToI(cast<Instruction>(V), Lower, Upper);
10490     CR = ConstantRange::getNonEmpty(Lower, Upper);
10491   } else if (const auto *A = dyn_cast<Argument>(V))
10492     if (std::optional<ConstantRange> Range = A->getRange())
10493       CR = *Range;
10494 
10495   if (auto *I = dyn_cast<Instruction>(V)) {
10496     if (auto *Range = SQ.IIQ.getMetadata(I, LLVMContext::MD_range))
10497       CR = CR.intersectWith(getConstantRangeFromMetadata(*Range));
10498 
10499     Value *FrexpSrc;
10500     if (const auto *CB = dyn_cast<CallBase>(V)) {
10501       if (std::optional<ConstantRange> Range = CB->getRange())
10502         CR = CR.intersectWith(*Range);
10503     } else if (match(I, m_ExtractValue<1>(m_Intrinsic<Intrinsic::frexp>(
10504                             m_Value(FrexpSrc))))) {
10505       const fltSemantics &FltSem =
10506           FrexpSrc->getType()->getScalarType()->getFltSemantics();
10507       // It should be possible to implement this for any type, but this logic
10508       // only computes the range assuming standard subnormal handling.
10509       if (APFloat::isIEEELikeFP(FltSem)) {
10510         KnownFPClass KnownSrc = computeKnownFPClass(
10511             FrexpSrc, fcSubnormal | fcNan | fcInf, SQ, Depth + 1);
10512 
10513         // The exponent of frexp(NaN) and frexp(Inf) is unspecified. Only
10514         // constrain its range when the source can be neither.
10515         if (KnownSrc.isKnownNeverInfOrNaN()) {
10516           int MinExp = APFloat::semanticsMinExponent(FltSem) + 1;
10517 
10518           // Offset to find the true minimum exponent value for a denormal.
10519           if (!KnownSrc.isKnownNeverSubnormal())
10520             MinExp -= (APFloat::semanticsPrecision(FltSem) - 1);
10521 
10522           int MaxExp = APFloat::semanticsMaxExponent(FltSem) + 1;
10523 
10524           auto [AdjustedMin, AdjustedMax] =
10525               computeKnownExponentRangeFromContext(FrexpSrc, SQ);
10526 
10527           MinExp = std::max(AdjustedMin, MinExp);
10528           MaxExp = std::min(AdjustedMax, MaxExp);
10529 
10530           CR = ConstantRange::getNonEmpty(
10531               APInt(BitWidth, static_cast<int64_t>(MinExp), /*isSigned=*/true),
10532               APInt(BitWidth, static_cast<int64_t>(MaxExp) + 1,
10533                     /*isSigned=*/true));
10534         }
10535       }
10536     }
10537   }
10538 
10539   if (SQ.CxtI && SQ.AC) {
10540     // Try to restrict the range based on information from assumptions.
10541     for (auto &AssumeVH : SQ.AC->assumptionsFor(V)) {
10542       if (!AssumeVH)
10543         continue;
10544       CallInst *I = cast<CallInst>(AssumeVH);
10545       assert(I->getParent()->getParent() == SQ.CxtI->getParent()->getParent() &&
10546              "Got assumption for the wrong function!");
10547       assert(I->getIntrinsicID() == Intrinsic::assume &&
10548              "must be an assume intrinsic");
10549 
10550       if (!isValidAssumeForContext(I, SQ))
10551         continue;
10552       Value *Arg = I->getArgOperand(0);
10553       ICmpInst *Cmp = dyn_cast<ICmpInst>(Arg);
10554       // Currently we just use information from comparisons.
10555       if (!Cmp || Cmp->getOperand(0) != V)
10556         continue;
10557       // TODO: Set "ForSigned" parameter via Cmp->isSigned()?
10558       ConstantRange RHS =
10559           computeConstantRange(Cmp->getOperand(1), /*ForSigned=*/false,
10560                                SQ.getWithInstruction(I), Depth + 1);
10561       CR = CR.intersectWith(
10562           ConstantRange::makeAllowedICmpRegion(Cmp->getCmpPredicate(), RHS));
10563     }
10564   }
10565 
10566   return CR;
10567 }
10568 
10569 static void
10570 addValueAffectedByCondition(Value *V,
10571                             function_ref<void(Value *)> InsertAffected) {
10572   assert(V != nullptr);
10573   if (isa<Argument>(V) || isa<GlobalValue>(V)) {
10574     InsertAffected(V);
10575   } else if (auto *I = dyn_cast<Instruction>(V)) {
10576     InsertAffected(V);
10577 
10578     // Peek through unary operators to find the source of the condition.
10579     Value *Op;
10580     if (match(I, m_CombineOr(m_PtrToIntOrAddr(m_Value(Op)),
10581                              m_Trunc(m_Value(Op))))) {
10582       if (isa<Instruction>(Op) || isa<Argument>(Op))
10583         InsertAffected(Op);
10584     }
10585   }
10586 }
10587 
10588 void llvm::findValuesAffectedByCondition(
10589     Value *Cond, bool IsAssume, function_ref<void(Value *)> InsertAffected) {
10590   auto AddAffected = [&InsertAffected](Value *V) {
10591     addValueAffectedByCondition(V, InsertAffected);
10592   };
10593 
10594   auto AddCmpOperands = [&AddAffected, IsAssume](Value *LHS, Value *RHS) {
10595     if (IsAssume) {
10596       AddAffected(LHS);
10597       AddAffected(RHS);
10598     } else if (match(RHS, m_Constant()))
10599       AddAffected(LHS);
10600   };
10601 
10602   SmallVector<Value *, 8> Worklist;
10603   SmallPtrSet<Value *, 8> Visited;
10604   Worklist.push_back(Cond);
10605   while (!Worklist.empty()) {
10606     Value *V = Worklist.pop_back_val();
10607     if (!Visited.insert(V).second)
10608       continue;
10609 
10610     CmpPredicate Pred;
10611     Value *A, *B, *X;
10612 
10613     if (IsAssume) {
10614       AddAffected(V);
10615       if (match(V, m_Not(m_Value(X))))
10616         AddAffected(X);
10617     }
10618 
10619     if (match(V, m_LogicalOp(m_Value(A), m_Value(B)))) {
10620       // assume(A && B) is split to -> assume(A); assume(B);
10621       // assume(!(A || B)) is split to -> assume(!A); assume(!B);
10622       // Finally, assume(A || B) / assume(!(A && B)) generally don't provide
10623       // enough information to be worth handling (intersection of information as
10624       // opposed to union).
10625       if (!IsAssume) {
10626         Worklist.push_back(A);
10627         Worklist.push_back(B);
10628       }
10629     } else if (match(V, m_ICmp(Pred, m_Value(A), m_Value(B)))) {
10630       bool HasRHSC = match(B, m_ConstantInt());
10631       if (ICmpInst::isEquality(Pred)) {
10632         AddAffected(A);
10633         if (IsAssume)
10634           AddAffected(B);
10635         if (HasRHSC) {
10636           Value *Y;
10637           // (X << C) or (X >>_s C) or (X >>_u C).
10638           if (match(A, m_Shift(m_Value(X), m_ConstantInt())))
10639             AddAffected(X);
10640           // (X & C) or (X | C).
10641           else if (match(A, m_And(m_Value(X), m_Value(Y))) ||
10642                    match(A, m_Or(m_Value(X), m_Value(Y)))) {
10643             AddAffected(X);
10644             AddAffected(Y);
10645           }
10646           // X - Y
10647           else if (match(A, m_Sub(m_Value(X), m_Value(Y)))) {
10648             AddAffected(X);
10649             AddAffected(Y);
10650           }
10651         }
10652       } else {
10653         AddCmpOperands(A, B);
10654         if (HasRHSC) {
10655           // Handle (A + C1) u< C2, which is the canonical form of
10656           // A > C3 && A < C4.
10657           if (match(A, m_AddLike(m_Value(X), m_ConstantInt())))
10658             AddAffected(X);
10659 
10660           if (ICmpInst::isUnsigned(Pred)) {
10661             Value *Y;
10662             // X & Y u> C    -> X >u C && Y >u C
10663             // X | Y u< C    -> X u< C && Y u< C
10664             // X nuw+ Y u< C -> X u< C && Y u< C
10665             if (match(A, m_And(m_Value(X), m_Value(Y))) ||
10666                 match(A, m_Or(m_Value(X), m_Value(Y))) ||
10667                 match(A, m_NUWAdd(m_Value(X), m_Value(Y)))) {
10668               AddAffected(X);
10669               AddAffected(Y);
10670             }
10671             // X nuw- Y u> C -> X u> C
10672             if (match(A, m_NUWSub(m_Value(X), m_Value())))
10673               AddAffected(X);
10674           }
10675         }
10676 
10677         // Handle icmp slt/sgt (bitcast X to int), 0/-1, which is supported
10678         // by computeKnownFPClass().
10679         if (match(A, m_ElementWiseBitCast(m_Value(X)))) {
10680           if (Pred == ICmpInst::ICMP_SLT && match(B, m_Zero()))
10681             InsertAffected(X);
10682           else if (Pred == ICmpInst::ICMP_SGT && match(B, m_AllOnes()))
10683             InsertAffected(X);
10684         }
10685       }
10686 
10687       if (HasRHSC && match(A, m_Ctpop(m_Value(X))))
10688         AddAffected(X);
10689     } else if (match(V, m_FCmp(Pred, m_Value(A), m_Value(B)))) {
10690       AddCmpOperands(A, B);
10691 
10692       // fcmp fneg(x), y
10693       // fcmp fabs(x), y
10694       // fcmp fneg(fabs(x)), y
10695       if (match(A, m_FNeg(m_Value(A))))
10696         AddAffected(A);
10697       if (match(A, m_FAbs(m_Value(A))))
10698         AddAffected(A);
10699 
10700     } else if (match(V, m_Intrinsic<Intrinsic::is_fpclass>(m_Value(A),
10701                                                            m_Value()))) {
10702       // Handle patterns that computeKnownFPClass() support.
10703       AddAffected(A);
10704     } else if (!IsAssume && match(V, m_Trunc(m_Value(X)))) {
10705       // Assume is checked here as X is already added above for assumes in
10706       // addValueAffectedByCondition
10707       AddAffected(X);
10708     } else if (!IsAssume && match(V, m_Not(m_Value(X)))) {
10709       // Assume is checked here to avoid issues with ephemeral values
10710       Worklist.push_back(X);
10711     }
10712   }
10713 }
10714 
10715 const Value *llvm::stripNullTest(const Value *V) {
10716   // (X >> C) or/add (X & mask(C) != 0)
10717   if (const auto *BO = dyn_cast<BinaryOperator>(V)) {
10718     if (BO->getOpcode() == Instruction::Add ||
10719         BO->getOpcode() == Instruction::Or) {
-----------------------------------------------------

TOOL CALL: read250

{"file":"llvm/lib/Support/KnownFPClass.cpp","position":760}

TOOL OUTPUT

file: llvm/lib/Support/KnownFPClass.cpp:760-915
-----------------------------------------------
760 
761   return Known;
762 }
763 
764 KnownFPClass KnownFPClass::frexp_mant(const KnownFPClass &KnownSrc,
765                                       DenormalMode Mode) {
766   KnownFPClass Known;
767   Known.knownNot(fcSubnormal);
768 
769   if (KnownSrc.isKnownNever(fcNegative))
770     Known.knownNot(fcNegative);
771   else {
772     if (KnownSrc.isKnownNeverLogicalNegZero(Mode))
773       Known.knownNot(fcNegZero);
774     if (KnownSrc.isKnownNever(fcNegInf))
775       Known.knownNot(fcNegInf);
776   }
777 
778   if (KnownSrc.isKnownNever(fcPositive))
779     Known.knownNot(fcPositive);
780   else {
781     if (KnownSrc.isKnownNeverLogicalPosZero(Mode))
782       Known.knownNot(fcPosZero);
783     if (KnownSrc.isKnownNever(fcPosInf))
784       Known.knownNot(fcPosInf);
785   }
786 
787   Known.propagateNaN(KnownSrc);
788   return Known;
789 }
790 
791 KnownFPClass KnownFPClass::ldexp(const KnownFPClass &KnownSrc,
792                                  const APInt &ConstantRangeExpMin,
793                                  const APInt &ConstantRangeExpMax,
794                                  const fltSemantics &Flt, DenormalMode Mode) {
795   KnownFPClass Known;
796   Known.propagateNaN(KnownSrc, /*PropagateSign=*/true);
797 
798   // Sign is preserved, but underflows may produce zeroes.
799   if (KnownSrc.isKnownNever(fcNegative))
800     Known.knownNot(fcNegative);
801   else if (KnownSrc.cannotBeOrderedLessThanZero())
802     Known.knownNot(OrderedLessThanZeroMask);
803 
804   if (KnownSrc.isKnownNever(fcPositive))
805     Known.knownNot(fcPositive);
806   else if (KnownSrc.cannotBeOrderedGreaterThanZero())
807     Known.knownNot(OrderedGreaterThanZeroMask);
808 
809   unsigned Precision = APFloat::semanticsPrecision(Flt);
810   const int MantissaBits = Precision - 1;
811   if (ConstantRangeExpMin.sge(MantissaBits))
812     Known.knownNot(fcSubnormal);
813 
814   if (ConstantRangeExpMin.isZero() && ConstantRangeExpMax.isZero()) {
815     // ldexp(x, 0) -> x, so propagate everything.
816     Known.propagateCanonicalizingSrc(KnownSrc, Mode);
817   } else if (ConstantRangeExpMax.isNonPositive()) {
818     // If we know the power is <= 0, can't introduce inf
819     if (KnownSrc.isKnownNeverPosInfinity())
820       Known.knownNot(fcPosInf);
821     if (KnownSrc.isKnownNeverNegInfinity())
822       Known.knownNot(fcNegInf);
823   } else if (ConstantRangeExpMin.isNonNegative()) {
824     // If we know the power is >= 0, can't introduce subnormal or zero
825     if (KnownSrc.isKnownNeverPosSubnormal())
826       Known.knownNot(fcPosSubnormal);
827     if (KnownSrc.isKnownNeverNegSubnormal())
828       Known.knownNot(fcNegSubnormal);
829     if (KnownSrc.isKnownNeverLogicalPosZero(Mode))
830       Known.knownNot(fcPosZero);
831     if (KnownSrc.isKnownNeverLogicalNegZero(Mode))
832       Known.knownNot(fcNegZero);
833   }
834 
835   return Known;
836 }
837 
838 KnownFPClass KnownFPClass::ldexp(const KnownFPClass &KnownSrc,
839                                  const KnownBits &ExpBits,
840                                  const fltSemantics &Flt, DenormalMode Mode) {
841   return ldexp(KnownSrc, ExpBits.getSignedMinValue(),
842                ExpBits.getSignedMaxValue(), Flt, Mode);
843 }
844 
845 KnownFPClass KnownFPClass::powi(const KnownFPClass &KnownSrc,
846                                 const KnownBits &ExponentKnownBits) {
847   KnownFPClass Known;
848   Known.propagateNaN(KnownSrc);
849 
850   if (ExponentKnownBits.isZero()) {
851     // powi(QNaN, 0) returns 1.0, and powi(SNaN, 0) may non-deterministically
852     // return 1.0 or a NaN.
853     if (KnownSrc.isKnownNever(fcSNan)) {
854       Known.knownNot(~fcPosNormal);
855       return Known;
856     }
857 
858     Known.knownNot(~(fcPosNormal | fcNan));
859     return Known;
860   }
861 
862   // powi(x, exp) --> inf
863   // when:
864   //   * powi(inf, exp), exp > 0
865   //   * powi(+/-0, exp), exp < 0
866   //   * powi(finite, exp), |exp| > 1
867   //   * powi(subnormal, -1)
868   // TODO:
869   //   1. This simple all or nothing approach. We can do better
870   //      and cover sign/parity and exp > 1 vs exp < -1 separately.
871   //   2. powi(0/nan, exp), exp > 0 can be refinable
872   //      to fcNan | fcZero | fcPosNormal.
873   {
874     APInt MinExp = ExponentKnownBits.getSignedMinValue();
875     APInt MaxExp = ExponentKnownBits.getSignedMaxValue();
876 
877     // powi(inf, exp), exp > 0
878     bool MayInfSrc =
879         !KnownSrc.isKnownNever(fcInf) && MaxExp.isStrictlyPositive();
880 
881     // powi(+/-0, exp), exp < 0
882     bool MayDivByZero = !KnownSrc.isKnownNever(fcZero) && MinExp.isNegative();
883 
884     // powi(finite, exp), |exp| > 1
885     bool MayFinite = !KnownSrc.isKnownNever(fcNormal | fcSubnormal);
886     bool MayAbsExpGT1 = MinExp.slt(-1) || MaxExp.sgt(1);
887     bool MayFiniteOverflow = MayFinite && MayAbsExpGT1;
888 
889     // powi(subnormal, -1)
890     bool MayBeNegOne = ExponentKnownBits.Zero.isZero();
891     bool MaySubnormInv = !KnownSrc.isKnownNever(fcSubnormal) && MayBeNegOne;
892 
893     if (!MayInfSrc && !MayDivByZero && !MayFiniteOverflow && !MaySubnormInv)
894       Known.knownNot(fcInf);
895   }
896 
897   if (ExponentKnownBits.isEven()) {
898     Known.knownNot(fcNegative);
899     return Known;
900   }
901 
902   // Given that exp is an integer, here are the
903   // ways that pow can return a negative value:
904   //
905   //   pow(-x, exp)   --> negative if exp is odd and x is negative.
906   //   pow(-0, exp)   --> -inf if exp is negative odd.
907   //   pow(-0, exp)   --> -0 if exp is positive odd.
908   //   pow(-inf, exp) --> -0 if exp is negative odd.
909   //   pow(-inf, exp) --> -inf if exp is positive odd.
910   if (KnownSrc.isKnownNever(fcNegative))
911     Known.knownNot(fcNegative);
912 
913   return Known;
914 }
-----------------------------------------------

TOOL CALL: grep250

{"args":"-nRI 'IEK_Zero\\|enum.*IEK' llvm/include/llvm llvm/lib/Support","k":1}

TOOL OUTPUT

llvm/include/llvm/ADT/APFloat.h:1665:///   0   -> \c IEK_Zero
llvm/include/llvm/ADT/APFloat.h:385:    IEK_Zero = INT_MIN + 1,
llvm/lib/Support/APFloat.cpp:4599:    return APFloat::IEK_Zero;
llvm/lib/Support/APFloat.cpp:4649:  Exp = Exp == APFloat::IEK_Zero ? 0 : Exp + 1;
llvm/lib/Support/APFloat.cpp:5731:  if (Exp == APFloat::IEK_Zero) {

TOOL CALL: read250

{"file":"llvm/include/llvm/ADT/APFloat.h","position":360}

TOOL OUTPUT

file: llvm/include/llvm/ADT/APFloat.h:360-610
---------------------------------------------
360   ///    shall be a quiet NaN."
361   enum opStatus {
362     opOK = 0x00,
363     opInvalidOp = 0x01,
364     opDivByZero = 0x02,
365     opOverflow = 0x04,
366     opUnderflow = 0x08,
367     opInexact = 0x10
368   };
369 
370   /// Category of internally-represented number.
371   enum fltCategory {
372     fcInfinity,
373     fcNaN,
374     fcNormal,
375     fcZero
376   };
377 
378   /// Convenience enum used to construct an uninitialized APFloat.
379   enum uninitializedTag {
380     uninitialized
381   };
382 
383   /// Enumeration of \c ilogb error results.
384   enum IlogbErrorKinds {
385     IEK_Zero = INT_MIN + 1,
386     IEK_NaN = INT_MIN,
387     IEK_Inf = INT_MAX
388   };
389 
390   LLVM_ABI static unsigned int semanticsPrecision(const fltSemantics &);
391   LLVM_ABI static ExponentType semanticsMinExponent(const fltSemantics &);
392   LLVM_ABI static ExponentType semanticsMaxExponent(const fltSemantics &);
393   LLVM_ABI static unsigned int semanticsSizeInBits(const fltSemantics &);
394   LLVM_ABI static unsigned int semanticsIntSizeInBits(const fltSemantics &,
395                                                       bool);
396   LLVM_ABI static bool semanticsHasZero(const fltSemantics &);
397   LLVM_ABI static bool semanticsHasSignedRepr(const fltSemantics &);
398   LLVM_ABI static bool semanticsHasInf(const fltSemantics &);
399   LLVM_ABI static bool semanticsHasNaN(const fltSemantics &);
400   LLVM_ABI static bool isIEEELikeFP(const fltSemantics &);
401   LLVM_ABI static bool hasSignBitInMSB(const fltSemantics &);
402 
403   // Returns true if any number described by \p Src can be precisely represented
404   // by a normal (not subnormal) value in \p Dst.
405   LLVM_ABI static bool isRepresentableAsNormalIn(const fltSemantics &Src,
406                                                  const fltSemantics &Dst);
407 
408   /// Returns the size of the floating point number (in bits) in the given
409   /// semantics.
410   LLVM_ABI static unsigned getSizeInBits(const fltSemantics &Sem);
411 
412   /// Returns true if the given string is a valid arbitrary floating-point
413   /// format interpretation for llvm.convert.to.arbitrary.fp and
414   /// llvm.convert.from.arbitrary.fp intrinsics.
415   LLVM_ABI static bool isValidArbitraryFPFormat(StringRef Format);
416 
417   /// Returns the fltSemantics for a given arbitrary FP format string,
418   /// or nullptr if invalid.
419   LLVM_ABI static const fltSemantics *getArbitraryFPSemantics(StringRef Format);
420 };
421 
422 namespace detail {
423 
424 using integerPart = APFloatBase::integerPart;
425 using uninitializedTag = APFloatBase::uninitializedTag;
426 using roundingMode = APFloatBase::roundingMode;
427 using opStatus = APFloatBase::opStatus;
428 using cmpResult = APFloatBase::cmpResult;
429 using fltCategory = APFloatBase::fltCategory;
430 using ExponentType = APFloatBase::ExponentType;
431 static constexpr uninitializedTag uninitialized = APFloatBase::uninitialized;
432 static constexpr roundingMode rmNearestTiesToEven =
433     APFloatBase::rmNearestTiesToEven;
434 static constexpr roundingMode rmNearestTiesToAway =
435     APFloatBase::rmNearestTiesToAway;
436 static constexpr roundingMode rmTowardNegative = APFloatBase::rmTowardNegative;
437 static constexpr roundingMode rmTowardPositive = APFloatBase::rmTowardPositive;
438 static constexpr roundingMode rmTowardZero = APFloatBase::rmTowardZero;
439 static constexpr unsigned integerPartWidth = APFloatBase::integerPartWidth;
440 static constexpr cmpResult cmpEqual = APFloatBase::cmpEqual;
441 static constexpr cmpResult cmpLessThan = APFloatBase::cmpLessThan;
442 static constexpr cmpResult cmpGreaterThan = APFloatBase::cmpGreaterThan;
443 static constexpr cmpResult cmpUnordered = APFloatBase::cmpUnordered;
444 static constexpr opStatus opOK = APFloatBase::opOK;
445 static constexpr opStatus opInvalidOp = APFloatBase::opInvalidOp;
446 static constexpr opStatus opDivByZero = APFloatBase::opDivByZero;
447 static constexpr opStatus opOverflow = APFloatBase::opOverflow;
448 static constexpr opStatus opUnderflow = APFloatBase::opUnderflow;
449 static constexpr opStatus opInexact = APFloatBase::opInexact;
450 static constexpr fltCategory fcInfinity = APFloatBase::fcInfinity;
451 static constexpr fltCategory fcNaN = APFloatBase::fcNaN;
452 static constexpr fltCategory fcNormal = APFloatBase::fcNormal;
453 static constexpr fltCategory fcZero = APFloatBase::fcZero;
454 
455 class IEEEFloat final {
456 public:
457   /// \name Constructors
458   /// @{
459 
460   LLVM_ABI IEEEFloat(const fltSemantics &); // Default construct to +0.0
461   LLVM_ABI IEEEFloat(const fltSemantics &, integerPart);
462   LLVM_ABI IEEEFloat(const fltSemantics &, uninitializedTag);
463   LLVM_ABI IEEEFloat(const fltSemantics &, const APInt &);
464   LLVM_ABI explicit IEEEFloat(double d);
465   LLVM_ABI explicit IEEEFloat(float f);
466   LLVM_ABI IEEEFloat(const IEEEFloat &);
467   LLVM_ABI IEEEFloat(IEEEFloat &&);
468   LLVM_ABI ~IEEEFloat();
469 
470   /// @}
471 
472   /// Returns whether this instance allocated memory.
473   bool needsCleanup() const { return partCount() > 1; }
474 
475   /// \name Convenience "constructors"
476   /// @{
477 
478   /// @}
479 
480   /// \name Arithmetic
481   /// @{
482 
483   LLVM_ABI opStatus add(const IEEEFloat &, roundingMode);
484   LLVM_ABI opStatus subtract(const IEEEFloat &, roundingMode);
485   LLVM_ABI opStatus multiply(const IEEEFloat &, roundingMode);
486   LLVM_ABI opStatus divide(const IEEEFloat &, roundingMode);
487   /// IEEE remainder.
488   LLVM_ABI opStatus remainder(const IEEEFloat &);
489   /// C fmod, or llvm frem.
490   LLVM_ABI opStatus mod(const IEEEFloat &);
491   LLVM_ABI opStatus fusedMultiplyAdd(const IEEEFloat &, const IEEEFloat &,
492                                      roundingMode);
493   LLVM_ABI opStatus roundToIntegral(roundingMode);
494   /// IEEE-754R 5.3.1: nextUp/nextDown.
495   LLVM_ABI opStatus next(bool nextDown);
496 
497   /// @}
498 
499   /// \name Sign operations.
500   /// @{
501 
502   LLVM_ABI void changeSign();
503 
504   /// @}
505 
506   /// \name Conversions
507   /// @{
508 
509   LLVM_ABI opStatus convert(const fltSemantics &, roundingMode, bool *);
510   LLVM_ABI opStatus convertToInteger(MutableArrayRef<integerPart>, unsigned int,
511                                      bool, roundingMode, bool *) const;
512   LLVM_ABI opStatus convertFromAPInt(const APInt &, bool, roundingMode);
513   LLVM_ABI Expected<opStatus> convertFromString(StringRef, roundingMode);
514   LLVM_ABI APInt bitcastToAPInt() const;
515   LLVM_ABI double convertToDouble() const;
516 #ifdef HAS_IEE754_FLOAT128
517   LLVM_ABI float128 convertToQuad() const;
518 #endif
519   LLVM_ABI float convertToFloat() const;
520 
521   /// @}
522 
523   /// The definition of equality is not straightforward for floating point, so
524   /// we won't use operator==.  Use one of the following, or write whatever it
525   /// is you really mean.
526   bool operator==(const IEEEFloat &) const = delete;
527 
528   /// IEEE comparison with another floating point number (NaNs compare
529   /// unordered, 0==-0).
530   LLVM_ABI cmpResult compare(const IEEEFloat &) const;
531 
532   /// Bitwise comparison for equality (QNaNs compare equal, 0!=-0).
533   LLVM_ABI bool bitwiseIsEqual(const IEEEFloat &) const;
534 
535   /// Write out a hexadecimal representation of the floating point value to DST,
536   /// which must be of sufficient size, in the C99 form [-]0xh.hhhhp[+-]d.
537   /// Return the number of characters written, excluding the terminating NUL.
538   LLVM_ABI unsigned int convertToHexString(char *dst, unsigned int hexDigits,
539                                            bool upperCase, roundingMode) const;
540 
541   /// \name IEEE-754R 5.7.2 General operations.
542   /// @{
543 
544   /// IEEE-754R isSignMinus: Returns true if and only if the current value is
545   /// negative.
546   ///
547   /// This applies to zeros and NaNs as well.
548   bool isNegative() const { return sign; }
549 
550   /// IEEE-754R isNormal: Returns true if and only if the current value is normal.
551   ///
552   /// This implies that the current value of the float is not zero, subnormal,
553   /// infinite, or NaN following the definition of normality from IEEE-754R.
554   bool isNormal() const { return !isDenormal() && isFiniteNonZero(); }
555 
556   /// Returns true if and only if the current value is zero, subnormal, or
557   /// normal.
558   ///
559   /// This means that the value is not infinite or NaN.
560   bool isFinite() const { return !isNaN() && !isInfinity(); }
561 
562   /// Returns true if and only if the float is plus or minus zero.
563   bool isZero() const { return category == fltCategory::fcZero; }
564 
565   /// IEEE-754R isSubnormal(): Returns true if and only if the float is a
566   /// denormal.
567   LLVM_ABI bool isDenormal() const;
568 
569   /// IEEE-754R isInfinite(): Returns true if and only if the float is infinity.
570   bool isInfinity() const { return category == fcInfinity; }
571 
572   /// Returns true if and only if the float is a quiet or signaling NaN.
573   bool isNaN() const { return category == fcNaN; }
574 
575   /// Returns true if and only if the float is a signaling NaN.
576   LLVM_ABI bool isSignaling() const;
577 
578   /// @}
579 
580   /// \name Simple Queries
581   /// @{
582 
583   fltCategory getCategory() const { return category; }
584   const fltSemantics &getSemantics() const { return *semantics; }
585   bool isNonZero() const { return category != fltCategory::fcZero; }
586   bool isFiniteNonZero() const { return isFinite() && !isZero(); }
587   bool isPosZero() const { return isZero() && !isNegative(); }
588   bool isNegZero() const { return isZero() && isNegative(); }
589 
590   /// Returns true if and only if the number has the smallest possible non-zero
591   /// magnitude in the current semantics.
592   LLVM_ABI bool isSmallest() const;
593 
594   /// Returns true if this is the smallest (by magnitude) normalized finite
595   /// number in the given semantics.
596   LLVM_ABI bool isSmallestNormalized() const;
597 
598   /// Returns true if and only if the number has the largest possible finite
599   /// magnitude in the current semantics.
600   LLVM_ABI bool isLargest() const;
601 
602   /// Returns true if and only if the number is an exact integer.
603   LLVM_ABI bool isInteger() const;
604 
605   /// @}
606 
607   LLVM_ABI IEEEFloat &operator=(const IEEEFloat &);
608   LLVM_ABI IEEEFloat &operator=(IEEEFloat &&);
609 
---------------------------------------------

TOOL CALL: read250

{"file":"llvm/lib/Support/APFloat.cpp","position":4580}

TOOL OUTPUT

file: llvm/lib/Support/APFloat.cpp:4580-4830
--------------------------------------------
4580   sign = Negative;
4581   if (semantics->nanEncoding == fltNanEncoding::NegativeZero) {
4582     // Merge negative zero to positive because 0b10000...000 is used for NaN
4583     sign = false;
4584   }
4585   exponent = exponentZero();
4586   APInt::tcSet(significandParts(), 0, partCount());
4587 }
4588 
4589 void IEEEFloat::makeQuiet() {
4590   assert(isNaN());
4591   if (semantics->nonFiniteBehavior != fltNonfiniteBehavior::NanOnly)
4592     APInt::tcSetBit(significandParts(), semantics->precision - 2);
4593 }
4594 
4595 int ilogb(const IEEEFloat &Arg) {
4596   if (Arg.isNaN())
4597     return APFloat::IEK_NaN;
4598   if (Arg.isZero())
4599     return APFloat::IEK_Zero;
4600   if (Arg.isInfinity())
4601     return APFloat::IEK_Inf;
4602   if (!Arg.isDenormal())
4603     return Arg.exponent;
4604 
4605   IEEEFloat Normalized(Arg);
4606   int SignificandBits = Arg.getSemantics().precision - 1;
4607 
4608   Normalized.exponent += SignificandBits;
4609   Normalized.normalize(APFloat::rmNearestTiesToEven, lfExactlyZero);
4610   return Normalized.exponent - SignificandBits;
4611 }
4612 
4613 IEEEFloat scalbn(IEEEFloat X, int Exp, roundingMode RoundingMode) {
4614   auto MaxExp = X.getSemantics().maxExponent;
4615   auto MinExp = X.getSemantics().minExponent;
4616 
4617   // If Exp is wildly out-of-scale, simply adding it to X.exponent will
4618   // overflow; clamp it to a safe range before adding, but ensure that the range
4619   // is large enough that the clamp does not change the result. The range we
4620   // need to support is the difference between the largest possible exponent and
4621   // the normalized exponent of half the smallest denormal.
4622 
4623   int SignificandBits = X.getSemantics().precision - 1;
4624   int MaxIncrement = MaxExp - (MinExp - SignificandBits) + 1;
4625 
4626   // Clamp to one past the range ends to let normalize handle overlflow.
4627   X.exponent += std::clamp(Exp, -MaxIncrement - 1, MaxIncrement);
4628   X.normalize(RoundingMode, lfExactlyZero);
4629   if (X.isNaN())
4630     X.makeQuiet();
4631   return X;
4632 }
4633 
4634 IEEEFloat frexp(const IEEEFloat &Val, int &Exp, roundingMode RM) {
4635   Exp = ilogb(Val);
4636 
4637   // Quiet signalling nans.
4638   if (Exp == APFloat::IEK_NaN) {
4639     IEEEFloat Quiet(Val);
4640     Quiet.makeQuiet();
4641     return Quiet;
4642   }
4643 
4644   if (Exp == APFloat::IEK_Inf)
4645     return Val;
4646 
4647   // 1 is added because frexp is defined to return a normalized fraction in
4648   // +/-[0.5, 1.0), rather than the usual +/-[1.0, 2.0).
4649   Exp = Exp == APFloat::IEK_Zero ? 0 : Exp + 1;
4650   return scalbn(Val, -Exp, RM);
4651 }
4652 
4653 DoubleAPFloat::DoubleAPFloat(const fltSemantics &S)
4654     : Semantics(&S),
4655       Floats(new APFloat[2]{APFloat(APFloatBase::semIEEEdouble),
4656                             APFloat(APFloatBase::semIEEEdouble)}) {
4657   assert(Semantics == &APFloatBase::semPPCDoubleDouble);
4658 }
4659 
4660 DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, uninitializedTag)
4661     : Semantics(&S), Floats(new APFloat[2]{
4662                          APFloat(APFloatBase::semIEEEdouble, uninitialized),
4663                          APFloat(APFloatBase::semIEEEdouble, uninitialized)}) {
4664   assert(Semantics == &APFloatBase::semPPCDoubleDouble);
4665 }
4666 
4667 DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, integerPart I)
4668     : Semantics(&S),
4669       Floats(new APFloat[2]{APFloat(APFloatBase::semIEEEdouble, I),
4670                             APFloat(APFloatBase::semIEEEdouble)}) {
4671   assert(Semantics == &APFloatBase::semPPCDoubleDouble);
4672 }
4673 
4674 DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, const APInt &I)
4675     : Semantics(&S),
4676       Floats(new APFloat[2]{
4677           APFloat(APFloatBase::semIEEEdouble, APInt(64, I.getRawData()[0])),
4678           APFloat(APFloatBase::semIEEEdouble, APInt(64, I.getRawData()[1]))}) {
4679   assert(Semantics == &APFloatBase::semPPCDoubleDouble);
4680 }
4681 
4682 DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, APFloat &&First,
4683                              APFloat &&Second)
4684     : Semantics(&S),
4685       Floats(new APFloat[2]{std::move(First), std::move(Second)}) {
4686   assert(Semantics == &APFloatBase::semPPCDoubleDouble);
4687   assert(&Floats[0].getSemantics() == &APFloatBase::semIEEEdouble);
4688   assert(&Floats[1].getSemantics() == &APFloatBase::semIEEEdouble);
4689 }
4690 
4691 DoubleAPFloat::DoubleAPFloat(const DoubleAPFloat &RHS)
4692     : Semantics(RHS.Semantics),
4693       Floats(RHS.Floats ? new APFloat[2]{APFloat(RHS.Floats[0]),
4694                                          APFloat(RHS.Floats[1])}
4695                         : nullptr) {
4696   assert(Semantics == &APFloatBase::semPPCDoubleDouble);
4697 }
4698 
4699 DoubleAPFloat::DoubleAPFloat(DoubleAPFloat &&RHS)
4700     : Semantics(RHS.Semantics), Floats(RHS.Floats) {
4701   RHS.Semantics = &APFloatBase::semBogus;
4702   RHS.Floats = nullptr;
4703   assert(Semantics == &APFloatBase::semPPCDoubleDouble);
4704 }
4705 
4706 DoubleAPFloat &DoubleAPFloat::operator=(const DoubleAPFloat &RHS) {
4707   if (Semantics == RHS.Semantics && RHS.Floats) {
4708     Floats[0] = RHS.Floats[0];
4709     Floats[1] = RHS.Floats[1];
4710   } else if (this != &RHS) {
4711     this->~DoubleAPFloat();
4712     new (this) DoubleAPFloat(RHS);
4713   }
4714   return *this;
4715 }
4716 
4717 // Returns a result such that:
4718 // 1. abs(Lo) <= ulp(Hi)/2
4719 // 2. Hi == RTNE(Hi + Lo)
4720 // 3. Hi + Lo == X + Y
4721 //
4722 // Requires that log2(X) >= log2(Y).
4723 static std::pair<APFloat, APFloat> fastTwoSum(APFloat X, APFloat Y) {
4724   if (!X.isFinite())
4725     return {X, APFloat::getZero(X.getSemantics(), /*Negative=*/false)};
4726   APFloat Hi = X + Y;
4727   APFloat Delta = Hi - X;
4728   APFloat Lo = Y - Delta;
4729   return {Hi, Lo};
4730 }
4731 
4732 // Implement addition, subtraction, multiplication and division based on:
4733 // "Software for Doubled-Precision Floating-Point Computations",
4734 // by Seppo Linnainmaa, ACM TOMS vol 7 no 3, September 1981, pages 272-283.
4735 APFloat::opStatus DoubleAPFloat::addImpl(const APFloat &a, const APFloat &aa,
4736                                          const APFloat &c, const APFloat &cc,
4737                                          roundingMode RM) {
4738   int Status = opOK;
4739   APFloat z = a;
4740   Status |= z.add(c, RM);
4741   if (!z.isFinite()) {
4742     if (!z.isInfinity()) {
4743       Floats[0] = std::move(z);
4744       Floats[1].makeZero(/* Neg = */ false);
4745       return (opStatus)Status;
4746     }
4747     Status = opOK;
4748     auto AComparedToC = a.compareAbsoluteValue(c);
4749     z = cc;
4750     Status |= z.add(aa, RM);
4751     if (AComparedToC == APFloat::cmpGreaterThan) {
4752       // z = cc + aa + c + a;
4753       Status |= z.add(c, RM);
4754       Status |= z.add(a, RM);
4755     } else {
4756       // z = cc + aa + a + c;
4757       Status |= z.add(a, RM);
4758       Status |= z.add(c, RM);
4759     }
4760     if (!z.isFinite()) {
4761       Floats[0] = std::move(z);
4762       Floats[1].makeZero(/* Neg = */ false);
4763       return (opStatus)Status;
4764     }
4765     Floats[0] = z;
4766     APFloat zz = aa;
4767     Status |= zz.add(cc, RM);
4768     if (AComparedToC == APFloat::cmpGreaterThan) {
4769       // Floats[1] = a - z + c + zz;
4770       Floats[1] = a;
4771       Status |= Floats[1].subtract(z, RM);
4772       Status |= Floats[1].add(c, RM);
4773       Status |= Floats[1].add(zz, RM);
4774     } else {
4775       // Floats[1] = c - z + a + zz;
4776       Floats[1] = c;
4777       Status |= Floats[1].subtract(z, RM);
4778       Status |= Floats[1].add(a, RM);
4779       Status |= Floats[1].add(zz, RM);
4780     }
4781   } else {
4782     // q = a - z;
4783     APFloat q = a;
4784     Status |= q.subtract(z, RM);
4785 
4786     // zz = q + c + (a - (q + z)) + aa + cc;
4787     // Compute a - (q + z) as -((q + z) - a) to avoid temporary copies.
4788     auto zz = q;
4789     Status |= zz.add(c, RM);
4790     Status |= q.add(z, RM);
4791     Status |= q.subtract(a, RM);
4792     q.changeSign();
4793     Status |= zz.add(q, RM);
4794     Status |= zz.add(aa, RM);
4795     Status |= zz.add(cc, RM);
4796     if (zz.isZero() && !zz.isNegative()) {
4797       Floats[0] = std::move(z);
4798       Floats[1].makeZero(/* Neg = */ false);
4799       return opOK;
4800     }
4801     Floats[0] = z;
4802     Status |= Floats[0].add(zz, RM);
4803     if (!Floats[0].isFinite()) {
4804       Floats[1].makeZero(/* Neg = */ false);
4805       return (opStatus)Status;
4806     }
4807     Floats[1] = std::move(z);
4808     Status |= Floats[1].subtract(Floats[0], RM);
4809     Status |= Floats[1].add(zz, RM);
4810   }
4811   return (opStatus)Status;
4812 }
4813 
4814 APFloat::opStatus DoubleAPFloat::addWithSpecial(const DoubleAPFloat &LHS,
4815                                                 const DoubleAPFloat &RHS,
4816                                                 DoubleAPFloat &Out,
4817                                                 roundingMode RM) {
4818   if (LHS.getCategory() == fcNaN) {
4819     Out = LHS;
4820     return opOK;
4821   }
4822   if (RHS.getCategory() == fcNaN) {
4823     Out = RHS;
4824     return opOK;
4825   }
4826   if (LHS.getCategory() == fcZero) {
4827     Out = RHS;
4828     return opOK;
4829   }
--------------------------------------------

TOOL CALL: grep250

{"args":"-nRI 'frexp.*fabs\\|fabs.*frexp\\|ldexp.*frexp\\|extractvalue.*frexp' llvm/test/Transforms llvm/test/Analysis","k":1}

TOOL OUTPUT

llvm/test/Transforms/Inline/simplify-instruction-computeKnownFPClass-context.ll:200:  %frexp.0 = extractvalue { double, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:1004:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:1044:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:1085:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:1125:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:1163:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:1203:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:1236:  %exp = extractvalue { float, i128 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:1247:define float @frexp_fcmp_ogt_1_fabs_wrong_value(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:1248:; CHECK-LABEL: define float @frexp_fcmp_ogt_1_fabs_wrong_value(
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:1268:  %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x.fabs)
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:1269:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:128:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:160:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:192:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:225:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:257:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:289:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:321:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:32:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:353:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:385:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:417:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:449:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:481:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:513:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:545:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:577:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:609:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:641:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:64:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:673:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:705:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:735:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:760:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:790:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:815:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:848:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:881:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:914:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:947:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:96:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:978:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/frexp.ll:19:  %frexp0.0 = extractvalue { float, i32 } %frexp0, 0
llvm/test/Transforms/InstCombine/frexp.ll:309:  %frexp0.0 = extractvalue { double, i64 } %frexp0, 0llvm/test/Transforms/InstCombine/frexp.ll:32:  %frexp0.0 = extractvalue { <2 x float>, <2 x i32> } %frexp0, 0
llvm/test/Transforms/InstCombine/frexp.ll:43:  %frexp0.0 = extractvalue { float, i32 } %frexp0, 0
llvm/test/Transforms/InstCombine/frexp.ll:56:  %frexp0.0 = extractvalue { <vscale x 2 x float>, <vscale x 2 x i32> } %frexp0, 0
llvm/test/Transforms/InstCombine/known-range-frexp-exp.ll:111:  %exp = extractvalue { <2 x float>, <2 x i32> } %frexp, 1
llvm/test/Transforms/InstCombine/known-range-frexp-exp.ll:126:  %exp = extractvalue { double, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/known-range-frexp-exp.ll:13:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/known-range-frexp-exp.ll:140:  %exp = extractvalue { double, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/known-range-frexp-exp.ll:154:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/known-range-frexp-exp.ll:27:  %exp = extractvalue { float, i16 } %frexp, 1
llvm/test/Transforms/InstCombine/known-range-frexp-exp.ll:41:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/known-range-frexp-exp.ll:55:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/known-range-frexp-exp.ll:69:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/known-range-frexp-exp.ll:83:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/known-range-frexp-exp.ll:97:  %exp = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/select_frexp.ll:110:  %frexp.0 = extractvalue { float, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/select_frexp.ll:125:  %frexp.1 = extractvalue { float, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/select_frexp.ll:140:  %frexp.0 = extractvalue { float, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/select_frexp.ll:156:  %frexp.0 = extractvalue { <2 x float>, <2 x i32> } %frexp, 0
llvm/test/Transforms/InstCombine/select_frexp.ll:171:  %frexp.0 = extractvalue { <vscale x 2 x float>, <vscale x 2 x i32> } %frexp, 0
llvm/test/Transforms/InstCombine/select_frexp.ll:186:  %frexp.0 = extractvalue { <vscale x 2 x float>, <vscale x 2 x i32> } %frexp, 0
llvm/test/Transforms/InstCombine/select_frexp.ll:18:  %frexp.0 = extractvalue { float, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/select_frexp.ll:33:  %frexp.0 = extractvalue { float, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/select_frexp.ll:50:  %frexp.0 = extractvalue { float, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/select_frexp.ll:65:  %frexp.0 = extractvalue { <2 x float>, <2 x i32> } %frexp, 0
llvm/test/Transforms/InstCombine/select_frexp.ll:80:  %frexp.0 = extractvalue { <2 x float>, <2 x i32> } %frexp, 0
llvm/test/Transforms/InstCombine/select_frexp.ll:95:  %frexp.0 = extractvalue { <2 x float>, <2 x i32> } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:101:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:111:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:121:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:131:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:141:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:153:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:163:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:173:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:183:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:193:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:208:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:226:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:227:  %frexp.exp = extractvalue { half, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:245:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:263:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:264:  %frexp.exp = extractvalue { half, i32 } %frexp, 1
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:280:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:295:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:311:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:327:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:342:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:357:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:372:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:388:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:402:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:416:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:430:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:444:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:458:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:472:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:486:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:501:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:516:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:529:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:540:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:54:define nofpclass(nan) half @extractvalue_not_frexp() {
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:553:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:55:; CHECK-LABEL: define nofpclass(nan) half @extractvalue_not_frexp() {
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:566:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:579:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:590:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:608:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:609:  %frexp.mant2 = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:624:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:71:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:81:  %frexp.mant = extractvalue { half, i32 } %frexp, 0
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll:91:  %frexp.mant = extractvalue { half, i32 } %frexp, 0

TOOL CALL: read250

{"file":"llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll","position":1}

TOOL OUTPUT

file: llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:1-251
--------------------------------------------------------------------------------------------------
  1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
  2 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
  3 
  4 ; Test that nofpclass(inf) can be propagated based on the contextual
  5 ; knowledge that the exponent of a frexp must be negative
  6 ;
  7 ; We can infer from a not-inf source, plus the compare that the clamp
  8 ; of infinity inside small can be deleted.
  9 
 10 define float @frexp_fcmp_ogt_1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
 11 ; CHECK-LABEL: define float @frexp_fcmp_ogt_1(
 12 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
 13 ; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
 14 ; CHECK-NEXT:    [[IS_LARGE:%.*]] = fcmp ogt float [[X_FABS]], 1.000000e+00
 15 ; CHECK-NEXT:    br i1 [[IS_LARGE]], label %[[LARGE:.*]], label %[[SMALL:.*]]
 16 ; CHECK:       [[SMALL]]:
 17 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]])
 18 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 19 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float [[NOT_INF]], i32 [[EXP]])
 20 ; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
 21 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, float [[SCALED]]
 22 ; CHECK-NEXT:    ret float [[SELECT]]
 23 ; CHECK:       [[LARGE]]:
 24 ; CHECK-NEXT:    ret float 0.000000e+00
 25 ;
 26   %x.fabs = call float @llvm.fabs.f32(float %x)
 27   %is.large = fcmp ogt float %x.fabs, 1.0
 28   br i1 %is.large, label %large, label %small
 29 
 30 small:
 31   %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)
 32   %exp = extractvalue { float, i32 } %frexp, 1
 33   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
 34   %is.inf = fcmp oeq float %scaled, +inf
 35   %select = select i1 %is.inf, float 0.0, float %scaled
 36   ret float %select
 37 
 38 large:
 39   ret float 0.0
 40 }
 41 
 42 define float @frexp_fcmp_oge_1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
 43 ; CHECK-LABEL: define float @frexp_fcmp_oge_1(
 44 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
 45 ; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
 46 ; CHECK-NEXT:    [[IS_LARGE:%.*]] = fcmp ult float [[X_FABS]], 1.000000e+00
 47 ; CHECK-NEXT:    br i1 [[IS_LARGE]], label %[[SMALL:.*]], label %[[LARGE:.*]]
 48 ; CHECK:       [[SMALL]]:
 49 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]])
 50 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 51 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float [[NOT_INF]], i32 [[EXP]])
 52 ; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
 53 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, float [[SCALED]]
 54 ; CHECK-NEXT:    ret float [[SELECT]]
 55 ; CHECK:       [[LARGE]]:
 56 ; CHECK-NEXT:    ret float 0.000000e+00
 57 ;
 58   %x.fabs = call float @llvm.fabs.f32(float %x)
 59   %is.large = fcmp oge float %x.fabs, 1.0
 60   br i1 %is.large, label %large, label %small
 61 
 62 small:
 63   %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)
 64   %exp = extractvalue { float, i32 } %frexp, 1
 65   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
 66   %is.inf = fcmp oeq float %scaled, +inf
 67   %select = select i1 %is.inf, float 0.0, float %scaled
 68   ret float %select
 69 
 70 large:
 71   ret float 0.0
 72 }
 73 
 74 define float @frexp_fcmp_ugt_1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
 75 ; CHECK-LABEL: define float @frexp_fcmp_ugt_1(
 76 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
 77 ; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
 78 ; CHECK-NEXT:    [[IS_LARGE:%.*]] = fcmp ugt float [[X_FABS]], 1.000000e+00
 79 ; CHECK-NEXT:    br i1 [[IS_LARGE]], label %[[LARGE:.*]], label %[[SMALL:.*]]
 80 ; CHECK:       [[SMALL]]:
 81 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]])
 82 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
 83 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float [[NOT_INF]], i32 [[EXP]])
 84 ; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
 85 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, float [[SCALED]]
 86 ; CHECK-NEXT:    ret float [[SELECT]]
 87 ; CHECK:       [[LARGE]]:
 88 ; CHECK-NEXT:    ret float 0.000000e+00
 89 ;
 90   %x.fabs = call float @llvm.fabs.f32(float %x)
 91   %is.large = fcmp ugt float %x.fabs, 1.0
 92   br i1 %is.large, label %large, label %small
 93 
 94 small:
 95   %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)
 96   %exp = extractvalue { float, i32 } %frexp, 1
 97   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
 98   %is.inf = fcmp oeq float %scaled, +inf
 99   %select = select i1 %is.inf, float 0.0, float %scaled
100   ret float %select
101 
102 large:
103   ret float 0.0
104 }
105 
106 define float @frexp_fcmp_uge_1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
107 ; CHECK-LABEL: define float @frexp_fcmp_uge_1(
108 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
109 ; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
110 ; CHECK-NEXT:    [[IS_LARGE:%.*]] = fcmp uge float [[X_FABS]], 1.000000e+00
111 ; CHECK-NEXT:    br i1 [[IS_LARGE]], label %[[LARGE:.*]], label %[[SMALL:.*]]
112 ; CHECK:       [[SMALL]]:
113 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]])
114 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
115 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float [[NOT_INF]], i32 [[EXP]])
116 ; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
117 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, float [[SCALED]]
118 ; CHECK-NEXT:    ret float [[SELECT]]
119 ; CHECK:       [[LARGE]]:
120 ; CHECK-NEXT:    ret float 0.000000e+00
121 ;
122   %x.fabs = call float @llvm.fabs.f32(float %x)
123   %is.large = fcmp uge float %x.fabs, 1.0
124   br i1 %is.large, label %large, label %small
125 
126 small:
127   %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)
128   %exp = extractvalue { float, i32 } %frexp, 1
129   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
130   %is.inf = fcmp oeq float %scaled, +inf
131   %select = select i1 %is.inf, float 0.0, float %scaled
132   ret float %select
133 
134 large:
135   ret float 0.0
136 }
137 
138 define float @frexp_fcmp_olt_1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
139 ; CHECK-LABEL: define float @frexp_fcmp_olt_1(
140 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
141 ; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
142 ; CHECK-NEXT:    [[IS_SMALL:%.*]] = fcmp olt float [[X_FABS]], 1.000000e+00
143 ; CHECK-NEXT:    br i1 [[IS_SMALL]], label %[[SMALL:.*]], label %[[LARGE:.*]]
144 ; CHECK:       [[SMALL]]:
145 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]])
146 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
147 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float [[NOT_INF]], i32 [[EXP]])
148 ; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
149 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, float [[SCALED]]
150 ; CHECK-NEXT:    ret float [[SELECT]]
151 ; CHECK:       [[LARGE]]:
152 ; CHECK-NEXT:    ret float 0.000000e+00
153 ;
154   %x.fabs = call float @llvm.fabs.f32(float %x)
155   %is.small = fcmp olt float %x.fabs, 1.0
156   br i1 %is.small, label %small, label %large
157 
158 small:
159   %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)
160   %exp = extractvalue { float, i32 } %frexp, 1
161   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
162   %is.inf = fcmp oeq float %scaled, +inf
163   %select = select i1 %is.inf, float 0.0, float %scaled
164   ret float %select
165 
166 large:
167   ret float 0.0
168 }
169 
170 define float @frexp_fcmp_ole_1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
171 ; CHECK-LABEL: define float @frexp_fcmp_ole_1(
172 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
173 ; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
174 ; CHECK-NEXT:    [[IS_SMALL:%.*]] = fcmp ugt float [[X_FABS]], 1.000000e+00
175 ; CHECK-NEXT:    br i1 [[IS_SMALL]], label %[[LARGE:.*]], label %[[SMALL:.*]]
176 ; CHECK:       [[SMALL]]:
177 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]])
178 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
179 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float [[NOT_INF]], i32 [[EXP]])
180 ; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
181 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, float [[SCALED]]
182 ; CHECK-NEXT:    ret float [[SELECT]]
183 ; CHECK:       [[LARGE]]:
184 ; CHECK-NEXT:    ret float 0.000000e+00
185 ;
186   %x.fabs = call float @llvm.fabs.f32(float %x)
187   %is.small = fcmp ole float %x.fabs, 1.0
188   br i1 %is.small, label %small, label %large
189 
190 small:
191   %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)
192   %exp = extractvalue { float, i32 } %frexp, 1
193   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
194   %is.inf = fcmp oeq float %scaled, +inf
195   %select = select i1 %is.inf, float 0.0, float %scaled
196   ret float %select
197 
198 large:
199   ret float 0.0
200 }
201 
202 
203 define float @frexp_fcmp_ult_1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
204 ; CHECK-LABEL: define float @frexp_fcmp_ult_1(
205 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
206 ; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
207 ; CHECK-NEXT:    [[IS_SMALL:%.*]] = fcmp ult float [[X_FABS]], 1.000000e+00
208 ; CHECK-NEXT:    br i1 [[IS_SMALL]], label %[[SMALL:.*]], label %[[LARGE:.*]]
209 ; CHECK:       [[SMALL]]:
210 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]])
211 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
212 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float [[NOT_INF]], i32 [[EXP]])
213 ; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
214 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, float [[SCALED]]
215 ; CHECK-NEXT:    ret float [[SELECT]]
216 ; CHECK:       [[LARGE]]:
217 ; CHECK-NEXT:    ret float 0.000000e+00
218 ;
219   %x.fabs = call float @llvm.fabs.f32(float %x)
220   %is.small = fcmp ult float %x.fabs, 1.0
221   br i1 %is.small, label %small, label %large
222 
223 small:
224   %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)
225   %exp = extractvalue { float, i32 } %frexp, 1
226   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
227   %is.inf = fcmp oeq float %scaled, +inf
228   %select = select i1 %is.inf, float 0.0, float %scaled
229   ret float %select
230 
231 large:
232   ret float 0.0
233 }
234 
235 define float @frexp_fcmp_ule_1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
236 ; CHECK-LABEL: define float @frexp_fcmp_ule_1(
237 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
238 ; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
239 ; CHECK-NEXT:    [[IS_SMALL:%.*]] = fcmp ule float [[X_FABS]], 1.000000e+00
240 ; CHECK-NEXT:    br i1 [[IS_SMALL]], label %[[SMALL:.*]], label %[[LARGE:.*]]
241 ; CHECK:       [[SMALL]]:
242 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]])
243 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
244 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float [[NOT_INF]], i32 [[EXP]])
245 ; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
246 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, float [[SCALED]]
247 ; CHECK-NEXT:    ret float [[SELECT]]
248 ; CHECK:       [[LARGE]]:
249 ; CHECK-NEXT:    ret float 0.000000e+00
250 ;
--------------------------------------------------------------------------------------------------

TOOL CALL: read250

{"file":"llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll","position":735}

TOOL OUTPUT

file: llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:735-985
----------------------------------------------------------------------------------------------------
735   %exp = extractvalue { float, i32 } %frexp, 1
736   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
737   %is.inf = fcmp oeq float %scaled, +inf
738   %select = select i1 %is.inf, float 0.0, float %scaled
739   ret float %select
740 
741 large:
742   ret float 0.0
743 }
744 
745 define float @frexp_fcmp_false_1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
746 ; CHECK-LABEL: define float @frexp_fcmp_false_1(
747 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
748 ; CHECK-NEXT:    br i1 false, label %[[SMALL:.*]], label %[[LARGE:.*]]
749 ; CHECK:       [[SMALL]]:
750 ; CHECK-NEXT:    ret float poison
751 ; CHECK:       [[LARGE]]:
752 ; CHECK-NEXT:    ret float 0.000000e+00
753 ;
754   %x.fabs = call float @llvm.fabs.f32(float %x)
755   %is.false = fcmp false float %x.fabs, 1.0
756   br i1 %is.false, label %small, label %large
757 
758 small:
759   %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)
760   %exp = extractvalue { float, i32 } %frexp, 1
761   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
762   %is.inf = fcmp oeq float %scaled, +inf
763   %select = select i1 %is.inf, float 0.0, float %scaled
764   ret float %select
765 
766 large:
767   ret float 0.0
768 }
769 
770 define float @frexp_fcmp_ord_1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
771 ; CHECK-LABEL: define float @frexp_fcmp_ord_1(
772 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
773 ; CHECK-NEXT:    br i1 true, label %[[SMALL:.*]], label %[[LARGE:.*]]
774 ; CHECK:       [[SMALL]]:
775 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]])
776 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
777 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float [[NOT_INF]], i32 [[EXP]])
778 ; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
779 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, float [[SCALED]]
780 ; CHECK-NEXT:    ret float [[SELECT]]
781 ; CHECK:       [[LARGE]]:
782 ; CHECK-NEXT:    ret float 0.000000e+00
783 ;
784   %x.fabs = call float @llvm.fabs.f32(float %x)
785   %is.ord = fcmp ord float %x.fabs, 1.0
786   br i1 %is.ord, label %small, label %large
787 
788 small:
789   %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)
790   %exp = extractvalue { float, i32 } %frexp, 1
791   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
792   %is.inf = fcmp oeq float %scaled, +inf
793   %select = select i1 %is.inf, float 0.0, float %scaled
794   ret float %select
795 
796 large:
797   ret float 0.0
798 }
799 
800 define float @frexp_fcmp_uno_1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
801 ; CHECK-LABEL: define float @frexp_fcmp_uno_1(
802 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
803 ; CHECK-NEXT:    br i1 false, label %[[SMALL:.*]], label %[[LARGE:.*]]
804 ; CHECK:       [[SMALL]]:
805 ; CHECK-NEXT:    ret float poison
806 ; CHECK:       [[LARGE]]:
807 ; CHECK-NEXT:    ret float 0.000000e+00
808 ;
809   %x.fabs = call float @llvm.fabs.f32(float %x)
810   %is.uno = fcmp uno float %x.fabs, 1.0
811   br i1 %is.uno, label %small, label %large
812 
813 small:
814   %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)
815   %exp = extractvalue { float, i32 } %frexp, 1
816   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
817   %is.inf = fcmp oeq float %scaled, +inf
818   %select = select i1 %is.inf, float 0.0, float %scaled
819   ret float %select
820 
821 large:
822   ret float 0.0
823 }
824 
825 ; Negative test
826 define float @frexp_fcmp_ogt_nextafter1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
827 ; CHECK-LABEL: define float @frexp_fcmp_ogt_nextafter1(
828 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
829 ; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
830 ; CHECK-NEXT:    [[IS_LARGE:%.*]] = fcmp ogt float [[X_FABS]], f0x3F800001
831 ; CHECK-NEXT:    br i1 [[IS_LARGE]], label %[[LARGE:.*]], label %[[SMALL:.*]]
832 ; CHECK:       [[SMALL]]:
833 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]])
834 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
835 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float [[NOT_INF]], i32 [[EXP]])
836 ; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
837 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, float [[SCALED]]
838 ; CHECK-NEXT:    ret float [[SELECT]]
839 ; CHECK:       [[LARGE]]:
840 ; CHECK-NEXT:    ret float 0.000000e+00
841 ;
842   %x.fabs = call float @llvm.fabs.f32(float %x)
843   %is.large = fcmp ogt float %x.fabs, f0x3f800001
844   br i1 %is.large, label %large, label %small
845 
846 small:
847   %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)
848   %exp = extractvalue { float, i32 } %frexp, 1
849   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
850   %is.inf = fcmp oeq float %scaled, +inf
851   %select = select i1 %is.inf, float 0.0, float %scaled
852   ret float %select
853 
854 large:
855   ret float 0.0
856 }
857 
858 ; Negative test
859 define float @frexp_fcmp_ole_nextafter1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
860 ; CHECK-LABEL: define float @frexp_fcmp_ole_nextafter1(
861 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
862 ; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
863 ; CHECK-NEXT:    [[IS_SMALL:%.*]] = fcmp ugt float [[X_FABS]], f0x3F800001
864 ; CHECK-NEXT:    br i1 [[IS_SMALL]], label %[[LARGE:.*]], label %[[SMALL:.*]]
865 ; CHECK:       [[SMALL]]:
866 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]])
867 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
868 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float [[NOT_INF]], i32 [[EXP]])
869 ; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
870 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, float [[SCALED]]
871 ; CHECK-NEXT:    ret float [[SELECT]]
872 ; CHECK:       [[LARGE]]:
873 ; CHECK-NEXT:    ret float 0.000000e+00
874 ;
875   %x.fabs = call float @llvm.fabs.f32(float %x)
876   %is.small = fcmp ole float %x.fabs, f0x3f800001
877   br i1 %is.small, label %small, label %large
878 
879 small:
880   %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)
881   %exp = extractvalue { float, i32 } %frexp, 1
882   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
883   %is.inf = fcmp oeq float %scaled, +inf
884   %select = select i1 %is.inf, float 0.0, float %scaled
885   ret float %select
886 
887 large:
888   ret float 0.0
889 }
890 
891 ; Negative test
892 define float @frexp_fcmp_ogt_nextdown1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
893 ; CHECK-LABEL: define float @frexp_fcmp_ogt_nextdown1(
894 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
895 ; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
896 ; CHECK-NEXT:    [[IS_LARGE:%.*]] = fcmp ogt float [[X_FABS]], f0x3F7FFFFF
897 ; CHECK-NEXT:    br i1 [[IS_LARGE]], label %[[LARGE:.*]], label %[[SMALL:.*]]
898 ; CHECK:       [[SMALL]]:
899 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]])
900 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
901 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float [[NOT_INF]], i32 [[EXP]])
902 ; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
903 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, float [[SCALED]]
904 ; CHECK-NEXT:    ret float [[SELECT]]
905 ; CHECK:       [[LARGE]]:
906 ; CHECK-NEXT:    ret float 0.000000e+00
907 ;
908   %x.fabs = call float @llvm.fabs.f32(float %x)
909   %is.large = fcmp ogt float %x.fabs, f0x3f7fffff
910   br i1 %is.large, label %large, label %small
911 
912 small:
913   %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)
914   %exp = extractvalue { float, i32 } %frexp, 1
915   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
916   %is.inf = fcmp oeq float %scaled, +inf
917   %select = select i1 %is.inf, float 0.0, float %scaled
918   ret float %select
919 
920 large:
921   ret float 0.0
922 }
923 
924 ; Negative test
925 define float @frexp_fcmp_ole_nextdown1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
926 ; CHECK-LABEL: define float @frexp_fcmp_ole_nextdown1(
927 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
928 ; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
929 ; CHECK-NEXT:    [[IS_SMALL:%.*]] = fcmp ugt float [[X_FABS]], f0x3F7FFFFF
930 ; CHECK-NEXT:    br i1 [[IS_SMALL]], label %[[LARGE:.*]], label %[[SMALL:.*]]
931 ; CHECK:       [[SMALL]]:
932 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]])
933 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
934 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float [[NOT_INF]], i32 [[EXP]])
935 ; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
936 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, float [[SCALED]]
937 ; CHECK-NEXT:    ret float [[SELECT]]
938 ; CHECK:       [[LARGE]]:
939 ; CHECK-NEXT:    ret float 0.000000e+00
940 ;
941   %x.fabs = call float @llvm.fabs.f32(float %x)
942   %is.small = fcmp ole float %x.fabs, f0x3f7fffff
943   br i1 %is.small, label %small, label %large
944 
945 small:
946   %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)
947   %exp = extractvalue { float, i32 } %frexp, 1
948   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
949   %is.inf = fcmp oeq float %scaled, +inf
950   %select = select i1 %is.inf, float 0.0, float %scaled
951   ret float %select
952 
953 large:
954   ret float 0.0
955 }
956 
957 ; Negative test
958 define float @frexp_fcmp_ole_inf(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
959 ; CHECK-LABEL: define float @frexp_fcmp_ole_inf(
960 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
961 ; CHECK-NEXT:    br i1 true, label %[[SMALL:.*]], label %[[LARGE:.*]]
962 ; CHECK:       [[SMALL]]:
963 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]])
964 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
965 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float [[NOT_INF]], i32 [[EXP]])
966 ; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
967 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, float [[SCALED]]
968 ; CHECK-NEXT:    ret float [[SELECT]]
969 ; CHECK:       [[LARGE]]:
970 ; CHECK-NEXT:    ret float 0.000000e+00
971 ;
972   %x.fabs = call float @llvm.fabs.f32(float %x)
973   %is.small = fcmp ole float %x.fabs, +inf
974   br i1 %is.small, label %small, label %large
975 
976 small:
977   %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)
978   %exp = extractvalue { float, i32 } %frexp, 1
979   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
980   %is.inf = fcmp oeq float %scaled, +inf
981   %select = select i1 %is.inf, float 0.0, float %scaled
982   ret float %select
983 
984 large:
----------------------------------------------------------------------------------------------------

TOOL CALL: read250

{"file":"llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll","position":985}

TOOL OUTPUT

file: llvm/test/Transforms/InstCombine/frexp-implied-exponent-range-dominating-conditions.ll:985-1235
-----------------------------------------------------------------------------------------------------
 985   ret float 0.0
 986 }
 987 
 988 ; Negative test
 989 define float @frexp_fcmp_ole_nan(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
 990 ; CHECK-LABEL: define float @frexp_fcmp_ole_nan(
 991 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
 992 ; CHECK-NEXT:    br i1 false, label %[[SMALL:.*]], label %[[LARGE:.*]]
 993 ; CHECK:       [[SMALL]]:
 994 ; CHECK-NEXT:    ret float poison
 995 ; CHECK:       [[LARGE]]:
 996 ; CHECK-NEXT:    ret float 0.000000e+00
 997 ;
 998   %x.fabs = call float @llvm.fabs.f32(float %x)
 999   %is.small = fcmp ole float %x.fabs, +qnan
1000   br i1 %is.small, label %small, label %large
1001 
1002 small:
1003   %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)
1004   %exp = extractvalue { float, i32 } %frexp, 1
1005   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
1006   %is.inf = fcmp oeq float %scaled, +inf
1007   %select = select i1 %is.inf, float 0.0, float %scaled
1008   ret float %select
1009 
1010 large:
1011   ret float 0.0
1012 }
1013 
1014 ; Negative test
1015 define float @frexp_fcmp_olt_1_not_dominated(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf, i1 %arg) {
1016 ; CHECK-LABEL: define float @frexp_fcmp_olt_1_not_dominated(
1017 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]], i1 [[ARG:%.*]]) {
1018 ; CHECK-NEXT:  [[ENTRY:.*:]]
1019 ; CHECK-NEXT:    br i1 [[ARG]], label %[[GUARD:.*]], label %[[SMALL:.*]]
1020 ; CHECK:       [[GUARD]]:
1021 ; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
1022 ; CHECK-NEXT:    [[IS_SMALL:%.*]] = fcmp olt float [[X_FABS]], 1.000000e+00
1023 ; CHECK-NEXT:    br i1 [[IS_SMALL]], label %[[SMALL]], label %[[EXIT:.*]]
1024 ; CHECK:       [[SMALL]]:
1025 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]])
1026 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
1027 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float [[NOT_INF]], i32 [[EXP]])
1028 ; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
1029 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, float [[SCALED]]
1030 ; CHECK-NEXT:    ret float [[SELECT]]
1031 ; CHECK:       [[EXIT]]:
1032 ; CHECK-NEXT:    ret float 0.000000e+00
1033 ;
1034 entry:
1035   br i1 %arg, label %guard, label %small
1036 
1037 guard:
1038   %x.fabs = call float @llvm.fabs.f32(float %x)
1039   %is.small = fcmp olt float %x.fabs, 1.0
1040   br i1 %is.small, label %small, label %exit
1041 
1042 small:
1043   %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)
1044   %exp = extractvalue { float, i32 } %frexp, 1
1045   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
1046   %is.inf = fcmp oeq float %scaled, +inf
1047   %select = select i1 %is.inf, float 0.0, float %scaled
1048   ret float %select
1049 
1050 exit:
1051   ret float 0.0
1052 }
1053 
1054 ; Make sure the inner compare against 1 is recognized and doesn't
1055 ; abort the search after seeing the outer compare.
1056 define float @frexp_fcmp_olt_1_multiple_conditions_wrong_constant(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
1057 ; CHECK-LABEL: define float @frexp_fcmp_olt_1_multiple_conditions_wrong_constant(
1058 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
1059 ; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
1060 ; CHECK-NEXT:    [[IS_SMALL:%.*]] = fcmp olt float [[X_FABS]], 2.000000e+00
1061 ; CHECK-NEXT:    br i1 [[IS_SMALL]], label %[[SMALL:.*]], label %[[EXIT:.*]]
1062 ; CHECK:       [[SMALL]]:
1063 ; CHECK-NEXT:    [[OTHER_COND:%.*]] = fcmp olt float [[X_FABS]], 1.000000e+00
1064 ; CHECK-NEXT:    br i1 [[OTHER_COND]], label %[[BODY:.*]], label %[[EXIT]]
1065 ; CHECK:       [[BODY]]:
1066 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]])
1067 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
1068 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float [[NOT_INF]], i32 [[EXP]])
1069 ; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
1070 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, float [[SCALED]]
1071 ; CHECK-NEXT:    ret float [[SELECT]]
1072 ; CHECK:       [[EXIT]]:
1073 ; CHECK-NEXT:    ret float 0.000000e+00
1074 ;
1075   %x.fabs = call float @llvm.fabs.f32(float %x)
1076   %is.small = fcmp olt float %x.fabs, 2.0
1077   br i1 %is.small, label %small, label %exit
1078 
1079 small:
1080   %other.cond = fcmp olt float %x.fabs, 1.0
1081   br i1 %other.cond, label %body, label %exit
1082 
1083 body:
1084   %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)
1085   %exp = extractvalue { float, i32 } %frexp, 1
1086   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
1087   %is.inf = fcmp oeq float %scaled, +inf
1088   %select = select i1 %is.inf, float 0.0, float %scaled
1089   ret float %select
1090 
1091 exit:
1092   ret float 0.0
1093 }
1094 
1095 ; Make sure the inner compare against 1 is recognized and doesn't
1096 ; abort the search after seeing the outer compare.
1097 define float @frexp_fcmp_olt_1_multiple_conditions_nonfinite_constant(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
1098 ; CHECK-LABEL: define float @frexp_fcmp_olt_1_multiple_conditions_nonfinite_constant(
1099 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
1100 ; CHECK-NEXT:    br i1 true, label %[[SMALL:.*]], label %[[EXIT:.*]]
1101 ; CHECK:       [[SMALL]]:
1102 ; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
1103 ; CHECK-NEXT:    [[OTHER_COND:%.*]] = fcmp olt float [[X_FABS]], 1.000000e+00
1104 ; CHECK-NEXT:    br i1 [[OTHER_COND]], label %[[BODY:.*]], label %[[EXIT]]
1105 ; CHECK:       [[BODY]]:
1106 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]])
1107 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
1108 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float [[NOT_INF]], i32 [[EXP]])
1109 ; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
1110 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, float [[SCALED]]
1111 ; CHECK-NEXT:    ret float [[SELECT]]
1112 ; CHECK:       [[EXIT]]:
1113 ; CHECK-NEXT:    ret float 0.000000e+00
1114 ;
1115   %x.fabs = call float @llvm.fabs.f32(float %x)
1116   %is.small = fcmp olt float %x.fabs, +inf
1117   br i1 %is.small, label %small, label %exit
1118 
1119 small:
1120   %other.cond = fcmp olt float %x.fabs, 1.0
1121   br i1 %other.cond, label %body, label %exit
1122 
1123 body:
1124   %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)
1125   %exp = extractvalue { float, i32 } %frexp, 1
1126   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
1127   %is.inf = fcmp oeq float %scaled, +inf
1128   %select = select i1 %is.inf, float 0.0, float %scaled
1129   ret float %select
1130 
1131 exit:
1132   ret float 0.0
1133 }
1134 
1135 define float @frexp_fcmp_olt_1_multiple_conditions_edge_case_compare(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
1136 ; CHECK-LABEL: define float @frexp_fcmp_olt_1_multiple_conditions_edge_case_compare(
1137 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
1138 ; CHECK-NEXT:    br i1 true, label %[[SMALL:.*]], label %[[EXIT:.*]]
1139 ; CHECK:       [[SMALL]]:
1140 ; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
1141 ; CHECK-NEXT:    [[OTHER_COND:%.*]] = fcmp olt float [[X_FABS]], 1.000000e+00
1142 ; CHECK-NEXT:    br i1 [[OTHER_COND]], label %[[BODY:.*]], label %[[EXIT]]
1143 ; CHECK:       [[BODY]]:
1144 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]])
1145 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
1146 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float [[NOT_INF]], i32 [[EXP]])
1147 ; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
1148 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, float [[SCALED]]
1149 ; CHECK-NEXT:    ret float [[SELECT]]
1150 ; CHECK:       [[EXIT]]:
1151 ; CHECK-NEXT:    ret float 0.000000e+00
1152 ;
1153   %x.fabs = call float @llvm.fabs.f32(float %x)
1154   %is.small = fcmp ord float %x.fabs, 0.0
1155   br i1 %is.small, label %small, label %exit
1156 
1157 small:
1158   %other.cond = fcmp olt float %x.fabs, 1.0
1159   br i1 %other.cond, label %body, label %exit
1160 
1161 body:
1162   %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)
1163   %exp = extractvalue { float, i32 } %frexp, 1
1164   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
1165   %is.inf = fcmp oeq float %scaled, +inf
1166   %select = select i1 %is.inf, float 0.0, float %scaled
1167   ret float %select
1168 
1169 exit:
1170   ret float 0.0
1171 }
1172 
1173 
1174 define float @frexp_fcmp_olt_1_multiple_conditions_other(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
1175 ; CHECK-LABEL: define float @frexp_fcmp_olt_1_multiple_conditions_other(
1176 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
1177 ; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
1178 ; CHECK-NEXT:    [[IS_SMALL:%.*]] = fcmp olt float [[X_FABS]], 1.000000e+00
1179 ; CHECK-NEXT:    br i1 [[IS_SMALL]], label %[[SMALL:.*]], label %[[EXIT:.*]]
1180 ; CHECK:       [[SMALL]]:
1181 ; CHECK-NEXT:    [[OTHER_COND:%.*]] = fcmp ueq float [[X]], 5.000000e-01
1182 ; CHECK-NEXT:    br i1 [[OTHER_COND]], label %[[EXIT]], label %[[BODY:.*]]
1183 ; CHECK:       [[BODY]]:
1184 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]])
1185 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1
1186 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i32(float [[NOT_INF]], i32 [[EXP]])
1187 ; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
1188 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, float [[SCALED]]
1189 ; CHECK-NEXT:    ret float [[SELECT]]
1190 ; CHECK:       [[EXIT]]:
1191 ; CHECK-NEXT:    ret float 0.000000e+00
1192 ;
1193   %x.fabs = call float @llvm.fabs.f32(float %x)
1194   %is.small = fcmp olt float %x.fabs, 1.0
1195   br i1 %is.small, label %small, label %exit
1196 
1197 small:
1198   %other.cond = fcmp one float %x, 0.5
1199   br i1 %other.cond, label %body, label %exit
1200 
1201 body:
1202   %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)
1203   %exp = extractvalue { float, i32 } %frexp, 1
1204   %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)
1205   %is.inf = fcmp oeq float %scaled, +inf
1206   %select = select i1 %is.inf, float 0.0, float %scaled
1207   ret float %select
1208 
1209 exit:
1210   ret float 0.0
1211 }
1212 
1213 ; Test no assertion on exponent type > 64
1214 define float @frexp_fcmp_ogt_1_large_int(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {
1215 ; CHECK-LABEL: define float @frexp_fcmp_ogt_1_large_int(
1216 ; CHECK-SAME: float nofpclass(nan inf) [[X:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
1217 ; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
1218 ; CHECK-NEXT:    [[IS_LARGE:%.*]] = fcmp ogt float [[X_FABS]], 1.000000e+00
1219 ; CHECK-NEXT:    br i1 [[IS_LARGE]], label %[[LARGE:.*]], label %[[SMALL:.*]]
1220 ; CHECK:       [[SMALL]]:
1221 ; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i128 } @llvm.frexp.f32.i128(float [[X]])
1222 ; CHECK-NEXT:    [[EXP:%.*]] = extractvalue { float, i128 } [[FREXP]], 1
1223 ; CHECK-NEXT:    [[SCALED:%.*]] = call float @llvm.ldexp.f32.i128(float [[NOT_INF]], i128 [[EXP]])
1224 ; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[SCALED]], +inf
1225 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0.000000e+00, float [[SCALED]]
1226 ; CHECK-NEXT:    ret float [[SELECT]]
1227 ; CHECK:       [[LARGE]]:
1228 ; CHECK-NEXT:    ret float 0.000000e+00
1229 ;
1230   %x.fabs = call float @llvm.fabs.f32(float %x)
1231   %is.large = fcmp ogt float %x.fabs, 1.0
1232   br i1 %is.large, label %large, label %small
1233 
1234 small:
-----------------------------------------------------------------------------------------------------

TOOL CALL: stop

{"strategies":[{"expected_issue":"The optimizer may prove the frexp exponent is <= 0 and remove an ldexp overflow check, but at x = 1.0 frexp returns exponent 1, so ldexp(max_finite, 1) can overflow to +inf and the removed check was semantically observable.","name":"Inclusive one off-by-one overflow guard","rationale":"The new context range uses ilogb(K) as the inclusive maximum frexp exponent for fabs(x) <= K. For nonzero finite x, frexp exponent is ilogb(x)+1. Thus fabs(x) <= 1.0 permits x=1.0 with exponent 1, but the analysis records max 0.","target":"Mutate an existing frexp_fcmp_ole_1 / frexp_fcmp_ogt_1 false-edge test so the ldexp source can be the largest finite float/double and the result is guarded by `fcmp oeq +inf` or an `is_fpclass(inf)` path."},{"expected_issue":"Integer users of the exponent may be folded incorrectly, e.g. `icmp sle i32 %exp, -1` or `icmp slt i32 %exp, 0` may become true under a dominating `fabs(x) <= 0.75`, although x=0.75 gives frexp exponent 0.","name":"Non-power-of-two bound off-by-one","rationale":"For a non-power-of-two K in (0.5, 1), ilogb(K) is -1, but values in [0.5,K] have frexp exponent 0. The patch accepts any finite K <= 1.0, not just strict comparisons against powers of two where ilogb(K) is a valid upper bound.","target":"Mutate the dominating compare constant from 1.0 to 0.75 (or hex f0x3F400000) and add an integer comparison/select on the extracted frexp exponent, such as `select (icmp slt %exp, 0) ...`."},{"expected_issue":"The analysis may create a nonsensical or wrapped ConstantRange for the exponent, possibly leading to wrong folds of comparisons against very negative values, or assertions in debug builds around ConstantRange construction/use.","name":"Zero limit pathological range","rationale":"`ilogb(0.0)` returns APFloat::IEK_Zero (INT_MIN+1), but frexp(0.0) returns exponent 0. Under `fabs(x) <= 0.0` or `fabs(x) == 0.0`, the patch sets the adjusted max to IEK_Zero rather than 0, making max less than the normal minimum exponent and potentially wrapping when converted to ConstantRange.","target":"Mutate the compare limit to `0.0` with a no-NaN/non-inf source and use the extracted exponent in an `icmp` (for example `icmp slt %exp, -1000000`) or downstream ldexp classification."},{"expected_issue":"Equality cases may be optimized as if the exponent is <= ilogb(K), but when fabs(x) == K and K is nonzero, the exponent is ilogb(K)+1; this can miscompile both integer exponent tests and ldexp overflow pruning.","name":"OEQ/UEQ exact-bound exponent","rationale":"The patch groups `oeq`/`ueq` with less-or-equal predicates. Equality to a finite nonzero magnitude gives a precise frexp exponent of ilogb(K)+1, not ilogb(K). With `nofpclass(nan inf)` on the source, unordered complications are removed and the off-by-one becomes directly observable.","target":"Mutate an existing `fcmp ole/ule` case to `fcmp oeq float fabs(x), 1.0` (and separately `0.5` or `0.75`) on the true edge, then test either `ldexp(max_finite, %exp)` overflow or an `icmp sle %exp, 0` fold."},{"expected_issue":"For small integer exponent result types, min/max APInt construction may truncate the real float exponent bounds, producing wrapped or overly precise ConstantRanges and incorrect signed comparisons or known-fp-class deductions.","name":"Narrow frexp exponent type wrapping","rationale":"The frexp exponent range for float is roughly [-149,128], which does not fit in i8 and certainly not in i1/i2. The patch constructs `APInt(BitWidth, MinExp, isSigned=true)` and `APInt(BitWidth, MaxExp+1, isSigned=true)`, so narrow result types can wrap the mathematical bounds. Existing tests cover i16/i128 but not too-narrow types.","target":"Mutate `known-range-frexp-exp.ll` or the dominating-condition test to declare/use `@llvm.frexp.f32.i8` (and possibly i1/i2), extract the exponent, and feed it to signed `icmp` or `llvm.ldexp.f32.i8` under a dominating `fabs(x) < 1.0` condition."}],"thoughts":"### 1. Fix Understanding\nThe patch improves ValueTracking by deriving a signed ConstantRange for the exponent result of `llvm.frexp` from dominating control-flow conditions of the form `fcmp Pred (fabs V), finite_constant`. That exponent range is then used by `computeConstantRange`, and `computeKnownFPClass` for `llvm.ldexp` is changed from `KnownBits`-based exponent reasoning to ConstantRange min/max reasoning. The intended optimization is to recognize that, in a block dominated by a condition like `fabs(x) < 1.0`, `frexp(x)` has a non-positive exponent, so a following `ldexp(finite, exp)` cannot overflow to infinity.\n\nKey changed pieces:\n* `computeKnownExponentRangeFromContext(V,Q)` scans dominating conditional branches involving `fabs(V)` and a finite constant <= 1.0.\n* For a matching dominated edge, it returns `{IEK_NaN, ilogb(LimitC)}` as adjusted exponent min/max.\n* `computeConstantRange` for `extractvalue 1 (llvm.frexp(src))` intersects the normal IEEE exponent bounds with that contextual bound.\n* `KnownFPClass::ldexp` now accepts exponent signed min/max APInts, with a KnownBits wrapper preserving old API users.\n\n### 2. Formal Semantic Modeling\nBefore the fix, for a non-NaN/non-inf IEEE-like source `x`, ValueTracking modeled the frexp exponent result with a type-wide-ish floating format range:\n* normal/subnormal float: approximately `[-149, 128]` for f32, because frexp returns 0 for zero and `ilogb(x)+1` for finite nonzero x.\n* no dominating `fabs` condition affected this range.\n\nAfter the fix, under a dominating branch condition matching `fabs(x) Pred K` with finite `K <= 1.0`, the range is further adjusted to max exponent `ilogb(K)` for the edge interpreted as proving `fabs(x) <= K` (or the false edge of a greater-than predicate).\n\nThe semantic contract the patch appears to claim is:\n* If the current block is dominated by a condition implying `fabs(x) <= K`, with finite `K <= 1.0`, and `x` is known not NaN/Inf, then `frexp(x).exp <= ilogb(K)`.\n\nHowever, the mathematical frexp semantics are:\n* `frexp(0).exp = 0`.\n* For finite nonzero `x`, `frexp(x).exp = ilogb(x) + 1`.\n\nConcrete instantiation:\n* Let `x = 1.0f`; `fabs(x) <= 1.0` is true.\n* `ilogb(1.0) = 0`.\n* `frexp(1.0).exp = 1`, because mantissa is 0.5 and exponent is 1.\n* The patch would infer max exponent 0 on inclusive/equality paths, which excludes the real value 1.\n\nAnother instantiation:\n* Let `x = 0.75f`; `fabs(x) <= 0.75` is true.\n* `ilogb(0.75) = -1`.\n* `frexp(0.75).exp = 0`, excluding the inferred max -1.\n\n### 3. Assumptions and Preconditions Identified\nThe fix relies on these assumptions:\n1. `ilogb(K)` is a sound upper bound for the frexp exponent whenever the branch implies `fabs(x) <= K`.\n2. Inclusive comparisons (`ole`, `ule`) and equality comparisons (`oeq`, `ueq`) can be treated the same as strict less-than for exponent upper-bound purposes.\n3. The zero limit can be handled by the same `ilogb` path as nonzero finite constants.\n4. The extracted frexp exponent integer type is wide enough to represent the APFloat exponent bounds and adjusted bounds without harmful APInt truncation.\n5. Passing only ConstantRange signed min/max to `KnownFPClass::ldexp` is conservative enough for all ranges produced by computeConstantRange.\n6. Unordered predicates are safe provided `KnownSrc.isKnownNeverInfOrNaN()` is checked before constraining the frexp range.\n\n### 4. Potential Cases to Break Assumptions\n* Inclusive bound at exactly 1.0: `fabs(x) <= 1.0` allows `x = +/-1.0`, where frexp exponent is 1, not 0.\n* Equality bound: `fabs(x) == 1.0` or `fabs(x) == 0.5` gives exponent 1 or 0 respectively, but the patch uses ilogb(K), one less for nonzero K.\n* Non-power-of-two bound: `fabs(x) <= 0.75` allows exponents up to 0, while `ilogb(0.75)` is -1.\n* Zero bound: `fabs(x) <= 0.0` implies x is zero (modulo NaN handling), whose frexp exponent is 0; `ilogb(0.0)` is an error sentinel `IEK_Zero`, not a valid upper bound.\n* Narrow exponent result types: the mathematical f32 exponent range does not fit in i8/i1, and APInt construction may wrap values, producing invalid-looking ConstantRanges.\n* Downstream observable effects: integer comparisons on the exponent may fold incorrectly; ldexp known-fp-class may remove infinity checks when the real exponent can still be positive.\n\n### 5. Test Strategies\nThe proposed strategies focus on mutating existing frexp/ldexp InstCombine and known-range tests to make the inferred exponent bound observable through either removed overflow checks or folded integer comparisons. The highest-risk strategies are the inclusive/equality off-by-one cases and zero-limit case because they are direct semantic mismatches with LangRef frexp semantics."}

TOOL OUTPUT

{
  "strategies": [
    [
      "Inclusive one off-by-one overflow guard",
      "Mutate an existing frexp_fcmp_ole_1 / frexp_fcmp_ogt_1 false-edge test so the ldexp source can be the largest finite float/double and the result is guarded by `fcmp oeq +inf` or an `is_fpclass(inf)` path.",
      "The new context range uses ilogb(K) as the inclusive maximum frexp exponent for fabs(x) <= K. For nonzero finite x, frexp exponent is ilogb(x)+1. Thus fabs(x) <= 1.0 permits x=1.0 with exponent 1, but the analysis records max 0.",
      "The optimizer may prove the frexp exponent is <= 0 and remove an ldexp overflow check, but at x = 1.0 frexp returns exponent 1, so ldexp(max_finite, 1) can overflow to +inf and the removed check was semantically observable."
    ],
    [
      "Non-power-of-two bound off-by-one",
      "Mutate the dominating compare constant from 1.0 to 0.75 (or hex f0x3F400000) and add an integer comparison/select on the extracted frexp exponent, such as `select (icmp slt %exp, 0) ...`.",
      "For a non-power-of-two K in (0.5, 1), ilogb(K) is -1, but values in [0.5,K] have frexp exponent 0. The patch accepts any finite K <= 1.0, not just strict comparisons against powers of two where ilogb(K) is a valid upper bound.",
      "Integer users of the exponent may be folded incorrectly, e.g. `icmp sle i32 %exp, -1` or `icmp slt i32 %exp, 0` may become true under a dominating `fabs(x) <= 0.75`, although x=0.75 gives frexp exponent 0."
    ],
    [
      "Zero limit pathological range",
      "Mutate the compare limit to `0.0` with a no-NaN/non-inf source and use the extracted exponent in an `icmp` (for example `icmp slt %exp, -1000000`) or downstream ldexp classification.",
      "`ilogb(0.0)` returns APFloat::IEK_Zero (INT_MIN+1), but frexp(0.0) returns exponent 0. Under `fabs(x) <= 0.0` or `fabs(x) == 0.0`, the patch sets the adjusted max to IEK_Zero rather than 0, making max less than the normal minimum exponent and potentially wrapping when converted to ConstantRange.",
      "The analysis may create a nonsensical or wrapped ConstantRange for the exponent, possibly leading to wrong folds of comparisons against very negative values, or assertions in debug builds around ConstantRange construction/use."
    ],
    [
      "OEQ/UEQ exact-bound exponent",
      "Mutate an existing `fcmp ole/ule` case to `fcmp oeq float fabs(x), 1.0` (and separately `0.5` or `0.75`) on the true edge, then test either `ldexp(max_finite, %exp)` overflow or an `icmp sle %exp, 0` fold.",
      "The patch groups `oeq`/`ueq` with less-or-equal predicates. Equality to a finite nonzero magnitude gives a precise frexp exponent of ilogb(K)+1, not ilogb(K). With `nofpclass(nan inf)` on the source, unordered complications are removed and the off-by-one becomes directly observable.",
      "Equality cases may be optimized as if the exponent is <= ilogb(K), but when fabs(x) == K and K is nonzero, the exponent is ilogb(K)+1; this can miscompile both integer exponent tests and ldexp overflow pruning."
    ],
    [
      "Narrow frexp exponent type wrapping",
      "Mutate `known-range-frexp-exp.ll` or the dominating-condition test to declare/use `@llvm.frexp.f32.i8` (and possibly i1/i2), extract the exponent, and feed it to signed `icmp` or `llvm.ldexp.f32.i8` under a dominating `fabs(x) < 1.0` condition.",
      "The frexp exponent range for float is roughly [-149,128], which does not fit in i8 and certainly not in i1/i2. The patch constructs `APInt(BitWidth, MinExp, isSigned=true)` and `APInt(BitWidth, MaxExp+1, isSigned=true)`, so narrow result types can wrap the mathematical bounds. Existing tests cover i16/i128 but not too-narrow types.",
      "For small integer exponent result types, min/max APInt construction may truncate the real float exponent bounds, producing wrapped or overly precise ConstantRanges and incorrect signed comparisons or known-fp-class deductions."
    ]
  ],
  "thoughts": "### 1. Fix Understanding\nThe patch improves ValueTracking by deriving a signed ConstantRange for the exponent result of `llvm.frexp` from dominating control-flow conditions of the form `fcmp Pred (fabs V), finite_constant`. That exponent range is then used by `computeConstantRange`, and `computeKnownFPClass` for `llvm.ldexp` is changed from `KnownBits`-based exponent reasoning to ConstantRange min/max reasoning. The intended optimization is to recognize that, in a block dominated by a condition like `fabs(x) < 1.0`, `frexp(x)` has a non-positive exponent, so a following `ldexp(finite, exp)` cannot overflow to infinity.\n\nKey changed pieces:\n* `computeKnownExponentRangeFromContext(V,Q)` scans dominating conditional branches involving `fabs(V)` and a finite constant <= 1.0.\n* For a matching dominated edge, it returns `{IEK_NaN, ilogb(LimitC)}` as adjusted exponent min/max.\n* `computeConstantRange` for `extractvalue 1 (llvm.frexp(src))` intersects the normal IEEE exponent bounds with that contextual bound.\n* `KnownFPClass::ldexp` now accepts exponent signed min/max APInts, with a KnownBits wrapper preserving old API users.\n\n### 2. Formal Semantic Modeling\nBefore the fix, for a non-NaN/non-inf IEEE-like source `x`, ValueTracking modeled the frexp exponent result with a type-wide-ish floating format range:\n* normal/subnormal float: approximately `[-149, 128]` for f32, because frexp returns 0 for zero and `ilogb(x)+1` for finite nonzero x.\n* no dominating `fabs` condition affected this range.\n\nAfter the fix, under a dominating branch condition matching `fabs(x) Pred K` with finite `K <= 1.0`, the range is further adjusted to max exponent `ilogb(K)` for the edge interpreted as proving `fabs(x) <= K` (or the false edge of a greater-than predicate).\n\nThe semantic contract the patch appears to claim is:\n* If the current block is dominated by a condition implying `fabs(x) <= K`, with finite `K <= 1.0`, and `x` is known not NaN/Inf, then `frexp(x).exp <= ilogb(K)`.\n\nHowever, the mathematical frexp semantics are:\n* `frexp(0).exp = 0`.\n* For finite nonzero `x`, `frexp(x).exp = ilogb(x) + 1`.\n\nConcrete instantiation:\n* Let `x = 1.0f`; `fabs(x) <= 1.0` is true.\n* `ilogb(1.0) = 0`.\n* `frexp(1.0).exp = 1`, because mantissa is 0.5 and exponent is 1.\n* The patch would infer max exponent 0 on inclusive/equality paths, which excludes the real value 1.\n\nAnother instantiation:\n* Let `x = 0.75f`; `fabs(x) <= 0.75` is true.\n* `ilogb(0.75) = -1`.\n* `frexp(0.75).exp = 0`, excluding the inferred max -1.\n\n### 3. Assumptions and Preconditions Identified\nThe fix relies on these assumptions:\n1. `ilogb(K)` is a sound upper bound for the frexp exponent whenever the branch implies `fabs(x) <= K`.\n2. Inclusive comparisons (`ole`, `ule`) and equality comparisons (`oeq`, `ueq`) can be treated the same as strict less-than for exponent upper-bound purposes.\n3. The zero limit can be handled by the same `ilogb` path as nonzero finite constants.\n4. The extracted frexp exponent integer type is wide enough to represent the APFloat exponent bounds and adjusted bounds without harmful APInt truncation.\n5. Passing only ConstantRange signed min/max to `KnownFPClass::ldexp` is conservative enough for all ranges produced by computeConstantRange.\n6. Unordered predicates are safe provided `KnownSrc.isKnownNeverInfOrNaN()` is checked before constraining the frexp range.\n\n### 4. Potential Cases to Break Assumptions\n* Inclusive bound at exactly 1.0: `fabs(x) <= 1.0` allows `x = +/-1.0`, where frexp exponent is 1, not 0.\n* Equality bound: `fabs(x) == 1.0` or `fabs(x) == 0.5` gives exponent 1 or 0 respectively, but the patch uses ilogb(K), one less for nonzero K.\n* Non-power-of-two bound: `fabs(x) <= 0.75` allows exponents up to 0, while `ilogb(0.75)` is -1.\n* Zero bound: `fabs(x) <= 0.0` implies x is zero (modulo NaN handling), whose frexp exponent is 0; `ilogb(0.0)` is an error sentinel `IEK_Zero`, not a valid upper bound.\n* Narrow exponent result types: the mathematical f32 exponent range does not fit in i8/i1, and APInt construction may wrap values, producing invalid-looking ConstantRanges.\n* Downstream observable effects: integer comparisons on the exponent may fold incorrectly; ldexp known-fp-class may remove infinity checks when the real exponent can still be positive.\n\n### 5. Test Strategies\nThe proposed strategies focus on mutating existing frexp/ldexp InstCombine and known-range tests to make the inferred exponent bound observable through either removed overflow checks or folded integer comparisons. The highest-risk strategies are the inclusive/equality off-by-one cases and zero-limit case because they are direct semantic mismatches with LangRef frexp semantics."
}

USER

# Phase 2: Generate Verified Test Cases

You have proposed the following test strategies in Phase 1:

[{'name': 'Inclusive one off-by-one overflow guard', 'target': 'Mutate an existing frexp_fcmp_ole_1 / frexp_fcmp_ogt_1 false-edge test so the ldexp source can be the largest finite float/double and the result is guarded by `fcmp oeq +inf` or an `is_fpclass(inf)` path.', 'rationale': 'The new context range uses ilogb(K) as the inclusive maximum frexp exponent for fabs(x) <= K. For nonzero finite x, frexp exponent is ilogb(x)+1. Thus fabs(x) <= 1.0 permits x=1.0 with exponent 1, but the analysis records max 0.', 'expected_issue': 'The optimizer may prove the frexp exponent is <= 0 and remove an ldexp overflow check, but at x = 1.0 frexp returns exponent 1, so ldexp(max_finite, 1) can overflow to +inf and the removed check was semantically observable.'}, {'name': 'Non-power-of-two bound off-by-one', 'target': 'Mutate the dominating compare constant from 1.0 to 0.75 (or hex f0x3F400000) and add an integer comparison/select on the extracted frexp exponent, such as `select (icmp slt %exp, 0) ...`.', 'rationale': 'For a non-power-of-two K in (0.5, 1), ilogb(K) is -1, but values in [0.5,K] have frexp exponent 0. The patch accepts any finite K <= 1.0, not just strict comparisons against powers of two where ilogb(K) is a valid upper bound.', 'expected_issue': 'Integer users of the exponent may be folded incorrectly, e.g. `icmp sle i32 %exp, -1` or `icmp slt i32 %exp, 0` may become true under a dominating `fabs(x) <= 0.75`, although x=0.75 gives frexp exponent 0.'}, {'name': 'Zero limit pathological range', 'target': 'Mutate the compare limit to `0.0` with a no-NaN/non-inf source and use the extracted exponent in an `icmp` (for example `icmp slt %exp, -1000000`) or downstream ldexp classification.', 'rationale': '`ilogb(0.0)` returns APFloat::IEK_Zero (INT_MIN+1), but frexp(0.0) returns exponent 0. Under `fabs(x) <= 0.0` or `fabs(x) == 0.0`, the patch sets the adjusted max to IEK_Zero rather than 0, making max less than the normal minimum exponent and potentially wrapping when converted to ConstantRange.', 'expected_issue': 'The analysis may create a nonsensical or wrapped ConstantRange for the exponent, possibly leading to wrong folds of comparisons against very negative values, or assertions in debug builds around ConstantRange construction/use.'}, {'name': 'OEQ/UEQ exact-bound exponent', 'target': 'Mutate an existing `fcmp ole/ule` case to `fcmp oeq float fabs(x), 1.0` (and separately `0.5` or `0.75`) on the true edge, then test either `ldexp(max_finite, %exp)` overflow or an `icmp sle %exp, 0` fold.', 'rationale': 'The patch groups `oeq`/`ueq` with less-or-equal predicates. Equality to a finite nonzero magnitude gives a precise frexp exponent of ilogb(K)+1, not ilogb(K). With `nofpclass(nan inf)` on the source, unordered complications are removed and the off-by-one becomes directly observable.', 'expected_issue': 'Equality cases may be optimized as if the exponent is <= ilogb(K), but when fabs(x) == K and K is nonzero, the exponent is ilogb(K)+1; this can miscompile both integer exponent tests and ldexp overflow pruning.'}, {'name': 'Narrow frexp exponent type wrapping', 'target': 'Mutate `known-range-frexp-exp.ll` or the dominating-condition test to declare/use `@llvm.frexp.f32.i8` (and possibly i1/i2), extract the exponent, and feed it to signed `icmp` or `llvm.ldexp.f32.i8` under a dominating `fabs(x) < 1.0` condition.', 'rationale': 'The frexp exponent range for float is roughly [-149,128], which does not fit in i8 and certainly not in i1/i2. The patch constructs `APInt(BitWidth, MinExp, isSigned=true)` and `APInt(BitWidth, MaxExp+1, isSigned=true)`, so narrow result types can wrap the mathematical bounds. Existing tests cover i16/i128 but not too-narrow types.', 'expected_issue': 'For small integer exponent result types, min/max APInt construction may truncate the real float exponent bounds, producing wrapped or overly precise ConstantRanges and incorrect signed comparisons or known-fp-class deductions.'}]

## Your Task for Phase 2

In this phase, you will use the `tests_manager` tool to retrieve existing test cases, apply your proposed mutations, and verify them. You must ensure that **every test case** managed by the `tests_manager` is processed and marked as tested.

Follow this structured workflow:

### Step 1: Retrieve and Prioritize Test Cases
- Use the `tests_manager` tool with the `list` action to see all available test cases and their current status.
- Use the `tests_manager` tool with the `get` action to retrieve the full details of an untested test case.
- Due to context length and round limit, you should prioritize test cases that are more relevant to the identified issues.

### Step 2: Understand the Test Case
- Analyze the selected test case to understand its structure, input characteristics, and what it is testing.
- Call the `verify` tool to see how the LLVM IR code in the test case is transformed by the optimization pass. This can help you understand the semantics of the test case and how it relates to the fix.

### Step 3: Apply Mutations
For the selected test case, apply mutations according to your proposed test strategies:
- **Focus**: Ensure the mutations focus on exposing the potential issues identified in Phase 1.
- **Format**: Provide each mutated test case in a separate ```llvm ... ``` code block.
- **Coverage**: **CRITICAL**: You must cover all the proposed test strategies across different test cases to ensure comprehensive testing of potential issues.

### Step 4: Verify and Test
- **Verify Tool**: Use the `verify` tool to submit the generated test cases along with your reasoning. This uses `alive2` to check if the test cases expose any issues with the fix.
- **Difftest Tool**: Use the `difftest` tool to execute the original and optimized LLVM IR (transformed by `opt`) with specific input values to check for execution differences.

### Step 5: Analyze Results and Refine
- If the `verify` or `difftest` fails to find issues, refine the test case only if you believe unexplored potential issues remain. Otherwise, move on to other strategies or test cases. Check **Guidelines for Refining Test Cases** below for suggestions on how to refine test cases based on verification results.

### Step 6: Mark as Tested
- Once you have fully explored and verified a test case, use the `tests_manager` tool with the `mark_tested` action to mark it as completed.
- **CRITICAL**: You must repeat this process until the `tests_manager` confirms that **all** test cases have been tested.

Repeat the above steps for each test case until all test cases in the `tests_manager` are marked as tested.

You are also allowed to generate tests from scratch or find more related tests from the LLVM test suite by using `find` or `list` tools and reading them with `read` or `grep` tools if you think the provided test cases have limited coverage of potential issues. Make sure you call `verify` and `difftest` tools to check the validity of these test cases and confirm whether the issues can be exposed by actual execution.

---

## Guidelines for Refining Test Cases

### Important Rule
You can always keep mutating the test case and verifying it until you find an issue or are confident that no issues can be found. However, make sure it is aligned with the potential issues you identified in Phase 1. Meanwhile, avoid stucking on a test case for too long. If you have tried multiple mutations and still cannot find any issues, move on to other test cases or strategies.

### Handling Verification Results
- **Failed-to-prove**:
  1. Try to reduce the test case to a smaller example that still fails. This can help isolate the specific conditions that cause the issue.
  2. Try to call `difftest` to run the test case with specific input value that you think can trigger the issue based on your analysis. This can help check if the issue can be exposed by actual execution even if it cannot be proved by alive2.
- **Alive2 errors**: Try to call `trans` to run opt with the same command arguments and adjust the test case or command arguments to fix.
- **Correct transformation**: Try to first analyze if the test strategy is correct and then decide to refine the test case or continue to generate other test cases.

### Additional Notes
- **Coverage**: If you think the provided test cases have limited coverage of potential issues, you can also find more related tests from the LLVM test suite by using `find` or `list` tools and reading them with `read` or `grep` tools.
- **Completeness**: Make sure you have at least explored all the test strategies you proposed in Phase 1, and generated multiple test cases if possible.
- **Completion**: You cannot finish Phase 2 until all tests in the `tests_manager` are marked as tested.

---

## Tools that you can use

- `findN`: Search for files in the LLVM codebase related to the component or optimization pass to understand the context of the fix and find relevant tests.
- `listN`: List files in the LLVM codebase to find relevant tests or code regions.
- `readN`: Read the content of a file in the LLVM codebase to understand existing tests or the fix.
- `grepN`: Search for specific patterns in the codebase to find relevant tests or code regions.
- `langref`: Query the LLVM Language Reference Manual for specific instructions, semantics, or optimization details relevant to the fix.
- `tests_manager`: Manage the list of test cases. You can list all tests to see their status, get the details of a specific test, or mark a test as tested. Your goal is to ensure all tests are tested.
- `trans`: Run the `opt` tool with specific arguments to see how the LLVM IR code is transformed by the optimization pass.
- `verify`: Use alive2 to verify if the transformation from original LLVM IR code to optimized LLVM IR code is correct, which can help check the validity of generated test cases in Phase 2.
- `difftest`: Use llubi to perform differential testing on the original and transformed LLVM IR code, which can help check if the generated test cases cannot be proved by alive2.
- `report`: End Phase 2 by submitting the generated test cases and their verification results.

TOOL CALL: tests_manager

{"action":"list"}

TOOL OUTPUT

{
  "tests": [
    {
      "index": 0,
      "name": "ret_ldexp_f32_neg127",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 1,
      "name": "ret_ldexp_f32_noinf_exp_known_neg_or_0",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 2,
      "name": "ret_ldexp_v2f32_known_neg_exp_noinf_nonsplat",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 3,
      "name": "ret_ldexp_v2f32_known_pos_exp_noinf",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 4,
      "name": "ret_ldexp_v2f32_known_neg_exp_noinf_splat",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 5,
      "name": "frexp_fcmp_ule_1",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 6,
      "name": "frexp_fcmp_une_1",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 7,
      "name": "frexp_fcmp_oeq_1",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 8,
      "name": "frexp_fcmp_ogt_nextdown1",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 9,
      "name": "frexp_fcmp_one_0.5",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 10,
      "name": "frexp_fcmp_olt_1",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 11,
      "name": "frexp_cmp_uge_0.5",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 12,
      "name": "frexp_fcmp_ogt_1",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 13,
      "name": "frexp_fcmp_ugt_0.5",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 14,
      "name": "frexp_fcmp_one_1",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 15,
      "name": "frexp_fcmp_olt_1_multiple_conditions_wrong_constant",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 16,
      "name": "frexp_cmp_ugt_0.5",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 17,
      "name": "frexp_fcmp_ole_1",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 18,
      "name": "frexp_fcmp_ueq_0.5",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 19,
      "name": "frexp_fcmp_oeq_0.5",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 20,
      "name": "frexp_fcmp_ogt_1_large_int",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 21,
      "name": "frexp_fcmp_ult_0.5",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 22,
      "name": "frexp_fcmp_une_0.5",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 23,
      "name": "frexp_fcmp_olt_1_multiple_conditions_nonfinite_constant",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 24,
      "name": "frexp_fcmp_ole_nextdown1",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 25,
      "name": "frexp_fcmp_olt_1_multiple_conditions_other",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 26,
      "name": "frexp_fcmp_ueq_1",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 27,
      "name": "frexp_fcmp_ule_0.5",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 28,
      "name": "frexp_fcmp_olt_1_multiple_conditions_edge_case_compare",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 29,
      "name": "frexp_fcmp_uge_1",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 30,
      "name": "frexp_fcmp_oge_1",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 31,
      "name": "frexp_fcmp_uge_0.5",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 32,
      "name": "frexp_fcmp_ugt_1",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 33,
      "name": "frexp_fcmp_ult_1",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 34,
      "name": "ldexp_v2f32_v2i32_fmul_crash",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    },
    {
      "index": 35,
      "name": "qnan_result_demands_snan_src",
      "tested": false,
      "uncovered_strategies": [
        "Narrow frexp exponent type wrapping",
        "OEQ/UEQ exact-bound exponent",
        "Zero limit pathological range",
        "Non-power-of-two bound off-by-one",
        "Inclusive one off-by-one overflow guard"
      ]
    }
  ],
  "all_tested": false,
  "message": "Some tests have not covered all Phase 1 strategies yet."
}

TOOL CALL: tests_manager

{"action":"get","index":17}

TOOL OUTPUT

{
  "test_name": "frexp_fcmp_ole_1",
  "test_body": "define float @frexp_fcmp_ole_1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {\n  %x.fabs = call float @llvm.fabs.f32(float %x)\n  %is.small = fcmp ole float %x.fabs, 1.000000e+00\n  br i1 %is.small, label %small, label %large\n\nsmall:                                            ; preds = %0\n  %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)\n  %exp = extractvalue { float, i32 } %frexp, 1\n  %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)\n  %is.inf = fcmp oeq float %scaled, +inf\n  %select = select i1 %is.inf, float 0.000000e+00, float %scaled\n  ret float %select\n\nlarge:                                            ; preds = %0\n  ret float 0.000000e+00\n}\n\n; Function Attrs: nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none)\ndeclare float @llvm.fabs.f32(float) #0\n\n; Function Attrs: nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none)\ndeclare { float, i32 } @llvm.frexp.f32.i32(float) #0\n\n; Function Attrs: nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none)\ndeclare float @llvm.ldexp.f32.i32(float, i32) #0\n\nattributes #0 = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }\n",
  "commands": [
    "opt -S -passes=instcombine < %s"
  ],
  "tested": false,
  "uncovered_strategies": [
    "Narrow frexp exponent type wrapping",
    "OEQ/UEQ exact-bound exponent",
    "Zero limit pathological range",
    "Non-power-of-two bound off-by-one",
    "Inclusive one off-by-one overflow guard"
  ]
}

TOOL CALL: verify

{"args":"-passes=instcombine","orig_ir":"```llvm\ndefine float @frexp_fcmp_ole_1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {\n  %x.fabs = call float @llvm.fabs.f32(float %x)\n  %is.small = fcmp ole float %x.fabs, 1.000000e+00\n  br i1 %is.small, label %small, label %large\n\nsmall:\n  %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)\n  %exp = extractvalue { float, i32 } %frexp, 1\n  %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)\n  %is.inf = fcmp oeq float %scaled, +inf\n  %select = select i1 %is.inf, float 0.000000e+00, float %scaled\n  ret float %select\n\nlarge:\n  ret float 0.000000e+00\n}\n\ndeclare float @llvm.fabs.f32(float) #0\ndeclare { float, i32 } @llvm.frexp.f32.i32(float) #0\ndeclare float @llvm.ldexp.f32.i32(float, i32) #0\nattributes #0 = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }\n```"}

TOOL OUTPUT

{"found": false, "tool": "verify", "args": "-passes=instcombine", "original_ir": "define float @frexp_fcmp_ole_1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {\n  %x.fabs = call float @llvm.fabs.f32(float %x)\n  %is.small = fcmp ole float %x.fabs, 1.000000e+00\n  br i1 %is.small, label %small, label %large\n\nsmall:\n  %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)\n  %exp = extractvalue { float, i32 } %frexp, 1\n  %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)\n  %is.inf = fcmp oeq float %scaled, +inf\n  %select = select i1 %is.inf, float 0.000000e+00, float %scaled\n  ret float %select\n\nlarge:\n  ret float 0.000000e+00\n}\n\ndeclare float @llvm.fabs.f32(float) #0\ndeclare { float, i32 } @llvm.frexp.f32.i32(float) #0\ndeclare float @llvm.ldexp.f32.i32(float, i32) #0\nattributes #0 = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }", "transformed_ir": "; ModuleID = '/data/tmp/tmp28icunly/orig.ll'\nsource_filename = \"/data/tmp/tmp28icunly/orig.ll\"\n\ndefine float @frexp_fcmp_ole_1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {\n  %x.fabs = call float @llvm.fabs.f32(float %x)\n  %is.small = fcmp ugt float %x.fabs, 1.000000e+00\n  br i1 %is.small, label %large, label %small\n\nsmall:                                            ; preds = %0\n  %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)\n  %exp = extractvalue { float, i32 } %frexp, 1\n  %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)\n  ret float %scaled\n\nlarge:                                            ; preds = %0\n  ret float 0.000000e+00\n}\n\n; Function Attrs: nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none)\ndeclare float @llvm.fabs.f32(float) #0\n\n; Function Attrs: nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none)\ndeclare { float, i32 } @llvm.frexp.f32.i32(float) #0\n\n; Function Attrs: nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none)\ndeclare float @llvm.ldexp.f32.i32(float, i32) #0\n\nattributes #0 = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }\n", "log": "----------------------------------------\ndeclare float @llvm.ldexp.f32.i32(float, i32) nofree willreturn memory(none)\n\ndefine float @frexp_fcmp_ole_1(float nofpclass(519) %x, float nofpclass(516) %not.inf) {\n#0:\n  %x.fabs = fabs float nofpclass(519) %x\n  %is.small = fcmp ole float %x.fabs, 1e+00\n  br i1 %is.small, label %small, label %large\n\nlarge:\n  ret float 0e+00\n\nsmall:\n  %frexp = frexp float nofpclass(519) %x\n  %exp = extractvalue {float, i32} %frexp, 1\n  %scaled = call float @llvm.ldexp.f32.i32(float nofpclass(516) %not.inf, i32 %exp) nofree willreturn memory(none)\n  %is.inf = fcmp oeq float %scaled, inf\n  %select = select i1 %is.inf, float 0e+00, float %scaled\n  ret float %select\n}\n=>\ndeclare float @llvm.ldexp.f32.i32(float, i32) nofree willreturn memory(none)\n\ndefine float @frexp_fcmp_ole_1(float nofpclass(519) %x, float nofpclass(516) %not.inf) {\n#0:\n  %x.fabs = fabs float nofpclass(519) %x\n  %is.small = fcmp ugt float %x.fabs, 1e+00\n  br i1 %is.small, label %large, label %small\n\nsmall:\n  %frexp = frexp float nofpclass(519) %x\n  %exp = extractvalue {float, i32} %frexp, 1\n  %scaled = call float @llvm.ldexp.f32.i32(float nofpclass(516) %not.inf, i32 %exp) nofree willreturn memory(none)\n  ret float %scaled\n\nlarge:\n  ret float 0e+00\n}\nERROR: Couldn't prove the correctness of the transformation\nAlive2 approximated the semantics of the programs and therefore we\ncannot conclude whether the bug found is valid or not.\n\nApproximations done:\n - Unknown libcall: @llvm.ldexp.f32.i32\n\n\nSummary:\n  0 correct transformations\n  0 incorrect transformations\n  1 failed-to-prove transformations\n  0 Alive2 errors"}

TOOL CALL: difftest

{"action":"test","args":"-S -passes=instcombine","call_instr":"call float @frexp_fcmp_ole_1(float 1.000000e+00, float 0x47EFFFFFE0000000)","covered_strategy":"Inclusive one off-by-one overflow guard","is_bug":false,"orig_ir":"```llvm\ndefine float @frexp_fcmp_ole_1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {\n  %x.fabs = call float @llvm.fabs.f32(float %x)\n  %is.small = fcmp ole float %x.fabs, 1.000000e+00\n  br i1 %is.small, label %small, label %large\n\nsmall:\n  %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)\n  %exp = extractvalue { float, i32 } %frexp, 1\n  %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)\n  %is.inf = fcmp oeq float %scaled, +inf\n  %select = select i1 %is.inf, float 0.000000e+00, float %scaled\n  ret float %select\n\nlarge:\n  ret float 0.000000e+00\n}\n\ndeclare float @llvm.fabs.f32(float) #0\ndeclare { float, i32 } @llvm.frexp.f32.i32(float) #0\ndeclare float @llvm.ldexp.f32.i32(float, i32) #0\nattributes #0 = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }\n```","test_index":17,"thoughts":"Testing inclusive <= 1 off-by-one: x=1 gives frexp exp 1, and max finite ldexp by 1 overflows to +inf. Original selects 0 on inf; optimized removed guard and returns inf if patch is unsound.","use_lli":true}

TOOL OUTPUT

Error: [Errno 2] No such file or directory: 'bin/lli'

TOOL CALL: difftest

{"action":"test","args":"-S -passes=instcombine","call_instr":"call float @frexp_fcmp_ole_1(float 1.000000e+00, float 0x47EFFFFFE0000000)","covered_strategy":"Inclusive one off-by-one overflow guard","orig_ir":"```llvm\ndefine float @frexp_fcmp_ole_1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {\n  %x.fabs = call float @llvm.fabs.f32(float %x)\n  %is.small = fcmp ole float %x.fabs, 1.000000e+00\n  br i1 %is.small, label %small, label %large\n\nsmall:\n  %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)\n  %exp = extractvalue { float, i32 } %frexp, 1\n  %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)\n  %is.inf = fcmp oeq float %scaled, +inf\n  %select = select i1 %is.inf, float 0.000000e+00, float %scaled\n  ret float %select\n\nlarge:\n  ret float 0.000000e+00\n}\n\ndeclare float @llvm.fabs.f32(float) #0\ndeclare { float, i32 } @llvm.frexp.f32.i32(float) #0\ndeclare float @llvm.ldexp.f32.i32(float, i32) #0\nattributes #0 = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }\n```","test_index":17,"thoughts":"Testing inclusive <= 1 off-by-one: x=1 gives frexp exp 1, and max finite ldexp by 1 overflows to +inf. Original selects 0 on inf; optimized removed guard and returns inf if patch is unsound."}

TOOL OUTPUT

{"found": false, "tool": "difftest", "action": "test", "args": "-S -passes=instcombine", "original_ir": "\ndefine float @frexp_fcmp_ole_1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {\n  %x.fabs = call float @llvm.fabs.f32(float %x)\n  %is.small = fcmp ole float %x.fabs, 1.000000e+00\n  br i1 %is.small, label %small, label %large\n\nsmall:\n  %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)\n  %exp = extractvalue { float, i32 } %frexp, 1\n  %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)\n  %is.inf = fcmp oeq float %scaled, +inf\n  %select = select i1 %is.inf, float 0.000000e+00, float %scaled\n  ret float %select\n\nlarge:\n  ret float 0.000000e+00\n}\n\ndeclare float @llvm.fabs.f32(float) #0\ndeclare { float, i32 } @llvm.frexp.f32.i32(float) #0\ndeclare float @llvm.ldexp.f32.i32(float, i32) #0\nattributes #0 = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }\n\ndefine float @main(i32 %argc, ptr %argv) {\nentry:\n  %r = call float @frexp_fcmp_ole_1(float 1.000000e+00, float 0x47EFFFFFE0000000)\n  ret float %r\n}\n", "transformed_ir": "\n; ModuleID = '/data/tmp/tmp4jdpnvss/orig.ll'\nsource_filename = \"/data/tmp/tmp4jdpnvss/orig.ll\"\n\ndefine float @frexp_fcmp_ole_1(float nofpclass(nan inf) %x, float nofpclass(inf) %not.inf) {\n  %x.fabs = call float @llvm.fabs.f32(float %x)\n  %is.small = fcmp ugt float %x.fabs, 1.000000e+00\n  br i1 %is.small, label %large, label %small\n\nsmall:                                            ; preds = %0\n  %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x)\n  %exp = extractvalue { float, i32 } %frexp, 1\n  %scaled = call float @llvm.ldexp.f32.i32(float %not.inf, i32 %exp)\n  ret float %scaled\n\nlarge:                                            ; preds = %0\n  ret float 0.000000e+00\n}\n\n; Function Attrs: nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none)\ndeclare float @llvm.fabs.f32(float) #0\n\n; Function Attrs: nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none)\ndeclare { float, i32 } @llvm.frexp.f32.i32(float) #0\n\n; Function Attrs: nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none)\ndeclare float @llvm.ldexp.f32.i32(float, i32) #0\n\nattributes #0 = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }\n\ndefine float @main(i32 %argc, ptr %argv) {\nentry:\n  %r = call float @frexp_fcmp_ole_1(float 1.000000e+00, float 0x47EFFFFFE0000000)\n  ret float %r\n}\n", "log": {"original_test_output": {"timed_out": false, "return_code": 1, "stdout": "", "stderr": "/data/yunboni/projects/Archer/deps/llvm-ub-aware-interpreter/build/llubi_legacy: /data/tmp/tmpuj6dmvhu/orig.ll:11:37: error: expected value token\n  %is.inf = fcmp oeq float %scaled, +inf\n                                    ^", "executor": "llubi"}, "transformed_test_output": {"timed_out": false, "return_code": -6, "stdout": "", "stderr": "Unsupported intrinsic: llvm.frexp.f32.i32\nPLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace and instructions to reproduce the bug.\nStack dump:\n0.\tProgram arguments: /data/yunboni/projects/Archer/deps/llvm-ub-aware-interpreter/build/llubi_legacy /data/tmp/tmpuj6dmvhu/transformed.ll\n #0 0x000071b0db868a68 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/data/yunboni/utils/compilers/llvm_latest_llubi/lib/libLLVM.so.23.0git+0x868a68)\n #1 0x000071b0db8658e5 llvm::sys::RunSignalHandlers() (/data/yunboni/utils/compilers/llvm_latest_llubi/lib/libLLVM.so.23.0git+0x8658e5)\n #2 0x000071b0db8698c1 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0\n #3 0x000071b0da845330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)\n #4 0x000071b0da89eb2c __pthread_kill_implementation ./nptl/pthread_kill.c:44:76\n #5 0x000071b0da89eb2c __pthread_kill_internal ./nptl/pthread_kill.c:78:10\n #6 0x000071b0da89eb2c pthread_kill ./nptl/pthread_kill.c:89:10\n #7 0x000071b0da84527e raise ./signal/../sysdeps/posix/raise.c:27:6\n #8 0x000071b0da8288ff abort ./stdlib/abort.c:81:7\n #9 0x00005d4c1637770c UBAwareInterpreter::callIntrinsic(llvm::IntrinsicInst&, llvm::SmallVectorImpl<AnyValue>&) (/data/yunboni/projects/Archer/deps/llvm-ub-aware-interpreter/build/llubi_legacy+0x3b70c)\n#10 0x00005d4c1637e488 UBAwareInterpreter::call(llvm::Function*, llvm::CallBase*, llvm::SmallVectorImpl<AnyValue>&) (/data/yunboni/projects/Archer/deps/llvm-ub-aware-interpreter/build/llubi_legacy+0x42488)\n#11 0x00005d4c1638154c UBAwareInterpreter::handleCall(llvm::CallBase&) (/data/yunboni/projects/Archer/deps/llvm-ub-aware-interpreter/build/llubi_legacy+0x4554c)\n#12 0x00005d4c16381a2f UBAwareInterpreter::visitCallInst(llvm::CallInst&) (/data/yunboni/projects/Archer/deps/llvm-ub-aware-interpreter/build/llubi_legacy+0x45a2f)\n#13 0x00005d4c1637ea64 UBAwareInterpreter::call(llvm::Function*, llvm::CallBase*, llvm::SmallVectorImpl<AnyValue>&) (/data/yunboni/projects/Archer/deps/llvm-ub-aware-interpreter/build/llubi_legacy+0x42a64)\n#14 0x00005d4c1638154c UBAwareInterpreter::handleCall(llvm::CallBase&) (/data/yunboni/projects/Archer/deps/llvm-ub-aware-interpreter/build/llubi_legacy+0x4554c)\n#15 0x00005d4c16381a2f UBAwareInterpreter::visitCallInst(llvm::CallInst&) (/data/yunboni/projects/Archer/deps/llvm-ub-aware-interpreter/build/llubi_legacy+0x45a2f)\n#16 0x00005d4c1637ea64 UBAwareInterpreter::call(llvm::Function*, llvm::CallBase*, llvm::SmallVectorImpl<AnyValue>&) (/data/yunboni/projects/Archer/deps/llvm-ub-aware-interpreter/build/llubi_legacy+0x42a64)\n#17 0x00005d4c163821b7 UBAwareInterpreter::runMain() (/data/yunboni/projects/Archer/deps/llvm-ub-aware-interpreter/build/llubi_legacy+0x461b7)\n#18 0x00005d4c1634beab main (/data/yunboni/projects/Archer/deps/llvm-ub-aware-interpreter/build/llubi_legacy+0xfeab)\n#19 0x000071b0da82a1ca __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3\n#20 0x000071b0da82a28b call_init ./csu/../csu/libc-start.c:128:20\n#21 0x000071b0da82a28b __libc_start_main ./csu/../csu/libc-start.c:347:5\n#22 0x00005d4c1634c155 _start (/data/yunboni/projects/Archer/deps/llvm-ub-aware-interpreter/build/llubi_legacy+0x10155)", "executor": "llubi"}}, "thoughts": "Testing inclusive <= 1 off-by-one: x=1 gives frexp exp 1, and max finite ldexp by 1 overflows to +inf. Original selects 0 on inf; optimized removed guard and returns inf if patch is unsound.", "test_index": 17, "covered_strategy": "Inclusive one off-by-one overflow guard"}

TOOL CALL: verify

{"args":"-passes=instcombine","orig_ir":"```llvm\ndefine i1 @bug_ole_one_exp_le0(float nofpclass(nan inf) %x) {\nentry:\n  %abs = call float @llvm.fabs.f32(float %x)\n  %c = fcmp ole float %abs, 1.0\n  br i1 %c, label %small, label %large\nsmall:\n  %fx = call { float, i32 } @llvm.frexp.f32.i32(float %x)\n  %e = extractvalue { float, i32 } %fx, 1\n  %r = icmp sle i32 %e, 0\n  ret i1 %r\nlarge:\n  ret i1 false\n}\ndeclare float @llvm.fabs.f32(float) #0\ndeclare { float, i32 } @llvm.frexp.f32.i32(float) #0\nattributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }\n```"}

TOOL OUTPUT

{"found": true, "tool": "verify", "args": "-passes=instcombine", "original_ir": "define i1 @bug_ole_one_exp_le0(float nofpclass(nan inf) %x) {\nentry:\n  %abs = call float @llvm.fabs.f32(float %x)\n  %c = fcmp ole float %abs, 1.0\n  br i1 %c, label %small, label %large\nsmall:\n  %fx = call { float, i32 } @llvm.frexp.f32.i32(float %x)\n  %e = extractvalue { float, i32 } %fx, 1\n  %r = icmp sle i32 %e, 0\n  ret i1 %r\nlarge:\n  ret i1 false\n}\ndeclare float @llvm.fabs.f32(float) #0\ndeclare { float, i32 } @llvm.frexp.f32.i32(float) #0\nattributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }", "transformed_ir": "; ModuleID = '/data/tmp/tmp0upfw8ci/orig.ll'\nsource_filename = \"/data/tmp/tmp0upfw8ci/orig.ll\"\n\ndefine i1 @bug_ole_one_exp_le0(float nofpclass(nan inf) %x) {\nentry:\n  %abs = call float @llvm.fabs.f32(float %x)\n  %c = fcmp ugt float %abs, 1.000000e+00\n  br i1 %c, label %large, label %small\n\nsmall:                                            ; preds = %entry\n  ret i1 true\n\nlarge:                                            ; preds = %entry\n  ret i1 false\n}\n\n; Function Attrs: nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none)\ndeclare float @llvm.fabs.f32(float) #0\n\n; Function Attrs: nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none)\ndeclare { float, i32 } @llvm.frexp.f32.i32(float) #0\n\nattributes #0 = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }\n", "log": "----------------------------------------\ndefine i1 @bug_ole_one_exp_le0(float nofpclass(519) %x) {\nentry:\n  %abs = fabs float nofpclass(519) %x\n  %c = fcmp ole float %abs, 1e+00\n  br i1 %c, label %small, label %large\n\nlarge:\n  ret i1 0\n\nsmall:\n  %fx = frexp float nofpclass(519) %x\n  %e = extractvalue {float, i32} %fx, 1\n  %r = icmp sle i32 %e, 0\n  ret i1 %r\n}\n=>\ndefine i1 @bug_ole_one_exp_le0(float nofpclass(519) %x) {\nentry:\n  %abs = fabs float nofpclass(519) %x\n  %c = fcmp ugt float %abs, 1e+00\n  br i1 %c, label %large, label %small\n\nsmall:\n  ret i1 1\n\nlarge:\n  ret i1 0\n}\nTransformation doesn't verify!\n\nERROR: Value mismatch\n\nExample:\nfloat nofpclass(519) %x = #x3f800000 (1e+00)\n\nSource:\nfloat %abs = #x3f800000 (1e+00)\ni1 %c = #x1 (1)\n  >> Jump to %small\n{float, i32} %fx = { #x3f000000 (5e-01), #x00000001 (1) }\ni32 %e = #x00000001 (1)\ni1 %r = #x0 (0)\n\nTarget:\nfloat %abs = #x3f800000 (1e+00)\ni1 %c = #x0 (0)\n  >> Jump to %small\nSource value: #x0 (0)\nTarget value: #x1 (1)\n\nSummary:\n  0 correct transformations\n  1 incorrect transformations\n  0 failed-to-prove transformations\n  0 Alive2 errors"}

TOOL CALL: report

{"force":true,"test":["```llvm\ndefine i1 @bug_ole_one_exp_le0(float nofpclass(nan inf) %x) {\nentry:\n  %abs = call float @llvm.fabs.f32(float %x)\n  %c = fcmp ole float %abs, 1.0\n  br i1 %c, label %small, label %large\n\nsmall:\n  %fx = call { float, i32 } @llvm.frexp.f32.i32(float %x)\n  %e = extractvalue { float, i32 } %fx, 1\n  %r = icmp sle i32 %e, 0\n  ret i1 %r\n\nlarge:\n  ret i1 false\n}\n\ndeclare float @llvm.fabs.f32(float) #0\ndeclare { float, i32 } @llvm.frexp.f32.i32(float) #0\nattributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }\n```","opt -S -passes=instcombine repro.ll"],"thoughts":"## Bug Triggering Analysis\nThe patch infers the exponent range of `llvm.frexp` from a dominating `fabs(x) <= 1.0` condition by using `ilogb(1.0) == 0` as the maximum exponent. This is off by one for nonzero finite inputs: `frexp(1.0)` returns mantissa `0.5` and exponent `1`. The reduced test makes this observable with `icmp sle i32 %e, 0`. InstCombine transforms the guarded block to `ret i1 true`, but Alive2 produces the counterexample `x = 1.0`, where the original returns false.\n\nAlive2 verification result:\n- Command: `alive-tv -passes=instcombine`\n- Result: incorrect transformation\n- Counterexample: `%x = 1.0f`\n- Source: `%e = 1`, `%r = false`\n- Target: `true`\n\n## Fix Weakness Analysis\nThe weakness is in `computeKnownExponentRangeFromContext`: it treats `ilogb(K)` as an inclusive upper bound for the frexp exponent when the path implies `fabs(x) <= K`. For finite nonzero values, frexp's exponent is `ilogb(x) + 1`, so inclusive/equality predicates at the boundary are unsound. The same issue likely affects `oeq/ueq` and non-power-of-two constants such as `0.75`, and zero requires special handling because `ilogb(0.0)` returns an error sentinel while `frexp(0.0)` returns exponent `0`."}

TOOL OUTPUT

{
  "test": [
    "```llvm\ndefine i1 @bug_ole_one_exp_le0(float nofpclass(nan inf) %x) {\nentry:\n  %abs = call float @llvm.fabs.f32(float %x)\n  %c = fcmp ole float %abs, 1.0\n  br i1 %c, label %small, label %large\n\nsmall:\n  %fx = call { float, i32 } @llvm.frexp.f32.i32(float %x)\n  %e = extractvalue { float, i32 } %fx, 1\n  %r = icmp sle i32 %e, 0\n  ret i1 %r\n\nlarge:\n  ret i1 false\n}\n\ndeclare float @llvm.fabs.f32(float) #0\ndeclare { float, i32 } @llvm.frexp.f32.i32(float) #0\nattributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }\n```",
    "opt -S -passes=instcombine repro.ll"
  ],
  "thoughts": "## Bug Triggering Analysis\nThe patch infers the exponent range of `llvm.frexp` from a dominating `fabs(x) <= 1.0` condition by using `ilogb(1.0) == 0` as the maximum exponent. This is off by one for nonzero finite inputs: `frexp(1.0)` returns mantissa `0.5` and exponent `1`. The reduced test makes this observable with `icmp sle i32 %e, 0`. InstCombine transforms the guarded block to `ret i1 true`, but Alive2 produces the counterexample `x = 1.0`, where the original returns false.\n\nAlive2 verification result:\n- Command: `alive-tv -passes=instcombine`\n- Result: incorrect transformation\n- Counterexample: `%x = 1.0f`\n- Source: `%e = 1`, `%r = false`\n- Target: `true`\n\n## Fix Weakness Analysis\nThe weakness is in `computeKnownExponentRangeFromContext`: it treats `ilogb(K)` as an inclusive upper bound for the frexp exponent when the path implies `fabs(x) <= K`. For finite nonzero values, frexp's exponent is `ilogb(x) + 1`, so inclusive/equality predicates at the boundary are unsound. The same issue likely affects `oeq/ueq` and non-power-of-two constants such as `0.75`, and zero requires special handling because `ilogb(0.0)` returns an error sentinel while `frexp(0.0)` returns exponent `0`.",
  "force": true
}