Index: lib/Transforms/InstCombine/InstCombineAddSub.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1340,7 +1340,7 @@ // -A + B --> B - A // -A + -B --> -(A + B) - if (Value *LHSV = dyn_castFNegVal(LHS)) { + if (Value *LHSV = dyn_castFNegVal(LHS, true)) { Instruction *RI = BinaryOperator::CreateFSub(RHS, LHSV); RI->copyFastMathFlags(&I); return RI; Index: lib/Transforms/InstCombine/InstCombineInternal.h =================================================================== --- lib/Transforms/InstCombine/InstCombineInternal.h +++ lib/Transforms/InstCombine/InstCombineInternal.h @@ -345,7 +345,7 @@ bool ShouldChangeType(unsigned FromBitWidth, unsigned ToBitWidth) const; bool ShouldChangeType(Type *From, Type *To) const; Value *dyn_castNegVal(Value *V) const; - Value *dyn_castFNegVal(Value *V, bool NoSignedZero = false) const; + Value *dyn_castFNegVal(Value *V, bool IgnoreZeroSign = false) const; Type *FindElementAtOffset(PointerType *PtrTy, int64_t Offset, SmallVectorImpl &NewIndices); Instruction *FoldOpIntoSelect(Instruction &Op, SelectInst *SI); Index: test/Transforms/InstCombine/fadd.ll =================================================================== --- /dev/null +++ test/Transforms/InstCombine/fadd.ll @@ -0,0 +1,23 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +; -A + B --> B - A +define float @test1(float %x, float %y) { + %t0 = fsub float -0.000000e+00, %x + %t1 = fadd float %t0, %y + ret float %t1 + +; CHECK-LABEL: @test1 +; CHECK-NEXT: [[R:%[a-z0-9]*]] = fsub float %y, %x +; CHECK-NEXT: ret float [[R]] +} + +; -A + B --> B - A +define float @test2(float %x, float %y) { + %t0 = fsub float +0.000000e+00, %x + %t1 = fadd float %t0, %y + ret float %t1 + +; CHECK-LABEL: @test2 +; CHECK-NEXT: [[R:%[a-z0-9]*]] = fsub float %y, %x +; CHECK-NEXT: ret float [[R]] +}