diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 02137a51844a..d0794364a735 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4396,6 +4396,11 @@ static Value *SimplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF, 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; } diff --git a/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll b/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll index 0481ee456514..6350c233a932 100644 --- a/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll +++ b/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll @@ -737,9 +737,7 @@ define float @maxnum_x_y_maxnum_z(float %x, float %y, float %z) { 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 @@ -748,9 +746,7 @@ define float @fsub_fsub_common_op(float %x, float %y) { 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