diff --git a/cranelift/codegen/meta/src/cdsl/type_inference.rs b/cranelift/codegen/meta/src/cdsl/type_inference.rs index 9852dd1e7b..0313345175 100644 --- a/cranelift/codegen/meta/src/cdsl/type_inference.rs +++ b/cranelift/codegen/meta/src/cdsl/type_inference.rs @@ -161,8 +161,16 @@ impl TypeEnvironment { // Check extra conditions for InTypeset constraints. if let Constraint::InTypeset(tv, _) = &constraint { - assert!(tv.base.is_none()); - assert!(tv.name.starts_with("typeof_")); + assert!( + tv.base.is_none(), + "type variable is {:?}, while expecting none", + tv + ); + assert!( + tv.name.starts_with("typeof_"), + "Name \"{}\" should start with \"typeof_\"", + tv.name + ); } self.constraints.push(constraint); diff --git a/cranelift/codegen/meta/src/shared/legalize.rs b/cranelift/codegen/meta/src/shared/legalize.rs index 2f20e5a613..7c7b121ab4 100644 --- a/cranelift/codegen/meta/src/shared/legalize.rs +++ b/cranelift/codegen/meta/src/shared/legalize.rs @@ -207,6 +207,28 @@ pub(crate) fn define(insts: &InstructionGroup, imm: &Immediates) -> TransformGro // embedded as part of arguments), so use a custom legalization for now. narrow.custom_legalize(iconst, "narrow_iconst"); + { + let inst = uextend.bind(I128).bind(I64); + narrow.legalize( + def!(a = inst(x)), + vec![ + def!(ah = iconst(Literal::constant(&imm.imm64, 0))), + def!(a = iconcat(x, ah)), + ], + ); + } + + { + let inst = sextend.bind(I128).bind(I64); + narrow.legalize( + def!(a = inst(x)), + vec![ + def!(ah = sshr_imm(x, Literal::constant(&imm.imm64, 63))), // splat sign bit to whole number + def!(a = iconcat(x, ah)), + ], + ); + } + for &bin_op in &[band, bor, bxor, band_not, bor_not, bxor_not] { narrow.legalize( def!(a = bin_op(x, y)), diff --git a/cranelift/filetests/filetests/isa/x86/extend-i128-run.clif b/cranelift/filetests/filetests/isa/x86/extend-i128-run.clif new file mode 100644 index 0000000000..c2550b8f4e --- /dev/null +++ b/cranelift/filetests/filetests/isa/x86/extend-i128-run.clif @@ -0,0 +1,26 @@ +test run +target x86_64 + +function u0:0() -> b1 { +ebb0: + v0 = iconst.i64 0xffff_ffff_eeee_0000 + v1 = uextend.i128 v0 + v2, v3 = isplit v1 + v4 = icmp_imm eq v2, 0xffff_ffff_eeee_0000 + v5 = icmp_imm eq v3, 0 + v6 = band v4, v5 + return v6 +} +; run + +function u0:1() -> b1 { +ebb0: + v0 = iconst.i64 0xffff_ffff_eeee_0000 + v1 = sextend.i128 v0 + v2, v3 = isplit v1 + v4 = icmp_imm eq v2, 0xffff_ffff_eeee_0000 + v5 = icmp_imm eq v3, 0xffff_ffff_ffff_ffff + v6 = band v4, v5 + return v6 +} +; run diff --git a/cranelift/filetests/filetests/isa/x86/extend-i128.clif b/cranelift/filetests/filetests/isa/x86/extend-i128.clif new file mode 100644 index 0000000000..0d9e4c8aa9 --- /dev/null +++ b/cranelift/filetests/filetests/isa/x86/extend-i128.clif @@ -0,0 +1,37 @@ +test compile +target x86_64 + +function u0:0() -> b1 { +ebb0: + v0 = iconst.i64 0xffff_ffff_eeee_0000 + ; check: v0 = iconst.i64 0xffff_ffff_eeee_0000 + ; nextln: v2 -> v0 + v1 = uextend.i128 v0 + ; nextln: v7 = iconst.i64 0 + ; nextln: v3 -> v7 + ; nextln: v1 = iconcat v0, v7 + + v2, v3 = isplit v1 + v4 = icmp_imm eq v2, 0xffff_ffff_eeee_0000 + v5 = icmp_imm eq v3, 0 + + v6 = band v4, v5 + return v6 +} + +function u0:1() -> b1 { +ebb0: + v0 = iconst.i64 0xffff_ffff_eeee_0000 + ; check: v0 = iconst.i64 0xffff_ffff_eeee_0000 + ; nextln: v2 -> v0 + v1 = sextend.i128 v0 + ; nextln: v8 = copy v0 + ; nextln: v7 = sshr_imm v8, 63 + ; nextln: v3 -> v7 + + v2, v3 = isplit v1 + v4 = icmp_imm eq v2, 0xffff_ffff_eeee_0000 + v5 = icmp_imm eq v3, 0xffff_ffff_ffff_ffff + v6 = band v4, v5 + return v6 +} diff --git a/cranelift/filetests/filetests/legalizer/popcnt-i128.clif b/cranelift/filetests/filetests/legalizer/popcnt-i128.clif index b241c640a9..0ecf7f74c5 100644 --- a/cranelift/filetests/filetests/legalizer/popcnt-i128.clif +++ b/cranelift/filetests/filetests/legalizer/popcnt-i128.clif @@ -24,8 +24,8 @@ ebb0: ; check: v16, v17 = iadd_ifcout v12, v14 ; check: v18 = iadd_ifcin v13, v15, v17 ; check: v11 = iconcat v16, v18 -; check: v4 = uextend.i128 v11 -; check: v19, v20 = isplit v4 -; check: v21, v22 = isplit v19 -; check: v23, v24 = isplit v20 -; check: return v21, v22, v23, v24 +; check: v20 = iconst.i32 0 +; check: v21 = iconst.i32 0 +; check: v19 = iconcat v20, v21 +; check: v4 = iconcat v11, v19 +; check: return v16, v18, v20, v21