[llvm] InstCombine: Prepare to handle multiple uses in SimplifyDemandedFPClass (PR #174863)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 7 13:09:40 PST 2026
https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/174863
Follow the structure of SimplifyDemandedBits. Doesn't handle anything
in the multiple use case for now, and continues just calling
computeKnownFPClass.
>From 8ba8c78e7f94c0d6b2443a741886dbc28a11f653 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 1 Jan 2026 11:18:25 +0100
Subject: [PATCH] InstCombine: Prepare to handle multiple uses in
SimplifyDemandedFPClass
Follow the structure of SimplifyDemandedBits. Doesn't handle anything
in the multiple use case for now, and continues just calling
computeKnownFPClass.
---
.../InstCombine/InstCombineInternal.h | 7 +-
.../InstCombineSimplifyDemanded.cpp | 100 ++++++++++++------
.../InstCombine/InstructionCombining.cpp | 8 +-
3 files changed, 75 insertions(+), 40 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
index 654af16191c8d..8c8b300bb2002 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -611,9 +611,14 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
/// Attempts to replace V with a simpler value based on the demanded
/// floating-point classes
- Value *SimplifyDemandedUseFPClass(Value *V, FPClassTest DemandedMask,
+ Value *SimplifyDemandedUseFPClass(Instruction *I, FPClassTest DemandedMask,
KnownFPClass &Known, Instruction *CxtI,
unsigned Depth = 0);
+ Value *SimplifyMultipleUseDemandedFPClass(Instruction *I,
+ FPClassTest DemandedMask,
+ KnownFPClass &Known,
+ Instruction *CxtI, unsigned Depth);
+
bool SimplifyDemandedFPClass(Instruction *I, unsigned Op,
FPClassTest DemandedMask, KnownFPClass &Known,
unsigned Depth = 0);
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index e816e943380f5..7430fa4d253d8 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2033,45 +2033,16 @@ static Constant *getFPClassConstant(Type *Ty, FPClassTest Mask,
}
}
-Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Value *V,
+Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
FPClassTest DemandedMask,
KnownFPClass &Known,
Instruction *CxtI,
unsigned Depth) {
assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth");
- Type *VTy = V->getType();
-
assert(Known == KnownFPClass() && "expected uninitialized state");
+ assert(I->hasOneUse() && "wrong version called");
- if (DemandedMask == fcNone)
- return isa<UndefValue>(V) ? nullptr : PoisonValue::get(VTy);
-
- if (Depth == MaxAnalysisRecursionDepth)
- return nullptr;
-
- Instruction *I = dyn_cast<Instruction>(V);
- if (!I) {
- // Handle constants and arguments
- Known = computeKnownFPClass(V, fcAllFlags, CxtI, Depth + 1);
-
- FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
- if (ValidResults == fcNone)
- return isa<UndefValue>(V) ? nullptr : PoisonValue::get(VTy);
-
- // Do not try to replace values which are already constants (unless we are
- // folding to poison). Doing so could promote poison elements to non-poison
- // constants.
- if (isa<Constant>(V))
- return nullptr;
-
- Value *FoldedToConst = getFPClassConstant(VTy, ValidResults);
- return FoldedToConst == V ? nullptr : FoldedToConst;
- }
-
- if (!I->hasOneUse()) {
- Known = computeKnownFPClass(V, DemandedMask, CxtI, Depth + 1);
- return nullptr;
- }
+ Type *VTy = I->getType();
FastMathFlags FMF;
if (auto *FPOp = dyn_cast<FPMathOperator>(I)) {
@@ -2628,13 +2599,74 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Value *V,
return getFPClassConstant(VTy, DemandedMask & Known.KnownFPClasses);
}
+/// Helper routine of SimplifyDemandedUseFPClass. It computes Known
+/// floating-point classes. It also tries to handle simplifications that can be
+/// done based on DemandedMask, but without modifying the Instruction.
+Value *InstCombinerImpl::SimplifyMultipleUseDemandedFPClass(
+ Instruction *I, FPClassTest DemandedMask, KnownFPClass &Known,
+ Instruction *CxtI, unsigned Depth) {
+ Known = computeKnownFPClass(I, DemandedMask, CxtI, Depth + 1);
+ return getFPClassConstant(I->getType(), DemandedMask & Known.KnownFPClasses);
+}
+
bool InstCombinerImpl::SimplifyDemandedFPClass(Instruction *I, unsigned OpNo,
FPClassTest DemandedMask,
KnownFPClass &Known,
unsigned Depth) {
Use &U = I->getOperandUse(OpNo);
- Value *NewVal =
- SimplifyDemandedUseFPClass(U.get(), DemandedMask, Known, I, Depth);
+ Value *V = U.get();
+ Type *VTy = V->getType();
+
+ if (DemandedMask == fcNone) {
+ if (isa<UndefValue>(V))
+ return false;
+ replaceUse(U, PoisonValue::get(VTy));
+ return true;
+ }
+
+ // Handle constant
+ Instruction *VInst = dyn_cast<Instruction>(V);
+ if (!VInst) {
+ // Handle constants and arguments
+ Known = computeKnownFPClass(V, fcAllFlags, I, Depth);
+
+ FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+ if (ValidResults == fcNone) {
+ if (isa<UndefValue>(V))
+ return false;
+ replaceUse(U, PoisonValue::get(VTy));
+ return true;
+ }
+
+ // Do not try to replace values which are already constants (unless we are
+ // folding to poison). Doing so could promote poison elements to non-poison
+ // constants.
+ if (isa<Constant>(V))
+ return false;
+
+ Value *FoldedToConst = getFPClassConstant(VTy, ValidResults);
+ if (!FoldedToConst || FoldedToConst == V)
+ return false;
+
+ replaceUse(U, FoldedToConst);
+ return true;
+ }
+
+ if (Depth == MaxAnalysisRecursionDepth)
+ return false;
+
+ Value *NewVal;
+
+ if (VInst->hasOneUse()) {
+ // If the instruction has one use, we can directly simplify it.
+ NewVal = SimplifyDemandedUseFPClass(VInst, DemandedMask, Known, I, Depth);
+ } else {
+ // If there are multiple uses of this instruction, then we can simplify
+ // VInst to some other value, but not modify the instruction.
+ NewVal = SimplifyMultipleUseDemandedFPClass(VInst, DemandedMask, Known, I,
+ Depth);
+ }
+
if (!NewVal)
return false;
if (Instruction *OpInst = dyn_cast<Instruction>(U))
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 49504b20fa1ec..d84d26df9bd20 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -4070,12 +4070,10 @@ Instruction *InstCombinerImpl::visitReturnInst(ReturnInst &RI) {
return nullptr;
KnownFPClass KnownClass;
- Value *Simplified =
- SimplifyDemandedUseFPClass(RetVal, ~ReturnClass, KnownClass, &RI);
- if (!Simplified)
- return nullptr;
+ if (SimplifyDemandedFPClass(&RI, 0, ~ReturnClass, KnownClass))
+ return &RI;
- return ReturnInst::Create(RI.getContext(), Simplified);
+ return nullptr;
}
// WARNING: keep in sync with SimplifyCFGOpt::simplifyUnreachable()!
More information about the llvm-commits
mailing list