diff --git a/cranelift/codegen/src/isle_prelude.rs b/cranelift/codegen/src/isle_prelude.rs index 6339f3efb35e..a9e5ba097c13 100644 --- a/cranelift/codegen/src/isle_prelude.rs +++ b/cranelift/codegen/src/isle_prelude.rs @@ -95,6 +95,11 @@ macro_rules! isle_common_prelude_methods { Some(x as u32 as i32 as i64 as u64) } + #[inline] + fn u64_uextend_u32(&mut self, x: u64) -> Option { + Some(x & 0xffff_ffff) + } + #[inline] fn ty_bits(&mut self, ty: Type) -> Option { use std::convert::TryInto; diff --git a/cranelift/codegen/src/opts/algebraic.isle b/cranelift/codegen/src/opts/algebraic.isle index 4669fc34918d..5611f40e0019 100644 --- a/cranelift/codegen/src/opts/algebraic.isle +++ b/cranelift/codegen/src/opts/algebraic.isle @@ -7,8 +7,8 @@ ;; can freely rewrite e.g. `x+y-y` to `x`. ;; uextend/sextend of a constant. -(rule (simplify (uextend $I64 (iconst $I32 imm))) - (iconst $I64 imm)) +(rule (simplify (uextend $I64 (iconst $I32 (u64_from_imm64 imm)))) + (iconst $I64 (imm64 (u64_uextend_u32 imm)))) (rule (simplify (sextend $I64 (iconst $I32 (u64_from_imm64 imm)))) (iconst $I64 (imm64 (u64_sextend_u32 imm)))) diff --git a/cranelift/codegen/src/prelude.isle b/cranelift/codegen/src/prelude.isle index de2be1588ce8..c2029c8f6837 100644 --- a/cranelift/codegen/src/prelude.isle +++ b/cranelift/codegen/src/prelude.isle @@ -125,6 +125,9 @@ (decl pure u64_sextend_u32 (u64) u64) (extern constructor u64_sextend_u32 u64_sextend_u32) +(decl pure u64_uextend_u32 (u64) u64) +(extern constructor u64_uextend_u32 u64_uextend_u32) + (decl u64_is_zero (bool) u64) (extern extractor infallible u64_is_zero u64_is_zero) diff --git a/cranelift/filetests/filetests/egraph/algebraic.clif b/cranelift/filetests/filetests/egraph/algebraic.clif index 51ae57c2ce0f..348dbf7212f6 100644 --- a/cranelift/filetests/filetests/egraph/algebraic.clif +++ b/cranelift/filetests/filetests/egraph/algebraic.clif @@ -3,7 +3,7 @@ set opt_level=none set use_egraphs=true target x86_64 -function %f(i32) -> i32 { +function %f0(i32) -> i32 { block0(v0: i32): v1 = iconst.i32 2 v2 = imul v0, v1 @@ -11,3 +11,12 @@ block0(v0: i32): ; nextln: return v1 return v2 } + +function %f1() -> i64 { +block0: + v0 = iconst.i32 0xffff_ffff_9876_5432 + v1 = uextend.i64 v0 + return v1 + ; check: v0 = iconst.i64 0x9876_5432 + ; nextln: return v0 ; v0 = 0x9876_5432 +}