Skip to content
Open
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
9 changes: 9 additions & 0 deletions cranelift/codegen/src/opts/arithmetic.isle
Original file line number Diff line number Diff line change
Expand Up @@ -568,3 +568,12 @@

;; (-X) * C = X * (-C)
(rule (simplify (imul (fits_in_64 ty) (ineg ty x) (iconst ty y))) (imul ty x (iconst ty (imm64_neg ty y))))

;; -(~x) --> x + 1
(rule (simplify (ineg ty (bnot ty x))) (iadd ty x (iconst_u ty 1)))

;; ~(-x) --> x - 1.
(rule (simplify (bnot ty (ineg ty x))) (isub ty x (iconst_u ty 1)))

;; -1 - x --> ~x
(rule (simplify (isub ty (iconst_s ty -1) x)) (bnot ty x))
12 changes: 10 additions & 2 deletions cranelift/codegen/src/opts/bitops.isle
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,17 @@
(iconst_u ty 0)))
(subsume x))

;; Create an all-zero bit pattern for integer, float, and vector types.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add an all-zero helper for float and vector types.

(decl rec all_zero (Type) Value)
(rule 0 (all_zero (ty_int ty)) (iconst_u ty 0))
(rule 1 (all_zero $F32) (f32const $F32 (f32_from_uint 0)))
(rule 2 (all_zero $F64) (f64const $F64 (f64_from_uint 0)))
(rule 3 (all_zero (ty_vec64 ty)) (splat ty (all_zero (lane_type ty))))
(rule 4 (all_zero (ty_vec128 ty)) (splat ty (all_zero (lane_type ty))))
Comment on lines +22 to +23

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it more efficient to load zeros by splatting than via loads from the constant pool?

It seems like we don't have any terms in the mid-end's prelude for working with ir::Constants, but they would be easy to add if necessary.

But if splatting is expected to be more efficient, then we should add a comment to that effect here.


;; x ^ x == 0.
(rule (simplify (bxor (ty_int ty) x x))
(subsume (iconst_u ty 0)))
(rule (simplify (bxor ty x x))
Comment thread
fitzgen marked this conversation as resolved.
(subsume (all_zero ty)))

;; 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.
Expand Down
3 changes: 3 additions & 0 deletions cranelift/codegen/src/opts/extends.isle
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,6 @@
;; Try to transform an `iconcat` into an i128 into either an sextend or uextend
(rule (simplify (iconcat $I128 x (iconst_u _ 0))) (uextend $I128 x))
(rule (simplify (iconcat $I128 x (sshr _ x (iconst_u _ 63)))) (sextend $I128 x))

;; Select narrowest type
(rule (simplify (ireduce ty (ireduce cty x))) (ireduce ty x))
26 changes: 16 additions & 10 deletions cranelift/codegen/src/opts/icmp.isle
Original file line number Diff line number Diff line change
Expand Up @@ -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 (ty_int ty) x x)) (subsume (iconst_u ty 1)))
(rule (simplify (ne (ty_int ty) x x)) (subsume (iconst_u ty 0)))
(rule (simplify (ugt (ty_int ty) x x)) (subsume (iconst_u ty 0)))
(rule (simplify (uge (ty_int ty) x x)) (subsume (iconst_u ty 1)))
(rule (simplify (sgt (ty_int ty) x x)) (subsume (iconst_u ty 0)))
(rule (simplify (sge (ty_int ty) x x)) (subsume (iconst_u ty 1)))
(rule (simplify (ult (ty_int ty) x x)) (subsume (iconst_u ty 0)))
(rule (simplify (ule (ty_int ty) x x)) (subsume (iconst_u ty 1)))
(rule (simplify (slt (ty_int ty) x x)) (subsume (iconst_u ty 0)))
(rule (simplify (sle (ty_int ty) x x)) (subsume (iconst_u ty 1)))
(rule (simplify (eq ty x x)) (subsume (cmp_true ty)))
(rule (simplify (ne ty x x)) (subsume (iconst_u ty 0)))
(rule (simplify (ugt ty x x)) (subsume (iconst_u ty 0)))
(rule (simplify (uge ty x x)) (subsume (cmp_true ty)))
(rule (simplify (sgt ty x x)) (subsume (iconst_u ty 0)))
(rule (simplify (sge ty x x)) (subsume (cmp_true ty)))
(rule (simplify (ult ty x x)) (subsume (iconst_u ty 0)))
(rule (simplify (ule ty x x)) (subsume (cmp_true ty)))
(rule (simplify (slt ty x x)) (subsume (iconst_u ty 0)))
(rule (simplify (sle ty x x)) (subsume (cmp_true ty)))

;; For integers, adding the same thing on both sides of an equality check
;; (or an inequality check) doesn't change the result.
Expand Down Expand Up @@ -474,3 +474,9 @@

(rule (simplify_skeleton (brif (ireduce _ (clz x_ty x)) _ _))
(replace_branch_cond (sge $I8 x (iconst_u x_ty 0))))

;; ~x == x --> 0
(rule (simplify (eq ty (bnot cty x) x)) (subsume (iconst_u ty 0)))

;; ~x != x --> 1
(rule (simplify (ne ty (bnot cty x) x)) (subsume (cmp_true ty)))
12 changes: 12 additions & 0 deletions cranelift/codegen/src/opts/shifts.isle
Original file line number Diff line number Diff line change
Expand Up @@ -315,3 +315,15 @@
(rule (simplify (iadd ty (ishl ty x z) (ishl ty y z))) (ishl ty (iadd ty x y) z))

(rule (simplify (ushr ty (band ty (ishl ty x y) z) y)) (band ty x (ushr ty z y)))

;; Zero remains zero for any shift or rotate amount.
(rule (simplify (ishl ty (iconst_u ty 0) x)) (subsume (iconst_u ty 0)))
(rule (simplify (ushr ty (iconst_u ty 0) x)) (subsume (iconst_u ty 0)))
(rule (simplify (sshr ty (iconst_u ty 0) x)) (subsume (iconst_u ty 0)))
(rule (simplify (rotl ty (iconst_u ty 0) x)) (subsume (iconst_u ty 0)))
(rule (simplify (rotr ty (iconst_u ty 0) x)) (subsume (iconst_u ty 0)))

;; All ones remain all ones for arithmetic right shifts or rotates.
(rule (simplify (sshr ty (iconst_s ty -1) x)) (subsume (iconst_s ty -1)))
(rule (simplify (rotl ty (iconst_s ty -1) x)) (subsume (iconst_s ty -1)))
(rule (simplify (rotr ty (iconst_s ty -1) x)) (subsume (iconst_s ty -1)))
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,8 @@ block0(v0: i32x4, v1: i32x4):
; const0 = 0xffffffffffffffffffffffffffffffff
;
; block0(v0: i32x4, v1: i32x4):
; v9 = icmp eq v0, v0
; return v9
; v7 = vconst.i32x4 const0
; return v7 ; v7 = const0
; }

;; (x - y) != x --> y != 0
Expand Down
21 changes: 21 additions & 0 deletions cranelift/filetests/filetests/egraph/arithmetic.clif
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,17 @@ block0(v0: i32):
; check: v6 = ineg v0
; check: return v6

function %ineg_bnot_to_iadd_one(i32) -> i32 {
block0(v0: i32):
v1 = bnot v0
v2 = ineg v1
return v2
}

; check: v3 = iconst.i32 1
; check: v4 = iadd v0, v3 ; v3 = 1
; check: return v4

function %byte_sub_smax_twice(i8) -> i8 {
block0(v0: i8):
v1 = iconst.i8 127
Expand Down Expand Up @@ -464,3 +475,13 @@ block0(v0: i64):
; check: v6 = iadd v4, v5
; check: return v6
}

;; -1 - x --> ~x
function %isub_minus_one_lhs_to_bnot(i32) -> i32 {
block0(v0: i32):
v1 = iconst.i32 -1
v2 = isub v1, v0
return v2
; check: v12 = bnot v0
; check: return v12
}
74 changes: 74 additions & 0 deletions cranelift/filetests/filetests/egraph/bitops.clif
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,54 @@ block0(v1: i64):
; check: v5 = bnot v1
; check: return v5

function %bxor_x_x_f32(f32) -> f32 {
block0(v0: f32):
v1 = bxor v0, v0
return v1
}

; check: v2 = f32const 0.0
; check: return v2

function %bxor_x_x_f64(f64) -> f64 {
block0(v0: f64):
v1 = bxor v0, v0
return v1
}

; check: v2 = f64const 0.0
; check: return v2

function %vector_bxor_x_x_f32x4(f32x4) -> f32x4 {
block0(v0: f32x4):
v1 = bxor v0, v0
return v1
}

; check: const0 = 0x00000000000000000000000000000000
; check: v4 = vconst.f32x4 const0
; check: return v4

function %vector_bxor_x_x_f64x2(f64x2) -> f64x2 {
block0(v0: f64x2):
v1 = bxor v0, v0
return v1
}

; check: const0 = 0x00000000000000000000000000000000
; check: v4 = vconst.f64x2 const0
; check: return v4

function %vector_bxor_x_x_f32x2(f32x2) -> f32x2 {
block0(v0: f32x2):
v1 = bxor v0, v0
return v1
}

; check: f32const 0.0
; check: splat.f32x2
; check: return

function %vector_bxor_x_bnot_x(i32x4) -> i32x4 {
block0(v0: i32x4):
v1 = bnot v0
Expand All @@ -160,6 +208,17 @@ block0(v0: i32x4):
; check: v5 = vconst.i32x4 const0
; check: return v5

function %vector_bxor_bnot_x_bnot_x(i32x4) -> i32x4 {
block0(v0: i32x4):
v1 = bnot v0
v2 = bxor v1, v1
return v2
}

; check: const0 = 0x00000000000000000000000000000000
; check: v5 = vconst.i32x4 const0
; check: return v5

function %vector_bor_x_bnot_x(i32x4) -> i32x4 {
block0(v0: i32x4):
v1 = bnot v0
Expand Down Expand Up @@ -803,6 +862,21 @@ block0(v0: i32, v1: i32):
; return v5
; }

;; (bnot ty (ineg ty x)) -> (isub ty x (iconst_u ty 1))
function %test_bnot_ineg_to_isub_one(i32) -> i32 fast {
block0(v0: i32):
v1 = ineg v0
v2 = bnot v1
return v2
}

; function %test_bnot_ineg_to_isub_one(i32) -> i32 fast {
; block0(v0: i32):
; v3 = iconst.i32 1
; v4 = isub v0, v3
; return v4
; }

;; (bor ty (bxor ty x z) (bor ty y x)) -> (bor ty (bor ty y x) z)
function %test_bor_bxor_bor(i32, i32, i32) -> i32 fast {
block0(v0: i32, v1: i32, v2: i32):
Expand Down
10 changes: 10 additions & 0 deletions cranelift/filetests/filetests/egraph/extends.clif
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,16 @@ block0(v1: i16):
; check: v4 = uextend.i32 v1
; check: return v4

function %nested_ireduce(i64) -> i8 {
block0(v1: i64):
v2 = ireduce.i32 v1
v3 = ireduce.i8 v2
return v3
}

; check: v4 = ireduce.i8 v1
; check: return v4

function %sextend_then_slt_zero(i8) -> i8 {
block0(v0: i8):
v1 = sextend.i16 v0
Expand Down
10 changes: 6 additions & 4 deletions cranelift/filetests/filetests/egraph/i128-opts.clif
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,18 @@ 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
; check: const0 = 0xffffffffffffffffffffffffffffffff
; check: v4 = vconst.i8x16 const0
; check: return v4 ; v4 = const0
}

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
; check: const0 = 0x00000000000000000000000000000000
; check: v4 = vconst.i8x16 const0
; check: return v4 ; v4 = const0
}

function %bor_extended_constants_i128() -> i128 {
Expand Down
28 changes: 28 additions & 0 deletions cranelift/filetests/filetests/egraph/icmp.clif
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,34 @@ block0(v0: i32, v1: i32):
; return v5
; }

;; `~x == x` to false.
function %simplify_icmp_eq_bnot_x_x(i32) -> i8 fast {
block0(v0: i32):
v1 = bnot v0
v2 = icmp eq v1, v0
return v2
}

; function %simplify_icmp_eq_bnot_x_x(i32) -> i8 fast {
; block0(v0: i32):
; v3 = iconst.i8 0
; return v3 ; v3 = 0
; }

;; `~x != x` to true.
function %simplify_icmp_ne_bnot_x_x(i32) -> i8 fast {
block0(v0: i32):
v1 = bnot v0
v2 = icmp ne v1, v0
return v2
}

; function %simplify_icmp_ne_bnot_x_x(i32) -> i8 fast {
; block0(v0: i32):
; v3 = iconst.i8 1
; return v3 ; v3 = 1
; }

function %issue_10929_no_crash_on_icmp_vectors() -> i32x4 {
const0 = 0x40ad3fb47cb16076c8cb1fdd8189d40f

Expand Down
63 changes: 63 additions & 0 deletions cranelift/filetests/filetests/egraph/shifts.clif
Original file line number Diff line number Diff line change
Expand Up @@ -606,3 +606,66 @@ block0(v0: i64):
v2 = ishl v0, v1
return v2
}
function %ishl_zero_left_operand(i64) -> i64 {
block0(v0: i64):
v1 = iconst.i64 0
v2 = ishl v1, v0
return v2
; check: return v1
}
function %ushr_zero_left_operand(i64) -> i64 {
block0(v0: i64):
v1 = iconst.i64 0
v2 = ushr v1, v0
return v2
; check: return v1
}
function %rotl_zero_left_operand(i64) -> i64 {
block0(v0: i64):
v1 = iconst.i64 0
v2 = rotl v1, v0
return v2
; check: return v1
}
function %rotr_zero_left_operand(i64) -> i64 {
block0(v0: i64):
v1 = iconst.i64 0
v2 = rotr v1, v0
return v2
; check: return v1
}
function %rotl_const_multiple_of_64(i64) -> i64 {
block0(v0: i64):
v1 = iconst.i64 128
v2 = rotl v0, v1
return v2
; check: return v0
}
function %sshr_all_ones_left_operand(i64) -> i64 {
block0(v0: i64):
v1 = iconst.i64 -1
v2 = sshr v1, v0
return v2
; check: return v1
}
function %rotl_all_ones_left_operand(i64) -> i64 {
block0(v0: i64):
v1 = iconst.i64 -1
v2 = rotl v1, v0
return v2
; check: return v1
}
function %rotr_all_ones_left_operand(i64) -> i64 {
block0(v0: i64):
v1 = iconst.i64 -1
v2 = rotr v1, v0
return v2
; check: return v1
}
function %sshr_zero_left_operand(i64) -> i64 {
block0(v0: i64):
v1 = iconst.i64 0
v2 = sshr v1, v0
return v2
; check: return v1
}
12 changes: 12 additions & 0 deletions cranelift/filetests/filetests/runtests/arithmetic.clif
Original file line number Diff line number Diff line change
Expand Up @@ -1065,3 +1065,15 @@ block0(v0: i64):
; run: %fold_bnot_iadd_neg_const_i64_rt(7) == -1
; run: %fold_bnot_iadd_neg_const_i64_rt(-1) == 7
; run: %fold_bnot_iadd_neg_const_i64_rt(0x80000000_00000000) == 0x80000000_00000006

function %fold_isub_minus_one_lhs_to_bnot_i32_rt(i32) -> i32 fast {
block0(v0: i32):
v1 = iconst.i32 -1
v2 = isub v1, v0
return v2
}

; run: %fold_isub_minus_one_lhs_to_bnot_i32_rt(0) == -1
; run: %fold_isub_minus_one_lhs_to_bnot_i32_rt(1) == -2
; run: %fold_isub_minus_one_lhs_to_bnot_i32_rt(-1) == 0
; run: %fold_isub_minus_one_lhs_to_bnot_i32_rt(0x7fffffff) == 0x80000000
Loading
Loading