Skip to content

Commit 4ea9942

Browse files
committed
Support a few more rvalues.
1 parent 22eae62 commit 4ea9942

17 files changed

+130
-103
lines changed

compiler/rustc_mir_transform/src/dataflow_const_prop.rs

+50-33
Original file line numberDiff line numberDiff line change
@@ -193,47 +193,64 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
193193
rvalue: &Rvalue<'tcx>,
194194
state: &mut State<Self::Value>,
195195
) -> ValueOrPlace<Self::Value> {
196-
match rvalue {
197-
Rvalue::Cast(
198-
kind @ (CastKind::IntToInt
199-
| CastKind::FloatToInt
200-
| CastKind::FloatToFloat
201-
| CastKind::IntToFloat),
202-
operand,
203-
ty,
204-
) => match self.eval_operand(operand, state) {
205-
FlatSet::Elem(op) => match kind {
206-
CastKind::IntToInt | CastKind::IntToFloat => {
207-
self.ecx.int_to_int_or_float(&op, *ty)
208-
}
209-
CastKind::FloatToInt | CastKind::FloatToFloat => {
210-
self.ecx.float_to_float_or_int(&op, *ty)
211-
}
212-
_ => unreachable!(),
196+
let val = match rvalue {
197+
Rvalue::Cast(CastKind::IntToInt | CastKind::IntToFloat, operand, ty) => {
198+
match self.eval_operand(operand, state) {
199+
FlatSet::Elem(op) => self
200+
.ecx
201+
.int_to_int_or_float(&op, *ty)
202+
.map_or(FlatSet::Top, |result| self.wrap_immediate(result, *ty)),
203+
FlatSet::Bottom => FlatSet::Bottom,
204+
FlatSet::Top => FlatSet::Top,
213205
}
214-
.map(|result| ValueOrPlace::Value(self.wrap_immediate(result, *ty)))
215-
.unwrap_or(ValueOrPlace::TOP),
216-
_ => ValueOrPlace::TOP,
217-
},
206+
}
207+
Rvalue::Cast(CastKind::FloatToInt | CastKind::FloatToFloat, operand, ty) => {
208+
match self.eval_operand(operand, state) {
209+
FlatSet::Elem(op) => self
210+
.ecx
211+
.float_to_float_or_int(&op, *ty)
212+
.map_or(FlatSet::Top, |result| self.wrap_immediate(result, *ty)),
213+
FlatSet::Bottom => FlatSet::Bottom,
214+
FlatSet::Top => FlatSet::Top,
215+
}
216+
}
217+
Rvalue::Cast(CastKind::Transmute, operand, ty) => {
218+
match self.eval_operand(operand, state) {
219+
FlatSet::Elem(op) => self.wrap_immediate(*op, *ty),
220+
FlatSet::Bottom => FlatSet::Bottom,
221+
FlatSet::Top => FlatSet::Top,
222+
}
223+
}
218224
Rvalue::BinaryOp(op, box (left, right)) => {
219225
// Overflows must be ignored here.
220226
let (val, _overflow) = self.binary_op(state, *op, left, right);
221-
ValueOrPlace::Value(val)
227+
val
222228
}
223229
Rvalue::UnaryOp(op, operand) => match self.eval_operand(operand, state) {
224-
FlatSet::Elem(value) => self
225-
.ecx
226-
.unary_op(*op, &value)
227-
.map(|val| ValueOrPlace::Value(self.wrap_immty(val)))
228-
.unwrap_or(ValueOrPlace::Value(FlatSet::Top)),
229-
FlatSet::Bottom => ValueOrPlace::Value(FlatSet::Bottom),
230-
FlatSet::Top => ValueOrPlace::Value(FlatSet::Top),
230+
FlatSet::Elem(value) => {
231+
self.ecx.unary_op(*op, &value).map_or(FlatSet::Top, |val| self.wrap_immty(val))
232+
}
233+
FlatSet::Bottom => FlatSet::Bottom,
234+
FlatSet::Top => FlatSet::Top,
231235
},
232-
Rvalue::Discriminant(place) => {
233-
ValueOrPlace::Value(state.get_discr(place.as_ref(), self.map()))
236+
Rvalue::NullaryOp(null_op, ty) => {
237+
let Ok(layout) = self.tcx.layout_of(self.param_env.and(*ty)) else {
238+
return ValueOrPlace::Value(FlatSet::Top);
239+
};
240+
let val = match null_op {
241+
NullOp::SizeOf if layout.is_sized() => layout.size.bytes(),
242+
NullOp::AlignOf if layout.is_sized() => layout.align.abi.bytes(),
243+
NullOp::OffsetOf(fields) => layout
244+
.offset_of_subfield(&self.ecx, fields.iter().map(|f| f.index()))
245+
.bytes(),
246+
_ => return ValueOrPlace::Value(FlatSet::Top),
247+
};
248+
self.wrap_scalar(Scalar::from_target_usize(val, &self.tcx), self.tcx.types.usize)
234249
}
235-
_ => self.super_rvalue(rvalue, state),
236-
}
250+
Rvalue::Discriminant(place) => state.get_discr(place.as_ref(), self.map()),
251+
_ => return self.super_rvalue(rvalue, state),
252+
};
253+
ValueOrPlace::Value(val)
237254
}
238255

239256
fn handle_constant(

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

+6-3
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@
2222
StorageLive(_1);
2323
StorageLive(_2);
2424
StorageLive(_3);
25-
_4 = SizeOf(i32);
26-
_5 = AlignOf(i32);
27-
_6 = alloc::alloc::exchange_malloc(move _4, move _5) -> [return: bb1, unwind unreachable];
25+
- _4 = SizeOf(i32);
26+
- _5 = AlignOf(i32);
27+
- _6 = alloc::alloc::exchange_malloc(move _4, move _5) -> [return: bb1, unwind unreachable];
28+
+ _4 = const 4_usize;
29+
+ _5 = const 4_usize;
30+
+ _6 = alloc::alloc::exchange_malloc(const 4_usize, const 4_usize) -> [return: bb1, unwind unreachable];
2831
}
2932

3033
bb1: {

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

+6-3
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@
2222
StorageLive(_1);
2323
StorageLive(_2);
2424
StorageLive(_3);
25-
_4 = SizeOf(i32);
26-
_5 = AlignOf(i32);
27-
_6 = alloc::alloc::exchange_malloc(move _4, move _5) -> [return: bb1, unwind continue];
25+
- _4 = SizeOf(i32);
26+
- _5 = AlignOf(i32);
27+
- _6 = alloc::alloc::exchange_malloc(move _4, move _5) -> [return: bb1, unwind continue];
28+
+ _4 = const 4_usize;
29+
+ _5 = const 4_usize;
30+
+ _6 = alloc::alloc::exchange_malloc(const 4_usize, const 4_usize) -> [return: bb1, unwind continue];
2831
}
2932

3033
bb1: {

tests/mir-opt/const_prop/offset_of.concrete.ConstProp.panic-abort.diff

+16-8
Original file line numberDiff line numberDiff line change
@@ -27,32 +27,40 @@
2727
bb0: {
2828
StorageLive(_1);
2929
StorageLive(_2);
30-
_2 = OffsetOf(Alpha, [0]);
31-
_1 = must_use::<usize>(move _2) -> [return: bb1, unwind unreachable];
30+
- _2 = OffsetOf(Alpha, [0]);
31+
- _1 = must_use::<usize>(move _2) -> [return: bb1, unwind unreachable];
32+
+ _2 = const 4_usize;
33+
+ _1 = must_use::<usize>(const 4_usize) -> [return: bb1, unwind unreachable];
3234
}
3335

3436
bb1: {
3537
StorageDead(_2);
3638
StorageLive(_3);
3739
StorageLive(_4);
38-
_4 = OffsetOf(Alpha, [1]);
39-
_3 = must_use::<usize>(move _4) -> [return: bb2, unwind unreachable];
40+
- _4 = OffsetOf(Alpha, [1]);
41+
- _3 = must_use::<usize>(move _4) -> [return: bb2, unwind unreachable];
42+
+ _4 = const 0_usize;
43+
+ _3 = must_use::<usize>(const 0_usize) -> [return: bb2, unwind unreachable];
4044
}
4145

4246
bb2: {
4347
StorageDead(_4);
4448
StorageLive(_5);
4549
StorageLive(_6);
46-
_6 = OffsetOf(Alpha, [2, 0]);
47-
_5 = must_use::<usize>(move _6) -> [return: bb3, unwind unreachable];
50+
- _6 = OffsetOf(Alpha, [2, 0]);
51+
- _5 = must_use::<usize>(move _6) -> [return: bb3, unwind unreachable];
52+
+ _6 = const 2_usize;
53+
+ _5 = must_use::<usize>(const 2_usize) -> [return: bb3, unwind unreachable];
4854
}
4955

5056
bb3: {
5157
StorageDead(_6);
5258
StorageLive(_7);
5359
StorageLive(_8);
54-
_8 = OffsetOf(Alpha, [2, 1]);
55-
_7 = must_use::<usize>(move _8) -> [return: bb4, unwind unreachable];
60+
- _8 = OffsetOf(Alpha, [2, 1]);
61+
- _7 = must_use::<usize>(move _8) -> [return: bb4, unwind unreachable];
62+
+ _8 = const 3_usize;
63+
+ _7 = must_use::<usize>(const 3_usize) -> [return: bb4, unwind unreachable];
5664
}
5765

5866
bb4: {

tests/mir-opt/const_prop/offset_of.concrete.ConstProp.panic-unwind.diff

+16-8
Original file line numberDiff line numberDiff line change
@@ -27,32 +27,40 @@
2727
bb0: {
2828
StorageLive(_1);
2929
StorageLive(_2);
30-
_2 = OffsetOf(Alpha, [0]);
31-
_1 = must_use::<usize>(move _2) -> [return: bb1, unwind continue];
30+
- _2 = OffsetOf(Alpha, [0]);
31+
- _1 = must_use::<usize>(move _2) -> [return: bb1, unwind continue];
32+
+ _2 = const 4_usize;
33+
+ _1 = must_use::<usize>(const 4_usize) -> [return: bb1, unwind continue];
3234
}
3335

3436
bb1: {
3537
StorageDead(_2);
3638
StorageLive(_3);
3739
StorageLive(_4);
38-
_4 = OffsetOf(Alpha, [1]);
39-
_3 = must_use::<usize>(move _4) -> [return: bb2, unwind continue];
40+
- _4 = OffsetOf(Alpha, [1]);
41+
- _3 = must_use::<usize>(move _4) -> [return: bb2, unwind continue];
42+
+ _4 = const 0_usize;
43+
+ _3 = must_use::<usize>(const 0_usize) -> [return: bb2, unwind continue];
4044
}
4145

4246
bb2: {
4347
StorageDead(_4);
4448
StorageLive(_5);
4549
StorageLive(_6);
46-
_6 = OffsetOf(Alpha, [2, 0]);
47-
_5 = must_use::<usize>(move _6) -> [return: bb3, unwind continue];
50+
- _6 = OffsetOf(Alpha, [2, 0]);
51+
- _5 = must_use::<usize>(move _6) -> [return: bb3, unwind continue];
52+
+ _6 = const 2_usize;
53+
+ _5 = must_use::<usize>(const 2_usize) -> [return: bb3, unwind continue];
4854
}
4955

5056
bb3: {
5157
StorageDead(_6);
5258
StorageLive(_7);
5359
StorageLive(_8);
54-
_8 = OffsetOf(Alpha, [2, 1]);
55-
_7 = must_use::<usize>(move _8) -> [return: bb4, unwind continue];
60+
- _8 = OffsetOf(Alpha, [2, 1]);
61+
- _7 = must_use::<usize>(move _8) -> [return: bb4, unwind continue];
62+
+ _8 = const 3_usize;
63+
+ _7 = must_use::<usize>(const 3_usize) -> [return: bb4, unwind continue];
5664
}
5765

5866
bb4: {

tests/mir-opt/const_prop/offset_of.generic.ConstProp.panic-abort.diff

+8-4
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,20 @@
4343
StorageDead(_4);
4444
StorageLive(_5);
4545
StorageLive(_6);
46-
_6 = OffsetOf(Delta<T>, [1]);
47-
_5 = must_use::<usize>(move _6) -> [return: bb3, unwind unreachable];
46+
- _6 = OffsetOf(Delta<T>, [1]);
47+
- _5 = must_use::<usize>(move _6) -> [return: bb3, unwind unreachable];
48+
+ _6 = const 0_usize;
49+
+ _5 = must_use::<usize>(const 0_usize) -> [return: bb3, unwind unreachable];
4850
}
4951

5052
bb3: {
5153
StorageDead(_6);
5254
StorageLive(_7);
5355
StorageLive(_8);
54-
_8 = OffsetOf(Delta<T>, [2]);
55-
_7 = must_use::<usize>(move _8) -> [return: bb4, unwind unreachable];
56+
- _8 = OffsetOf(Delta<T>, [2]);
57+
- _7 = must_use::<usize>(move _8) -> [return: bb4, unwind unreachable];
58+
+ _8 = const 2_usize;
59+
+ _7 = must_use::<usize>(const 2_usize) -> [return: bb4, unwind unreachable];
5660
}
5761

5862
bb4: {

tests/mir-opt/const_prop/offset_of.generic.ConstProp.panic-unwind.diff

+8-4
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,20 @@
4343
StorageDead(_4);
4444
StorageLive(_5);
4545
StorageLive(_6);
46-
_6 = OffsetOf(Delta<T>, [1]);
47-
_5 = must_use::<usize>(move _6) -> [return: bb3, unwind continue];
46+
- _6 = OffsetOf(Delta<T>, [1]);
47+
- _5 = must_use::<usize>(move _6) -> [return: bb3, unwind continue];
48+
+ _6 = const 0_usize;
49+
+ _5 = must_use::<usize>(const 0_usize) -> [return: bb3, unwind continue];
4850
}
4951

5052
bb3: {
5153
StorageDead(_6);
5254
StorageLive(_7);
5355
StorageLive(_8);
54-
_8 = OffsetOf(Delta<T>, [2]);
55-
_7 = must_use::<usize>(move _8) -> [return: bb4, unwind continue];
56+
- _8 = OffsetOf(Delta<T>, [2]);
57+
- _7 = must_use::<usize>(move _8) -> [return: bb4, unwind continue];
58+
+ _8 = const 2_usize;
59+
+ _7 = must_use::<usize>(const 2_usize) -> [return: bb4, unwind continue];
5660
}
5761

5862
bb4: {

tests/mir-opt/const_prop/transmute.from_char.ConstProp.32bit.diff

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
}
88

99
bb0: {
10-
_0 = const 'R' as i32 (Transmute);
10+
- _0 = const 'R' as i32 (Transmute);
11+
+ _0 = const 82_i32;
1112
return;
1213
}
1314
}

tests/mir-opt/const_prop/transmute.from_char.ConstProp.64bit.diff

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
}
88

99
bb0: {
10-
_0 = const 'R' as i32 (Transmute);
10+
- _0 = const 'R' as i32 (Transmute);
11+
+ _0 = const 82_i32;
1112
return;
1213
}
1314
}

tests/mir-opt/const_prop/transmute.invalid_bool.ConstProp.32bit.diff

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
}
88

99
bb0: {
10-
_0 = const -1_i8 as bool (Transmute);
10+
- _0 = const -1_i8 as bool (Transmute);
11+
+ _0 = const {transmute(0xff): bool};
1112
return;
1213
}
1314
}

tests/mir-opt/const_prop/transmute.invalid_bool.ConstProp.64bit.diff

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
}
88

99
bb0: {
10-
_0 = const -1_i8 as bool (Transmute);
10+
- _0 = const -1_i8 as bool (Transmute);
11+
+ _0 = const {transmute(0xff): bool};
1112
return;
1213
}
1314
}

tests/mir-opt/const_prop/transmute.invalid_char.ConstProp.32bit.diff

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
}
88

99
bb0: {
10-
_0 = const _ as char (Transmute);
10+
- _0 = const _ as char (Transmute);
11+
+ _0 = const {transmute(0x7fffffff): char};
1112
return;
1213
}
1314
}

tests/mir-opt/const_prop/transmute.invalid_char.ConstProp.64bit.diff

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
}
88

99
bb0: {
10-
_0 = const _ as char (Transmute);
10+
- _0 = const _ as char (Transmute);
11+
+ _0 = const {transmute(0x7fffffff): char};
1112
return;
1213
}
1314
}

tests/mir-opt/const_prop/transmute.valid_char.ConstProp.32bit.diff

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
}
88

99
bb0: {
10-
_0 = const 82_u32 as char (Transmute);
10+
- _0 = const 82_u32 as char (Transmute);
11+
+ _0 = const 'R';
1112
return;
1213
}
1314
}

tests/mir-opt/const_prop/transmute.valid_char.ConstProp.64bit.diff

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
}
88

99
bb0: {
10-
_0 = const 82_u32 as char (Transmute);
10+
- _0 = const 82_u32 as char (Transmute);
11+
+ _0 = const 'R';
1112
return;
1213
}
1314
}

tests/mir-opt/pre-codegen/intrinsics.f_u64.PreCodegen.after.mir

+2-16
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,16 @@ fn f_u64() -> () {
44
let mut _0: ();
55
scope 1 (inlined f_dispatch::<u64>) {
66
debug t => const 0_u64;
7-
let mut _1: usize;
8-
let _2: ();
9-
let _3: ();
7+
let _1: ();
108
scope 2 (inlined std::mem::size_of::<u64>) {
119
}
1210
}
1311

1412
bb0: {
15-
StorageLive(_1);
16-
_1 = SizeOf(u64);
17-
switchInt(move _1) -> [0: bb1, otherwise: bb2];
13+
_1 = f_non_zst::<u64>(const 0_u64) -> [return: bb1, unwind unreachable];
1814
}
1915

2016
bb1: {
21-
StorageDead(_1);
22-
_2 = f_zst::<u64>(const 0_u64) -> [return: bb3, unwind unreachable];
23-
}
24-
25-
bb2: {
26-
StorageDead(_1);
27-
_3 = f_non_zst::<u64>(const 0_u64) -> [return: bb3, unwind unreachable];
28-
}
29-
30-
bb3: {
3117
return;
3218
}
3319
}

0 commit comments

Comments
 (0)