[llvm] a954b8a - [ValueTracking] fix CannotBeNegativeZero() to disregard 'nsz' FMF

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Tue May 5 13:11:49 PDT 2020


Author: Sanjay Patel
Date: 2020-05-05T16:04:59-04:00
New Revision: a954b8a363adae382e076ba0ef1d39910778a02d

URL: https://github.com/llvm/llvm-project/commit/a954b8a363adae382e076ba0ef1d39910778a02d
DIFF: https://github.com/llvm/llvm-project/commit/a954b8a363adae382e076ba0ef1d39910778a02d.diff

LOG: [ValueTracking] fix CannotBeNegativeZero() to disregard 'nsz' FMF

The 'nsz' flag is different than 'nnan' or 'ninf' in that it does not create poison.
Make that explicit in the LangRef and fix ValueTracking analysis that misinterpreted
the definition.

This manifests as bugs in InstSimplify shown in the test diffs and as discussed in
PR45778:
https://bugs.llvm.org/show_bug.cgi?id=45778

Differential Revision: https://reviews.llvm.org/D79422

Added: 
    

Modified: 
    llvm/docs/LangRef.rst
    llvm/lib/Analysis/ValueTracking.cpp
    llvm/test/Transforms/InstSimplify/fast-math.ll

Removed: 
    


################################################################################
diff  --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index cddb5700a839..0bcb7cda76db 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -2727,7 +2727,8 @@ floating-point transformations.
 
 ``nsz``
    No Signed Zeros - Allow optimizations to treat the sign of a zero
-   argument or result as insignificant.
+   argument or result as insignificant. This does not imply that -0.0
+   is poison and/or guaranteed to not exist in the operation.
 
 ``arcp``
    Allow Reciprocal - Allow optimizations to use the reciprocal of an

diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 3d1e627e3df9..b02a4d236e99 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -3202,6 +3202,9 @@ Intrinsic::ID llvm::getIntrinsicForCallSite(const CallBase &CB,
 
 /// Return true if we can prove that the specified FP value is never equal to
 /// -0.0.
+/// NOTE: Do not check 'nsz' here because that fast-math-flag does not guarantee
+///       that a value is not -0.0. It only guarantees that -0.0 may be treated
+///       the same as +0.0 in floating-point ops.
 ///
 /// NOTE: this function will need to be revisited when we support non-default
 /// rounding modes!
@@ -3218,11 +3221,6 @@ bool llvm::CannotBeNegativeZero(const Value *V, const TargetLibraryInfo *TLI,
   if (!Op)
     return false;
 
-  // Check if the nsz fast-math flag is set.
-  if (auto *FPO = dyn_cast<FPMathOperator>(Op))
-    if (FPO->hasNoSignedZeros())
-      return true;
-
   // (fadd x, 0.0) is guaranteed to return +0.0, not -0.0.
   if (match(Op, m_FAdd(m_Value(), m_PosZeroFP())))
     return true;

diff  --git a/llvm/test/Transforms/InstSimplify/fast-math.ll b/llvm/test/Transforms/InstSimplify/fast-math.ll
index a53d6ff6982c..2eea3efb1cd1 100644
--- a/llvm/test/Transforms/InstSimplify/fast-math.ll
+++ b/llvm/test/Transforms/InstSimplify/fast-math.ll
@@ -293,10 +293,13 @@ define float @fold_fadd_nsz_x_0(float %a) {
   ret float %add
 }
 
+; 'nsz' does not guarantee that -0.0 does not occur, so this does not simplify.
+
 define float @fold_fadd_cannot_be_neg0_nsz_src_x_0(float %a, float %b) {
 ; CHECK-LABEL: @fold_fadd_cannot_be_neg0_nsz_src_x_0(
 ; CHECK-NEXT:    [[NSZ:%.*]] = fmul nsz float [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT:    ret float [[NSZ]]
+; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[NSZ]], 0.000000e+00
+; CHECK-NEXT:    ret float [[ADD]]
 ;
   %nsz = fmul nsz float %a, %b
   %add = fadd float %nsz, 0.0
@@ -313,11 +316,14 @@ define float @fold_fadd_cannot_be_neg0_fabs_src_x_0(float %a) {
   ret float %add
 }
 
+; 'nsz' does not guarantee that -0.0 does not occur, so this does not simplify.
+
 define float @fold_fadd_cannot_be_neg0_sqrt_nsz_src_x_0(float %a, float %b) {
 ; CHECK-LABEL: @fold_fadd_cannot_be_neg0_sqrt_nsz_src_x_0(
 ; CHECK-NEXT:    [[NSZ:%.*]] = fmul nsz float [[A:%.*]], [[B:%.*]]
 ; CHECK-NEXT:    [[SQRT:%.*]] = call float @llvm.sqrt.f32(float [[NSZ]])
-; CHECK-NEXT:    ret float [[SQRT]]
+; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[SQRT]], 0.000000e+00
+; CHECK-NEXT:    ret float [[ADD]]
 ;
   %nsz = fmul nsz float %a, %b
   %sqrt = call float @llvm.sqrt.f32(float %nsz)
@@ -325,11 +331,14 @@ define float @fold_fadd_cannot_be_neg0_sqrt_nsz_src_x_0(float %a, float %b) {
   ret float %add
 }
 
+; 'nsz' does not guarantee that -0.0 does not occur, so this does not simplify.
+
 define float @fold_fadd_cannot_be_neg0_canonicalize_nsz_src_x_0(float %a, float %b) {
 ; CHECK-LABEL: @fold_fadd_cannot_be_neg0_canonicalize_nsz_src_x_0(
 ; CHECK-NEXT:    [[NSZ:%.*]] = fmul nsz float [[A:%.*]], [[B:%.*]]
 ; CHECK-NEXT:    [[CANON:%.*]] = call float @llvm.canonicalize.f32(float [[NSZ]])
-; CHECK-NEXT:    ret float [[CANON]]
+; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[CANON]], 0.000000e+00
+; CHECK-NEXT:    ret float [[ADD]]
 ;
   %nsz = fmul nsz float %a, %b
   %canon = call float @llvm.canonicalize.f32(float %nsz)


        


More information about the llvm-commits mailing list