if (match(Op0, m_NegZeroFP()) && match(Op1, m_FNeg(m_Value(X))))
return X;
- if (!isDefaultFPEnvironment(ExBehavior, Rounding))
- return nullptr;
-
// fsub 0.0, (fsub 0.0, X) ==> X if signed zeros are ignored.
// fsub 0.0, (fneg X) ==> X if signed zeros are ignored.
- if (FMF.noSignedZeros() && match(Op0, m_AnyZeroFP()) &&
- (match(Op1, m_FSub(m_AnyZeroFP(), m_Value(X))) ||
- match(Op1, m_FNeg(m_Value(X)))))
- return X;
+ if (canIgnoreSNaN(ExBehavior, FMF))
+ if (FMF.noSignedZeros() && match(Op0, m_AnyZeroFP()) &&
+ (match(Op1, m_FSub(m_AnyZeroFP(), m_Value(X))) ||
+ match(Op1, m_FNeg(m_Value(X)))))
+ return X;
+
+ if (!isDefaultFPEnvironment(ExBehavior, Rounding))
+ return nullptr;
// fsub nnan x, x ==> 0.0
if (FMF.noNaNs() && Op0 == Op1)
ret float %ret
}
-; TODO: The instruction is expected to remain, but the result isn't used.
+; The instruction is expected to remain, but the result isn't used.
define float @fsub_nnan_x_p0_ebstrict(float %a) #0 {
; CHECK-LABEL: @fsub_nnan_x_p0_ebstrict(
; CHECK-NEXT: [[RET:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float 0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
ret float %sub
}
-; TODO: The instruction is expected to remain, but the result isn't used.
+; 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]]
ret float %sub
}
-; TODO: The instruction is expected to remain, but the result isn't used.
+; 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:%.*]])
ret float %ret
}
-; NOTE: The instruction is expected to remain, but the result isn't used.
+; The instruction is expected to remain, but the result isn't used.
define float @fsub_fneg_nnan_n0_fnX_ebstrict(float %a) #0 {
; CHECK-LABEL: @fsub_fneg_nnan_n0_fnX_ebstrict(
; CHECK-NEXT: [[NEGA:%.*]] = fneg float [[A:%.*]]
ret float %ret
}
-; TODO: This will fold if we allow non-default floating point environments.
define float @fsub_fneg_nsz_nnan_p0_fnX_ebmaytrap(float %a) #0 {
; CHECK-LABEL: @fsub_fneg_nsz_nnan_p0_fnX_ebmaytrap(
-; CHECK-NEXT: [[NEGA:%.*]] = fneg float [[A:%.*]]
-; CHECK-NEXT: [[RET:%.*]] = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
-; CHECK-NEXT: ret float [[RET]]
+; CHECK-NEXT: ret float [[A:%.*]]
;
%nega = fneg float %a
%ret = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
ret float %ret
}
-; 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.
+; The instruction is expected to remain, but the result isn't used.
define float @fsub_fneg_nnan_nsz_p0_fnX_ebstrict(float %a) #0 {
; CHECK-LABEL: @fsub_fneg_nnan_nsz_p0_fnX_ebstrict(
; CHECK-NEXT: [[NEGA:%.*]] = fneg float [[A:%.*]]
; CHECK-NEXT: [[RET:%.*]] = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
-; CHECK-NEXT: ret float [[RET]]
+; CHECK-NEXT: ret float [[A]]
;
%nega = fneg float %a
%ret = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
}
; 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.
+; The instruction is expected to remain, but the result isn't used.
define float @fsub_nnan_x_x_ebstrict(float %a) #0 {
; CHECK-LABEL: @fsub_nnan_x_x_ebstrict(
; CHECK-NEXT: [[RET:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float [[A]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]