When splitting a const, insert prior to the terminal branch group. (#1325)
* When splitting a const, insert prior to the terminal branch group. Closes #1159 Given code like the following, on x86_64, which does not have i128 registers: ebb0(v0: i64): v1 = iconst.i128 0 v2 = icmp_imm eq v0, 1 brnz v2, ebb1 jump ebb2(v1) It would be split to: ebb0(v0: i64): v1 = iconst.i128 0 v2 = icmp_imm eq v0, 1 brnz v2, ebb1 v3, v4 = isplit.i128 v1 jump ebb2(v3, v4) But that fails basic-block invariants. This patch changes that to: ebb0(v0: i64): v1 = iconst.i128 0 v2 = icmp_imm eq v0, 1 v3, v4 = isplit.i128 v1 brnz v2, ebb1 jump ebb2(v3, v4) * Add isplit-bb.clif testcase
This commit is contained in:
committed by
Benjamin Bouvier
parent
d6134a6f3a
commit
b4c6bfd371
@@ -189,6 +189,17 @@ fn perform_repairs(pos: &mut FuncCursor, cfg: &ControlFlowGraph, mut repairs: Ve
|
||||
|
||||
// Split the old argument, possibly causing more repairs to be scheduled.
|
||||
pos.goto_inst(inst);
|
||||
#[cfg(feature = "basic-blocks")]
|
||||
{
|
||||
let inst_ebb = pos.func.layout.inst_ebb(inst).expect("inst in ebb");
|
||||
|
||||
// Insert split values prior to the terminal branch group.
|
||||
let dfg = &pos.func.dfg;
|
||||
let canonical = pos.func.layout.canonical_branch_inst(dfg, inst_ebb);
|
||||
if let Some(first_branch) = canonical {
|
||||
pos.goto_inst(first_branch);
|
||||
}
|
||||
}
|
||||
let (lo, hi) = split_value(pos, old_arg, repair.concat, &mut repairs);
|
||||
|
||||
// The `lo` part replaces the original argument.
|
||||
@@ -248,8 +259,8 @@ fn split_value(
|
||||
}
|
||||
}
|
||||
ValueDef::Param(ebb, num) => {
|
||||
// This is an EBB parameter. We can split the parameter value unless this is the entry
|
||||
// block.
|
||||
// This is an EBB parameter.
|
||||
// We can split the parameter value unless this is the entry block.
|
||||
if pos.func.layout.entry_block() != Some(ebb) {
|
||||
reuse = Some(split_ebb_param(pos, ebb, num, value, concat, repairs));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user