Switch ifcmp+brif folding to be icmp+brz folding, which is what frontends actually produce.

This commit is contained in:
Tyler McMullen
2019-01-02 20:01:52 -08:00
committed by Benjamin Bouvier
parent 67cc5aafec
commit 571b87414f
2 changed files with 56 additions and 20 deletions

View File

@@ -556,9 +556,8 @@ enum BranchOptKind {
fn branch_opt(pos: &mut FuncCursor, inst: Inst) { fn branch_opt(pos: &mut FuncCursor, inst: Inst) {
let info = match pos.func.dfg[inst] { let info = match pos.func.dfg[inst] {
InstructionData::BranchInt { InstructionData::Branch {
opcode: Opcode::Brif, opcode,
cond: br_cond,
destination, destination,
ref args, ref args,
} => { } => {
@@ -566,6 +565,7 @@ fn branch_opt(pos: &mut FuncCursor, inst: Inst) {
let args = pos.func.dfg.inst_args(inst); let args = pos.func.dfg.inst_args(inst);
args[0] args[0]
}; };
let iconst_inst = let iconst_inst =
if let ValueDef::Result(iconst_inst, _) = pos.func.dfg.value_def(first_arg) { if let ValueDef::Result(iconst_inst, _) = pos.func.dfg.value_def(first_arg) {
iconst_inst iconst_inst
@@ -573,10 +573,11 @@ fn branch_opt(pos: &mut FuncCursor, inst: Inst) {
return; return;
}; };
if let InstructionData::BinaryImm { if let InstructionData::IntCompareImm {
opcode: Opcode::IfcmpImm, opcode: Opcode::IcmpImm,
imm: cmp_imm,
arg: cmp_arg, arg: cmp_arg,
cond: cmp_cond,
imm: cmp_imm,
} = pos.func.dfg[iconst_inst] } = pos.func.dfg[iconst_inst]
{ {
let cmp_imm: i64 = cmp_imm.into(); let cmp_imm: i64 = cmp_imm.into();
@@ -584,9 +585,17 @@ fn branch_opt(pos: &mut FuncCursor, inst: Inst) {
return; return;
} }
let kind = match br_cond { // icmp_imm returns non-zero when the comparison is true. So, if
IntCC::NotEqual => BranchOptKind::NotEqualZero, // we're branching on zero, we need to invert the condition.
let cond = match opcode {
Opcode::Brz => cmp_cond.inverse(),
Opcode::Brnz => cmp_cond,
_ => return,
};
let kind = match cond {
IntCC::Equal => BranchOptKind::EqualZero, IntCC::Equal => BranchOptKind::EqualZero,
IntCC::NotEqual => BranchOptKind::NotEqualZero,
_ => return, _ => return,
}; };

View File

@@ -1,31 +1,58 @@
test simple_preopt test simple_preopt
target x86_64 target x86_64
function %brif_to_brz_fold(i32) -> i32 { function %icmp_to_brz_fold(i32) -> i32 {
ebb0(v0: i32): ebb0(v0: i32):
v1 = ifcmp_imm v0, 0 v1 = icmp_imm eq v0, 0
brif eq v1, ebb1 brnz v1, ebb1
jump ebb2 jump ebb2
ebb1: ebb1:
v2 = iconst.i32 1 v3 = iconst.i32 1
return v2
ebb2:
v3 = iconst.i32 2
return v3 return v3
ebb2:
v4 = iconst.i32 2
return v4
} }
; sameln: function %brif_to_brz_fold ; sameln: function %icmp_to_brz_fold
; nextln: ebb0(v0: i32): ; nextln: ebb0(v0: i32):
; nextln: v1 = ifcmp_imm v0, 0 ; nextln: v1 = icmp_imm eq v0, 0
; nextln: brnz v0, ebb2 ; nextln: brnz v0, ebb2
; nextln: fallthrough ebb1 ; nextln: fallthrough ebb1
; nextln: ; nextln:
; nextln: ebb1: ; nextln: ebb1:
; nextln: v2 = iconst.i32 1 ; nextln: v3 = iconst.i32 1
; nextln: return v2 ; nextln: return v3
; nextln: ; nextln:
; nextln: ebb2: ; nextln: ebb2:
; nextln: v3 = iconst.i32 2 ; nextln: v4 = iconst.i32 2
; nextln: return v4
; nextln: }
function %icmp_to_brz_inverted_fold(i32) -> i32 {
ebb0(v0: i32):
v1 = icmp_imm ne v0, 0
brz v1, ebb1
jump ebb2
ebb1:
v3 = iconst.i32 1
return v3
ebb2:
v4 = iconst.i32 2
return v4
}
; sameln: function %icmp_to_brz_inve
; nextln: ebb0(v0: i32):
; nextln: v1 = icmp_imm ne v0, 0
; nextln: brnz v0, ebb2
; nextln: fallthrough ebb1
; nextln:
; nextln: ebb1:
; nextln: v3 = iconst.i32 1
; nextln: return v3 ; nextln: return v3
; nextln:
; nextln: ebb2:
; nextln: v4 = iconst.i32 2
; nextln: return v4
; nextln: } ; nextln: }
function %brif_inversion(i32) -> i32 { function %brif_inversion(i32) -> i32 {