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 (iconst_u ty 0)) 33(rule (simplify 34 (sge ty 35 (uextend $I64 x @ (value_type $I32)) 36 (iconst_u _ 0))) 37 (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)))) x) 51(rule (simplify (ireduce ty (uextend _ x @ (value_type ty)))) x) 52 53;; `band`, `bor`, and `bxor` can't affect any bits that aren't set in the one of 54;; the inputs, so they can be pushed down inside `uextend`s 55(rule (simplify (band bigty (uextend _ x@(value_type smallty)) (uextend _ y@(value_type smallty)))) 56 (uextend bigty (band smallty x y))) 57(rule (simplify (bor bigty (uextend _ x@(value_type smallty)) (uextend _ y@(value_type smallty)))) 58 (uextend bigty (bor smallty x y))) 59(rule (simplify (bxor bigty (uextend _ x@(value_type smallty)) (uextend _ y@(value_type smallty)))) 60 (uextend bigty (bxor smallty x y))) 61 62;; Matches values where `ireducing` them will not actually introduce another 63;; instruction, since other rules will collapse them with the reduction. 64(decl pure multi will_simplify_with_ireduce (Value) Value) 65(rule (will_simplify_with_ireduce x@(uextend _ _)) x) 66(rule (will_simplify_with_ireduce x@(sextend _ _)) x) 67(rule (will_simplify_with_ireduce x@(iconst _ _)) x) 68(rule (will_simplify_with_ireduce x@(unary_op _ _ a)) 69 (if-let _ (will_simplify_with_ireduce a)) 70 x) 71(rule (will_simplify_with_ireduce x@(binary_op _ _ a b)) 72 (if-let _ (will_simplify_with_ireduce a)) 73 (if-let _ (will_simplify_with_ireduce b)) 74 x) 75 76;; Matches values where the high bits of the input don't affect lower bits of 77;; the output, and thus the inputs can be reduced before the operation rather 78;; than doing the wide operation then reducing afterwards. 79(decl pure multi reducible_modular_op (Value) Value) 80(rule (reducible_modular_op x@(ineg _ _)) x) 81(rule (reducible_modular_op x@(bnot _ _)) x) 82(rule (reducible_modular_op x@(iadd _ _ _)) x) 83(rule (reducible_modular_op x@(isub _ _ _)) x) 84(rule (reducible_modular_op x@(imul _ _ _)) x) 85(rule (reducible_modular_op x@(bor _ _ _)) x) 86(rule (reducible_modular_op x@(bxor _ _ _)) x) 87(rule (reducible_modular_op x@(band _ _ _)) x) 88 89;; Replace `(small)(x OP y)` with `(small)x OP (small)y` in cases where that's 90;; legal and it reduces the total number of instructions since the reductions 91;; to the arguments simplify further. 92(rule (simplify (ireduce smallty val@(unary_op _ op x))) 93 (if-let _ (reducible_modular_op val)) 94 (if-let _ (will_simplify_with_ireduce x)) 95 (unary_op smallty op (ireduce smallty x))) 96(rule (simplify (ireduce smallty val@(binary_op _ op x y))) 97 (if-let _ (reducible_modular_op val)) 98 (if-let _ (will_simplify_with_ireduce x)) 99 (if-let _ (will_simplify_with_ireduce y)) 100 (binary_op smallty op (ireduce smallty x) (ireduce smallty y))) 101