https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/176122
>From 6432eb2c4bab2e75c6ed539120f95836fe953287 Mon Sep 17 00:00:00 2001 From: Matt Arsenault <[email protected]> Date: Thu, 15 Jan 2026 10:18:49 +0100 Subject: [PATCH 1/3] 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 78d7be41fae67..93bb72f6fde2b 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 548f81e18b25f..9861c99034b90 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 1529b088e124806770a2d5a1a3cdf0c9fbe370e5 Mon Sep 17 00:00:00 2001 From: Matt Arsenault <[email protected]> Date: Thu, 15 Jan 2026 17:20:50 +0100 Subject: [PATCH 2/3] 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 93bb72f6fde2b..7b8fca244c55d 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) >From c8f6bc4398347209bf2af7da166d96cddc3f9a90 Mon Sep 17 00:00:00 2001 From: Matt Arsenault <[email protected]> Date: Thu, 15 Jan 2026 20:22:44 +0100 Subject: [PATCH 3/3] one use check --- .../Transforms/InstCombine/InstCombineSimplifyDemanded.cpp | 2 +- .../InstCombine/simplify-demanded-fpclass-frexp.ll | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 7b8fca244c55d..db8193f97ccf8 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -2943,7 +2943,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I, } case Instruction::ExtractValue: { Value *ExtractSrc; - if (match(I, m_ExtractValue<0>(m_Value(ExtractSrc)))) { + if (match(I, m_ExtractValue<0>(m_OneUse(m_Value(ExtractSrc))))) { if (auto *II = dyn_cast<IntrinsicInst>(ExtractSrc)) { const Intrinsic::ID IID = II->getIntrinsicID(); switch (IID) { diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll index 9861c99034b90..dc9c00ef15461 100644 --- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll +++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-frexp.ll @@ -213,7 +213,8 @@ 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: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]]) +; 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_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 @@ -250,7 +251,8 @@ 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: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]]) +; 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_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: store { half, i32 } [[FREXP]], ptr [[PTR]], align 4 ; CHECK-NEXT: ret half [[FREXP_MANT]] _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
