[llvm-branch-commits] [llvm] InstCombine: Clean up SimplifyDemandedFPClass use context application (PR #176886)
Matt Arsenault via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Jan 20 02:07:16 PST 2026
https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/176886
Clean up some now redundant propagation of known-result to known-source
cases. Also move the application of the demanded mask to individual
cases, since the intermediate results are often used.
>From 86cb3cac1913838cf0a04470b73fedf520f4c096 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Tue, 20 Jan 2026 09:43:57 +0100
Subject: [PATCH] InstCombine: Clean up SimplifyDemandedFPClass use context
application
Clean up some now redundant propagation of known-result to known-source
cases. Also move the application of the demanded mask to individual
cases, since the intermediate results are often used.
---
.../InstCombineSimplifyDemanded.cpp | 127 +++++++-----------
1 file changed, 51 insertions(+), 76 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index b83cb48b8cd8f..1309bf55b2593 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "InstCombineInternal.h"
-#include "llvm/ADT/ScopeExit.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/IntrinsicInst.h"
@@ -2055,6 +2054,7 @@ static Value *simplifyDemandedFPClassFabs(KnownFPClass &Known, Value *Src,
return Src;
Known = KnownFPClass::fabs(KnownSrc);
+ Known.knownNot(~DemandedMask);
return nullptr;
}
@@ -2063,15 +2063,6 @@ simplifyDemandedFPClassMinMax(KnownFPClass &Known, Intrinsic::ID IID,
const CallInst *CI, FPClassTest DemandedMask,
KnownFPClass KnownLHS, KnownFPClass KnownRHS,
const Function &F, bool NSZ) {
- const bool PropagateNaN =
- IID == Intrinsic::maximum || IID == Intrinsic::minimum;
-
- /// Propagate nnan-ness to simplify edge case checks.
- if (PropagateNaN && (DemandedMask & fcNan) == fcNone) {
- KnownLHS.knownNot(fcNan);
- KnownRHS.knownNot(fcNan);
- }
-
bool OrderedZeroSign = !NSZ;
KnownFPClass::MinMaxKind OpKind;
@@ -2147,9 +2138,9 @@ simplifyDemandedFPClassMinMax(KnownFPClass &Known, Intrinsic::ID IID,
Type *EltTy = CI->getType()->getScalarType();
DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
Known = KnownFPClass::minMaxLike(KnownLHS, KnownRHS, OpKind, Mode);
+ Known.knownNot(~DemandedMask);
- FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
- return getFPClassConstant(CI->getType(), ValidResults,
+ return getFPClassConstant(CI->getType(), Known.KnownFPClasses,
/*IsCanonicalizing=*/true);
}
@@ -2199,16 +2190,13 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
DemandedMask = adjustDemandedMaskFromFlags(DemandedMask, FMF);
}
- // Remove unwanted results from the computed result
- scope_exit ApplyDemandedMask(
- [=, &Known]() { Known.knownNot(~DemandedMask); });
-
switch (I->getOpcode()) {
case Instruction::FNeg: {
if (SimplifyDemandedFPClass(I, 0, llvm::fneg(DemandedMask), Known,
Depth + 1))
return I;
Known.fneg();
+ Known.knownNot(~DemandedMask);
break;
}
case Instruction::FAdd: {
@@ -2274,17 +2262,14 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
Known = KnownFPClass::fadd(KnownLHS, KnownRHS, Mode);
}
- FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
- if (Constant *SingleVal =
- getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true))
+ Known.knownNot(~DemandedMask);
+
+ if (Constant *SingleVal = getFPClassConstant(VTy, Known.KnownFPClasses,
+ /*IsCanonicalizing=*/true))
return SingleVal;
// Propagate known result to simplify edge case checks.
bool ResultNotNan = (DemandedMask & fcNan) == fcNone;
- if (ResultNotNan) {
- KnownLHS.knownNot(fcNan);
- KnownRHS.knownNot(fcNan);
- }
// With nnan: X + {+/-}Inf --> {+/-}Inf
if (ResultNotNan && KnownRHS.isKnownAlways(fcInf | fcNan) &&
@@ -2296,8 +2281,8 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
KnownRHS.isKnownNever(fcNan))
return I->getOperand(0);
- FastMathFlags InferredFMF =
- inferFastMathValueFlagsBinOp(FMF, ValidResults, KnownLHS, KnownRHS);
+ FastMathFlags InferredFMF = inferFastMathValueFlagsBinOp(
+ FMF, Known.KnownFPClasses, KnownLHS, KnownRHS);
if (InferredFMF != FMF) {
I->setFastMathFlags(InferredFMF);
return I;
@@ -2345,21 +2330,14 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
Known = KnownFPClass::square(KnownLHS, Mode);
+ Known.knownNot(~DemandedMask);
- // Propagate known result to simplify edge case checks.
- if ((DemandedMask & fcNan) == fcNone)
- Known.knownNot(fcNan);
- if ((DemandedMask & fcPosInf) == fcNone)
- Known.knownNot(fcInf);
-
- FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
- if (Constant *Folded =
- getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true))
+ if (Constant *Folded = getFPClassConstant(VTy, Known.KnownFPClasses,
+ /*IsCanonicalizing=*/true))
return Folded;
- if (Known.isKnownAlways(fcPosZero | fcPosInf | fcNan)) {
- assert(KnownLHS.isKnownNever(fcPosNormal));
-
+ if (Known.isKnownAlways(fcPosZero | fcPosInf | fcNan) &&
+ KnownLHS.isKnownNever(fcSubnormal | fcNormal)) {
// We can skip the fabs if the source was already known positive.
if (KnownLHS.isKnownAlways(fcPositive))
return X;
@@ -2380,12 +2358,6 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
SimplifyDemandedFPClass(I, 0, SrcDemandedMask, KnownLHS, Depth + 1))
return I;
- // Propagate nnan-ness to sources to simplify source checks.
- if ((DemandedMask & fcNan) == fcNone) {
- KnownLHS.knownNot(fcNan);
- KnownRHS.knownNot(fcNan);
- }
-
if (FMF.noInfs()) {
// Flag implies inputs cannot be infinity.
KnownLHS.knownNot(fcInf);
@@ -2457,14 +2429,14 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
}
Known = KnownFPClass::fmul(KnownLHS, KnownRHS, Mode);
+ Known.knownNot(~DemandedMask);
- FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
- if (Constant *SingleVal =
- getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true))
+ if (Constant *SingleVal = getFPClassConstant(VTy, Known.KnownFPClasses,
+ /*IsCanonicalizing=*/true))
return SingleVal;
- FastMathFlags InferredFMF =
- inferFastMathValueFlagsBinOp(FMF, ValidResults, KnownLHS, KnownRHS);
+ FastMathFlags InferredFMF = inferFastMathValueFlagsBinOp(
+ FMF, Known.KnownFPClasses, KnownLHS, KnownRHS);
if (InferredFMF != FMF) {
I->setFastMathFlags(InferredFMF);
return I;
@@ -2490,9 +2462,10 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
I->getOperand(0)->getType()->getScalarType()->getFltSemantics();
Known = KnownFPClass::fpext(KnownSrc, DstTy, SrcTy);
- FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+ Known.knownNot(~DemandedMask);
- return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+ return getFPClassConstant(VTy, Known.KnownFPClasses,
+ /*IsCanonicalizing=*/true);
}
case Instruction::Call: {
CallInst *CI = cast<CallInst>(I);
@@ -2557,6 +2530,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
}
Known.copysign(KnownSign);
+ Known.knownNot(~DemandedMask);
break;
}
case Intrinsic::maximum:
@@ -2675,10 +2649,6 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
if (SimplifyDemandedFPClass(I, 0, SrcDemandedMask, KnownSrc, Depth + 1))
return I;
- /// Propagate nnan-ness to simplify edge case checks.
- if ((DemandedMask & fcNan) == fcNone)
- KnownSrc.knownNot(fcNan);
-
// exp(+/-0) = 1
if (KnownSrc.isKnownAlways(fcZero))
return ConstantFP::get(VTy, 1.0);
@@ -2717,9 +2687,10 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
}
Known = KnownFPClass::exp(KnownSrc);
+ Known.knownNot(~DemandedMask);
- FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
- return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+ return getFPClassConstant(VTy, Known.KnownFPClasses,
+ /*IsCanonicalizing=*/true);
}
case Intrinsic::log:
case Intrinsic::log2:
@@ -2754,9 +2725,10 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
return I;
Known = KnownFPClass::log(KnownSrc, Mode);
+ Known.knownNot(~DemandedMask);
- FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
- return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+ return getFPClassConstant(VTy, Known.KnownFPClasses,
+ /*IsCanonicalizing=*/true);
}
case Intrinsic::sqrt: {
FPClassTest DemandedSrcMask =
@@ -2782,9 +2754,9 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
return ConstantFP::getQNaN(VTy);
Known = KnownFPClass::sqrt(KnownSrc, Mode);
- FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+ Known.knownNot(~DemandedMask);
- if (ValidResults == fcZero) {
+ if (Known.KnownFPClasses == fcZero) {
if (FMF.noSignedZeros())
return ConstantFP::getZero(VTy);
@@ -2794,7 +2766,8 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
return Copysign;
}
- return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+ return getFPClassConstant(VTy, Known.KnownFPClasses,
+ /*IsCanonicalizing=*/true);
}
case Intrinsic::trunc:
case Intrinsic::floor:
@@ -2820,10 +2793,6 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
if (KnownSrc.isKnownAlways(fcInf | fcNan | fcZero))
return CI->getArgOperand(0);
- // Propagate nnan-ness to source to simplify source checks.
- if ((DemandedMask & fcNan) == fcNone)
- KnownSrc.knownNot(fcNan);
-
bool IsRoundNearestOrTrunc =
IID == Intrinsic::round || IID == Intrinsic::roundeven ||
IID == Intrinsic::nearbyint || IID == Intrinsic::rint ||
@@ -2848,9 +2817,10 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
KnownSrc, IID == Intrinsic::trunc,
VTy->getScalarType()->isMultiUnitFPType());
- FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
- if (Constant *SingleVal =
- getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true))
+ Known.knownNot(~DemandedMask);
+
+ if (Constant *SingleVal = getFPClassConstant(VTy, Known.KnownFPClasses,
+ /*IsCanonicalizing=*/true))
return SingleVal;
if ((IID == Intrinsic::trunc || IsRoundNearestOrTrunc) &&
@@ -2904,9 +2874,9 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
// Perform the canonicalization to see if this folded to a constant.
Known = KnownFPClass::canonicalize(KnownSrc, Mode);
+ Known.knownNot(~DemandedMask);
- if (Constant *SingleVal =
- getFPClassConstant(VTy, DemandedMask & Known.KnownFPClasses))
+ if (Constant *SingleVal = getFPClassConstant(VTy, Known.KnownFPClasses))
return SingleVal;
// For IEEE handling, there is only a bit change for nan inputs, so we
@@ -2926,6 +2896,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
}
default:
Known = computeKnownFPClass(I, DemandedMask, CxtI, Depth + 1);
+ Known.knownNot(~DemandedMask);
break;
}
@@ -2948,12 +2919,14 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
adjustKnownFPClassForSelectArm(KnownRHS, I->getOperand(0), I->getOperand(2),
/*Invert=*/true, SQ, Depth);
Known = KnownLHS.intersectWith(KnownRHS);
+ Known.knownNot(~DemandedMask);
break;
}
case Instruction::ExtractElement: {
// TODO: Handle demanded element mask
if (SimplifyDemandedFPClass(I, 0, DemandedMask, Known, Depth + 1))
return I;
+ Known.knownNot(~DemandedMask);
break;
}
case Instruction::InsertElement: {
@@ -2964,6 +2937,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
// TODO: Use demanded elements logic from computeKnownFPClass
Known = KnownVec | KnownInserted;
+ Known.knownNot(~DemandedMask);
break;
}
case Instruction::ShuffleVector: {
@@ -2975,14 +2949,16 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
// TODO: This is overly conservative and should consider demanded elements,
// and splats.
Known = KnownLHS | KnownRHS;
+ Known.knownNot(~DemandedMask);
break;
}
default:
Known = computeKnownFPClass(I, DemandedMask, CxtI, Depth + 1);
+ Known.knownNot(~DemandedMask);
break;
}
- return getFPClassConstant(VTy, DemandedMask & Known.KnownFPClasses);
+ return getFPClassConstant(VTy, Known.KnownFPClasses);
}
/// Helper routine of SimplifyDemandedUseFPClass. It computes Known
@@ -2997,10 +2973,6 @@ Value *InstCombinerImpl::SimplifyMultipleUseDemandedFPClass(
DemandedMask = adjustDemandedMaskFromFlags(DemandedMask, FMF);
}
- // Remove unwanted results from the computed result
- scope_exit ApplyDemandedMask(
- [=, &Known]() { Known.knownNot(~DemandedMask); });
-
switch (I->getOpcode()) {
case Instruction::Select: {
// TODO: Can we infer which side it came from based on adjusted result
@@ -3021,6 +2993,7 @@ Value *InstCombinerImpl::SimplifyMultipleUseDemandedFPClass(
adjustKnownFPClassForSelectArm(KnownRHS, I->getOperand(0), I->getOperand(2),
/*Invert=*/true, SQ, Depth);
Known = KnownLHS.intersectWith(KnownRHS);
+ Known.knownNot(~DemandedMask);
break;
}
case Instruction::FNeg: {
@@ -3055,6 +3028,7 @@ Value *InstCombinerImpl::SimplifyMultipleUseDemandedFPClass(
return Src;
Known = KnownFPClass::fneg(KnownFPClass::fabs(KnownSrc));
+ Known.knownNot(~DemandedMask);
break;
}
case Instruction::Call: {
@@ -3096,10 +3070,11 @@ Value *InstCombinerImpl::SimplifyMultipleUseDemandedFPClass(
}
default:
Known = computeKnownFPClass(I, DemandedMask, CxtI, Depth + 1);
+ Known.knownNot(~DemandedMask);
break;
}
- return getFPClassConstant(I->getType(), DemandedMask & Known.KnownFPClasses);
+ return getFPClassConstant(I->getType(), Known.KnownFPClasses);
}
bool InstCombinerImpl::SimplifyDemandedFPClass(Instruction *I, unsigned OpNo,
More information about the llvm-branch-commits
mailing list