if (FMF.noNaNs() && Op0 == Op1)
return Constant::getNullValue(Op0->getType());
+ // Y - (Y - X) --> X
+ if (FMF.noSignedZeros() && FMF.allowReassoc() &&
+ match(Op1, m_FSub(m_Specific(Op0), m_Value(X))))
+ return X;
+
return nullptr;
}
define float @fsub_fsub_common_op(float %x, float %y) {
; CHECK-LABEL: @fsub_fsub_common_op(
-; CHECK-NEXT: [[S:%.*]] = fsub float [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float [[Y]], [[S]]
-; CHECK-NEXT: ret float [[R]]
+; CHECK-NEXT: ret float [[X:%.*]]
;
%s = fsub float %y, %x
%r = fsub reassoc nsz float %y, %s
define <2 x float> @fsub_fsub_common_op_vec(<2 x float> %x, <2 x float> %y) {
; CHECK-LABEL: @fsub_fsub_common_op_vec(
-; CHECK-NEXT: [[S:%.*]] = fsub <2 x float> [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz <2 x float> [[Y]], [[S]]
-; CHECK-NEXT: ret <2 x float> [[R]]
+; CHECK-NEXT: ret <2 x float> [[X:%.*]]
;
%s = fsub <2 x float> %y, %x
%r = fsub reassoc nsz <2 x float> %y, %s