Skip to content

Commit 031bdf9

Browse files
committed
Support a few more rvalues.
1 parent d74446b commit 031bdf9

17 files changed

+130
-103
lines changed

compiler/rustc_mir_transform/src/dataflow_const_prop.rs

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

240257
fn handle_constant(

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

Lines changed: 6 additions & 3 deletions
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

Lines changed: 6 additions & 3 deletions
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

Lines changed: 16 additions & 8 deletions
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

Lines changed: 16 additions & 8 deletions
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

Lines changed: 8 additions & 4 deletions
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

Lines changed: 8 additions & 4 deletions
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

Lines changed: 2 additions & 1 deletion
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

Lines changed: 2 additions & 1 deletion
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

Lines changed: 2 additions & 1 deletion
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

Lines changed: 2 additions & 1 deletion
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

Lines changed: 2 additions & 1 deletion
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

Lines changed: 2 additions & 1 deletion
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

Lines changed: 2 additions & 1 deletion
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

Lines changed: 2 additions & 1 deletion
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

Lines changed: 2 additions & 16 deletions
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)