Cranelift: fix regalloc2 integration bug wrt blockparam branch args. (#4042)
Previously, the block successor accumulation and the blockparam branch arg setup were decoupled. The lowering backend implicitly specified the order of successor edges via its `MachTerminator` enum on the last instruction in the block, while the `Lower` toplevel machine-independent driver set up blockparam branch args in the edge order seen in CLIF. In some cases, these orders did not match -- for example, when the conditional branch depended on an FP condition that was implemented by swapping taken/not-taken edges and inverting the condition code. This PR refactors the successor handling to be centralized in `Lower` rather than flow through the terminator `MachInst`, and adds a successor block and its blockparam args at the same time, ensuring the orders match.
This commit is contained in:
@@ -94,7 +94,7 @@ pub trait MachInst: Clone + Debug {
|
||||
|
||||
/// Is this a terminator (branch or ret)? If so, return its type
|
||||
/// (ret/uncond/cond) and target if applicable.
|
||||
fn is_term<'a>(&'a self) -> MachTerminator<'a>;
|
||||
fn is_term(&self) -> MachTerminator;
|
||||
|
||||
/// Returns true if the instruction is an epilogue placeholder.
|
||||
fn is_epilogue_placeholder(&self) -> bool;
|
||||
@@ -221,18 +221,22 @@ pub trait MachInstLabelUse: Clone + Copy + Debug + Eq {
|
||||
|
||||
/// Describes a block terminator (not call) in the vcode, when its branches
|
||||
/// have not yet been finalized (so a branch may have two targets).
|
||||
///
|
||||
/// Actual targets are not included: the single-source-of-truth for
|
||||
/// those is the VCode itself, which holds, for each block, successors
|
||||
/// and outgoing branch args per successor.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum MachTerminator<'a> {
|
||||
pub enum MachTerminator {
|
||||
/// Not a terminator.
|
||||
None,
|
||||
/// A return instruction.
|
||||
Ret,
|
||||
/// An unconditional branch to another block.
|
||||
Uncond(MachLabel),
|
||||
Uncond,
|
||||
/// A conditional branch to one of two other blocks.
|
||||
Cond(MachLabel, MachLabel),
|
||||
Cond,
|
||||
/// An indirect branch with known possible targets.
|
||||
Indirect(&'a [MachLabel]),
|
||||
Indirect,
|
||||
}
|
||||
|
||||
/// A trait describing the ability to encode a MachInst into binary machine code.
|
||||
|
||||
Reference in New Issue
Block a user