[llvm] [InstCombine] Add select to worklist when demanded FP class adds nsz (PR #222847)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 10 22:57:23 PDT 2026
https://github.com/itsvineet99 created https://github.com/llvm/llvm-project/pull/222847
When InstCombine simplifies a demanded FP class and applies the nsz fast-math flag to an instruction, it previously failed to push the instruction's operands back onto the worklist.
If one of those operands was a select representing a hand-rolled min/max, this bookkeeping failure caused the select to be optimized during the fixpoint verification pass, resulting in a fatal compiler crash.
This patch ensures that when nsz is inferred and added, any select operands are explicitly pushed to the worklist for re-evaluation.
Fixes #222343
>From ebae652039d78bc0e8783818b0cd9d08e6a80a15 Mon Sep 17 00:00:00 2001
From: Vineet Dorikar <vineetdorikar06 at gmail.com>
Date: Fri, 11 Sep 2026 11:19:56 +0530
Subject: [PATCH] [InstCombine] Add select to worklist when demanded FP class
adds nsz
When InstCombine simplifies a demanded FP class and applies the nsz fast-math flag to an instruction, it previously failed to push the instruction's operands back onto the worklist.
If one of those operands was a select representing a hand-rolled min/max, this bookkeeping failure caused the select to be optimized during the fixpoint verification pass, resulting in a fatal compiler crash.
This patch ensures that when nsz is inferred and added, any select operands are explicitly pushed to the worklist for re-evaluation.
Fixes #222343
---
.../InstCombineSimplifyDemanded.cpp | 12 +++++++++++
.../simplify-demanded-fpclass-maximum.ll | 21 +++++++++++++++++++
2 files changed, 33 insertions(+)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 1002f34de0b8e..c3d8d101c7890 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -3056,7 +3056,19 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
}
if (InferredFMF != FMF) {
+ bool AddedNSZ = !FMF.noSignedZeros() && InferredFMF.noSignedZeros();
CI->setFastMathFlags(InferredFMF);
+
+ // BUG FIX: If we just added the nsz (No Signed Zero) flag, the demanded
+ // FP class for our operands has changed. If an operand is a select,
+ // it may now be foldable into a maxnum/minnum. Push it to the worklist!
+ if (AddedNSZ) {
+ for (Use &Op : CI->operands()) {
+ if (auto *Sel = dyn_cast<SelectInst>(Op.get()))
+ Worklist.push(Sel);
+ }
+ }
+
return FPOp;
}
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximum.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximum.ll
index 8b8284e8a50ae..fff8a9b7aa9ad 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximum.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-maximum.ll
@@ -2192,3 +2192,24 @@ define nofpclass(snan) float @qnan_result_demands_snan_rhs(i1 %cond, float %unkn
attributes #0 = { denormal_fpenv(preservesign) }
attributes #1 = { denormal_fpenv(dynamic) }
+
+
+; nsf flag or something
+
+; Adapted from ret_always_positive_nonzero__maximum__not_zero_select_positive_or_unknown
+; in file Transforms/InstCombine/simplify-demanded-fpclass-maximum.ll
+
+define nofpclass(pinf pnorm psub) float @test_nofpclass_worklist_bug(float %unknown, float nofpclass(zero) %not.zero) {
+; CHECK-LABEL: define nofpclass(pinf psub pnorm) float @test_nofpclass_worklist_bug(
+; CHECK-SAME: float [[UNKNOWN:%.*]], float nofpclass(zero) [[NOT_ZERO:%.*]]) {
+; CHECK-NEXT: [[ALWAYS_POSITIVE:%.*]] = call float @returns_positive()
+; CHECK-NEXT: [[SELECT_RHS:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[ALWAYS_POSITIVE]], float [[UNKNOWN]])
+; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.maximum.f32(float [[NOT_ZERO]], float [[SELECT_RHS]])
+; CHECK-NEXT: ret float [[RESULT]]
+;
+ %always.positive = call float @returns_positive()
+ %cond = fcmp nnan ogt float %always.positive, %unknown
+ %select.rhs = select i1 %cond, float %always.positive, float %unknown
+ %result = call float @llvm.maximum.f32(float %not.zero, float %select.rhs)
+ ret float %result
+}
More information about the llvm-commits
mailing list