-
Notifications
You must be signed in to change notification settings - Fork 15.7k
InstCombine: Handle fmul in SimplifyDemandedFPClass #173872
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
InstCombine: Handle fmul in SimplifyDemandedFPClass #173872
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
|
@llvm/pr-subscribers-llvm-support @llvm/pr-subscribers-llvm-analysis Author: Matt Arsenault (arsenm) ChangesPatch is 30.69 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/173872.diff 5 Files Affected:
diff --git a/llvm/include/llvm/Support/KnownFPClass.h b/llvm/include/llvm/Support/KnownFPClass.h
index bf70ddb272e29..62df87ad8a67e 100644
--- a/llvm/include/llvm/Support/KnownFPClass.h
+++ b/llvm/include/llvm/Support/KnownFPClass.h
@@ -54,6 +54,9 @@ struct KnownFPClass {
/// Return true if it's known this can never be an infinity.
bool isKnownNeverInfinity() const { return isKnownNever(fcInf); }
+ /// Return true if it's known this can never be an infinity or nan
+ bool isKnownNeverInfOrNaN() const { return isKnownNever(fcInf | fcNan); }
+
/// Return true if it's known this can never be +infinity.
bool isKnownNeverPosInfinity() const { return isKnownNever(fcPosInf); }
@@ -119,6 +122,17 @@ struct KnownFPClass {
return isKnownNever(OrderedGreaterThanZeroMask);
}
+ /// Return true if it's know this can never be a negative value or a logical
+ /// 0.
+ ///
+ /// NaN --> true
+ /// x >= -0 --> false
+ /// nsub --> true if mode is ieee, false otherwise.
+ /// x < -0 --> true
+ bool cannotBeOrderedGreaterEqZero(DenormalMode Mode) const {
+ return isKnownNever(fcPositive) && isKnownNeverLogicalNegZero(Mode);
+ }
+
KnownFPClass &operator|=(const KnownFPClass &RHS) {
KnownFPClasses = KnownFPClasses | RHS.KnownFPClasses;
@@ -165,6 +179,21 @@ struct KnownFPClass {
canonicalize(const KnownFPClass &Src,
DenormalMode DenormMode = DenormalMode::getDynamic());
+ /// Report known values for fmul
+ LLVM_ABI static KnownFPClass
+ fmul(const KnownFPClass &LHS, const KnownFPClass &RHS,
+ DenormalMode Mode = DenormalMode::getDynamic());
+
+ // Special case of fmul x, x.
+ static KnownFPClass square(const KnownFPClass &Src,
+ DenormalMode Mode = DenormalMode::getDynamic()) {
+ KnownFPClass Known = fmul(Src, Src, Mode);
+
+ // X, * X is always non-negative or a NaN.
+ Known.knownNot(fcNegative);
+ return Known;
+ }
+
/// Report known values for exp, exp2 and exp10.
LLVM_ABI static KnownFPClass exp(const KnownFPClass &Src);
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index cf7c6796f76c7..757bf28144371 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5704,66 +5704,12 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
computeKnownFPClass(Op->getOperand(0), DemandedElts, fcAllFlags, KnownLHS,
Q, Depth + 1);
- // xor sign bit.
- if ((KnownLHS.isKnownNever(fcNegative) &&
- KnownRHS.isKnownNever(fcNegative)) ||
- (KnownLHS.isKnownNever(fcPositive) &&
- KnownRHS.isKnownNever(fcPositive)))
- Known.knownNot(fcNegative);
-
- if ((KnownLHS.isKnownAlways(fcNegative | fcNan) &&
- KnownRHS.isKnownNever(fcNegative)) ||
- (KnownLHS.isKnownNever(fcNegative) &&
- KnownRHS.isKnownAlways(fcNegative | fcNan)))
- Known.knownNot(fcPositive);
-
- // inf * anything => inf or nan
- if (KnownLHS.isKnownAlways(fcInf | fcNan) ||
- KnownRHS.isKnownAlways(fcInf | fcNan))
- Known.knownNot(fcNormal | fcSubnormal | fcZero);
-
- // 0 * anything => 0 or nan
- if (KnownRHS.isKnownAlways(fcZero | fcNan) ||
- KnownLHS.isKnownAlways(fcZero | fcNan))
- Known.knownNot(fcNormal | fcSubnormal | fcInf);
-
- // +/-0 * +/-inf = nan
- if ((KnownLHS.isKnownAlways(fcZero | fcNan) &&
- KnownRHS.isKnownAlways(fcInf | fcNan)) ||
- (KnownLHS.isKnownAlways(fcInf | fcNan) &&
- KnownRHS.isKnownAlways(fcZero | fcNan)))
- Known.knownNot(~fcNan);
-
- if (!KnownLHS.isKnownNeverNaN() || !KnownRHS.isKnownNeverNaN())
- break;
-
- if (KnownLHS.SignBit && KnownRHS.SignBit) {
- if (*KnownLHS.SignBit == *KnownRHS.SignBit)
- Known.signBitMustBeZero();
- else
- Known.signBitMustBeOne();
- }
-
- // If 0 * +/-inf produces NaN.
- if (KnownLHS.isKnownNeverInfinity() && KnownRHS.isKnownNeverInfinity()) {
- Known.knownNot(fcNan);
- break;
- }
-
const Function *F = cast<Instruction>(Op)->getFunction();
- if (!F)
- break;
-
- Type *OpTy = Op->getType()->getScalarType();
- const fltSemantics &FltSem = OpTy->getFltSemantics();
- DenormalMode Mode = F->getDenormalMode(FltSem);
-
- if ((KnownRHS.isKnownNeverInfinity() ||
- KnownLHS.isKnownNeverLogicalZero(Mode)) &&
- (KnownLHS.isKnownNeverInfinity() ||
- KnownRHS.isKnownNeverLogicalZero(Mode)))
- Known.knownNot(fcNan);
-
+ DenormalMode Mode =
+ F ? F->getDenormalMode(
+ Op->getType()->getScalarType()->getFltSemantics())
+ : DenormalMode::getDynamic();
+ Known = KnownFPClass::fmul(KnownLHS, KnownRHS, Mode);
break;
}
case Instruction::FDiv:
diff --git a/llvm/lib/Support/KnownFPClass.cpp b/llvm/lib/Support/KnownFPClass.cpp
index 9ca040366b611..cfed2e5aaf5e0 100644
--- a/llvm/lib/Support/KnownFPClass.cpp
+++ b/llvm/lib/Support/KnownFPClass.cpp
@@ -141,6 +141,64 @@ KnownFPClass KnownFPClass::canonicalize(const KnownFPClass &KnownSrc,
return Known;
}
+KnownFPClass KnownFPClass::fmul(const KnownFPClass &KnownLHS,
+ const KnownFPClass &KnownRHS,
+ DenormalMode Mode) {
+ KnownFPClass Known;
+
+ // xor sign bit.
+ if ((KnownLHS.isKnownNever(fcNegative) &&
+ KnownRHS.isKnownNever(fcNegative)) ||
+ (KnownLHS.isKnownNever(fcPositive) && KnownRHS.isKnownNever(fcPositive)))
+ Known.knownNot(fcNegative);
+
+ if ((KnownLHS.isKnownAlways(fcNegative | fcNan) &&
+ KnownRHS.isKnownNever(fcNegative)) ||
+ (KnownLHS.isKnownNever(fcNegative) &&
+ KnownRHS.isKnownAlways(fcNegative | fcNan)))
+ Known.knownNot(fcPositive);
+
+ // inf * anything => inf or nan
+ if (KnownLHS.isKnownAlways(fcInf) || KnownRHS.isKnownAlways(fcInf))
+ Known.knownNot(fcNormal | fcSubnormal | fcZero);
+
+ // 0 * anything => 0 or nan
+ if (KnownRHS.isKnownAlways(fcZero | fcNan) ||
+ KnownLHS.isKnownAlways(fcZero | fcNan))
+ Known.knownNot(fcNormal | fcSubnormal | fcInf);
+
+ // +/-0 * +/-inf = nan
+ if ((KnownLHS.isKnownAlways(fcZero | fcNan) &&
+ KnownRHS.isKnownAlways(fcInf | fcNan)) ||
+ (KnownLHS.isKnownAlways(fcInf | fcNan) &&
+ KnownRHS.isKnownAlways(fcZero | fcNan)))
+ Known.knownNot(~fcNan);
+
+ if (!KnownLHS.isKnownNeverNaN() || !KnownRHS.isKnownNeverNaN())
+ return Known;
+
+ if (KnownLHS.SignBit && KnownRHS.SignBit) {
+ if (*KnownLHS.SignBit == *KnownRHS.SignBit)
+ Known.signBitMustBeZero();
+ else
+ Known.signBitMustBeOne();
+ }
+
+ // If 0 * +/-inf produces NaN.
+ if (KnownLHS.isKnownNeverInfinity() && KnownRHS.isKnownNeverInfinity()) {
+ Known.knownNot(fcNan);
+ return Known;
+ }
+
+ if ((KnownRHS.isKnownNeverInfinity() ||
+ KnownLHS.isKnownNeverLogicalZero(Mode)) &&
+ (KnownLHS.isKnownNeverInfinity() ||
+ KnownRHS.isKnownNeverLogicalZero(Mode)))
+ Known.knownNot(fcNan);
+
+ return Known;
+}
+
KnownFPClass KnownFPClass::exp(const KnownFPClass &KnownSrc) {
KnownFPClass Known;
Known.knownNot(fcNegative);
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 519e321572072..1c997db8e85ad 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2005,13 +2005,18 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
/// For floating-point classes that resolve to a single bit pattern, return that
/// value.
-static Constant *getFPClassConstant(Type *Ty, FPClassTest Mask) {
+static Constant *getFPClassConstant(Type *Ty, FPClassTest Mask,
+ bool IsCanonicalizing = false) {
if (Mask == fcNone)
return PoisonValue::get(Ty);
if (Mask == fcPosZero)
return Constant::getNullValue(Ty);
+ // Turn any possible snans into quiet if we can.
+ if (Mask == fcNan && IsCanonicalizing)
+ return ConstantFP::getQNaN(Ty);
+
// TODO: Support aggregate types that are allowed by FPMathOperator.
if (Ty->isAggregateType())
return nullptr;
@@ -2280,6 +2285,122 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Value *V,
Known = KnownLHS | KnownRHS;
break;
}
+ case Instruction::FMul: {
+ KnownFPClass KnownLHS, KnownRHS;
+
+ Value *X = I->getOperand(0);
+ Value *Y = I->getOperand(1);
+
+ FPClassTest SrcDemandedMask = DemandedMask & (fcNan | fcZero | fcSubnormal);
+
+ if (DemandedMask & fcInf) {
+ // mul x, inf = inf
+ // mul large_x, large_y = inf
+ SrcDemandedMask |= fcSubnormal | fcNormal | fcInf;
+ }
+
+ if (DemandedMask & fcNan) {
+ // mul +/-inf, 0 => nan
+ SrcDemandedMask |= fcZero | fcInf;
+
+ // TODO: Mode check
+ // mul +/-inf, sub => nan if daz
+ SrcDemandedMask |= fcSubnormal;
+ }
+
+ if (X == Y) {
+ if (SimplifyDemandedFPClass(I, 0, SrcDemandedMask, KnownLHS, Depth + 1))
+ return I;
+ Type *EltTy = VTy->getScalarType();
+
+ DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
+ Known = KnownFPClass::square(KnownLHS, Mode);
+
+ // Propagate known result to simplify edge case checks.
+ if ((DemandedMask & fcNan) == fcNone)
+ Known.knownNot(fcNan);
+ if ((DemandedMask & fcPosInf) == fcNone)
+ Known.knownNot(fcInf);
+
+ FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+ if (Constant *Folded =
+ getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true))
+ return Folded;
+
+ if (Known.isKnownAlways(fcPosZero | fcPosInf | fcNan)) {
+ // We can skip the fabs if the source was already known positive.
+ if (KnownLHS.isKnownAlways(fcPositive))
+ return X;
+
+ // => fabs(x), in case this was a -inf or -0.
+ // Note: Dropping canonicalize.
+ IRBuilderBase::InsertPointGuard Guard(Builder);
+ Builder.SetInsertPoint(I);
+ Value *Fabs = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, X);
+ Fabs->takeName(I);
+ return Fabs;
+ }
+
+ return nullptr;
+ }
+
+ if (SimplifyDemandedFPClass(I, 1, SrcDemandedMask, KnownRHS, Depth + 1) ||
+ SimplifyDemandedFPClass(I, 0, SrcDemandedMask, KnownLHS, Depth + 1))
+ return I;
+
+ // Propagate nnan-ness to sources to simplify source checks.
+ if ((DemandedMask & fcNan) == fcNone) {
+ KnownLHS.knownNot(fcNan);
+ KnownRHS.knownNot(fcNan);
+ }
+
+ // TODO: Apply knowledge of no-infinity returns to sources.
+
+ // TODO: Known -0, turn into copysign(y, fneg(x)) like visitFMul.
+ if (KnownLHS.isKnownNeverInfOrNaN() &&
+ KnownRHS.isKnownAlways(fcPosZero | fcNan)) {
+ // => copysign(+0, lhs)
+ // Note: Dropping canonicalize
+ Value *Copysign = Builder.CreateCopySign(Y, X);
+ Copysign->takeName(I);
+ return Copysign;
+ }
+
+ if (KnownLHS.isKnownAlways(fcPosZero | fcNan) &&
+ KnownRHS.isKnownNeverInfOrNaN()) {
+ // => copysign(+0, rhs)
+ // Note: Dropping canonicalize
+ Value *Copysign = Builder.CreateCopySign(X, Y);
+ Copysign->takeName(I);
+ return Copysign;
+ }
+
+ Type *EltTy = VTy->getScalarType();
+ DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
+
+ if (KnownLHS.isKnownAlways(fcInf | fcNan) &&
+ (KnownRHS.isKnownNeverNaN() &&
+ KnownRHS.cannotBeOrderedGreaterEqZero(Mode))) {
+ // Note: Dropping canonicalize
+ Value *Neg = Builder.CreateFNeg(X);
+ Neg->takeName(I);
+ return Neg;
+ }
+
+ if (KnownRHS.isKnownAlways(fcInf | fcNan) &&
+ (KnownLHS.isKnownNeverNaN() &&
+ KnownLHS.cannotBeOrderedGreaterEqZero(Mode))) {
+ // Note: Dropping canonicalize
+ Value *Neg = Builder.CreateFNeg(Y);
+ Neg->takeName(I);
+ return Neg;
+ }
+
+ Known = KnownFPClass::fmul(KnownLHS, KnownRHS, Mode);
+
+ FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+ return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+ }
default:
Known = computeKnownFPClass(I, ~DemandedMask, CxtI, Depth + 1);
break;
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll
index 594d5fbddb61e..503262a503a0d 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll
@@ -46,8 +46,7 @@ define nofpclass(inf) float @ret_nofpclass_inf__fmul_unknown_or_pinf(i1 %cond, f
define nofpclass(pinf pnorm psub pzero) float @ret_only_negative_results_or_nan_square(float %x) {
; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @ret_only_negative_results_or_nan_square(
; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT: [[MUL:%.*]] = fmul float [[X]], [[X]]
-; CHECK-NEXT: ret float [[MUL]]
+; CHECK-NEXT: ret float 0x7FF8000000000000
;
%mul = fmul float %x, %x
ret float %mul
@@ -85,8 +84,7 @@ define nofpclass(inf norm sub nan) float @ret_only_zero_results_square(float %x)
define nofpclass(inf norm sub zero) float @ret_only_nan_results_square(float %x) {
; CHECK-LABEL: define nofpclass(inf zero sub norm) float @ret_only_nan_results_square(
; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT: [[MUL:%.*]] = fmul float [[X]], [[X]]
-; CHECK-NEXT: ret float [[MUL]]
+; CHECK-NEXT: ret float 0x7FF8000000000000
;
%mul = fmul float %x, %x
ret float %mul
@@ -163,8 +161,7 @@ define nofpclass(pinf norm sub zero nan) float @ret_only_ninf_results_square(flo
define nofpclass(inf) float @ret_src_must_be_zero_square(float nofpclass(nan inf norm sub) %x) {
; CHECK-LABEL: define nofpclass(inf) float @ret_src_must_be_zero_square(
; CHECK-SAME: float nofpclass(nan inf sub norm) [[X:%.*]]) {
-; CHECK-NEXT: [[MUL:%.*]] = fmul float [[X]], [[X]]
-; CHECK-NEXT: ret float [[MUL]]
+; CHECK-NEXT: ret float 0.000000e+00
;
%mul = fmul float %x, %x
ret float %mul
@@ -173,8 +170,7 @@ define nofpclass(inf) float @ret_src_must_be_zero_square(float nofpclass(nan inf
define nofpclass(inf) float @ret_src_must_be_pzero(float nofpclass(nan inf norm sub nzero) %x) {
; CHECK-LABEL: define nofpclass(inf) float @ret_src_must_be_pzero(
; CHECK-SAME: float nofpclass(nan inf nzero sub norm) [[X:%.*]]) {
-; CHECK-NEXT: [[MUL:%.*]] = fmul float [[X]], [[X]]
-; CHECK-NEXT: ret float [[MUL]]
+; CHECK-NEXT: ret float 0.000000e+00
;
%mul = fmul float %x, %x
ret float %mul
@@ -183,8 +179,7 @@ define nofpclass(inf) float @ret_src_must_be_pzero(float nofpclass(nan inf norm
define nofpclass(inf) float @ret_src_must_be_nzero(float nofpclass(nan inf norm sub pzero) %x) {
; CHECK-LABEL: define nofpclass(inf) float @ret_src_must_be_nzero(
; CHECK-SAME: float nofpclass(nan inf pzero sub norm) [[X:%.*]]) {
-; CHECK-NEXT: [[MUL:%.*]] = fmul float [[X]], [[X]]
-; CHECK-NEXT: ret float [[MUL]]
+; CHECK-NEXT: ret float 0.000000e+00
;
%mul = fmul float %x, %x
ret float %mul
@@ -193,7 +188,7 @@ define nofpclass(inf) float @ret_src_must_be_nzero(float nofpclass(nan inf norm
define nofpclass(inf) float @ret_src_must_be_zero_or_nan_square(float nofpclass(inf norm sub) %x) {
; CHECK-LABEL: define nofpclass(inf) float @ret_src_must_be_zero_or_nan_square(
; CHECK-SAME: float nofpclass(inf sub norm) [[X:%.*]]) {
-; CHECK-NEXT: [[MUL:%.*]] = fmul float [[X]], [[X]]
+; CHECK-NEXT: [[MUL:%.*]] = call float @llvm.fabs.f32(float [[X]])
; CHECK-NEXT: ret float [[MUL]]
;
%mul = fmul float %x, %x
@@ -204,6 +199,27 @@ define nofpclass(inf) float @ret_src_must_be_zero_or_nan_square(float nofpclass(
define nofpclass(nzero) float @ret_src_must_be_nan_square(float nofpclass(inf norm sub zero) %x) {
; CHECK-LABEL: define nofpclass(nzero) float @ret_src_must_be_nan_square(
; CHECK-SAME: float nofpclass(inf zero sub norm) [[X:%.*]]) {
+; CHECK-NEXT: ret float 0x7FF8000000000000
+;
+ %mul = fmul float %x, %x
+ ret float %mul
+}
+
+; Make sure this doesn't get dropped as a no-op
+define nofpclass(nzero) float @ret_src_must_be_positive_square(float nofpclass(ninf nnorm nsub nzero) %x) {
+; CHECK-LABEL: define nofpclass(nzero) float @ret_src_must_be_positive_square(
+; CHECK-SAME: float nofpclass(ninf nzero nsub nnorm) [[X:%.*]]) {
+; CHECK-NEXT: [[MUL:%.*]] = fmul float [[X]], [[X]]
+; CHECK-NEXT: ret float [[MUL]]
+;
+ %mul = fmul float %x, %x
+ ret float %mul
+}
+
+; Make sure this doesn't get dropped as a no-op
+define nofpclass(nzero) float @ret_src_must_be_negative_square(float nofpclass(pinf pnorm psub pzero) %x) {
+; CHECK-LABEL: define nofpclass(nzero) float @ret_src_must_be_negative_square(
+; CHECK-SAME: float nofpclass(pinf pzero psub pnorm) [[X:%.*]]) {
; CHECK-NEXT: [[MUL:%.*]] = fmul float [[X]], [[X]]
; CHECK-NEXT: ret float [[MUL]]
;
@@ -215,9 +231,7 @@ define nofpclass(nzero) float @ret_src_must_be_nan_square(float nofpclass(inf no
define nofpclass(pinf pnorm psub pzero) float @ret_only_negative_results_or_nan_fabs_xy(float %x, float nofpclass(ninf nnorm nsub nzero) %y.pos.or.nan) {
; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @ret_only_negative_results_or_nan_fabs_xy(
; CHECK-SAME: float [[X:%.*]], float nofpclass(ninf nzero nsub nnorm) [[Y_POS_OR_NAN:%.*]]) {
-; CHECK-NEXT: [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
-; CHECK-NEXT: [[MUL:%.*]] = fmul float [[X_FABS]], [[Y_POS_OR_NAN]]
-; CHECK-NEXT: ret float [[MUL]]
+; CHECK-NEXT: ret float 0x7FF8000000000000
;
%x.fabs = call float @llvm.fabs.f32(float %x)
%mul = fmul float %x.fabs, %y.pos.or.nan
@@ -228,9 +242,7 @@ define nofpclass(pinf pnorm psub pzero) float @ret_only_negative_results_or_nan_
define nofpclass(pinf pnorm psub pzero nan) float @ret_only_negative_results_fabs_xy(float %x,float nofpclass(ninf nnorm nsub nzero) %y.pos.or.nan) {
; CHECK-LABEL: define nofpclass(nan pinf pzero psub pnorm) float @ret_only_negative_results_fabs_xy(
; CHECK-SAME: float [[X:%.*]], float nofpclass(ninf nzero nsub nnorm) [[Y_POS_OR_NAN:%.*]]) {
-; CHECK-NEXT: [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
-; CHECK-NEXT: [[MUL:%.*]] = fmul float [[X_FABS]], [[Y_POS_OR_NAN]]
-; CHECK-NEXT: ret float [[MUL]]
+; CHECK-NEXT: ret float poison
;
%x.fabs = call float @llvm.fabs.f32(float %x)
%mul = fmul float %x.fabs, %y.pos.or.nan
@@ -351,8 +363,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: [[X_OR_PINF:%.*]] = select i1 [[COND]], float [[X]], float 0x7FF0000000000000
-; CHECK-NEXT: [[MUL:%.*]] = fmul float [[X_OR_PINF]], [[Y]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul float [[X]], [[Y]]
; CHECK-NEXT: ret float [[MUL]]
;
%x.or.pinf = select i1 %cond, float %x, float 0x7FF0000000000000
@@ -364,8 +375,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: [[Y_OR_PINF:%.*]] = select i1 [[COND]], float [[Y]], float 0x7FF0000000000000
-; CHECK-NEXT: [[MUL:%.*]] = fmul float [[X]], [[Y_OR_PINF]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul float [[X]], [[Y]]
; CHECK-NEXT: ret float [[MUL]]
;
%y.or.pinf = select i1 %cond, float %y, float 0x7FF0000000000000
@@ -377,8 +387,7 @@ define nofpclass(inf nan) float @ret_no_inf_or_nan_results__rhs_known_non_inf(i1
define nofpclass(ninf nnorm nsub nzero) float @ret_only_positive_results_or_nan_known_negative_fmul(float nofpclass(ninf nnorm nsub nzero) %only.positive.or.nan, float nofpclass(pinf pnorm psub pzero) %only.negative.or.nan) {
; CHECK-LABEL: define nofpclass...
[truncated]
|
🪟 Windows x64 Test Results
✅ The build succeeded and all tests passed. |
🐧 Linux x64 Test Results
✅ The build succeeded and all tests passed. |
58a85fc to
fe65a5b
Compare
96f40af to
3d8c8a4
Compare
3d8c8a4 to
83c4abd
Compare
fe65a5b to
28318a0
Compare
83c4abd to
2302c6a
Compare
28318a0 to
5b8b491
Compare
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
5b8b491 to
daeaccd
Compare
2302c6a to
bb4c18d
Compare
daeaccd to
75fc190
Compare
bb4c18d to
171dd91
Compare
171dd91 to
f2f9302
Compare
75fc190 to
8f68e52
Compare
|
|
||
| if (X == Y) { | ||
| if (SimplifyDemandedFPClass(I, 0, SrcDemandedMask, KnownLHS, Depth + 1)) | ||
| return I; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a bit weird that the RHS doesn't get simplified as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is kind of broken. It works out in these tests since the only select simplifications performed can support multiple uses. Really this needs to be broken up into single and multiple use versions like SimpilfyDemandedBits is
| getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true)) | ||
| return Folded; | ||
|
|
||
| if (Known.isKnownAlways(fcPosZero | fcPosInf | fcNan)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The square of a large normal value can produce +inf. But it doesn't happen in the KnownFPClass propagation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is checking the result, which should assume inf is a possible result for normal inputs, so everything here seems to work as intended. I'll add an assert that the source isn't normal
8f68e52 to
dac5083
Compare
f2f9302 to
ec17cc4
Compare

No description provided.