From 44c6999cbc86341d7f060f3f3415064becdfd4a7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 6 Jul 2023 18:37:17 +0200 Subject: [PATCH 1/3] disable ConstProp of floats --- compiler/rustc_mir_transform/src/const_prop.rs | 8 ++++++++ compiler/rustc_mir_transform/src/dataflow_const_prop.rs | 8 ++++++++ 2 files changed, 16 insertions(+) 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, ) -> ValueOrPlace { + 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 From 797ebf5d9b3f158113ef8fe8fd92ec2ed4c211ef Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 7 Jul 2023 12:50:07 +0200 Subject: [PATCH 2/3] add tests --- tests/ui/const_prop/issue-102403.rs | 15 +++++++++++++++ tests/ui/const_prop/issue-113407.rs | 8 ++++++++ 2 files changed, 23 insertions(+) create mode 100644 tests/ui/const_prop/issue-102403.rs create mode 100644 tests/ui/const_prop/issue-113407.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); +} From 7153840c8289964f282aba3d19752730123c9837 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 7 Jul 2023 13:36:23 +0200 Subject: [PATCH 3/3] move misplaced tests --- tests/ui/{consts/const-eval => const_prop}/const_prop_errors.rs | 0 tests/ui/{consts => const_prop}/issue-67696-const-prop-ice.rs | 0 .../{consts/const-eval => lint}/index_out_of_bounds_propagated.rs | 0 .../const-eval => lint}/index_out_of_bounds_propagated.stderr | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{consts/const-eval => const_prop}/const_prop_errors.rs (100%) rename tests/ui/{consts => const_prop}/issue-67696-const-prop-ice.rs (100%) rename tests/ui/{consts/const-eval => lint}/index_out_of_bounds_propagated.rs (100%) rename tests/ui/{consts/const-eval => lint}/index_out_of_bounds_propagated.stderr (100%) 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/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