Skip to content

Commit

Permalink
Rollup merge of rust-lang#119759 - sfzhu93:master, r=cjgillot
Browse files Browse the repository at this point in the history
Add FileCheck annotations to dataflow-const-prop tests

part of rust-lang#116971.

A few shadowing variable names are changed, so that it is easier to match the variable names in MIR using FileCheck syntax.

Also, there's a FIXME in [enum.rs](https://github.com/rust-lang/rust/pull/119759/files#diff-7621f55327838e489a95ac99ae1e6126b37c57aff582594e6bee9d7e7e56fc58) because the MIR looks suspicious to me. It has been explained in the comments.

r? cjgillot
  • Loading branch information
matthiaskrgr authored Feb 4, 2024
2 parents 671eb38 + 699b59c commit 2b25957
Show file tree
Hide file tree
Showing 32 changed files with 394 additions and 87 deletions.
14 changes: 13 additions & 1 deletion tests/mir-opt/dataflow-const-prop/array_index.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: DataflowConstProp
// EMIT_MIR_FOR_EACH_BIT_WIDTH

// EMIT_MIR array_index.main.DataflowConstProp.diff

// CHECK-LABEL: fn main() -> () {
fn main() {
// CHECK: let mut [[array_lit:_.*]]: [u32; 4];
// CHECK: debug x => [[x:_.*]];

// CHECK: [[array_lit]] = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
// CHECK-NOT: {{_.*}} = Len(
// CHECK-NOT: {{_.*}} = Lt(
// CHECK-NOT: assert(move _
// CHECK: {{_.*}} = const 4_usize;
// CHECK: {{_.*}} = const true;
// CHECK: assert(const true
// CHECK: [[x]] = [[array_lit]][2 of 3];
let x: u32 = [0, 1, 2, 3][2];
}
9 changes: 8 additions & 1 deletion tests/mir-opt/dataflow-const-prop/boolean_identities.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
// skip-filecheck
// unit-test: DataflowConstProp

// EMIT_MIR boolean_identities.test.DataflowConstProp.diff

// CHECK-LABEL: fn test(
pub fn test(x: bool, y: bool) -> bool {
// CHECK-NOT: BitAnd(
// CHECK-NOT: BitOr(
(y | true) & (x & false)
// CHECK: _0 = const false;
// CHECK-NOT: BitAnd(
// CHECK-NOT: BitOr(
}

// CHECK-LABEL: fn main(
fn main() {
test(true, false);
}
8 changes: 7 additions & 1 deletion tests/mir-opt/dataflow-const-prop/cast.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
// skip-filecheck
// unit-test: DataflowConstProp

// EMIT_MIR cast.main.DataflowConstProp.diff

// CHECK-LABEL: fn main(
fn main() {
// CHECK: debug a => [[a:_.*]];
// CHECK: debug b => [[b:_.*]];

// CHECK: [[a]] = const 257_i32;
let a = 257;
// CHECK: [[b]] = const 2_u8;
let b = a as u8 + 1;
}
19 changes: 18 additions & 1 deletion tests/mir-opt/dataflow-const-prop/checked.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,32 @@
// skip-filecheck
// unit-test: DataflowConstProp
// compile-flags: -Coverflow-checks=on
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY

// EMIT_MIR checked.main.DataflowConstProp.diff
#[allow(arithmetic_overflow)]

// CHECK-LABEL: fn main(
fn main() {
// CHECK: debug a => [[a:_.*]];
// CHECK: debug b => [[b:_.*]];
// CHECK: debug c => [[c:_.*]];
// CHECK: debug d => [[d:_.*]];
// CHECK: debug e => [[e:_.*]];

// CHECK: [[a]] = const 1_i32;
let a = 1;

// CHECK: [[b]] = const 2_i32;
let b = 2;

// CHECK: assert(!const false,
// CHECK: [[c]] = const 3_i32;
let c = a + b;

// CHECK: [[d]] = const _;
let d = i32::MAX;

// CHECK: assert(!const true,
// CHECK: [[e]] = const i32::MIN;
let e = d + 1;
}
13 changes: 12 additions & 1 deletion tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
// skip-filecheck
// unit-test: DataflowConstProp
// compile-flags: -Zmir-enable-passes=+GVN,+Inline
// ignore-debug assertions change the output MIR
// EMIT_MIR_FOR_EACH_BIT_WIDTH
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY

// This test is to check ICE in issue [#115789](https://github.com/rust-lang/rust/issues/115789).

struct A {
foo: Box<[bool]>,
}

// EMIT_MIR default_boxed_slice.main.GVN.diff
// EMIT_MIR default_boxed_slice.main.DataflowConstProp.diff

// CHECK-LABEL: fn main(
fn main() {
// ConstProp will create a constant of type `Box<[bool]>`.
// FIXME: it is not yet a constant.

// Verify that `DataflowConstProp` does not ICE trying to dereference it directly.

// CHECK: debug a => [[a:_.*]];
// We may check other inlined functions as well...

// CHECK: {{_.*}} = Box::<[bool]>(
// FIXME: should be `{{_.*}} = const Box::<[bool]>`
let a: A = A { foo: Box::default() };
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
debug x => _2;
}
scope 3 {
debug x => _4;
debug x1 => _4;
}
scope 4 {
debug x => _5;
debug x2 => _5;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
debug x => _2;
}
scope 3 {
debug x => _4;
debug x1 => _4;
}
scope 4 {
debug x => _5;
debug x2 => _5;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
let _6: u8;
let _8: u8;
scope 2 {
debug x => _6;
debug x2 => _6;
let _9: u8;
scope 4 {
debug y => _9;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
let _6: u8;
let _8: u8;
scope 2 {
debug x => _6;
debug x2 => _6;
let _9: u8;
scope 4 {
debug y => _9;
Expand Down
80 changes: 70 additions & 10 deletions tests/mir-opt/dataflow-const-prop/enum.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// skip-filecheck
// unit-test: DataflowConstProp
// EMIT_MIR_FOR_EACH_BIT_WIDTH

Expand All @@ -13,34 +12,76 @@ enum E {
}

// EMIT_MIR enum.simple.DataflowConstProp.diff

// CHECK-LABEL: fn simple(
fn simple() {
// CHECK: debug e => [[e:_.*]];
// CHECK: debug x => [[x:_.*]];
// CHECK: [[e]] = const E::V1(0_i32);
let e = E::V1(0);
let x = match e { E::V1(x) => x, E::V2(x) => x };

// CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb1, otherwise: bb2];
// CHECK: [[target_bb]]: {
// CHECK: [[x]] = const 0_i32;
let x = match e { E::V1(x1) => x1, E::V2(x2) => x2 };
}

// EMIT_MIR enum.constant.DataflowConstProp.diff

// CHECK-LABEL: fn constant(
fn constant() {
// CHECK: debug e => [[e:_.*]];
// CHECK: debug x => [[x:_.*]];
const C: E = E::V1(0);

// CHECK: [[e]] = const _;
let e = C;
let x = match e { E::V1(x) => x, E::V2(x) => x };
// CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb1, otherwise: bb2];
// CHECK: [[target_bb]]: {
// CHECK: [[x]] = const 0_i32;
let x = match e { E::V1(x1) => x1, E::V2(x2) => x2 };
}

// EMIT_MIR enum.statics.DataflowConstProp.diff

// CHECK-LABEL: fn statics(
fn statics() {
// CHECK: debug e1 => [[e1:_.*]];
// CHECK: debug x1 => [[x1:_.*]];
// CHECK: debug e2 => [[e2:_.*]];
// CHECK: debug x2 => [[x2:_.*]];

static C: E = E::V1(0);
let e = C;
let x = match e { E::V1(x) => x, E::V2(x) => x };

// CHECK: [[e1]] = const E::V1(0_i32);
let e1 = C;
// CHECK: switchInt(const 0_isize) -> [0: [[target_bb:bb.*]], 1: bb1, otherwise: bb2];
// CHECK: [[target_bb]]: {
// CHECK: [[x1]] = const 0_i32;
let x1 = match e1 { E::V1(x11) => x11, E::V2(x12) => x12 };

static RC: &E = &E::V2(4);
let e = RC;
let x = match e { E::V1(x) => x, E::V2(x) => x };

// CHECK: [[t:_.*]] = const {alloc2: &&E};
// CHECK: [[e2]] = (*[[t]]);
let e2 = RC;

// CHECK: switchInt({{move _.*}}) -> {{.*}}
// FIXME: add checks for x2. Currently, their MIRs are not symmetric in the two
// switch branches.
// One is `_9 = &(*_12) and another is `_9 = _11`. It is different from what we can
// get by printing MIR directly. It is better to check if there are any bugs in the
// MIR passes around this stage.
let x2 = match e2 { E::V1(x21) => x21, E::V2(x22) => x22 };
}

#[rustc_layout_scalar_valid_range_start(1)]
#[rustc_nonnull_optimization_guaranteed]
struct NonZeroUsize(usize);

// EMIT_MIR enum.mutate_discriminant.DataflowConstProp.diff

// CHECK-LABEL: fn mutate_discriminant(
#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
fn mutate_discriminant() -> u8 {
mir!(
Expand All @@ -50,7 +91,11 @@ fn mutate_discriminant() -> u8 {
// This assignment overwrites the niche in which the discriminant is stored.
place!(Field(Field(Variant(x, 1), 0), 0)) = 0_usize;
// So we cannot know the value of this discriminant.

// CHECK: [[a:_.*]] = discriminant({{_.*}});
let a = Discriminant(x);

// CHECK: switchInt([[a]]) -> [0: {{bb.*}}, otherwise: {{bb.*}}];
match a {
0 => bb1,
_ => bad,
Expand All @@ -68,18 +113,33 @@ fn mutate_discriminant() -> u8 {
}

// EMIT_MIR enum.multiple.DataflowConstProp.diff
// CHECK-LABEL: fn multiple(
fn multiple(x: bool, i: u8) {
// CHECK: debug x => [[x:_.*]];
// CHECK: debug e => [[e:_.*]];
// CHECK: debug x2 => [[x2:_.*]];
// CHECK: debug y => [[y:_.*]];
let e = if x {
// CHECK: [[e]] = Option::<u8>::Some(move {{_.*}});
Some(i)
} else {
// CHECK: [[e]] = Option::<u8>::None;
None
};
// The dataflow state must have:
// discriminant(e) => Top
// (e as Some).0 => Top
let x = match e { Some(i) => i, None => 0 };
// Therefore, `x` should be `Top` here, and no replacement shall happen.
let y = x;
// CHECK: [[x2]] = const 0_u8;
// CHECK: [[some:_.*]] = (({{_.*}} as Some).0: u8)
// CHECK: [[x2]] = [[some]];
let x2 = match e { Some(i) => i, None => 0 };

// Therefore, `x2` should be `Top` here, and no replacement shall happen.

// CHECK-NOT: [[y]] = const
// CHECK: [[y]] = [[x2]];
// CHECK-NOT: [[y]] = const
let y = x2;
}

fn main() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
debug x => _2;
}
scope 3 {
debug x => _4;
debug x1 => _4;
}
scope 4 {
debug x => _5;
debug x2 => _5;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
debug x => _2;
}
scope 3 {
debug x => _4;
debug x1 => _4;
}
scope 4 {
debug x => _5;
debug x2 => _5;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,34 @@
let mut _8: &&E;
let mut _10: isize;
scope 1 {
debug e => _1;
debug e1 => _1;
let _3: i32;
let _5: i32;
let _6: i32;
scope 2 {
debug x => _3;
debug x1 => _3;
let _7: &E;
scope 5 {
debug e => _7;
debug e2 => _7;
let _9: &i32;
let _11: &i32;
let _12: &i32;
scope 6 {
debug x => _9;
debug x2 => _9;
}
scope 7 {
debug x => _11;
debug x21 => _11;
}
scope 8 {
debug x => _12;
debug x22 => _12;
}
}
}
scope 3 {
debug x => _5;
debug x11 => _5;
}
scope 4 {
debug x => _6;
debug x12 => _6;
}
}

Expand Down
Loading

0 comments on commit 2b25957

Please sign in to comment.