diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2023-04-17 22:14:36 -0400 |
---|---|---|
committer | Matt Arsenault <arsenm2@gmail.com> | 2023-05-17 23:40:06 +0100 |
commit | dd61b63b5ca1c8a15013e2154bf3b30243df66bd (patch) | |
tree | 20ac548e78dfabddf682bf7b3fe8f2f28857c71d | |
parent | 6666969a08001c37b564cdd9e8da7b5c7291788c (diff) | |
download | llvm-dd61b63b5ca1c8a15013e2154bf3b30243df66bd.tar.gz |
ValueTracking: Handle sign bit for fptrunc in computeKnownFPClass
-rw-r--r-- | llvm/include/llvm/Analysis/ValueTracking.h | 2 | ||||
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 13 | ||||
-rw-r--r-- | llvm/test/Transforms/Attributor/nofpclass-fptrunc.ll | 14 |
3 files changed, 17 insertions, 12 deletions
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h index e6609f2e0073..92781c598a59 100644 --- a/llvm/include/llvm/Analysis/ValueTracking.h +++ b/llvm/include/llvm/Analysis/ValueTracking.h @@ -323,7 +323,7 @@ struct KnownFPClass { /// x > +0 --> true /// x < -0 --> false bool cannotBeOrderedLessThanZero() const { - return isKnownNever(OrderedLessThanZeroMask); + return isKnownNever(OrderedLessThanZeroMask); } /// Return true if we can prove that the analyzed floating-point value is diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 37414de4c240..05ed497b7601 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4617,17 +4617,22 @@ static void computeKnownFPClassForFPTrunc(const Operator *Op, KnownFPClass &Known, unsigned Depth, const Query &Q, const TargetLibraryInfo *TLI) { - if ((InterestedClasses & fcNan) == fcNone) + if ((InterestedClasses & + (KnownFPClass::OrderedLessThanZeroMask | fcNan)) == fcNone) return; KnownFPClass KnownSrc; computeKnownFPClass(Op->getOperand(0), DemandedElts, InterestedClasses, KnownSrc, Depth + 1, Q, TLI); - if (KnownSrc.isKnownNeverNaN()) - Known.knownNot(fcNan); + + // Sign should be preserved + // TODO: Handle cannot be ordered greater than zero + if (KnownSrc.cannotBeOrderedLessThanZero()) + Known.knownNot(KnownFPClass::OrderedLessThanZeroMask); + + Known.propagateNaN(KnownSrc, true); // Infinity needs a range check. - // TODO: Sign bit should be preserved } // TODO: Merge implementations of isKnownNeverNaN, isKnownNeverInfinity, diff --git a/llvm/test/Transforms/Attributor/nofpclass-fptrunc.ll b/llvm/test/Transforms/Attributor/nofpclass-fptrunc.ll index 9274114611a8..2e9c30b42b41 100644 --- a/llvm/test/Transforms/Attributor/nofpclass-fptrunc.ll +++ b/llvm/test/Transforms/Attributor/nofpclass-fptrunc.ll @@ -34,7 +34,7 @@ define float @ret_fptrunc_noqnan(double nofpclass(qnan) %arg0) { } define float @ret_fptrunc_nosnan(double nofpclass(snan) %arg0) { -; CHECK-LABEL: define float @ret_fptrunc_nosnan +; CHECK-LABEL: define nofpclass(snan) float @ret_fptrunc_nosnan ; CHECK-SAME: (double nofpclass(snan) [[ARG0:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[EXT:%.*]] = fptrunc double [[ARG0]] to float ; CHECK-NEXT: ret float [[EXT]] @@ -134,7 +134,7 @@ define float @ret_fptrunc_nonorm(double nofpclass(norm) %arg0) { } define float @ret_fptrunc_posonly(double nofpclass(ninf nnorm nsub nzero) %arg0) { -; CHECK-LABEL: define float @ret_fptrunc_posonly +; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @ret_fptrunc_posonly ; CHECK-SAME: (double nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[EXT:%.*]] = fptrunc double [[ARG0]] to float ; CHECK-NEXT: ret float [[EXT]] @@ -144,7 +144,7 @@ define float @ret_fptrunc_posonly(double nofpclass(ninf nnorm nsub nzero) %arg0) } define float @ret_fptrunc_posonly_zero(double nofpclass(ninf nnorm nsub) %arg0) { -; CHECK-LABEL: define float @ret_fptrunc_posonly_zero +; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @ret_fptrunc_posonly_zero ; CHECK-SAME: (double nofpclass(ninf nsub nnorm) [[ARG0:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[EXT:%.*]] = fptrunc double [[ARG0]] to float ; CHECK-NEXT: ret float [[EXT]] @@ -154,7 +154,7 @@ define float @ret_fptrunc_posonly_zero(double nofpclass(ninf nnorm nsub) %arg0) } define float @ret_fptrunc_posonly_zero_nan(double nofpclass(ninf nnorm nsub nan) %arg0) { -; CHECK-LABEL: define nofpclass(nan) float @ret_fptrunc_posonly_zero_nan +; CHECK-LABEL: define nofpclass(nan ninf nsub nnorm) float @ret_fptrunc_posonly_zero_nan ; CHECK-SAME: (double nofpclass(nan ninf nsub nnorm) [[ARG0:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[EXT:%.*]] = fptrunc double [[ARG0]] to float ; CHECK-NEXT: ret float [[EXT]] @@ -164,7 +164,7 @@ define float @ret_fptrunc_posonly_zero_nan(double nofpclass(ninf nnorm nsub nan) } define float @ret_fptrunc_posonly_nan(double nofpclass(ninf nnorm nsub nzero nan) %arg0) { -; CHECK-LABEL: define nofpclass(nan) float @ret_fptrunc_posonly_nan +; CHECK-LABEL: define nofpclass(nan ninf nsub nnorm) float @ret_fptrunc_posonly_nan ; CHECK-SAME: (double nofpclass(nan ninf nzero nsub nnorm) [[ARG0:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: [[EXT:%.*]] = fptrunc double [[ARG0]] to float ; CHECK-NEXT: ret float [[EXT]] @@ -234,9 +234,9 @@ define float @ret_fptrunc_round_noqnan(double nofpclass(qnan) %arg0) { } define float @ret_fptrunc_round_nosnan(double nofpclass(snan) %arg0) { -; CHECK-LABEL: define float @ret_fptrunc_round_nosnan +; CHECK-LABEL: define nofpclass(snan) float @ret_fptrunc_round_nosnan ; CHECK-SAME: (double nofpclass(snan) [[ARG0:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: [[EXT:%.*]] = call float @llvm.fptrunc.round.f32.f64(double [[ARG0]], metadata !"round.downward") #[[ATTR2]] +; CHECK-NEXT: [[EXT:%.*]] = call nofpclass(snan) float @llvm.fptrunc.round.f32.f64(double [[ARG0]], metadata !"round.downward") #[[ATTR2]] ; CHECK-NEXT: ret float [[EXT]] ; %ext = call float @llvm.fptrunc.round.f32.f64(double %arg0, metadata !"round.downward") |