[llvm] d871ef4 - [instcombine] remove fsub to fneg hacks; only emit fneg

Simon Moll via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 10 08:57:24 PDT 2020


Author: Simon Moll
Date: 2020-03-10T16:57:02+01:00
New Revision: d871ef4e6ade3797c73cbc54d9214513ee6c7468

URL: https://github.com/llvm/llvm-project/commit/d871ef4e6ade3797c73cbc54d9214513ee6c7468
DIFF: https://github.com/llvm/llvm-project/commit/d871ef4e6ade3797c73cbc54d9214513ee6c7468.diff

LOG: [instcombine] remove fsub to fneg hacks; only emit fneg

Summary: Rewrite the fsub-0.0 idiom to fneg and always emit fneg for fp
negation. This also extends the scalarization cost in instcombine for unary
operators to result in the same IR rewrites for fneg as for the idiom.

Reviewed By: cameron.mcinally

Differential Revision: https://reviews.llvm.org/D75467

Added: 
    

Modified: 
    clang/test/CodeGen/fma-builtins-constrained.c
    llvm/include/llvm/IR/PatternMatch.h
    llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
    llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
    llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
    llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
    llvm/test/Transforms/InstCombine/X86/x86-avx512.ll
    llvm/test/Transforms/InstCombine/cos-1.ll
    llvm/test/Transforms/InstCombine/fadd.ll
    llvm/test/Transforms/InstCombine/fast-math.ll
    llvm/test/Transforms/InstCombine/fdiv.ll
    llvm/test/Transforms/InstCombine/fmul.ll
    llvm/test/Transforms/InstCombine/fneg.ll
    llvm/test/Transforms/InstCombine/fpextend.ll
    llvm/test/Transforms/InstCombine/fsub.ll
    llvm/test/Transforms/InstCombine/maximum.ll
    llvm/test/Transforms/InstCombine/maxnum.ll
    llvm/test/Transforms/InstCombine/minimum.ll
    llvm/test/Transforms/InstCombine/minnum.ll
    llvm/test/Transforms/InstCombine/operand-complexity.ll
    llvm/test/Transforms/InstCombine/vec_shuffle.ll

Removed: 
    


################################################################################
diff  --git a/clang/test/CodeGen/fma-builtins-constrained.c b/clang/test/CodeGen/fma-builtins-constrained.c
index 6b299278b108..685b55cc4eb0 100644
--- a/clang/test/CodeGen/fma-builtins-constrained.c
+++ b/clang/test/CodeGen/fma-builtins-constrained.c
@@ -66,10 +66,10 @@ __m128d test_mm_fmsub_pd(__m128d a, __m128d b, __m128d c) {
 
 __m128 test_mm_fmsub_ss(__m128 a, __m128 b, __m128 c) {
   // COMMON-LABEL: test_mm_fmsub_ss
-  // COMMONIR: [[NEG:%.+]] = fneg <4 x float> %{{.+}}
   // COMMONIR: extractelement <4 x float> %{{.*}}, i64 0
   // COMMONIR: extractelement <4 x float> %{{.*}}, i64 0
   // COMMONIR: extractelement <4 x float> %{{.*}}, i64 0
+  // COMMONIR: [[NEG:%.+]] = fneg float %{{.+}}
   // UNCONSTRAINED: call float @llvm.fma.f32(float %{{.*}}, float %{{.*}}, float %{{.*}})
   // CONSTRAINED: call float @llvm.experimental.constrained.fma.f32(float %{{.*}}, float %{{.*}}, float %{{.*}}, metadata !{{.*}})
   // CHECK-ASM: vfmsub213ss
@@ -79,10 +79,10 @@ __m128 test_mm_fmsub_ss(__m128 a, __m128 b, __m128 c) {
 
 __m128d test_mm_fmsub_sd(__m128d a, __m128d b, __m128d c) {
   // COMMON-LABEL: test_mm_fmsub_sd
-  // COMMONIR: [[NEG:%.+]] = fneg <2 x double> %{{.+}}
   // COMMONIR: extractelement <2 x double> %{{.*}}, i64 0
   // COMMONIR: extractelement <2 x double> %{{.*}}, i64 0
   // COMMONIR: extractelement <2 x double> %{{.*}}, i64 0
+  // COMMONIR: [[NEG:%.+]] = fneg double %{{.+}}
   // UNCONSTRAINED: call double @llvm.fma.f64(double %{{.*}}, double %{{.*}}, double %{{.*}})
   // CONSTRAINED: call double @llvm.experimental.constrained.fma.f64(double %{{.*}}, double %{{.*}}, double %{{.*}}, metadata !{{.*}})
   // CHECK-ASM: vfmsub213sd
@@ -110,9 +110,9 @@ __m128d test_mm_fnmadd_pd(__m128d a, __m128d b, __m128d c) {
 
 __m128 test_mm_fnmadd_ss(__m128 a, __m128 b, __m128 c) {
   // COMMON-LABEL: test_mm_fnmadd_ss
-  // COMMONIR: [[NEG:%.+]] = fneg <4 x float> %{{.+}}
   // COMMONIR: extractelement <4 x float> %{{.*}}, i64 0
   // COMMONIR: extractelement <4 x float> %{{.*}}, i64 0
+  // COMMONIR: [[NEG:%.+]] = fneg float %{{.+}}
   // COMMONIR: extractelement <4 x float> %{{.*}}, i64 0
   // UNCONSTRAINED: call float @llvm.fma.f32(float %{{.*}}, float %{{.*}}, float %{{.*}})
   // CONSTRAINED: call float @llvm.experimental.constrained.fma.f32(float %{{.*}}, float %{{.*}}, float %{{.*}}, metadata !{{.*}})
@@ -123,9 +123,9 @@ __m128 test_mm_fnmadd_ss(__m128 a, __m128 b, __m128 c) {
 
 __m128d test_mm_fnmadd_sd(__m128d a, __m128d b, __m128d c) {
   // COMMON-LABEL: test_mm_fnmadd_sd
-  // COMMONIR: [[NEG:%.+]] = fneg <2 x double> %{{.+}}
   // COMMONIR: extractelement <2 x double> %{{.*}}, i64 0
   // COMMONIR: extractelement <2 x double> %{{.*}}, i64 0
+  // COMMONIR: [[NEG:%.+]] = fneg double %{{.+}}
   // COMMONIR: extractelement <2 x double> %{{.*}}, i64 0
   // UNCONSTRAINED: call double @llvm.fma.f64(double %{{.*}}, double %{{.*}}, double %{{.*}})
   // CONSTRAINED: call double @llvm.experimental.constrained.fma.f64(double %{{.*}}, double %{{.*}}, double %{{.*}}, metadata !{{.*}})
@@ -156,11 +156,11 @@ __m128d test_mm_fnmsub_pd(__m128d a, __m128d b, __m128d c) {
 
 __m128 test_mm_fnmsub_ss(__m128 a, __m128 b, __m128 c) {
   // COMMON-LABEL: test_mm_fnmsub_ss
-  // COMMONIR: [[NEG:%.+]] = fneg <4 x float> %{{.+}}
-  // COMMONIR: [[NEG2:%.+]] = fneg <4 x float> %{{.+}}
   // COMMONIR: extractelement <4 x float> %{{.*}}, i64 0
   // COMMONIR: extractelement <4 x float> %{{.*}}, i64 0
+  // COMMONIR: [[NEG:%.+]] = fneg float %{{.+}}
   // COMMONIR: extractelement <4 x float> %{{.*}}, i64 0
+  // COMMONIR: [[NEG2:%.+]] = fneg float %{{.+}}
   // UNCONSTRAINED: call float @llvm.fma.f32(float %{{.*}}, float %{{.*}}, float %{{.*}})
   // CONSTRAINED: call float @llvm.experimental.constrained.fma.f32(float %{{.*}}, float %{{.*}}, float %{{.*}}, metadata !{{.*}})
   // CHECK-ASM: vfnmsub213ss
@@ -170,11 +170,11 @@ __m128 test_mm_fnmsub_ss(__m128 a, __m128 b, __m128 c) {
 
 __m128d test_mm_fnmsub_sd(__m128d a, __m128d b, __m128d c) {
   // COMMON-LABEL: test_mm_fnmsub_sd
-  // COMMONIR: [[NEG:%.+]] = fneg <2 x double> %{{.+}}
-  // COMMONIR: [[NEG2:%.+]] = fneg <2 x double> %{{.+}}
   // COMMONIR: extractelement <2 x double> %{{.*}}, i64 0
   // COMMONIR: extractelement <2 x double> %{{.*}}, i64 0
+  // COMMONIR: [[NEG:%.+]] = fneg double %{{.+}}
   // COMMONIR: extractelement <2 x double> %{{.*}}, i64 0
+  // COMMONIR: [[NEG2:%.+]] = fneg double %{{.+}}
   // UNCONSTRAINED: call double @llvm.fma.f64(double %{{.*}}, double %{{.*}}, double %{{.*}})
   // CONSTRAINED: call double @llvm.experimental.constrained.fma.f64(double %{{.*}}, double %{{.*}}, double %{{.*}}, metadata !{{.*}})
   // CHECK-ASM: vfnmsub213sd

diff  --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index 04db59eb0f7b..9531914dfccb 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -71,6 +71,11 @@ template <typename Class> struct class_match {
 /// Match an arbitrary value and ignore it.
 inline class_match<Value> m_Value() { return class_match<Value>(); }
 
+/// Match an arbitrary unary operation and ignore it.
+inline class_match<UnaryOperator> m_UnOp() {
+  return class_match<UnaryOperator>();
+}
+
 /// Match an arbitrary binary operation and ignore it.
 inline class_match<BinaryOperator> m_BinOp() {
   return class_match<BinaryOperator>();
@@ -614,6 +619,8 @@ inline bind_ty<const Value> m_Value(const Value *&V) { return V; }
 
 /// Match an instruction, capturing it if we match.
 inline bind_ty<Instruction> m_Instruction(Instruction *&I) { return I; }
+/// Match a unary operator, capturing it if we match.
+inline bind_ty<UnaryOperator> m_UnOp(UnaryOperator *&I) { return I; }
 /// Match a binary operator, capturing it if we match.
 inline bind_ty<BinaryOperator> m_BinOp(BinaryOperator *&I) { return I; }
 /// Match a with overflow intrinsic, capturing it if we match.
@@ -785,6 +792,26 @@ inline AnyBinaryOp_match<LHS, RHS> m_BinOp(const LHS &L, const RHS &R) {
   return AnyBinaryOp_match<LHS, RHS>(L, R);
 }
 
+//===----------------------------------------------------------------------===//
+// Matcher for any unary operator.
+// TODO fuse unary, binary matcher into n-ary matcher
+//
+template <typename OP_t> struct AnyUnaryOp_match {
+  OP_t X;
+
+  AnyUnaryOp_match(const OP_t &X) : X(X) {}
+
+  template <typename OpTy> bool match(OpTy *V) {
+    if (auto *I = dyn_cast<UnaryOperator>(V))
+      return X.match(I->getOperand(0));
+    return false;
+  }
+};
+
+template <typename OP_t> inline AnyUnaryOp_match<OP_t> m_UnOp(const OP_t &X) {
+  return AnyUnaryOp_match<OP_t>(X);
+}
+
 //===----------------------------------------------------------------------===//
 // Matchers for specific binary operators.
 //

diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index cf2cac286b0b..8a143c25112e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -663,8 +663,7 @@ Value *FAddCombine::createFSub(Value *Opnd0, Value *Opnd1) {
 }
 
 Value *FAddCombine::createFNeg(Value *V) {
-  Value *Zero = cast<Value>(ConstantFP::getZeroValueForNegation(V->getType()));
-  Value *NewV = createFSub(Zero, V);
+  Value *NewV = Builder.CreateFNeg(V);
   if (Instruction *I = dyn_cast<Instruction>(NewV))
     createInstPostProc(I, true); // fneg's don't receive instruction numbers.
   return NewV;
@@ -724,8 +723,6 @@ unsigned FAddCombine::calcInstrNumber(const AddendVect &Opnds) {
     if (!CE.isMinusOne() && !CE.isOne())
       InstrNeeded++;
   }
-  if (NegOpndNum == OpndNum)
-    InstrNeeded++;
   return InstrNeeded;
 }
 
@@ -2133,10 +2130,15 @@ Instruction *InstCombiner::visitFSub(BinaryOperator &I) {
     return X;
 
   // Subtraction from -0.0 is the canonical form of fneg.
-  // fsub nsz 0, X ==> fsub nsz -0.0, X
-  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
-  if (I.hasNoSignedZeros() && match(Op0, m_PosZeroFP()))
-    return UnaryOperator::CreateFNegFMF(Op1, &I);
+  // fsub -0.0, X ==> fneg X
+  // fsub nsz 0.0, X ==> fneg nsz X
+  //
+  // FIXME This matcher does not respect FTZ or DAZ yet:
+  // fsub -0.0, Denorm ==> +-0
+  // fneg Denorm ==> -Denorm
+  Value *Op;
+  if (match(&I, m_FNeg(m_Value(Op))))
+    return UnaryOperator::CreateFNegFMF(Op, &I);
 
   if (Instruction *X = foldFNegIntoConstant(I))
     return X;
@@ -2147,6 +2149,7 @@ Instruction *InstCombiner::visitFSub(BinaryOperator &I) {
   Value *X, *Y;
   Constant *C;
 
+  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
   // If Op0 is not -0.0 or we can ignore -0.0: Z - (X - Y) --> Z + (Y - X)
   // Canonicalize to fadd to make analysis easier.
   // This can also help codegen because fadd is commutative.

diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 52edda6af1ef..0b1d9e8df039 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -1634,10 +1634,6 @@ Instruction *InstCombiner::visitFPTrunc(FPTruncInst &FPT) {
     if (match(Op, m_FNeg(m_Value(X)))) {
       Value *InnerTrunc = Builder.CreateFPTrunc(X, Ty);
 
-      // FIXME: Once we're sure that unary FNeg optimizations are on par with
-      // binary FNeg, this should always return a unary operator.
-      if (isa<BinaryOperator>(Op))
-        return UnaryOperator::CreateFNegFMF(InnerTrunc, Op);
       return UnaryOperator::CreateFNegFMF(InnerTrunc, Op);
     }
 

diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 5ef150bb0dab..0e4d1134c80d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -338,11 +338,7 @@ Instruction *InstCombiner::foldSelectOpOp(SelectInst &SI, Instruction *TI,
   if (match(TI, m_FNeg(m_Value(X))) && match(FI, m_FNeg(m_Value(Y))) &&
       (TI->hasOneUse() || FI->hasOneUse())) {
     Value *NewSel = Builder.CreateSelect(Cond, X, Y, SI.getName() + ".v", &SI);
-    // TODO: Remove the hack for the binop form when the unary op is optimized
-    //       properly with all IR passes.
-    if (TI->getOpcode() != Instruction::FNeg)
-      return UnaryOperator::CreateFNegFMF(NewSel, cast<BinaryOperator>(TI));
-    return UnaryOperator::CreateFNeg(NewSel);
+    return UnaryOperator::CreateFNegFMF(NewSel, TI);
   }
 
   // Only handle binary operators (including two-operand getelementptr) with

diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index a5f41e43f9eb..bc6696a2a325 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -63,6 +63,9 @@ static bool cheapToScalarize(Value *V, bool IsConstantExtractIndex) {
   if (match(V, m_OneUse(m_Load(m_Value()))))
     return true;
 
+  if (match(V, m_OneUse(m_UnOp())))
+    return true;
+
   Value *V0, *V1;
   if (match(V, m_OneUse(m_BinOp(m_Value(V0), m_Value(V1)))))
     if (cheapToScalarize(V0, IsConstantExtractIndex) ||
@@ -373,6 +376,16 @@ Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) {
         return ScalarPHI;
   }
 
+  // TODO come up with a n-ary matcher that subsumes both unary and
+  // binary matchers.
+  UnaryOperator *UO;
+  if (match(SrcVec, m_UnOp(UO)) && cheapToScalarize(SrcVec, IndexC)) {
+    // extelt (unop X), Index --> unop (extelt X, Index)
+    Value *X = UO->getOperand(0);
+    Value *E = Builder.CreateExtractElement(X, Index);
+    return UnaryOperator::CreateWithCopiedFlags(UO->getOpcode(), E, UO);
+  }
+
   BinaryOperator *BO;
   if (match(SrcVec, m_BinOp(BO)) && cheapToScalarize(SrcVec, IndexC)) {
     // extelt (binop X, Y), Index --> binop (extelt X, Index), (extelt Y, Index)

diff  --git a/llvm/test/Transforms/InstCombine/X86/x86-avx512.ll b/llvm/test/Transforms/InstCombine/X86/x86-avx512.ll
index 127260d0e558..3ead926f8df7 100644
--- a/llvm/test/Transforms/InstCombine/X86/x86-avx512.ll
+++ b/llvm/test/Transforms/InstCombine/X86/x86-avx512.ll
@@ -1345,7 +1345,7 @@ define <4 x float> @test_mask3_vfmsub_ss(<4 x float> %a, <4 x float> %b, <4 x fl
 ; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <4 x float> [[A:%.*]], i64 0
 ; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <4 x float> [[B:%.*]], i64 0
 ; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <4 x float> [[C:%.*]], i64 0
-; CHECK-NEXT:    [[TMP4:%.*]] = fsub float -0.000000e+00, [[TMP3]]
+; CHECK-NEXT:    [[TMP4:%.*]] = fneg float [[TMP3]]
 ; CHECK-NEXT:    [[TMP5:%.*]] = call float @llvm.fma.f32(float [[TMP1]], float [[TMP2]], float [[TMP4]])
 ; CHECK-NEXT:    [[TMP6:%.*]] = extractelement <4 x float> [[C]], i64 0
 ; CHECK-NEXT:    [[TMP7:%.*]] = bitcast i8 [[MASK:%.*]] to <8 x i1>
@@ -1378,7 +1378,7 @@ define float @test_mask3_vfmsub_ss_0(<4 x float> %a, <4 x float> %b, <4 x float>
 ; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <4 x float> [[A:%.*]], i64 0
 ; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <4 x float> [[B:%.*]], i64 0
 ; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <4 x float> [[C:%.*]], i32 0
-; CHECK-NEXT:    [[TMP4:%.*]] = fsub float -0.000000e+00, [[TMP3]]
+; CHECK-NEXT:    [[TMP4:%.*]] = fneg float [[TMP3]]
 ; CHECK-NEXT:    [[TMP5:%.*]] = call float @llvm.fma.f32(float [[TMP1]], float [[TMP2]], float [[TMP4]])
 ; CHECK-NEXT:    [[TMP6:%.*]] = extractelement <4 x float> [[C]], i32 0
 ; CHECK-NEXT:    [[TMP7:%.*]] = bitcast i8 [[MASK:%.*]] to <8 x i1>
@@ -1450,7 +1450,7 @@ define <2 x double> @test_mask3_vfmsub_sd(<2 x double> %a, <2 x double> %b, <2 x
 ; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x double> [[A:%.*]], i64 0
 ; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <2 x double> [[B:%.*]], i64 0
 ; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <2 x double> [[C:%.*]], i64 0
-; CHECK-NEXT:    [[TMP4:%.*]] = fsub double -0.000000e+00, [[TMP3]]
+; CHECK-NEXT:    [[TMP4:%.*]] = fneg double [[TMP3]]
 ; CHECK-NEXT:    [[TMP5:%.*]] = call double @llvm.fma.f64(double [[TMP1]], double [[TMP2]], double [[TMP4]])
 ; CHECK-NEXT:    [[TMP6:%.*]] = extractelement <2 x double> [[C]], i64 0
 ; CHECK-NEXT:    [[TMP7:%.*]] = bitcast i8 [[MASK:%.*]] to <8 x i1>
@@ -1479,7 +1479,7 @@ define double @test_mask3_vfmsub_sd_0(<2 x double> %a, <2 x double> %b, <2 x dou
 ; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x double> [[A:%.*]], i64 0
 ; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <2 x double> [[B:%.*]], i64 0
 ; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <2 x double> [[C:%.*]], i64 0
-; CHECK-NEXT:    [[TMP4:%.*]] = fsub double -0.000000e+00, [[TMP3]]
+; CHECK-NEXT:    [[TMP4:%.*]] = fneg double [[TMP3]]
 ; CHECK-NEXT:    [[TMP5:%.*]] = call double @llvm.fma.f64(double [[TMP1]], double [[TMP2]], double [[TMP4]])
 ; CHECK-NEXT:    [[TMP6:%.*]] = extractelement <2 x double> [[C]], i64 0
 ; CHECK-NEXT:    [[TMP7:%.*]] = bitcast i8 [[MASK:%.*]] to <8 x i1>
@@ -1543,10 +1543,10 @@ define double @test_mask3_vfmsub_sd_1_unary_fneg(<2 x double> %a, <2 x double> %
 define <4 x float> @test_mask3_vfnmsub_ss(<4 x float> %a, <4 x float> %b, <4 x float> %c, i8 %mask) {
 ; CHECK-LABEL: @test_mask3_vfnmsub_ss(
 ; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <4 x float> [[A:%.*]], i64 0
-; CHECK-NEXT:    [[TMP2:%.*]] = fsub float -0.000000e+00, [[TMP1]]
+; CHECK-NEXT:    [[TMP2:%.*]] = fneg float [[TMP1]]
 ; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <4 x float> [[B:%.*]], i64 0
 ; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <4 x float> [[C:%.*]], i64 0
-; CHECK-NEXT:    [[TMP5:%.*]] = fsub float -0.000000e+00, [[TMP4]]
+; CHECK-NEXT:    [[TMP5:%.*]] = fneg float [[TMP4]]
 ; CHECK-NEXT:    [[TMP6:%.*]] = call float @llvm.fma.f32(float [[TMP2]], float [[TMP3]], float [[TMP5]])
 ; CHECK-NEXT:    [[TMP7:%.*]] = extractelement <4 x float> [[C]], i64 0
 ; CHECK-NEXT:    [[TMP8:%.*]] = bitcast i8 [[MASK:%.*]] to <8 x i1>
@@ -1578,10 +1578,10 @@ define <4 x float> @test_mask3_vfnmsub_ss(<4 x float> %a, <4 x float> %b, <4 x f
 define float @test_mask3_vfnmsub_ss_0(<4 x float> %a, <4 x float> %b, <4 x float> %c, i8 %mask) {
 ; CHECK-LABEL: @test_mask3_vfnmsub_ss_0(
 ; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <4 x float> [[A:%.*]], i64 0
-; CHECK-NEXT:    [[TMP2:%.*]] = fsub float -0.000000e+00, [[TMP1]]
+; CHECK-NEXT:    [[TMP2:%.*]] = fneg float [[TMP1]]
 ; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <4 x float> [[B:%.*]], i64 0
 ; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <4 x float> [[C:%.*]], i32 0
-; CHECK-NEXT:    [[TMP5:%.*]] = fsub float -0.000000e+00, [[TMP4]]
+; CHECK-NEXT:    [[TMP5:%.*]] = fneg float [[TMP4]]
 ; CHECK-NEXT:    [[TMP6:%.*]] = call float @llvm.fma.f32(float [[TMP2]], float [[TMP3]], float [[TMP5]])
 ; CHECK-NEXT:    [[TMP7:%.*]] = extractelement <4 x float> [[C]], i32 0
 ; CHECK-NEXT:    [[TMP8:%.*]] = bitcast i8 [[MASK:%.*]] to <8 x i1>
@@ -1654,10 +1654,10 @@ define float @test_mask3_vfnmsub_ss_1_unary_fneg(<4 x float> %a, <4 x float> %b,
 define <2 x double> @test_mask3_vfnmsub_sd(<2 x double> %a, <2 x double> %b, <2 x double> %c, i8 %mask) {
 ; CHECK-LABEL: @test_mask3_vfnmsub_sd(
 ; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x double> [[A:%.*]], i64 0
-; CHECK-NEXT:    [[TMP2:%.*]] = fsub double -0.000000e+00, [[TMP1]]
+; CHECK-NEXT:    [[TMP2:%.*]] = fneg double [[TMP1]]
 ; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <2 x double> [[B:%.*]], i64 0
 ; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <2 x double> [[C:%.*]], i64 0
-; CHECK-NEXT:    [[TMP5:%.*]] = fsub double -0.000000e+00, [[TMP4]]
+; CHECK-NEXT:    [[TMP5:%.*]] = fneg double [[TMP4]]
 ; CHECK-NEXT:    [[TMP6:%.*]] = call double @llvm.fma.f64(double [[TMP2]], double [[TMP3]], double [[TMP5]])
 ; CHECK-NEXT:    [[TMP7:%.*]] = extractelement <2 x double> [[C]], i64 0
 ; CHECK-NEXT:    [[TMP8:%.*]] = bitcast i8 [[MASK:%.*]] to <8 x i1>
@@ -1685,10 +1685,10 @@ define <2 x double> @test_mask3_vfnmsub_sd(<2 x double> %a, <2 x double> %b, <2
 define double @test_mask3_vfnmsub_sd_0(<2 x double> %a, <2 x double> %b, <2 x double> %c, i8 %mask) {
 ; CHECK-LABEL: @test_mask3_vfnmsub_sd_0(
 ; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x double> [[A:%.*]], i64 0
-; CHECK-NEXT:    [[TMP2:%.*]] = fsub double -0.000000e+00, [[TMP1]]
+; CHECK-NEXT:    [[TMP2:%.*]] = fneg double [[TMP1]]
 ; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <2 x double> [[B:%.*]], i64 0
 ; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <2 x double> [[C:%.*]], i64 0
-; CHECK-NEXT:    [[TMP5:%.*]] = fsub double -0.000000e+00, [[TMP4]]
+; CHECK-NEXT:    [[TMP5:%.*]] = fneg double [[TMP4]]
 ; CHECK-NEXT:    [[TMP6:%.*]] = call double @llvm.fma.f64(double [[TMP2]], double [[TMP3]], double [[TMP5]])
 ; CHECK-NEXT:    [[TMP7:%.*]] = extractelement <2 x double> [[C]], i64 0
 ; CHECK-NEXT:    [[TMP8:%.*]] = bitcast i8 [[MASK:%.*]] to <8 x i1>

diff  --git a/llvm/test/Transforms/InstCombine/cos-1.ll b/llvm/test/Transforms/InstCombine/cos-1.ll
index cf668f926aa8..6b2474ed1d08 100644
--- a/llvm/test/Transforms/InstCombine/cos-1.ll
+++ b/llvm/test/Transforms/InstCombine/cos-1.ll
@@ -151,7 +151,7 @@ declare void @use(double)
 
 define double @sin_negated_arg_extra_use(double %x) {
 ; ANY-LABEL: @sin_negated_arg_extra_use(
-; ANY-NEXT:    [[NEG:%.*]] = fsub double -0.000000e+00, [[X:%.*]]
+; ANY-NEXT:    [[NEG:%.*]] = fneg double [[X:%.*]]
 ; ANY-NEXT:    [[R:%.*]] = call double @sin(double [[NEG]])
 ; ANY-NEXT:    call void @use(double [[NEG]])
 ; ANY-NEXT:    ret double [[R]]

diff  --git a/llvm/test/Transforms/InstCombine/fadd.ll b/llvm/test/Transforms/InstCombine/fadd.ll
index 24a22dc52ffd..65c2f605cf39 100644
--- a/llvm/test/Transforms/InstCombine/fadd.ll
+++ b/llvm/test/Transforms/InstCombine/fadd.ll
@@ -165,7 +165,7 @@ define double @fmul_fneg2_commute(double %x, double %py, double %pz) {
 define float @fdiv_fneg1_extra_use(float %x, float %y, float %pz) {
 ; CHECK-LABEL: @fdiv_fneg1_extra_use(
 ; CHECK-NEXT:    [[Z:%.*]] = frem float 4.200000e+01, [[PZ:%.*]]
-; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[NEG]], [[Y:%.*]]
 ; CHECK-NEXT:    call void @use(float [[DIV]])
 ; CHECK-NEXT:    [[R:%.*]] = fadd float [[Z]], [[DIV]]
@@ -185,7 +185,7 @@ define float @fdiv_fneg2_extra_use(float %x, float %py, float %pz) {
 ; CHECK-LABEL: @fdiv_fneg2_extra_use(
 ; CHECK-NEXT:    [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]]
 ; CHECK-NEXT:    [[Z:%.*]] = frem float 4.200000e+01, [[PZ:%.*]]
-; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[Y]], [[NEG]]
 ; CHECK-NEXT:    call void @use(float [[DIV]])
 ; CHECK-NEXT:    [[R:%.*]] = fadd float [[Z]], [[DIV]]
@@ -205,7 +205,7 @@ define float @fdiv_fneg2_extra_use(float %x, float %py, float %pz) {
 define <2 x float> @fmul_fneg1_extra_use(<2 x float> %x, <2 x float> %y, <2 x float> %pz) {
 ; CHECK-LABEL: @fmul_fneg1_extra_use(
 ; CHECK-NEXT:    [[Z:%.*]] = frem <2 x float> <float 4.200000e+01, float -1.000000e+00>, [[PZ:%.*]]
-; CHECK-NEXT:    [[NEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg <2 x float> [[X:%.*]]
 ; CHECK-NEXT:    [[MUL:%.*]] = fmul <2 x float> [[NEG]], [[Y:%.*]]
 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[MUL]])
 ; CHECK-NEXT:    [[R:%.*]] = fadd <2 x float> [[Z]], [[MUL]]
@@ -225,7 +225,7 @@ define float @fmul_fneg2_extra_use(float %x, float %py, float %pz) {
 ; CHECK-LABEL: @fmul_fneg2_extra_use(
 ; CHECK-NEXT:    [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]]
 ; CHECK-NEXT:    [[Z:%.*]] = frem float 4.200000e+01, [[PZ:%.*]]
-; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[Y]], [[NEG]]
 ; CHECK-NEXT:    call void @use(float [[MUL]])
 ; CHECK-NEXT:    [[R:%.*]] = fadd float [[Z]], [[MUL]]
@@ -244,7 +244,7 @@ define float @fmul_fneg2_extra_use(float %x, float %py, float %pz) {
 
 define float @fdiv_fneg1_extra_use2(float %x, float %y, float %z) {
 ; CHECK-LABEL: @fdiv_fneg1_extra_use2(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    call void @use(float [[NEG]])
 ; CHECK-NEXT:    [[TMP1:%.*]] = fdiv float [[X]], [[Y:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = fsub float [[Z:%.*]], [[TMP1]]
@@ -261,7 +261,7 @@ define float @fdiv_fneg1_extra_use2(float %x, float %y, float %z) {
 
 define float @fdiv_fneg2_extra_use2(float %x, float %y, float %z) {
 ; CHECK-LABEL: @fdiv_fneg2_extra_use2(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    call void @use(float [[NEG]])
 ; CHECK-NEXT:    [[TMP1:%.*]] = fdiv float [[Y:%.*]], [[X]]
 ; CHECK-NEXT:    [[R:%.*]] = fsub float [[Z:%.*]], [[TMP1]]
@@ -278,7 +278,7 @@ define float @fdiv_fneg2_extra_use2(float %x, float %y, float %z) {
 
 define <2 x float> @fmul_fneg1_extra_use2(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
 ; CHECK-LABEL: @fmul_fneg1_extra_use2(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg <2 x float> [[X:%.*]]
 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[NEG]])
 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul <2 x float> [[X]], [[Y:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = fsub <2 x float> [[Z:%.*]], [[TMP1]]
@@ -296,7 +296,7 @@ define <2 x float> @fmul_fneg1_extra_use2(<2 x float> %x, <2 x float> %y, <2 x f
 define float @fmul_fneg2_extra_use2(float %x, float %py, float %z) {
 ; CHECK-LABEL: @fmul_fneg2_extra_use2(
 ; CHECK-NEXT:    [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]]
-; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    call void @use(float [[NEG]])
 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul float [[Y]], [[X]]
 ; CHECK-NEXT:    [[R:%.*]] = fsub float [[Z:%.*]], [[TMP1]]
@@ -314,7 +314,7 @@ define float @fmul_fneg2_extra_use2(float %x, float %py, float %z) {
 
 define float @fdiv_fneg1_extra_use3(float %x, float %y, float %z) {
 ; CHECK-LABEL: @fdiv_fneg1_extra_use3(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    call void @use(float [[NEG]])
 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[NEG]], [[Y:%.*]]
 ; CHECK-NEXT:    call void @use(float [[DIV]])
@@ -333,7 +333,7 @@ define float @fdiv_fneg1_extra_use3(float %x, float %y, float %z) {
 
 define float @fdiv_fneg2_extra_use3(float %x, float %y, float %z) {
 ; CHECK-LABEL: @fdiv_fneg2_extra_use3(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    call void @use(float [[NEG]])
 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[Y:%.*]], [[NEG]]
 ; CHECK-NEXT:    call void @use(float [[DIV]])
@@ -352,7 +352,7 @@ define float @fdiv_fneg2_extra_use3(float %x, float %y, float %z) {
 
 define <2 x float> @fmul_fneg1_extra_use3(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
 ; CHECK-LABEL: @fmul_fneg1_extra_use3(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg <2 x float> [[X:%.*]]
 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[NEG]])
 ; CHECK-NEXT:    [[MUL:%.*]] = fmul <2 x float> [[NEG]], [[Y:%.*]]
 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[MUL]])
@@ -372,7 +372,7 @@ define <2 x float> @fmul_fneg1_extra_use3(<2 x float> %x, <2 x float> %y, <2 x f
 define float @fmul_fneg2_extra_use3(float %x, float %py, float %z) {
 ; CHECK-LABEL: @fmul_fneg2_extra_use3(
 ; CHECK-NEXT:    [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]]
-; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    call void @use(float [[NEG]])
 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[Y]], [[NEG]]
 ; CHECK-NEXT:    call void @use(float [[MUL]])

diff  --git a/llvm/test/Transforms/InstCombine/fast-math.ll b/llvm/test/Transforms/InstCombine/fast-math.ll
index 03502fa355cc..a3e334c7dfe9 100644
--- a/llvm/test/Transforms/InstCombine/fast-math.ll
+++ b/llvm/test/Transforms/InstCombine/fast-math.ll
@@ -429,7 +429,7 @@ define float @fail1(float %f1, float %f2) {
 define double @fail2(double %f1, double %f2) {
 ; CHECK-LABEL: @fail2(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd fast double [[F2:%.*]], [[F2]]
-; CHECK-NEXT:    [[TMP2:%.*]] = fsub fast double -0.000000e+00, [[TMP1]]
+; CHECK-NEXT:    [[TMP2:%.*]] = fneg fast double [[TMP1]]
 ; CHECK-NEXT:    ret double [[TMP2]]
 ;
   %t1 = fsub fast double %f1, %f2

diff  --git a/llvm/test/Transforms/InstCombine/fdiv.ll b/llvm/test/Transforms/InstCombine/fdiv.ll
index ec1119cb2457..888f5e8f9c32 100644
--- a/llvm/test/Transforms/InstCombine/fdiv.ll
+++ b/llvm/test/Transforms/InstCombine/fdiv.ll
@@ -516,7 +516,7 @@ define <2 x float> @div_constant_dividend3(<2 x float> %x) {
 
 define double @fdiv_fneg1(double %x, double %y) {
 ; CHECK-LABEL: @fdiv_fneg1(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub double -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg double [[X:%.*]]
 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv double [[NEG]], [[Y:%.*]]
 ; CHECK-NEXT:    ret double [[DIV]]
 ;
@@ -538,7 +538,7 @@ define double @fdiv_unary_fneg1(double %x, double %y) {
 
 define <2 x float> @fdiv_fneg2(<2 x float> %x, <2 x float> %y) {
 ; CHECK-LABEL: @fdiv_fneg2(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg <2 x float> [[X:%.*]]
 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv <2 x float> [[Y:%.*]], [[NEG]]
 ; CHECK-NEXT:    ret <2 x float> [[DIV]]
 ;
@@ -560,7 +560,7 @@ define <2 x float> @fdiv_unary_fneg2(<2 x float> %x, <2 x float> %y) {
 
 define float @fdiv_fneg1_extra_use(float %x, float %y) {
 ; CHECK-LABEL: @fdiv_fneg1_extra_use(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    call void @use_f32(float [[NEG]])
 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[NEG]], [[Y:%.*]]
 ; CHECK-NEXT:    ret float [[DIV]]

diff  --git a/llvm/test/Transforms/InstCombine/fmul.ll b/llvm/test/Transforms/InstCombine/fmul.ll
index 7c6b53034f23..350cc90f6834 100644
--- a/llvm/test/Transforms/InstCombine/fmul.ll
+++ b/llvm/test/Transforms/InstCombine/fmul.ll
@@ -211,8 +211,8 @@ declare void @use_f32(float)
 
 define float @neg_neg_multi_use(float %x, float %y) {
 ; CHECK-LABEL: @neg_neg_multi_use(
-; CHECK-NEXT:    [[NX:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
-; CHECK-NEXT:    [[NY:%.*]] = fsub float -0.000000e+00, [[Y:%.*]]
+; CHECK-NEXT:    [[NX:%.*]] = fneg float [[X:%.*]]
+; CHECK-NEXT:    [[NY:%.*]] = fneg float [[Y:%.*]]
 ; CHECK-NEXT:    [[MUL:%.*]] = fmul afn float [[X]], [[Y]]
 ; CHECK-NEXT:    call void @use_f32(float [[NX]])
 ; CHECK-NEXT:    call void @use_f32(float [[NY]])
@@ -246,7 +246,7 @@ define float @unary_neg_unary_neg_multi_use(float %x, float %y) {
 define float @unary_neg_neg_multi_use(float %x, float %y) {
 ; CHECK-LABEL: @unary_neg_neg_multi_use(
 ; CHECK-NEXT:    [[NX:%.*]] = fneg float [[X:%.*]]
-; CHECK-NEXT:    [[NY:%.*]] = fsub float -0.000000e+00, [[Y:%.*]]
+; CHECK-NEXT:    [[NY:%.*]] = fneg float [[Y:%.*]]
 ; CHECK-NEXT:    [[MUL:%.*]] = fmul afn float [[X]], [[Y]]
 ; CHECK-NEXT:    call void @use_f32(float [[NX]])
 ; CHECK-NEXT:    call void @use_f32(float [[NY]])
@@ -262,7 +262,7 @@ define float @unary_neg_neg_multi_use(float %x, float %y) {
 
 define float @neg_unary_neg_multi_use(float %x, float %y) {
 ; CHECK-LABEL: @neg_unary_neg_multi_use(
-; CHECK-NEXT:    [[NX:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NX:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    [[NY:%.*]] = fneg float [[Y:%.*]]
 ; CHECK-NEXT:    [[MUL:%.*]] = fmul afn float [[X]], [[Y]]
 ; CHECK-NEXT:    call void @use_f32(float [[NX]])
@@ -280,7 +280,7 @@ define float @neg_unary_neg_multi_use(float %x, float %y) {
 ; (-0.0 - X) * Y
 define float @neg_mul(float %x, float %y) {
 ; CHECK-LABEL: @neg_mul(
-; CHECK-NEXT:    [[SUB:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[SUB:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[SUB]], [[Y:%.*]]
 ; CHECK-NEXT:    ret float [[MUL]]
 ;
@@ -302,7 +302,7 @@ define float @unary_neg_mul(float %x, float %y) {
 
 define <2 x float> @neg_mul_vec(<2 x float> %x, <2 x float> %y) {
 ; CHECK-LABEL: @neg_mul_vec(
-; CHECK-NEXT:    [[SUB:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
+; CHECK-NEXT:    [[SUB:%.*]] = fneg <2 x float> [[X:%.*]]
 ; CHECK-NEXT:    [[MUL:%.*]] = fmul <2 x float> [[SUB]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <2 x float> [[MUL]]
 ;
@@ -324,7 +324,7 @@ define <2 x float> @unary_neg_mul_vec(<2 x float> %x, <2 x float> %y) {
 
 define <2 x float> @neg_mul_vec_undef(<2 x float> %x, <2 x float> %y) {
 ; CHECK-LABEL: @neg_mul_vec_undef(
-; CHECK-NEXT:    [[SUB:%.*]] = fsub <2 x float> <float undef, float -0.000000e+00>, [[X:%.*]]
+; CHECK-NEXT:    [[SUB:%.*]] = fneg <2 x float> [[X:%.*]]
 ; CHECK-NEXT:    [[MUL:%.*]] = fmul <2 x float> [[SUB]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <2 x float> [[MUL]]
 ;
@@ -347,7 +347,7 @@ define float @neg_sink_nsz(float %x, float %y) {
 
 define float @neg_sink_multi_use(float %x, float %y) {
 ; CHECK-LABEL: @neg_sink_multi_use(
-; CHECK-NEXT:    [[SUB1:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[SUB1:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[SUB1]], [[Y:%.*]]
 ; CHECK-NEXT:    [[MUL2:%.*]] = fmul float [[MUL]], [[SUB1]]
 ; CHECK-NEXT:    ret float [[MUL2]]

diff  --git a/llvm/test/Transforms/InstCombine/fneg.ll b/llvm/test/Transforms/InstCombine/fneg.ll
index 7cf42385a17e..8d3f3a3e8873 100644
--- a/llvm/test/Transforms/InstCombine/fneg.ll
+++ b/llvm/test/Transforms/InstCombine/fneg.ll
@@ -62,7 +62,7 @@ define float @fmul_fneg_fmf(float %x) {
 define float @fmul_fsub_extra_use(float %x) {
 ; CHECK-LABEL: @fmul_fsub_extra_use(
 ; CHECK-NEXT:    [[M:%.*]] = fmul float [[X:%.*]], 4.200000e+01
-; CHECK-NEXT:    [[R:%.*]] = fsub float -0.000000e+00, [[M]]
+; CHECK-NEXT:    [[R:%.*]] = fneg float [[M]]
 ; CHECK-NEXT:    call void @use(float [[M]])
 ; CHECK-NEXT:    ret float [[R]]
 ;
@@ -156,7 +156,7 @@ define float @fdiv_op1_constant_fneg_fmf(float %x) {
 define float @fdiv_op1_constant_fsub_extra_use(float %x) {
 ; CHECK-LABEL: @fdiv_op1_constant_fsub_extra_use(
 ; CHECK-NEXT:    [[D:%.*]] = fdiv float [[X:%.*]], 4.200000e+01
-; CHECK-NEXT:    [[R:%.*]] = fsub float -0.000000e+00, [[D]]
+; CHECK-NEXT:    [[R:%.*]] = fneg float [[D]]
 ; CHECK-NEXT:    call void @use(float [[D]])
 ; CHECK-NEXT:    ret float [[R]]
 ;
@@ -250,7 +250,7 @@ define float @fdiv_op0_constant_fneg_fmf(float %x) {
 define float @fdiv_op0_constant_fsub_extra_use(float %x) {
 ; CHECK-LABEL: @fdiv_op0_constant_fsub_extra_use(
 ; CHECK-NEXT:    [[D:%.*]] = fdiv float -4.200000e+01, [[X:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = fsub float -0.000000e+00, [[D]]
+; CHECK-NEXT:    [[R:%.*]] = fneg float [[D]]
 ; CHECK-NEXT:    call void @use(float [[D]])
 ; CHECK-NEXT:    ret float [[R]]
 ;
@@ -346,7 +346,7 @@ define float @fneg_fneg_sel_extra_use2(float %x, float %y, i1 %cond) {
 
 define float @fsub_fsub_sel_extra_use1(float %x, float %y, i1 %cond) {
 ; CHECK-LABEL: @fsub_fsub_sel_extra_use1(
-; CHECK-NEXT:    [[N1:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[N1:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    call void @use(float [[N1]])
 ; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[COND:%.*]], float [[X]], float [[Y:%.*]]
 ; CHECK-NEXT:    [[SEL:%.*]] = fneg float [[SEL_V]]
@@ -396,7 +396,7 @@ define float @fneg_fadd_constant(float %x) {
 define float @fake_nsz_fadd_constant(float %x) {
 ; CHECK-LABEL: @fake_nsz_fadd_constant(
 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[X:%.*]], 4.200000e+01
-; CHECK-NEXT:    [[R:%.*]] = fsub float -0.000000e+00, [[A]]
+; CHECK-NEXT:    [[R:%.*]] = fneg float [[A]]
 ; CHECK-NEXT:    ret float [[R]]
 ;
   %a = fadd float %x, 42.0
@@ -449,7 +449,7 @@ define float @fake_fneg_nsz_fadd_constant_extra_use(float %x) {
 ; CHECK-LABEL: @fake_fneg_nsz_fadd_constant_extra_use(
 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[X:%.*]], 4.200000e+01
 ; CHECK-NEXT:    call void @use(float [[A]])
-; CHECK-NEXT:    [[R:%.*]] = fsub fast float -0.000000e+00, [[A]]
+; CHECK-NEXT:    [[R:%.*]] = fneg fast float [[A]]
 ; CHECK-NEXT:    ret float [[R]]
 ;
   %a = fadd float %x, 42.0

diff  --git a/llvm/test/Transforms/InstCombine/fpextend.ll b/llvm/test/Transforms/InstCombine/fpextend.ll
index 0b2d985bfb29..1483277b93eb 100644
--- a/llvm/test/Transforms/InstCombine/fpextend.ll
+++ b/llvm/test/Transforms/InstCombine/fpextend.ll
@@ -38,7 +38,7 @@ define float @test3(float %x, float %y) nounwind  {
 
 define float @test4(float %x) nounwind  {
 ; CHECK-LABEL: @test4(
-; CHECK-NEXT:    [[T34:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[T34:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    ret float [[T34]]
 ;
   %t1 = fpext float %x to double

diff  --git a/llvm/test/Transforms/InstCombine/fsub.ll b/llvm/test/Transforms/InstCombine/fsub.ll
index f9af9987ece7..3daf97779161 100644
--- a/llvm/test/Transforms/InstCombine/fsub.ll
+++ b/llvm/test/Transforms/InstCombine/fsub.ll
@@ -6,7 +6,7 @@
 define float @test1(float %x, float %y) {
 ; CHECK-LABEL: @test1(
 ; CHECK-NEXT:    [[T1:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[T2:%.*]] = fsub float -0.000000e+00, [[T1]]
+; CHECK-NEXT:    [[T2:%.*]] = fneg float [[T1]]
 ; CHECK-NEXT:    ret float [[T2]]
 ;
   %t1 = fsub float %x, %y
@@ -58,7 +58,7 @@ declare void @use2(float, double)
 define float @neg_sub_nsz_extra_use(float %x, float %y) {
 ; CHECK-LABEL: @neg_sub_nsz_extra_use(
 ; CHECK-NEXT:    [[T1:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[T2:%.*]] = fsub nsz float -0.000000e+00, [[T1]]
+; CHECK-NEXT:    [[T2:%.*]] = fneg nsz float [[T1]]
 ; CHECK-NEXT:    call void @use(float [[T1]])
 ; CHECK-NEXT:    ret float [[T2]]
 ;
@@ -296,7 +296,7 @@ define double @unary_neg_ext_op1_fast(float %a, double %b) {
 
 define float @neg_ext_op1_extra_use(half %a, float %b) {
 ; CHECK-LABEL: @neg_ext_op1_extra_use(
-; CHECK-NEXT:    [[T1:%.*]] = fsub half 0xH8000, [[A:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = fneg half [[A:%.*]]
 ; CHECK-NEXT:    [[T2:%.*]] = fpext half [[T1]] to float
 ; CHECK-NEXT:    [[T3:%.*]] = fsub float [[B:%.*]], [[T2]]
 ; CHECK-NEXT:    call void @use(float [[T2]])
@@ -362,7 +362,7 @@ define float @unary_neg_trunc_op1_extra_use(double %a, float %b) {
 
 define float @neg_trunc_op1_extra_uses(double %a, float %b) {
 ; CHECK-LABEL: @neg_trunc_op1_extra_uses(
-; CHECK-NEXT:    [[T1:%.*]] = fsub double -0.000000e+00, [[A:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = fneg double [[A:%.*]]
 ; CHECK-NEXT:    [[T2:%.*]] = fptrunc double [[T1]] to float
 ; CHECK-NEXT:    [[T3:%.*]] = fsub float [[B:%.*]], [[T2]]
 ; CHECK-NEXT:    call void @use2(float [[T2]], double [[T1]])
@@ -454,7 +454,7 @@ define double @fsub_fmul_fneg2(double %x, double %y, double %z) {
 
 define float @fsub_fdiv_fneg1_extra_use(float %x, float %y, float %z) {
 ; CHECK-LABEL: @fsub_fdiv_fneg1_extra_use(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[NEG]], [[Y:%.*]]
 ; CHECK-NEXT:    call void @use(float [[DIV]])
 ; CHECK-NEXT:    [[R:%.*]] = fsub float [[Z:%.*]], [[DIV]]
@@ -469,7 +469,7 @@ define float @fsub_fdiv_fneg1_extra_use(float %x, float %y, float %z) {
 
 define float @fsub_fdiv_fneg2_extra_use(float %x, float %y, float %z) {
 ; CHECK-LABEL: @fsub_fdiv_fneg2_extra_use(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[Y:%.*]], [[NEG]]
 ; CHECK-NEXT:    call void @use(float [[DIV]])
 ; CHECK-NEXT:    [[R:%.*]] = fsub float [[Z:%.*]], [[DIV]]
@@ -486,7 +486,7 @@ declare void @use_vec(<2 x float>)
 
 define <2 x float> @fsub_fmul_fneg1_extra_use(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
 ; CHECK-LABEL: @fsub_fmul_fneg1_extra_use(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg <2 x float> [[X:%.*]]
 ; CHECK-NEXT:    [[MUL:%.*]] = fmul <2 x float> [[NEG]], [[Y:%.*]]
 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[MUL]])
 ; CHECK-NEXT:    [[R:%.*]] = fsub <2 x float> [[Z:%.*]], [[MUL]]
@@ -501,7 +501,7 @@ define <2 x float> @fsub_fmul_fneg1_extra_use(<2 x float> %x, <2 x float> %y, <2
 
 define float @fsub_fmul_fneg2_extra_use(float %x, float %y, float %z) {
 ; CHECK-LABEL: @fsub_fmul_fneg2_extra_use(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[NEG]], [[Y:%.*]]
 ; CHECK-NEXT:    call void @use(float [[MUL]])
 ; CHECK-NEXT:    [[R:%.*]] = fsub float [[Z:%.*]], [[MUL]]
@@ -516,7 +516,7 @@ define float @fsub_fmul_fneg2_extra_use(float %x, float %y, float %z) {
 
 define float @fsub_fdiv_fneg1_extra_use2(float %x, float %y, float %z) {
 ; CHECK-LABEL: @fsub_fdiv_fneg1_extra_use2(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    call void @use(float [[NEG]])
 ; CHECK-NEXT:    [[TMP1:%.*]] = fdiv float [[X]], [[Y:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = fadd float [[TMP1]], [[Z:%.*]]
@@ -531,7 +531,7 @@ define float @fsub_fdiv_fneg1_extra_use2(float %x, float %y, float %z) {
 
 define float @fsub_fdiv_fneg2_extra_use2(float %x, float %y, float %z) {
 ; CHECK-LABEL: @fsub_fdiv_fneg2_extra_use2(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    call void @use(float [[NEG]])
 ; CHECK-NEXT:    [[TMP1:%.*]] = fdiv float [[Y:%.*]], [[X]]
 ; CHECK-NEXT:    [[R:%.*]] = fadd float [[TMP1]], [[Z:%.*]]
@@ -546,7 +546,7 @@ define float @fsub_fdiv_fneg2_extra_use2(float %x, float %y, float %z) {
 
 define <2 x float> @fsub_fmul_fneg1_extra_use2(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
 ; CHECK-LABEL: @fsub_fmul_fneg1_extra_use2(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg <2 x float> [[X:%.*]]
 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[NEG]])
 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul <2 x float> [[X]], [[Y:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = fadd <2 x float> [[TMP1]], [[Z:%.*]]
@@ -561,7 +561,7 @@ define <2 x float> @fsub_fmul_fneg1_extra_use2(<2 x float> %x, <2 x float> %y, <
 
 define float @fsub_fmul_fneg2_extra_use2(float %x, float %y, float %z) {
 ; CHECK-LABEL: @fsub_fmul_fneg2_extra_use2(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    call void @use(float [[NEG]])
 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul float [[X]], [[Y:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = fadd float [[TMP1]], [[Z:%.*]]
@@ -576,7 +576,7 @@ define float @fsub_fmul_fneg2_extra_use2(float %x, float %y, float %z) {
 
 define float @fsub_fdiv_fneg1_extra_use3(float %x, float %y, float %z) {
 ; CHECK-LABEL: @fsub_fdiv_fneg1_extra_use3(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    call void @use(float [[NEG]])
 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[NEG]], [[Y:%.*]]
 ; CHECK-NEXT:    call void @use(float [[DIV]])
@@ -593,7 +593,7 @@ define float @fsub_fdiv_fneg1_extra_use3(float %x, float %y, float %z) {
 
 define float @fsub_fdiv_fneg2_extra_use3(float %x, float %y, float %z) {
 ; CHECK-LABEL: @fsub_fdiv_fneg2_extra_use3(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    call void @use(float [[NEG]])
 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[Y:%.*]], [[NEG]]
 ; CHECK-NEXT:    call void @use(float [[DIV]])
@@ -610,7 +610,7 @@ define float @fsub_fdiv_fneg2_extra_use3(float %x, float %y, float %z) {
 
 define <2 x float> @fsub_fmul_fneg1_extra_use3(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
 ; CHECK-LABEL: @fsub_fmul_fneg1_extra_use3(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg <2 x float> [[X:%.*]]
 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[NEG]])
 ; CHECK-NEXT:    [[MUL:%.*]] = fmul <2 x float> [[NEG]], [[Y:%.*]]
 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[MUL]])
@@ -627,7 +627,7 @@ define <2 x float> @fsub_fmul_fneg1_extra_use3(<2 x float> %x, <2 x float> %y, <
 
 define float @fsub_fmul_fneg2_extra_use3(float %x, float %y, float %z) {
 ; CHECK-LABEL: @fsub_fmul_fneg2_extra_use3(
-; CHECK-NEXT:    [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    call void @use(float [[NEG]])
 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[NEG]], [[Y:%.*]]
 ; CHECK-NEXT:    call void @use(float [[MUL]])
@@ -753,9 +753,9 @@ define float @fake_fneg_fsub_fast(float %x, float %y) {
 
 define float @fake_fneg_fsub_fast_extra_use(float %x, float %y) {
 ; CHECK-LABEL: @fake_fneg_fsub_fast_extra_use(
-; CHECK-NEXT:    [[NEGX:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEGX:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    call void @use(float [[NEGX]])
-; CHECK-NEXT:    [[SUB:%.*]] = fsub fast float [[NEGX]], [[Y:%.*]]
+; CHECK-NEXT:    [[SUB:%.*]] = fsub fast float [[NEGX:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret float [[SUB]]
 ;
   %negx = fsub float -0.0, %x

diff  --git a/llvm/test/Transforms/InstCombine/maximum.ll b/llvm/test/Transforms/InstCombine/maximum.ll
index a6fbbd8a4398..a60d0a6685af 100644
--- a/llvm/test/Transforms/InstCombine/maximum.ll
+++ b/llvm/test/Transforms/InstCombine/maximum.ll
@@ -270,7 +270,7 @@ define float @unary_neg_neg_vec_fmf(float %x, float %y) {
 declare void @use(float)
 define float @neg_neg_extra_use_x(float %x, float %y) {
 ; CHECK-LABEL: @neg_neg_extra_use_x(
-; CHECK-NEXT:    [[NEGX:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEGX:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.minimum.f32(float [[X]], float [[Y:%.*]])
 ; CHECK-NEXT:    [[R:%.*]] = fneg float [[TMP1]]
 ; CHECK-NEXT:    call void @use(float [[NEGX]])
@@ -300,7 +300,7 @@ define float @unary_neg_neg_extra_use_x(float %x, float %y) {
 
 define float @neg_neg_extra_use_y(float %x, float %y) {
 ; CHECK-LABEL: @neg_neg_extra_use_y(
-; CHECK-NEXT:    [[NEGY:%.*]] = fsub float -0.000000e+00, [[Y:%.*]]
+; CHECK-NEXT:    [[NEGY:%.*]] = fneg float [[Y:%.*]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.minimum.f32(float [[X:%.*]], float [[Y]])
 ; CHECK-NEXT:    [[R:%.*]] = fneg float [[TMP1]]
 ; CHECK-NEXT:    call void @use(float [[NEGY]])
@@ -330,8 +330,8 @@ define float @unary_neg_neg_extra_use_y(float %x, float %y) {
 
 define float @neg_neg_extra_use_x_and_y(float %x, float %y) {
 ; CHECK-LABEL: @neg_neg_extra_use_x_and_y(
-; CHECK-NEXT:    [[NEGX:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
-; CHECK-NEXT:    [[NEGY:%.*]] = fsub float -0.000000e+00, [[Y:%.*]]
+; CHECK-NEXT:    [[NEGX:%.*]] = fneg float [[X:%.*]]
+; CHECK-NEXT:    [[NEGY:%.*]] = fneg float [[Y:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = call float @llvm.maximum.f32(float [[NEGX]], float [[NEGY]])
 ; CHECK-NEXT:    call void @use(float [[NEGX]])
 ; CHECK-NEXT:    call void @use(float [[NEGY]])

diff  --git a/llvm/test/Transforms/InstCombine/maxnum.ll b/llvm/test/Transforms/InstCombine/maxnum.ll
index 509818db9b23..c89e30598db4 100644
--- a/llvm/test/Transforms/InstCombine/maxnum.ll
+++ b/llvm/test/Transforms/InstCombine/maxnum.ll
@@ -264,7 +264,7 @@ define float @unary_neg_neg_vec_fmf(float %x, float %y) {
 declare void @use(float)
 define float @neg_neg_extra_use_x(float %x, float %y) {
 ; CHECK-LABEL: @neg_neg_extra_use_x(
-; CHECK-NEXT:    [[NEGX:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEGX:%.*]] = fneg float [[X:%.*]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.minnum.f32(float [[X]], float [[Y:%.*]])
 ; CHECK-NEXT:    [[R:%.*]] = fneg float [[TMP1]]
 ; CHECK-NEXT:    call void @use(float [[NEGX]])
@@ -294,7 +294,7 @@ define float @unary_neg_neg_extra_use_x(float %x, float %y) {
 
 define float @neg_neg_extra_use_y(float %x, float %y) {
 ; CHECK-LABEL: @neg_neg_extra_use_y(
-; CHECK-NEXT:    [[NEGY:%.*]] = fsub float -0.000000e+00, [[Y:%.*]]
+; CHECK-NEXT:    [[NEGY:%.*]] = fneg float [[Y:%.*]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y]])
 ; CHECK-NEXT:    [[R:%.*]] = fneg float [[TMP1]]
 ; CHECK-NEXT:    call void @use(float [[NEGY]])
@@ -324,8 +324,8 @@ define float @unary_neg_neg_extra_use_y(float %x, float %y) {
 
 define float @neg_neg_extra_use_x_and_y(float %x, float %y) {
 ; CHECK-LABEL: @neg_neg_extra_use_x_and_y(
-; CHECK-NEXT:    [[NEGX:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
-; CHECK-NEXT:    [[NEGY:%.*]] = fsub float -0.000000e+00, [[Y:%.*]]
+; CHECK-NEXT:    [[NEGX:%.*]] = fneg float [[X:%.*]]
+; CHECK-NEXT:    [[NEGY:%.*]] = fneg float [[Y:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = call float @llvm.maxnum.f32(float [[NEGX]], float [[NEGY]])
 ; CHECK-NEXT:    call void @use(float [[NEGX]])
 ; CHECK-NEXT:    call void @use(float [[NEGY]])

diff  --git a/llvm/test/Transforms/InstCombine/minimum.ll b/llvm/test/Transforms/InstCombine/minimum.ll
index 2c22ed9d7d12..158e44ce9cc5 100644
--- a/llvm/test/Transforms/InstCombine/minimum.ll
+++ b/llvm/test/Transforms/InstCombine/minimum.ll
@@ -295,7 +295,7 @@ define <2 x double> @unary_neg_neg_vec_fmf(<2 x double> %x, <2 x double> %y) {
 declare void @use(double)
 define double @neg_neg_extra_use_x(double %x, double %y) {
 ; CHECK-LABEL: @neg_neg_extra_use_x(
-; CHECK-NEXT:    [[NEGX:%.*]] = fsub double -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEGX:%.*]] = fneg double [[X:%.*]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.maximum.f64(double [[X]], double [[Y:%.*]])
 ; CHECK-NEXT:    [[R:%.*]] = fneg double [[TMP1]]
 ; CHECK-NEXT:    call void @use(double [[NEGX]])
@@ -325,7 +325,7 @@ define double @unary_neg_neg_extra_use_x(double %x, double %y) {
 
 define double @neg_neg_extra_use_y(double %x, double %y) {
 ; CHECK-LABEL: @neg_neg_extra_use_y(
-; CHECK-NEXT:    [[NEGY:%.*]] = fsub double -0.000000e+00, [[Y:%.*]]
+; CHECK-NEXT:    [[NEGY:%.*]] = fneg double [[Y:%.*]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.maximum.f64(double [[X:%.*]], double [[Y]])
 ; CHECK-NEXT:    [[R:%.*]] = fneg double [[TMP1]]
 ; CHECK-NEXT:    call void @use(double [[NEGY]])
@@ -355,8 +355,8 @@ define double @unary_neg_neg_extra_use_y(double %x, double %y) {
 
 define double @neg_neg_extra_use_x_and_y(double %x, double %y) {
 ; CHECK-LABEL: @neg_neg_extra_use_x_and_y(
-; CHECK-NEXT:    [[NEGX:%.*]] = fsub double -0.000000e+00, [[X:%.*]]
-; CHECK-NEXT:    [[NEGY:%.*]] = fsub double -0.000000e+00, [[Y:%.*]]
+; CHECK-NEXT:    [[NEGX:%.*]] = fneg double [[X:%.*]]
+; CHECK-NEXT:    [[NEGY:%.*]] = fneg double [[Y:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = call double @llvm.minimum.f64(double [[NEGX]], double [[NEGY]])
 ; CHECK-NEXT:    call void @use(double [[NEGX]])
 ; CHECK-NEXT:    call void @use(double [[NEGY]])

diff  --git a/llvm/test/Transforms/InstCombine/minnum.ll b/llvm/test/Transforms/InstCombine/minnum.ll
index a15b29b97a58..f65d055c66e6 100644
--- a/llvm/test/Transforms/InstCombine/minnum.ll
+++ b/llvm/test/Transforms/InstCombine/minnum.ll
@@ -301,7 +301,7 @@ define <2 x double> @unary_neg_neg_vec_fmf(<2 x double> %x, <2 x double> %y) {
 declare void @use(double)
 define double @neg_neg_extra_use_x(double %x, double %y) {
 ; CHECK-LABEL: @neg_neg_extra_use_x(
-; CHECK-NEXT:    [[NEGX:%.*]] = fsub double -0.000000e+00, [[X:%.*]]
+; CHECK-NEXT:    [[NEGX:%.*]] = fneg double [[X:%.*]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.maxnum.f64(double [[X]], double [[Y:%.*]])
 ; CHECK-NEXT:    [[R:%.*]] = fneg double [[TMP1]]
 ; CHECK-NEXT:    call void @use(double [[NEGX]])
@@ -331,7 +331,7 @@ define double @unary_neg_neg_extra_use_x(double %x, double %y) {
 
 define double @neg_neg_extra_use_y(double %x, double %y) {
 ; CHECK-LABEL: @neg_neg_extra_use_y(
-; CHECK-NEXT:    [[NEGY:%.*]] = fsub double -0.000000e+00, [[Y:%.*]]
+; CHECK-NEXT:    [[NEGY:%.*]] = fneg double [[Y:%.*]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.maxnum.f64(double [[X:%.*]], double [[Y]])
 ; CHECK-NEXT:    [[R:%.*]] = fneg double [[TMP1]]
 ; CHECK-NEXT:    call void @use(double [[NEGY]])
@@ -361,8 +361,8 @@ define double @unary_neg_neg_extra_use_y(double %x, double %y) {
 
 define double @neg_neg_extra_use_x_and_y(double %x, double %y) {
 ; CHECK-LABEL: @neg_neg_extra_use_x_and_y(
-; CHECK-NEXT:    [[NEGX:%.*]] = fsub double -0.000000e+00, [[X:%.*]]
-; CHECK-NEXT:    [[NEGY:%.*]] = fsub double -0.000000e+00, [[Y:%.*]]
+; CHECK-NEXT:    [[NEGX:%.*]] = fneg double [[X:%.*]]
+; CHECK-NEXT:    [[NEGY:%.*]] = fneg double [[Y:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = call double @llvm.minnum.f64(double [[NEGX]], double [[NEGY]])
 ; CHECK-NEXT:    call void @use(double [[NEGX]])
 ; CHECK-NEXT:    call void @use(double [[NEGY]])

diff  --git a/llvm/test/Transforms/InstCombine/operand-complexity.ll b/llvm/test/Transforms/InstCombine/operand-complexity.ll
index 2cccb09328f9..c09daa4a0b14 100644
--- a/llvm/test/Transforms/InstCombine/operand-complexity.ll
+++ b/llvm/test/Transforms/InstCombine/operand-complexity.ll
@@ -92,7 +92,7 @@ declare void @use_vec(<2 x float>)
 define float @fneg(float %x) {
 ; CHECK-LABEL: @fneg(
 ; CHECK-NEXT:    [[BO:%.*]] = fdiv float [[X:%.*]], 4.200000e+01
-; CHECK-NEXT:    [[FNEGX:%.*]] = fsub float -0.000000e+00, [[X]]
+; CHECK-NEXT:    [[FNEGX:%.*]] = fneg float [[X]]
 ; CHECK-NEXT:    [[R:%.*]] = fmul float [[BO]], [[FNEGX]]
 ; CHECK-NEXT:    call void @use(float [[FNEGX]])
 ; CHECK-NEXT:    ret float [[R]]
@@ -122,7 +122,7 @@ define float @unary_fneg(float %x) {
 define <2 x float> @fneg_vec(<2 x float> %x) {
 ; CHECK-LABEL: @fneg_vec(
 ; CHECK-NEXT:    [[BO:%.*]] = fdiv <2 x float> [[X:%.*]], <float 4.200000e+01, float -4.200000e+01>
-; CHECK-NEXT:    [[FNEGX:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X]]
+; CHECK-NEXT:    [[FNEGX:%.*]] = fneg <2 x float> [[X]]
 ; CHECK-NEXT:    [[R:%.*]] = fmul <2 x float> [[BO]], [[FNEGX]]
 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[FNEGX]])
 ; CHECK-NEXT:    ret <2 x float> [[R]]
@@ -137,7 +137,7 @@ define <2 x float> @fneg_vec(<2 x float> %x) {
 define <2 x float> @fneg_vec_undef(<2 x float> %x) {
 ; CHECK-LABEL: @fneg_vec_undef(
 ; CHECK-NEXT:    [[BO:%.*]] = fdiv <2 x float> [[X:%.*]], <float 4.200000e+01, float -4.200000e+01>
-; CHECK-NEXT:    [[FNEGX:%.*]] = fsub <2 x float> <float -0.000000e+00, float undef>, [[X]]
+; CHECK-NEXT:    [[FNEGX:%.*]] = fneg <2 x float> [[X]]
 ; CHECK-NEXT:    [[R:%.*]] = fmul <2 x float> [[BO]], [[FNEGX]]
 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[FNEGX]])
 ; CHECK-NEXT:    ret <2 x float> [[R]]

diff  --git a/llvm/test/Transforms/InstCombine/vec_shuffle.ll b/llvm/test/Transforms/InstCombine/vec_shuffle.ll
index 3ba0d41ba712..e7e55b07b7cd 100644
--- a/llvm/test/Transforms/InstCombine/vec_shuffle.ll
+++ b/llvm/test/Transforms/InstCombine/vec_shuffle.ll
@@ -1263,7 +1263,7 @@ define <2 x float> @fsub_splat_constant1(<2 x float> %x) {
 
 define <2 x float> @fneg(<2 x float> %x) {
 ; CHECK-LABEL: @fneg(
-; CHECK-NEXT:    [[TMP1:%.*]] = fsub <2 x float> <float -0.000000e+00, float undef>, [[X:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fneg <2 x float> [[X:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> undef, <2 x i32> zeroinitializer
 ; CHECK-NEXT:    ret <2 x float> [[R]]
 ;


        


More information about the llvm-commits mailing list