diff --git a/cranelift/codegen/meta/src/shared/legalize.rs b/cranelift/codegen/meta/src/shared/legalize.rs index 1b37f9661b..23420009f6 100644 --- a/cranelift/codegen/meta/src/shared/legalize.rs +++ b/cranelift/codegen/meta/src/shared/legalize.rs @@ -61,6 +61,7 @@ pub(crate) fn define(insts: &InstructionGroup, imm: &Immediates) -> TransformGro let cls = insts.by_name("cls"); let clz = insts.by_name("clz"); let ctz = insts.by_name("ctz"); + let copy = insts.by_name("copy"); let fabs = insts.by_name("fabs"); let f32const = insts.by_name("f32const"); let f64const = insts.by_name("f64const"); @@ -629,6 +630,14 @@ pub(crate) fn define(insts: &InstructionGroup, imm: &Immediates) -> TransformGro ); } + for &(ty_half, ty) in &[(I64, I128), (I32, I64)] { + let inst = ireduce.bind(ty_half).bind(ty); + expand.legalize( + def!(a = inst(x)), + vec![def!((b, c) = isplit(x)), def!(a = copy(b))], + ); + } + // Expand integer operations with carry for RISC architectures that don't have // the flags. let intcc_ult = Literal::enumerator_for(&imm.intcc, "ult"); diff --git a/cranelift/filetests/filetests/isa/x86/legalize-ireduce-i128.clif b/cranelift/filetests/filetests/isa/x86/legalize-ireduce-i128.clif new file mode 100644 index 0000000000..4dd275ccc9 --- /dev/null +++ b/cranelift/filetests/filetests/isa/x86/legalize-ireduce-i128.clif @@ -0,0 +1,11 @@ +test compile +target x86_64 + +function u0:0(i64, i64) -> i64 { +block0(v0: i64, v1: i64): + v2 = iconcat v0, v1 + v3 = ireduce.i64 v2 + ; check: v3 = copy v0 + ; check: return v3 + return v3 +} diff --git a/cranelift/filetests/filetests/isa/x86/legalize-ireduce-i64.clif b/cranelift/filetests/filetests/isa/x86/legalize-ireduce-i64.clif new file mode 100644 index 0000000000..44c211709a --- /dev/null +++ b/cranelift/filetests/filetests/isa/x86/legalize-ireduce-i64.clif @@ -0,0 +1,11 @@ +test compile +target i686 + +function u0:0(i32, i32) -> i32 { +block0(v0: i32, v1: i32): + v2 = iconcat v0, v1 + v3 = ireduce.i32 v2 + ; check: v3 = fill v0 + ; check: return v3 + return v3 +}