cranelift: Remove redundant branch and select instructions (#5097)
As discussed in the 2022/10/19 meeting, this PR removes many of the branch and select instructions that used iflags, in favor if using brz/brnz and select in their place. Additionally, it reworks selectif_spectre_guard to take an i8 input instead of an iflags input. For reference, the removed instructions are: br_icmp, brif, brff, trueif, trueff, and selectif.
This commit is contained in:
@@ -75,82 +75,9 @@ fn define_control_flow(
|
||||
);
|
||||
}
|
||||
|
||||
let iB = &TypeVar::new(
|
||||
"iB",
|
||||
"A scalar integer type",
|
||||
TypeSetBuilder::new().ints(Interval::All).build(),
|
||||
);
|
||||
let iflags: &TypeVar = &ValueType::Special(types::Flag::IFlags.into()).into();
|
||||
let fflags: &TypeVar = &ValueType::Special(types::Flag::FFlags.into()).into();
|
||||
|
||||
{
|
||||
let Cond = &Operand::new("Cond", &imm.intcc);
|
||||
let x = &Operand::new("x", iB);
|
||||
let y = &Operand::new("y", iB);
|
||||
|
||||
ig.push(
|
||||
Inst::new(
|
||||
"br_icmp",
|
||||
r#"
|
||||
Compare scalar integers and branch.
|
||||
|
||||
Compare ``x`` and ``y`` in the same way as the `icmp` instruction
|
||||
and take the branch if the condition is true:
|
||||
|
||||
```text
|
||||
br_icmp ugt v1, v2, block4(v5, v6)
|
||||
```
|
||||
|
||||
is semantically equivalent to:
|
||||
|
||||
```text
|
||||
v10 = icmp ugt, v1, v2
|
||||
brnz v10, block4(v5, v6)
|
||||
```
|
||||
|
||||
Some RISC architectures like MIPS and RISC-V provide instructions that
|
||||
implement all or some of the condition codes. The instruction can also
|
||||
be used to represent *macro-op fusion* on architectures like Intel's.
|
||||
"#,
|
||||
&formats.branch_icmp,
|
||||
)
|
||||
.operands_in(vec![Cond, x, y, block, args])
|
||||
.is_branch(true),
|
||||
);
|
||||
|
||||
let f = &Operand::new("f", iflags);
|
||||
|
||||
ig.push(
|
||||
Inst::new(
|
||||
"brif",
|
||||
r#"
|
||||
Branch when condition is true in integer CPU flags.
|
||||
"#,
|
||||
&formats.branch_int,
|
||||
)
|
||||
.operands_in(vec![Cond, f, block, args])
|
||||
.is_branch(true),
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
let Cond = &Operand::new("Cond", &imm.floatcc);
|
||||
|
||||
let f = &Operand::new("f", fflags);
|
||||
|
||||
ig.push(
|
||||
Inst::new(
|
||||
"brff",
|
||||
r#"
|
||||
Branch when condition is true in floating point CPU flags.
|
||||
"#,
|
||||
&formats.branch_float,
|
||||
)
|
||||
.operands_in(vec![Cond, f, block, args])
|
||||
.is_branch(true),
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
let _i32 = &TypeVar::new(
|
||||
"i32",
|
||||
@@ -1498,28 +1425,13 @@ pub(crate) fn define(
|
||||
.operands_out(vec![a]),
|
||||
);
|
||||
|
||||
let cc = &Operand::new("cc", &imm.intcc).with_doc("Controlling condition code");
|
||||
let flags = &Operand::new("flags", iflags).with_doc("The machine's flag register");
|
||||
|
||||
ig.push(
|
||||
Inst::new(
|
||||
"selectif",
|
||||
r#"
|
||||
Conditional select, dependent on integer condition codes.
|
||||
"#,
|
||||
&formats.int_select,
|
||||
)
|
||||
.operands_in(vec![cc, flags, x, y])
|
||||
.operands_out(vec![a]),
|
||||
);
|
||||
|
||||
ig.push(
|
||||
Inst::new(
|
||||
"selectif_spectre_guard",
|
||||
"select_spectre_guard",
|
||||
r#"
|
||||
Conditional select intended for Spectre guards.
|
||||
|
||||
This operation is semantically equivalent to a selectif instruction.
|
||||
This operation is semantically equivalent to a select instruction.
|
||||
However, it is guaranteed to not be removed or otherwise altered by any
|
||||
optimization pass, and is guaranteed to result in a conditional-move
|
||||
instruction, not a branch-based lowering. As such, it is suitable
|
||||
@@ -1534,9 +1446,9 @@ pub(crate) fn define(
|
||||
speculative path, this ensures that no Spectre vulnerability will
|
||||
exist.
|
||||
"#,
|
||||
&formats.int_select,
|
||||
&formats.ternary,
|
||||
)
|
||||
.operands_in(vec![cc, flags, x, y])
|
||||
.operands_in(vec![c, x, y])
|
||||
.operands_out(vec![a])
|
||||
.other_side_effects(true),
|
||||
);
|
||||
@@ -3194,43 +3106,6 @@ pub(crate) fn define(
|
||||
.operands_out(vec![a]),
|
||||
);
|
||||
|
||||
let Cond = &Operand::new("Cond", &imm.intcc);
|
||||
let f = &Operand::new("f", iflags);
|
||||
let a = &Operand::new("a", i8);
|
||||
|
||||
ig.push(
|
||||
Inst::new(
|
||||
"trueif",
|
||||
r#"
|
||||
Test integer CPU flags for a specific condition.
|
||||
|
||||
Check the CPU flags in ``f`` against the ``Cond`` condition code and
|
||||
return true when the condition code is satisfied.
|
||||
"#,
|
||||
&formats.int_cond,
|
||||
)
|
||||
.operands_in(vec![Cond, f])
|
||||
.operands_out(vec![a]),
|
||||
);
|
||||
|
||||
let Cond = &Operand::new("Cond", &imm.floatcc);
|
||||
let f = &Operand::new("f", fflags);
|
||||
|
||||
ig.push(
|
||||
Inst::new(
|
||||
"trueff",
|
||||
r#"
|
||||
Test floating point CPU flags for a specific condition.
|
||||
|
||||
Check the CPU flags in ``f`` against the ``Cond`` condition code and
|
||||
return true when the condition code is satisfied.
|
||||
"#,
|
||||
&formats.float_cond,
|
||||
)
|
||||
.operands_in(vec![Cond, f])
|
||||
.operands_out(vec![a]),
|
||||
);
|
||||
|
||||
let x = &Operand::new("x", Mem);
|
||||
let a = &Operand::new("a", MemTo).with_doc("Bits of `x` reinterpreted");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user