[FPEnv][InstSimplify] Fold fsub X, -0 ==> X, when we know X is not -0

Currently the fsub optimizations in InstSimplify don't know how to fold
X - -0.0 to X when we know X is not zero and the constrained intrinsics
are used. This adds the support.

This review is split out from D107285.

Differential Revision: https://reviews.llvm.org/D119746
This commit is contained in:
Kevin P. Neal 2022-02-14 13:53:42 -05:00
parent f1ec99f973
commit c7400892ca
2 changed files with 10 additions and 15 deletions

View File

@ -5138,14 +5138,15 @@ SimplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF,
if (match(Op1, m_PosZeroFP()))
return Op0;
// fsub X, -0 ==> X, when we know X is not -0
if (canIgnoreSNaN(ExBehavior, FMF))
if (match(Op1, m_NegZeroFP()) &&
(FMF.noSignedZeros() || CannotBeNegativeZero(Op0, Q.TLI)))
return Op0;
if (!isDefaultFPEnvironment(ExBehavior, Rounding))
return nullptr;
// fsub X, -0 ==> X, when we know X is not -0
if (match(Op1, m_NegZeroFP()) &&
(FMF.noSignedZeros() || CannotBeNegativeZero(Op0, Q.TLI)))
return Op0;
// fsub -0.0, (fsub -0.0, X) ==> X
// fsub -0.0, (fneg X) ==> X
Value *X;

View File

@ -127,11 +127,9 @@ define float @fold_fsub_nsz_x_n0_ebmaytrap(float %a) #0 {
ret float %sub
}
; TODO: This will fold if we allow non-default floating point environments.
define float @fold_fsub_nnan_nsz_x_n0_ebmaytrap(float %a) #0 {
; CHECK-LABEL: @fold_fsub_nnan_nsz_x_n0_ebmaytrap(
; CHECK-NEXT: [[SUB:%.*]] = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float -0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
; CHECK-NEXT: ret float [[SUB]]
; CHECK-NEXT: ret float [[A:%.*]]
;
%sub = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float %a, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
ret float %sub
@ -147,12 +145,11 @@ define float @fold_fsub_nsz_x_n0_ebstrict(float %a) #0 {
ret float %sub
}
; TODO: This will fold if we allow non-default floating point environments.
; TODO: The instruction is expected to remain, but the result isn't used.
define float @fold_fsub_nsz_nnan_x_n0_ebstrict(float %a) #0 {
; CHECK-LABEL: @fold_fsub_nsz_nnan_x_n0_ebstrict(
; CHECK-NEXT: [[SUB:%.*]] = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float -0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
; CHECK-NEXT: ret float [[SUB]]
; CHECK-NEXT: ret float [[A]]
;
%sub = call nsz nnan float @llvm.experimental.constrained.fsub.f32(float %a, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
ret float %sub
@ -185,12 +182,10 @@ define float @fold_fsub_fabs_x_n0_ebmaytrap(float %a) #0 {
ret float %sub
}
; TODO: This will fold if we allow non-default floating point environments.
define float @fold_fsub_fabs_nnan_x_n0_ebmaytrap(float %a) #0 {
; CHECK-LABEL: @fold_fsub_fabs_nnan_x_n0_ebmaytrap(
; CHECK-NEXT: [[ABSA:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]])
; CHECK-NEXT: [[SUB:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float [[ABSA]], float -0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
; CHECK-NEXT: ret float [[SUB]]
; CHECK-NEXT: ret float [[ABSA]]
;
%absa = call float @llvm.fabs.f32(float %a)
%sub = call nnan float @llvm.experimental.constrained.fsub.f32(float %absa, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
@ -209,13 +204,12 @@ define float @fold_fsub_fabs_x_n0_ebstrict(float %a) #0 {
ret float %sub
}
; TODO: This will fold if we allow non-default floating point environments.
; TODO: The instruction is expected to remain, but the result isn't used.
define float @fold_fsub_fabs_nnan_x_n0_ebstrict(float %a) #0 {
; CHECK-LABEL: @fold_fsub_fabs_nnan_x_n0_ebstrict(
; CHECK-NEXT: [[ABSA:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]])
; CHECK-NEXT: [[SUB:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float [[ABSA]], float -0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
; CHECK-NEXT: ret float [[SUB]]
; CHECK-NEXT: ret float [[ABSA]]
;
%absa = call float @llvm.fabs.f32(float %a)
%sub = call nnan float @llvm.experimental.constrained.fsub.f32(float %absa, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.strict") #0