Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions cranelift/codegen/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,12 @@ fn get_isle_compilations(
output: out_dir.join("isle_opt.rs"),
inputs: vec![
prelude_isle.clone(),
prelude_opt_isle.clone(),
prelude_opt_isle,
src_opts.join("algebraic.isle"),
src_opts.join("icmp.isle"),
src_opts.join("cprop.isle"),
],
untracked_inputs: vec![clif_opt_isle.clone()],
untracked_inputs: vec![clif_opt_isle],
},
// The x86-64 instruction selector.
IsleCompilation {
Expand Down
191 changes: 0 additions & 191 deletions cranelift/codegen/src/opts/algebraic.isle
Original file line number Diff line number Diff line change
Expand Up @@ -322,151 +322,11 @@
(rule (simplify x @ (f64const _ _))
(remat x))

;; Optimize icmp-of-icmp.
(rule (simplify (ne ty
(uextend _ inner @ (icmp ty _ _ _))
(iconst _ (u64_from_imm64 0))))
(subsume inner))

(rule (simplify (eq ty
(uextend _ (icmp ty cc x y))
(iconst _ (u64_from_imm64 0))))
(subsume (icmp ty (intcc_inverse cc) x y)))

;; Optimize select-of-uextend-of-icmp to select-of-icmp, because
;; select can take an I8 condition too.
(rule (simplify
(select ty (uextend _ c @ (icmp _ _ _ _)) x y))
(select ty c x y))
(rule (simplify
(select ty (uextend _ c @ (icmp _ _ _ _)) x y))
(select ty c x y))

;; `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 ty (imm64 1)))
(rule (simplify (ne (fits_in_64 (ty_int ty)) x x)) (iconst ty (imm64 0)))
(rule (simplify (ugt (fits_in_64 (ty_int ty)) x x)) (iconst ty (imm64 0)))
(rule (simplify (uge (fits_in_64 (ty_int ty)) x x)) (iconst ty (imm64 1)))
(rule (simplify (sgt (fits_in_64 (ty_int ty)) x x)) (iconst ty (imm64 0)))
(rule (simplify (sge (fits_in_64 (ty_int ty)) x x)) (iconst ty (imm64 1)))
(rule (simplify (ult (fits_in_64 (ty_int ty)) x x)) (iconst ty (imm64 0)))
(rule (simplify (ule (fits_in_64 (ty_int ty)) x x)) (iconst ty (imm64 1)))
(rule (simplify (slt (fits_in_64 (ty_int ty)) x x)) (iconst ty (imm64 0)))
(rule (simplify (sle (fits_in_64 (ty_int ty)) x x)) (iconst ty (imm64 1)))

;; (x ^ -1) can be replaced with the `bnot` instruction
(rule (simplify (bxor ty x (iconst ty k)))
(if-let -1 (i64_sextend_imm64 ty k))
(bnot ty x))


;; Masking the result of a comparison with 1 always results in the comparison
;; itself. Note that comparisons in wasm may sometimes be hidden behind
;; extensions.
(rule (simplify
(band (ty_int _)
cmp @ (icmp _ _ _ _)
(iconst _ (u64_from_imm64 1))))
cmp)
(rule (simplify
(band (ty_int _)
extend @ (uextend _ (icmp _ _ _ _))
(iconst _ (u64_from_imm64 1))))
extend)

;; ult(x, 0) == false.
(rule (simplify
(ult (fits_in_64 (ty_int bty)) x zero @ (iconst _ (u64_from_imm64 0))))
(subsume (iconst bty (imm64 0))))

;; ule(x, 0) == eq(x, 0)
(rule (simplify
(ule (fits_in_64 (ty_int bty)) x zero @ (iconst _ (u64_from_imm64 0))))
(eq bty x zero))

;; ugt(x, 0) == ne(x, 0).
(rule (simplify
(ugt (fits_in_64 (ty_int bty)) x zero @ (iconst _ (u64_from_imm64 0))))
(ne bty x zero))

;; uge(x, 0) == true.
(rule (simplify
(uge (fits_in_64 (ty_int bty)) x zero @ (iconst _ (u64_from_imm64 0))))
(subsume (iconst bty (imm64 1))))

;; ult(x, UMAX) == ne(x, UMAX).
(rule (simplify
(ult (fits_in_64 (ty_int bty)) x umax @ (iconst cty (u64_from_imm64 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))))
(if-let $true (u64_eq y (ty_umax cty)))
(subsume (iconst bty (imm64 1))))

;; ugt(x, UMAX) == false.
(rule (simplify
(ugt (fits_in_64 (ty_int bty)) x umax @ (iconst cty (u64_from_imm64 y))))
(if-let $true (u64_eq y (ty_umax cty)))
(subsume (iconst bty (imm64 0))))

;; uge(x, UMAX) == eq(x, UMAX).
(rule (simplify
(uge (fits_in_64 (ty_int bty)) x umax @ (iconst cty (u64_from_imm64 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))))
(if-let $true (u64_eq y (ty_smin cty)))
(subsume (iconst bty (imm64 0))))

;; sle(x, SMIN) == eq(x, SMIN).
(rule (simplify
(sle (fits_in_64 (ty_int bty)) x smin @ (iconst cty (u64_from_imm64 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))))
(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))))
(if-let $true (u64_eq y (ty_smin cty)))
(subsume (iconst bty (imm64 1))))

;; slt(x, SMAX) == ne(x, SMAX).
(rule (simplify
(slt (fits_in_64 (ty_int bty)) x smax @ (iconst cty (u64_from_imm64 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))))
(if-let $true (u64_eq y (ty_smax cty)))
(subsume (iconst bty (imm64 1))))

;; sgt(x, SMAX) == false.
(rule (simplify
(sgt (fits_in_64 (ty_int bty)) x smax @ (iconst cty (u64_from_imm64 y))))
(if-let $true (u64_eq y (ty_smax cty)))
(subsume (iconst bty (imm64 0))))

;; sge(x, SMAX) == eq(x, SMAX).
(rule (simplify
(sge (fits_in_64 (ty_int bty)) x smax @ (iconst cty (u64_from_imm64 y))))
(if-let $true (u64_eq y (ty_smax cty)))
(eq bty x smax))

;; 32-bit integers zero-extended to 64-bit integers are never negative
(rule (simplify
(slt ty
Expand All @@ -479,57 +339,6 @@
(iconst _ (u64_from_imm64 0))))
(iconst ty (imm64 1)))

(decl pure decompose_intcc (IntCC) u64)
(rule (decompose_intcc (IntCC.Equal)) 1)
(rule (decompose_intcc (IntCC.UnsignedLessThan)) 2)
(rule (decompose_intcc (IntCC.SignedLessThan)) 2)
(rule (decompose_intcc (IntCC.UnsignedLessThanOrEqual)) 3)
(rule (decompose_intcc (IntCC.SignedLessThanOrEqual)) 3)
(rule (decompose_intcc (IntCC.UnsignedGreaterThan)) 4)
(rule (decompose_intcc (IntCC.SignedGreaterThan)) 4)
(rule (decompose_intcc (IntCC.UnsignedGreaterThanOrEqual)) 5)
(rule (decompose_intcc (IntCC.SignedGreaterThanOrEqual)) 5)
(rule (decompose_intcc (IntCC.NotEqual)) 6)

(decl compose_icmp (Type u64 bool Value Value) Value)
(rule (compose_icmp ty 0 _ _ _) (subsume (iconst ty (imm64 0))))
(rule (compose_icmp ty 1 _ x y) (icmp ty (IntCC.Equal) x y))
(rule (compose_icmp ty 2 $false x y) (icmp ty (IntCC.UnsignedLessThan) x y))
(rule (compose_icmp ty 2 $true x y) (icmp ty (IntCC.SignedLessThan) x y))
(rule (compose_icmp ty 3 $false x y) (icmp ty (IntCC.UnsignedLessThanOrEqual) x y))
(rule (compose_icmp ty 3 $true x y) (icmp ty (IntCC.SignedLessThanOrEqual) x y))
(rule (compose_icmp ty 4 $false x y) (icmp ty (IntCC.UnsignedGreaterThan) x y))
(rule (compose_icmp ty 4 $true x y) (icmp ty (IntCC.SignedGreaterThan) x y))
(rule (compose_icmp ty 5 $false x y) (icmp ty (IntCC.UnsignedGreaterThanOrEqual) x y))
(rule (compose_icmp ty 5 $true x y) (icmp ty (IntCC.SignedGreaterThanOrEqual) x y))
(rule (compose_icmp ty 6 _ x y) (icmp ty (IntCC.NotEqual) x y))
(rule (compose_icmp ty 7 _ _ _) (subsume (iconst ty (imm64 1))))

(decl pure intcc_class (IntCC) u64)
(rule (intcc_class (IntCC.UnsignedLessThan)) 1)
(rule (intcc_class (IntCC.UnsignedLessThanOrEqual)) 1)
(rule (intcc_class (IntCC.UnsignedGreaterThan)) 1)
(rule (intcc_class (IntCC.UnsignedGreaterThanOrEqual)) 1)
(rule (intcc_class (IntCC.SignedLessThan)) 2)
(rule (intcc_class (IntCC.SignedLessThanOrEqual)) 2)
(rule (intcc_class (IntCC.SignedGreaterThan)) 2)
(rule (intcc_class (IntCC.SignedGreaterThanOrEqual)) 2)
(rule (intcc_class (IntCC.Equal)) 3)
(rule (intcc_class (IntCC.NotEqual)) 3)

(decl pure partial intcc_comparable (IntCC IntCC) bool)
(rule (intcc_comparable x y)
(if-let (u64_nonzero class) (u64_and (intcc_class x) (intcc_class y)))
(u64_eq 2 class))

(rule (simplify (band ty (icmp ty cc1 x y) (icmp ty cc2 x y)))
(if-let signed (intcc_comparable cc1 cc2))
(compose_icmp ty (u64_and (decompose_intcc cc1) (decompose_intcc cc2)) signed x y))

(rule (simplify (bor ty (icmp ty cc1 x y) (icmp ty cc2 x y)))
(if-let signed (intcc_comparable cc1 cc2))
(compose_icmp ty (u64_or (decompose_intcc cc1) (decompose_intcc cc2)) signed x y))

;; Transform select-of-icmp into {u,s}{min,max} instructions where possible.
(rule (simplify (select ty (sgt _ x y) x y)) (smax ty x y))
(rule (simplify (select ty (sge _ x y) x y)) (smax ty x y))
Expand Down
Loading