Skip to content

Commit b56aaec

Browse files
committed
Auto merge of #144389 - scottmcm:no-more-mir-cast-assume, r=davidtwco
MIR-build: No longer emit assumes in enum-as casting This just uses the `valid_range` from the backend, so it's duplicating the range metadata that now we include on parameters and loads, and thus no longer seems to be useful -- notably there's no codegen test failures from removing it. (Because it's using data from the same source as the backend annotations, it doesn't do anything to mitigate things like #144388 where the range in the layout is more permissive than the actual possible discriminants. A variant of this that actually checked the discriminants more specifically might be useful, so could potentially be added in future, but I don't think the *current* checks are actually providing value.) r? mir Randomly turns out that this Fixes #121097
2 parents 246733a + 01524ab commit b56aaec

File tree

11 files changed

+38
-151
lines changed

11 files changed

+38
-151
lines changed

compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs

Lines changed: 2 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! See docs in `build/expr/mod.rs`.
22
3-
use rustc_abi::{BackendRepr, FieldIdx, Primitive};
3+
use rustc_abi::FieldIdx;
44
use rustc_hir::lang_items::LangItem;
55
use rustc_index::{Idx, IndexVec};
66
use rustc_middle::bug;
@@ -9,7 +9,6 @@ use rustc_middle::mir::interpret::Scalar;
99
use rustc_middle::mir::*;
1010
use rustc_middle::thir::*;
1111
use rustc_middle::ty::cast::{CastTy, mir_cast_kind};
12-
use rustc_middle::ty::layout::IntegerExt;
1312
use rustc_middle::ty::util::IntTypeExt;
1413
use rustc_middle::ty::{self, Ty, UpvarArgs};
1514
use rustc_span::source_map::Spanned;
@@ -200,89 +199,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
200199
{
201200
let discr_ty = adt_def.repr().discr_type().to_ty(this.tcx);
202201
let temp = unpack!(block = this.as_temp(block, scope, source, Mutability::Not));
203-
let layout =
204-
this.tcx.layout_of(this.typing_env().as_query_input(source_expr.ty));
205202
let discr = this.temp(discr_ty, source_expr.span);
206203
this.cfg.push_assign(
207204
block,
208205
source_info,
209206
discr,
210207
Rvalue::Discriminant(temp.into()),
211208
);
212-
let (op, ty) = (Operand::Move(discr), discr_ty);
213-
214-
if let BackendRepr::Scalar(scalar) = layout.unwrap().backend_repr
215-
&& !scalar.is_always_valid(&this.tcx)
216-
&& let Primitive::Int(int_width, _signed) = scalar.primitive()
217-
{
218-
let unsigned_ty = int_width.to_ty(this.tcx, false);
219-
let unsigned_place = this.temp(unsigned_ty, expr_span);
220-
this.cfg.push_assign(
221-
block,
222-
source_info,
223-
unsigned_place,
224-
Rvalue::Cast(CastKind::IntToInt, Operand::Copy(discr), unsigned_ty),
225-
);
226-
227-
let bool_ty = this.tcx.types.bool;
228-
let range = scalar.valid_range(&this.tcx);
229-
let merge_op =
230-
if range.start <= range.end { BinOp::BitAnd } else { BinOp::BitOr };
231-
232-
let mut comparer = |range: u128, bin_op: BinOp| -> Place<'tcx> {
233-
// We can use `ty::TypingEnv::fully_monomorphized()` here
234-
// as we only need it to compute the layout of a primitive.
235-
let range_val = Const::from_bits(
236-
this.tcx,
237-
range,
238-
ty::TypingEnv::fully_monomorphized(),
239-
unsigned_ty,
240-
);
241-
let lit_op = this.literal_operand(expr.span, range_val);
242-
let is_bin_op = this.temp(bool_ty, expr_span);
243-
this.cfg.push_assign(
244-
block,
245-
source_info,
246-
is_bin_op,
247-
Rvalue::BinaryOp(
248-
bin_op,
249-
Box::new((Operand::Copy(unsigned_place), lit_op)),
250-
),
251-
);
252-
is_bin_op
253-
};
254-
let assert_place = if range.start == 0 {
255-
comparer(range.end, BinOp::Le)
256-
} else {
257-
let start_place = comparer(range.start, BinOp::Ge);
258-
let end_place = comparer(range.end, BinOp::Le);
259-
let merge_place = this.temp(bool_ty, expr_span);
260-
this.cfg.push_assign(
261-
block,
262-
source_info,
263-
merge_place,
264-
Rvalue::BinaryOp(
265-
merge_op,
266-
Box::new((
267-
Operand::Move(start_place),
268-
Operand::Move(end_place),
269-
)),
270-
),
271-
);
272-
merge_place
273-
};
274-
this.cfg.push(
275-
block,
276-
Statement::new(
277-
source_info,
278-
StatementKind::Intrinsic(Box::new(NonDivergingIntrinsic::Assume(
279-
Operand::Move(assert_place),
280-
))),
281-
),
282-
);
283-
}
284-
285-
(op, ty)
209+
(Operand::Move(discr), discr_ty)
286210
} else {
287211
let ty = source_expr.ty;
288212
let source = unpack!(

tests/crashes/121097.rs

Lines changed: 0 additions & 10 deletions
This file was deleted.

tests/mir-opt/building/enum_cast.bar.built.after.mir

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,11 @@ fn bar(_1: Bar) -> usize {
55
let mut _0: usize;
66
let _2: Bar;
77
let mut _3: isize;
8-
let mut _4: u8;
9-
let mut _5: bool;
108

119
bb0: {
1210
StorageLive(_2);
1311
_2 = move _1;
1412
_3 = discriminant(_2);
15-
_4 = copy _3 as u8 (IntToInt);
16-
_5 = Le(copy _4, const 1_u8);
17-
assume(move _5);
1813
_0 = move _3 as usize (IntToInt);
1914
StorageDead(_2);
2015
return;

tests/mir-opt/building/enum_cast.boo.built.after.mir

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,11 @@ fn boo(_1: Boo) -> usize {
55
let mut _0: usize;
66
let _2: Boo;
77
let mut _3: u8;
8-
let mut _4: u8;
9-
let mut _5: bool;
108

119
bb0: {
1210
StorageLive(_2);
1311
_2 = move _1;
1412
_3 = discriminant(_2);
15-
_4 = copy _3 as u8 (IntToInt);
16-
_5 = Le(copy _4, const 1_u8);
17-
assume(move _5);
1813
_0 = move _3 as usize (IntToInt);
1914
StorageDead(_2);
2015
return;

tests/mir-opt/building/enum_cast.far.built.after.mir

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,11 @@ fn far(_1: Far) -> isize {
55
let mut _0: isize;
66
let _2: Far;
77
let mut _3: i16;
8-
let mut _4: u16;
9-
let mut _5: bool;
108

119
bb0: {
1210
StorageLive(_2);
1311
_2 = move _1;
1412
_3 = discriminant(_2);
15-
_4 = copy _3 as u16 (IntToInt);
16-
_5 = Le(copy _4, const 1_u16);
17-
assume(move _5);
1813
_0 = move _3 as isize (IntToInt);
1914
StorageDead(_2);
2015
return;

tests/mir-opt/building/enum_cast.offsetty.built.after.mir

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,11 @@ fn offsetty(_1: NotStartingAtZero) -> u32 {
55
let mut _0: u32;
66
let _2: NotStartingAtZero;
77
let mut _3: isize;
8-
let mut _4: u8;
9-
let mut _5: bool;
10-
let mut _6: bool;
11-
let mut _7: bool;
128

139
bb0: {
1410
StorageLive(_2);
1511
_2 = move _1;
1612
_3 = discriminant(_2);
17-
_4 = copy _3 as u8 (IntToInt);
18-
_5 = Ge(copy _4, const 4_u8);
19-
_6 = Le(copy _4, const 8_u8);
20-
_7 = BitAnd(move _5, move _6);
21-
assume(move _7);
2213
_0 = move _3 as u32 (IntToInt);
2314
StorageDead(_2);
2415
return;

tests/mir-opt/building/enum_cast.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44
// EMIT_MIR enum_cast.boo.built.after.mir
55
// EMIT_MIR enum_cast.far.built.after.mir
66

7+
// Previously MIR building included range `Assume`s in the MIR statements,
8+
// which these tests demonstrated, but now that we have range metadata on
9+
// parameters in LLVM (in addition to !range metadata on loads) the impact
10+
// of the extra volume of MIR is worse than its value.
11+
// Thus these are now about the discriminant type and the cast type,
12+
// both of which might be different from the backend type of the tag.
13+
714
enum Foo {
815
A,
916
}

tests/mir-opt/building/enum_cast.signy.built.after.mir

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,11 @@ fn signy(_1: SignedAroundZero) -> i16 {
55
let mut _0: i16;
66
let _2: SignedAroundZero;
77
let mut _3: i16;
8-
let mut _4: u16;
9-
let mut _5: bool;
10-
let mut _6: bool;
11-
let mut _7: bool;
128

139
bb0: {
1410
StorageLive(_2);
1511
_2 = move _1;
1612
_3 = discriminant(_2);
17-
_4 = copy _3 as u16 (IntToInt);
18-
_5 = Ge(copy _4, const 65534_u16);
19-
_6 = Le(copy _4, const 2_u16);
20-
_7 = BitOr(move _5, move _6);
21-
assume(move _7);
2213
_0 = move _3 as i16 (IntToInt);
2314
StorageDead(_2);
2415
return;

tests/ui/simd/repr-simd-on-enum.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Used to ICE; see <https://github.com/rust-lang/rust/issues/121097>
2+
3+
#![feature(repr_simd)]
4+
5+
#[repr(simd)] //~ ERROR attribute should be applied to a struct
6+
enum Aligned {
7+
Zero = 0,
8+
One = 1,
9+
}
10+
11+
fn tou8(al: Aligned) -> u8 {
12+
al as u8
13+
}
14+
15+
fn main() {}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0517]: attribute should be applied to a struct
2+
--> $DIR/repr-simd-on-enum.rs:5:8
3+
|
4+
LL | #[repr(simd)]
5+
| ^^^^
6+
LL | / enum Aligned {
7+
LL | | Zero = 0,
8+
LL | | One = 1,
9+
LL | | }
10+
| |_- not a struct
11+
12+
error: aborting due to 1 previous error
13+
14+
For more information about this error, try `rustc --explain E0517`.

0 commit comments

Comments
 (0)