1;; Chained `uextend` and `sextend`. 2(rule (simplify (uextend ty (uextend _intermediate_ty x))) 3 (uextend ty x)) 4(rule (simplify (sextend ty (sextend _intermediate_ty x))) 5 (sextend ty x)) 6 7;; Once something has be `uextend`ed, further `sextend`ing is the same as `uextend` 8(rule (simplify (sextend ty (uextend _intermediate_ty x))) 9 (uextend ty x)) 10 11;; `icmp` is zero or one, so sign-extending is the same as zero-extending 12(rule (simplify (sextend ty x@(icmp _ _ _ _))) 13 (uextend ty x)) 14 15;; Masking out any of the top bits of the result of `uextend` is a no-op. (This 16;; is like a cheap version of known-bits analysis.) 17(rule (simplify (band wide x @ (uextend _ (value_type narrow)) (iconst_u _ mask))) 18 ; Check that `narrow_mask` has a subset of the bits that `mask` does. 19 (if-let true (let ((narrow_mask u64 (ty_mask narrow))) (u64_eq narrow_mask (u64_and mask narrow_mask)))) 20 x) 21 22;; Masking out the sign-extended bits of an `sextend` turns it into a `uextend`. 23(rule (simplify (band wide (sextend _ x @ (value_type narrow)) (iconst_u _ mask))) 24 (if-let true (u64_eq mask (ty_mask narrow))) 25 (uextend wide x)) 26 27;; 32-bit integers zero-extended to 64-bit integers are never negative 28(rule (simplify 29 (slt ty 30 (uextend $I64 x @ (value_type $I32)) 31 (iconst_u _ 0))) 32 (subsume (iconst_u ty 0))) 33(rule (simplify 34 (sge ty 35 (uextend $I64 x @ (value_type $I32)) 36 (iconst_u _ 0))) 37 (subsume (iconst_u ty 1))) 38 39;; Sign-extending can't change whether a number is zero nor how it signed-compares to zero 40(rule (simplify (eq _ (sextend _ x@(value_type ty)) (iconst_s _ 0))) 41 (eq ty x (iconst_s ty 0))) 42(rule (simplify (ne _ (sextend _ x@(value_type ty)) (iconst_s _ 0))) 43 (ne ty x (iconst_s ty 0))) 44(rule (simplify (icmp _ cc (sextend _ x@(value_type ty)) (iconst_s _ 0))) 45 (if (signed_cond_code cc)) 46 (icmp ty cc x (iconst_s ty 0))) 47 48;; A reduction-of-an-extend back to the same original type is the same as not 49;; actually doing the extend in the first place. 50(rule (simplify (ireduce ty (sextend _ x @ (value_type ty)))) (subsume x)) 51(rule (simplify (ireduce ty (uextend _ x @ (value_type ty)))) (subsume x)) 52 53;; A reduction-of-an-extend that's not just to the original type is either: 54;; a reduction of the original if the final type is smaller, or 55(rule (simplify (ireduce (ty_int ty_final) (sextend _ inner@(value_type ty_initial)))) 56 (if-let true (u64_lt (ty_bits_u64 ty_final) (ty_bits_u64 ty_initial))) 57 (ireduce ty_final inner)) 58(rule (simplify (ireduce (ty_int ty_final) (uextend _ inner@(value_type ty_initial)))) 59 (if-let true (u64_lt (ty_bits_u64 ty_final) (ty_bits_u64 ty_initial))) 60 (ireduce ty_final inner)) 61;; an extension of the original if the final type is larger. 62(rule (simplify (ireduce (ty_int ty_final) (sextend _ inner@(value_type ty_initial)))) 63 (if-let true (u64_lt (ty_bits_u64 ty_initial) (ty_bits_u64 ty_final))) 64 (sextend ty_final inner)) 65(rule (simplify (ireduce (ty_int ty_final) (uextend _ inner@(value_type ty_initial)))) 66 (if-let true (u64_lt (ty_bits_u64 ty_initial) (ty_bits_u64 ty_final))) 67 (uextend ty_final inner)) 68 69;; `band`, `bor`, and `bxor` can't affect any bits that aren't set in the one of 70;; the inputs, so they can be pushed down inside `uextend`s 71(rule (simplify (band bigty (uextend _ x@(value_type smallty)) (uextend _ y@(value_type smallty)))) 72 (uextend bigty (band smallty x y))) 73(rule (simplify (bor bigty (uextend _ x@(value_type smallty)) (uextend _ y@(value_type smallty)))) 74 (uextend bigty (bor smallty x y))) 75(rule (simplify (bxor bigty (uextend _ x@(value_type smallty)) (uextend _ y@(value_type smallty)))) 76 (uextend bigty (bxor smallty x y))) 77 78;; Replace `(small)(x OP y)` with `(small)x OP (small)y` in cases where that's 79;; legal. 80;; Matches values where the high bits of the input don't affect lower bits of 81;; the output, and thus the inputs can be reduced before the operation rather 82;; than doing the wide operation then reducing afterwards. 83(rule (simplify (ireduce ty (ineg _ x))) (ineg ty (ireduce ty x))) 84(rule (simplify (ireduce ty (bnot _ x))) (bnot ty (ireduce ty x))) 85 86(rule (simplify (ireduce ty (iadd _ x y))) (iadd ty (ireduce ty x) (ireduce ty y))) 87(rule (simplify (ireduce ty (isub _ x y))) (isub ty (ireduce ty x) (ireduce ty y))) 88(rule (simplify (ireduce ty (imul _ x y))) (imul ty (ireduce ty x) (ireduce ty y))) 89(rule (simplify (ireduce ty (bor _ x y))) (bor ty (ireduce ty x) (ireduce ty y))) 90(rule (simplify (ireduce ty (bxor _ x y))) (bxor ty (ireduce ty x) (ireduce ty y))) 91(rule (simplify (ireduce ty (band _ x y))) (band ty (ireduce ty x) (ireduce ty y))) 92 93;; Try to transform an `iconcat` into an i128 into either an sextend or uextend 94(rule (simplify (iconcat $I128 x (iconst_u _ 0))) (uextend $I128 x)) 95(rule (simplify (iconcat $I128 x (sshr _ x (iconst_u _ 63)))) (sextend $I128 x)) 96