| ;; Constant propagation. |
| |
| (rule (simplify |
| (iadd (fits_in_64 ty) |
| (iconst ty (u64_from_imm64 k1)) |
| (iconst ty (u64_from_imm64 k2)))) |
| (subsume (iconst ty (imm64_masked ty (u64_add k1 k2))))) |
| |
| (rule (simplify |
| (isub (fits_in_64 ty) |
| (iconst ty (u64_from_imm64 k1)) |
| (iconst ty (u64_from_imm64 k2)))) |
| (subsume (iconst ty (imm64_masked ty (u64_sub k1 k2))))) |
| |
| (rule (simplify |
| (imul (fits_in_64 ty) |
| (iconst ty (u64_from_imm64 k1)) |
| (iconst ty (u64_from_imm64 k2)))) |
| (subsume (iconst ty (imm64_masked ty (u64_mul k1 k2))))) |
| |
| (rule (simplify |
| (sdiv (fits_in_64 ty) |
| (iconst ty (u64_from_imm64 k1)) |
| (iconst ty (u64_from_imm64 k2)))) |
| (if-let d (u64_sdiv k1 k2)) |
| (subsume (iconst ty (imm64_masked ty d)))) |
| |
| (rule (simplify |
| (udiv (fits_in_64 ty) |
| (iconst ty (u64_from_imm64 k1)) |
| (iconst ty (u64_from_imm64 k2)))) |
| (if-let d (u64_udiv k1 k2)) |
| (subsume (iconst ty (imm64_masked ty d)))) |
| |
| (rule (simplify |
| (bor (fits_in_64 ty) |
| (iconst ty (u64_from_imm64 k1)) |
| (iconst ty (u64_from_imm64 k2)))) |
| (subsume (iconst ty (imm64_masked ty (u64_or k1 k2))))) |
| |
| (rule (simplify |
| (band (fits_in_64 ty) |
| (iconst ty (u64_from_imm64 k1)) |
| (iconst ty (u64_from_imm64 k2)))) |
| (subsume (iconst ty (imm64_masked ty (u64_and k1 k2))))) |
| |
| (rule (simplify |
| (bxor (fits_in_64 ty) |
| (iconst ty (u64_from_imm64 k1)) |
| (iconst ty (u64_from_imm64 k2)))) |
| (subsume (iconst ty (imm64_masked ty (u64_xor k1 k2))))) |
| |
| (rule (simplify |
| (bnot (fits_in_64 ty) |
| (iconst ty (u64_from_imm64 k)))) |
| (subsume (iconst ty (imm64_masked ty (u64_not k))))) |
| |
| (rule (simplify (ishl (fits_in_64 ty) |
| (iconst ty k1) |
| (iconst _ k2))) |
| (subsume (iconst ty (imm64_shl ty k1 k2)))) |
| |
| (rule (simplify (ushr (fits_in_64 ty) |
| (iconst ty k1) |
| (iconst _ k2))) |
| (subsume (iconst ty (imm64_ushr ty k1 k2)))) |
| |
| (rule (simplify (sshr (fits_in_64 ty) |
| (iconst ty k1) |
| (iconst _ k2))) |
| (subsume (iconst ty (imm64_sshr ty k1 k2)))) |
| |
| (rule (simplify (ireduce narrow (iconst (fits_in_64 _) (u64_from_imm64 imm)))) |
| (subsume (iconst narrow (imm64_masked narrow imm)))) |
| |
| (rule (simplify (uextend (fits_in_64 wide) (iconst narrow imm))) |
| (subsume (iconst wide (imm64 (u64_uextend_imm64 narrow imm))))) |
| |
| (rule (simplify (sextend (fits_in_64 wide) (iconst narrow imm))) |
| (subsume (iconst wide (imm64_masked wide (i64_as_u64 (i64_sextend_imm64 narrow imm)))))) |
| |
| (rule (simplify |
| (icmp result_ty |
| cc |
| (iconst ty k1) |
| (iconst ty k2))) |
| (subsume (iconst result_ty (imm64_icmp ty cc k1 k2)))) |
| |
| |
| ;; Canonicalize via commutativity: push immediates to the right. |
| ;; |
| ;; (op k x) --> (op x k) |
| |
| (rule (simplify |
| (iadd ty k @ (iconst ty _) x)) |
| (iadd ty x k)) |
| ;; sub is not commutative, but we can flip the args and negate the |
| ;; whole thing. |
| (rule (simplify |
| (isub ty k @ (iconst ty _) x)) |
| (ineg ty (isub ty x k))) |
| (rule (simplify |
| (imul ty k @ (iconst ty _) x)) |
| (imul ty x k)) |
| |
| (rule (simplify |
| (bor ty k @ (iconst ty _) x)) |
| (bor ty x k)) |
| (rule (simplify |
| (band ty k @ (iconst ty _) x)) |
| (band ty x k)) |
| (rule (simplify |
| (bxor ty k @ (iconst ty _) x)) |
| (bxor ty x k)) |
| |
| (rule (simplify |
| (icmp ty cc k @ (iconst _ _) x)) |
| (icmp ty (intcc_swap_args cc) x k)) |
| |
| ;; Canonicalize via associativity: reassociate to a right-heavy tree |
| ;; for constants. |
| ;; |
| ;; (op (op x k) k) --> (op x (op k k)) |
| |
| (rule (simplify |
| (iadd ty (iadd ty x k1 @ (iconst ty _)) k2 @ (iconst ty _))) |
| (iadd ty x (iadd ty k1 k2))) |
| ;; sub is not directly associative, but we can flip a sub to an add to |
| ;; make it work: |
| ;; - (sub (sub x k1) k2) -> (sub x (add k1 k2)) |
| ;; - (sub (sub k1 x) k2) -> (sub (sub k1 k2) x) |
| ;; - (sub (add x k1) k2) -> (sub x (sub k2 k1)) |
| ;; - (add (sub x k1) k2) -> (add x (sub k2 k1)) |
| ;; - (add (sub k1 x) k2) -> (sub (add k1 k2) x) |
| (rule (simplify (isub ty |
| (isub ty x (iconst ty (u64_from_imm64 k1))) |
| (iconst ty (u64_from_imm64 k2)))) |
| (isub ty x (iconst ty (imm64_masked ty (u64_add k1 k2))))) |
| (rule (simplify (isub ty |
| (isub ty (iconst ty (u64_from_imm64 k1)) x) |
| (iconst ty (u64_from_imm64 k2)))) |
| (isub ty (iconst ty (imm64_masked ty (u64_sub k1 k2))) x)) |
| (rule (simplify (isub ty |
| (iadd ty x (iconst ty (u64_from_imm64 k1))) |
| (iconst ty (u64_from_imm64 k2)))) |
| (isub ty x (iconst ty (imm64_masked ty (u64_sub k2 k1))))) |
| (rule (simplify (iadd ty |
| (isub ty x (iconst ty (u64_from_imm64 k1))) |
| (iconst ty (u64_from_imm64 k2)))) |
| (iadd ty x (iconst ty (imm64_masked ty (u64_sub k2 k1))))) |
| (rule (simplify (iadd ty |
| (isub ty (iconst ty (u64_from_imm64 k1)) x) |
| (iconst ty (u64_from_imm64 k2)))) |
| (isub ty (iconst ty (imm64_masked ty (u64_add k1 k2))) x)) |
| |
| (rule (simplify |
| (imul ty (imul ty x k1 @ (iconst ty _)) k2 @ (iconst ty _))) |
| (imul ty x (imul ty k1 k2))) |
| (rule (simplify |
| (bor ty (bor ty x k1 @ (iconst ty _)) k2 @ (iconst ty _))) |
| (bor ty x (bor ty k1 k2))) |
| (rule (simplify |
| (band ty (band ty x k1 @ (iconst ty _)) k2 @ (iconst ty _))) |
| (band ty x (band ty k1 k2))) |
| (rule (simplify |
| (bxor ty (bxor ty x k1 @ (iconst ty _)) k2 @ (iconst ty _))) |
| (bxor ty x (bxor ty k1 k2))) |
| |
| (rule (simplify |
| (select ty (iconst _ (u64_from_imm64 (u64_nonzero _))) x y)) |
| x) |
| (rule (simplify |
| (select ty (iconst _ (u64_from_imm64 0)) x y)) |
| y) |
| |
| ;; TODO: fadd, fsub, fmul, fdiv, fneg, fabs |
| |
| ;; A splat of a constant can become a direct `vconst` with the appropriate bit |
| ;; pattern. |
| (rule (simplify (splat dst (iconst $I8 n))) |
| (vconst dst (splat8 (u64_uextend_imm64 $I8 n)))) |
| (rule (simplify (splat dst (iconst $I16 n))) |
| (vconst dst (splat16 (u64_uextend_imm64 $I16 n)))) |
| (rule (simplify (splat dst (iconst $I32 n))) |
| (vconst dst (splat32 (u64_uextend_imm64 $I32 n)))) |
| (rule (simplify (splat dst (iconst $I64 n))) |
| (vconst dst (splat64 (u64_uextend_imm64 $I64 n)))) |
| (rule (simplify (splat dst (f32const _ (u32_from_ieee32 n)))) |
| (vconst dst (splat32 n))) |
| (rule (simplify (splat dst (f64const _ (u64_from_ieee64 n)))) |
| (vconst dst (splat64 n))) |
| |
| (decl splat8 (u64) Constant) |
| (rule (splat8 n) (splat16 (u64_or n (u64_shl n 8)))) |
| (decl splat16 (u64) Constant) |
| (rule (splat16 n) (splat32 (u64_or n (u64_shl n 16)))) |
| (decl splat32 (u64) Constant) |
| (rule (splat32 n) (splat64 (u64_or n (u64_shl n 32)))) |
| (decl splat64 (u64) Constant) |
| (extern constructor splat64 splat64) |