diff options
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 8 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/fast-math.ll | 7 |
2 files changed, 11 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index 052cb4ab675..f3fe09f1cb0 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1907,6 +1907,14 @@ Instruction *InstCombiner::visitFSub(BinaryOperator &I) { return replaceInstUsesWith(I, V); if (I.hasAllowReassoc() && I.hasNoSignedZeros()) { + // (Y - X) - Y --> -X + if (match(Op0, m_FSub(m_Specific(Op1), m_Value(X)))) + return BinaryOperator::CreateFNegFMF(X, &I); + + // TODO: This performs reassociative folds for FP ops. Some fraction of the + // functionality has been subsumed by simple pattern matching here and in + // InstSimplify. We should let a dedicated reassociation pass handle more + // complex pattern matching and remove this from InstCombine. if (Value *V = FAddCombine(Builder).simplify(&I)) return replaceInstUsesWith(I, V); } diff --git a/llvm/test/Transforms/InstCombine/fast-math.ll b/llvm/test/Transforms/InstCombine/fast-math.ll index 7ea9beb8456..8a802105885 100644 --- a/llvm/test/Transforms/InstCombine/fast-math.ll +++ b/llvm/test/Transforms/InstCombine/fast-math.ll @@ -335,8 +335,8 @@ define <2 x float> @fsub_fadd_common_op_fneg_commute_vec(<2 x float> %x, <2 x fl define float @fsub_fsub_common_op_fneg(float %x, float %y) { ; CHECK-LABEL: @fsub_fsub_common_op_fneg( -; CHECK-NEXT: [[TMP1:%.*]] = fsub reassoc nsz float -0.000000e+00, [[X:%.*]] -; CHECK-NEXT: ret float [[TMP1]] +; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float -0.000000e+00, [[X:%.*]] +; CHECK-NEXT: ret float [[R]] ; %s = fsub float %y, %x %r = fsub reassoc nsz float %s, %y @@ -347,8 +347,7 @@ define float @fsub_fsub_common_op_fneg(float %x, float %y) { define <2 x float> @fsub_fsub_common_op_fneg_vec(<2 x float> %x, <2 x float> %y) { ; CHECK-LABEL: @fsub_fsub_common_op_fneg_vec( -; CHECK-NEXT: [[S:%.*]] = fsub <2 x float> [[Y:%.*]], [[X:%.*]] -; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz <2 x float> [[S]], [[Y]] +; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]] ; CHECK-NEXT: ret <2 x float> [[R]] ; %s = fsub <2 x float> %y, %x |

