From 5e96a447f032f635237842e06f50c35193dbe6c2 Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Mon, 1 Nov 2021 13:34:31 -0700 Subject: [PATCH] Add back the `ifcmp_sp` CLIF opcode. This opcode was removed as part of the old-backend cleanup in #3446. While this opcode will definitely go away eventually, it is unfortunately still used today in Lucet (as we just discovered while working to upgrade Lucet's pinned Cranelift version). Lucet is deprecated and slated to eventually be completely sunset in favor of Wasmtime; but until that happens, we need to keep this opcode. --- .../codegen/meta/src/shared/instructions.rs | 15 +++++++++ .../codegen/src/isa/aarch64/lower_inst.rs | 2 +- cranelift/codegen/src/isa/s390x/lower.rs | 4 +++ cranelift/codegen/src/isa/x64/lower.rs | 19 +++++++++++- .../filetests/filetests/isa/x64/ifcmp-sp.clif | 31 +++++++++++++++++++ cranelift/interpreter/src/step.rs | 1 + 6 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 cranelift/filetests/filetests/isa/x64/ifcmp-sp.clif diff --git a/cranelift/codegen/meta/src/shared/instructions.rs b/cranelift/codegen/meta/src/shared/instructions.rs index 4923276aea..8b693c370b 100644 --- a/cranelift/codegen/meta/src/shared/instructions.rs +++ b/cranelift/codegen/meta/src/shared/instructions.rs @@ -1797,6 +1797,21 @@ pub(crate) fn define( .operands_out(vec![a]), ); + ig.push( + Inst::new( + "ifcmp_sp", + r#" + Compare ``addr`` with the stack pointer and set the CPU flags. + + This is like `ifcmp` where ``addr`` is the LHS operand and the stack + pointer is the RHS. + "#, + &formats.unary, + ) + .operands_in(vec![addr]) + .operands_out(vec![flags]), + ); + let x = &Operand::new("x", TxN).with_doc("Vector to split"); let lo = &Operand::new("lo", &TxN.half_vector()).with_doc("Low-numbered lanes of `x`"); let hi = &Operand::new("hi", &TxN.half_vector()).with_doc("High-numbered lanes of `x`"); diff --git a/cranelift/codegen/src/isa/aarch64/lower_inst.rs b/cranelift/codegen/src/isa/aarch64/lower_inst.rs index 8fa9115d79..5b898ef835 100644 --- a/cranelift/codegen/src/isa/aarch64/lower_inst.rs +++ b/cranelift/codegen/src/isa/aarch64/lower_inst.rs @@ -3744,7 +3744,7 @@ pub(crate) fn lower_insn_to_regs>( }); } - Opcode::ConstAddr | Opcode::Vconcat | Opcode::Vsplit => { + Opcode::ConstAddr | Opcode::Vconcat | Opcode::Vsplit | Opcode::IfcmpSp => { return Err(CodegenError::Unsupported(format!( "Unimplemented lowering: {}", op diff --git a/cranelift/codegen/src/isa/s390x/lower.rs b/cranelift/codegen/src/isa/s390x/lower.rs index fe96631ccb..b7a1336871 100644 --- a/cranelift/codegen/src/isa/s390x/lower.rs +++ b/cranelift/codegen/src/isa/s390x/lower.rs @@ -2888,6 +2888,10 @@ fn lower_insn_to_regs>( Opcode::Isplit | Opcode::Iconcat => unimplemented!("Wide integer ops not implemented."), + Opcode::IfcmpSp => { + panic!("Unused opcode should not be encountered."); + } + Opcode::Ifcmp | Opcode::Ffcmp | Opcode::Trapff diff --git a/cranelift/codegen/src/isa/x64/lower.rs b/cranelift/codegen/src/isa/x64/lower.rs index eb7711480c..c67dab3dde 100644 --- a/cranelift/codegen/src/isa/x64/lower.rs +++ b/cranelift/codegen/src/isa/x64/lower.rs @@ -6860,7 +6860,7 @@ fn lower_insn_to_regs>( panic!("table_addr should have been removed by legalization!"); } - Opcode::Copy => { + Opcode::IfcmpSp | Opcode::Copy => { panic!("Unused opcode should not be encountered."); } @@ -7075,6 +7075,23 @@ impl LowerBackend for X64Backend { let cond_code = emit_cmp(ctx, ifcmp, cond_code); let cc = CC::from_intcc(cond_code); ctx.emit(Inst::jmp_cond(cc, taken, not_taken)); + } else if let Some(ifcmp_sp) = matches_input(ctx, flag_input, Opcode::IfcmpSp) { + let operand = put_input_in_reg( + ctx, + InsnInput { + insn: ifcmp_sp, + input: 0, + }, + ); + let ty = ctx.input_ty(ifcmp_sp, 0); + ctx.emit(Inst::cmp_rmi_r( + OperandSize::from_ty(ty), + RegMemImm::reg(regs::rsp()), + operand, + )); + let cond_code = ctx.data(branches[0]).cond_code().unwrap(); + let cc = CC::from_intcc(cond_code); + ctx.emit(Inst::jmp_cond(cc, taken, not_taken)); } else { // Should be disallowed by flags checks in verifier. unimplemented!("Brif with non-ifcmp input"); diff --git a/cranelift/filetests/filetests/isa/x64/ifcmp-sp.clif b/cranelift/filetests/filetests/isa/x64/ifcmp-sp.clif new file mode 100644 index 0000000000..ee43f9c372 --- /dev/null +++ b/cranelift/filetests/filetests/isa/x64/ifcmp-sp.clif @@ -0,0 +1,31 @@ +test compile +target x86_64 + +function %f(i64) -> i32 { +block0(v0: i64): + v1 = ifcmp_sp v0 + brif ugt v1, block1 + jump block2 + +block1: + v2 = iconst.i32 0 + return v2 + +block2: + v3 = iconst.i32 1 + return v3 +} + +; check: pushq %rbp +; nextln: movq %rsp, %rbp +; nextln: cmpq %rsp, %rdi +; nextln: jnbe label1; j label2 +; check: xorl %eax, %eax +; nextln: movq %rbp, %rsp +; nextln: popq %rbp +; nextln: ret +; check: movl $$1, %eax +; nextln: movq %rbp, %rsp +; nextln: popq %rbp +; nextln: ret + diff --git a/cranelift/interpreter/src/step.rs b/cranelift/interpreter/src/step.rs index 5764974bc1..01f41279e7 100644 --- a/cranelift/interpreter/src/step.rs +++ b/cranelift/interpreter/src/step.rs @@ -448,6 +448,7 @@ where assign(Value::or(mask_a, mask_b)?) } Opcode::Copy => assign(arg(0)?), + Opcode::IfcmpSp => unimplemented!("IfcmpSp"), Opcode::Icmp => assign(icmp( ctrl_ty, inst.cond_code().unwrap(),