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
22 changes: 22 additions & 0 deletions cranelift/codegen/src/opts/icmp.isle
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,28 @@
(if-let signed (intcc_comparable cc1 cc2))
(compose_icmp ty (u64_or (decompose_intcc cc1) (decompose_intcc cc2)) signed x y))

;; Prefer comparing against zero
;; uge(x, 1) == ne(x, 0)
(rule (simplify (uge ty x (iconst cty (u64_from_imm64 1))))
(ne ty x (iconst cty (imm64 0))))
;; ult(x, 1) == eq(x, 0)
(rule (simplify (ult ty x (iconst cty (u64_from_imm64 1))))
(eq ty x (iconst cty (imm64 0))))
;; sge(x, 1) == sgt(x, 0)
(rule (simplify (sge ty x (iconst cty (u64_from_imm64 1))))
(sgt ty x (iconst cty (imm64 0))))
;; slt(x, 1) == sle(x, 0)
(rule (simplify (slt ty x (iconst cty (u64_from_imm64 1))))
(sle ty x (iconst cty (imm64 0))))
;; sgt(x, -1) == sge(x, 0)
(rule (simplify (sgt ty x (iconst cty c)))
(if-let -1 (i64_sextend_imm64 cty c))
(sge ty x (iconst cty (imm64 0))))
;; sle(x, -1) == slt(x, 0)
(rule (simplify (sle ty x (iconst cty c)))
(if-let -1 (i64_sextend_imm64 cty c))
(slt ty x (iconst cty (imm64 0))))

(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)))
Expand Down
17 changes: 17 additions & 0 deletions cranelift/codegen/src/opts/selects.isle
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@
(rule (simplify (select ty _ x x)) x)
(rule (simplify (bitselect ty _ x x)) x)

;; if icmp(x, y) { 1 } else { 0 } => uextend(icmp(x, y))
(rule (simplify (select ty cmp@(icmp _ cc x y)
(iconst _ (u64_from_imm64 1))
(iconst _ (u64_from_imm64 0))))
(uextend_from_i8 ty cmp))
;; if icmp(x, y) { 0 } else { 1 } => uextend(!icmp(x, y))
(rule (simplify (select sty (icmp cty cc x y)
(iconst _ (u64_from_imm64 0))
(iconst _ (u64_from_imm64 1))))
(uextend_from_i8 sty (icmp cty (intcc_complement cc) 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 Expand Up @@ -57,3 +68,9 @@
(rule (simplify (bor (ty_vec128 ty) (band ty (bnot ty c) y) (band ty x c))) (bitselect ty c x y))
(rule (simplify (bor (ty_vec128 ty) (band ty y (bnot ty c)) (band ty c x))) (bitselect ty c x y))
(rule (simplify (bor (ty_vec128 ty) (band ty y (bnot ty c)) (band ty x c))) (bitselect ty c x y))

;; extend from i8 to i8 is invalid CLIF, so this allows fixing that in the output
;; rather than needing to duplicate rules for the different width categories
(decl uextend_from_i8 (Type Value) Value)
(rule 0 (uextend_from_i8 ty val) (uextend ty val))
(rule 1 (uextend_from_i8 $I8 val) val)
12 changes: 6 additions & 6 deletions cranelift/filetests/filetests/egraph/icmp-parameterized.clif
Original file line number Diff line number Diff line change
Expand Up @@ -567,9 +567,9 @@ block0(v0: i32):

; function %icmp_sle_umax(i32) -> i8 fast {
; block0(v0: i32):
; v1 = iconst.i32 0xffff_ffff
; v2 = icmp sle v0, v1 ; v1 = 0xffff_ffff
; return v2
; v3 = iconst.i32 0
; v4 = icmp slt v0, v3 ; v3 = 0
; return v4
; }

function %icmp_sle_smin(i32) -> i8 {
Expand Down Expand Up @@ -622,9 +622,9 @@ block0(v0: i32):

; function %icmp_sgt_umax(i32) -> i8 fast {
; block0(v0: i32):
; v1 = iconst.i32 0xffff_ffff
; v2 = icmp sgt v0, v1 ; v1 = 0xffff_ffff
; return v2
; v3 = iconst.i32 0
; v4 = icmp sge v0, v3 ; v3 = 0
; return v4
; }

function %icmp_sgt_smin(i32) -> i8 {
Expand Down
56 changes: 56 additions & 0 deletions cranelift/filetests/filetests/egraph/icmp.clif
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,59 @@ block0:
; v5 = icmp ne v2, v3 ; v3 = 0
; return v5
; }

function %sge_one(i64) -> i8 {
block0(v0: i64):
v1 = iconst.i64 1
v2 = icmp sge v0, v1
return v2
}

; function %sge_one(i64) -> i8 fast {
; block0(v0: i64):
; v3 = iconst.i64 0
; v4 = icmp sgt v0, v3 ; v3 = 0
; return v4
; }

function %slt_one(i16) -> i8 {
block0(v0: i16):
v1 = iconst.i16 1
v2 = icmp slt v0, v1
return v2
}

; function %slt_one(i16) -> i8 fast {
; block0(v0: i16):
; v3 = iconst.i16 0
; v4 = icmp sle v0, v3 ; v3 = 0
; return v4
; }

function %uge_one(i32) -> i8 {
block0(v0: i32):
v1 = iconst.i32 1
v2 = icmp uge v0, v1
return v2
}

; function %uge_one(i32) -> i8 fast {
; block0(v0: i32):
; v3 = iconst.i32 0
; v4 = icmp ne v0, v3 ; v3 = 0
; return v4
; }

function %ult_one(i8) -> i8 {
block0(v0: i8):
v1 = iconst.i8 1
v2 = icmp ult v0, v1
return v2
}

; function %ult_one(i8) -> i8 fast {
; block0(v0: i8):
; v3 = iconst.i8 0
; v4 = icmp eq v0, v3 ; v3 = 0
; return v4
; }
44 changes: 44 additions & 0 deletions cranelift/filetests/filetests/egraph/select.clif
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,47 @@ block0(v0: i32, v1: i32, v2: i32, v3: i32):
; check: v4 = icmp ule v0, v1
; check: v5 = select v4, v2, v3
; check: return v5

function %then_true_else_false(i32, i32) -> i8 {
block0(v0: i32, v1: i32):
v2 = icmp ule v0, v1
v3 = iconst.i8 1
v4 = iconst.i8 0
v5 = select v2, v3, v4
return v5
}
; check: return v2

function %then_false_else_true(i32, i32) -> i8 {
block0(v0: i32, v1: i32):
v2 = icmp slt v0, v1
v3 = iconst.i8 0
v4 = iconst.i8 1
v5 = select v2, v3, v4
return v5
}
; check: v6 = icmp sge v0, v1
; check: return v6

function %then_one_else_zero(i32, i32) -> i64 {
block0(v0: i32, v1: i32):
v2 = icmp ule v0, v1
v3 = iconst.i64 1
v4 = iconst.i64 0
v5 = select v2, v3, v4
return v5
}
; check: v6 = uextend.i64 v2
; check: return v6

function %then_zero_else_false(i32, i32) -> i64 {
block0(v0: i32, v1: i32):
v2 = icmp slt v0, v1
v3 = iconst.i64 0
v4 = iconst.i64 1
v5 = select v2, v3, v4
return v5
}
; check: v6 = icmp sge v0, v1
; check: v7 = uextend.i64 v6
; check: return v7