/// 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!
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;
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
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)
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)