diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/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 diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/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(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 --- a/llvm/test/Transforms/InstSimplify/fast-math.ll +++ b/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)