[llvm-branch-commits] [llvm] InstCombine: Implement SimplifyDemandedFPClass for frexp (PR #176122)
Matt Arsenault via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Jan 15 08:42:31 PST 2026
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/176122
>From 9fc86544efff9d888632a0a27b7ec106fa69c21f Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 15 Jan 2026 10:18:49 +0100
Subject: [PATCH 1/2] InstCombine: Implement SimplifyDemandedFPClass for frexp
---
llvm/include/llvm/Support/KnownFPClass.h | 4 ++
llvm/lib/Analysis/ValueTracking.cpp | 24 ++-------
llvm/lib/Support/KnownFPClass.cpp | 27 ++++++++++
.../InstCombineSimplifyDemanded.cpp | 49 +++++++++++++++++
.../simplify-demanded-fpclass-frexp.ll | 54 ++++++-------------
5 files changed, 99 insertions(+), 59 deletions(-)
diff --git a/llvm/include/llvm/Support/KnownFPClass.h b/llvm/include/llvm/Support/KnownFPClass.h
index 6c1a6a7e9b5c3..93ebf99564386 100644
--- a/llvm/include/llvm/Support/KnownFPClass.h
+++ b/llvm/include/llvm/Support/KnownFPClass.h
@@ -332,6 +332,10 @@ struct KnownFPClass {
bool IsTrunc,
bool IsMultiUnitFPType);
+ /// Propagate known class for mantissa component of frexp
+ static LLVM_ABI KnownFPClass frexp_mant(
+ const KnownFPClass &Src, DenormalMode Mode = DenormalMode::getDynamic());
+
void resetAll() { *this = KnownFPClass(); }
};
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 171952120fc40..4ff3ca6bfbcf1 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5926,27 +5926,9 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
const fltSemantics &FltSem =
Op->getType()->getScalarType()->getFltSemantics();
- if (KnownSrc.isKnownNever(fcNegative))
- Known.knownNot(fcNegative);
- else {
- if (F &&
- KnownSrc.isKnownNeverLogicalNegZero(F->getDenormalMode(FltSem)))
- Known.knownNot(fcNegZero);
- if (KnownSrc.isKnownNever(fcNegInf))
- Known.knownNot(fcNegInf);
- }
-
- if (KnownSrc.isKnownNever(fcPositive))
- Known.knownNot(fcPositive);
- else {
- if (F &&
- KnownSrc.isKnownNeverLogicalPosZero(F->getDenormalMode(FltSem)))
- Known.knownNot(fcPosZero);
- if (KnownSrc.isKnownNever(fcPosInf))
- Known.knownNot(fcPosInf);
- }
-
- Known.propagateNaN(KnownSrc);
+ DenormalMode Mode =
+ F ? F->getDenormalMode(FltSem) : DenormalMode::getDynamic();
+ Known = KnownFPClass::frexp_mant(KnownSrc, Mode);
return;
}
default:
diff --git a/llvm/lib/Support/KnownFPClass.cpp b/llvm/lib/Support/KnownFPClass.cpp
index ae8c4a9133897..ae7b7aa598da4 100644
--- a/llvm/lib/Support/KnownFPClass.cpp
+++ b/llvm/lib/Support/KnownFPClass.cpp
@@ -450,3 +450,30 @@ KnownFPClass KnownFPClass::roundToIntegral(const KnownFPClass &KnownSrc,
return Known;
}
+
+KnownFPClass KnownFPClass::frexp_mant(const KnownFPClass &KnownSrc,
+ DenormalMode Mode) {
+ KnownFPClass Known;
+ Known.knownNot(fcSubnormal);
+
+ if (KnownSrc.isKnownNever(fcNegative))
+ Known.knownNot(fcNegative);
+ else {
+ if (KnownSrc.isKnownNeverLogicalNegZero(Mode))
+ Known.knownNot(fcNegZero);
+ if (KnownSrc.isKnownNever(fcNegInf))
+ Known.knownNot(fcNegInf);
+ }
+
+ if (KnownSrc.isKnownNever(fcPositive))
+ Known.knownNot(fcPositive);
+ else {
+ if (KnownSrc.isKnownNeverLogicalPosZero(Mode))
+ Known.knownNot(fcPosZero);
+ if (KnownSrc.isKnownNever(fcPosInf))
+ Known.knownNot(fcPosInf);
+ }
+
+ Known.propagateNaN(KnownSrc);
+ return Known;
+}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 86c229c667eea..f958d9fb9569e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2941,6 +2941,55 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
Known = KnownLHS | KnownRHS;
break;
}
+ case Instruction::ExtractValue: {
+ ExtractValueInst *Extract = cast<ExtractValueInst>(I);
+ ArrayRef<unsigned> Indices = Extract->getIndices();
+ Value *Src = Extract->getAggregateOperand();
+ if (isa<StructType>(Src->getType()) && Indices.size() == 1 &&
+ Indices[0] == 0) {
+ if (auto *II = dyn_cast<IntrinsicInst>(Src)) {
+ switch (II->getIntrinsicID()) {
+ case Intrinsic::frexp: {
+ FPClassTest SrcDemandedMask = fcNone;
+ if (DemandedMask & fcNan)
+ SrcDemandedMask |= fcNan;
+ if (DemandedMask & fcNegFinite)
+ SrcDemandedMask |= fcNegFinite;
+ if (DemandedMask & fcPosFinite)
+ SrcDemandedMask |= fcPosFinite;
+ if (DemandedMask & fcPosInf)
+ SrcDemandedMask |= fcPosInf;
+ if (DemandedMask & fcNegInf)
+ SrcDemandedMask |= fcNegInf;
+
+ KnownFPClass KnownSrc;
+ if (SimplifyDemandedFPClass(II, 0, SrcDemandedMask, KnownSrc,
+ Depth + 1))
+ return I;
+
+ Type *EltTy = VTy->getScalarType();
+ DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
+
+ Known = KnownFPClass::frexp_mant(KnownSrc, Mode);
+ Known.KnownFPClasses &= DemandedMask;
+
+ if (Constant *SingleVal =
+ getFPClassConstant(VTy, Known.KnownFPClasses,
+ /*IsCanonicalizing=*/true))
+ return SingleVal;
+
+ if (Known.isKnownAlways(fcInf | fcNan))
+ return II->getArgOperand(0);
+
+ return nullptr;
+ }
+ default:
+ break;
+ }
+ }
+ }
+ [[fallthrough]];
+ }
default:
Known = computeKnownFPClass(I, DemandedMask, CxtI, Depth + 1);
break;
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll
index 4b465f249fc50..c0715b637295a 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll
@@ -65,9 +65,7 @@ define nofpclass(nan) half @extractvalue_not_frexp() {
define nofpclass(snan inf norm sub zero) half @ret_only_qnan__frexp(half %unknown) {
; CHECK-LABEL: define nofpclass(snan inf zero sub norm) half @ret_only_qnan__frexp(
; CHECK-SAME: half [[UNKNOWN:%.*]]) {
-; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]])
-; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0
-; CHECK-NEXT: ret half [[FREXP_MANT]]
+; CHECK-NEXT: ret half [[UNKNOWN]]
;
%frexp = call { half, i32 } @llvm.frexp.f16.i32(half %unknown)
%frexp.mant = extractvalue { half, i32 } %frexp, 0
@@ -77,9 +75,7 @@ define nofpclass(snan inf norm sub zero) half @ret_only_qnan__frexp(half %unknow
define nofpclass(qnan inf norm sub zero) half @ret_only_snan__frexp(half %unknown) {
; CHECK-LABEL: define nofpclass(qnan inf zero sub norm) half @ret_only_snan__frexp(
; CHECK-SAME: half [[UNKNOWN:%.*]]) {
-; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]])
-; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0
-; CHECK-NEXT: ret half [[FREXP_MANT]]
+; CHECK-NEXT: ret half [[UNKNOWN]]
;
%frexp = call { half, i32 } @llvm.frexp.f16.i32(half %unknown)
%frexp.mant = extractvalue { half, i32 } %frexp, 0
@@ -89,9 +85,7 @@ define nofpclass(qnan inf norm sub zero) half @ret_only_snan__frexp(half %unknow
define nofpclass(inf norm sub zero) half @ret_only_nan__frexp(half %unknown) {
; CHECK-LABEL: define nofpclass(inf zero sub norm) half @ret_only_nan__frexp(
; CHECK-SAME: half [[UNKNOWN:%.*]]) {
-; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]])
-; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0
-; CHECK-NEXT: ret half [[FREXP_MANT]]
+; CHECK-NEXT: ret half 0xH7E00
;
%frexp = call { half, i32 } @llvm.frexp.f16.i32(half %unknown)
%frexp.mant = extractvalue { half, i32 } %frexp, 0
@@ -121,9 +115,7 @@ define nofpclass(nan pinf norm sub zero) half @ret_only_ninf__frexp(half %unknow
define nofpclass(nan norm sub zero) half @ret_only_inf__frexp(half %unknown) {
; CHECK-LABEL: define nofpclass(nan zero sub norm) half @ret_only_inf__frexp(
; CHECK-SAME: half [[UNKNOWN:%.*]]) {
-; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]])
-; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0
-; CHECK-NEXT: ret half [[FREXP_MANT]]
+; CHECK-NEXT: ret half [[UNKNOWN]]
;
%frexp = call { half, i32 } @llvm.frexp.f16.i32(half %unknown)
%frexp.mant = extractvalue { half, i32 } %frexp, 0
@@ -206,8 +198,7 @@ define nofpclass(pinf) half @ret_nofpclass_pinf__frexp_select_unknown_or_pinf(i1
; CHECK-LABEL: define nofpclass(pinf) half @ret_nofpclass_pinf__frexp_select_unknown_or_pinf(
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]]) {
; CHECK-NEXT: [[ONLY_PINF:%.*]] = call half @returns_pinf()
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_PINF]]
-; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]])
+; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]])
; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0
; CHECK-NEXT: ret half [[FREXP_MANT]]
;
@@ -222,8 +213,7 @@ define nofpclass(pinf) half @ret_nofpclass_pinf__frexp_select_unknown_or_pinf__u
; CHECK-LABEL: define nofpclass(pinf) half @ret_nofpclass_pinf__frexp_select_unknown_or_pinf__use_other_output(
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]], ptr [[PTR:%.*]]) {
; CHECK-NEXT: [[ONLY_PINF:%.*]] = call half @returns_pinf()
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_PINF]]
-; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]])
+; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]])
; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0
; CHECK-NEXT: [[FREXP_EXP:%.*]] = extractvalue { half, i32 } [[FREXP]], 1
; CHECK-NEXT: store i32 [[FREXP_EXP]], ptr [[PTR]], align 4
@@ -260,8 +250,7 @@ define nofpclass(pinf) half @ret_nofpclass_pinf__frexp_select_unknown_or_pinf__u
; CHECK-LABEL: define nofpclass(pinf) half @ret_nofpclass_pinf__frexp_select_unknown_or_pinf__use_struct(
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]], ptr [[PTR:%.*]]) {
; CHECK-NEXT: [[ONLY_PINF:%.*]] = call half @returns_pinf()
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_PINF]]
-; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]])
+; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]])
; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0
; CHECK-NEXT: store { half, i32 } [[FREXP]], ptr [[PTR]], align 4
; CHECK-NEXT: ret half [[FREXP_MANT]]
@@ -279,8 +268,7 @@ define nofpclass(ninf) half @ret_nofpclass_ninf__frexp_select_unknown_or_ninf(i1
; CHECK-LABEL: define nofpclass(ninf) half @ret_nofpclass_ninf__frexp_select_unknown_or_ninf(
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]]) {
; CHECK-NEXT: [[ONLY_NINF:%.*]] = call half @returns_ninf()
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_NINF]]
-; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]])
+; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]])
; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0
; CHECK-NEXT: ret half [[FREXP_MANT]]
;
@@ -295,8 +283,7 @@ define nofpclass(inf) half @ret_nofpclass_inf__frexp_select_unknown_or_inf(i1 %c
; CHECK-LABEL: define nofpclass(inf) half @ret_nofpclass_inf__frexp_select_unknown_or_inf(
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]]) {
; CHECK-NEXT: [[ONLY_INF:%.*]] = call half @returns_inf()
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_INF]]
-; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]])
+; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]])
; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0
; CHECK-NEXT: ret half [[FREXP_MANT]]
;
@@ -343,8 +330,7 @@ define nofpclass(nan) half @ret_nofpclass_nan__frexp_select_unknown_nan(i1 %cond
; CHECK-LABEL: define nofpclass(nan) half @ret_nofpclass_nan__frexp_select_unknown_nan(
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]]) {
; CHECK-NEXT: [[ONLY_NAN:%.*]] = call half @returns_nan()
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_NAN]]
-; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]])
+; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]])
; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0
; CHECK-NEXT: ret half [[FREXP_MANT]]
;
@@ -359,8 +345,7 @@ define nofpclass(pzero) half @ret_nofpclass_pzero__frexp_select_unknown_only_pze
; CHECK-LABEL: define nofpclass(pzero) half @ret_nofpclass_pzero__frexp_select_unknown_only_pzero(
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]]) {
; CHECK-NEXT: [[ONLY_PZERO:%.*]] = call half @returns_pzero()
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_PZERO]]
-; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]])
+; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]])
; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0
; CHECK-NEXT: ret half [[FREXP_MANT]]
;
@@ -375,8 +360,7 @@ define nofpclass(nzero) half @ret_nofpclass_nzero__frexp_select_unknown_or_not_n
; CHECK-LABEL: define nofpclass(nzero) half @ret_nofpclass_nzero__frexp_select_unknown_or_not_nzero(
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]]) {
; CHECK-NEXT: [[ONLY_NZERO:%.*]] = call half @returns_nzero()
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_NZERO]]
-; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]])
+; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]])
; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0
; CHECK-NEXT: ret half [[FREXP_MANT]]
;
@@ -505,8 +489,7 @@ define nofpclass(ninf nnorm nsub nzero) half @ret_only_positive_or_nan__frexp_se
; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) half @ret_only_positive_or_nan__frexp_select_negative_or_unknown(
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]]) {
; CHECK-NEXT: [[NEGATIVE:%.*]] = call half @returns_negative()
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[NEGATIVE]]
-; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]])
+; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]])
; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0
; CHECK-NEXT: ret half [[FREXP_MANT]]
;
@@ -521,8 +504,7 @@ define nofpclass(pinf pnorm psub pzero) half @ret_only_negative_or_nan__frexp_se
; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) half @ret_only_negative_or_nan__frexp_select_positive_or_unknown(
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]]) {
; CHECK-NEXT: [[POSITIVE:%.*]] = call half @returns_positive()
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[POSITIVE]]
-; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]])
+; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]])
; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0
; CHECK-NEXT: ret half [[FREXP_MANT]]
;
@@ -549,9 +531,7 @@ define nofpclass(snan) half @src_only_inf__frexp() {
define nofpclass(snan) half @src_only_nan__frexp() {
; CHECK-LABEL: define nofpclass(snan) half @src_only_nan__frexp() {
; CHECK-NEXT: [[ONLY_NAN:%.*]] = call half @returns_nan()
-; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[ONLY_NAN]])
-; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0
-; CHECK-NEXT: ret half [[FREXP_MANT]]
+; CHECK-NEXT: ret half [[ONLY_NAN]]
;
%only.nan = call half @returns_nan()
%frexp = call { half, i32 } @llvm.frexp.f16.i32(half %only.nan)
@@ -601,9 +581,7 @@ define nofpclass(nan) half @ret_no_nan_src_only_inf__frexp() {
define nofpclass(inf) half @ret_no_inf_src_only_nan__frexp() {
; CHECK-LABEL: define nofpclass(inf) half @ret_no_inf_src_only_nan__frexp() {
; CHECK-NEXT: [[NAN:%.*]] = call half @returns_nan()
-; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[NAN]])
-; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0
-; CHECK-NEXT: ret half [[FREXP_MANT]]
+; CHECK-NEXT: ret half 0xH7E00
;
%nan = call half @returns_nan()
%frexp = call { half, i32 } @llvm.frexp.f16.i32(half %nan)
>From 22bf72d76ed9eb2dc80332bb7a7ce9a6489845cd Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 15 Jan 2026 17:20:50 +0100
Subject: [PATCH 2/2] Use m_Extractvalue
---
.../InstCombine/InstCombineSimplifyDemanded.cpp | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index f958d9fb9569e..f19449a003e9f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2942,13 +2942,11 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
break;
}
case Instruction::ExtractValue: {
- ExtractValueInst *Extract = cast<ExtractValueInst>(I);
- ArrayRef<unsigned> Indices = Extract->getIndices();
- Value *Src = Extract->getAggregateOperand();
- if (isa<StructType>(Src->getType()) && Indices.size() == 1 &&
- Indices[0] == 0) {
- if (auto *II = dyn_cast<IntrinsicInst>(Src)) {
- switch (II->getIntrinsicID()) {
+ Value *ExtractSrc;
+ if (match(I, m_ExtractValue<0>(m_Value(ExtractSrc)))) {
+ if (auto *II = dyn_cast<IntrinsicInst>(ExtractSrc)) {
+ const Intrinsic::ID IID = II->getIntrinsicID();
+ switch (IID) {
case Intrinsic::frexp: {
FPClassTest SrcDemandedMask = fcNone;
if (DemandedMask & fcNan)
More information about the llvm-branch-commits
mailing list