[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