diff --git a/cranelift/codegen/src/opts/arithmetic.isle b/cranelift/codegen/src/opts/arithmetic.isle index 5ed3669e7745..ec40c310f4c8 100644 --- a/cranelift/codegen/src/opts/arithmetic.isle +++ b/cranelift/codegen/src/opts/arithmetic.isle @@ -47,7 +47,7 @@ (subsume inner)) ;; x-x == 0. -(rule (simplify (isub (fits_in_64 (ty_int ty)) x x)) (subsume (iconst_u ty 0))) +(rule (simplify (isub (ty_int ty) x x)) (subsume (iconst_u ty 0))) ;; x*1 == x. (rule (simplify (imul ty diff --git a/cranelift/codegen/src/opts/bitops.isle b/cranelift/codegen/src/opts/bitops.isle index a56774cec2fd..de1515912b1f 100644 --- a/cranelift/codegen/src/opts/bitops.isle +++ b/cranelift/codegen/src/opts/bitops.isle @@ -15,16 +15,15 @@ (subsume x)) ;; x ^ x == 0. -(rule (simplify (bxor (fits_in_64 (ty_int ty)) x x)) +(rule (simplify (bxor (ty_int ty) x x)) (subsume (iconst_u ty 0))) ;; x ^ not(x) == not(x) ^ x == x | not(x) == not(x) | x == -1. ;; This identity also holds for non-integer types, vectors, and wider types. -;; But `iconst` is only valid for integers up to 64 bits wide. -(rule (simplify (bxor (fits_in_64 (ty_int ty)) x (bnot ty x))) (subsume (iconst ty (imm64 (ty_mask ty))))) -(rule (simplify (bxor (fits_in_64 (ty_int ty)) (bnot ty x) x)) (subsume (iconst ty (imm64 (ty_mask ty))))) -(rule (simplify (bor (fits_in_64 (ty_int ty)) x (bnot ty x))) (subsume (iconst ty (imm64 (ty_mask ty))))) -(rule (simplify (bor (fits_in_64 (ty_int ty)) (bnot ty x) x)) (subsume (iconst ty (imm64 (ty_mask ty))))) +(rule (simplify (bxor (ty_int ty) x (bnot ty x))) (subsume (iconst_s ty -1))) +(rule (simplify (bxor (ty_int ty) (bnot ty x) x)) (subsume (iconst_s ty -1))) +(rule (simplify (bor (ty_int ty) x (bnot ty x))) (subsume (iconst_s ty -1))) +(rule (simplify (bor (ty_int ty) (bnot ty x) x)) (subsume (iconst_s ty -1))) ;; x & x == x & -1 == x. (rule (simplify (band ty x x)) (subsume x)) @@ -33,8 +32,8 @@ ;; x & 0 == x & not(x) == not(x) & x == 0. (rule (simplify (band ty _ zero @ (iconst_u ty 0))) (subsume zero)) -(rule (simplify (band (fits_in_64 (ty_int ty)) x (bnot ty x))) (subsume (iconst_u ty 0))) -(rule (simplify (band (fits_in_64 (ty_int ty)) (bnot ty x) x)) (subsume (iconst_u ty 0))) +(rule (simplify (band (ty_int ty) x (bnot ty x))) (subsume (iconst_u ty 0))) +(rule (simplify (band (ty_int ty) (bnot ty x) x)) (subsume (iconst_u ty 0))) ;; not(not(x)) == x. (rule (simplify (bnot ty (bnot ty x))) (subsume x)) @@ -69,8 +68,8 @@ ;; (No need to duplicate for commutative `bor` for this constant version because ;; we move constants to the right.) (rule (simplify (bor ty - (band ty x (iconst ty (u64_from_imm64 y))) - z @ (iconst ty (u64_from_imm64 zk)))) + (band ty x (iconst_u ty y)) + z @ (iconst_u ty zk))) (if-let $true (u64_eq (u64_and (ty_mask ty) zk) (u64_and (ty_mask ty) (u64_not y)))) (bor ty x z)) @@ -83,11 +82,11 @@ ;; ;; (x | -x) sets the sign bit to 1 if x is nonzero, and 0 if x is zero. sshr propagates ;; the sign bit to the rest of the value. -(rule (simplify (sshr ty (bor ty x (ineg ty x)) (iconst ty (u64_from_imm64 shift_amt)))) +(rule (simplify (sshr ty (bor ty x (ineg ty x)) (iconst_u ty shift_amt))) (if-let $true (u64_eq shift_amt (ty_shift_mask ty))) (bmask ty x)) -(rule (simplify (sshr ty (bor ty (ineg ty x) x) (iconst ty (u64_from_imm64 shift_amt)))) +(rule (simplify (sshr ty (bor ty (ineg ty x) x) (iconst_u ty shift_amt))) (if-let $true (u64_eq shift_amt (ty_shift_mask ty))) (bmask ty x)) @@ -104,7 +103,7 @@ (rule (truthy (popcnt _ x)) x) (rule (truthy (rotl _ x _)) x) (rule (truthy (rotr _ x _)) x) -(rule (truthy (select _ x (iconst _ (u64_from_imm64 (u64_nonzero _))) (iconst _ (u64_from_imm64 0)))) x) +(rule (truthy (select _ x (iconst_u _ (u64_nonzero _)) (iconst_u _ 0))) x) ;; (ne ty (iconst 0) v) is also canonicalized into this form via another rule (rule (truthy (ne _ x (iconst_u _ 0))) x) diff --git a/cranelift/codegen/src/opts/cprop.isle b/cranelift/codegen/src/opts/cprop.isle index a76ecdd71a00..94574592d2e2 100644 --- a/cranelift/codegen/src/opts/cprop.isle +++ b/cranelift/codegen/src/opts/cprop.isle @@ -73,11 +73,12 @@ (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)))))) +;; iconst_[su] support $I128, but do so by extending, so restricting to +;; 64-bit or smaller keeps it from just remaking essentially the same thing. +(rule (simplify (uextend (fits_in_64 wide) (iconst_u narrow k))) + (subsume (iconst_u wide k))) +(rule (simplify (sextend (fits_in_64 wide) (iconst_s narrow k))) + (subsume (iconst_s wide k))) (rule (simplify (icmp result_ty @@ -167,10 +168,10 @@ (bxor ty x (bxor ty k1 k2))) (rule (simplify - (select ty (iconst _ (u64_from_imm64 (u64_nonzero _))) x y)) + (select ty (iconst_u _ (u64_nonzero _)) x y)) x) (rule (simplify - (select ty (iconst _ (u64_from_imm64 0)) x y)) + (select ty (iconst_u _ 0) x y)) y) ;; Replace subtraction by a "negative" constant with addition. @@ -179,10 +180,9 @@ ;; TODO: it would be nice to do this for `x + (-1) == x - 1` as well, but ;; that needs work in lowering first to avoid regressing addressing modes. -(rule (simplify (isub ty x (iconst ty k1))) - (if-let k2 (i64_sextend_imm64 ty k1)) - (if-let $true (u64_lt (i64_as_u64 (i64_neg k2)) (i64_as_u64 k2))) - (iadd ty x (iconst ty (imm64_masked ty (i64_as_u64 (i64_neg k2)))))) +(rule (simplify (isub ty x (iconst_s ty k))) + (if-let $true (u64_lt (i64_as_u64 (i64_neg k)) (i64_as_u64 k))) + (iadd ty x (iconst ty (imm64_masked ty (i64_as_u64 (i64_neg k)))))) ;; TODO: fadd, fsub, fmul, fdiv, fneg, fabs diff --git a/cranelift/codegen/src/opts/extends.isle b/cranelift/codegen/src/opts/extends.isle index dd45c1954494..17be06f456cb 100644 --- a/cranelift/codegen/src/opts/extends.isle +++ b/cranelift/codegen/src/opts/extends.isle @@ -14,13 +14,13 @@ ;; Masking out any of the top bits of the result of `uextend` is a no-op. (This ;; is like a cheap version of known-bits analysis.) -(rule (simplify (band wide x @ (uextend _ (value_type narrow)) (iconst _ (u64_from_imm64 mask)))) +(rule (simplify (band wide x @ (uextend _ (value_type narrow)) (iconst_u _ mask))) ; Check that `narrow_mask` has a subset of the bits that `mask` does. (if-let $true (let ((narrow_mask u64 (ty_mask narrow))) (u64_eq narrow_mask (u64_and mask narrow_mask)))) x) ;; Masking out the sign-extended bits of an `sextend` turns it into a `uextend`. -(rule (simplify (band wide (sextend _ x @ (value_type narrow)) (iconst _ (u64_from_imm64 mask)))) +(rule (simplify (band wide (sextend _ x @ (value_type narrow)) (iconst_u _ mask))) (if-let $true (u64_eq mask (ty_mask narrow))) (uextend wide x)) @@ -49,3 +49,12 @@ ;; actually doing the extend in the first place. (rule (simplify (ireduce ty (sextend _ x @ (value_type ty)))) x) (rule (simplify (ireduce ty (uextend _ x @ (value_type ty)))) x) + +;; `band`, `bor`, and `bxor` can't affect any bits that aren't set in the one of +;; the inputs, so they can be pushed down inside `uextend`s +(rule (simplify (band bigty (uextend _ x@(value_type smallty)) (uextend _ y@(value_type smallty)))) + (uextend bigty (band smallty x y))) +(rule (simplify (bor bigty (uextend _ x@(value_type smallty)) (uextend _ y@(value_type smallty)))) + (uextend bigty (bor smallty x y))) +(rule (simplify (bxor bigty (uextend _ x@(value_type smallty)) (uextend _ y@(value_type smallty)))) + (uextend bigty (bxor smallty x y))) diff --git a/cranelift/codegen/src/opts/icmp.isle b/cranelift/codegen/src/opts/icmp.isle index bdc868162a4f..65429870eebf 100644 --- a/cranelift/codegen/src/opts/icmp.isle +++ b/cranelift/codegen/src/opts/icmp.isle @@ -2,16 +2,16 @@ ;; `x == x` is always true for integers; `x != x` is false. Strict ;; inequalities are false, and loose inequalities are true. -(rule (simplify (eq (fits_in_64 (ty_int ty)) x x)) (iconst_u ty 1)) -(rule (simplify (ne (fits_in_64 (ty_int ty)) x x)) (iconst_u ty 0)) -(rule (simplify (ugt (fits_in_64 (ty_int ty)) x x)) (iconst_u ty 0)) -(rule (simplify (uge (fits_in_64 (ty_int ty)) x x)) (iconst_u ty 1)) -(rule (simplify (sgt (fits_in_64 (ty_int ty)) x x)) (iconst_u ty 0)) -(rule (simplify (sge (fits_in_64 (ty_int ty)) x x)) (iconst_u ty 1)) -(rule (simplify (ult (fits_in_64 (ty_int ty)) x x)) (iconst_u ty 0)) -(rule (simplify (ule (fits_in_64 (ty_int ty)) x x)) (iconst_u ty 1)) -(rule (simplify (slt (fits_in_64 (ty_int ty)) x x)) (iconst_u ty 0)) -(rule (simplify (sle (fits_in_64 (ty_int ty)) x x)) (iconst_u ty 1)) +(rule (simplify (eq (ty_int ty) x x)) (iconst_u ty 1)) +(rule (simplify (ne (ty_int ty) x x)) (iconst_u ty 0)) +(rule (simplify (ugt (ty_int ty) x x)) (iconst_u ty 0)) +(rule (simplify (uge (ty_int ty) x x)) (iconst_u ty 1)) +(rule (simplify (sgt (ty_int ty) x x)) (iconst_u ty 0)) +(rule (simplify (sge (ty_int ty) x x)) (iconst_u ty 1)) +(rule (simplify (ult (ty_int ty) x x)) (iconst_u ty 0)) +(rule (simplify (ule (ty_int ty) x x)) (iconst_u ty 1)) +(rule (simplify (slt (ty_int ty) x x)) (iconst_u ty 0)) +(rule (simplify (sle (ty_int ty) x x)) (iconst_u ty 1)) ;; Optimize icmp-of-icmp. (rule (simplify (ne ty @@ -65,62 +65,62 @@ (subsume (iconst_u bty 1))) ;; ult(x, UMAX) == ne(x, UMAX). -(rule (simplify (ult (fits_in_64 (ty_int bty)) x umax @ (iconst cty (u64_from_imm64 y)))) +(rule (simplify (ult (fits_in_64 (ty_int bty)) x umax @ (iconst_u cty y))) (if-let $true (u64_eq y (ty_umax cty))) (ne bty x umax)) ;; ule(x, UMAX) == true. -(rule (simplify (ule (fits_in_64 (ty_int bty)) x umax @ (iconst cty (u64_from_imm64 y)))) +(rule (simplify (ule (fits_in_64 (ty_int bty)) x umax @ (iconst_u cty y))) (if-let $true (u64_eq y (ty_umax cty))) (subsume (iconst_u bty 1))) ;; ugt(x, UMAX) == false. -(rule (simplify (ugt (fits_in_64 (ty_int bty)) x umax @ (iconst cty (u64_from_imm64 y)))) +(rule (simplify (ugt (fits_in_64 (ty_int bty)) x umax @ (iconst_u cty y))) (if-let $true (u64_eq y (ty_umax cty))) (subsume (iconst_u bty 0))) ;; uge(x, UMAX) == eq(x, UMAX). -(rule (simplify (uge (fits_in_64 (ty_int bty)) x umax @ (iconst cty (u64_from_imm64 y)))) +(rule (simplify (uge (fits_in_64 (ty_int bty)) x umax @ (iconst_u cty y))) (if-let $true (u64_eq y (ty_umax cty))) (eq bty x umax)) ;; slt(x, SMIN) == false. -(rule (simplify (slt (fits_in_64 (ty_int bty)) x smin @ (iconst cty (u64_from_imm64 y)))) +(rule (simplify (slt (fits_in_64 (ty_int bty)) x smin @ (iconst_u cty y))) (if-let $true (u64_eq y (ty_smin cty))) (subsume (iconst_u bty 0))) ;; sle(x, SMIN) == eq(x, SMIN). -(rule (simplify (sle (fits_in_64 (ty_int bty)) x smin @ (iconst cty (u64_from_imm64 y)))) +(rule (simplify (sle (fits_in_64 (ty_int bty)) x smin @ (iconst_u cty y))) (if-let $true (u64_eq y (ty_smin cty))) (eq bty x smin)) ;; sgt(x, SMIN) == ne(x, SMIN). -(rule (simplify (sgt (fits_in_64 (ty_int bty)) x smin @ (iconst cty (u64_from_imm64 y)))) +(rule (simplify (sgt (fits_in_64 (ty_int bty)) x smin @ (iconst_u cty y))) (if-let $true (u64_eq y (ty_smin cty))) (ne bty x smin)) ;; sge(x, SMIN) == true. -(rule (simplify (sge (fits_in_64 (ty_int bty)) x smin @ (iconst cty (u64_from_imm64 y)))) +(rule (simplify (sge (fits_in_64 (ty_int bty)) x smin @ (iconst_u cty y))) (if-let $true (u64_eq y (ty_smin cty))) (subsume (iconst_u bty 1))) ;; slt(x, SMAX) == ne(x, SMAX). -(rule (simplify (slt (fits_in_64 (ty_int bty)) x smax @ (iconst cty (u64_from_imm64 y)))) +(rule (simplify (slt (fits_in_64 (ty_int bty)) x smax @ (iconst_u cty y))) (if-let $true (u64_eq y (ty_smax cty))) (ne bty x smax)) ;; sle(x, SMAX) == true. -(rule (simplify (sle (fits_in_64 (ty_int bty)) x smax @ (iconst cty (u64_from_imm64 y)))) +(rule (simplify (sle (fits_in_64 (ty_int bty)) x smax @ (iconst_u cty y))) (if-let $true (u64_eq y (ty_smax cty))) (subsume (iconst_u bty 1))) ;; sgt(x, SMAX) == false. -(rule (simplify (sgt (fits_in_64 (ty_int bty)) x smax @ (iconst cty (u64_from_imm64 y)))) +(rule (simplify (sgt (fits_in_64 (ty_int bty)) x smax @ (iconst_u cty y))) (if-let $true (u64_eq y (ty_smax cty))) (subsume (iconst_u bty 0))) ;; sge(x, SMAX) == eq(x, SMAX). -(rule (simplify (sge (fits_in_64 (ty_int bty)) x smax @ (iconst cty (u64_from_imm64 y)))) +(rule (simplify (sge (fits_in_64 (ty_int bty)) x smax @ (iconst_u cty y))) (if-let $true (u64_eq y (ty_smax cty))) (eq bty x smax)) diff --git a/cranelift/codegen/src/opts/shifts.isle b/cranelift/codegen/src/opts/shifts.isle index 0849d541ecb4..290e4d148a3f 100644 --- a/cranelift/codegen/src/opts/shifts.isle +++ b/cranelift/codegen/src/opts/shifts.isle @@ -50,9 +50,8 @@ (rule (simplify (sshr wide (ishl wide (uextend wide x @ (value_type narrow)) - (iconst _ shift)) - (iconst _ shift))) - (if-let (u64_from_imm64 shift_u64) shift) + (iconst_u _ shift_u64)) + (iconst_u _ shift_u64))) (if-let $true (u64_eq shift_u64 (u64_sub (ty_bits_u64 wide) (ty_bits_u64 narrow)))) (sextend wide x)) @@ -62,9 +61,8 @@ (rule (simplify (sshr wide (ishl wide x @ (uextend wide (value_type narrow)) - (iconst _ shift)) - (iconst _ shift))) - (if-let (u64_from_imm64 shift_u64) shift) + (iconst_u _ shift_u64)) + (iconst_u _ shift_u64))) (if-let $true (u64_lt shift_u64 (u64_sub (ty_bits_u64 wide) (ty_bits_u64 narrow)))) x) @@ -73,9 +71,8 @@ (rule (simplify (sshr wide (ishl wide x @ (sextend wide (value_type narrow)) - (iconst _ shift)) - (iconst _ shift))) - (if-let (u64_from_imm64 shift_u64) shift) + (iconst_u _ shift_u64)) + (iconst_u _ shift_u64))) (if-let $true (u64_le shift_u64 (u64_sub (ty_bits_u64 wide) (ty_bits_u64 narrow)))) x) @@ -99,7 +96,7 @@ (rule (shift_amt_to_type 32) $I32) ;; ineg(ushr(x, k)) == sshr(x, k) when k == ty_bits - 1. -(rule (simplify (ineg ty (ushr ty x sconst @ (iconst ty (u64_from_imm64 shift_amt))))) +(rule (simplify (ineg ty (ushr ty x sconst @ (iconst_u ty shift_amt)))) (if-let $true (u64_eq shift_amt (ty_shift_mask ty))) (sshr ty x sconst)) @@ -153,8 +150,8 @@ ;; (ushr (ushr x k1) k2) == (ushr x (add k1 k2)) if shift_mask(k1) + shift_mask(k2) < ty_bits ;; (sshr (sshr x k1) k2) == (sshr x (add k1 k2)) if shift_mask(k1) + shift_mask(k2) < ty_bits (rule (simplify (ishl ty - (ishl ty x (iconst kty (u64_from_imm64 k1))) - (iconst _ (u64_from_imm64 k2)))) + (ishl ty x (iconst_u kty k1)) + (iconst_u _ k2))) (if-let shift_amt (u64_add (u64_and k1 (ty_shift_mask ty)) (u64_and k2 (ty_shift_mask ty)))) @@ -162,8 +159,8 @@ (ishl ty x (iconst_u kty shift_amt))) (rule (simplify (ushr ty - (ushr ty x (iconst kty (u64_from_imm64 k1))) - (iconst _ (u64_from_imm64 k2)))) + (ushr ty x (iconst_u kty k1)) + (iconst_u _ k2))) (if-let shift_amt (u64_add (u64_and k1 (ty_shift_mask ty)) (u64_and k2 (ty_shift_mask ty)))) @@ -171,8 +168,8 @@ (ushr ty x (iconst_u kty shift_amt))) (rule (simplify (sshr ty - (sshr ty x (iconst kty (u64_from_imm64 k1))) - (iconst _ (u64_from_imm64 k2)))) + (sshr ty x (iconst_u kty k1)) + (iconst_u _ k2))) (if-let shift_amt (u64_add (u64_and k1 (ty_shift_mask ty)) (u64_and k2 (ty_shift_mask ty)))) @@ -185,8 +182,8 @@ ;; (ishl (ishl x k1) k2) == 0 if shift_mask(k1) + shift_mask(k2) >= ty_bits ;; (ushr (ushr x k1) k2) == 0 if shift_mask(k1) + shift_mask(k2) >= ty_bits (rule (simplify (ishl ty - (ishl ty x (iconst _ (u64_from_imm64 k1))) - (iconst _ (u64_from_imm64 k2)))) + (ishl ty x (iconst_u _ k1)) + (iconst_u _ k2))) (if-let shift_amt (u64_add (u64_and k1 (ty_shift_mask ty)) (u64_and k2 (ty_shift_mask ty)))) @@ -194,8 +191,8 @@ (subsume (iconst_u ty 0))) (rule (simplify (ushr ty - (ushr ty x (iconst _ (u64_from_imm64 k1))) - (iconst _ (u64_from_imm64 k2)))) + (ushr ty x (iconst_u _ k1)) + (iconst_u _ k2))) (if-let shift_amt (u64_add (u64_and k1 (ty_shift_mask ty)) (u64_and k2 (ty_shift_mask ty)))) @@ -293,18 +290,18 @@ ;; (op x k) == (op x (and k (ty_shift_mask ty))) ;; ;; where `op` is one of ishl, ushr, sshr, rotl, rotr -(rule (simplify (ishl ty x (iconst kty (u64_from_imm64 k)))) +(rule (simplify (ishl ty x (iconst_u kty k))) (if-let $false (u64_eq k (u64_and k (ty_shift_mask ty)))) - (ishl ty x (iconst kty (imm64 (u64_and k (ty_shift_mask ty)))))) -(rule (simplify (ushr ty x (iconst kty (u64_from_imm64 k)))) + (ishl ty x (iconst_u kty (u64_and k (ty_shift_mask ty))))) +(rule (simplify (ushr ty x (iconst_u kty k))) (if-let $false (u64_eq k (u64_and k (ty_shift_mask ty)))) - (ushr ty x (iconst kty (imm64 (u64_and k (ty_shift_mask ty)))))) -(rule (simplify (sshr ty x (iconst kty (u64_from_imm64 k)))) + (ushr ty x (iconst_u kty (u64_and k (ty_shift_mask ty))))) +(rule (simplify (sshr ty x (iconst_u kty k))) (if-let $false (u64_eq k (u64_and k (ty_shift_mask ty)))) - (sshr ty x (iconst kty (imm64 (u64_and k (ty_shift_mask ty)))))) -(rule (simplify (rotr ty x (iconst kty (u64_from_imm64 k)))) + (sshr ty x (iconst_u kty (u64_and k (ty_shift_mask ty))))) +(rule (simplify (rotr ty x (iconst_u kty k))) (if-let $false (u64_eq k (u64_and k (ty_shift_mask ty)))) - (rotr ty x (iconst kty (imm64 (u64_and k (ty_shift_mask ty)))))) -(rule (simplify (rotl ty x (iconst kty (u64_from_imm64 k)))) + (rotr ty x (iconst_u kty (u64_and k (ty_shift_mask ty))))) +(rule (simplify (rotl ty x (iconst_u kty k))) (if-let $false (u64_eq k (u64_and k (ty_shift_mask ty)))) - (rotl ty x (iconst kty (imm64 (u64_and k (ty_shift_mask ty)))))) + (rotl ty x (iconst_u kty (u64_and k (ty_shift_mask ty))))) diff --git a/cranelift/filetests/filetests/egraph/extends.clif b/cranelift/filetests/filetests/egraph/extends.clif index 871b29ffa023..6562dc58d46b 100644 --- a/cranelift/filetests/filetests/egraph/extends.clif +++ b/cranelift/filetests/filetests/egraph/extends.clif @@ -117,3 +117,4 @@ block0(v0: i8): ; check: v4 = iconst.i8 0 ; check: v5 = icmp ne v0, v4 ; check: return v5 + diff --git a/cranelift/filetests/filetests/egraph/i128-opts.clif b/cranelift/filetests/filetests/egraph/i128-opts.clif index 40ef77f76763..f5347fb077a3 100644 --- a/cranelift/filetests/filetests/egraph/i128-opts.clif +++ b/cranelift/filetests/filetests/egraph/i128-opts.clif @@ -2,11 +2,136 @@ test optimize set opt_level=speed target x86_64 -; This it a regression test to ensure that we don't insert a iconst.i128 when optimizing bxor. -function %bxor_i128(i128) -> i128 system_v { +;; There's no `iconst.i128`, so these tests check that the various patterns +;; that might apply to `i128` introduce extended 64-bit constants instead, +;; or they're sufficiently conditioned to not apply. + +function %bxor_self_i128(i128) -> i128 { block0(v0: i128): v1 = bxor v0, v0 return v1 - ; check: v1 = bxor v0, v0 - ; nextln: return v1 + ; check: v2 = iconst.i64 0 + ; check: v3 = uextend.i128 v2 + ; check: return v3 +} + +function %isub_self_i128(i128) -> i128 { +block0(v0: i128): + v1 = isub v0, v0 + return v1 + ; check: v2 = iconst.i64 0 + ; check: v3 = uextend.i128 v2 ; v2 = 0 + ; check: return v3 +} + +function %band_bnot_self_i128(i128) -> i128 { +block0(v0: i128): + v1 = bnot v0 + v2 = band v0, v1 + return v2 + ; check: v3 = iconst.i64 0 + ; check: v4 = uextend.i128 v3 ; v3 = 0 + ; check: return v4 +} + +function %bxor_bnot_self_i128(i128) -> i128 { +block0(v0: i128): + v1 = bnot v0 + v2 = bxor v0, v1 + return v2 + ; check: v3 = iconst.i64 -1 + ; check: v4 = sextend.i128 v3 ; v3 = -1 + ; check: return v4 +} + +function %bor_bnot_self_i128(i128) -> i128 { +block0(v0: i128): + v1 = bnot v0 + v2 = bor v0, v1 + return v2 + ; check: v3 = iconst.i64 -1 + ; check: v4 = sextend.i128 v3 ; v3 = -1 + ; check: return v4 +} + +function %eq_self_i128(i128) -> i8 { +block0(v0: i128): + v1 = icmp eq v0, v0 + return v1 + ; check: v2 = iconst.i8 1 + ; check: return v2 ; v2 = 1 +} + +function %ne_self_i128(i128) -> i8 { +block0(v0: i128): + v1 = icmp ne v0, v0 + return v1 + ; check: v2 = iconst.i8 0 + ; check: return v2 ; v2 = 0 +} + +function %eq_self_v128(i8x16) -> i8x16 { +block0(v0: i8x16): + v1 = icmp eq v0, v0 + return v1 + ; check: v1 = icmp eq v0, v0 + ; check: return v1 +} + +function %ne_self_v128(i8x16) -> i8x16 { +block0(v0: i8x16): + v1 = icmp ne v0, v0 + return v1 + ; check: v1 = icmp ne v0, v0 + ; check: return v1 +} + +function %bor_extended_constants_i128() -> i128 { +block0: + v0 = iconst.i32 9 + v1 = uextend.i128 v0 + v2 = iconst.i32 12 + v3 = uextend.i128 v2 + v4 = bor v1, v3 + return v4 + ; check: v6 = iconst.i32 13 + ; check: v12 = uextend.i128 v6 ; v6 = 13 + ; check: return v12 +} + +;; These are big enough that they overflow u64, so should not be collapsed + +function %bnot_extended_constant_i128() -> i128 { +block0: + v0 = iconst.i32 0 + v1 = uextend.i128 v0 + v2 = bnot v1 + return v2 + ; check: v0 = iconst.i32 0 + ; check: v1 = uextend.i128 v0 + ; check: return v2 +} + +function %imul_extended_constants_i128() -> i128 { +block0: + v0 = iconst.i64 5_000_000_000 + v1 = uextend.i128 v0 + v2 = iconst.i64 7_000_000_000 + v3 = uextend.i128 v2 + v4 = imul v1, v3 + return v4 + ; check: v4 = imul v1, v3 + ; check: return v4 +} + +function %iadd_extended_constants_i128() -> i128 { +block0: + v0 = iconst.i64 0x8888_8888_8888_8888 + v1 = uextend.i128 v0 + v2 = iconst.i64 0x9999_9999_9999_9999 + v3 = uextend.i128 v2 + v4 = iadd v1, v3 + return v4 + ; check: v4 = iadd v1, v3 + ; check: return v4 }