mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 14:01:51 +00:00
Rollup merge of #119759 - sfzhu93:master, r=cjgillot
Add FileCheck annotations to dataflow-const-prop tests part of #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
This commit is contained in:
commit
2b259577aa
@ -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];
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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() };
|
||||
}
|
||||
|
@ -14,10 +14,10 @@
|
||||
debug x => _2;
|
||||
}
|
||||
scope 3 {
|
||||
debug x => _4;
|
||||
debug x1 => _4;
|
||||
}
|
||||
scope 4 {
|
||||
debug x => _5;
|
||||
debug x2 => _5;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,10 +14,10 @@
|
||||
debug x => _2;
|
||||
}
|
||||
scope 3 {
|
||||
debug x => _4;
|
||||
debug x1 => _4;
|
||||
}
|
||||
scope 4 {
|
||||
debug x => _5;
|
||||
debug x2 => _5;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -1,4 +1,3 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
|
||||
@ -13,27 +12,67 @@ 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)]
|
||||
@ -41,6 +80,8 @@ fn statics() {
|
||||
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!(
|
||||
@ -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,
|
||||
@ -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() {
|
||||
|
@ -14,10 +14,10 @@
|
||||
debug x => _2;
|
||||
}
|
||||
scope 3 {
|
||||
debug x => _4;
|
||||
debug x1 => _4;
|
||||
}
|
||||
scope 4 {
|
||||
debug x => _5;
|
||||
debug x2 => _5;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,10 +14,10 @@
|
||||
debug x => _2;
|
||||
}
|
||||
scope 3 {
|
||||
debug x => _4;
|
||||
debug x1 => _4;
|
||||
}
|
||||
scope 4 {
|
||||
debug x => _5;
|
||||
debug x2 => _5;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,26 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
|
||||
// EMIT_MIR if.main.DataflowConstProp.diff
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// CHECK: debug b => [[b:_.*]];
|
||||
// CHECK: debug c => [[c:_.*]];
|
||||
// CHECK: debug d => [[d:_.*]];
|
||||
// CHECK: debug e => [[e:_.*]];
|
||||
|
||||
let a = 1;
|
||||
|
||||
// CHECK: switchInt(const true) -> [0: {{bb.*}}, otherwise: {{bb.*}}];
|
||||
// CHECK: [[b]] = const 2_i32;
|
||||
let b = if a == 1 { 2 } else { 3 };
|
||||
|
||||
// CHECK: [[c]] = const 3_i32;
|
||||
let c = b + 1;
|
||||
|
||||
// CHECK: switchInt(const true) -> [0: {{bb.*}}, otherwise: {{bb.*}}];
|
||||
// CHECK: [[d]] = const 1_i32;
|
||||
let d = if a == 1 { a } else { a + 1 };
|
||||
|
||||
// CHECK: [[e]] = const 2_i32;
|
||||
let e = d + 1;
|
||||
}
|
||||
|
@ -1,11 +1,14 @@
|
||||
// skip-filecheck
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
// unit-test: DataflowConstProp
|
||||
// compile-flags: -Zmir-enable-passes=+Inline
|
||||
|
||||
// EMIT_MIR inherit_overflow.main.DataflowConstProp.diff
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// After inlining, this will contain a `CheckedBinaryOp`.
|
||||
// Propagating the overflow is ok as codegen will just skip emitting the panic.
|
||||
|
||||
// CHECK: {{_.*}} = const (0_u8, true);
|
||||
// CHECK: assert(!const true,
|
||||
let _ = <u8 as std::ops::Add>::add(255, 1);
|
||||
}
|
||||
|
@ -1,9 +1,18 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
|
||||
// EMIT_MIR issue_81605.f.DataflowConstProp.diff
|
||||
|
||||
// Plese find the original issue [here](https://github.com/rust-lang/rust/issues/81605).
|
||||
// This test program comes directly from the issue. Prior to this issue,
|
||||
// the compiler cannot simplify the return value of `f` into 2. This was
|
||||
// solved by adding a new MIR constant propagation based on dataflow
|
||||
// analysis in [#101168](https://github.com/rust-lang/rust/pull/101168).
|
||||
|
||||
// CHECK-LABEL: fn f(
|
||||
fn f() -> usize {
|
||||
// CHECK: switchInt(const true) -> [0: {{bb.*}}, otherwise: {{bb.*}}];
|
||||
1 + if true { 1 } else { 2 }
|
||||
// CHECK: _0 = const 2_usize;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -1,10 +1,18 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
|
||||
// EMIT_MIR large_array_index.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// check that we don't propagate this, because it's too large
|
||||
|
||||
// CHECK: debug x => [[x:_.*]];
|
||||
// CHECK: [[array_lit:_.*]] = [const 0_u8; 5000];
|
||||
// CHECK: {{_.*}} = const 5000_usize;
|
||||
// CHECK: {{_.*}} = const true;
|
||||
// CHECK: assert(const true
|
||||
// CHECK: [[x]] = [[array_lit]][2 of 3];
|
||||
let x: u8 = [0_u8; 5000][2];
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
|
||||
// EMIT_MIR mult_by_zero.test.DataflowConstProp.diff
|
||||
// CHECK-LABEL: fn test(
|
||||
fn test(x : i32) -> i32 {
|
||||
x * 0
|
||||
// CHECK: _0 = const 0_i32;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -1,4 +1,3 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
|
||||
@ -29,18 +28,46 @@ struct Delta<T> {
|
||||
}
|
||||
|
||||
// EMIT_MIR offset_of.concrete.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn concrete(
|
||||
fn concrete() {
|
||||
// CHECK: debug x => [[x:_.*]];
|
||||
// CHECK: debug y => [[y:_.*]];
|
||||
// CHECK: debug z0 => [[z0:_.*]];
|
||||
// CHECK: debug z1 => [[z1:_.*]];
|
||||
|
||||
// CHECK: [[x]] = must_use::<usize>(const 4_usize) -> {{.*}}
|
||||
let x = offset_of!(Alpha, x);
|
||||
|
||||
// CHECK: [[y]] = must_use::<usize>(const 0_usize) -> {{.*}}
|
||||
let y = offset_of!(Alpha, y);
|
||||
|
||||
// CHECK: [[z0]] = must_use::<usize>(const 2_usize) -> {{.*}}
|
||||
let z0 = offset_of!(Alpha, z.0);
|
||||
|
||||
// CHECK: [[z1]] = must_use::<usize>(const 3_usize) -> {{.*}}
|
||||
let z1 = offset_of!(Alpha, z.1);
|
||||
}
|
||||
|
||||
// EMIT_MIR offset_of.generic.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn generic(
|
||||
fn generic<T>() {
|
||||
// CHECK: debug gx => [[gx:_.*]];
|
||||
// CHECK: debug gy => [[gy:_.*]];
|
||||
// CHECK: debug dx => [[dx:_.*]];
|
||||
// CHECK: debug dy => [[dy:_.*]];
|
||||
|
||||
// CHECK: [[gx]] = must_use::<usize>(move {{_.*}}) -> {{.*}}
|
||||
let gx = offset_of!(Gamma<T>, x);
|
||||
|
||||
// CHECK: [[gy]] = must_use::<usize>(move {{_.*}}) -> {{.*}}
|
||||
let gy = offset_of!(Gamma<T>, y);
|
||||
|
||||
// CHECK: [[dx]] = must_use::<usize>(const 0_usize) -> {{.*}}
|
||||
let dx = offset_of!(Delta<T>, x);
|
||||
|
||||
// CHECK: [[dy]] = must_use::<usize>(const 2_usize) -> {{.*}}
|
||||
let dy = offset_of!(Delta<T>, y);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
// skip-filecheck
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
// unit-test: DataflowConstProp
|
||||
|
||||
@ -9,11 +8,23 @@ fn escape<T>(x: &T) {}
|
||||
fn some_function() {}
|
||||
|
||||
// EMIT_MIR ref_without_sb.main.DataflowConstProp.diff
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// CHECK: debug a => [[a:_.*]];
|
||||
// CHECK: debug b => [[b:_.*]];
|
||||
|
||||
let mut a = 0;
|
||||
|
||||
// CHECK: {{_.*}} = escape::<i32>(move {{_.*}}) -> {{.*}}
|
||||
escape(&a);
|
||||
a = 1;
|
||||
|
||||
// CHECK: {{_.*}} = some_function() -> {{.*}}
|
||||
some_function();
|
||||
// This should currently not be propagated.
|
||||
|
||||
// CHECK-NOT: [[b]] = const
|
||||
// CHECK: [[b]] = [[a]];
|
||||
// CHECK-NOT: [[b]] = const
|
||||
let b = a;
|
||||
}
|
||||
|
@ -1,9 +1,21 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
|
||||
// EMIT_MIR repeat.main.DataflowConstProp.diff
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// CHECK: debug x => [[x:_.*]];
|
||||
|
||||
// CHECK: [[array_lit:_.*]] = [const 42_u32; 8];
|
||||
// CHECK-NOT: {{_.*}} = Len(
|
||||
// CHECK-NOT: {{_.*}} = Lt(
|
||||
// CHECK: {{_.*}} = const 8_usize;
|
||||
// CHECK: {{_.*}} = const true;
|
||||
// CHECK: assert(const true
|
||||
|
||||
// CHECK-NOT: [[t:_.*]] = [[array_lit]][_
|
||||
// CHECK: [[t:_.*]] = [[array_lit]][2 of 3];
|
||||
// CHECK: [[x]] = Add(move [[t]], const 0_u32);
|
||||
let x: u32 = [42; 8][2] + 0;
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
|
||||
// The struct has scalar ABI, but is not a scalar type.
|
||||
@ -7,7 +6,15 @@
|
||||
struct I32(i32);
|
||||
|
||||
// EMIT_MIR repr_transparent.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// CHECK: debug x => [[x:_.*]];
|
||||
// CHECK: debug y => [[y:_.*]];
|
||||
|
||||
// CHECK: [[x]] = const I32(0_i32);
|
||||
let x = I32(0);
|
||||
|
||||
// CHECK: [[y]] = const I32(0_i32);
|
||||
let y = I32(x.0 + x.0);
|
||||
}
|
||||
|
@ -1,13 +1,26 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
|
||||
// EMIT_MIR self_assign.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// CHECK: debug a => [[a:_.*]];
|
||||
// CHECK: debug b => [[b:_.*]];
|
||||
|
||||
let mut a = 0;
|
||||
|
||||
// CHECK: [[a]] = Add(move {{_.*}}, const 1_i32);
|
||||
a = a + 1;
|
||||
|
||||
// CHECK: [[a]] = move {{_.*}};
|
||||
a = a;
|
||||
|
||||
// CHECK: [[b]] = &[[a]];
|
||||
let mut b = &a;
|
||||
|
||||
// CHECK: [[b]] = move {{_.*}};
|
||||
b = b;
|
||||
|
||||
// CHECK: [[a]] = move {{_.*}};
|
||||
a = *b;
|
||||
}
|
||||
|
@ -1,9 +1,15 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
|
||||
// EMIT_MIR self_assign_add.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// CHECK: debug a => [[a:_.*]];
|
||||
let mut a = 0;
|
||||
|
||||
// CHECK: [[a]] = const 1_i32;
|
||||
a += 1;
|
||||
|
||||
// CHECK: [[a]] = const 2_i32;
|
||||
a += 1;
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
// skip-filecheck
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
// This attempts to modify `x.1` via a pointer derived from `addr_of_mut!(x.0)`.
|
||||
// According to Miri, that is UB. However, T-opsem has not finalized that
|
||||
@ -10,11 +9,17 @@
|
||||
// unit-test: DataflowConstProp
|
||||
|
||||
// EMIT_MIR sibling_ptr.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// CHECK: debug x1 => [[x1:_.*]];
|
||||
|
||||
let mut x: (u8, u8) = (0, 0);
|
||||
unsafe {
|
||||
let p = std::ptr::addr_of_mut!(x.0);
|
||||
*p.add(1) = 1;
|
||||
}
|
||||
|
||||
// CHECK: [[x1]] = ({{_.*}}.1: u8);
|
||||
let x1 = x.1; // should not be propagated
|
||||
}
|
||||
|
@ -1,13 +1,34 @@
|
||||
// skip-filecheck
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
// unit-test: DataflowConstProp
|
||||
// compile-flags: -Zmir-enable-passes=+InstSimplify
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
|
||||
// EMIT_MIR slice_len.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// CHECK: debug local => [[local:_.*]];
|
||||
// CHECK: debug constant => [[constant:_.*]];
|
||||
|
||||
// CHECK-NOT: {{_.*}} = Len(
|
||||
// CHECK-NOT: {{_.*}} = Lt(
|
||||
// CHECK-NOT: assert(move _
|
||||
// CHECK: {{_.*}} = const 3_usize;
|
||||
// CHECK: {{_.*}} = const true;
|
||||
// CHECK: assert(const true,
|
||||
|
||||
// CHECK: [[local]] = (*{{_.*}})[1 of 2];
|
||||
let local = (&[1u32, 2, 3] as &[u32])[1];
|
||||
|
||||
// CHECK-NOT: {{_.*}} = Len(
|
||||
// CHECK-NOT: {{_.*}} = Lt(
|
||||
// CHECK-NOT: assert(move _
|
||||
const SLICE: &[u32] = &[1, 2, 3];
|
||||
// CHECK: {{_.*}} = const 3_usize;
|
||||
// CHECK: {{_.*}} = const true;
|
||||
// CHECK: assert(const true,
|
||||
|
||||
// CHECK-NOT: [[constant]] = (*{{_.*}})[_
|
||||
// CHECK: [[constant]] = (*{{_.*}})[1 of 2];
|
||||
let constant = SLICE[1];
|
||||
}
|
||||
|
@ -37,16 +37,16 @@
|
||||
let _8: std::option::Option<S>;
|
||||
let _9: &[f32];
|
||||
scope 4 {
|
||||
debug a => _7;
|
||||
debug b => _8;
|
||||
debug c => _9;
|
||||
debug a1 => _7;
|
||||
debug b1 => _8;
|
||||
debug c1 => _9;
|
||||
let _11: f32;
|
||||
let _12: std::option::Option<S>;
|
||||
let _13: &[f32];
|
||||
scope 5 {
|
||||
debug a => _11;
|
||||
debug b => _12;
|
||||
debug c => _13;
|
||||
debug a2 => _11;
|
||||
debug b2 => _12;
|
||||
debug c2 => _13;
|
||||
let _15: SmallStruct;
|
||||
scope 6 {
|
||||
debug ss => _15;
|
||||
@ -54,16 +54,16 @@
|
||||
let _20: std::option::Option<S>;
|
||||
let _21: &[f32];
|
||||
scope 7 {
|
||||
debug a => _19;
|
||||
debug b => _20;
|
||||
debug c => _21;
|
||||
debug a3 => _19;
|
||||
debug b3 => _20;
|
||||
debug c3 => _21;
|
||||
let _23: f32;
|
||||
let _24: std::option::Option<S>;
|
||||
let _25: &[f32];
|
||||
scope 8 {
|
||||
debug a => _23;
|
||||
debug b => _24;
|
||||
debug c => _25;
|
||||
debug a4 => _23;
|
||||
debug b4 => _24;
|
||||
debug c4 => _25;
|
||||
let _27: BigStruct;
|
||||
scope 9 {
|
||||
debug bs => _27;
|
||||
|
@ -37,16 +37,16 @@
|
||||
let _8: std::option::Option<S>;
|
||||
let _9: &[f32];
|
||||
scope 4 {
|
||||
debug a => _7;
|
||||
debug b => _8;
|
||||
debug c => _9;
|
||||
debug a1 => _7;
|
||||
debug b1 => _8;
|
||||
debug c1 => _9;
|
||||
let _11: f32;
|
||||
let _12: std::option::Option<S>;
|
||||
let _13: &[f32];
|
||||
scope 5 {
|
||||
debug a => _11;
|
||||
debug b => _12;
|
||||
debug c => _13;
|
||||
debug a2 => _11;
|
||||
debug b2 => _12;
|
||||
debug c2 => _13;
|
||||
let _15: SmallStruct;
|
||||
scope 6 {
|
||||
debug ss => _15;
|
||||
@ -54,16 +54,16 @@
|
||||
let _20: std::option::Option<S>;
|
||||
let _21: &[f32];
|
||||
scope 7 {
|
||||
debug a => _19;
|
||||
debug b => _20;
|
||||
debug c => _21;
|
||||
debug a3 => _19;
|
||||
debug b3 => _20;
|
||||
debug c3 => _21;
|
||||
let _23: f32;
|
||||
let _24: std::option::Option<S>;
|
||||
let _25: &[f32];
|
||||
scope 8 {
|
||||
debug a => _23;
|
||||
debug b => _24;
|
||||
debug c => _25;
|
||||
debug a4 => _23;
|
||||
debug b4 => _24;
|
||||
debug c4 => _25;
|
||||
let _27: BigStruct;
|
||||
scope 9 {
|
||||
debug bs => _27;
|
||||
|
@ -1,4 +1,3 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
|
||||
@ -12,27 +11,69 @@ struct SmallStruct(f32, Option<S>, &'static [f32]);
|
||||
struct BigStruct(f32, Option<S>, &'static [f32]);
|
||||
|
||||
// EMIT_MIR struct.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// CHECK: debug s => [[s:_.*]];
|
||||
// CHECK: debug a => [[a:_.*]];
|
||||
// CHECK: debug b => [[b:_.*]];
|
||||
// CHECK: debug a1 => [[a1:_.*]];
|
||||
// CHECK: debug b1 => [[b1:_.*]];
|
||||
// CHECK: debug c1 => [[c1:_.*]];
|
||||
// CHECK: debug a2 => [[a2:_.*]];
|
||||
// CHECK: debug b2 => [[b2:_.*]];
|
||||
// CHECK: debug c2 => [[c2:_.*]];
|
||||
// CHECK: debug ss => [[ss:_.*]];
|
||||
// CHECK: debug a3 => [[a3:_.*]];
|
||||
// CHECK: debug b3 => [[b3:_.*]];
|
||||
// CHECK: debug c3 => [[c3:_.*]];
|
||||
// CHECK: debug a4 => [[a4:_.*]];
|
||||
// CHECK: debug b4 => [[b4:_.*]];
|
||||
// CHECK: debug c4 => [[c4:_.*]];
|
||||
// CHECK: debug bs => [[bs:_.*]];
|
||||
|
||||
// CHECK: [[s]] = const S(1_i32);
|
||||
let mut s = S(1);
|
||||
|
||||
// CHECK: [[a]] = const 3_i32;
|
||||
let a = s.0 + 2;
|
||||
s.0 = 3;
|
||||
|
||||
// CHECK: [[b]] = const 6_i32;
|
||||
let b = a + s.0;
|
||||
|
||||
const SMALL_VAL: SmallStruct = SmallStruct(4., Some(S(1)), &[]);
|
||||
let SmallStruct(a, b, c) = SMALL_VAL;
|
||||
|
||||
// CHECK: [[a1]] = const 4f32;
|
||||
// CHECK: [[b1]] = const Option::<S>::Some(S(1_i32));
|
||||
// CHECK: [[c1]] = ({{_.*}}.2: &[f32]);
|
||||
let SmallStruct(a1, b1, c1) = SMALL_VAL;
|
||||
|
||||
static SMALL_STAT: &SmallStruct = &SmallStruct(9., None, &[13.]);
|
||||
let SmallStruct(a, b, c) = *SMALL_STAT;
|
||||
|
||||
let ss = SmallStruct(a, b, c);
|
||||
// CHECK: [[a2]] = const 9f32;
|
||||
// CHECK: [[b2]] = ((*{{_.*}}).1: std::option::Option<S>);
|
||||
// CHECK: [[c2]] = ((*{{_.*}}).2: &[f32]);
|
||||
let SmallStruct(a2, b2, c2) = *SMALL_STAT;
|
||||
|
||||
// CHECK: [[ss]] = SmallStruct(const 9f32, move {{_.*}}, move {{_.*}});
|
||||
let ss = SmallStruct(a2, b2, c2);
|
||||
|
||||
const BIG_VAL: BigStruct = BigStruct(25., None, &[]);
|
||||
let BigStruct(a, b, c) = BIG_VAL;
|
||||
|
||||
// CHECK: [[a3]] = const 25f32;
|
||||
// CHECK: [[b3]] = ({{_.*}}.1: std::option::Option<S>);
|
||||
// CHECK: [[c3]] = ({{_.*}}.2: &[f32]);
|
||||
let BigStruct(a3, b3, c3) = BIG_VAL;
|
||||
|
||||
static BIG_STAT: &BigStruct = &BigStruct(82., Some(S(35)), &[45., 72.]);
|
||||
let BigStruct(a, b, c) = *BIG_STAT;
|
||||
// CHECK: [[a4]] = const 82f32;
|
||||
// CHECK: [[b4]] = const Option::<S>::Some(S(35_i32));
|
||||
// CHECK: [[c4]] = ((*{{_.*}}).2: &[f32]);
|
||||
let BigStruct(a4, b4, c4) = *BIG_STAT;
|
||||
|
||||
// We arbitrarily limit the size of synthetized values to 4 pointers.
|
||||
// `BigStruct` can be read, but we will keep a MIR aggregate for this.
|
||||
let bs = BigStruct(a, b, c);
|
||||
// CHECK: [[bs]] = BigStruct(const 82f32, const Option::<S>::Some(S(35_i32)), move {{_.*}});
|
||||
let bs = BigStruct(a4, b4, c4);
|
||||
}
|
||||
|
@ -1,12 +1,14 @@
|
||||
// skip-filecheck
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
// unit-test: DataflowConstProp
|
||||
|
||||
fn foo(n: i32) {}
|
||||
|
||||
// EMIT_MIR terminator.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
let a = 1;
|
||||
// Checks that we propagate into terminators.
|
||||
// CHECK: {{_.*}} = foo(const 2_i32) -> [return: {{bb.*}}, unwind
|
||||
foo(a + 1);
|
||||
}
|
||||
|
@ -1,13 +1,27 @@
|
||||
// skip-filecheck
|
||||
// unit-test: DataflowConstProp
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
|
||||
// EMIT_MIR tuple.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// CHECK: debug a => [[a:_.*]];
|
||||
// CHECK: debug b => [[b:_.*]];
|
||||
// CHECK: debug c => [[c:_.*]];
|
||||
// CHECK: debug d => [[d:_.*]];
|
||||
|
||||
// CHECK: [[a]] = const (1_i32, 2_i32);
|
||||
let mut a = (1, 2);
|
||||
|
||||
// CHECK: [[b]] = const 6_i32;
|
||||
let b = a.0 + a.1 + 3;
|
||||
|
||||
// CHECK: [[a]] = const (2_i32, 3_i32);
|
||||
a = (2, 3);
|
||||
|
||||
// CHECK: [[c]] = const 11_i32;
|
||||
let c = a.0 + a.1 + b;
|
||||
|
||||
// CHECK: [[d]] = (const 6_i32, const (2_i32, 3_i32), const 11_i32);
|
||||
let d = (b, a, c);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user