diff --git a/cranelift/codegen/meta/src/gen_legalizer.rs b/cranelift/codegen/meta/src/gen_legalizer.rs index 67959b3c7c..344bad7472 100644 --- a/cranelift/codegen/meta/src/gen_legalizer.rs +++ b/cranelift/codegen/meta/src/gen_legalizer.rs @@ -415,6 +415,11 @@ fn gen_transform<'a>( fmt.line("let removed = pos.remove_inst();"); fmt.line("debug_assert_eq!(removed, inst);"); } + + if transform.def_pool.get(transform.src).apply.inst.is_branch { + fmt.line("cfg.recompute_ebb(pos.func, pos.current_ebb().unwrap());"); + } + fmt.line("return true;"); }); fmt.line("}"); diff --git a/cranelift/codegen/meta/src/shared/legalize.rs b/cranelift/codegen/meta/src/shared/legalize.rs index 90fe47d0fd..57ad9c89b8 100644 --- a/cranelift/codegen/meta/src/shared/legalize.rs +++ b/cranelift/codegen/meta/src/shared/legalize.rs @@ -4,7 +4,7 @@ use crate::cdsl::xform::{TransformGroupBuilder, TransformGroups}; use crate::shared::immediates::Immediates; use crate::shared::types::Float::{F32, F64}; -use crate::shared::types::Int::{I16, I32, I64, I8}; +use crate::shared::types::Int::{I16, I128, I32, I64, I8}; pub(crate) fn define(insts: &InstructionGroup, imm: &Immediates) -> TransformGroups { let mut narrow = TransformGroupBuilder::new( @@ -49,6 +49,8 @@ pub(crate) fn define(insts: &InstructionGroup, imm: &Immediates) -> TransformGro let bor = insts.by_name("bor"); let bor_imm = insts.by_name("bor_imm"); let bor_not = insts.by_name("bor_not"); + let brnz = insts.by_name("brnz"); + let brz = insts.by_name("brz"); let br_icmp = insts.by_name("br_icmp"); let br_table = insts.by_name("br_table"); let bxor = insts.by_name("bxor"); @@ -177,9 +179,11 @@ pub(crate) fn define(insts: &InstructionGroup, imm: &Immediates) -> TransformGro let al = var("al"); let ah = var("ah"); let cc = var("cc"); + let ebb = var("ebb"); let ptr = var("ptr"); let flags = var("flags"); let offset = var("off"); + let vararg = var("vararg"); narrow.legalize( def!(a = iadd(x, y)), @@ -227,6 +231,26 @@ pub(crate) fn define(insts: &InstructionGroup, imm: &Immediates) -> TransformGro ], ); + narrow.legalize( + def!(brz.I128(x, ebb, vararg)), + vec![ + def!((xl, xh) = isplit(x)), + def!(a = icmp_imm(Literal::enumerator_for(intcc, "eq"), xl, Literal::constant(imm64, 0))), + def!(b = icmp_imm(Literal::enumerator_for(intcc, "eq"), xh, Literal::constant(imm64, 0))), + def!(c = band(a, b)), + def!(brz(c, ebb, vararg)), + ], + ); + + narrow.legalize( + def!(brnz.I128(x, ebb, vararg)), + vec![ + def!((xl, xh) = isplit(x)), + def!(brnz(xl, ebb, vararg)), + def!(brnz(xh, ebb, vararg)), + ], + ); + // Widen instructions with one input operand. for &op in &[bnot, popcnt] { for &int_ty in &[I8, I16] { diff --git a/cranelift/filetests/filetests/isa/x86/br-i128.clif b/cranelift/filetests/filetests/isa/x86/br-i128.clif new file mode 100644 index 0000000000..a09db3f41b --- /dev/null +++ b/cranelift/filetests/filetests/isa/x86/br-i128.clif @@ -0,0 +1,24 @@ +test compile +target x86_64 + +function u0:0(i128) -> i8 fast { +ebb0(v0: i128): + brz v0, ebb1 + v1 = iconst.i8 0 + return v1 + +ebb1: + v2 = iconst.i8 1 + return v2 +} + +function u0:1(i128) -> i8 fast { +ebb0(v0: i128): + brnz v0, ebb1 + v1 = iconst.i8 0 + return v1 + +ebb1: + v2 = iconst.i8 1 + return v2 +}