diff --git a/cranelift/codegen/src/opts/cprop.isle b/cranelift/codegen/src/opts/cprop.isle index 19f5f2aacdf9..26580a7ea0c8 100644 --- a/cranelift/codegen/src/opts/cprop.isle +++ b/cranelift/codegen/src/opts/cprop.isle @@ -198,3 +198,13 @@ (rule (splat32 n) (splat64 (u64_or n (u64_shl n 32)))) (decl splat64 (u64) Constant) (extern constructor splat64 splat64) + +;; Reassociate nested shifts of constants to put constants together for cprop. +;; +;; ((A shift b) shift C) ==> ((A shift C) shift b) +(rule (simplify (ishl ty (ishl ty a@(iconst _ _) b) c@(iconst _ _))) + (ishl ty (ishl ty a c) b)) +(rule (simplify (ushr ty (ushr ty a@(iconst _ _) b) c@(iconst _ _))) + (ushr ty (ushr ty a c) b)) +(rule (simplify (sshr ty (sshr ty a@(iconst _ _) b) c@(iconst _ _))) + (sshr ty (sshr ty a c) b)) diff --git a/cranelift/filetests/filetests/egraph/reassociate-constants-in-shifts.clif b/cranelift/filetests/filetests/egraph/reassociate-constants-in-shifts.clif new file mode 100644 index 000000000000..9d50399d5b1c --- /dev/null +++ b/cranelift/filetests/filetests/egraph/reassociate-constants-in-shifts.clif @@ -0,0 +1,41 @@ +test optimize +set opt_level=speed +target x86_64 + +;; Test egraph rewrite rules that reassociate constants out of nested shifts. + +function %a(i32) -> i32 { +block0(v0: i32): + v1 = iconst.i32 1 + v2 = ishl v1, v0 + v3 = iconst.i32 2 + v4 = ishl v2, v3 + return v4 +; check: v6 = iconst.i32 4 +; nextln: v7 = ishl v6, v0 +; check: return v7 +} + +function %b(i32) -> i32 { +block0(v0: i32): + v1 = iconst.i32 8 + v2 = ushr v1, v0 + v3 = iconst.i32 2 + v4 = ushr v2, v3 + return v4 +; check: v3 = iconst.i32 2 +; nextln: v6 = ushr v3, v0 +; check: return v6 +} + +function %c(i32) -> i32 { +block0(v0: i32): + v1 = iconst.i32 8 + v2 = sshr v1, v0 + v3 = iconst.i32 2 + v4 = sshr v2, v3 + return v4 +; check: v3 = iconst.i32 2 +; nextln: v6 = sshr v3, v0 +; check: return v6 +}