Skip to content

Can MIR have irreducible control flow? #114047

Open
@RalfJung

Description

@RalfJung

All Rust programs have reducible control flow -- except if we write them with custom MIR:

#![feature(custom_mir, core_intrinsics)]
extern crate core;
use core::intrinsics::mir::*;

#[custom_mir(dialect = "built")]
pub fn irreducible(x: bool) { mir! (
    // start block jumps to one of two different blocks inside the below loop
    {
        match x {
            true => bb1,
            _ => bb2
        }
    }

    // bb1, bb2 form a loop
    bb1 = {
        Goto(bb2)
    }
    bb2 = {
        Goto(bb1)
    }
)}

Here is a more complicated example that doesn't get optimized away immediately:

#![feature(custom_mir, core_intrinsics)]
extern crate core;
use core::intrinsics::mir::*;

#[inline(never)]
pub fn black_box() -> i32 {
    std::hint::black_box(42)
}

#[custom_mir(dialect = "built")]
pub fn irreducible(x: bool) { mir! (
    let y: i32;
    // start block jumps to one of two different blocks inside the below loop
    {
        match x {
            true => bb1,
            _ => bb3
        }
    }

    // bb1, bb2, bb3, bb4 form a loop (with some early exit points)
    bb1 = {
        Call(y, bb2, black_box())
    }
    bb2 = {
        match y {
            1 => bb3,
            _ => ret
        }
    }
    
    bb3 = {
        Call(y, bb4, black_box())
    }
    bb4 = {
        match y {
            1 => bb1,
            _ => ret
        }
    }
    ret = {
        Return()
    }
)}

This should probably be rejected right after Custom MIR building? At least I assume later MIR passes can generally assume reducible control flow.

Thanks to @cbeuw for the examples.

Cc @JakobDegen

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions