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

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue May 5 08:36:05 PDT 2020


spatel created this revision.
spatel added reviewers: nlopes, efriedma, regehr, lebedev.ri.
Herald added subscribers: hiraditya, mcrosier.
Herald added a project: LLVM.

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


https://reviews.llvm.org/D79422

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


Index: llvm/test/Transforms/InstSimplify/fast-math.ll
===================================================================
--- llvm/test/Transforms/InstSimplify/fast-math.ll
+++ llvm/test/Transforms/InstSimplify/fast-math.ll
@@ -293,10 +293,13 @@
   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 @@
   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 @@
   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)
Index: llvm/lib/Analysis/ValueTracking.cpp
===================================================================
--- llvm/lib/Analysis/ValueTracking.cpp
+++ llvm/lib/Analysis/ValueTracking.cpp
@@ -3202,6 +3202,9 @@
 
 /// 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 @@
   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;
Index: llvm/docs/LangRef.rst
===================================================================
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -2727,7 +2727,8 @@
 
 ``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


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D79422.262113.patch
Type: text/x-patch
Size: 3523 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200505/7af1a6e8/attachment.bin>


More information about the llvm-commits mailing list