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
7 changes: 7 additions & 0 deletions cranelift/codegen/meta/src/gen_isle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,13 @@ fn gen_common_isle(
(IsleTarget::Lower, _, _, _) => ("Inst", false, "make_inst", "inst_data_value"),
};

if ty_in_decl && isle_target == IsleTarget::Opt {
fmt.line(";; The `Type` argument is the instruction's *controlling* type, both");
fmt.line(";; when matching and when constructing. For most instructions this is");
fmt.line(";; the result type, but not for e.g. comparisons (`icmp`'s controlling");
fmt.line(";; type is the operand type; its result is `i8` or a lane-wise mask).");
fmt.line(";; Use `(has_type ty ...)` to bind the result type instead.");
}
fmtln!(
fmt,
"(decl {} ({}{}) {})",
Expand Down
21 changes: 18 additions & 3 deletions cranelift/codegen/src/egraph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,27 @@ pub(crate) enum NewOrExistingInst {
Existing(Inst),
}

/// The type paired with an instruction's `InstructionData` throughout the
/// e-graph: its controlling type variable, or, for a non-polymorphic
/// instruction that has no controlling type (e.g. `f32const`), the type of its
/// first result.
pub(crate) fn inst_ctrl_type(dfg: &DataFlowGraph, inst: Inst) -> Type {
let ty = dfg.ctrl_typevar(inst);
if ty != crate::ir::types::INVALID {
ty
} else if let Some(result) = dfg.inst_results(inst).first() {
dfg.value_type(*result)
} else {
ty
}
}

impl NewOrExistingInst {
fn get_inst_key<'a>(&'a self, dfg: &'a DataFlowGraph) -> (Type, InstructionData) {
match self {
NewOrExistingInst::New(data, ty) => (*ty, *data),
NewOrExistingInst::Existing(inst) => {
let ty = dfg.ctrl_typevar(*inst);
let ty = inst_ctrl_type(dfg, *inst);
(ty, dfg.insts[*inst])
}
}
Expand Down Expand Up @@ -250,7 +265,7 @@ where
NewOrExistingInst::Existing(inst) => {
self.stats.pure_inst_insert_orig += 1;
let result = self.func.dfg.first_result(inst);
let ty = self.func.dfg.ctrl_typevar(inst);
let ty = inst_ctrl_type(&self.func.dfg, inst);
(inst, result, ty)
}
};
Expand Down Expand Up @@ -514,7 +529,7 @@ where
// skeleton (`Layout`), we need to be mindful of whether
// our current position is dominated by an instance of the
// instruction. (See #5796 for details.)
let ty = self.func.dfg.ctrl_typevar(inst);
let ty = inst_ctrl_type(&self.func.dfg, inst);
match self
.gvn_map
.entry(&NullCtx, (ty, self.func.dfg.insts[inst]))
Expand Down
11 changes: 8 additions & 3 deletions cranelift/codegen/src/opts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
mod div_const;

use crate::egraph::{NewOrExistingInst, OptimizeCtx};
use crate::egraph::{NewOrExistingInst, OptimizeCtx, inst_ctrl_type};
pub use crate::ir::condcodes::{FloatCC, IntCC};
use crate::ir::dfg::ValueDef;
pub use crate::ir::immediates::{Ieee16, Ieee32, Ieee64, Ieee128, Imm64, Offset32, Uimm8, V128Imm};
Expand Down Expand Up @@ -114,8 +114,13 @@ where
return None;
}
ctx.ctx.extractor_fuel -= 1;
let ty = ctx.ctx.func.dfg.value_type(value);
trace!(" -> value of type {}", ty);
// The type we yield is the instruction's controlling
// type, matching what `make_inst` takes when a rule
// constructs an instruction. For most opcodes this is
// the result type, but e.g. `icmp`'s controlling type
// is the operand type while its result is `i8`.
let ty = inst_ctrl_type(&ctx.ctx.func.dfg, inst);
trace!(" -> controlling type {}", ty);
return Some((ty, ctx.ctx.func.dfg.insts[inst]));
}
_ => {}
Expand Down
59 changes: 31 additions & 28 deletions cranelift/codegen/src/opts/arithmetic.isle
Original file line number Diff line number Diff line change
Expand Up @@ -413,10 +413,10 @@
(rule 1 (cmp_true (ty_vec128 ty)) (iconst_s ty -1))

;; (x + y) == (y + x) --> true
(rule (simplify (eq ty (iadd cty x y) (iadd cty y x))) (cmp_true ty))
(rule (simplify (eq ty (iadd cty y x) (iadd cty x y))) (cmp_true ty))
(rule (simplify (eq ty (iadd cty x y) (iadd cty x y))) (cmp_true ty))
(rule (simplify (eq ty (iadd cty y x) (iadd cty y x))) (cmp_true ty))
(rule (simplify (has_type ty (eq _ (iadd cty x y) (iadd cty y x)))) (cmp_true ty))
(rule (simplify (has_type ty (eq _ (iadd cty y x) (iadd cty x y)))) (cmp_true ty))
(rule (simplify (has_type ty (eq _ (iadd cty x y) (iadd cty x y)))) (cmp_true ty))
(rule (simplify (has_type ty (eq _ (iadd cty y x) (iadd cty y x)))) (cmp_true ty))

;; (x - y) != x --> y != 0
(rule (simplify (ne cty (isub ty x y) x)) (ne cty y (all_zero ty)))
Expand All @@ -440,24 +440,24 @@
(rule (simplify (ineg ty (imul ty x (ineg ty y)))) (imul ty x y))

;; max(x, y) >= x
(rule (simplify (sge ty (smax ty x y) x)) (cmp_true ty))
(rule (simplify (sge ty (smax ty y x) x)) (cmp_true ty))
(rule (simplify (sle ty x (smax ty x y))) (cmp_true ty))
(rule (simplify (sle ty x (smax ty y x))) (cmp_true ty))
(rule (simplify (uge ty (umax ty x y) x)) (cmp_true ty))
(rule (simplify (uge ty (umax ty y x) x)) (cmp_true ty))
(rule (simplify (ule ty x (umax ty x y))) (cmp_true ty))
(rule (simplify (ule ty x (umax ty y x))) (cmp_true ty))
(rule (simplify (has_type bty (sge ty (smax ty x y) x))) (cmp_true bty))
(rule (simplify (has_type bty (sge ty (smax ty y x) x))) (cmp_true bty))
(rule (simplify (has_type bty (sle ty x (smax ty x y)))) (cmp_true bty))
(rule (simplify (has_type bty (sle ty x (smax ty y x)))) (cmp_true bty))
(rule (simplify (has_type bty (uge ty (umax ty x y) x))) (cmp_true bty))
(rule (simplify (has_type bty (uge ty (umax ty y x) x))) (cmp_true bty))
(rule (simplify (has_type bty (ule ty x (umax ty x y)))) (cmp_true bty))
(rule (simplify (has_type bty (ule ty x (umax ty y x)))) (cmp_true bty))

;; x >= min(x, y)
(rule (simplify (sge ty x (smin ty x y))) (cmp_true ty))
(rule (simplify (sge ty x (smin ty y x))) (cmp_true ty))
(rule (simplify (sle ty (smin ty x y) x)) (cmp_true ty))
(rule (simplify (sle ty (smin ty y x) x)) (cmp_true ty))
(rule (simplify (uge ty x (umin ty x y))) (cmp_true ty))
(rule (simplify (uge ty x (umin ty y x))) (cmp_true ty))
(rule (simplify (ule ty (umin ty x y) x)) (cmp_true ty))
(rule (simplify (ule ty (umin ty y x) x)) (cmp_true ty))
(rule (simplify (has_type bty (sge ty x (smin ty x y)))) (cmp_true bty))
(rule (simplify (has_type bty (sge ty x (smin ty y x)))) (cmp_true bty))
(rule (simplify (has_type bty (sle ty (smin ty x y) x))) (cmp_true bty))
(rule (simplify (has_type bty (sle ty (smin ty y x) x))) (cmp_true bty))
(rule (simplify (has_type bty (uge ty x (umin ty x y)))) (cmp_true bty))
(rule (simplify (has_type bty (uge ty x (umin ty y x)))) (cmp_true bty))
(rule (simplify (has_type bty (ule ty (umin ty x y) x))) (cmp_true bty))
(rule (simplify (has_type bty (ule ty (umin ty y x) x))) (cmp_true bty))

;; min/max(x,x) --> x
(rule (simplify (umin ty x x)) x)
Expand Down Expand Up @@ -586,14 +586,17 @@
(rule (simplify (umax ty (umin ty x y) (umax ty y x))) (umax ty x y))

;; x > max(x, y) --> 0
(rule (simplify (sgt ty x (smax ty x y))) (all_zero ty))
(rule (simplify (sgt ty x (smax ty y x))) (all_zero ty))
(rule (simplify (slt ty (smax ty x y) x)) (all_zero ty))
(rule (simplify (slt ty (smax ty y x) x)) (all_zero ty))
(rule (simplify (ugt ty x (umax ty x y))) (all_zero ty))
(rule (simplify (ugt ty x (umax ty y x))) (all_zero ty))
(rule (simplify (ult ty (umax ty x y) x)) (all_zero ty))
(rule (simplify (ult ty (umax ty y x) x)) (all_zero ty))
;;
;; Note: result type `rty` is an i8 for scalars, which may not be the
;; same as the controlling type ty.
(rule (simplify (has_type rty (sgt ty x (smax ty x y)))) (all_zero rty))
(rule (simplify (has_type rty (sgt ty x (smax ty y x)))) (all_zero rty))
(rule (simplify (has_type rty (slt ty (smax ty x y) x))) (all_zero rty))
(rule (simplify (has_type rty (slt ty (smax ty y x) x))) (all_zero rty))
(rule (simplify (has_type rty (ugt ty x (umax ty x y)))) (all_zero rty))
(rule (simplify (has_type rty (ugt ty x (umax ty y x)))) (all_zero rty))
(rule (simplify (has_type rty (ult ty (umax ty x y) x))) (all_zero rty))
(rule (simplify (has_type rty (ult ty (umax ty y x) x))) (all_zero rty))

;; (-X) * C = X * (-C)
(rule imul_ineg_const (simplify (imul (fits_in_64 ty) (ineg ty x) (iconst ty y))) (imul ty x (iconst ty (imm64_neg ty y))))
Expand Down
102 changes: 51 additions & 51 deletions cranelift/codegen/src/opts/bitops.isle
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@

;; Since icmp is always 0 or 1, bmask is just a negation.
;; TODO: Explore whether this makes sense for things needing extension too.
(rule (simplify (bmask $I8 cmp@(icmp $I8 _ _ _)))
(rule (simplify (bmask $I8 cmp@(icmp _ _ _ _)))
(ineg $I8 cmp))

;; Matches any expressions that preserve "truthiness".
Expand All @@ -126,10 +126,10 @@
(rule (simplify (bmask ty v)) (if-let x (truthy v)) (bmask ty x))
(rule (simplify (select ty v t f)) (if-let c (truthy v)) (select ty c t f))
;; (ne ty (iconst 0) v) is also canonicalized into this form via another rule
(rule (simplify (ne cty v (all_zero _)))
(rule (simplify (ne _ v (all_zero _)))
(if-let c (truthy v))
(if-let (value_type (ty_int_ref_scalar_64_extract ty)) c)
(ne cty c (all_zero ty)))
(ne ty c (all_zero ty)))



Expand Down Expand Up @@ -343,24 +343,24 @@
(rule (simplify (bxor ty (bor ty y x) (bnot ty x))) (bor ty x (bnot ty y)))

; (x < y) | (x > y) --> x != y
(rule (simplify (bor ty (slt ty x y) (sgt ty x y))) (ne ty x y))
(rule (simplify (bor ty (sgt ty x y) (slt ty x y))) (ne ty x y))
(rule (simplify (bor ty (slt ty x y) (slt ty y x))) (ne ty x y))
(rule (simplify (bor ty (slt ty y x) (slt ty x y))) (ne ty x y))
(rule (simplify (bor ty (sgt ty y x) (sgt ty x y))) (ne ty x y))
(rule (simplify (bor ty (sgt ty x y) (sgt ty y x))) (ne ty x y))
(rule (simplify (bor ty (sgt ty y x) (slt ty y x))) (ne ty x y))
(rule (simplify (bor ty (slt ty y x) (sgt ty y x))) (ne ty x y))
(rule (simplify (bor _ (slt ty x y) (sgt ty x y))) (ne ty x y))
(rule (simplify (bor _ (sgt ty x y) (slt ty x y))) (ne ty x y))
(rule (simplify (bor _ (slt ty x y) (slt ty y x))) (ne ty x y))
(rule (simplify (bor _ (slt ty y x) (slt ty x y))) (ne ty x y))
(rule (simplify (bor _ (sgt ty y x) (sgt ty x y))) (ne ty x y))
(rule (simplify (bor _ (sgt ty x y) (sgt ty y x))) (ne ty x y))
(rule (simplify (bor _ (sgt ty y x) (slt ty y x))) (ne ty x y))
(rule (simplify (bor _ (slt ty y x) (sgt ty y x))) (ne ty x y))

; (x <_u y) | (x >_u y) --> x != y
(rule (simplify (bor ty (ult ty x y) (ugt ty x y))) (ne ty x y))
(rule (simplify (bor ty (ugt ty x y) (ult ty x y))) (ne ty x y))
(rule (simplify (bor ty (ult ty x y) (ult ty y x))) (ne ty x y))
(rule (simplify (bor ty (ult ty y x) (ult ty x y))) (ne ty x y))
(rule (simplify (bor ty (ugt ty y x) (ugt ty x y))) (ne ty x y))
(rule (simplify (bor ty (ugt ty x y) (ugt ty y x))) (ne ty x y))
(rule (simplify (bor ty (ugt ty y x) (ult ty y x))) (ne ty x y))
(rule (simplify (bor ty (ult ty y x) (ugt ty y x))) (ne ty x y))
(rule (simplify (bor _ (ult ty x y) (ugt ty x y))) (ne ty x y))
(rule (simplify (bor _ (ugt ty x y) (ult ty x y))) (ne ty x y))
(rule (simplify (bor _ (ult ty x y) (ult ty y x))) (ne ty x y))
(rule (simplify (bor _ (ult ty y x) (ult ty x y))) (ne ty x y))
(rule (simplify (bor _ (ugt ty y x) (ugt ty x y))) (ne ty x y))
(rule (simplify (bor _ (ugt ty x y) (ugt ty y x))) (ne ty x y))
(rule (simplify (bor _ (ugt ty y x) (ult ty y x))) (ne ty x y))
(rule (simplify (bor _ (ult ty y x) (ugt ty y x))) (ne ty x y))

; ~((~x) & y) --> x | ~y
(rule (simplify (bnot ty (band ty (bnot ty x) y))) (bor ty x (bnot ty y)))
Expand All @@ -371,28 +371,28 @@
(rule (simplify (bnot ty (bor ty y (bnot ty x)))) (band ty x (bnot ty y)))

; (x <_u y) | (x == y) --> (x <=_u y)
(rule (simplify (bor ty (ult ty x y) (eq ty x y))) (ule ty x y))
(rule (simplify (bor ty (eq ty x y) (ult ty x y))) (ule ty x y))
(rule (simplify (bor ty (ult ty x y) (eq ty y x))) (ule ty x y))
(rule (simplify (bor ty (eq ty y x) (ult ty x y))) (ule ty x y))
(rule (simplify (bor _ (ult ty x y) (eq ty x y))) (ule ty x y))
(rule (simplify (bor _ (eq ty x y) (ult ty x y))) (ule ty x y))
(rule (simplify (bor _ (ult ty x y) (eq ty y x))) (ule ty x y))
(rule (simplify (bor _ (eq ty y x) (ult ty x y))) (ule ty x y))

; (y >_u x) | (x == y) --> (x <=_u y)
(rule (simplify (bor ty (ugt ty y x) (eq ty x y))) (ule ty x y))
(rule (simplify (bor ty (eq ty x y) (ugt ty y x))) (ule ty x y))
(rule (simplify (bor ty (ugt ty y x) (eq ty y x))) (ule ty x y))
(rule (simplify (bor ty (eq ty y x) (ugt ty y x))) (ule ty x y))
(rule (simplify (bor _ (ugt ty y x) (eq ty x y))) (ule ty x y))
(rule (simplify (bor _ (eq ty x y) (ugt ty y x))) (ule ty x y))
(rule (simplify (bor _ (ugt ty y x) (eq ty y x))) (ule ty x y))
(rule (simplify (bor _ (eq ty y x) (ugt ty y x))) (ule ty x y))

; (x < y) | (x == y) --> (x <= y)
(rule (simplify (bor ty (slt ty x y) (eq ty x y))) (sle ty x y))
(rule (simplify (bor ty (eq ty x y) (slt ty x y))) (sle ty x y))
(rule (simplify (bor ty (slt ty x y) (eq ty y x))) (sle ty x y))
(rule (simplify (bor ty (eq ty y x) (slt ty x y))) (sle ty x y))
(rule (simplify (bor _ (slt ty x y) (eq ty x y))) (sle ty x y))
(rule (simplify (bor _ (eq ty x y) (slt ty x y))) (sle ty x y))
(rule (simplify (bor _ (slt ty x y) (eq ty y x))) (sle ty x y))
(rule (simplify (bor _ (eq ty y x) (slt ty x y))) (sle ty x y))

; (y > x) | (x == y) --> (x <= y)
(rule (simplify (bor ty (sgt ty y x) (eq ty x y))) (sle ty x y))
(rule (simplify (bor ty (eq ty x y) (sgt ty y x))) (sle ty x y))
(rule (simplify (bor ty (sgt ty y x) (eq ty y x))) (sle ty x y))
(rule (simplify (bor ty (eq ty y x) (sgt ty y x))) (sle ty x y))
(rule (simplify (bor _ (sgt ty y x) (eq ty x y))) (sle ty x y))
(rule (simplify (bor _ (eq ty x y) (sgt ty y x))) (sle ty x y))
(rule (simplify (bor _ (sgt ty y x) (eq ty y x))) (sle ty x y))
(rule (simplify (bor _ (eq ty y x) (sgt ty y x))) (sle ty x y))

; (x ^ z) | (((x ^ z) ^ y)) --> (x ^ z) | y
(rule (simplify (bor ty (bxor ty x z) (bxor ty (bxor ty x z) y))) (bor ty (bxor ty x z) y))
Expand Down Expand Up @@ -760,24 +760,24 @@
(subsume (all_zero ty)))

;; x >=u (x & y) --> true
(rule (simplify (uge rty x (band ty x y))) (cmp_true rty))
(rule (simplify (uge rty x (band ty y x))) (cmp_true rty))
(rule (simplify (ule rty (band ty x y) x)) (cmp_true rty))
(rule (simplify (ule rty (band ty y x) x)) (cmp_true rty))
(rule (simplify (ugt rty (band ty x y) x)) (subsume (all_zero rty)))
(rule (simplify (ugt rty (band ty y x) x)) (subsume (all_zero rty)))
(rule (simplify (ult rty x (band ty x y))) (subsume (all_zero rty)))
(rule (simplify (ult rty x (band ty y x))) (subsume (all_zero rty)))
(rule (simplify (has_type rty (uge _ x (band ty x y)))) (cmp_true rty))
(rule (simplify (has_type rty (uge _ x (band ty y x)))) (cmp_true rty))
(rule (simplify (has_type rty (ule _ (band ty x y) x))) (cmp_true rty))
(rule (simplify (has_type rty (ule _ (band ty y x) x))) (cmp_true rty))
(rule (simplify (has_type rty (ugt _ (band ty x y) x))) (subsume (all_zero rty)))
(rule (simplify (has_type rty (ugt _ (band ty y x) x))) (subsume (all_zero rty)))
(rule (simplify (has_type rty (ult _ x (band ty x y)))) (subsume (all_zero rty)))
(rule (simplify (has_type rty (ult _ x (band ty y x)))) (subsume (all_zero rty)))

;; (x | y) >=u x --> true
(rule (simplify (uge rty (bor ty x y) x)) (cmp_true rty))
(rule (simplify (uge rty (bor ty y x) x)) (cmp_true rty))
(rule (simplify (ule rty x (bor ty x y))) (cmp_true rty))
(rule (simplify (ule rty x (bor ty y x))) (cmp_true rty))
(rule (simplify (ult rty (bor ty x y) x)) (subsume (all_zero rty)))
(rule (simplify (ult rty (bor ty y x) x)) (subsume (all_zero rty)))
(rule (simplify (ugt rty x (bor ty x y))) (subsume (all_zero rty)))
(rule (simplify (ugt rty x (bor ty y x))) (subsume (all_zero rty)))
(rule (simplify (has_type rty (uge _ (bor ty x y) x))) (cmp_true rty))
(rule (simplify (has_type rty (uge _ (bor ty y x) x))) (cmp_true rty))
(rule (simplify (has_type rty (ule _ x (bor ty x y)))) (cmp_true rty))
(rule (simplify (has_type rty (ule _ x (bor ty y x)))) (cmp_true rty))
(rule (simplify (has_type rty (ult _ (bor ty x y) x))) (subsume (all_zero rty)))
(rule (simplify (has_type rty (ult _ (bor ty y x) x))) (subsume (all_zero rty)))
(rule (simplify (has_type rty (ugt _ x (bor ty x y)))) (subsume (all_zero rty)))
(rule (simplify (has_type rty (ugt _ x (bor ty y x)))) (subsume (all_zero rty)))

;; (x & y) & (x & z) --> (x & y) & z
(rule (simplify (band ty (band ty x y) (band ty x z))) (band ty (band ty x y) z))
Expand Down
9 changes: 5 additions & 4 deletions cranelift/codegen/src/opts/cprop.isle
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,11 @@
(subsume (iconst_s wide k)))

(rule (simplify
(icmp result_ty
cc
(iconst ty k1)
(iconst ty k2)))
(has_type result_ty
(icmp ty
cc
(iconst ty k1)
(iconst ty k2))))
(subsume (iconst result_ty (imm64_icmp ty cc k1 k2))))


Expand Down
Loading
Loading