Index: include/llvm/IR/PatternMatch.h =================================================================== --- include/llvm/IR/PatternMatch.h +++ include/llvm/IR/PatternMatch.h @@ -666,6 +666,13 @@ return m_FSub(m_NegZeroFP(), X); } +/// Match 'fneg X' as 'fsub +-0.0, X'. +template +inline BinaryOp_match, RHS, Instruction::FSub> +m_FNegNSZ(const RHS &X) { + return m_FSub(m_AnyZeroFP(), X); +} + template inline BinaryOp_match m_Mul(const LHS &L, const RHS &R) { Index: lib/Analysis/InstructionSimplify.cpp =================================================================== --- lib/Analysis/InstructionSimplify.cpp +++ lib/Analysis/InstructionSimplify.cpp @@ -4508,10 +4508,8 @@ // -X / X -> -1.0 and // X / -X -> -1.0 are legal when NaNs are ignored. // We can ignore signed zeros because +-0.0/+-0.0 is NaN and ignored. - if ((BinaryOperator::isFNeg(Op0, /*IgnoreZeroSign=*/true) && - BinaryOperator::getFNegArgument(Op0) == Op1) || - (BinaryOperator::isFNeg(Op1, /*IgnoreZeroSign=*/true) && - BinaryOperator::getFNegArgument(Op1) == Op0)) + if (match(Op0, m_FNegNSZ(m_Specific(Op1))) || + match(Op1, m_FNegNSZ(m_Specific(Op0)))) return ConstantFP::get(Op0->getType(), -1.0); } Index: test/Transforms/InstSimplify/fast-math.ll =================================================================== --- test/Transforms/InstSimplify/fast-math.ll +++ test/Transforms/InstSimplify/fast-math.ll @@ -401,9 +401,7 @@ define <2 x float> @fdiv_neg_vec_undef_elt(<2 x float> %f) { ; CHECK-LABEL: @fdiv_neg_vec_undef_elt( -; CHECK-NEXT: [[NEG:%.*]] = fsub <2 x float> , [[F:%.*]] -; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan <2 x float> [[F]], [[NEG]] -; CHECK-NEXT: ret <2 x float> [[DIV]] +; CHECK-NEXT: ret <2 x float> ; %neg = fsub <2 x float> , %f %div = fdiv nnan <2 x float> %f, %neg