From 5432f062b0fd5e9795caab4be2e52d5a71558c1e Mon Sep 17 00:00:00 2001 From: Bongjun Date: Sun, 26 Apr 2026 12:41:12 +0000 Subject: [PATCH 1/4] [Cranelift] allow bitop ops for vectors --- cranelift/codegen/src/opts/bitops.isle | 12 ++-- .../filetests/filetests/egraph/bitops.clif | 68 ++++++++++++++++++- 2 files changed, 73 insertions(+), 7 deletions(-) diff --git a/cranelift/codegen/src/opts/bitops.isle b/cranelift/codegen/src/opts/bitops.isle index 0bc815a7f734..e314a57984a7 100644 --- a/cranelift/codegen/src/opts/bitops.isle +++ b/cranelift/codegen/src/opts/bitops.isle @@ -20,10 +20,10 @@ ;; 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. -(rule (simplify (bxor (ty_int ty) x (bnot ty x))) (subsume (iconst_s ty -1))) -(rule (simplify (bxor (ty_int ty) (bnot ty x) x)) (subsume (iconst_s ty -1))) -(rule (simplify (bor (ty_int ty) x (bnot ty x))) (subsume (iconst_s ty -1))) -(rule (simplify (bor (ty_int ty) (bnot ty x) x)) (subsume (iconst_s ty -1))) +(rule (simplify (bxor ty x (bnot ty x))) (subsume (iconst_s ty -1))) +(rule (simplify (bxor ty (bnot ty x) x)) (subsume (iconst_s ty -1))) +(rule (simplify (bor ty x (bnot ty x))) (subsume (iconst_s ty -1))) +(rule (simplify (bor ty (bnot ty x) x)) (subsume (iconst_s ty -1))) ;; x & x == x & -1 == x. (rule (simplify (band ty x x)) (subsume x)) @@ -32,8 +32,8 @@ ;; x & 0 == x & not(x) == not(x) & x == 0. (rule (simplify (band ty _ zero @ (iconst_u ty 0))) (subsume zero)) -(rule (simplify (band (ty_int ty) x (bnot ty x))) (subsume (iconst_u ty 0))) -(rule (simplify (band (ty_int ty) (bnot ty x) x)) (subsume (iconst_u ty 0))) +(rule (simplify (band ty x (bnot ty x))) (subsume (iconst_u ty 0))) +(rule (simplify (band ty (bnot ty x) x)) (subsume (iconst_u ty 0))) ;; (x & y) ^ (x ^ y) == x | y (rule (simplify (bxor ty (band ty X Y) (bxor ty X Y))) (bor ty X Y)) diff --git a/cranelift/filetests/filetests/egraph/bitops.clif b/cranelift/filetests/filetests/egraph/bitops.clif index 1ffd6dec748d..8f33aea6d31d 100644 --- a/cranelift/filetests/filetests/egraph/bitops.clif +++ b/cranelift/filetests/filetests/egraph/bitops.clif @@ -138,6 +138,72 @@ block0(v1: i64): ; check: v5 = bnot v1 ; check: return v5 +function %vector_bxor_x_bnot_x(i32x4) -> i32x4 { +block0(v0: i32x4): + v1 = bnot v0 + v2 = bxor v0, v1 + return v2 +} + +; check: const0 = 0xffffffffffffffffffffffffffffffff +; check: v5 = vconst.i32x4 const0 +; check: return v5 + +function %vector_bxor_bnot_x_x(i32x4) -> i32x4 { +block0(v0: i32x4): + v1 = bnot v0 + v2 = bxor v1, v0 + return v2 +} + +; check: const0 = 0xffffffffffffffffffffffffffffffff +; check: v5 = vconst.i32x4 const0 +; check: return v5 + +function %vector_bor_x_bnot_x(i32x4) -> i32x4 { +block0(v0: i32x4): + v1 = bnot v0 + v2 = bor v0, v1 + return v2 +} + +; check: const0 = 0xffffffffffffffffffffffffffffffff +; check: v5 = vconst.i32x4 const0 +; check: return v5 + +function %vector_bor_bnot_x_x(i32x4) -> i32x4 { +block0(v0: i32x4): + v1 = bnot v0 + v2 = bor v1, v0 + return v2 +} + +; check: const0 = 0xffffffffffffffffffffffffffffffff +; check: v5 = vconst.i32x4 const0 +; check: return v5 + +function %vector_band_x_bnot_x(i32x4) -> i32x4 { +block0(v0: i32x4): + v1 = bnot v0 + v2 = band v0, v1 + return v2 +} + +; check: const0 = 0x00000000000000000000000000000000 +; check: v5 = vconst.i32x4 const0 +; check: return v5 + +function %vector_band_bnot_x_x(i32x4) -> i32x4 { +block0(v0: i32x4): + v1 = bnot v0 + v2 = band v1, v0 + return v2 +} + +; check: const0 = 0x00000000000000000000000000000000 +; check: v5 = vconst.i32x4 const0 +; check: return v5 + function %bitops_bmask(i64) -> i64 { block0(v0: i64): v1 = bnot v0 @@ -957,4 +1023,4 @@ block0(v0: i32, v1: i32): ; block0(v0: i32, v1: i32): ; v5 = bor v1, v0 ; return v5 -; } \ No newline at end of file +; } From e9a5bdb964659d52f4d96a338101df881c5a0449 Mon Sep 17 00:00:00 2001 From: Bongjun Date: Mon, 27 Apr 2026 00:45:04 +0000 Subject: [PATCH 2/4] [Cranelift] fix affected tests --- cranelift/filetests/filetests/egraph/icmp.clif | 7 +++---- tests/disas/issue-10929-v128-icmp-egraphs.wat | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/cranelift/filetests/filetests/egraph/icmp.clif b/cranelift/filetests/filetests/egraph/icmp.clif index b3567685cc25..f1a025122a5e 100644 --- a/cranelift/filetests/filetests/egraph/icmp.clif +++ b/cranelift/filetests/filetests/egraph/icmp.clif @@ -214,12 +214,12 @@ block0(): ; function %issue_10929_no_crash_on_icmp_vectors() -> i32x4 fast { ; const0 = 0x40ad3fb47cb16076c8cb1fdd8189d40f +; const1 = 0xffffffffffffffffffffffffffffffff ; ; block0: ; v1 = vconst.i32x4 const0 -; v4 = bnot v1 ; v1 = const0 -; v2 = bxor v1, v4 ; v1 = const0 -; v3 = icmp ne v1, v2 ; v1 = const0 +; v7 = vconst.i32x4 const1 +; v3 = icmp ne v1, v7 ; v1 = const0, v7 = const1 ; return v3 ; } @@ -420,4 +420,3 @@ block0(v0: i32, v1: i32): ; v6 = icmp ult v0, v1 ; return v6 ; } - diff --git a/tests/disas/issue-10929-v128-icmp-egraphs.wat b/tests/disas/issue-10929-v128-icmp-egraphs.wat index 8d906ef67d77..74c0f657a87d 100644 --- a/tests/disas/issue-10929-v128-icmp-egraphs.wat +++ b/tests/disas/issue-10929-v128-icmp-egraphs.wat @@ -14,14 +14,14 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned gv1+24 +;; const0 = 0xffffffffffffffffffffffffffffffff ;; stack_limit = gv2 ;; ;; block0(v0: i64, v1: i64, v2: i8x16): ;; @0025 jump block1 ;; ;; block1: -;; @001f v4 = bnot.i8x16 v2 -;; @0021 v5 = bxor.i8x16 v2, v4 -;; @0023 v6 = icmp.i8x16 ne v2, v5 +;; v9 = vconst.i8x16 const0 +;; @0023 v6 = icmp.i8x16 ne v2, v9 ; v9 = const0 ;; @0025 return v6 ;; } From ca2fd03b7a47a1a4ebb5717d2fb55565581f2734 Mon Sep 17 00:00:00 2001 From: Bongjun Date: Mon, 27 Apr 2026 03:39:00 +0000 Subject: [PATCH 3/4] [Cranelift] allow more opts --- cranelift/codegen/src/opts/arithmetic.isle | 5 ++++- cranelift/codegen/src/opts/icmp.isle | 14 +++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/cranelift/codegen/src/opts/arithmetic.isle b/cranelift/codegen/src/opts/arithmetic.isle index d92ffedf7bbb..49ea53572482 100644 --- a/cranelift/codegen/src/opts/arithmetic.isle +++ b/cranelift/codegen/src/opts/arithmetic.isle @@ -340,7 +340,10 @@ ;; Helper to create a "true" value for a comparison. For scalar integers this is ;; a value of 1 but for vectors this is -1 since each lane is filled with all -;; 1s. +;; 1s. We use `(iconst_u ty 0)` for falses for both integers and vector. This is +;; because of the Cranelift semantics: +;; When comparing scalars, the result is 1 if the condition holds, or 0 otherwise. +;; When comparing vectors, the result is -1 (all-ones) if the condition holds, or 0 otherwise. (decl cmp_true (Type) Value) (rule 0 (cmp_true (ty_int ty)) (iconst_u ty 1)) (rule 1 (cmp_true (ty_vec128 ty)) (iconst_s ty -1)) diff --git a/cranelift/codegen/src/opts/icmp.isle b/cranelift/codegen/src/opts/icmp.isle index 71a58d57a3d2..c47278172104 100644 --- a/cranelift/codegen/src/opts/icmp.isle +++ b/cranelift/codegen/src/opts/icmp.isle @@ -101,7 +101,7 @@ ;; Comparisons against largest/smallest signed/unsigned values: ;; ult(x, 0) == false. -(rule (simplify (ult (fits_in_64 (ty_int bty)) x zero @ (iconst_u _ 0))) +(rule (simplify (ult bty x zero @ (iconst_u _ 0))) (subsume (iconst_u bty 0))) ;; ule(x, 0) == eq(x, 0) @@ -113,8 +113,8 @@ (ne bty x zero)) ;; uge(x, 0) == true. -(rule (simplify (uge (fits_in_64 (ty_int bty)) x zero @ (iconst_u _ 0))) - (subsume (iconst_u bty 1))) +(rule (simplify (uge bty x zero @ (iconst_u _ 0))) + (subsume (cmp_true bty))) ;; ult(x, UMAX) == ne(x, UMAX). (rule (simplify (ult (fits_in_64 (ty_int bty)) x umax @ (iconst_u cty y))) @@ -317,10 +317,10 @@ (rule (simplify (bxor ty (ult ty x y) (ult ty y x))) (ne ty x y)) ;; a < b && a > b = false -(rule (simplify (band (fits_in_64 ty) (sgt ty x y) (slt ty x y))) (iconst_u ty 0)) -(rule (simplify (band (fits_in_64 ty) (slt ty x y) (sgt ty x y))) (iconst_u ty 0)) -(rule (simplify (band (fits_in_64 ty) (ugt ty x y) (ult ty x y))) (iconst_u ty 0)) -(rule (simplify (band (fits_in_64 ty) (ult ty x y) (ugt ty x y))) (iconst_u ty 0)) +(rule (simplify (band ty (sgt ty x y) (slt ty x y))) (iconst_u ty 0)) +(rule (simplify (band ty (slt ty x y) (sgt ty x y))) (iconst_u ty 0)) +(rule (simplify (band ty (ugt ty x y) (ult ty x y))) (iconst_u ty 0)) +(rule (simplify (band ty (ult ty x y) (ugt ty x y))) (iconst_u ty 0)) (rule (simplify (band ty (sgt ty x (iconst_s _ y)) (ult ty x (iconst_s _ y)))) (if-let true (i64_gt_eq y 0)) From 15a8b0d0ba55d32932407728c2fec0c4805f499c Mon Sep 17 00:00:00 2001 From: Bongjun Date: Mon, 27 Apr 2026 04:11:45 +0000 Subject: [PATCH 4/4] [Cranelift] update tests for new vec opts --- .../filetests/egraph/issue-12328.clif | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/cranelift/filetests/filetests/egraph/issue-12328.clif b/cranelift/filetests/filetests/egraph/issue-12328.clif index e95e825e7ef5..6d4b0bc94bb1 100644 --- a/cranelift/filetests/filetests/egraph/issue-12328.clif +++ b/cranelift/filetests/filetests/egraph/issue-12328.clif @@ -8,6 +8,9 @@ block0(v0: i32x4, v1: i32x4): v3 = icmp slt v0, v1 v4 = band v2, v3 return v4 + ; check: const0 = 0x00000000000000000000000000000000 + ; check: v7 = vconst.i32x4 const0 + ; check: return v7 ; v7 = const0 } function %slt_sgt_i32x4(i32x4, i32x4) -> i32x4 { @@ -16,6 +19,9 @@ block0(v0: i32x4, v1: i32x4): v3 = icmp sgt v0, v1 v4 = band v2, v3 return v4 + ; check: const0 = 0x00000000000000000000000000000000 + ; check: v7 = vconst.i32x4 const0 + ; check: return v7 ; v7 = const0 } function %ugt_ult_i32x4(i32x4, i32x4) -> i32x4 { @@ -24,6 +30,9 @@ block0(v0: i32x4, v1: i32x4): v3 = icmp ult v0, v1 v4 = band v2, v3 return v4 + ; check: const0 = 0x00000000000000000000000000000000 + ; check: v7 = vconst.i32x4 const0 + ; check: return v7 ; v7 = const0 } function %ult_ugt_i32x4(i32x4, i32x4) -> i32x4 { @@ -32,6 +41,9 @@ block0(v0: i32x4, v1: i32x4): v3 = icmp ugt v0, v1 v4 = band v2, v3 return v4 + ; check: const0 = 0x00000000000000000000000000000000 + ; check: v7 = vconst.i32x4 const0 + ; check: return v7 ; v7 = const0 } function %sgt_slt_i64x2(i64x2, i64x2) -> i64x2 { @@ -40,6 +52,9 @@ block0(v0: i64x2, v1: i64x2): v3 = icmp slt v0, v1 v4 = band v2, v3 return v4 + ; check: const0 = 0x00000000000000000000000000000000 + ; check: v7 = vconst.i64x2 const0 + ; check: return v7 ; v7 = const0 } function %slt_sgt_i16x8(i16x8, i16x8) -> i16x8 { @@ -48,6 +63,9 @@ block0(v0: i16x8, v1: i16x8): v3 = icmp sgt v0, v1 v4 = band v2, v3 return v4 + ; check: const0 = 0x00000000000000000000000000000000 + ; check: v7 = vconst.i16x8 const0 + ; check: return v7 ; v7 = const0 } function %ugt_ult_i8x16(i8x16, i8x16) -> i8x16 { @@ -56,4 +74,7 @@ block0(v0: i8x16, v1: i8x16): v3 = icmp ult v0, v1 v4 = band v2, v3 return v4 + ; check: const0 = 0x00000000000000000000000000000000 + ; check: v7 = vconst.i8x16 const0 + ; check: return v7 ; v7 = const0 }