Skip to content

Commit 680ff86

Browse files
committedOct 7, 2021
Auto merge of #86525 - shamatar:array_len_opt, r=oli-obk
Array `.len()` MIR optimization pass This pass kind-of works back the `[T; N].len()` call that at the moment is first coerced as `&[T; N]` -> `&[T]` and then uses `&[T].len()`. Depends on #86383
·
1.88.01.57.0
2 parents ca8078d + a31518f commit 680ff86

18 files changed

+979
-9
lines changed
 

‎compiler/rustc_mir_transform/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ mod lower_intrinsics;
5858
mod lower_slice_len;
5959
mod match_branches;
6060
mod multiple_return_terminators;
61+
mod normalize_array_len;
6162
mod nrvo;
6263
mod remove_noop_landing_pads;
6364
mod remove_storage_markers;
@@ -488,6 +489,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
488489
// machine than on MIR with async primitives.
489490
let optimizations_with_generators: &[&dyn MirPass<'tcx>] = &[
490491
&lower_slice_len::LowerSliceLenCalls, // has to be done before inlining, otherwise actual call will be almost always inlined. Also simple, so can just do first
492+
&normalize_array_len::NormalizeArrayLen, // has to run after `slice::len` lowering
491493
&unreachable_prop::UnreachablePropagation,
492494
&uninhabited_enum_branching::UninhabitedEnumBranching,
493495
&simplify::SimplifyCfg::new("after-uninhabited-enum-branching"),
Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
//! This pass eliminates casting of arrays into slices when their length
2+
//! is taken using `.len()` method. Handy to preserve information in MIR for const prop
3+
4+
use crate::MirPass;
5+
use rustc_data_structures::fx::FxIndexMap;
6+
use rustc_index::bit_set::BitSet;
7+
use rustc_index::vec::IndexVec;
8+
use rustc_middle::mir::*;
9+
use rustc_middle::ty::{self, TyCtxt};
10+
11+
const MAX_NUM_BLOCKS: usize = 800;
12+
const MAX_NUM_LOCALS: usize = 3000;
13+
14+
pub struct NormalizeArrayLen;
15+
16+
impl<'tcx> MirPass<'tcx> for NormalizeArrayLen {
17+
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
18+
if tcx.sess.mir_opt_level() < 4 {
19+
return;
20+
}
21+
22+
// early returns for edge cases of highly unrolled functions
23+
if body.basic_blocks().len() > MAX_NUM_BLOCKS {
24+
return;
25+
}
26+
if body.local_decls().len() > MAX_NUM_LOCALS {
27+
return;
28+
}
29+
normalize_array_len_calls(tcx, body)
30+
}
31+
}
32+
33+
pub fn normalize_array_len_calls<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
34+
let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
35+
36+
// do a preliminary analysis to see if we ever have locals of type `[T;N]` or `&[T;N]`
37+
let mut interesting_locals = BitSet::new_empty(local_decls.len());
38+
for (local, decl) in local_decls.iter_enumerated() {
39+
match decl.ty.kind() {
40+
ty::Array(..) => {
41+
interesting_locals.insert(local);
42+
}
43+
ty::Ref(.., ty, Mutability::Not) => match ty.kind() {
44+
ty::Array(..) => {
45+
interesting_locals.insert(local);
46+
}
47+
_ => {}
48+
},
49+
_ => {}
50+
}
51+
}
52+
if interesting_locals.is_empty() {
53+
// we have found nothing to analyze
54+
return;
55+
}
56+
let num_intesting_locals = interesting_locals.count();
57+
let mut state = FxIndexMap::with_capacity_and_hasher(num_intesting_locals, Default::default());
58+
let mut patches_scratchpad =
59+
FxIndexMap::with_capacity_and_hasher(num_intesting_locals, Default::default());
60+
let mut replacements_scratchpad =
61+
FxIndexMap::with_capacity_and_hasher(num_intesting_locals, Default::default());
62+
for block in basic_blocks {
63+
// make length calls for arrays [T; N] not to decay into length calls for &[T]
64+
// that forbids constant propagation
65+
normalize_array_len_call(
66+
tcx,
67+
block,
68+
local_decls,
69+
&interesting_locals,
70+
&mut state,
71+
&mut patches_scratchpad,
72+
&mut replacements_scratchpad,
73+
);
74+
state.clear();
75+
patches_scratchpad.clear();
76+
replacements_scratchpad.clear();
77+
}
78+
}
79+
80+
struct Patcher<'a, 'tcx> {
81+
tcx: TyCtxt<'tcx>,
82+
patches_scratchpad: &'a FxIndexMap<usize, usize>,
83+
replacements_scratchpad: &'a mut FxIndexMap<usize, Local>,
84+
local_decls: &'a mut IndexVec<Local, LocalDecl<'tcx>>,
85+
statement_idx: usize,
86+
}
87+
88+
impl<'a, 'tcx> Patcher<'a, 'tcx> {
89+
fn patch_expand_statement(
90+
&mut self,
91+
statement: &mut Statement<'tcx>,
92+
) -> Option<std::vec::IntoIter<Statement<'tcx>>> {
93+
let idx = self.statement_idx;
94+
if let Some(len_statemnt_idx) = self.patches_scratchpad.get(&idx).copied() {
95+
let mut statements = Vec::with_capacity(2);
96+
97+
// we are at statement that performs a cast. The only sound way is
98+
// to create another local that performs a similar copy without a cast and then
99+
// use this copy in the Len operation
100+
101+
match &statement.kind {
102+
StatementKind::Assign(box (
103+
..,
104+
Rvalue::Cast(
105+
CastKind::Pointer(ty::adjustment::PointerCast::Unsize),
106+
operand,
107+
_,
108+
),
109+
)) => {
110+
match operand {
111+
Operand::Copy(place) | Operand::Move(place) => {
112+
// create new local
113+
let ty = operand.ty(self.local_decls, self.tcx);
114+
let local_decl =
115+
LocalDecl::with_source_info(ty, statement.source_info.clone());
116+
let local = self.local_decls.push(local_decl);
117+
// make it live
118+
let mut make_live_statement = statement.clone();
119+
make_live_statement.kind = StatementKind::StorageLive(local);
120+
statements.push(make_live_statement);
121+
// copy into it
122+
123+
let operand = Operand::Copy(*place);
124+
let mut make_copy_statement = statement.clone();
125+
let assign_to = Place::from(local);
126+
let rvalue = Rvalue::Use(operand);
127+
make_copy_statement.kind =
128+
StatementKind::Assign(box (assign_to, rvalue));
129+
statements.push(make_copy_statement);
130+
131+
// to reorder we have to copy and make NOP
132+
statements.push(statement.clone());
133+
statement.make_nop();
134+
135+
self.replacements_scratchpad.insert(len_statemnt_idx, local);
136+
}
137+
_ => {
138+
unreachable!("it's a bug in the implementation")
139+
}
140+
}
141+
}
142+
_ => {
143+
unreachable!("it's a bug in the implementation")
144+
}
145+
}
146+
147+
self.statement_idx += 1;
148+
149+
Some(statements.into_iter())
150+
} else if let Some(local) = self.replacements_scratchpad.get(&idx).copied() {
151+
let mut statements = Vec::with_capacity(2);
152+
153+
match &statement.kind {
154+
StatementKind::Assign(box (into, Rvalue::Len(place))) => {
155+
let add_deref = if let Some(..) = place.as_local() {
156+
false
157+
} else if let Some(..) = place.local_or_deref_local() {
158+
true
159+
} else {
160+
unreachable!("it's a bug in the implementation")
161+
};
162+
// replace len statement
163+
let mut len_statement = statement.clone();
164+
let mut place = Place::from(local);
165+
if add_deref {
166+
place = self.tcx.mk_place_deref(place);
167+
}
168+
len_statement.kind = StatementKind::Assign(box (*into, Rvalue::Len(place)));
169+
statements.push(len_statement);
170+
171+
// make temporary dead
172+
let mut make_dead_statement = statement.clone();
173+
make_dead_statement.kind = StatementKind::StorageDead(local);
174+
statements.push(make_dead_statement);
175+
176+
// make original statement NOP
177+
statement.make_nop();
178+
}
179+
_ => {
180+
unreachable!("it's a bug in the implementation")
181+
}
182+
}
183+
184+
self.statement_idx += 1;
185+
186+
Some(statements.into_iter())
187+
} else {
188+
self.statement_idx += 1;
189+
None
190+
}
191+
}
192+
}
193+
194+
fn normalize_array_len_call<'tcx>(
195+
tcx: TyCtxt<'tcx>,
196+
block: &mut BasicBlockData<'tcx>,
197+
local_decls: &mut IndexVec<Local, LocalDecl<'tcx>>,
198+
interesting_locals: &BitSet<Local>,
199+
state: &mut FxIndexMap<Local, usize>,
200+
patches_scratchpad: &mut FxIndexMap<usize, usize>,
201+
replacements_scratchpad: &mut FxIndexMap<usize, Local>,
202+
) {
203+
for (statement_idx, statement) in block.statements.iter_mut().enumerate() {
204+
match &mut statement.kind {
205+
StatementKind::Assign(box (place, rvalue)) => {
206+
match rvalue {
207+
Rvalue::Cast(
208+
CastKind::Pointer(ty::adjustment::PointerCast::Unsize),
209+
operand,
210+
cast_ty,
211+
) => {
212+
let local = if let Some(local) = place.as_local() { local } else { return };
213+
match operand {
214+
Operand::Copy(place) | Operand::Move(place) => {
215+
let operand_local =
216+
if let Some(local) = place.local_or_deref_local() {
217+
local
218+
} else {
219+
return;
220+
};
221+
if !interesting_locals.contains(operand_local) {
222+
return;
223+
}
224+
let operand_ty = local_decls[operand_local].ty;
225+
match (operand_ty.kind(), cast_ty.kind()) {
226+
(ty::Array(of_ty_src, ..), ty::Slice(of_ty_dst)) => {
227+
if of_ty_src == of_ty_dst {
228+
// this is a cast from [T; N] into [T], so we are good
229+
state.insert(local, statement_idx);
230+
}
231+
}
232+
// current way of patching doesn't allow to work with `mut`
233+
(
234+
ty::Ref(
235+
ty::RegionKind::ReErased,
236+
operand_ty,
237+
Mutability::Not,
238+
),
239+
ty::Ref(ty::RegionKind::ReErased, cast_ty, Mutability::Not),
240+
) => {
241+
match (operand_ty.kind(), cast_ty.kind()) {
242+
// current way of patching doesn't allow to work with `mut`
243+
(ty::Array(of_ty_src, ..), ty::Slice(of_ty_dst)) => {
244+
if of_ty_src == of_ty_dst {
245+
// this is a cast from [T; N] into [T], so we are good
246+
state.insert(local, statement_idx);
247+
}
248+
}
249+
_ => {}
250+
}
251+
}
252+
_ => {}
253+
}
254+
}
255+
_ => {}
256+
}
257+
}
258+
Rvalue::Len(place) => {
259+
let local = if let Some(local) = place.local_or_deref_local() {
260+
local
261+
} else {
262+
return;
263+
};
264+
if let Some(cast_statement_idx) = state.get(&local).copied() {
265+
patches_scratchpad.insert(cast_statement_idx, statement_idx);
266+
}
267+
}
268+
_ => {
269+
// invalidate
270+
state.remove(&place.local);
271+
}
272+
}
273+
}
274+
_ => {}
275+
}
276+
}
277+
278+
let mut patcher = Patcher {
279+
tcx,
280+
patches_scratchpad: &*patches_scratchpad,
281+
replacements_scratchpad,
282+
local_decls,
283+
statement_idx: 0,
284+
};
285+
286+
block.expand_statements(|st| patcher.patch_expand_statement(st));
287+
}

‎src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
let mut _7: usize; // in scope 0 at $DIR/slice_len.rs:5:5: 5:33
1313
let mut _8: bool; // in scope 0 at $DIR/slice_len.rs:5:5: 5:33
1414
let mut _9: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:5:6: 5:19
15+
let mut _10: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:5:6: 5:19
1516

1617
bb0: {
1718
StorageLive(_1); // scope 0 at $DIR/slice_len.rs:5:5: 5:33
@@ -27,14 +28,16 @@
2728
// + literal: Const { ty: &[u32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[6547]::main), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) }
2829
_4 = _9; // scope 0 at $DIR/slice_len.rs:5:6: 5:19
2930
_3 = _4; // scope 0 at $DIR/slice_len.rs:5:6: 5:19
31+
StorageLive(_10); // scope 0 at $DIR/slice_len.rs:5:6: 5:19
32+
_10 = _3; // scope 0 at $DIR/slice_len.rs:5:6: 5:19
3033
_2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:5:6: 5:19
3134
StorageDead(_3); // scope 0 at $DIR/slice_len.rs:5:18: 5:19
3235
StorageLive(_6); // scope 0 at $DIR/slice_len.rs:5:31: 5:32
3336
_6 = const 1_usize; // scope 0 at $DIR/slice_len.rs:5:31: 5:32
34-
- _7 = Len((*_2)); // scope 0 at $DIR/slice_len.rs:5:5: 5:33
37+
_7 = const 3_usize; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
38+
StorageDead(_10); // scope 0 at $DIR/slice_len.rs:5:5: 5:33
3539
- _8 = Lt(_6, _7); // scope 0 at $DIR/slice_len.rs:5:5: 5:33
3640
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
37-
+ _7 = const 3_usize; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
3841
+ _8 = const true; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
3942
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> bb1; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
4043
}

‎src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
let mut _7: usize; // in scope 0 at $DIR/slice_len.rs:5:5: 5:33
1313
let mut _8: bool; // in scope 0 at $DIR/slice_len.rs:5:5: 5:33
1414
let mut _9: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:5:6: 5:19
15+
let mut _10: &[u32; 3]; // in scope 0 at $DIR/slice_len.rs:5:6: 5:19
1516

1617
bb0: {
1718
StorageLive(_1); // scope 0 at $DIR/slice_len.rs:5:5: 5:33
@@ -27,14 +28,16 @@
2728
// + literal: Const { ty: &[u32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[6547]::main), const_param_did: None }, substs_: Some([]), promoted: Some(promoted[0]) }) }
2829
_4 = _9; // scope 0 at $DIR/slice_len.rs:5:6: 5:19
2930
_3 = _4; // scope 0 at $DIR/slice_len.rs:5:6: 5:19
31+
StorageLive(_10); // scope 0 at $DIR/slice_len.rs:5:6: 5:19
32+
_10 = _3; // scope 0 at $DIR/slice_len.rs:5:6: 5:19
3033
_2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:5:6: 5:19
3134
StorageDead(_3); // scope 0 at $DIR/slice_len.rs:5:18: 5:19
3235
StorageLive(_6); // scope 0 at $DIR/slice_len.rs:5:31: 5:32
3336
_6 = const 1_usize; // scope 0 at $DIR/slice_len.rs:5:31: 5:32
34-
- _7 = Len((*_2)); // scope 0 at $DIR/slice_len.rs:5:5: 5:33
37+
_7 = const 3_usize; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
38+
StorageDead(_10); // scope 0 at $DIR/slice_len.rs:5:5: 5:33
3539
- _8 = Lt(_6, _7); // scope 0 at $DIR/slice_len.rs:5:5: 5:33
3640
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
37-
+ _7 = const 3_usize; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
3841
+ _8 = const true; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
3942
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> bb1; // scope 0 at $DIR/slice_len.rs:5:5: 5:33
4043
}

‎src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
let mut _20: *const T; // in scope 0 at $DIR/issue_76432.rs:9:70: 9:84
2323
let mut _21: *const T; // in scope 0 at $DIR/issue_76432.rs:9:70: 9:84
2424
let mut _22: !; // in scope 0 at $SRC_DIR/core/src/panic.rs:LL:COL
25+
let mut _23: &[T; 3]; // in scope 0 at $DIR/issue_76432.rs:7:19: 7:29
2526
scope 1 {
2627
debug v => _2; // in scope 1 at $DIR/issue_76432.rs:7:9: 7:10
2728
let _13: &T; // in scope 1 at $DIR/issue_76432.rs:9:10: 9:16
@@ -51,16 +52,17 @@
5152
StorageDead(_6); // scope 0 at $DIR/issue_76432.rs:7:28: 7:29
5253
_4 = &_5; // scope 0 at $DIR/issue_76432.rs:7:19: 7:29
5354
_3 = _4; // scope 0 at $DIR/issue_76432.rs:7:19: 7:29
55+
StorageLive(_23); // scope 0 at $DIR/issue_76432.rs:7:19: 7:29
56+
_23 = _3; // scope 0 at $DIR/issue_76432.rs:7:19: 7:29
5457
_2 = move _3 as &[T] (Pointer(Unsize)); // scope 0 at $DIR/issue_76432.rs:7:19: 7:29
5558
StorageDead(_3); // scope 0 at $DIR/issue_76432.rs:7:28: 7:29
5659
StorageDead(_4); // scope 0 at $DIR/issue_76432.rs:7:29: 7:30
5760
StorageLive(_9); // scope 1 at $DIR/issue_76432.rs:8:5: 11:6
58-
_10 = Len((*_2)); // scope 1 at $DIR/issue_76432.rs:9:9: 9:33
61+
_10 = const 3_usize; // scope 1 at $DIR/issue_76432.rs:9:9: 9:33
62+
StorageDead(_23); // scope 1 at $DIR/issue_76432.rs:9:9: 9:33
5963
_11 = const 3_usize; // scope 1 at $DIR/issue_76432.rs:9:9: 9:33
60-
- _12 = Eq(move _10, const 3_usize); // scope 1 at $DIR/issue_76432.rs:9:9: 9:33
61-
- switchInt(move _12) -> [false: bb1, otherwise: bb2]; // scope 1 at $DIR/issue_76432.rs:9:9: 9:33
62-
+ nop; // scope 1 at $DIR/issue_76432.rs:9:9: 9:33
63-
+ switchInt(move _10) -> [3_usize: bb2, otherwise: bb1]; // scope 1 at $DIR/issue_76432.rs:9:9: 9:33
64+
_12 = const true; // scope 1 at $DIR/issue_76432.rs:9:9: 9:33
65+
goto -> bb2; // scope 1 at $DIR/issue_76432.rs:9:9: 9:33
6466
}
6567

6668
bb1: {
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
- // MIR for `array_bound` before InstCombine
2+
+ // MIR for `array_bound` after InstCombine
3+
4+
fn array_bound(_1: usize, _2: &[u8; N]) -> u8 {
5+
debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:6:36: 6:41
6+
debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:6:50: 6:55
7+
let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:6:70: 6:72
8+
let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:7:8: 7:27
9+
let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:7:8: 7:13
10+
let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
11+
let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
12+
let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
13+
let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:8:15: 8:20
14+
let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
15+
let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
16+
let mut _11: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
17+
18+
bb0: {
19+
StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:7:8: 7:27
20+
StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:7:8: 7:13
21+
_4 = _1; // scope 0 at $DIR/lower_array_len.rs:7:8: 7:13
22+
StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
23+
StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
24+
StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
25+
- _7 = &(*_2); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
26+
+ _7 = _2; // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
27+
StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
28+
_11 = _7; // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
29+
_6 = move _7 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
30+
StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:7:20: 7:21
31+
- _5 = Len((*_11)); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
32+
+ _5 = const N; // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
33+
StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
34+
StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:7:26: 7:27
35+
_3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:7:8: 7:27
36+
StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:7:26: 7:27
37+
StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:7:26: 7:27
38+
switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len.rs:7:8: 7:27
39+
}
40+
41+
bb1: {
42+
StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:8:15: 8:20
43+
_8 = _1; // scope 0 at $DIR/lower_array_len.rs:8:15: 8:20
44+
- _9 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
45+
+ _9 = const N; // scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
46+
_10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
47+
assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb2; // scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
48+
}
49+
50+
bb2: {
51+
_0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
52+
StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:9:5: 9:6
53+
goto -> bb4; // scope 0 at $DIR/lower_array_len.rs:7:5: 11:6
54+
}
55+
56+
bb3: {
57+
_0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:10:9: 10:11
58+
goto -> bb4; // scope 0 at $DIR/lower_array_len.rs:7:5: 11:6
59+
}
60+
61+
bb4: {
62+
StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:11:5: 11:6
63+
return; // scope 0 at $DIR/lower_array_len.rs:12:2: 12:2
64+
}
65+
}
66+
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
- // MIR for `array_bound` before NormalizeArrayLen
2+
+ // MIR for `array_bound` after NormalizeArrayLen
3+
4+
fn array_bound(_1: usize, _2: &[u8; N]) -> u8 {
5+
debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:6:36: 6:41
6+
debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:6:50: 6:55
7+
let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:6:70: 6:72
8+
let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:7:8: 7:27
9+
let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:7:8: 7:13
10+
let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
11+
let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
12+
let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
13+
let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:8:15: 8:20
14+
let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
15+
let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
16+
+ let mut _11: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
17+
18+
bb0: {
19+
StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:7:8: 7:27
20+
StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:7:8: 7:13
21+
_4 = _1; // scope 0 at $DIR/lower_array_len.rs:7:8: 7:13
22+
StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
23+
StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
24+
StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
25+
_7 = &(*_2); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
26+
+ StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
27+
+ _11 = _7; // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
28+
_6 = move _7 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
29+
StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:7:20: 7:21
30+
- _5 = Len((*_6)); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
31+
+ _5 = Len((*_11)); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
32+
+ StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
33+
goto -> bb1; // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
34+
}
35+
36+
bb1: {
37+
StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:7:26: 7:27
38+
_3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:7:8: 7:27
39+
StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:7:26: 7:27
40+
StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:7:26: 7:27
41+
switchInt(move _3) -> [false: bb4, otherwise: bb2]; // scope 0 at $DIR/lower_array_len.rs:7:8: 7:27
42+
}
43+
44+
bb2: {
45+
StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:8:15: 8:20
46+
_8 = _1; // scope 0 at $DIR/lower_array_len.rs:8:15: 8:20
47+
_9 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
48+
_10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
49+
assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb3; // scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
50+
}
51+
52+
bb3: {
53+
_0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
54+
StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:9:5: 9:6
55+
goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:7:5: 11:6
56+
}
57+
58+
bb4: {
59+
_0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:10:9: 10:11
60+
goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:7:5: 11:6
61+
}
62+
63+
bb5: {
64+
StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:11:5: 11:6
65+
return; // scope 0 at $DIR/lower_array_len.rs:12:2: 12:2
66+
}
67+
}
68+
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
- // MIR for `array_bound` before SimplifyLocals
2+
+ // MIR for `array_bound` after SimplifyLocals
3+
4+
fn array_bound(_1: usize, _2: &[u8; N]) -> u8 {
5+
debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:6:36: 6:41
6+
debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:6:50: 6:55
7+
let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:6:70: 6:72
8+
let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:7:8: 7:27
9+
let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:7:8: 7:13
10+
let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
11+
- let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
12+
- let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
13+
- let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:8:15: 8:20
14+
- let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
15+
- let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
16+
- let mut _11: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
17+
+ let _6: usize; // in scope 0 at $DIR/lower_array_len.rs:8:15: 8:20
18+
+ let mut _7: usize; // in scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
19+
+ let mut _8: bool; // in scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
20+
21+
bb0: {
22+
StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:7:8: 7:27
23+
StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:7:8: 7:13
24+
_4 = _1; // scope 0 at $DIR/lower_array_len.rs:7:8: 7:13
25+
StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
26+
- StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
27+
- StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
28+
- _7 = _2; // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
29+
- StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
30+
- _11 = _7; // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
31+
- _6 = move _7 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
32+
- StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:7:20: 7:21
33+
_5 = const N; // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
34+
- StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:7:16: 7:27
35+
- StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:7:26: 7:27
36+
_3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:7:8: 7:27
37+
StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:7:26: 7:27
38+
StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:7:26: 7:27
39+
switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len.rs:7:8: 7:27
40+
}
41+
42+
bb1: {
43+
- StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:8:15: 8:20
44+
- _8 = _1; // scope 0 at $DIR/lower_array_len.rs:8:15: 8:20
45+
- _9 = const N; // scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
46+
- _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
47+
- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb2; // scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
48+
+ StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:8:15: 8:20
49+
+ _6 = _1; // scope 0 at $DIR/lower_array_len.rs:8:15: 8:20
50+
+ _7 = const N; // scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
51+
+ _8 = Lt(_6, _7); // scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
52+
+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb2; // scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
53+
}
54+
55+
bb2: {
56+
- _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
57+
- StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:9:5: 9:6
58+
+ _0 = (*_2)[_6]; // scope 0 at $DIR/lower_array_len.rs:8:9: 8:21
59+
+ StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:9:5: 9:6
60+
goto -> bb4; // scope 0 at $DIR/lower_array_len.rs:7:5: 11:6
61+
}
62+
63+
bb3: {
64+
_0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:10:9: 10:11
65+
goto -> bb4; // scope 0 at $DIR/lower_array_len.rs:7:5: 11:6
66+
}
67+
68+
bb4: {
69+
StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:11:5: 11:6
70+
return; // scope 0 at $DIR/lower_array_len.rs:12:2: 12:2
71+
}
72+
}
73+
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
- // MIR for `array_bound_mut` before InstCombine
2+
+ // MIR for `array_bound_mut` after InstCombine
3+
4+
fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 {
5+
debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:17:40: 17:45
6+
debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:17:54: 17:59
7+
let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:17:78: 17:80
8+
let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:18:8: 18:27
9+
let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:18:8: 18:13
10+
let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
11+
let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
12+
let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
13+
let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:19:15: 19:20
14+
let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
15+
let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
16+
let _11: usize; // in scope 0 at $DIR/lower_array_len.rs:21:15: 21:16
17+
let mut _12: usize; // in scope 0 at $DIR/lower_array_len.rs:21:9: 21:17
18+
let mut _13: bool; // in scope 0 at $DIR/lower_array_len.rs:21:9: 21:17
19+
let mut _14: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
20+
21+
bb0: {
22+
StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:18:8: 18:27
23+
StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:18:8: 18:13
24+
_4 = _1; // scope 0 at $DIR/lower_array_len.rs:18:8: 18:13
25+
StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
26+
StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
27+
StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
28+
_7 = &(*_2); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
29+
StorageLive(_14); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
30+
_14 = _7; // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
31+
_6 = move _7 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
32+
StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:18:20: 18:21
33+
- _5 = Len((*_14)); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
34+
+ _5 = const N; // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
35+
StorageDead(_14); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
36+
StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:18:26: 18:27
37+
_3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:18:8: 18:27
38+
StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:18:26: 18:27
39+
StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:18:26: 18:27
40+
switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len.rs:18:8: 18:27
41+
}
42+
43+
bb1: {
44+
StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:19:15: 19:20
45+
_8 = _1; // scope 0 at $DIR/lower_array_len.rs:19:15: 19:20
46+
- _9 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
47+
+ _9 = const N; // scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
48+
_10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
49+
assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb2; // scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
50+
}
51+
52+
bb2: {
53+
_0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
54+
StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:20:5: 20:6
55+
goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:18:5: 24:6
56+
}
57+
58+
bb3: {
59+
StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:21:15: 21:16
60+
_11 = const 0_usize; // scope 0 at $DIR/lower_array_len.rs:21:15: 21:16
61+
- _12 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:21:9: 21:17
62+
+ _12 = const N; // scope 0 at $DIR/lower_array_len.rs:21:9: 21:17
63+
_13 = Lt(_11, _12); // scope 0 at $DIR/lower_array_len.rs:21:9: 21:17
64+
assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> bb4; // scope 0 at $DIR/lower_array_len.rs:21:9: 21:17
65+
}
66+
67+
bb4: {
68+
(*_2)[_11] = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:21:9: 21:22
69+
StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:21:22: 21:23
70+
_0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:23:9: 23:11
71+
goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:18:5: 24:6
72+
}
73+
74+
bb5: {
75+
StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:24:5: 24:6
76+
return; // scope 0 at $DIR/lower_array_len.rs:25:2: 25:2
77+
}
78+
}
79+
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
- // MIR for `array_bound_mut` before NormalizeArrayLen
2+
+ // MIR for `array_bound_mut` after NormalizeArrayLen
3+
4+
fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 {
5+
debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:17:40: 17:45
6+
debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:17:54: 17:59
7+
let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:17:78: 17:80
8+
let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:18:8: 18:27
9+
let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:18:8: 18:13
10+
let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
11+
let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
12+
let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
13+
let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:19:15: 19:20
14+
let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
15+
let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
16+
let _11: usize; // in scope 0 at $DIR/lower_array_len.rs:21:15: 21:16
17+
let mut _12: usize; // in scope 0 at $DIR/lower_array_len.rs:21:9: 21:17
18+
let mut _13: bool; // in scope 0 at $DIR/lower_array_len.rs:21:9: 21:17
19+
+ let mut _14: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
20+
21+
bb0: {
22+
StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:18:8: 18:27
23+
StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:18:8: 18:13
24+
_4 = _1; // scope 0 at $DIR/lower_array_len.rs:18:8: 18:13
25+
StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
26+
StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
27+
StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
28+
_7 = &(*_2); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
29+
+ StorageLive(_14); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
30+
+ _14 = _7; // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
31+
_6 = move _7 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
32+
StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:18:20: 18:21
33+
- _5 = Len((*_6)); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
34+
+ _5 = Len((*_14)); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
35+
+ StorageDead(_14); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
36+
goto -> bb1; // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
37+
}
38+
39+
bb1: {
40+
StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:18:26: 18:27
41+
_3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:18:8: 18:27
42+
StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:18:26: 18:27
43+
StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:18:26: 18:27
44+
switchInt(move _3) -> [false: bb4, otherwise: bb2]; // scope 0 at $DIR/lower_array_len.rs:18:8: 18:27
45+
}
46+
47+
bb2: {
48+
StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:19:15: 19:20
49+
_8 = _1; // scope 0 at $DIR/lower_array_len.rs:19:15: 19:20
50+
_9 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
51+
_10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
52+
assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb3; // scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
53+
}
54+
55+
bb3: {
56+
_0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
57+
StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:20:5: 20:6
58+
goto -> bb6; // scope 0 at $DIR/lower_array_len.rs:18:5: 24:6
59+
}
60+
61+
bb4: {
62+
StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:21:15: 21:16
63+
_11 = const 0_usize; // scope 0 at $DIR/lower_array_len.rs:21:15: 21:16
64+
_12 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:21:9: 21:17
65+
_13 = Lt(_11, _12); // scope 0 at $DIR/lower_array_len.rs:21:9: 21:17
66+
assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> bb5; // scope 0 at $DIR/lower_array_len.rs:21:9: 21:17
67+
}
68+
69+
bb5: {
70+
(*_2)[_11] = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:21:9: 21:22
71+
StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:21:22: 21:23
72+
_0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:23:9: 23:11
73+
goto -> bb6; // scope 0 at $DIR/lower_array_len.rs:18:5: 24:6
74+
}
75+
76+
bb6: {
77+
StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:24:5: 24:6
78+
return; // scope 0 at $DIR/lower_array_len.rs:25:2: 25:2
79+
}
80+
}
81+
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
- // MIR for `array_bound_mut` before SimplifyLocals
2+
+ // MIR for `array_bound_mut` after SimplifyLocals
3+
4+
fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 {
5+
debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:17:40: 17:45
6+
debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:17:54: 17:59
7+
let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:17:78: 17:80
8+
let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:18:8: 18:27
9+
let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:18:8: 18:13
10+
let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
11+
- let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
12+
- let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
13+
- let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:19:15: 19:20
14+
- let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
15+
- let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
16+
- let _11: usize; // in scope 0 at $DIR/lower_array_len.rs:21:15: 21:16
17+
- let mut _12: usize; // in scope 0 at $DIR/lower_array_len.rs:21:9: 21:17
18+
- let mut _13: bool; // in scope 0 at $DIR/lower_array_len.rs:21:9: 21:17
19+
- let mut _14: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
20+
+ let _6: usize; // in scope 0 at $DIR/lower_array_len.rs:19:15: 19:20
21+
+ let mut _7: usize; // in scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
22+
+ let mut _8: bool; // in scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
23+
+ let _9: usize; // in scope 0 at $DIR/lower_array_len.rs:21:15: 21:16
24+
+ let mut _10: usize; // in scope 0 at $DIR/lower_array_len.rs:21:9: 21:17
25+
+ let mut _11: bool; // in scope 0 at $DIR/lower_array_len.rs:21:9: 21:17
26+
27+
bb0: {
28+
StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:18:8: 18:27
29+
StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:18:8: 18:13
30+
_4 = _1; // scope 0 at $DIR/lower_array_len.rs:18:8: 18:13
31+
StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
32+
- StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
33+
- StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
34+
- _7 = &(*_2); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
35+
- StorageLive(_14); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
36+
- _14 = _7; // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
37+
- _6 = move _7 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
38+
- StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:18:20: 18:21
39+
_5 = const N; // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
40+
- StorageDead(_14); // scope 0 at $DIR/lower_array_len.rs:18:16: 18:27
41+
- StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:18:26: 18:27
42+
_3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:18:8: 18:27
43+
StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:18:26: 18:27
44+
StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:18:26: 18:27
45+
switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len.rs:18:8: 18:27
46+
}
47+
48+
bb1: {
49+
- StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:19:15: 19:20
50+
- _8 = _1; // scope 0 at $DIR/lower_array_len.rs:19:15: 19:20
51+
- _9 = const N; // scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
52+
- _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
53+
- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb2; // scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
54+
+ StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:19:15: 19:20
55+
+ _6 = _1; // scope 0 at $DIR/lower_array_len.rs:19:15: 19:20
56+
+ _7 = const N; // scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
57+
+ _8 = Lt(_6, _7); // scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
58+
+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb2; // scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
59+
}
60+
61+
bb2: {
62+
- _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
63+
- StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:20:5: 20:6
64+
+ _0 = (*_2)[_6]; // scope 0 at $DIR/lower_array_len.rs:19:9: 19:21
65+
+ StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:20:5: 20:6
66+
goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:18:5: 24:6
67+
}
68+
69+
bb3: {
70+
- StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:21:15: 21:16
71+
- _11 = const 0_usize; // scope 0 at $DIR/lower_array_len.rs:21:15: 21:16
72+
- _12 = const N; // scope 0 at $DIR/lower_array_len.rs:21:9: 21:17
73+
- _13 = Lt(const 0_usize, _12); // scope 0 at $DIR/lower_array_len.rs:21:9: 21:17
74+
- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, const 0_usize) -> bb4; // scope 0 at $DIR/lower_array_len.rs:21:9: 21:17
75+
+ StorageLive(_9); // scope 0 at $DIR/lower_array_len.rs:21:15: 21:16
76+
+ _9 = const 0_usize; // scope 0 at $DIR/lower_array_len.rs:21:15: 21:16
77+
+ _10 = const N; // scope 0 at $DIR/lower_array_len.rs:21:9: 21:17
78+
+ _11 = Lt(const 0_usize, _10); // scope 0 at $DIR/lower_array_len.rs:21:9: 21:17
79+
+ assert(move _11, "index out of bounds: the length is {} but the index is {}", move _10, const 0_usize) -> bb4; // scope 0 at $DIR/lower_array_len.rs:21:9: 21:17
80+
}
81+
82+
bb4: {
83+
- (*_2)[_11] = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:21:9: 21:22
84+
- StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:21:22: 21:23
85+
+ (*_2)[_9] = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:21:9: 21:22
86+
+ StorageDead(_9); // scope 0 at $DIR/lower_array_len.rs:21:22: 21:23
87+
_0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:23:9: 23:11
88+
goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:18:5: 24:6
89+
}
90+
91+
bb5: {
92+
StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:24:5: 24:6
93+
return; // scope 0 at $DIR/lower_array_len.rs:25:2: 25:2
94+
}
95+
}
96+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
- // MIR for `array_len` before InstCombine
2+
+ // MIR for `array_len` after InstCombine
3+
4+
fn array_len(_1: &[u8; N]) -> usize {
5+
debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:30:34: 30:37
6+
let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:30:52: 30:57
7+
let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
8+
let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
9+
let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
10+
11+
bb0: {
12+
StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
13+
StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
14+
- _3 = &(*_1); // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
15+
+ _3 = _1; // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
16+
StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
17+
_4 = _3; // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
18+
_2 = move _3 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
19+
StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:31:7: 31:8
20+
- _0 = Len((*_4)); // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
21+
+ _0 = const N; // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
22+
StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
23+
StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:31:13: 31:14
24+
return; // scope 0 at $DIR/lower_array_len.rs:32:2: 32:2
25+
}
26+
}
27+
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
- // MIR for `array_len` before NormalizeArrayLen
2+
+ // MIR for `array_len` after NormalizeArrayLen
3+
4+
fn array_len(_1: &[u8; N]) -> usize {
5+
debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:30:34: 30:37
6+
let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:30:52: 30:57
7+
let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
8+
let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
9+
+ let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
10+
11+
bb0: {
12+
StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
13+
StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
14+
_3 = &(*_1); // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
15+
+ StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
16+
+ _4 = _3; // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
17+
_2 = move _3 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
18+
StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:31:7: 31:8
19+
- _0 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
20+
+ _0 = Len((*_4)); // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
21+
+ StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
22+
goto -> bb1; // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
23+
}
24+
25+
bb1: {
26+
StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:31:13: 31:14
27+
return; // scope 0 at $DIR/lower_array_len.rs:32:2: 32:2
28+
}
29+
}
30+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
- // MIR for `array_len` before SimplifyLocals
2+
+ // MIR for `array_len` after SimplifyLocals
3+
4+
fn array_len(_1: &[u8; N]) -> usize {
5+
debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:30:34: 30:37
6+
let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:30:52: 30:57
7+
- let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
8+
- let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
9+
- let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
10+
11+
bb0: {
12+
- StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
13+
- StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
14+
- _3 = _1; // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
15+
- StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
16+
- _4 = _3; // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
17+
- _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
18+
- StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:31:7: 31:8
19+
_0 = const N; // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
20+
- StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:31:5: 31:14
21+
- StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:31:13: 31:14
22+
return; // scope 0 at $DIR/lower_array_len.rs:32:2: 32:2
23+
}
24+
}
25+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
- // MIR for `array_len_by_value` before InstCombine
2+
+ // MIR for `array_len_by_value` after InstCombine
3+
4+
fn array_len_by_value(_1: [u8; N]) -> usize {
5+
debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:37:43: 37:46
6+
let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:37:60: 37:65
7+
let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
8+
let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
9+
let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
10+
11+
bb0: {
12+
StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
13+
StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
14+
_3 = &_1; // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
15+
StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
16+
_4 = _3; // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
17+
_2 = move _3 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
18+
StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:38:7: 38:8
19+
- _0 = Len((*_4)); // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
20+
+ _0 = const N; // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
21+
StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
22+
StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:38:13: 38:14
23+
return; // scope 0 at $DIR/lower_array_len.rs:39:2: 39:2
24+
}
25+
}
26+
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
- // MIR for `array_len_by_value` before NormalizeArrayLen
2+
+ // MIR for `array_len_by_value` after NormalizeArrayLen
3+
4+
fn array_len_by_value(_1: [u8; N]) -> usize {
5+
debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:37:43: 37:46
6+
let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:37:60: 37:65
7+
let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
8+
let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
9+
+ let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
10+
11+
bb0: {
12+
StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
13+
StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
14+
_3 = &_1; // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
15+
+ StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
16+
+ _4 = _3; // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
17+
_2 = move _3 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
18+
StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:38:7: 38:8
19+
- _0 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
20+
+ _0 = Len((*_4)); // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
21+
+ StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
22+
goto -> bb1; // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
23+
}
24+
25+
bb1: {
26+
StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:38:13: 38:14
27+
return; // scope 0 at $DIR/lower_array_len.rs:39:2: 39:2
28+
}
29+
}
30+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
- // MIR for `array_len_by_value` before SimplifyLocals
2+
+ // MIR for `array_len_by_value` after SimplifyLocals
3+
4+
fn array_len_by_value(_1: [u8; N]) -> usize {
5+
debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:37:43: 37:46
6+
let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:37:60: 37:65
7+
- let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
8+
- let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
9+
- let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
10+
11+
bb0: {
12+
- StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
13+
- StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
14+
- _3 = &_1; // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
15+
- StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
16+
- _4 = _3; // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
17+
- _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
18+
- StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:38:7: 38:8
19+
_0 = const N; // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
20+
- StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:38:5: 38:14
21+
- StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:38:13: 38:14
22+
return; // scope 0 at $DIR/lower_array_len.rs:39:2: 39:2
23+
}
24+
}
25+

‎src/test/mir-opt/lower_array_len.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// compile-flags: -Z mir-opt-level=4
2+
3+
// EMIT_MIR lower_array_len.array_bound.NormalizeArrayLen.diff
4+
// EMIT_MIR lower_array_len.array_bound.SimplifyLocals.diff
5+
// EMIT_MIR lower_array_len.array_bound.InstCombine.diff
6+
pub fn array_bound<const N: usize>(index: usize, slice: &[u8; N]) -> u8 {
7+
if index < slice.len() {
8+
slice[index]
9+
} else {
10+
42
11+
}
12+
}
13+
14+
// EMIT_MIR lower_array_len.array_bound_mut.NormalizeArrayLen.diff
15+
// EMIT_MIR lower_array_len.array_bound_mut.SimplifyLocals.diff
16+
// EMIT_MIR lower_array_len.array_bound_mut.InstCombine.diff
17+
pub fn array_bound_mut<const N: usize>(index: usize, slice: &mut [u8; N]) -> u8 {
18+
if index < slice.len() {
19+
slice[index]
20+
} else {
21+
slice[0] = 42;
22+
23+
42
24+
}
25+
}
26+
27+
// EMIT_MIR lower_array_len.array_len.NormalizeArrayLen.diff
28+
// EMIT_MIR lower_array_len.array_len.SimplifyLocals.diff
29+
// EMIT_MIR lower_array_len.array_len.InstCombine.diff
30+
pub fn array_len<const N: usize>(arr: &[u8; N]) -> usize {
31+
arr.len()
32+
}
33+
34+
// EMIT_MIR lower_array_len.array_len_by_value.NormalizeArrayLen.diff
35+
// EMIT_MIR lower_array_len.array_len_by_value.SimplifyLocals.diff
36+
// EMIT_MIR lower_array_len.array_len_by_value.InstCombine.diff
37+
pub fn array_len_by_value<const N: usize>(arr: [u8; N]) -> usize {
38+
arr.len()
39+
}
40+
41+
fn main() {
42+
let _ = array_bound(3, &[0, 1, 2, 3]);
43+
let mut tmp = [0, 1, 2, 3, 4];
44+
let _ = array_bound_mut(3, &mut [0, 1, 2, 3]);
45+
let _ = array_len(&[0]);
46+
let _ = array_len_by_value([0, 2]);
47+
}

0 commit comments

Comments
 (0)
Please sign in to comment.