Skip to content

Commit cba8a23

Browse files
committed
Try harder to evaluate constants.
1 parent 0208ee0 commit cba8a23

13 files changed

+46
-30
lines changed

compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,16 +1006,16 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
10061006
operand: &mut Operand<'tcx>,
10071007
location: Location,
10081008
) -> Option<VnIndex> {
1009-
match *operand {
1010-
Operand::Constant(ref constant) => Some(self.insert_constant(constant.const_)),
1009+
let value = match *operand {
1010+
Operand::Constant(ref constant) => self.insert_constant(constant.const_),
10111011
Operand::Copy(ref mut place) | Operand::Move(ref mut place) => {
1012-
let value = self.simplify_place_value(place, location)?;
1013-
if let Some(const_) = self.try_as_constant(value) {
1014-
*operand = Operand::Constant(Box::new(const_));
1015-
}
1016-
Some(value)
1012+
self.simplify_place_value(place, location)?
10171013
}
1014+
};
1015+
if let Some(const_) = self.try_as_constant(value) {
1016+
*operand = Operand::Constant(Box::new(const_));
10181017
}
1018+
Some(value)
10191019
}
10201020

10211021
#[instrument(level = "trace", skip(self), ret)]
@@ -1790,14 +1790,28 @@ impl<'tcx> VnState<'_, '_, 'tcx> {
17901790

17911791
/// If `index` is a `Value::Constant`, return the `Constant` to be put in the MIR.
17921792
fn try_as_constant(&mut self, index: VnIndex) -> Option<ConstOperand<'tcx>> {
1793-
// This was already constant in MIR, do not change it. If the constant is not
1794-
// deterministic, adding an additional mention of it in MIR will not give the same value as
1795-
// the former mention.
1796-
if let Value::Constant { value, disambiguator: None } = self.get(index) {
1797-
debug_assert!(value.is_deterministic());
1793+
let value = self.get(index);
1794+
1795+
// This was already an *evaluated* constant in MIR, do not change it.
1796+
if let Value::Constant { value, disambiguator: None } = value
1797+
&& let Const::Val(..) = value
1798+
{
17981799
return Some(ConstOperand { span: DUMMY_SP, user_ty: None, const_: value });
17991800
}
18001801

1802+
if let Some(value) = self.try_as_evaluated_constant(index) {
1803+
return Some(ConstOperand { span: DUMMY_SP, user_ty: None, const_: value });
1804+
}
1805+
1806+
// We failed to provide an evaluated form, fallback to using the unevaluated constant.
1807+
if let Value::Constant { value, disambiguator: None } = value {
1808+
return Some(ConstOperand { span: DUMMY_SP, user_ty: None, const_: value });
1809+
}
1810+
1811+
None
1812+
}
1813+
1814+
fn try_as_evaluated_constant(&mut self, index: VnIndex) -> Option<Const<'tcx>> {
18011815
let op = self.eval_to_const(index)?;
18021816
if op.layout.is_unsized() {
18031817
// Do not attempt to propagate unsized locals.
@@ -1811,8 +1825,7 @@ impl<'tcx> VnState<'_, '_, 'tcx> {
18111825
// FIXME: remove this hack once https://github.com/rust-lang/rust/issues/79738 is fixed.
18121826
assert!(!value.may_have_provenance(self.tcx, op.layout.size));
18131827

1814-
let const_ = Const::Val(value, op.layout.ty);
1815-
Some(ConstOperand { span: DUMMY_SP, user_ty: None, const_ })
1828+
Some(Const::Val(value, op.layout.ty))
18161829
}
18171830

18181831
/// Construct a place which holds the same value as `index` and for which all locals strictly

tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
- StorageLive(_2);
2323
+ nop;
2424
StorageLive(_3);
25-
_4 = alloc::alloc::exchange_malloc(const <i32 as std::mem::SizedTypeProperties>::SIZE, const <i32 as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb1, unwind unreachable];
25+
- _4 = alloc::alloc::exchange_malloc(const <i32 as std::mem::SizedTypeProperties>::SIZE, const <i32 as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb1, unwind unreachable];
26+
+ _4 = alloc::alloc::exchange_malloc(const 4_usize, const 4_usize) -> [return: bb1, unwind unreachable];
2627
}
2728

2829
bb1: {

tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
- StorageLive(_2);
2323
+ nop;
2424
StorageLive(_3);
25-
_4 = alloc::alloc::exchange_malloc(const <i32 as std::mem::SizedTypeProperties>::SIZE, const <i32 as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb1, unwind continue];
25+
- _4 = alloc::alloc::exchange_malloc(const <i32 as std::mem::SizedTypeProperties>::SIZE, const <i32 as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb1, unwind continue];
26+
+ _4 = alloc::alloc::exchange_malloc(const 4_usize, const 4_usize) -> [return: bb1, unwind continue];
2627
}
2728

2829
bb1: {

tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
StorageLive(_20);
4848
StorageLive(_21);
4949
_21 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
50-
_20 = BitAnd(move _21, const core::fmt::flags::SIGN_PLUS_FLAG);
50+
_20 = BitAnd(move _21, const 2097152_u32);
5151
StorageDead(_21);
5252
_4 = Ne(move _20, const 0_u32);
5353
StorageDead(_20);
@@ -72,7 +72,7 @@
7272
StorageLive(_22);
7373
StorageLive(_23);
7474
_23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
75-
_22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG);
75+
_22 = BitAnd(move _23, const 268435456_u32);
7676
StorageDead(_23);
7777
switchInt(move _22) -> [0: bb10, otherwise: bb11];
7878
}

tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
StorageLive(_20);
4848
StorageLive(_21);
4949
_21 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
50-
_20 = BitAnd(move _21, const core::fmt::flags::SIGN_PLUS_FLAG);
50+
_20 = BitAnd(move _21, const 2097152_u32);
5151
StorageDead(_21);
5252
_4 = Ne(move _20, const 0_u32);
5353
StorageDead(_20);
@@ -72,7 +72,7 @@
7272
StorageLive(_22);
7373
StorageLive(_23);
7474
_23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
75-
_22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG);
75+
_22 = BitAnd(move _23, const 268435456_u32);
7676
StorageDead(_23);
7777
switchInt(move _22) -> [0: bb10, otherwise: bb11];
7878
}

tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
StorageLive(_20);
4848
StorageLive(_21);
4949
_21 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
50-
_20 = BitAnd(move _21, const core::fmt::flags::SIGN_PLUS_FLAG);
50+
_20 = BitAnd(move _21, const 2097152_u32);
5151
StorageDead(_21);
5252
_4 = Ne(move _20, const 0_u32);
5353
StorageDead(_20);
@@ -72,7 +72,7 @@
7272
StorageLive(_22);
7373
StorageLive(_23);
7474
_23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
75-
_22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG);
75+
_22 = BitAnd(move _23, const 268435456_u32);
7676
StorageDead(_23);
7777
switchInt(move _22) -> [0: bb10, otherwise: bb11];
7878
}

tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
StorageLive(_20);
4848
StorageLive(_21);
4949
_21 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
50-
_20 = BitAnd(move _21, const core::fmt::flags::SIGN_PLUS_FLAG);
50+
_20 = BitAnd(move _21, const 2097152_u32);
5151
StorageDead(_21);
5252
_4 = Ne(move _20, const 0_u32);
5353
StorageDead(_20);
@@ -72,7 +72,7 @@
7272
StorageLive(_22);
7373
StorageLive(_23);
7474
_23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
75-
_22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG);
75+
_22 = BitAnd(move _23, const 268435456_u32);
7676
StorageDead(_23);
7777
switchInt(move _22) -> [0: bb10, otherwise: bb11];
7878
}

tests/mir-opt/gvn_const_eval_polymorphic.no_optimize.GVN.diff

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
let mut _0: bool;
66

77
bb0: {
8-
_0 = Eq(const no_optimize::<T>::{constant#0}, const no_optimize::<T>::{constant#1});
8+
- _0 = Eq(const no_optimize::<T>::{constant#0}, const no_optimize::<T>::{constant#1});
9+
+ _0 = Eq(const no_optimize::<T>::{constant#0}, const true);
910
return;
1011
}
1112
}

tests/mir-opt/gvn_const_eval_polymorphic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ fn optimize_false<T>() -> bool {
5151
// EMIT_MIR gvn_const_eval_polymorphic.no_optimize.GVN.diff
5252
fn no_optimize<T>() -> bool {
5353
// CHECK-LABEL: fn no_optimize(
54-
// CHECK: _0 = Eq(const no_optimize::<T>::{constant#0}, const no_optimize::<T>::{constant#1});
54+
// CHECK: _0 = Eq(const no_optimize::<T>::{constant#0}, const true);
5555
// CHECK-NEXT: return;
5656
(const { type_name_contains_i32(&generic::<T>) }) == const { true }
5757
}

tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-abort.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ fn checked_shl(_1: u32, _2: u32) -> Option<u32> {
1717

1818
bb0: {
1919
StorageLive(_3);
20-
_3 = Lt(copy _2, const core::num::<impl u32>::BITS);
20+
_3 = Lt(copy _2, const 32_u32);
2121
switchInt(move _3) -> [0: bb1, otherwise: bb2];
2222
}
2323

0 commit comments

Comments
 (0)