Skip to content

Commit eac55e7

Browse files
authored
Rollup merge of rust-lang#120171 - cjgillot:jump-threading-assume-assert, r=tmiasko
Fix assume and assert in jump threading r? `@tmiasko`
2 parents 866296b + a0a7173 commit eac55e7

File tree

11 files changed

+209
-15
lines changed

11 files changed

+209
-15
lines changed

compiler/rustc_mir_build/src/build/custom/parse/instruction.rs

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
2020
@call(mir_storage_dead, args) => {
2121
Ok(StatementKind::StorageDead(self.parse_local(args[0])?))
2222
},
23+
@call(mir_assume, args) => {
24+
let op = self.parse_operand(args[0])?;
25+
Ok(StatementKind::Intrinsic(Box::new(NonDivergingIntrinsic::Assume(op))))
26+
},
2327
@call(mir_deinit, args) => {
2428
Ok(StatementKind::Deinit(Box::new(self.parse_place(args[0])?)))
2529
},

compiler/rustc_mir_transform/src/jump_threading.rs

+2-15
Original file line numberDiff line numberDiff line change
@@ -518,11 +518,6 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
518518
cost: &CostChecker<'_, 'tcx>,
519519
depth: usize,
520520
) {
521-
let register_opportunity = |c: Condition| {
522-
debug!(?bb, ?c.target, "register");
523-
self.opportunities.push(ThreadingOpportunity { chain: vec![bb], target: c.target })
524-
};
525-
526521
let term = self.body.basic_blocks[bb].terminator();
527522
let place_to_flood = match term.kind {
528523
// We come from a target, so those are not possible.
@@ -544,16 +539,8 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
544539
// Flood the overwritten place, and progress through.
545540
TerminatorKind::Drop { place: destination, .. }
546541
| TerminatorKind::Call { destination, .. } => Some(destination),
547-
// Treat as an `assume(cond == expected)`.
548-
TerminatorKind::Assert { ref cond, expected, .. } => {
549-
if let Some(place) = cond.place()
550-
&& let Some(conditions) = state.try_get(place.as_ref(), self.map)
551-
{
552-
let expected = if expected { ScalarInt::TRUE } else { ScalarInt::FALSE };
553-
conditions.iter_matches(expected).for_each(register_opportunity);
554-
}
555-
None
556-
}
542+
// Ignore, as this can be a no-op at codegen time.
543+
TerminatorKind::Assert { .. } => None,
557544
};
558545

559546
// We can recurse through this terminator.

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,7 @@ symbols! {
10271027
minnumf32,
10281028
minnumf64,
10291029
mips_target_feature,
1030+
mir_assume,
10301031
mir_basic_block,
10311032
mir_call,
10321033
mir_cast_transmute,

library/core/src/intrinsics/mir.rs

+2
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,8 @@ define!("mir_unwind_resume",
357357

358358
define!("mir_storage_live", fn StorageLive<T>(local: T));
359359
define!("mir_storage_dead", fn StorageDead<T>(local: T));
360+
#[cfg(not(bootstrap))]
361+
define!("mir_assume", fn Assume(operand: bool));
360362
define!("mir_deinit", fn Deinit<T>(place: T));
361363
define!("mir_checked", fn Checked<T>(binop: T) -> (T, bool));
362364
define!("mir_len", fn Len<T>(place: T) -> usize);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// MIR for `assume_constant` after built
2+
3+
fn assume_constant() -> () {
4+
let mut _0: ();
5+
6+
bb0: {
7+
assume(const true);
8+
return;
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// MIR for `assume_local` after built
2+
3+
fn assume_local(_1: bool) -> () {
4+
let mut _0: ();
5+
6+
bb0: {
7+
assume(_1);
8+
return;
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// MIR for `assume_place` after built
2+
3+
fn assume_place(_1: (bool, u8)) -> () {
4+
let mut _0: ();
5+
6+
bb0: {
7+
assume((_1.0: bool));
8+
return;
9+
}
10+
}
+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// skip-filecheck
2+
#![feature(custom_mir, core_intrinsics)]
3+
4+
extern crate core;
5+
use core::intrinsics::mir::*;
6+
7+
// EMIT_MIR assume.assume_local.built.after.mir
8+
#[custom_mir(dialect = "built")]
9+
fn assume_local(x: bool) {
10+
mir!(
11+
{
12+
Assume(x);
13+
Return()
14+
}
15+
)
16+
}
17+
18+
// EMIT_MIR assume.assume_place.built.after.mir
19+
#[custom_mir(dialect = "built")]
20+
fn assume_place(p: (bool, u8)) {
21+
mir!(
22+
{
23+
Assume(p.0);
24+
Return()
25+
}
26+
)
27+
}
28+
29+
// EMIT_MIR assume.assume_constant.built.after.mir
30+
#[custom_mir(dialect = "built")]
31+
fn assume_constant() {
32+
mir!(
33+
{
34+
Assume(true);
35+
Return()
36+
}
37+
)
38+
}
39+
40+
fn main() {
41+
assume_local(true);
42+
assume_place((true, 50));
43+
assume_constant();
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
- // MIR for `assume` before JumpThreading
2+
+ // MIR for `assume` after JumpThreading
3+
4+
fn assume(_1: u8, _2: bool) -> u8 {
5+
let mut _0: u8;
6+
7+
bb0: {
8+
switchInt(_1) -> [7: bb1, otherwise: bb2];
9+
}
10+
11+
bb1: {
12+
assume(_2);
13+
- goto -> bb3;
14+
+ goto -> bb6;
15+
}
16+
17+
bb2: {
18+
goto -> bb3;
19+
}
20+
21+
bb3: {
22+
switchInt(_2) -> [0: bb4, otherwise: bb5];
23+
}
24+
25+
bb4: {
26+
_0 = const 4_u8;
27+
return;
28+
}
29+
30+
bb5: {
31+
_0 = const 5_u8;
32+
return;
33+
+ }
34+
+
35+
+ bb6: {
36+
+ goto -> bb5;
37+
}
38+
}
39+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
- // MIR for `assume` before JumpThreading
2+
+ // MIR for `assume` after JumpThreading
3+
4+
fn assume(_1: u8, _2: bool) -> u8 {
5+
let mut _0: u8;
6+
7+
bb0: {
8+
switchInt(_1) -> [7: bb1, otherwise: bb2];
9+
}
10+
11+
bb1: {
12+
assume(_2);
13+
- goto -> bb3;
14+
+ goto -> bb6;
15+
}
16+
17+
bb2: {
18+
goto -> bb3;
19+
}
20+
21+
bb3: {
22+
switchInt(_2) -> [0: bb4, otherwise: bb5];
23+
}
24+
25+
bb4: {
26+
_0 = const 4_u8;
27+
return;
28+
}
29+
30+
bb5: {
31+
_0 = const 5_u8;
32+
return;
33+
+ }
34+
+
35+
+ bb6: {
36+
+ goto -> bb5;
37+
}
38+
}
39+

tests/mir-opt/jump_threading.rs

+48
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,52 @@ fn disappearing_bb(x: u8) -> u8 {
453453
)
454454
}
455455

456+
/// Verify that we can leverage the existence of an `Assume` terminator.
457+
#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
458+
fn assume(a: u8, b: bool) -> u8 {
459+
// CHECK-LABEL: fn assume(
460+
mir!(
461+
{
462+
// CHECK: bb0: {
463+
// CHECK-NEXT: switchInt(_1) -> [7: bb1, otherwise: bb2]
464+
match a { 7 => bb1, _ => bb2 }
465+
}
466+
bb1 = {
467+
// CHECK: bb1: {
468+
// CHECK-NEXT: assume(_2);
469+
// CHECK-NEXT: goto -> bb6;
470+
Assume(b);
471+
Goto(bb3)
472+
}
473+
bb2 = {
474+
// CHECK: bb2: {
475+
// CHECK-NEXT: goto -> bb3;
476+
Goto(bb3)
477+
}
478+
bb3 = {
479+
// CHECK: bb3: {
480+
// CHECK-NEXT: switchInt(_2) -> [0: bb4, otherwise: bb5];
481+
match b { false => bb4, _ => bb5 }
482+
}
483+
bb4 = {
484+
// CHECK: bb4: {
485+
// CHECK-NEXT: _0 = const 4_u8;
486+
// CHECK-NEXT: return;
487+
RET = 4;
488+
Return()
489+
}
490+
bb5 = {
491+
// CHECK: bb5: {
492+
// CHECK-NEXT: _0 = const 5_u8;
493+
// CHECK-NEXT: return;
494+
RET = 5;
495+
Return()
496+
}
497+
// CHECK: bb6: {
498+
// CHECK-NEXT: goto -> bb5;
499+
)
500+
}
501+
456502
fn main() {
457503
too_complex(Ok(0));
458504
identity(Ok(0));
@@ -464,6 +510,7 @@ fn main() {
464510
mutable_ref();
465511
renumbered_bb(true);
466512
disappearing_bb(7);
513+
assume(7, false);
467514
}
468515

469516
// EMIT_MIR jump_threading.too_complex.JumpThreading.diff
@@ -476,3 +523,4 @@ fn main() {
476523
// EMIT_MIR jump_threading.mutable_ref.JumpThreading.diff
477524
// EMIT_MIR jump_threading.renumbered_bb.JumpThreading.diff
478525
// EMIT_MIR jump_threading.disappearing_bb.JumpThreading.diff
526+
// EMIT_MIR jump_threading.assume.JumpThreading.diff

0 commit comments

Comments
 (0)