[llvm-branch-commits] [llvm] InstCombine: Handle fdiv in SimplifyDemandedFPClass (PR #175946)

Yingwei Zheng via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Jan 14 10:08:46 PST 2026


================
@@ -2342,6 +2342,136 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 
     return nullptr;
   }
+  case Instruction::FDiv: {
+    Value *X = I->getOperand(0);
+    Value *Y = I->getOperand(1);
+    if (X == Y && isGuaranteedNotToBeUndef(X, SQ.AC, CxtI, SQ.DT, Depth + 1)) {
+      // If the source is 0, inf or nan, the result is a nan
+
+      Value *IsZeroOrNan = Builder.CreateFCmpFMF(
+          FCmpInst::FCMP_UEQ, I->getOperand(0), ConstantFP::getZero(VTy), FMF);
+
+      Value *Fabs =
+          Builder.CreateUnaryIntrinsic(Intrinsic::fabs, I->getOperand(0), FMF);
+      Value *IsInfOrNan = Builder.CreateFCmpFMF(
+          FCmpInst::FCMP_UEQ, Fabs, ConstantFP::getInfinity(VTy), FMF);
+
+      Value *IsInfOrZeroOrNan = Builder.CreateOr(IsInfOrNan, IsZeroOrNan);
+
+      return Builder.CreateSelectFMF(
+          IsInfOrZeroOrNan, ConstantFP::getQNaN(VTy),
+          ConstantFP::get(
+              VTy, APFloat::getOne(VTy->getScalarType()->getFltSemantics())),
+          FMF);
+    }
+
+    Type *EltTy = VTy->getScalarType();
+    DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
+
+    // Every output class could require denormal inputs (except for the
+    // degenerate case of only-nan results, without DAZ).
+    FPClassTest SrcDemandedMask = (DemandedMask & fcNan) | fcSubnormal;
+
+    // Normal inputs may result in underflow.
+    // x / x = 1.0 for non0/inf/nan
+    // -x = +y / -z
+    // -x = -y / +z
+    if (DemandedMask & (fcSubnormal | fcNormal))
+      SrcDemandedMask |= fcNormal;
+
+    if (DemandedMask & fcNan) {
+      // 0 / 0 = nan
+      // inf / inf = nan
+
+      // Subnormal is added in case of DAZ, but this isn't strictly
+      // necessary. Every other input class implies a possible subnormal source,
+      // so this only could matter in the degenerate case of only-nan results.
+      SrcDemandedMask |= fcZero | fcInf;
+    }
+
+    // Zero outputs may be the result of underflow.
+    if (DemandedMask & fcZero)
+      SrcDemandedMask |= fcNormal | fcSubnormal;
+
+    FPClassTest LHSDemandedMask = SrcDemandedMask;
+    FPClassTest RHSDemandedMask = SrcDemandedMask;
+
+    // 0 / inf = 0
+    if (DemandedMask & fcZero) {
+      assert((LHSDemandedMask & fcSubnormal) &&
+             "should not have to worry about daz here");
+      LHSDemandedMask |= fcZero;
+      RHSDemandedMask |= fcInf;
+    }
+
+    // x / 0 = inf
+    // large_normal / small_normal = inf
+    // inf / 1 = inf
+    // large_normal / subnormal = inf
+    if (DemandedMask & fcInf) {
+      LHSDemandedMask |= fcInf | fcNormal | fcSubnormal;
+      RHSDemandedMask |= fcZero | fcSubnormal | fcNormal;
+    }
+
+    KnownFPClass KnownLHS, KnownRHS;
+    if (SimplifyDemandedFPClass(I, 0, LHSDemandedMask, KnownLHS, Depth + 1) ||
+        SimplifyDemandedFPClass(I, 1, RHSDemandedMask, KnownRHS, Depth + 1))
+      return I;
+
+    bool ResultNotNan = (DemandedMask & fcNan) == fcNone;
+    bool ResultNotInf = (DemandedMask & fcInf) == fcNone;
+    if (ResultNotNan) {
+      KnownLHS.knownNot(fcNan);
+      KnownRHS.knownNot(fcNan);
+    }
+
+    // nsz [+-]0 / x -> 0
+    if (FMF.noSignedZeros() && KnownLHS.isKnownAlways(fcZero | fcNan) &&
----------------
dtcxzyw wrote:

nan / non-nan still produces nan.

https://github.com/llvm/llvm-project/pull/175946


More information about the llvm-branch-commits mailing list