diff --git a/cranelift/codegen/src/opts/arithmetic.isle b/cranelift/codegen/src/opts/arithmetic.isle index 07faaba82148..5cfd071a3acb 100644 --- a/cranelift/codegen/src/opts/arithmetic.isle +++ b/cranelift/codegen/src/opts/arithmetic.isle @@ -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)) \ No newline at end of file diff --git a/cranelift/codegen/src/opts/bitops.isle b/cranelift/codegen/src/opts/bitops.isle index f3b47772f972..8904580ffab6 100644 --- a/cranelift/codegen/src/opts/bitops.isle +++ b/cranelift/codegen/src/opts/bitops.isle @@ -14,9 +14,17 @@ (iconst_u ty 0))) (subsume x)) +;; Create an all-zero bit pattern for integer, 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)))) + ;; x ^ x == 0. -(rule (simplify (bxor (ty_int ty) x x)) - (subsume (iconst_u ty 0))) +(rule (simplify (bxor ty x x)) + (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. diff --git a/cranelift/codegen/src/opts/extends.isle b/cranelift/codegen/src/opts/extends.isle index 0cc3c48e7f55..e0c89dc26859 100644 --- a/cranelift/codegen/src/opts/extends.isle +++ b/cranelift/codegen/src/opts/extends.isle @@ -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)) diff --git a/cranelift/codegen/src/opts/icmp.isle b/cranelift/codegen/src/opts/icmp.isle index db6f2510b2d7..6fd3487871ba 100644 --- a/cranelift/codegen/src/opts/icmp.isle +++ b/cranelift/codegen/src/opts/icmp.isle @@ -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. @@ -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))) diff --git a/cranelift/codegen/src/opts/shifts.isle b/cranelift/codegen/src/opts/shifts.isle index f3cfe7700c86..a809b5606e45 100644 --- a/cranelift/codegen/src/opts/shifts.isle +++ b/cranelift/codegen/src/opts/shifts.isle @@ -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))) diff --git a/cranelift/filetests/filetests/egraph/arithmetic-precise.clif b/cranelift/filetests/filetests/egraph/arithmetic-precise.clif index b006c8aa3f81..46ffa9a43190 100644 --- a/cranelift/filetests/filetests/egraph/arithmetic-precise.clif +++ b/cranelift/filetests/filetests/egraph/arithmetic-precise.clif @@ -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 diff --git a/cranelift/filetests/filetests/egraph/arithmetic.clif b/cranelift/filetests/filetests/egraph/arithmetic.clif index 964791ceb48f..0bb04d7ab10d 100644 --- a/cranelift/filetests/filetests/egraph/arithmetic.clif +++ b/cranelift/filetests/filetests/egraph/arithmetic.clif @@ -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 @@ -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 +} diff --git a/cranelift/filetests/filetests/egraph/bitops.clif b/cranelift/filetests/filetests/egraph/bitops.clif index 7e27f20aef64..5ccbc76b90fc 100644 --- a/cranelift/filetests/filetests/egraph/bitops.clif +++ b/cranelift/filetests/filetests/egraph/bitops.clif @@ -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 @@ -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 @@ -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): diff --git a/cranelift/filetests/filetests/egraph/extends.clif b/cranelift/filetests/filetests/egraph/extends.clif index fb891619f483..54c14fcb8082 100644 --- a/cranelift/filetests/filetests/egraph/extends.clif +++ b/cranelift/filetests/filetests/egraph/extends.clif @@ -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 diff --git a/cranelift/filetests/filetests/egraph/i128-opts.clif b/cranelift/filetests/filetests/egraph/i128-opts.clif index f970d696b9c2..107ea0425620 100644 --- a/cranelift/filetests/filetests/egraph/i128-opts.clif +++ b/cranelift/filetests/filetests/egraph/i128-opts.clif @@ -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 { diff --git a/cranelift/filetests/filetests/egraph/icmp.clif b/cranelift/filetests/filetests/egraph/icmp.clif index 3b1a2771f506..b15bbbb6ec20 100644 --- a/cranelift/filetests/filetests/egraph/icmp.clif +++ b/cranelift/filetests/filetests/egraph/icmp.clif @@ -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 diff --git a/cranelift/filetests/filetests/egraph/shifts.clif b/cranelift/filetests/filetests/egraph/shifts.clif index 96da6611b697..31ad3c3684cd 100644 --- a/cranelift/filetests/filetests/egraph/shifts.clif +++ b/cranelift/filetests/filetests/egraph/shifts.clif @@ -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 +} diff --git a/cranelift/filetests/filetests/runtests/arithmetic.clif b/cranelift/filetests/filetests/runtests/arithmetic.clif index 95d734da232e..e9fff188af61 100644 --- a/cranelift/filetests/filetests/runtests/arithmetic.clif +++ b/cranelift/filetests/filetests/runtests/arithmetic.clif @@ -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 diff --git a/cranelift/filetests/filetests/runtests/bitops.clif b/cranelift/filetests/filetests/runtests/bitops.clif index b1e327277b05..0fee56b7424f 100644 --- a/cranelift/filetests/filetests/runtests/bitops.clif +++ b/cranelift/filetests/filetests/runtests/bitops.clif @@ -554,6 +554,17 @@ block0(v0: i32, v1: i32): ; run: %test_bnot_iadd_bnot_to_isub_rt(4, 5) == -1 ; run: %test_bnot_iadd_bnot_to_isub_rt(0x12345678, 0x11111111) == 0x01234567 +function %test_bnot_ineg_to_isub_one_rt(i32) -> i32 fast { +block0(v0: i32): + v1 = ineg v0 + v2 = bnot v1 + return v2 +} + +; run: %test_bnot_ineg_to_isub_one_rt(0) == -1 +; run: %test_bnot_ineg_to_isub_one_rt(1) == 0 +; run: %test_bnot_ineg_to_isub_one_rt(0x12345678) == 0x12345677 + function %test_bor_bxor_bor(i32, i32, i32) -> i32 fast { block0(v0: i32, v1: i32, v2: i32): v3 = bxor v0, v2 @@ -807,4 +818,4 @@ block0(v0: i32, v1: i32): } ; run: %test_ule_x_bor(0, 0) == 1 -; run: %test_ule_x_bor(1, 0) == 1 \ No newline at end of file +; run: %test_ule_x_bor(1, 0) == 1 diff --git a/cranelift/filetests/filetests/runtests/extend.clif b/cranelift/filetests/filetests/runtests/extend.clif index f13a2efc65e4..063197ea76a2 100644 --- a/cranelift/filetests/filetests/runtests/extend.clif +++ b/cranelift/filetests/filetests/runtests/extend.clif @@ -238,3 +238,13 @@ block0(v0: i8): } ; run: %zext16_sext32(0xff) == 0xff ; run: %zext16_sext32(0x7f) == 0x7f + +function %nested_ireduce_i64_i8(i64) -> i8 { +block0(v0: i64): + v1 = ireduce.i32 v0 + v2 = ireduce.i8 v1 + return v2 +} +; run: %nested_ireduce_i64_i8(0) == 0 +; run: %nested_ireduce_i64_i8(-1) == -1 +; run: %nested_ireduce_i64_i8(0x1234_5678_9abc_def0) == 0xf0 diff --git a/cranelift/filetests/filetests/runtests/fp-bitops.clif b/cranelift/filetests/filetests/runtests/fp-bitops.clif index 8d36b0c644d0..14126db061ef 100644 --- a/cranelift/filetests/filetests/runtests/fp-bitops.clif +++ b/cranelift/filetests/filetests/runtests/fp-bitops.clif @@ -72,6 +72,15 @@ block0(v0: f32, v1: f32): ; run: %test_bxor_f32(0x1.ff, 0x1.0ff) == 0x0.f0fp-126 +function %test_bxor_x_x_f32(f32) -> f32 fast { +block0(v0: f32): + v1 = bxor v0, v0 + return v1 +} + +; run: %test_bxor_x_x_f32(0x1.ff) == 0x0.0 +; run: %test_bxor_x_x_f32(-NaN:0x3fffff) == 0x0.0 + function %test_bxor_f64(f64, f64) -> f64 fast { block0(v0: f64, v1: f64): v2 = bxor v0, v1 @@ -80,6 +89,15 @@ block0(v0: f64, v1: f64): ; run: %test_bxor_f64(0x1.ff, 0x1.0ff) == 0x0.f0fp-1022 +function %test_bxor_x_x_f64(f64) -> f64 fast { +block0(v0: f64): + v1 = bxor v0, v0 + return v1 +} + +; run: %test_bxor_x_x_f64(0x1.ff) == 0x0.0 +; run: %test_bxor_x_x_f64(-0x0.0) == 0x0.0 + function %test_bnot_bxor_f32(f32, f32) -> f32 { block0(v0: f32, v1: f32): v2 = bxor v0, v1 diff --git a/cranelift/filetests/filetests/runtests/icmp.clif b/cranelift/filetests/filetests/runtests/icmp.clif index fb0adab1eca8..65d049d2e42e 100644 --- a/cranelift/filetests/filetests/runtests/icmp.clif +++ b/cranelift/filetests/filetests/runtests/icmp.clif @@ -65,6 +65,28 @@ block0(v0: i8, v2: i8): ; run: %fold_cmp_over_nots2(2, 1) == 1 +function %eq_bnot_x_x(i32) -> i8 fast { +block0(v0: i32): + v1 = bnot v0 + v2 = icmp eq v1, v0 + return v2 +} + +; run: %eq_bnot_x_x(0) == 0 +; run: %eq_bnot_x_x(-1) == 0 +; run: %eq_bnot_x_x(42) == 0 + +function %ne_bnot_x_x(i32) -> i8 fast { +block0(v0: i32): + v1 = bnot v0 + v2 = icmp ne v1, v0 + return v2 +} + +; run: %ne_bnot_x_x(0) == 1 +; run: %ne_bnot_x_x(-1) == 1 +; run: %ne_bnot_x_x(42) == 1 + ;; (bxor ty (slt cty x y) (sgt cty x y)) -> (ne cty x y) function %test_bxor_slt_sgt(i32, i32) -> i8 fast { block0(v0: i32, v1: i32): diff --git a/cranelift/filetests/filetests/runtests/ineg.clif b/cranelift/filetests/filetests/runtests/ineg.clif index 6500a532d9ed..ace4b3d23dfe 100644 --- a/cranelift/filetests/filetests/runtests/ineg.clif +++ b/cranelift/filetests/filetests/runtests/ineg.clif @@ -57,3 +57,14 @@ block0(v0: i64): ; run: %ineg_i64(2) == -2 ; run: %ineg_i64(0x80000000_00000000) == 0x80000000_00000000 ; run: %ineg_i64(0x7fffffff_ffffffff) == 0x80000000_00000001 + +function %ineg_bnot_i32(i32) -> i32 { +block0(v0: i32): + v1 = bnot.i32 v0 + v2 = ineg.i32 v1 + return v2 +} +; run: %ineg_bnot_i32(0) == 1 +; run: %ineg_bnot_i32(1) == 2 +; run: %ineg_bnot_i32(-1) == 0 +; run: %ineg_bnot_i32(0x7fffffff) == 0x80000000 diff --git a/cranelift/filetests/filetests/runtests/rotl.clif b/cranelift/filetests/filetests/runtests/rotl.clif index 1aad67cecefa..bc37dc074a39 100644 --- a/cranelift/filetests/filetests/runtests/rotl.clif +++ b/cranelift/filetests/filetests/runtests/rotl.clif @@ -265,3 +265,12 @@ block0(v0: i64): ; run: %rotl_i64_const4(0xe000000000000000) == 0xe ; run: %rotl_i64_const4(0) == 0 ; run: %rotl_i64_const4(0xa00000000000000a) == 0xaa + +function %rotl_i64_const128(i64) -> i64 { +block0(v0: i64): + v1 = iconst.i64 128 + v2 = rotl v0, v1 + return v2 +} +; run: %rotl_i64_const128(0xe000000000000004) == 0xe000000000000004 +; run: %rotl_i64_const128(0xa00000000000000a) == 0xa00000000000000a diff --git a/cranelift/filetests/filetests/runtests/shifts.clif b/cranelift/filetests/filetests/runtests/shifts.clif index 113879b15356..d9a5f6a195b0 100644 --- a/cranelift/filetests/filetests/runtests/shifts.clif +++ b/cranelift/filetests/filetests/runtests/shifts.clif @@ -831,3 +831,98 @@ block0(v0: i32, v1: i32, v3: i32): ; run: %fold_shifts_over_and1(0, 0, 0) == 0 ; run: %fold_shifts_over_and1(1, 31, 0x80000000) == 1 +function %ishl_zero_left_operand(i64) -> i64 { +block0(v0: i64): + v1 = iconst.i64 0 + v2 = ishl v1, v0 + return v2 +} + +; run: %ishl_zero_left_operand(0) == 0 +; run: %ishl_zero_left_operand(1) == 0 +; run: %ishl_zero_left_operand(63) == 0 +; run: %ishl_zero_left_operand(64) == 0 + +function %ushr_zero_left_operand(i64) -> i64 { +block0(v0: i64): + v1 = iconst.i64 0 + v2 = ushr v1, v0 + return v2 +} + +; run: %ushr_zero_left_operand(0) == 0 +; run: %ushr_zero_left_operand(1) == 0 +; run: %ushr_zero_left_operand(63) == 0 +; run: %ushr_zero_left_operand(64) == 0 + +function %rotl_zero_left_operand(i64) -> i64 { +block0(v0: i64): + v1 = iconst.i64 0 + v2 = rotl v1, v0 + return v2 +} + +; run: %rotl_zero_left_operand(0) == 0 +; run: %rotl_zero_left_operand(1) == 0 +; run: %rotl_zero_left_operand(63) == 0 +; run: %rotl_zero_left_operand(64) == 0 + +function %rotr_zero_left_operand(i64) -> i64 { +block0(v0: i64): + v1 = iconst.i64 0 + v2 = rotr v1, v0 + return v2 +} + +; run: %rotr_zero_left_operand(0) == 0 +; run: %rotr_zero_left_operand(1) == 0 +; run: %rotr_zero_left_operand(63) == 0 +; run: %rotr_zero_left_operand(64) == 0 + +function %sshr_all_ones_left_operand(i64) -> i64 { +block0(v0: i64): + v1 = iconst.i64 -1 + v2 = sshr v1, v0 + return v2 +} + +; run: %sshr_all_ones_left_operand(0) == -1 +; run: %sshr_all_ones_left_operand(1) == -1 +; run: %sshr_all_ones_left_operand(63) == -1 +; run: %sshr_all_ones_left_operand(64) == -1 + +function %rotl_all_ones_left_operand(i64) -> i64 { +block0(v0: i64): + v1 = iconst.i64 -1 + v2 = rotl v1, v0 + return v2 +} + +; run: %rotl_all_ones_left_operand(0) == -1 +; run: %rotl_all_ones_left_operand(1) == -1 +; run: %rotl_all_ones_left_operand(63) == -1 +; run: %rotl_all_ones_left_operand(64) == -1 + +function %rotr_all_ones_left_operand(i64) -> i64 { +block0(v0: i64): + v1 = iconst.i64 -1 + v2 = rotr v1, v0 + return v2 +} + +; run: %rotr_all_ones_left_operand(0) == -1 +; run: %rotr_all_ones_left_operand(1) == -1 +; run: %rotr_all_ones_left_operand(63) == -1 +; run: %rotr_all_ones_left_operand(64) == -1 + +function %sshr_zero_left_operand(i64) -> i64 { +block0(v0: i64): + v1 = iconst.i64 0 + v2 = sshr v1, v0 + return v2 +} + +; run: %sshr_zero_left_operand(0) == 0 +; run: %sshr_zero_left_operand(1) == 0 +; run: %sshr_zero_left_operand(63) == 0 +; run: %sshr_zero_left_operand(64) == 0 diff --git a/cranelift/filetests/filetests/runtests/simd-vector.clif b/cranelift/filetests/filetests/runtests/simd-vector.clif new file mode 100644 index 000000000000..309ebe76f68a --- /dev/null +++ b/cranelift/filetests/filetests/runtests/simd-vector.clif @@ -0,0 +1,24 @@ +test interpret +test run +set opt_level=speed +target aarch64 +target s390x +target x86_64 +target x86_64 sse42 +target x86_64 sse42 has_avx +set enable_multi_ret_implicit_sret +target riscv64 has_v +target riscv64 has_v has_c has_zcb +target pulley32 +target pulley32be +target pulley64 +target pulley64be + +function %test_bxor_x_x_i64x2(i64x2) -> i64x2 fast { +block0(v0: i64x2): + v1 = bxor v0, v0 + return v1 +} + +; run: %test_bxor_x_x_i64x2([0 0]) == [0 0] +; run: %test_bxor_x_x_i64x2([0x123456789abcdef0 0xffffffffffffffff]) == [0 0] diff --git a/tests/disas/gc/copying/v128-fields.wat b/tests/disas/gc/copying/v128-fields.wat index 37172498c2bf..e2e35a2d0f56 100644 --- a/tests/disas/gc/copying/v128-fields.wat +++ b/tests/disas/gc/copying/v128-fields.wat @@ -19,6 +19,7 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly can_move region0 gv0+8 ;; gv2 = load.i64 notrap aligned region1 gv1+24 +;; const0 = 0x00000000000000000000000000000000 ;; stack_limit = gv2 ;; ;; block0(v0: i64, v1: i64, v2: i32): @@ -33,6 +34,6 @@ ;; @002e jump block1 ;; ;; block1: -;; @002c v17 = bxor.i8x16 v9, v9 -;; @002e return v17 +;; v20 = vconst.i8x16 const0 +;; @002e return v20 ; v20 = const0 ;; } diff --git a/tests/disas/gc/drc/externref-globals.wat b/tests/disas/gc/drc/externref-globals.wat index 6d240d68cbb5..51ae94c5517a 100644 --- a/tests/disas/gc/drc/externref-globals.wat +++ b/tests/disas/gc/drc/externref-globals.wat @@ -138,27 +138,27 @@ ;; @003b jump block3 ;; ;; block3: -;; v62 = iadd.i64 v0, v3 ; v3 = 48 -;; @003b store.i32 notrap aligned region2 v2, v62 -;; v63 = iconst.i32 1 -;; v64 = band.i32 v5, v63 ; v63 = 1 -;; v65 = iconst.i32 0 -;; v66 = icmp.i32 eq v5, v65 ; v65 = 0 -;; @003b v31 = uextend.i32 v66 -;; @003b v32 = bor v64, v31 +;; v63 = iadd.i64 v0, v3 ; v3 = 48 +;; @003b store.i32 notrap aligned region2 v2, v63 +;; v64 = iconst.i32 1 +;; v65 = band.i32 v5, v64 ; v64 = 1 +;; v66 = iconst.i32 0 +;; v67 = icmp.i32 eq v5, v66 ; v66 = 0 +;; @003b v31 = uextend.i32 v67 +;; @003b v32 = bor v65, v31 ;; @003b brif v32, block7, block4 ;; ;; block4: -;; v67 = load.i64 notrap aligned readonly can_move region0 v0+8 -;; v68 = load.i64 notrap aligned readonly can_move region3 v67+32 +;; v68 = load.i64 notrap aligned readonly can_move region0 v0+8 +;; v69 = load.i64 notrap aligned readonly can_move region3 v68+32 ;; @003b v33 = uextend.i64 v5 -;; @003b v36 = iadd v68, v33 -;; v69 = iconst.i64 8 -;; @003b v38 = iadd v36, v69 ; v69 = 8 +;; @003b v36 = iadd v69, v33 +;; v70 = iconst.i64 8 +;; @003b v38 = iadd v36, v70 ; v70 = 8 ;; @003b v39 = load.i64 user2 region5 v38 -;; v70 = iconst.i64 1 -;; v60 = icmp eq v39, v70 ; v70 = 1 -;; @003b brif v60, block5, block6 +;; v71 = iconst.i64 1 +;; v61 = icmp eq v39, v71 ; v71 = 1 +;; @003b brif v61, block5, block6 ;; ;; block5 cold: ;; @003b call fn0(v0, v5) @@ -167,8 +167,8 @@ ;; block6: ;; @003b v40 = iconst.i64 -1 ;; @003b v41 = iadd.i64 v39, v40 ; v40 = -1 -;; v71 = iadd.i64 v36, v69 ; v69 = 8 -;; @003b store user2 region5 v41, v71 +;; v72 = iadd.i64 v36, v70 ; v70 = 8 +;; @003b store user2 region5 v41, v72 ;; @003b jump block7 ;; ;; block7: diff --git a/tests/disas/gc/drc/struct-set.wat b/tests/disas/gc/drc/struct-set.wat index 9835e23fb1b0..425f5c60898e 100644 --- a/tests/disas/gc/drc/struct-set.wat +++ b/tests/disas/gc/drc/struct-set.wat @@ -113,25 +113,25 @@ ;; @004a jump block3 ;; ;; block3: -;; v67 = iadd.i64 v7, v8 ; v8 = 32 -;; @004a store.i32 user2 little region4 v3, v67 -;; v68 = iconst.i32 1 -;; v69 = band.i32 v10, v68 ; v68 = 1 -;; v70 = iconst.i32 0 -;; v71 = icmp.i32 eq v10, v70 ; v70 = 0 -;; @004a v36 = uextend.i32 v71 -;; @004a v37 = bor v69, v36 +;; v68 = iadd.i64 v7, v8 ; v8 = 32 +;; @004a store.i32 user2 little region4 v3, v68 +;; v69 = iconst.i32 1 +;; v70 = band.i32 v10, v69 ; v69 = 1 +;; v71 = iconst.i32 0 +;; v72 = icmp.i32 eq v10, v71 ; v71 = 0 +;; @004a v36 = uextend.i32 v72 +;; @004a v37 = bor v70, v36 ;; @004a brif v37, block7, block4 ;; ;; block4: ;; @004a v38 = uextend.i64 v10 ;; @004a v41 = iadd.i64 v6, v38 -;; v72 = iconst.i64 8 -;; @004a v43 = iadd v41, v72 ; v72 = 8 +;; v73 = iconst.i64 8 +;; @004a v43 = iadd v41, v73 ; v73 = 8 ;; @004a v44 = load.i64 user2 region4 v43 -;; v73 = iconst.i64 1 -;; v65 = icmp eq v44, v73 ; v73 = 1 -;; @004a brif v65, block5, block6 +;; v74 = iconst.i64 1 +;; v66 = icmp eq v44, v74 ; v74 = 1 +;; @004a brif v66, block5, block6 ;; ;; block5 cold: ;; @004a call fn0(v0, v10) @@ -140,8 +140,8 @@ ;; block6: ;; @004a v45 = iconst.i64 -1 ;; @004a v46 = iadd.i64 v44, v45 ; v45 = -1 -;; v74 = iadd.i64 v41, v72 ; v72 = 8 -;; @004a store user2 region4 v46, v74 +;; v75 = iadd.i64 v41, v73 ; v73 = 8 +;; @004a store user2 region4 v46, v75 ;; @004a jump block7 ;; ;; block7: diff --git a/tests/disas/gc/null/v128-fields.wat b/tests/disas/gc/null/v128-fields.wat index 99d385a6829b..ae58a342d46d 100644 --- a/tests/disas/gc/null/v128-fields.wat +++ b/tests/disas/gc/null/v128-fields.wat @@ -20,6 +20,7 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly can_move region0 gv0+8 ;; gv2 = load.i64 notrap aligned region1 gv1+24 +;; const0 = 0x00000000000000000000000000000000 ;; stack_limit = gv2 ;; ;; block0(v0: i64, v1: i64, v2: i32): @@ -34,6 +35,6 @@ ;; @002e jump block1 ;; ;; block1: -;; @002c v17 = bxor.i8x16 v9, v9 -;; @002e return v17 +;; v20 = vconst.i8x16 const0 +;; @002e return v20 ; v20 = const0 ;; }