[llvm-branch-commits] [llvm] InstCombine: Handle rounding intrinsics in SimplifyDemandedFPClass (PR #174842)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Jan 7 11:15:55 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-support
Author: Matt Arsenault (arsenm)
<details>
<summary>Changes</summary>
---
Patch is 37.56 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/174842.diff
5 Files Affected:
- (modified) llvm/include/llvm/Support/KnownFPClass.h (+7)
- (modified) llvm/lib/Analysis/ValueTracking.cpp (+2-20)
- (modified) llvm/lib/Support/KnownFPClass.cpp (+28)
- (modified) llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp (+66)
- (modified) llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-rounding-intrinsics.ll (+46-72)
``````````diff
diff --git a/llvm/include/llvm/Support/KnownFPClass.h b/llvm/include/llvm/Support/KnownFPClass.h
index 6453e8797310c..117ed8e96bf11 100644
--- a/llvm/include/llvm/Support/KnownFPClass.h
+++ b/llvm/include/llvm/Support/KnownFPClass.h
@@ -287,6 +287,13 @@ struct KnownFPClass {
static LLVM_ABI KnownFPClass
sqrt(const KnownFPClass &Src, DenormalMode Mode = DenormalMode::getDynamic());
+ /// Propagate known class for rounding intrinsics (trunc, floor, ceil, rint,
+ /// nearbyint, round, roundeven). This is trunc if \p IsTrunc. \p
+ /// IsMultiUnitFPType if this is for a multi-unit floating-point type.
+ static LLVM_ABI KnownFPClass roundToIntegral(const KnownFPClass &Src,
+ bool IsTrunc,
+ bool IsMultiUnitFPType);
+
void resetAll() { *this = KnownFPClass(); }
};
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 48b81597f68f0..8df7093cac48a 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5245,26 +5245,8 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
computeKnownFPClass(II->getArgOperand(0), DemandedElts, InterestedSrcs,
KnownSrc, Q, Depth + 1);
- // Integer results cannot be subnormal.
- Known.knownNot(fcSubnormal);
-
- Known.propagateNaN(KnownSrc, true);
-
- // Pass through infinities, except PPC_FP128 is a special case for
- // intrinsics other than trunc.
- if (IID == Intrinsic::trunc || !V->getType()->isMultiUnitFPType()) {
- if (KnownSrc.isKnownNeverPosInfinity())
- Known.knownNot(fcPosInf);
- if (KnownSrc.isKnownNeverNegInfinity())
- Known.knownNot(fcNegInf);
- }
-
- // Negative round ups to 0 produce -0
- if (KnownSrc.isKnownNever(fcPosFinite))
- Known.knownNot(fcPosFinite);
- if (KnownSrc.isKnownNever(fcNegFinite))
- Known.knownNot(fcNegFinite);
-
+ Known = KnownFPClass::roundToIntegral(KnownSrc, IID == Intrinsic::trunc,
+ V->getType()->isMultiUnitFPType());
break;
}
case Intrinsic::exp:
diff --git a/llvm/lib/Support/KnownFPClass.cpp b/llvm/lib/Support/KnownFPClass.cpp
index b8f6d97d1ee99..d6f1b33f0344d 100644
--- a/llvm/lib/Support/KnownFPClass.cpp
+++ b/llvm/lib/Support/KnownFPClass.cpp
@@ -353,3 +353,31 @@ KnownFPClass KnownFPClass::sqrt(const KnownFPClass &KnownSrc,
return Known;
}
+
+KnownFPClass KnownFPClass::roundToIntegral(const KnownFPClass &KnownSrc,
+ bool IsTrunc,
+ bool IsMultiUnitFPType) {
+ KnownFPClass Known;
+
+ // Integer results cannot be subnormal.
+ Known.knownNot(fcSubnormal);
+
+ Known.propagateNaN(KnownSrc, true);
+
+ // Pass through infinities, except PPC_FP128 is a special case for
+ // intrinsics other than trunc.
+ if (IsTrunc || !IsMultiUnitFPType) {
+ if (KnownSrc.isKnownNeverPosInfinity())
+ Known.knownNot(fcPosInf);
+ if (KnownSrc.isKnownNeverNegInfinity())
+ Known.knownNot(fcNegInf);
+ }
+
+ // Negative round ups to 0 produce -0
+ if (KnownSrc.isKnownNever(fcPosFinite))
+ Known.knownNot(fcPosFinite);
+ if (KnownSrc.isKnownNever(fcNegFinite))
+ Known.knownNot(fcNegFinite);
+
+ return Known;
+}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 3aca696f22827..6ed3c28488802 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2542,6 +2542,72 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Value *V,
return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
}
+ case Intrinsic::trunc:
+ case Intrinsic::floor:
+ case Intrinsic::ceil:
+ case Intrinsic::rint:
+ case Intrinsic::nearbyint:
+ case Intrinsic::round:
+ case Intrinsic::roundeven: {
+ FPClassTest DemandedSrcMask = DemandedMask;
+
+ // Zero results imply valid subnormal sources.
+ if (DemandedMask & fcNegZero)
+ DemandedSrcMask |= fcNegSubnormal;
+
+ if (DemandedMask & fcPosZero)
+ DemandedSrcMask |= fcPosSubnormal;
+
+ KnownFPClass KnownSrc;
+ if (SimplifyDemandedFPClass(CI, 0, DemandedSrcMask, KnownSrc, Depth + 1))
+ return I;
+
+ // Note: Possibly dropping snan quiet.
+ if (KnownSrc.isKnownAlways(fcInf | fcNan))
+ return CI->getArgOperand(0);
+
+ // Propagate nnan-ness to source to simplify source checks.
+ if ((DemandedMask & fcNan) == fcNone)
+ KnownSrc.knownNot(fcNan);
+
+ bool IsRoundNearest =
+ IID == Intrinsic::round || IID == Intrinsic::roundeven ||
+ IID == Intrinsic::nearbyint || IID == Intrinsic::rint;
+
+ // Ignore denormals-as-zero, as canonicalization is not mandated.
+ if ((IID == Intrinsic::trunc || IID == Intrinsic::floor ||
+ IsRoundNearest) &&
+ (KnownSrc.isKnownAlways(fcPosZero | fcPosSubnormal)))
+ return ConstantFP::getZero(VTy);
+
+ if ((IID == Intrinsic::trunc || IsRoundNearest) &&
+ KnownSrc.isKnownAlways(fcNegZero | fcNegSubnormal))
+ return ConstantFP::getZero(VTy, true);
+
+ if (IID == Intrinsic::floor && KnownSrc.isKnownAlways(fcNegSubnormal))
+ return ConstantFP::get(VTy, -1.0);
+
+ if (IID == Intrinsic::ceil && KnownSrc.isKnownAlways(fcPosSubnormal))
+ return ConstantFP::get(VTy, 1.0);
+
+ Known = KnownFPClass::roundToIntegral(KnownSrc, IID == Intrinsic::trunc,
+ VTy->isMultiUnitFPType());
+
+ FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+ if (Constant *SingleVal =
+ getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true))
+ return SingleVal;
+
+ if ((IID == Intrinsic::trunc || IsRoundNearest) &&
+ KnownSrc.isKnownAlways(fcZero | fcSubnormal)) {
+ Value *Copysign = Builder.CreateCopySign(ConstantFP::getZero(VTy),
+ CI->getArgOperand(0));
+ Copysign->takeName(CI);
+ return Copysign;
+ }
+
+ return nullptr;
+ }
case Intrinsic::canonicalize: {
Type *EltTy = VTy->getScalarType();
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 8e881efa86286..9ceab0e4574f1 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-rounding-intrinsics.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-rounding-intrinsics.ll
@@ -14,8 +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: [[RESULT:%.*]] = call float @llvm.floor.f32(float [[X]])
-; CHECK-NEXT: ret float [[RESULT]]
+; CHECK-NEXT: ret float 0x7FF8000000000000
;
%result = call float @llvm.floor.f32(float %x)
ret float %result
@@ -24,8 +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: [[RESULT:%.*]] = call <2 x float> @llvm.floor.v2f32(<2 x float> [[X]])
-; CHECK-NEXT: ret <2 x float> [[RESULT]]
+; CHECK-NEXT: ret <2 x float> splat (float 0x7FF8000000000000)
;
%result = call <2 x float> @llvm.floor.v2f32(<2 x float> %x)
ret <2 x float> %result
@@ -140,8 +138,7 @@ define nofpclass(nan inf) float @ret_no_nans_no_infs__floor(float %x) {
define nofpclass(nan) float @ret_no_nans__simplify_select_nan__floor(i1 %cond, float nofpclass(inf norm sub zero) %is.nan, float %unknown) {
; CHECK-LABEL: define nofpclass(nan) float @ret_no_nans__simplify_select_nan__floor(
; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(inf zero sub norm) [[IS_NAN:%.*]], float [[UNKNOWN:%.*]]) {
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[IS_NAN]], float [[UNKNOWN]]
-; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.floor.f32(float [[SELECT]])
+; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.floor.f32(float [[UNKNOWN]])
; CHECK-NEXT: ret float [[RESULT]]
;
%select = select i1 %cond, float %is.nan, float %unknown
@@ -152,8 +149,7 @@ define nofpclass(nan) float @ret_no_nans__simplify_select_nan__floor(i1 %cond, f
define nofpclass(inf) float @ret_no_infs__simplify_select_inf__floor(i1 %cond, float nofpclass(nan norm sub zero) %is.inf, float %unknown) {
; CHECK-LABEL: define nofpclass(inf) float @ret_no_infs__simplify_select_inf__floor(
; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan zero sub norm) [[IS_INF:%.*]], float [[UNKNOWN:%.*]]) {
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[IS_INF]], float [[UNKNOWN]]
-; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.floor.f32(float [[SELECT]])
+; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.floor.f32(float [[UNKNOWN]])
; CHECK-NEXT: ret float [[RESULT]]
;
%select = select i1 %cond, float %is.inf, float %unknown
@@ -164,8 +160,7 @@ define nofpclass(inf) float @ret_no_infs__simplify_select_inf__floor(i1 %cond, f
define nofpclass(nan inf) float @ret_no_inf_no_nan__simplify_select_inf_or_nan__floor(i1 %cond, float nofpclass(norm sub zero) %is.inf.or.nan, float %unknown) {
; CHECK-LABEL: define nofpclass(nan inf) float @ret_no_inf_no_nan__simplify_select_inf_or_nan__floor(
; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(zero sub norm) [[IS_INF_OR_NAN:%.*]], float [[UNKNOWN:%.*]]) {
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[IS_INF_OR_NAN]], float [[UNKNOWN]]
-; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.floor.f32(float [[SELECT]])
+; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.floor.f32(float [[UNKNOWN]])
; CHECK-NEXT: ret float [[RESULT]]
;
%select = select i1 %cond, float %is.inf.or.nan, float %unknown
@@ -228,8 +223,7 @@ define nofpclass(snan) <2 x float> @source_known_sub_or_zero_or_nan__floor_vec(<
define nofpclass(snan) float @source_known_psub_or_pzero__floor(float nofpclass(nan inf norm nsub nzero) %psub.or.pzero) {
; CHECK-LABEL: define nofpclass(snan) float @source_known_psub_or_pzero__floor(
; CHECK-SAME: float nofpclass(nan inf nzero nsub norm) [[PSUB_OR_PZERO:%.*]]) {
-; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.floor.f32(float [[PSUB_OR_PZERO]])
-; CHECK-NEXT: ret float [[RESULT]]
+; CHECK-NEXT: ret float 0.000000e+00
;
%result = call float @llvm.floor.f32(float %psub.or.pzero)
ret float %result
@@ -268,8 +262,7 @@ define nofpclass(snan) float @source_known_nsub_or_nzero_or_nan__floor(float nof
define nofpclass(snan) float @source_known_inf__floor(float nofpclass(nan norm sub zero) %inf) {
; CHECK-LABEL: define nofpclass(snan) float @source_known_inf__floor(
; CHECK-SAME: float nofpclass(nan zero sub norm) [[INF:%.*]]) {
-; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.floor.f32(float [[INF]])
-; CHECK-NEXT: ret float [[RESULT]]
+; CHECK-NEXT: ret float [[INF]]
;
%result = call float @llvm.floor.f32(float %inf)
ret float %result
@@ -278,8 +271,7 @@ define nofpclass(snan) float @source_known_inf__floor(float nofpclass(nan norm s
define nofpclass(snan) float @source_known_inf_or_nan__floor(float nofpclass(norm sub zero) %inf.or.nan) {
; CHECK-LABEL: define nofpclass(snan) float @source_known_inf_or_nan__floor(
; CHECK-SAME: float nofpclass(zero sub norm) [[INF_OR_NAN:%.*]]) {
-; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.floor.f32(float [[INF_OR_NAN]])
-; CHECK-NEXT: ret float [[RESULT]]
+; CHECK-NEXT: ret float [[INF_OR_NAN]]
;
%result = call float @llvm.floor.f32(float %inf.or.nan)
ret float %result
@@ -297,8 +289,7 @@ define nofpclass(snan) float @source_known_pinf__floor(float nofpclass(nan ninf
define nofpclass(snan) float @source_known_pinf_or_nan__floor(float nofpclass(ninf norm sub zero) %pinf.or.nan) {
; CHECK-LABEL: define nofpclass(snan) float @source_known_pinf_or_nan__floor(
; CHECK-SAME: float nofpclass(ninf zero sub norm) [[PINF_OR_NAN:%.*]]) {
-; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.floor.f32(float [[PINF_OR_NAN]])
-; CHECK-NEXT: ret float [[RESULT]]
+; CHECK-NEXT: ret float [[PINF_OR_NAN]]
;
%result = call float @llvm.floor.f32(float %pinf.or.nan)
ret float %result
@@ -316,8 +307,7 @@ define nofpclass(snan) float @source_known_ninf__floor(float nofpclass(nan pinf
define nofpclass(snan) float @source_known_ninf_or_nan__floor(float nofpclass(pinf norm sub zero) %ninf.or.nan) {
; CHECK-LABEL: define nofpclass(snan) float @source_known_ninf_or_nan__floor(
; CHECK-SAME: float nofpclass(pinf zero sub norm) [[NINF_OR_NAN:%.*]]) {
-; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.floor.f32(float [[NINF_OR_NAN]])
-; CHECK-NEXT: ret float [[RESULT]]
+; CHECK-NEXT: ret float [[NINF_OR_NAN]]
;
%result = call float @llvm.floor.f32(float %ninf.or.nan)
ret float %result
@@ -366,8 +356,7 @@ define nofpclass(snan) ppc_fp128 @source_known_not_ninf__floor_ppcf128(ppc_fp128
define nofpclass(nan) float @ret_no_nans__simplify_select_nan__trunc(i1 %cond, float nofpclass(inf norm sub zero) %is.nan, float %unknown) {
; CHECK-LABEL: define nofpclass(nan) float @ret_no_nans__simplify_select_nan__trunc(
; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(inf zero sub norm) [[IS_NAN:%.*]], float [[UNKNOWN:%.*]]) {
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[IS_NAN]], float [[UNKNOWN]]
-; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.trunc.f32(float [[SELECT]])
+; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.trunc.f32(float [[UNKNOWN]])
; CHECK-NEXT: ret float [[RESULT]]
;
%select = select i1 %cond, float %is.nan, float %unknown
@@ -378,8 +367,7 @@ define nofpclass(nan) float @ret_no_nans__simplify_select_nan__trunc(i1 %cond, f
define nofpclass(nan) float @ret_no_nans__simplify_select_nan__ceil(i1 %cond, float nofpclass(inf norm sub zero) %is.nan, float %unknown) {
; CHECK-LABEL: define nofpclass(nan) float @ret_no_nans__simplify_select_nan__ceil(
; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(inf zero sub norm) [[IS_NAN:%.*]], float [[UNKNOWN:%.*]]) {
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[IS_NAN]], float [[UNKNOWN]]
-; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.ceil.f32(float [[SELECT]])
+; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.ceil.f32(float [[UNKNOWN]])
; CHECK-NEXT: ret float [[RESULT]]
;
%select = select i1 %cond, float %is.nan, float %unknown
@@ -390,8 +378,7 @@ define nofpclass(nan) float @ret_no_nans__simplify_select_nan__ceil(i1 %cond, fl
define nofpclass(nan) float @ret_no_nans__simplify_select_nan__rint(i1 %cond, float nofpclass(inf norm sub zero) %is.nan, float %unknown) {
; CHECK-LABEL: define nofpclass(nan) float @ret_no_nans__simplify_select_nan__rint(
; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(inf zero sub norm) [[IS_NAN:%.*]], float [[UNKNOWN:%.*]]) {
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[IS_NAN]], float [[UNKNOWN]]
-; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.rint.f32(float [[SELECT]])
+; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.rint.f32(float [[UNKNOWN]])
; CHECK-NEXT: ret float [[RESULT]]
;
%select = select i1 %cond, float %is.nan, float %unknown
@@ -402,8 +389,7 @@ define nofpclass(nan) float @ret_no_nans__simplify_select_nan__rint(i1 %cond, fl
define nofpclass(nan) float @ret_no_nans__simplify_select_nan__nearbyint(i1 %cond, float nofpclass(inf norm sub zero) %is.nan, float %unknown) {
; CHECK-LABEL: define nofpclass(nan) float @ret_no_nans__simplify_select_nan__nearbyint(
; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(inf zero sub norm) [[IS_NAN:%.*]], float [[UNKNOWN:%.*]]) {
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[IS_NAN]], float [[UNKNOWN]]
-; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.nearbyint.f32(float [[SELECT]])
+; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.nearbyint.f32(float [[UNKNOWN]])
; CHECK-NEXT: ret float [[RESULT]]
;
%select = select i1 %cond, float %is.nan, float %unknown
@@ -414,8 +400,7 @@ define nofpclass(nan) float @ret_no_nans__simplify_select_nan__nearbyint(i1 %con
define nofpclass(nan) float @ret_no_nans__simplify_select_nan__round(i1 %cond, float nofpclass(inf norm sub zero) %is.nan, float %unknown) {
; CHECK-LABEL: define nofpclass(nan) float @ret_no_nans__simplify_select_nan__round(
; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(inf zero sub norm) [[IS_NAN:%.*]], float [[UNKNOWN:%.*]]) {
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[IS_NAN]], float [[UNKNOWN]]
-; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.round.f32(float [[SELECT]])
+; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.round.f32(float [[UNKNOWN]])
; CHECK-NEXT: ret float [[RESULT]]
;
%select = select i1 %cond, float %is.nan, float %unknown
@@ -426,8 +411,7 @@ define nofpclass(nan) float @ret_no_nans__simplify_select_nan__round(i1 %cond, f
define nofpclass(nan) float @ret_no_nans__simplify_select_nan__roundeven(i1 %cond, float nofpclass(inf norm sub zero) %is.nan, float %unknown) {
; CHECK-LABEL: define nofpclass(nan) float @ret_no_nans__simplify_select_nan__roundeven(
; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(inf zero sub norm) [[IS_NAN:%.*]], float [[UNKNOWN:%.*]]) {
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[IS_NAN]], float [[UNKNOWN]]
-; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.roundeven.f32(float [[SELECT]])
+; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.roundeven.f32(float [[UNKNOWN]])
; CHECK-NEXT: ret float [[RESULT]]
;
%select = select i1 %cond, float %is.nan, float %unknown
@@ -438,7 +422,7 @@ define nofpclass(nan) float @ret_no_nans__simplify_select_nan__roundeven(i1 %con
define nofpclass(snan) float @source_known_sub_or_zero__trunc(float nofpclass(nan inf norm) %sub.or.zero) {
; CHECK-LABEL: define nofpclass(snan) float @source_known_sub_or_zero__trunc(
; CHECK-SAME: float nofpclass(nan inf norm) [[SUB_OR_ZERO:%.*]]) {
-; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.trunc.f32(float [[SUB_OR_ZERO]])
+; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.copysign.f32(float 0.000000e+00, float [[SUB_OR_ZERO]])
; CHECK-NEXT: ret float [[RESULT]]
;
%result = call float @llvm.trunc.f32(float %sub.or.zero)
@@ -448,8 +432,7 @@ define nofpclass(snan) float @source_known_sub_or_zero__trunc(float nofpclass(na
define nofpclass(snan) float @source_known_psub_or_pzero__trunc(float nofpclass(nan inf norm nsub nzero) %psub.or.pzero) {
; CHECK-LABEL: define nofpclass(snan) float @source_known_psub_or_pzero__trunc(
; CHECK-SAME: float nofpclass(nan inf nzero nsub norm) [[PSUB_OR_PZERO:%.*]]) {
-; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.trunc.f32(float [[PSUB_OR_PZERO]])
-; CHECK-NEXT: ret float [[RESULT]]
+; CHECK-NEXT: ret float 0.000000e+00
;
%result = call float @llvm.trunc.f32(float %psub.or.pzero)
ret float %result
@@ -458,8 +441,7 @@ define nofpclass(snan) float @source_known_psub_or_pzero__trunc(float nofpclass(
define nofpclass(snan) float @source_known_nsub_or_nzero__trunc(float nofpclass(nan inf norm psub pzero) %nsub.or.nzero) {
; CHECK-LABEL: define nofpclass(snan) float @source_known_nsub_or_nzero__trunc(
; CHECK-SAME: float nofpclass(nan inf pzero psub norm) [[NSUB_OR_NZERO:%.*]]) {
-; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.trunc.f32(float [[NSUB_OR_NZERO]])
-; CHECK-NEXT: ret float [[RESULT]]
+; CHECK-NEXT: ret float -0.000000e+00
;
%result = call float @llvm.trunc.f32(float %nsub.or.nzero)
ret float %result
@@ -498,7 +480,7 @@ define nofpclass(snan) float @source_known_nsub_or_nzero__ceil(float nofpclass(n
define nofpclass(snan) float @source_known_sub_or_zero__rint(float nofpclass(nan inf norm) %sub.or.zero) {
; CHECK-LABEL: define nofpclass(snan) float @source_known_sub_or_zero__rint(...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/174842
More information about the llvm-branch-commits
mailing list