[llvm] be8aafa - ValueTracking: fdiv sign handling in computeKnownFPClass
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 26 03:22:39 PDT 2023
Author: Matt Arsenault
Date: 2023-04-26T06:22:30-04:00
New Revision: be8aafa1e2178810f06e5390f58058c31f16f66e
URL: https://github.com/llvm/llvm-project/commit/be8aafa1e2178810f06e5390f58058c31f16f66e
DIFF: https://github.com/llvm/llvm-project/commit/be8aafa1e2178810f06e5390f58058c31f16f66e.diff
LOG: ValueTracking: fdiv sign handling in computeKnownFPClass
Copy what cannotBeOrderedLessThanZeroImpl checks for fdiv.
Added:
Modified:
llvm/include/llvm/Analysis/ValueTracking.h
llvm/lib/Analysis/ValueTracking.cpp
llvm/test/Transforms/Attributor/nofpclass-fdiv.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index dc68691cae7c..5a83881b7cde 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -329,10 +329,14 @@ struct KnownFPClass {
SignBit = false;
}
+ /// Return true if the sign bit must be 0, ignoring the sign of nans.
+ bool signBitIsZeroOrNaN() const {
+ return isKnownNever(fcNegative);
+ }
+
/// Assume the sign bit is zero.
- void signBitIsZero() {
- KnownFPClasses = (KnownFPClasses & fcPositive) |
- (KnownFPClasses & fcNan);
+ void signBitMustBeZero() {
+ KnownFPClasses &= (fcPositive | fcNan);
SignBit = false;
}
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 249b22873c78..b47e7af0cbf6 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4760,7 +4760,7 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
Known.knownNot(fcSubnormal);
if (IID == Intrinsic::experimental_constrained_uitofp)
- Known.signBitIsZero();
+ Known.signBitMustBeZero();
// TODO: Copy inf handling from instructions
break;
@@ -4824,30 +4824,37 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
break;
}
case Instruction::FDiv: {
+ // X / X is always exactly 1.0 or a NaN.
+ if (Op->getOperand(0) == Op->getOperand(1)) {
+ // TODO: Could filter out snan if we inspect the operand
+ Known.KnownFPClasses = fcNan | fcPosNormal;
+ break;
+ }
+
const bool WantNan = (InterestedClasses & fcNan) != fcNone;
- if (!WantNan)
+ const bool WantNegative = (InterestedClasses & fcNegative) != fcNone;
+ if (!WantNan && !WantNegative)
break;
// TODO: FRem
KnownFPClass KnownLHS, KnownRHS;
computeKnownFPClass(Op->getOperand(1), DemandedElts,
- fcNan | fcInf | fcZero | fcSubnormal, KnownRHS,
+ fcNan | fcInf | fcZero | fcNegative, KnownRHS,
Depth + 1, Q, TLI);
- bool KnowSomethingUseful = KnownRHS.isKnownNeverNaN() ||
- KnownRHS.isKnownNeverInfinity() ||
- KnownRHS.isKnownNeverZero();
+ bool KnowSomethingUseful =
+ KnownRHS.isKnownNeverNaN() || KnownRHS.isKnownNever(fcNegative);
if (KnowSomethingUseful) {
computeKnownFPClass(Op->getOperand(0), DemandedElts,
- fcNan | fcInf | fcZero, KnownLHS, Depth + 1, Q, TLI);
+ fcNan | fcInf | fcZero | fcNegative, KnownLHS,
+ Depth + 1, Q, TLI);
}
const Function *F = cast<Instruction>(Op)->getFunction();
// Only 0/0, Inf/Inf, Inf REM x and x REM 0 produce NaN.
- // TODO: Track sign bit.
if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
(KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverInfinity()) &&
(KnownLHS.isKnownNeverLogicalZero(*F, Op->getType()) ||
@@ -4855,6 +4862,11 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
Known.knownNot(fcNan);
}
+ // X / -0.0 is -Inf (or NaN).
+ // +X / +X is +X
+ if (KnownLHS.isKnownNever(fcNegative) && KnownRHS.isKnownNever(fcNegative))
+ Known.knownNot(fcNegative);
+
break;
}
case Instruction::FPExt: {
@@ -4892,7 +4904,7 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
// sitofp and uitofp turn into +0.0 for zero.
Known.knownNot(fcNegZero);
if (Op->getOpcode() == Instruction::UIToFP)
- Known.signBitIsZero();
+ Known.signBitMustBeZero();
if (InterestedClasses & fcInf) {
// Get width of largest magnitude integer (remove a bit if signed).
diff --git a/llvm/test/Transforms/Attributor/nofpclass-fdiv.ll b/llvm/test/Transforms/Attributor/nofpclass-fdiv.ll
index 999a236a881f..82a10f60e838 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-fdiv.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-fdiv.ll
@@ -356,7 +356,7 @@ define float @ret_fdiv_daz_noinf__nozero_nosub(float nofpclass(inf) %arg0, float
}
define float @ret_fdiv_same_operands(float %arg) #0 {
-; CHECK-LABEL: define float @ret_fdiv_same_operands
+; CHECK-LABEL: define nofpclass(inf zero sub nnorm) float @ret_fdiv_same_operands
; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[FDIV]]
@@ -366,7 +366,7 @@ define float @ret_fdiv_same_operands(float %arg) #0 {
}
define float @ret_fdiv_same_operands_nosnan(float nofpclass(snan) %arg) #0 {
-; CHECK-LABEL: define float @ret_fdiv_same_operands_nosnan
+; CHECK-LABEL: define nofpclass(inf zero sub nnorm) float @ret_fdiv_same_operands_nosnan
; CHECK-SAME: (float nofpclass(snan) [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[FDIV]]
@@ -376,7 +376,7 @@ define float @ret_fdiv_same_operands_nosnan(float nofpclass(snan) %arg) #0 {
}
define float @ret_fdiv_same_operands_noqnan(float nofpclass(qnan) %arg) #0 {
-; CHECK-LABEL: define float @ret_fdiv_same_operands_noqnan
+; CHECK-LABEL: define nofpclass(inf zero sub nnorm) float @ret_fdiv_same_operands_noqnan
; CHECK-SAME: (float nofpclass(qnan) [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[FDIV]]
@@ -386,7 +386,7 @@ define float @ret_fdiv_same_operands_noqnan(float nofpclass(qnan) %arg) #0 {
}
define float @ret_fdiv_same_operands_nonan(float nofpclass(nan) %arg) #0 {
-; CHECK-LABEL: define float @ret_fdiv_same_operands_nonan
+; CHECK-LABEL: define nofpclass(inf zero sub nnorm) float @ret_fdiv_same_operands_nonan
; CHECK-SAME: (float nofpclass(nan) [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[FDIV]]
@@ -436,7 +436,7 @@ define float @ret_fdiv_no_neg(float nofpclass(ninf nsub nnorm) %arg0, float nofp
}
define float @ret_fdiv_no_neg_nzero(float nofpclass(ninf nsub nnorm nzero) %arg0, float nofpclass(ninf nsub nnorm nzero) %arg1) #0 {
-; CHECK-LABEL: define float @ret_fdiv_no_neg_nzero
+; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_fdiv_no_neg_nzero
; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nsub nnorm) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
@@ -456,7 +456,7 @@ define float @ret_fdiv_no_neg_rhs_no_nzero(float nofpclass(ninf nsub nnorm) %arg
}
define float @ret_fdiv_no_neg_no_zero_rhs(float nofpclass(ninf nsub nnorm nzero) %arg0, float nofpclass(ninf nsub nnorm zero) %arg1) #0 {
-; CHECK-LABEL: define float @ret_fdiv_no_neg_no_zero_rhs
+; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_fdiv_no_neg_no_zero_rhs
; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf zero nsub nnorm) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
More information about the llvm-commits
mailing list