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
34 changes: 34 additions & 0 deletions cranelift/codegen/src/opts/icmp.isle
Original file line number Diff line number Diff line change
Expand Up @@ -376,3 +376,37 @@
(simplify (band ty (ult ty x y) (ne ty (iconst_s _ -1) x)))
(ult ty x y))

;; icmp on select with two constant inputs compared with one of the two
;; constants can directly use the inner select condition.
;; See: https://github.com/bytecodealliance/wasmtime/issues/11578
(rule (simplify (eq _
(select select_ty inner_cond
(iconst_u _ k1)
(iconst_u _ k2))
(iconst_u _ k1)))
(if-let false (u64_eq k1 k2))
(ne select_ty inner_cond (iconst_u select_ty 0)))

(rule (simplify (eq _
(select select_ty inner_cond
(iconst_u _ k1)
(iconst_u _ k2))
(iconst_u _ k2)))
(if-let false (u64_eq k1 k2))
(eq select_ty inner_cond (iconst_u select_ty 0)))

(rule (simplify (ne _
(select select_ty inner_cond
(iconst_u _ k1)
(iconst_u _ k2))
(iconst_u _ k1)))
(if-let false (u64_eq k1 k2))
(eq select_ty inner_cond (iconst_u select_ty 0)))

(rule (simplify (ne _
(select select_ty inner_cond
(iconst_u _ k1)
(iconst_u _ k2))
(iconst_u _ k2)))
(if-let false (u64_eq k1 k2))
(ne select_ty inner_cond (iconst_u select_ty 0)))
127 changes: 127 additions & 0 deletions cranelift/filetests/filetests/egraph/issue-11578-opt.clif
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
test optimize
set opt_level=speed
target x86_64
target aarch64

function %eq_k1(i64) -> i8 {
block0(v2: i64):
v14 = iconst.i64 -562949953421310
v3 = band v2, v14
v16 = iconst.i64 0
v4 = icmp eq v3, v16
v5 = iconst.i64 6
v6 = iconst.i64 7
v7 = select v4, v5, v6
v8 = icmp eq v7, v5
return v8
}

; check: function %eq_k1(i64) -> i8 fast {
; check: block0(v2: i64):
; nextln: v14 = iconst.i64 -562949953421310
; nextln: v3 = band v2, v14
; nextln: v16 = iconst.i64 0
; nextln: v4 = icmp eq v3, v16
; nextln: return v4
; nextln: }

function %eq_k2(i64) -> i8 {
block0(v2: i64):
v14 = iconst.i64 -562949953421310
v3 = band v2, v14
v16 = iconst.i64 0
v4 = icmp eq v3, v16
v5 = iconst.i64 6
v6 = iconst.i64 7
v7 = select v4, v5, v6
v8 = icmp eq v7, v6
return v8
}

; check: function %eq_k2(i64) -> i8 fast {
; check: block0(v2: i64):
; nextln: v14 = iconst.i64 -562949953421310
; nextln: v3 = band v2, v14 ; v14 = -562949953421310
; nextln: v16 = iconst.i64 0
; nextln: v18 = icmp ne v3, v16 ; v16 = 0
; nextln: return v18
; nextln: }

function %ne_k1(i64) -> i8 {
block0(v2: i64):
v14 = iconst.i64 -562949953421310
v3 = band v2, v14
v16 = iconst.i64 0
v4 = icmp eq v3, v16
v5 = iconst.i64 6
v6 = iconst.i64 7
v7 = select v4, v5, v6
v8 = icmp ne v7, v5
return v8
}

; check: function %ne_k1(i64) -> i8 fast {
; check: block0(v2: i64):
; nextln: v14 = iconst.i64 -562949953421310
; nextln: v3 = band v2, v14 ; v14 = -562949953421310
; nextln: v16 = iconst.i64 0
; nextln: v18 = icmp ne v3, v16 ; v16 = 0
; nextln: return v18
; nextln: }

function %ne_k2(i64) -> i8 {
block0(v2: i64):
v14 = iconst.i64 -562949953421310
v3 = band v2, v14
v16 = iconst.i64 0
v4 = icmp eq v3, v16
v5 = iconst.i64 6
v6 = iconst.i64 7
v7 = select v4, v5, v6
v8 = icmp ne v7, v6
return v8
}

; check: function %ne_k2(i64) -> i8 fast {
; check: block0(v2: i64):
; nextln: v14 = iconst.i64 -562949953421310
; nextln: v3 = band v2, v14
; nextln: v16 = iconst.i64 0
; nextln: v4 = icmp eq v3, v16
; nextln: return v4
; nextln: }

; select x, k1, k1 should be constant propagated
function %constant_propagated(i64) -> i8 {
block0(v2: i64):
v14 = iconst.i64 -562949953421310
v3 = band v2, v14
v16 = iconst.i64 0
v4 = icmp eq v3, v16
v5 = iconst.i64 6
v6 = select v4, v5, v5
v7 = icmp eq v6, v5
return v7
}

; check: function %constant_propagated(i64) -> i8 fast {
; check: block0(v2: i64):
; nextln: v17 = iconst.i8 1
; nextln: return v17
; nextln: }

function %a(i64) -> i8 {
block0(v0: i64):
v1 = iconst.i64 6
v3 = iconst.i64 7
v4 = select v0, v1, v3
v5 = icmp eq v4, v1
return v5
}

; check: function %a(i64) -> i8 fast {
; check: block0(v0: i64):
; nextln: v6 = iconst.i64 0
; nextln: v7 = icmp ne v0, v6 ; v6 = 0
; nextln: return v7
; nextln: }
96 changes: 96 additions & 0 deletions cranelift/filetests/filetests/egraph/issue-11578-semantics.clif
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
test interpret
test run
set opt_level=none
target x86_64
target aarch64
set opt_level=speed
target x86_64
target aarch64

function %eq_k1(i64) -> i8 {
block0(v2: i64):
v14 = iconst.i64 -562949953421310
v3 = band v2, v14
v16 = iconst.i64 0
v4 = icmp eq v3, v16
v5 = iconst.i64 6
v6 = iconst.i64 7
v7 = select v4, v5, v6
v8 = icmp eq v7, v5
return v8
}

; run: %eq_k1(0) == 1

function %eq_k2(i64) -> i8 {
block0(v2: i64):
v14 = iconst.i64 -562949953421310
v3 = band v2, v14
v16 = iconst.i64 0
v4 = icmp eq v3, v16
v5 = iconst.i64 6
v6 = iconst.i64 7
v7 = select v4, v5, v6
v8 = icmp eq v7, v6
return v8
}

; run: %eq_k2(0) == 0

function %ne_k1(i64) -> i8 {
block0(v2: i64):
v14 = iconst.i64 -562949953421310
v3 = band v2, v14
v16 = iconst.i64 0
v4 = icmp eq v3, v16
v5 = iconst.i64 6
v6 = iconst.i64 7
v7 = select v4, v5, v6
v8 = icmp ne v7, v5
return v8
}

; run: %ne_k1(0) == 0

function %ne_k2(i64) -> i8 {
block0(v2: i64):
v14 = iconst.i64 -562949953421310
v3 = band v2, v14
v16 = iconst.i64 0
v4 = icmp eq v3, v16
v5 = iconst.i64 6
v6 = iconst.i64 7
v7 = select v4, v5, v6
v8 = icmp ne v7, v6
return v8
}

; run: %ne_k2(0) == 1

; select x, k1, k1 should be constant propagated
function %constant_propagated(i64) -> i8 {
block0(v2: i64):
v14 = iconst.i64 -562949953421310
v3 = band v2, v14
v16 = iconst.i64 0
v4 = icmp eq v3, v16
v5 = iconst.i64 6
v6 = select v4, v5, v5
v7 = icmp eq v6, v5
return v7
}

; run: %constant_propagated(0) == 1

function %non_icmp_inner(i64) -> i8 {
block0(v0: i64):
v1 = iconst.i64 6
v3 = iconst.i64 7
v4 = select v0, v1, v3
v5 = icmp eq v4, v1
return v5
}

; run: %non_icmp_inner(0) == 0
; run: %non_icmp_inner(1) == 1
; run: %non_icmp_inner(5) == 1