diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4977,14 +4977,6 @@
   if (ConsiderFlags && Op->hasPoisonGeneratingFlags())
     return true;
 
-  // TODO: this should really be under the ConsiderFlags block, but currently
-  // these are not dropped by dropPoisonGeneratingFlags
-  if (const auto *FP = dyn_cast<FPMathOperator>(Op)) {
-    auto FMF = FP->getFastMathFlags();
-    if (FMF.noNaNs() || FMF.noInfs())
-      return true;
-  }
-
   unsigned Opcode = Op->getOpcode();
 
   // Check whether opcode is a poison/undef-generating operation
diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp
--- a/llvm/lib/IR/Instruction.cpp
+++ b/llvm/lib/IR/Instruction.cpp
@@ -166,7 +166,10 @@
     cast<GetElementPtrInst>(this)->setIsInBounds(false);
     break;
   }
-  // TODO: FastMathFlags!
+  if (isa<FPMathOperator>(this)) {
+    setHasNoNaNs(false);
+    setHasNoInfs(false);
+  }
 
   assert(!hasPoisonGeneratingFlags() && "must be kept in sync");
 }
diff --git a/llvm/lib/IR/Operator.cpp b/llvm/lib/IR/Operator.cpp
--- a/llvm/lib/IR/Operator.cpp
+++ b/llvm/lib/IR/Operator.cpp
@@ -39,9 +39,10 @@
     return GEP->isInBounds() || GEP->getInRangeIndex() != None;
   }
   default:
+    if (const auto *FP = dyn_cast<FPMathOperator>(this))
+      return FP->hasNoNaNs() || FP->hasNoInfs();
     return false;
   }
-  // TODO: FastMathFlags!  (On instructions, but not constexpr)
 }
 
 Type *GEPOperator::getSourceElementType() const {
diff --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll
--- a/llvm/test/Transforms/InstCombine/freeze.ll
+++ b/llvm/test/Transforms/InstCombine/freeze.ll
@@ -365,9 +365,9 @@
 
 define float @propagate_drop_fneg(float %arg) {
 ; CHECK-LABEL: @propagate_drop_fneg(
-; CHECK-NEXT:    [[V1:%.*]] = fneg nnan ninf float [[ARG:%.*]]
-; CHECK-NEXT:    [[V1_FR:%.*]] = freeze float [[V1]]
-; CHECK-NEXT:    ret float [[V1_FR]]
+; CHECK-NEXT:    [[ARG_FR:%.*]] = freeze float [[ARG:%.*]]
+; CHECK-NEXT:    [[V1:%.*]] = fneg float [[ARG_FR]]
+; CHECK-NEXT:    ret float [[V1]]
 ;
   %v1 = fneg ninf nnan float %arg
   %v1.fr = freeze float %v1
@@ -377,9 +377,9 @@
 
 define float @propagate_drop_fadd(float %arg) {
 ; CHECK-LABEL: @propagate_drop_fadd(
-; CHECK-NEXT:    [[V1:%.*]] = fadd nnan ninf float [[ARG:%.*]], 2.000000e+00
-; CHECK-NEXT:    [[V1_FR:%.*]] = freeze float [[V1]]
-; CHECK-NEXT:    ret float [[V1_FR]]
+; CHECK-NEXT:    [[ARG_FR:%.*]] = freeze float [[ARG:%.*]]
+; CHECK-NEXT:    [[V1:%.*]] = fadd float [[ARG_FR]], 2.000000e+00
+; CHECK-NEXT:    ret float [[V1]]
 ;
   %v1 = fadd ninf nnan float %arg, 2.0
   %v1.fr = freeze float %v1
@@ -388,9 +388,9 @@
 
 define float @propagate_drop_fsub(float %arg) {
 ; CHECK-LABEL: @propagate_drop_fsub(
-; CHECK-NEXT:    [[V1:%.*]] = fadd nnan ninf float [[ARG:%.*]], -2.000000e+00
-; CHECK-NEXT:    [[V1_FR:%.*]] = freeze float [[V1]]
-; CHECK-NEXT:    ret float [[V1_FR]]
+; CHECK-NEXT:    [[ARG_FR:%.*]] = freeze float [[ARG:%.*]]
+; CHECK-NEXT:    [[V1:%.*]] = fadd float [[ARG_FR]], -2.000000e+00
+; CHECK-NEXT:    ret float [[V1]]
 ;
   %v1 = fsub ninf nnan float %arg, 2.0
   %v1.fr = freeze float %v1
@@ -399,9 +399,9 @@
 
 define float @propagate_drop_fmul(float %arg) {
 ; CHECK-LABEL: @propagate_drop_fmul(
-; CHECK-NEXT:    [[V1:%.*]] = fmul nnan ninf float [[ARG:%.*]], 2.000000e+00
-; CHECK-NEXT:    [[V1_FR:%.*]] = freeze float [[V1]]
-; CHECK-NEXT:    ret float [[V1_FR]]
+; CHECK-NEXT:    [[ARG_FR:%.*]] = freeze float [[ARG:%.*]]
+; CHECK-NEXT:    [[V1:%.*]] = fmul float [[ARG_FR]], 2.000000e+00
+; CHECK-NEXT:    ret float [[V1]]
 ;
   %v1 = fmul ninf nnan float %arg, 2.0
   %v1.fr = freeze float %v1
@@ -410,9 +410,9 @@
 
 define float @propagate_drop_fdiv(float %arg) {
 ; CHECK-LABEL: @propagate_drop_fdiv(
-; CHECK-NEXT:    [[V1:%.*]] = fmul nnan ninf float [[ARG:%.*]], 5.000000e-01
-; CHECK-NEXT:    [[V1_FR:%.*]] = freeze float [[V1]]
-; CHECK-NEXT:    ret float [[V1_FR]]
+; CHECK-NEXT:    [[ARG_FR:%.*]] = freeze float [[ARG:%.*]]
+; CHECK-NEXT:    [[V1:%.*]] = fmul float [[ARG_FR]], 5.000000e-01
+; CHECK-NEXT:    ret float [[V1]]
 ;
   %v1 = fdiv ninf nnan float %arg, 2.0
   %v1.fr = freeze float %v1
@@ -421,9 +421,9 @@
 
 define float @propagate_drop_frem(float %arg) {
 ; CHECK-LABEL: @propagate_drop_frem(
-; CHECK-NEXT:    [[V1:%.*]] = frem nnan ninf float [[ARG:%.*]], 2.000000e+00
-; CHECK-NEXT:    [[V1_FR:%.*]] = freeze float [[V1]]
-; CHECK-NEXT:    ret float [[V1_FR]]
+; CHECK-NEXT:    [[ARG_FR:%.*]] = freeze float [[ARG:%.*]]
+; CHECK-NEXT:    [[V1:%.*]] = frem float [[ARG_FR]], 2.000000e+00
+; CHECK-NEXT:    ret float [[V1]]
 ;
   %v1 = frem ninf nnan float %arg, 2.0
   %v1.fr = freeze float %v1
@@ -432,9 +432,9 @@
 
 define i1 @propagate_drop_fcmp(float %arg) {
 ; CHECK-LABEL: @propagate_drop_fcmp(
-; CHECK-NEXT:    [[V1:%.*]] = fcmp nnan ninf une float [[ARG:%.*]], 2.000000e+00
-; CHECK-NEXT:    [[V1_FR:%.*]] = freeze i1 [[V1]]
-; CHECK-NEXT:    ret i1 [[V1_FR]]
+; CHECK-NEXT:    [[ARG_FR:%.*]] = freeze float [[ARG:%.*]]
+; CHECK-NEXT:    [[V1:%.*]] = fcmp une float [[ARG_FR]], 2.000000e+00
+; CHECK-NEXT:    ret i1 [[V1]]
 ;
   %v1 = fcmp ninf nnan une float %arg, 2.0
   %v1.fr = freeze i1 %v1
@@ -443,9 +443,9 @@
 
 define float @propagate_drop_fmath_select(i1 %arg) {
 ; CHECK-LABEL: @propagate_drop_fmath_select(
-; CHECK-NEXT:    [[V1:%.*]] = select nnan ninf i1 [[ARG:%.*]], float 1.000000e+00, float -1.000000e+00
-; CHECK-NEXT:    [[V1_FR:%.*]] = freeze float [[V1]]
-; CHECK-NEXT:    ret float [[V1_FR]]
+; CHECK-NEXT:    [[ARG_FR:%.*]] = freeze i1 [[ARG:%.*]]
+; CHECK-NEXT:    [[V1:%.*]] = select i1 [[ARG_FR]], float 1.000000e+00, float -1.000000e+00
+; CHECK-NEXT:    ret float [[V1]]
 ;
   %v1 = select ninf nnan i1 %arg, float 1.0, float -1.0
   %v1.fr = freeze float %v1
diff --git a/llvm/test/Transforms/InstCombine/shuffle_select-inseltpoison.ll b/llvm/test/Transforms/InstCombine/shuffle_select-inseltpoison.ll
--- a/llvm/test/Transforms/InstCombine/shuffle_select-inseltpoison.ll
+++ b/llvm/test/Transforms/InstCombine/shuffle_select-inseltpoison.ll
@@ -778,7 +778,7 @@
 
 define <4 x double> @fdiv_fdiv(<4 x double> %v0) {
 ; CHECK-LABEL: @fdiv_fdiv(
-; CHECK-NEXT:    [[TMP1:%.*]] = fdiv nnan arcp <4 x double> <double undef, double 2.000000e+00, double 7.000000e+00, double 8.000000e+00>, [[V0:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fdiv arcp <4 x double> <double undef, double 2.000000e+00, double 7.000000e+00, double 8.000000e+00>, [[V0:%.*]]
 ; CHECK-NEXT:    ret <4 x double> [[TMP1]]
 ;
   %t1 = fdiv fast <4 x double> <double 1.0, double 2.0, double 3.0, double 4.0>, %v0
@@ -1271,7 +1271,7 @@
 define <4 x double> @frem_2_vars(<4 x double> %v0, <4 x double> %v1) {
 ; CHECK-LABEL: @frem_2_vars(
 ; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x double> [[V0:%.*]], <4 x double> [[V1:%.*]], <4 x i32> <i32 undef, i32 1, i32 6, i32 7>
-; CHECK-NEXT:    [[TMP2:%.*]] = frem nnan <4 x double> <double undef, double 2.000000e+00, double 7.000000e+00, double 8.000000e+00>, [[TMP1]]
+; CHECK-NEXT:    [[TMP2:%.*]] = frem <4 x double> <double undef, double 2.000000e+00, double 7.000000e+00, double 8.000000e+00>, [[TMP1]]
 ; CHECK-NEXT:    ret <4 x double> [[TMP2]]
 ;
   %t1 = frem nnan ninf <4 x double> <double 1.0, double 2.0, double 3.0, double 4.0>, %v0
diff --git a/llvm/test/Transforms/InstCombine/shuffle_select.ll b/llvm/test/Transforms/InstCombine/shuffle_select.ll
--- a/llvm/test/Transforms/InstCombine/shuffle_select.ll
+++ b/llvm/test/Transforms/InstCombine/shuffle_select.ll
@@ -778,7 +778,7 @@
 
 define <4 x double> @fdiv_fdiv(<4 x double> %v0) {
 ; CHECK-LABEL: @fdiv_fdiv(
-; CHECK-NEXT:    [[TMP1:%.*]] = fdiv nnan arcp <4 x double> <double undef, double 2.000000e+00, double 7.000000e+00, double 8.000000e+00>, [[V0:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fdiv arcp <4 x double> <double undef, double 2.000000e+00, double 7.000000e+00, double 8.000000e+00>, [[V0:%.*]]
 ; CHECK-NEXT:    ret <4 x double> [[TMP1]]
 ;
   %t1 = fdiv fast <4 x double> <double 1.0, double 2.0, double 3.0, double 4.0>, %v0
@@ -1271,7 +1271,7 @@
 define <4 x double> @frem_2_vars(<4 x double> %v0, <4 x double> %v1) {
 ; CHECK-LABEL: @frem_2_vars(
 ; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x double> [[V0:%.*]], <4 x double> [[V1:%.*]], <4 x i32> <i32 undef, i32 1, i32 6, i32 7>
-; CHECK-NEXT:    [[TMP2:%.*]] = frem nnan <4 x double> <double undef, double 2.000000e+00, double 7.000000e+00, double 8.000000e+00>, [[TMP1]]
+; CHECK-NEXT:    [[TMP2:%.*]] = frem <4 x double> <double undef, double 2.000000e+00, double 7.000000e+00, double 8.000000e+00>, [[TMP1]]
 ; CHECK-NEXT:    ret <4 x double> [[TMP2]]
 ;
   %t1 = frem nnan ninf <4 x double> <double 1.0, double 2.0, double 3.0, double 4.0>, %v0