riscv64: Implement fcmp in ISLE (#5512)

Rework the compilation of fcmp in the riscv64 backend to be in ISLE, removing the need for the dedicated Fcmp instruction. This change is motivated by #5500, which showed that the riscv64 backend was generating branch instructions in the middle of a basic block.

We can't remove lower_br_fcmp quite yet as it's used in a few places in the emit module, but it's now no longer reachable from the ISLE lowerings.

Fixes #5500
This commit is contained in:
Trevor Elliott
2023-01-04 11:52:00 -08:00
committed by GitHub
parent d1920f5a2d
commit b2d5afdf83
7 changed files with 202 additions and 113 deletions

View File

@@ -1337,42 +1337,6 @@ impl MachInstEmit for Inst {
}
}
&Inst::Fcmp {
rd,
cc,
ty,
rs1,
rs2,
} => {
let rs1 = allocs.next(rs1);
let rs2 = allocs.next(rs2);
let rd = allocs.next_writable(rd);
let label_true = sink.get_label();
let label_jump_over = sink.get_label();
Inst::lower_br_fcmp(
cc,
rs1,
rs2,
BranchTarget::Label(label_true),
BranchTarget::zero(),
ty,
rd,
)
.iter()
.for_each(|i| i.emit(&[], sink, emit_info, state));
// here is not taken.
Inst::load_imm12(rd, Imm12::FALSE).emit(&[], sink, emit_info, state);
// jump over.
Inst::Jal {
dest: BranchTarget::Label(label_jump_over),
}
.emit(&[], sink, emit_info, state);
// here is true
sink.bind_label(label_true);
Inst::load_imm12(rd, Imm12::TRUE).emit(&[], sink, emit_info, state);
sink.bind_label(label_jump_over);
}
&Inst::Select {
ref dst,
condition,

View File

@@ -2177,14 +2177,6 @@ fn riscv64_worst_case_instruction_size() {
//there are all candidates potential generate a lot of bytes.
let mut candidates: Vec<MInst> = vec![];
candidates.push(Inst::Fcmp {
rd: writable_a0(),
cc: FloatCC::UnorderedOrLessThanOrEqual,
ty: F64,
rs1: fa1(),
rs2: fa0(),
});
candidates.push(Inst::IntSelect {
dst: vec![writable_a0(), writable_a0()],
ty: I128,

View File

@@ -460,11 +460,6 @@ fn riscv64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut Operan
collector.reg_use(src);
collector.reg_def(rd);
}
&Inst::Fcmp { rd, rs1, rs2, .. } => {
collector.reg_use(rs1);
collector.reg_use(rs2);
collector.reg_early_def(rd);
}
&Inst::Select {
ref dst,
condition,
@@ -1366,25 +1361,6 @@ impl Inst {
let rd = format_reg(rd.to_reg(), allocs);
format!("{} {},{}", op.op_name(), rd, base,)
}
&Inst::Fcmp {
rd,
cc,
ty,
rs1,
rs2,
} => {
let rs1 = format_reg(rs1, allocs);
let rs2 = format_reg(rs2, allocs);
let rd = format_reg(rd.to_reg(), allocs);
format!(
"f{}.{} {},{},{}",
cc,
if ty == F32 { "s" } else { "d" },
rd,
rs1,
rs2,
)
}
&Inst::Store {
to,
src,