diff options
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 15 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/fsub.ll | 3 |
2 files changed, 12 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index 578ba23604d..0541eb7b291 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1698,10 +1698,17 @@ Instruction *InstCombiner::visitFSub(BinaryOperator &I) { SQ.getWithInstruction(&I))) return replaceInstUsesWith(I, V); - // Subtraction from -0.0 is the canonical form of fneg. - // fsub nsz 0, X ==> fsub nsz -0.0, X - if (I.getFastMathFlags().noSignedZeros() && match(Op0, m_PosZeroFP())) - return BinaryOperator::CreateFNegFMF(Op1, &I); + if (I.hasNoSignedZeros()) { + // Subtraction from -0.0 is the canonical form of fneg. + // fsub nsz 0, X ==> fsub nsz -0.0, X + if (match(Op0, m_PosZeroFP())) + 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); + } if (isa<Constant>(Op0)) if (SelectInst *SI = dyn_cast<SelectInst>(Op1)) diff --git a/llvm/test/Transforms/InstCombine/fsub.ll b/llvm/test/Transforms/InstCombine/fsub.ll index 2e5b7fb48bd..3fbafc28bf4 100644 --- a/llvm/test/Transforms/InstCombine/fsub.ll +++ b/llvm/test/Transforms/InstCombine/fsub.ll @@ -19,8 +19,7 @@ define float @test1(float %x, float %y) { define float @neg_sub(float %x, float %y) { ; CHECK-LABEL: @neg_sub( -; CHECK-NEXT: [[T1:%.*]] = fsub float [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[T2:%.*]] = fsub nsz float -0.000000e+00, [[T1]] +; CHECK-NEXT: [[T2:%.*]] = fsub nsz float [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: ret float [[T2]] ; %t1 = fsub float %x, %y |