diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs
index 2f2c7357b0069..e86e553e8eb71 100644
--- a/compiler/rustc_mir_transform/src/const_prop.rs
+++ b/compiler/rustc_mir_transform/src/const_prop.rs
@@ -520,6 +520,14 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         rvalue: &Rvalue<'tcx>,
         place: Place<'tcx>,
     ) -> Option<()> {
+        if place.ty(&self.ecx.frame().body.local_decls, *self.ecx.tcx).ty.is_floating_point() {
+            // Our apfloat is old and buggy (https://github.com/rust-lang/rust/issues/113409).
+            // Let's not risk wrong optimization results -- just do nothing for floats.
+            // This affects at least binary ops and casts, so just skip all rvalues.
+            // LLVM has a less buggy apfloat and will take care of const-propagation.
+            return None;
+        }
+
         match rvalue {
             Rvalue::BinaryOp(op, box (left, right))
             | Rvalue::CheckedBinaryOp(op, box (left, right)) => {
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index 78fb196358faf..4f9860ae9b23f 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -193,6 +193,14 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
         rvalue: &Rvalue<'tcx>,
         state: &mut State<Self::Value>,
     ) -> ValueOrPlace<Self::Value> {
+        if rvalue.ty(self.local_decls, self.tcx).is_floating_point() {
+            // Our apfloat is old and buggy (https://github.com/rust-lang/rust/issues/113409).
+            // Let's not risk wrong optimization results -- just do nothing for floats.
+            // This affects at least binary ops and casts, so just skip all rvalues.
+            // LLVM has a less buggy apfloat and will take care of const-propagation.
+            return ValueOrPlace::TOP;
+        }
+
         match rvalue {
             Rvalue::Cast(
                 kind @ (CastKind::IntToInt
diff --git a/tests/ui/consts/const-eval/const_prop_errors.rs b/tests/ui/const_prop/const_prop_errors.rs
similarity index 100%
rename from tests/ui/consts/const-eval/const_prop_errors.rs
rename to tests/ui/const_prop/const_prop_errors.rs
diff --git a/tests/ui/const_prop/issue-102403.rs b/tests/ui/const_prop/issue-102403.rs
new file mode 100644
index 0000000000000..0851ede9da47f
--- /dev/null
+++ b/tests/ui/const_prop/issue-102403.rs
@@ -0,0 +1,15 @@
+// run-pass
+// compile-flags: -O -Zmir-opt-level=3 -Cno-prepopulate-passes
+
+// Regression test for a broken MIR optimization.
+pub fn f() -> f64 {
+    std::hint::black_box(-1.0) % std::hint::black_box(-1.0)
+}
+
+pub fn g() -> f64 {
+    -1.0 % -1.0
+}
+
+pub fn main() {
+    assert_eq!(f().signum(), g().signum());
+}
diff --git a/tests/ui/const_prop/issue-113407.rs b/tests/ui/const_prop/issue-113407.rs
new file mode 100644
index 0000000000000..08711c06f809f
--- /dev/null
+++ b/tests/ui/const_prop/issue-113407.rs
@@ -0,0 +1,8 @@
+// run-pass
+// compile-flags: -O -Zmir-opt-level=3 -Cno-prepopulate-passes
+
+// Regression test for a broken MIR optimization.
+pub fn main() {
+    let f = f64::from_bits(0x19873cc2) as f32;
+    assert_eq!(f.to_bits(), 0);
+}
diff --git a/tests/ui/consts/issue-67696-const-prop-ice.rs b/tests/ui/const_prop/issue-67696-const-prop-ice.rs
similarity index 100%
rename from tests/ui/consts/issue-67696-const-prop-ice.rs
rename to tests/ui/const_prop/issue-67696-const-prop-ice.rs
diff --git a/tests/ui/consts/const-eval/index_out_of_bounds_propagated.rs b/tests/ui/lint/index_out_of_bounds_propagated.rs
similarity index 100%
rename from tests/ui/consts/const-eval/index_out_of_bounds_propagated.rs
rename to tests/ui/lint/index_out_of_bounds_propagated.rs
diff --git a/tests/ui/consts/const-eval/index_out_of_bounds_propagated.stderr b/tests/ui/lint/index_out_of_bounds_propagated.stderr
similarity index 100%
rename from tests/ui/consts/const-eval/index_out_of_bounds_propagated.stderr
rename to tests/ui/lint/index_out_of_bounds_propagated.stderr