[llvm] [InstSimplify] Fold fsub X, X using known non-NaN/non-Inf facts (PR #200782)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 1 03:54:16 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: AnkitDubeycs25 (AnkitDubeycs25)
<details>
<summary>Changes</summary>
InstSimplify currently folds 'fsub nnan X, X' to 0.0, but does not perform the same simplification when ValueTracking can already prove that the operand is neither NaN nor Inf.
Extend the self-subtraction fold to use isKnownNeverInfOrNaN(), allowing InstSimplify to exploit facts derived from computeKnownFPClass, such as nofpclass(nan inf).
Add a regression test covering the missed optimization.
---
Full diff: https://github.com/llvm/llvm-project/pull/200782.diff
2 Files Affected:
- (modified) llvm/lib/Analysis/InstructionSimplify.cpp (+6-4)
- (added) llvm/test/Transforms/InstSimplify/fsub-selfsub-nofpclass.ll (+23)
``````````diff
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 59a213b47825a..1bd32ff285830 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -5938,11 +5938,13 @@ simplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF,
if (!isDefaultFPEnvironment(ExBehavior, Rounding))
return nullptr;
- if (FMF.noNaNs()) {
- // fsub nnan x, x ==> 0.0
- if (Op0 == Op1)
- return Constant::getNullValue(Op0->getType());
+ // fsub nnan x, x ==> 0.0
+ // fsub x, x ==> 0.0 if x is known never Inf or NaN
+ if (Op0 == Op1 &&
+ (FMF.noNaNs() || isKnownNeverInfOrNaN(Op0, Q)))
+ return Constant::getNullValue(Op0->getType());
+ if (FMF.noNaNs()) {
// With nnan: {+/-}Inf - X --> {+/-}Inf
if (match(Op0, m_Inf()))
return Op0;
diff --git a/llvm/test/Transforms/InstSimplify/fsub-selfsub-nofpclass.ll b/llvm/test/Transforms/InstSimplify/fsub-selfsub-nofpclass.ll
new file mode 100644
index 0000000000000..8c192a734f258
--- /dev/null
+++ b/llvm/test/Transforms/InstSimplify/fsub-selfsub-nofpclass.ll
@@ -0,0 +1,23 @@
+; RUN: opt -S -passes=instcombine %s -o - | FileCheck %s
+
+declare double @llvm.fmuladd.f64(double, double, double)
+
+define double @missed_selfsub_consumer(
+ float nofpclass(nan inf) %x,
+ double %scale,
+ double %acc) {
+entry:
+ %d = fsub float %x, %x
+ %de = fpext float %d to double
+ %mul = fmul double %scale, %de
+ %fma = call double @llvm.fmuladd.f64(
+ double %mul,
+ double %de,
+ double %acc)
+ ret double %fma
+}
+
+; CHECK-LABEL: @missed_selfsub_consumer(
+; CHECK-NOT: fsub
+; CHECK-NOT: fpext
+; CHECK: fmul double %scale, 0.000000e+00
\ No newline at end of file
``````````
</details>
https://github.com/llvm/llvm-project/pull/200782
More information about the llvm-commits
mailing list