[llvm] 48c0e99 - InstCombine: Filter reported classes from SimplifyDemandedFPClass (#176885)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 20 08:13:14 PST 2026
Author: Matt Arsenault
Date: 2026-01-20T17:13:09+01:00
New Revision: 48c0e9995a8979e0e100872e3740187af294aa5c
URL: https://github.com/llvm/llvm-project/commit/48c0e9995a8979e0e100872e3740187af294aa5c
DIFF: https://github.com/llvm/llvm-project/commit/48c0e9995a8979e0e100872e3740187af294aa5c.diff
LOG: InstCombine: Filter reported classes from SimplifyDemandedFPClass (#176885)
When reporting the known class result, apply the demanded mask to
filter out rejected cases. This can simplify known-source checks
further up the call stack. There are a few improved test diffs. This
does not yet try to clean up now redundant result checks.
Do an initial brute-force scope_exit to ensure these are cleared.
Later we can do a better job by pushing this into the individual
instruction cases.
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-canonicalize.ll
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fadd.ll
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll
llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-rounding-intrinsics.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index e175e4213c72a..b83cb48b8cd8f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "InstCombineInternal.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/IntrinsicInst.h"
@@ -2198,6 +2199,10 @@ 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,
@@ -2992,6 +2997,10 @@ 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
@@ -3113,9 +3122,9 @@ bool InstCombinerImpl::SimplifyDemandedFPClass(Instruction *I, unsigned OpNo,
if (!VInst) {
// Handle constants and arguments
Known = computeKnownFPClass(V, fcAllFlags, I, Depth);
+ Known.knownNot(~DemandedMask);
- FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
- if (ValidResults == fcNone) {
+ if (Known.KnownFPClasses == fcNone) {
if (isa<UndefValue>(V))
return false;
replaceUse(U, PoisonValue::get(VTy));
@@ -3128,7 +3137,7 @@ bool InstCombinerImpl::SimplifyDemandedFPClass(Instruction *I, unsigned OpNo,
if (isa<Constant>(V))
return false;
- Value *FoldedToConst = getFPClassConstant(VTy, ValidResults);
+ Value *FoldedToConst = getFPClassConstant(VTy, Known.KnownFPClasses);
if (!FoldedToConst || FoldedToConst == V)
return false;
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-canonicalize.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-canonicalize.ll
index c263fd0eee402..4ffba812418c3 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-canonicalize.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-canonicalize.ll
@@ -58,8 +58,7 @@ define nofpclass(nan zero) float @ret_nofpclass_nan_zero__canonicalize_select_su
; CHECK-SAME: float [[X:%.*]], i1 [[COND:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[SUB:%.*]] = call float @returns_sub_norm()
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[X]], float [[SUB]]
-; CHECK-NEXT: [[CANON:%.*]] = call float @llvm.canonicalize.f32(float [[SELECT]])
-; CHECK-NEXT: ret float [[CANON]]
+; CHECK-NEXT: ret float [[SELECT]]
;
%sub = call float @returns_sub_norm()
%select = select i1 %cond, float %x, float %sub
@@ -97,8 +96,7 @@ define nofpclass(nan zero) float @ret_nofpclass_nan_zero__canonicalize_select_su
; CHECK-LABEL: define nofpclass(nan zero) float @ret_nofpclass_nan_zero__canonicalize_select_sub_daz(
; CHECK-SAME: float [[X:%.*]], i1 [[COND:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[SUB:%.*]] = call float @returns_sub()
-; CHECK-NEXT: [[CANON:%.*]] = call float @llvm.canonicalize.f32(float [[X]])
-; CHECK-NEXT: ret float [[CANON]]
+; CHECK-NEXT: ret float [[X]]
;
%sub = call float @returns_sub()
%select = select i1 %cond, float %x, float %sub
@@ -353,8 +351,7 @@ define nofpclass(zero) float @ret_nofpclass_zero__canonicalize_nnan_src_ieee(flo
define nofpclass(zero) float @ret_nofpclass_zero__canonicalize_nnan_src_daz(float nofpclass(nan) %x, i1 %cond) #0 {
; CHECK-LABEL: define nofpclass(zero) float @ret_nofpclass_zero__canonicalize_nnan_src_daz(
; CHECK-SAME: float nofpclass(nan) [[X:%.*]], i1 [[COND:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[CANON:%.*]] = call float @llvm.canonicalize.f32(float [[X]])
-; CHECK-NEXT: ret float [[CANON]]
+; CHECK-NEXT: ret float [[X]]
;
%canon = call float @llvm.canonicalize.f32(float %x)
ret float %canon
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fadd.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fadd.ll
index 02a4fa5b52d10..ae9458cc1fe34 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fadd.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fadd.ll
@@ -63,7 +63,7 @@ define nofpclass(qnan inf zero sub norm) half @ret_only_snan(half %x, half %y) {
define nofpclass(nan inf sub norm) half @ret_only_zero(half %x, half %y) {
; CHECK-LABEL: define nofpclass(nan inf sub norm) half @ret_only_zero(
; CHECK-SAME: half [[X:%.*]], half [[Y:%.*]]) {
-; CHECK-NEXT: [[ADD:%.*]] = fadd nnan half [[X]], [[Y]]
+; CHECK-NEXT: [[ADD:%.*]] = fadd nnan ninf half [[X]], [[Y]]
; CHECK-NEXT: ret half [[ADD]]
;
%add = fadd half %x, %y
@@ -215,7 +215,7 @@ define nofpclass(nan inf) half @ret_nofpclass_inf_nan__fadd_select_unknown_or_in
; CHECK-SAME: i1 [[COND:%.*]], half [[X:%.*]], half [[Y:%.*]]) {
; CHECK-NEXT: [[INF0:%.*]] = call half @returns_inf()
; CHECK-NEXT: [[INF1:%.*]] = call half @returns_inf()
-; CHECK-NEXT: [[ADD:%.*]] = fadd nnan half [[X]], [[Y]]
+; CHECK-NEXT: [[ADD:%.*]] = fadd nnan ninf half [[X]], [[Y]]
; CHECK-NEXT: ret half [[ADD]]
;
%inf0 = call half @returns_inf()
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll
index 4ed2e781a30d5..300fe7cfac036 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll
@@ -448,7 +448,7 @@ define nofpclass(pinf nan) float @ret_no_pinf_or_nan_results__lhs_known_non_inf(
define nofpclass(inf nan) float @ret_no_inf_or_nan_results__lhs_known_non_inf(i1 %cond, float %x, float nofpclass(inf) %y) {
; CHECK-LABEL: define nofpclass(nan inf) float @ret_no_inf_or_nan_results__lhs_known_non_inf(
; CHECK-SAME: i1 [[COND:%.*]], float [[X:%.*]], float nofpclass(inf) [[Y:%.*]]) {
-; CHECK-NEXT: [[MUL:%.*]] = fmul nnan float [[X]], [[Y]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf float [[X]], [[Y]]
; CHECK-NEXT: ret float [[MUL]]
;
%x.or.pinf = select i1 %cond, float %x, float 0x7FF0000000000000
@@ -460,7 +460,7 @@ define nofpclass(inf nan) float @ret_no_inf_or_nan_results__lhs_known_non_inf(i1
define nofpclass(inf nan) float @ret_no_inf_or_nan_results__rhs_known_non_inf(i1 %cond, float %x, float nofpclass(inf) %y) {
; CHECK-LABEL: define nofpclass(nan inf) float @ret_no_inf_or_nan_results__rhs_known_non_inf(
; CHECK-SAME: i1 [[COND:%.*]], float [[X:%.*]], float nofpclass(inf) [[Y:%.*]]) {
-; CHECK-NEXT: [[MUL:%.*]] = fmul nnan float [[X]], [[Y]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf float [[X]], [[Y]]
; CHECK-NEXT: ret float [[MUL]]
;
%y.or.pinf = select i1 %cond, float %y, float 0x7FF0000000000000
@@ -1297,7 +1297,7 @@ define nofpclass(nan inf norm sub) float @zero_result_demands_sub_source_lhs(i1
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
; CHECK-NEXT: [[SUB:%.*]] = call float @returns_sub()
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[SUB]], float [[UNKNOWN0]]
-; CHECK-NEXT: [[MUL:%.*]] = fmul nnan float [[SELECT]], [[UNKNOWN1]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf float [[SELECT]], [[UNKNOWN1]]
; CHECK-NEXT: ret float [[MUL]]
;
%sub = call float @returns_sub()
@@ -1311,7 +1311,7 @@ define nofpclass(nan inf norm sub) float @zero_result_demands_sub_source_rhs(i1
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
; CHECK-NEXT: [[SUB:%.*]] = call float @returns_sub()
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[SUB]], float [[UNKNOWN0]]
-; CHECK-NEXT: [[MUL:%.*]] = fmul nnan float [[UNKNOWN1]], [[SELECT]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf float [[UNKNOWN1]], [[SELECT]]
; CHECK-NEXT: ret float [[MUL]]
;
%sub = call float @returns_sub()
@@ -1325,7 +1325,7 @@ define nofpclass(nan inf norm sub) float @zero_result_demands_norm_source_lhs(i1
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
; CHECK-NEXT: [[NORM:%.*]] = call float @returns_norm()
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[NORM]], float [[UNKNOWN0]]
-; CHECK-NEXT: [[MUL:%.*]] = fmul nnan float [[SELECT]], [[UNKNOWN1]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf float [[SELECT]], [[UNKNOWN1]]
; CHECK-NEXT: ret float [[MUL]]
;
%norm = call float @returns_norm()
@@ -1339,7 +1339,7 @@ define nofpclass(nan inf norm sub) float @zero_result_demands_norm_source_rhs(i1
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
; CHECK-NEXT: [[NORM:%.*]] = call float @returns_norm()
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[NORM]], float [[UNKNOWN0]]
-; CHECK-NEXT: [[MUL:%.*]] = fmul nnan float [[UNKNOWN1]], [[SELECT]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf float [[UNKNOWN1]], [[SELECT]]
; CHECK-NEXT: ret float [[MUL]]
;
%norm = call float @returns_norm()
@@ -1353,7 +1353,7 @@ define nofpclass(nan inf norm zero) float @sub_result_demands_norm_source_lhs(i1
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
; CHECK-NEXT: [[NORM:%.*]] = call float @returns_norm()
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[NORM]], float [[UNKNOWN0]]
-; CHECK-NEXT: [[MUL:%.*]] = fmul nnan float [[SELECT]], [[UNKNOWN1]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf float [[SELECT]], [[UNKNOWN1]]
; CHECK-NEXT: ret float [[MUL]]
;
%norm = call float @returns_norm()
@@ -1367,7 +1367,7 @@ define nofpclass(nan inf norm zero) float @sub_result_demands_norm_source_rhs(i1
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
; CHECK-NEXT: [[NORM:%.*]] = call float @returns_norm()
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[NORM]], float [[UNKNOWN0]]
-; CHECK-NEXT: [[MUL:%.*]] = fmul nnan float [[UNKNOWN1]], [[SELECT]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf float [[UNKNOWN1]], [[SELECT]]
; CHECK-NEXT: ret float [[MUL]]
;
%norm = call float @returns_norm()
@@ -1381,7 +1381,7 @@ define nofpclass(nan inf sub zero) float @norm_result_demands_sub_source_lhs(i1
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
; CHECK-NEXT: [[SUB:%.*]] = call float @returns_sub()
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[SUB]], float [[UNKNOWN0]]
-; CHECK-NEXT: [[MUL:%.*]] = fmul nnan float [[SELECT]], [[UNKNOWN1]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf float [[SELECT]], [[UNKNOWN1]]
; CHECK-NEXT: ret float [[MUL]]
;
%sub = call float @returns_sub()
@@ -1395,7 +1395,7 @@ define nofpclass(nan inf sub zero) float @norm_result_demands_sub_source_rhs(i1
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
; CHECK-NEXT: [[SUB:%.*]] = call float @returns_sub()
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[SUB]], float [[UNKNOWN0]]
-; CHECK-NEXT: [[MUL:%.*]] = fmul nnan float [[UNKNOWN1]], [[SELECT]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf float [[UNKNOWN1]], [[SELECT]]
; CHECK-NEXT: ret float [[MUL]]
;
%sub = call float @returns_sub()
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-rounding-intrinsics.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-rounding-intrinsics.ll
index 1d8a08170677f..568a22b7c9a83 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-rounding-intrinsics.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-rounding-intrinsics.ll
@@ -14,7 +14,7 @@ define nofpclass(snan) float @ret_no_snan__floor_no_snan(float nofpclass(nan) %x
define nofpclass(inf norm sub zero) float @ret_only_nan__floor(float %x) {
; CHECK-LABEL: define nofpclass(inf zero sub norm) float @ret_only_nan__floor(
; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT: ret float 0x7FF8000000000000
+; CHECK-NEXT: ret float [[X]]
;
%result = call float @llvm.floor.f32(float %x)
ret float %result
@@ -23,7 +23,7 @@ define nofpclass(inf norm sub zero) float @ret_only_nan__floor(float %x) {
define nofpclass(inf norm sub zero) <2 x float> @ret_only_nan__floor_vec(<2 x float> %x) {
; CHECK-LABEL: define nofpclass(inf zero sub norm) <2 x float> @ret_only_nan__floor_vec(
; CHECK-SAME: <2 x float> [[X:%.*]]) {
-; CHECK-NEXT: ret <2 x float> splat (float 0x7FF8000000000000)
+; CHECK-NEXT: ret <2 x float> [[X]]
;
%result = call <2 x float> @llvm.floor.v2f32(<2 x float> %x)
ret <2 x float> %result
@@ -32,8 +32,7 @@ define nofpclass(inf norm sub zero) <2 x float> @ret_only_nan__floor_vec(<2 x fl
define nofpclass(inf norm sub zero qnan) float @ret_only_snan__floor(float %x) {
; CHECK-LABEL: define nofpclass(qnan inf zero sub norm) float @ret_only_snan__floor(
; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.floor.f32(float [[X]])
-; CHECK-NEXT: ret float [[RESULT]]
+; CHECK-NEXT: ret float [[X]]
;
%result = call float @llvm.floor.f32(float %x)
ret float %result
@@ -42,8 +41,7 @@ define nofpclass(inf norm sub zero qnan) float @ret_only_snan__floor(float %x) {
define nofpclass(inf norm sub zero snan) float @ret_only_qnan__floor(float %x) {
; CHECK-LABEL: define nofpclass(snan inf zero sub norm) float @ret_only_qnan__floor(
; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.floor.f32(float [[X]])
-; CHECK-NEXT: ret float [[RESULT]]
+; CHECK-NEXT: ret float [[X]]
;
%result = call float @llvm.floor.f32(float %x)
ret float %result
@@ -52,8 +50,7 @@ define nofpclass(inf norm sub zero snan) float @ret_only_qnan__floor(float %x) {
define nofpclass(nan norm sub zero) float @ret_only_inf__floor(float %x) {
; CHECK-LABEL: define nofpclass(nan zero sub norm) float @ret_only_inf__floor(
; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.floor.f32(float [[X]])
-; CHECK-NEXT: ret float [[RESULT]]
+; CHECK-NEXT: ret float [[X]]
;
%result = call float @llvm.floor.f32(float %x)
ret float %result
More information about the llvm-commits
mailing list