return DAG.getNode(ISD::FADD, DL, VT, N0,
GetNegatedExpression(N1, DAG, LegalOperations), Flags);
- // If 'unsafe math' is enabled, fold lots of things.
- if (Options.UnsafeFPMath) {
- // (fsub x, (fadd x, y)) -> (fneg y)
- // (fsub x, (fadd y, x)) -> (fneg y)
- if (N1.getOpcode() == ISD::FADD) {
- SDValue N10 = N1->getOperand(0);
- SDValue N11 = N1->getOperand(1);
-
- if (N10 == N0 && isNegatibleForFree(N11, LegalOperations, TLI, &Options))
- return GetNegatedExpression(N11, DAG, LegalOperations);
-
- if (N11 == N0 && isNegatibleForFree(N10, LegalOperations, TLI, &Options))
- return GetNegatedExpression(N10, DAG, LegalOperations);
- }
+ if (Options.UnsafeFPMath && N1.getOpcode() == ISD::FADD) {
+ // X - (X + Y) -> -Y
+ if (N0 == N1->getOperand(0))
+ return DAG.getNode(ISD::FNEG, DL, VT, N1->getOperand(1));
+ // X - (Y + X) -> -Y
+ if (N0 == N1->getOperand(1))
+ return DAG.getNode(ISD::FNEG, DL, VT, N1->getOperand(0));
}
// FSUB -> FMA combines:
; Y - (X + Y) --> -X
define float @fsub_fadd_common_op_fneg(float %x, float %y) {
-; ANY-LABEL: fsub_fadd_common_op_fneg:
-; ANY: # %bb.0:
-; ANY-NEXT: addss %xmm1, %xmm0
-; ANY-NEXT: subss %xmm0, %xmm1
-; ANY-NEXT: movaps %xmm1, %xmm0
-; ANY-NEXT: retq
+; STRICT-LABEL: fsub_fadd_common_op_fneg:
+; STRICT: # %bb.0:
+; STRICT-NEXT: addss %xmm1, %xmm0
+; STRICT-NEXT: subss %xmm0, %xmm1
+; STRICT-NEXT: movaps %xmm1, %xmm0
+; STRICT-NEXT: retq
+;
+; UNSAFE-LABEL: fsub_fadd_common_op_fneg:
+; UNSAFE: # %bb.0:
+; UNSAFE-NEXT: xorps {{.*}}(%rip), %xmm0
+; UNSAFE-NEXT: retq
%a = fadd float %x, %y
%r = fsub reassoc nsz float %y, %a
ret float %r
; Y - (X + Y) --> -X
define <4 x float> @fsub_fadd_common_op_fneg_vec(<4 x float> %x, <4 x float> %y) {
-; ANY-LABEL: fsub_fadd_common_op_fneg_vec:
-; ANY: # %bb.0:
-; ANY-NEXT: addps %xmm1, %xmm0
-; ANY-NEXT: subps %xmm0, %xmm1
-; ANY-NEXT: movaps %xmm1, %xmm0
-; ANY-NEXT: retq
+; STRICT-LABEL: fsub_fadd_common_op_fneg_vec:
+; STRICT: # %bb.0:
+; STRICT-NEXT: addps %xmm1, %xmm0
+; STRICT-NEXT: subps %xmm0, %xmm1
+; STRICT-NEXT: movaps %xmm1, %xmm0
+; STRICT-NEXT: retq
+;
+; UNSAFE-LABEL: fsub_fadd_common_op_fneg_vec:
+; UNSAFE: # %bb.0:
+; UNSAFE-NEXT: xorps {{.*}}(%rip), %xmm0
+; UNSAFE-NEXT: retq
%a = fadd <4 x float> %x, %y
%r = fsub nsz reassoc <4 x float> %y, %a
ret <4 x float> %r
; Commute operands of the 'add'.
define float @fsub_fadd_common_op_fneg_commute(float %x, float %y) {
-; ANY-LABEL: fsub_fadd_common_op_fneg_commute:
-; ANY: # %bb.0:
-; ANY-NEXT: addss %xmm1, %xmm0
-; ANY-NEXT: subss %xmm0, %xmm1
-; ANY-NEXT: movaps %xmm1, %xmm0
-; ANY-NEXT: retq
+; STRICT-LABEL: fsub_fadd_common_op_fneg_commute:
+; STRICT: # %bb.0:
+; STRICT-NEXT: addss %xmm1, %xmm0
+; STRICT-NEXT: subss %xmm0, %xmm1
+; STRICT-NEXT: movaps %xmm1, %xmm0
+; STRICT-NEXT: retq
+;
+; UNSAFE-LABEL: fsub_fadd_common_op_fneg_commute:
+; UNSAFE: # %bb.0:
+; UNSAFE-NEXT: xorps {{.*}}(%rip), %xmm0
+; UNSAFE-NEXT: retq
%a = fadd float %y, %x
%r = fsub reassoc nsz float %y, %a
ret float %r
; Y - (Y + X) --> -X
define <4 x float> @fsub_fadd_common_op_fneg_commute_vec(<4 x float> %x, <4 x float> %y) {
-; ANY-LABEL: fsub_fadd_common_op_fneg_commute_vec:
-; ANY: # %bb.0:
-; ANY-NEXT: addps %xmm1, %xmm0
-; ANY-NEXT: subps %xmm0, %xmm1
-; ANY-NEXT: movaps %xmm1, %xmm0
-; ANY-NEXT: retq
+; STRICT-LABEL: fsub_fadd_common_op_fneg_commute_vec:
+; STRICT: # %bb.0:
+; STRICT-NEXT: addps %xmm1, %xmm0
+; STRICT-NEXT: subps %xmm0, %xmm1
+; STRICT-NEXT: movaps %xmm1, %xmm0
+; STRICT-NEXT: retq
+;
+; UNSAFE-LABEL: fsub_fadd_common_op_fneg_commute_vec:
+; UNSAFE: # %bb.0:
+; UNSAFE-NEXT: xorps {{.*}}(%rip), %xmm0
+; UNSAFE-NEXT: retq
%a = fadd <4 x float> %y, %x
%r = fsub reassoc nsz <4 x float> %y, %a
ret <4 x float> %r