From 5d3b82944dce86fba563fbaa2d2c8e7970add170 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 5 Apr 2018 23:21:15 +0000 Subject: [PATCH] [InstCombine] FP: Z - (X - Y) --> Z + (Y - X) This restores what was lost with rL73243 but without re-introducing the bug that was present in the old code. Note that we already have these transforms if the ops are marked 'fast' (and I assume that's happening somewhere in the code added with rL170471), but we clearly don't need all of 'fast' for these transforms. llvm-svn: 329362 --- lib/Transforms/InstCombine/InstCombineAddSub.cpp | 13 +++++++++++-- test/Transforms/InstCombine/fsub.ll | 12 ++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/lib/Transforms/InstCombine/InstCombineAddSub.cpp index 0541eb7b291..fac3ea86359 100644 --- a/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1698,6 +1698,7 @@ Instruction *InstCombiner::visitFSub(BinaryOperator &I) { SQ.getWithInstruction(&I))) return replaceInstUsesWith(I, V); + Value *X, *Y; if (I.hasNoSignedZeros()) { // Subtraction from -0.0 is the canonical form of fneg. // fsub nsz 0, X ==> fsub nsz -0.0, X @@ -1705,11 +1706,20 @@ Instruction *InstCombiner::visitFSub(BinaryOperator &I) { return BinaryOperator::CreateFNegFMF(Op1, &I); // With no-signed-zeros: -(X - Y) --> Y - X - Value *X, *Y; if (match(Op0, m_NegZeroFP()) && match(Op1, m_FSub(m_Value(X), m_Value(Y)))) return BinaryOperator::CreateFSubFMF(Y, X, &I); } + // More generally than above, if Op0 is not -0.0: Z - (X - Y) --> Z + (Y - X) + // Canonicalize to fadd to make analysis easier. + // This can also help codegen because fadd is commutative. + if (I.hasNoSignedZeros() || CannotBeNegativeZero(Op0, SQ.TLI)) { + if (match(Op1, m_OneUse(m_FSub(m_Value(X), m_Value(Y))))) { + Value *NewSub = Builder.CreateFSubFMF(Y, X, &I); + return BinaryOperator::CreateFAddFMF(Op0, NewSub, &I); + } + } + if (isa(Op0)) if (SelectInst *SI = dyn_cast(Op1)) if (Instruction *NV = FoldOpIntoSelect(I, SI)) @@ -1721,7 +1731,6 @@ Instruction *InstCombiner::visitFSub(BinaryOperator &I) { return BinaryOperator::CreateFAddFMF(Op0, ConstantExpr::getFNeg(C), &I); // X - (-Y) --> X + Y - Value *Y; if (match(Op1, m_FNeg(m_Value(Y)))) return BinaryOperator::CreateFAddFMF(Op0, Y, &I); diff --git a/test/Transforms/InstCombine/fsub.ll b/test/Transforms/InstCombine/fsub.ll index 184d24f5bad..c9374fbbca9 100644 --- a/test/Transforms/InstCombine/fsub.ll +++ b/test/Transforms/InstCombine/fsub.ll @@ -27,12 +27,12 @@ define float @neg_sub_nsz(float %x, float %y) { ret float %t2 } -; FIXME: With nsz: Z - (X - Y) --> Z + (Y - X) +; With nsz: Z - (X - Y) --> Z + (Y - X) define float @sub_sub_nsz(float %x, float %y, float %z) { ; CHECK-LABEL: @sub_sub_nsz( -; CHECK-NEXT: [[T1:%.*]] = fsub float [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[T2:%.*]] = fsub nsz float [[Z:%.*]], [[T1]] +; CHECK-NEXT: [[TMP1:%.*]] = fsub nsz float [[Y:%.*]], [[X:%.*]] +; CHECK-NEXT: [[T2:%.*]] = fadd nsz float [[TMP1]], [[Z:%.*]] ; CHECK-NEXT: ret float [[T2]] ; %t1 = fsub float %x, %y @@ -40,12 +40,12 @@ define float @sub_sub_nsz(float %x, float %y, float %z) { ret float %t2 } -; FIXME: Same as above: if 'Z' is not -0.0, swap fsub operands and convert to fadd. +; Same as above: if 'Z' is not -0.0, swap fsub operands and convert to fadd. define float @sub_sub_known_not_negzero(float %x, float %y) { ; CHECK-LABEL: @sub_sub_known_not_negzero( -; CHECK-NEXT: [[T1:%.*]] = fsub float [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[T2:%.*]] = fsub float 4.200000e+01, [[T1]] +; CHECK-NEXT: [[TMP1:%.*]] = fsub float [[Y:%.*]], [[X:%.*]] +; CHECK-NEXT: [[T2:%.*]] = fadd float [[TMP1]], 4.200000e+01 ; CHECK-NEXT: ret float [[T2]] ; %t1 = fsub float %x, %y