From b6aa954ed65960ffde7e6668c70b30ae690bd181 Mon Sep 17 00:00:00 2001 From: Karl Meakin Date: Sat, 27 Jul 2024 20:06:01 +0100 Subject: [PATCH] egraphs: canonicalize `icmp` Canonicalize `icmp` instructions: * loose inequalities to strict inequalities (eg `ult(x, c) => ult(x, c+1)`) where possible * strict inequalities to equalities (eg `ult(x, 1) => eq(x, 0)`) where possible Copyright (c) 2024, Arm Limited. Signed-off-by: Karl Meakin --- cranelift/codegen/src/opts/icmp.isle | 45 +- .../filetests/filetests/egraph/cprop.clif | 12 +- .../filetests/egraph/icmp-parameterized.clif | 638 ++++++++++++++++-- .../filetests/filetests/egraph/icmp.clif | 10 +- .../egraph/make-icmp-parameterized-tests.sh | 30 +- .../filetests/filetests/egraph/spaceship.clif | 4 +- 6 files changed, 669 insertions(+), 70 deletions(-) diff --git a/cranelift/codegen/src/opts/icmp.isle b/cranelift/codegen/src/opts/icmp.isle index 024e6668f02a..abb7a61576a0 100644 --- a/cranelift/codegen/src/opts/icmp.isle +++ b/cranelift/codegen/src/opts/icmp.isle @@ -15,14 +15,14 @@ ;; Optimize icmp-of-icmp. ;; ne(icmp(ty, cc, x, y), 0) == icmp(ty, cc, x, y) -;; e.g. neq(ugt(x, y), 0) == ugt(x, y) +;; e.g. neq(ugt(x, y), 0) == ugt(x, y) (rule (simplify (ne ty (uextend_maybe _ inner @ (icmp ty _ _ _)) (iconst_u _ 0))) (subsume inner)) ;; eq(icmp(ty, cc, x, y), 0) == icmp(ty, cc_complement, x, y) -;; e.g. eq(ugt(x, y), 0) == ule(x, y) +;; e.g. eq(ugt(x, y), 0) == ule(x, y) (rule (simplify (eq ty (uextend_maybe _ (icmp ty cc x y)) (iconst_u _ 0))) @@ -65,11 +65,37 @@ (iconst_u _ 1))) extend) +;; Rewrite loose inequalities to strict inequalities: +;; ule(x, c) == ult(x, c+1), for c != UMAX. +(rule (simplify (ule (fits_in_64 (ty_int bty)) x (iconst cty (u64_from_imm64 c)))) + (if-let $false (u64_eq c (ty_umax cty))) + (ult bty x (iconst cty (imm64 (u64_add c 1))))) + +;; uge(x, c) == ugt(x, c-1), for c != 0. +(rule (simplify (uge (fits_in_64 (ty_int bty)) x (iconst cty (u64_from_imm64 c)))) + (if-let $false (u64_eq c 0)) + (ugt bty x (iconst cty (imm64 (u64_sub c 1))))) + +;; sle(x, c) == slt(x, c+1), for c != SMAX. +(rule (simplify (sle (fits_in_64 (ty_int bty)) x (iconst cty (u64_from_imm64 c)))) + (if-let $false (u64_eq c (ty_smax cty))) + (slt bty x (iconst cty (imm64 (u64_add c 1))))) + +;; FIXME: triggers verifier error +;; sge(x, c) == sgt(x, c-1), for c != SMIN. +;; (rule (simplify (sge (fits_in_64 (ty_int bty)) x (iconst cty (u64_from_imm64 c)))) +;; (if-let $false (u64_eq c (ty_smin cty))) +;; (sgt bty x (iconst cty (imm64 (u64_sub c 1))))) + ;; 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))) (subsume (iconst_u bty 0))) +;; ult(x, 1) == eq(x, 0) +(rule (simplify (ult (fits_in_64 (ty_int bty)) x (iconst cty (u64_from_imm64 0)))) + (eq bty x (iconst cty (imm64 0)))) + ;; ule(x, 0) == eq(x, 0) (rule (simplify (ule (fits_in_64 (ty_int bty)) x zero @ (iconst_u _ 0))) (eq bty x zero)) @@ -78,6 +104,11 @@ (rule (simplify (ugt (fits_in_64 (ty_int bty)) x zero @ (iconst_u _ 0))) (ne bty x zero)) +;; ugt(x, UMAX-1) == eq(x, UMAX). +(rule (simplify (ugt (fits_in_64 (ty_int bty)) x (iconst cty (u64_from_imm64 y)))) + (if-let $true (u64_eq y (u64_sub (ty_umax cty) 1))) + (eq bty x (iconst cty (imm64 (ty_umax cty))))) + ;; uge(x, 0) == true. (rule (simplify (uge (fits_in_64 (ty_int bty)) x zero @ (iconst_u _ 0))) (subsume (iconst_u bty 1))) @@ -112,6 +143,11 @@ (if-let $true (u64_eq y (ty_smin cty))) (eq bty x smin)) +;; slt(x, SMIN+1) == eq(x, SMIN). +(rule (simplify (slt (fits_in_64 (ty_int bty)) x (iconst cty (u64_from_imm64 y)))) + (if-let $true (u64_eq y (u64_add (ty_smin cty) 1))) + (eq bty x (iconst cty (imm64 (ty_smin cty))))) + ;; sgt(x, SMIN) == ne(x, SMIN). (rule (simplify (sgt (fits_in_64 (ty_int bty)) x smin @ (iconst_u cty y))) (if-let $true (u64_eq y (ty_smin cty))) @@ -142,6 +178,11 @@ (if-let $true (u64_eq y (ty_smax cty))) (eq bty x smax)) +;; sgt(x, SMAX-1) == eq(x, SMAX). +(rule (simplify (sgt (fits_in_64 (ty_int bty)) x (iconst cty (u64_from_imm64 y)))) + (if-let $true (u64_eq y (u64_sub (ty_smax cty) 1))) + (eq bty x (iconst cty (imm64 (ty_smax cty))))) + ;; `band`/`bor` of 2 comparisons: (rule (simplify (band (fits_in_64 ty) (icmp ty cc1 x y) (icmp ty cc2 x y))) (if-let signed (intcc_comparable cc1 cc2)) diff --git a/cranelift/filetests/filetests/egraph/cprop.clif b/cranelift/filetests/filetests/egraph/cprop.clif index f1ca491f4977..f23dde1c63bf 100644 --- a/cranelift/filetests/filetests/egraph/cprop.clif +++ b/cranelift/filetests/filetests/egraph/cprop.clif @@ -162,8 +162,8 @@ block0: return v2 } -; check: v3 = iconst.i8 1 -; nextln: return v3 +; check: v5 = iconst.i8 1 +; nextln: return v5 function %icmp_uge_i32() -> i8 { block0: @@ -173,8 +173,8 @@ block0: return v2 } -; check: v3 = iconst.i8 0 -; nextln: return v3 +; check: v4 = iconst.i8 0 +; nextln: return v4 function %icmp_ugt_i32() -> i8 { block0: @@ -206,8 +206,8 @@ block0: return v2 } -; check: v3 = iconst.i8 1 -; nextln: return v3 +; check: v5 = iconst.i8 1 +; nextln: return v5 function %icmp_sge_i32() -> i8 { block0: diff --git a/cranelift/filetests/filetests/egraph/icmp-parameterized.clif b/cranelift/filetests/filetests/egraph/icmp-parameterized.clif index 0ce76115c611..96c14f2fdf89 100644 --- a/cranelift/filetests/filetests/egraph/icmp-parameterized.clif +++ b/cranelift/filetests/filetests/egraph/icmp-parameterized.clif @@ -3,7 +3,7 @@ set opt_level=speed target x86_64 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -;; !!! GENERATED BY 'make-parameterized-icmp-tests.sh' DO NOT EDIT !!! +;; !!! GENERATED BY 'make-icmp-parameterized-tests.sh' DO NOT EDIT !!! ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ;; run with the 'CRANELIFT_TEST_BLESS=1' env var set to update this file @@ -127,36 +127,6 @@ block0(v0: i32): ; return v2 ; v2 = 1 ; } -function %mask_icmp_result(i64, i64) -> i8 { -block0(v1: i64, v2: i64): - v3 = icmp ult v1, v2 - v4 = iconst.i8 1 - v5 = band v3, v4 - return v5 -} - -; function %mask_icmp_result(i64, i64) -> i8 fast { -; block0(v1: i64, v2: i64): -; v3 = icmp ult v1, v2 -; return v3 -; } - -function %mask_icmp_extend_result(i64, i64) -> i64 { -block0(v1: i64, v2: i64): - v3 = icmp ult v1, v2 - v4 = uextend.i64 v3 - v5 = iconst.i64 1 - v6 = band v4, v5 - return v6 -} - -; function %mask_icmp_extend_result(i64, i64) -> i64 fast { -; block0(v1: i64, v2: i64): -; v3 = icmp ult v1, v2 -; v4 = uextend.i64 v3 -; return v4 -; } - function %icmp_eq_umin(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0 @@ -171,6 +141,20 @@ block0(v0: i32): ; return v2 ; } +function %icmp_eq_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 1 + v2 = icmp eq v0, v1 + return v2 +} + +; function %icmp_eq_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 1 +; v2 = icmp eq v0, v1 ; v1 = 1 +; return v2 +; } + function %icmp_eq_umax(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0xFFFF_FFFF @@ -185,6 +169,20 @@ block0(v0: i32): ; return v2 ; } +function %icmp_eq_umax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0xFFFF_FFFE + v2 = icmp eq v0, v1 + return v2 +} + +; function %icmp_eq_umax_minus_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 0xffff_fffe +; v2 = icmp eq v0, v1 ; v1 = 0xffff_fffe +; return v2 +; } + function %icmp_eq_smin(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0x8000_0000 @@ -199,6 +197,20 @@ block0(v0: i32): ; return v2 ; } +function %icmp_eq_smin_plus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x8000_0001 + v2 = icmp eq v0, v1 + return v2 +} + +; function %icmp_eq_smin_plus_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 0x8000_0001 +; v2 = icmp eq v0, v1 ; v1 = 0x8000_0001 +; return v2 +; } + function %icmp_eq_smax(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0x7FFF_FFFF @@ -213,6 +225,20 @@ block0(v0: i32): ; return v2 ; } +function %icmp_eq_smax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x7FFF_FFFE + v2 = icmp eq v0, v1 + return v2 +} + +; function %icmp_eq_smax_minus_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 0x7fff_fffe +; v2 = icmp eq v0, v1 ; v1 = 0x7fff_fffe +; return v2 +; } + function %icmp_ne_umin(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0 @@ -227,6 +253,20 @@ block0(v0: i32): ; return v2 ; } +function %icmp_ne_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 1 + v2 = icmp ne v0, v1 + return v2 +} + +; function %icmp_ne_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 1 +; v2 = icmp ne v0, v1 ; v1 = 1 +; return v2 +; } + function %icmp_ne_umax(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0xFFFF_FFFF @@ -241,6 +281,20 @@ block0(v0: i32): ; return v2 ; } +function %icmp_ne_umax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0xFFFF_FFFE + v2 = icmp ne v0, v1 + return v2 +} + +; function %icmp_ne_umax_minus_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 0xffff_fffe +; v2 = icmp ne v0, v1 ; v1 = 0xffff_fffe +; return v2 +; } + function %icmp_ne_smin(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0x8000_0000 @@ -255,6 +309,20 @@ block0(v0: i32): ; return v2 ; } +function %icmp_ne_smin_plus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x8000_0001 + v2 = icmp ne v0, v1 + return v2 +} + +; function %icmp_ne_smin_plus_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 0x8000_0001 +; v2 = icmp ne v0, v1 ; v1 = 0x8000_0001 +; return v2 +; } + function %icmp_ne_smax(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0x7FFF_FFFF @@ -269,6 +337,20 @@ block0(v0: i32): ; return v2 ; } +function %icmp_ne_smax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x7FFF_FFFE + v2 = icmp ne v0, v1 + return v2 +} + +; function %icmp_ne_smax_minus_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 0x7fff_fffe +; v2 = icmp ne v0, v1 ; v1 = 0x7fff_fffe +; return v2 +; } + function %icmp_ult_umin(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0 @@ -282,6 +364,20 @@ block0(v0: i32): ; return v3 ; v3 = 0 ; } +function %icmp_ult_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 1 + v2 = icmp ult v0, v1 + return v2 +} + +; function %icmp_ult_1(i32) -> i8 fast { +; block0(v0: i32): +; v3 = iconst.i32 0 +; v4 = icmp eq v0, v3 ; v3 = 0 +; return v4 +; } + function %icmp_ult_umax(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0xFFFF_FFFF @@ -296,6 +392,20 @@ block0(v0: i32): ; return v3 ; } +function %icmp_ult_umax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0xFFFF_FFFE + v2 = icmp ult v0, v1 + return v2 +} + +; function %icmp_ult_umax_minus_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 0xffff_fffe +; v2 = icmp ult v0, v1 ; v1 = 0xffff_fffe +; return v2 +; } + function %icmp_ult_smin(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0x8000_0000 @@ -310,6 +420,20 @@ block0(v0: i32): ; return v2 ; } +function %icmp_ult_smin_plus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x8000_0001 + v2 = icmp ult v0, v1 + return v2 +} + +; function %icmp_ult_smin_plus_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 0x8000_0001 +; v2 = icmp ult v0, v1 ; v1 = 0x8000_0001 +; return v2 +; } + function %icmp_ult_smax(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0x7FFF_FFFF @@ -324,6 +448,20 @@ block0(v0: i32): ; return v2 ; } +function %icmp_ult_smax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x7FFF_FFFE + v2 = icmp ult v0, v1 + return v2 +} + +; function %icmp_ult_smax_minus_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 0x7fff_fffe +; v2 = icmp ult v0, v1 ; v1 = 0x7fff_fffe +; return v2 +; } + function %icmp_ule_umin(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0 @@ -334,8 +472,22 @@ block0(v0: i32): ; function %icmp_ule_umin(i32) -> i8 fast { ; block0(v0: i32): ; v1 = iconst.i32 0 -; v3 = icmp eq v0, v1 ; v1 = 0 -; return v3 +; v5 = icmp eq v0, v1 ; v1 = 0 +; return v5 +; } + +function %icmp_ule_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 1 + v2 = icmp ule v0, v1 + return v2 +} + +; function %icmp_ule_1(i32) -> i8 fast { +; block0(v0: i32): +; v3 = iconst.i32 2 +; v4 = icmp ult v0, v3 ; v3 = 2 +; return v4 ; } function %icmp_ule_umax(i32) -> i8 { @@ -351,6 +503,20 @@ block0(v0: i32): ; return v3 ; v3 = 1 ; } +function %icmp_ule_umax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0xFFFF_FFFE + v2 = icmp ule v0, v1 + return v2 +} + +; function %icmp_ule_umax_minus_1(i32) -> i8 fast { +; block0(v0: i32): +; v3 = iconst.i32 0xffff_ffff +; v5 = icmp ne v0, v3 ; v3 = 0xffff_ffff +; return v5 +; } + function %icmp_ule_smin(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0x8000_0000 @@ -360,9 +526,23 @@ block0(v0: i32): ; function %icmp_ule_smin(i32) -> i8 fast { ; block0(v0: i32): -; v1 = iconst.i32 0x8000_0000 -; v2 = icmp ule v0, v1 ; v1 = 0x8000_0000 -; return v2 +; v3 = iconst.i32 0x8000_0001 +; v4 = icmp ult v0, v3 ; v3 = 0x8000_0001 +; return v4 +; } + +function %icmp_ule_smin_plus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x8000_0001 + v2 = icmp ule v0, v1 + return v2 +} + +; function %icmp_ule_smin_plus_1(i32) -> i8 fast { +; block0(v0: i32): +; v3 = iconst.i32 0x8000_0002 +; v4 = icmp ult v0, v3 ; v3 = 0x8000_0002 +; return v4 ; } function %icmp_ule_smax(i32) -> i8 { @@ -374,9 +554,23 @@ block0(v0: i32): ; function %icmp_ule_smax(i32) -> i8 fast { ; block0(v0: i32): -; v1 = iconst.i32 0x7fff_ffff -; v2 = icmp ule v0, v1 ; v1 = 0x7fff_ffff -; return v2 +; v3 = iconst.i32 0x8000_0000 +; v4 = icmp ult v0, v3 ; v3 = 0x8000_0000 +; return v4 +; } + +function %icmp_ule_smax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x7FFF_FFFE + v2 = icmp ule v0, v1 + return v2 +} + +; function %icmp_ule_smax_minus_1(i32) -> i8 fast { +; block0(v0: i32): +; v3 = iconst.i32 0x7fff_ffff +; v4 = icmp ult v0, v3 ; v3 = 0x7fff_ffff +; return v4 ; } function %icmp_ugt_umin(i32) -> i8 { @@ -393,6 +587,20 @@ block0(v0: i32): ; return v3 ; } +function %icmp_ugt_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 1 + v2 = icmp ugt v0, v1 + return v2 +} + +; function %icmp_ugt_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 1 +; v2 = icmp ugt v0, v1 ; v1 = 1 +; return v2 +; } + function %icmp_ugt_umax(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0xFFFF_FFFF @@ -406,6 +614,20 @@ block0(v0: i32): ; return v3 ; v3 = 0 ; } +function %icmp_ugt_umax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0xFFFF_FFFE + v2 = icmp ugt v0, v1 + return v2 +} + +; function %icmp_ugt_umax_minus_1(i32) -> i8 fast { +; block0(v0: i32): +; v3 = iconst.i32 0xffff_ffff +; v4 = icmp eq v0, v3 ; v3 = 0xffff_ffff +; return v4 +; } + function %icmp_ugt_smin(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0x8000_0000 @@ -420,6 +642,20 @@ block0(v0: i32): ; return v2 ; } +function %icmp_ugt_smin_plus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x8000_0001 + v2 = icmp ugt v0, v1 + return v2 +} + +; function %icmp_ugt_smin_plus_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 0x8000_0001 +; v2 = icmp ugt v0, v1 ; v1 = 0x8000_0001 +; return v2 +; } + function %icmp_ugt_smax(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0x7FFF_FFFF @@ -434,6 +670,20 @@ block0(v0: i32): ; return v2 ; } +function %icmp_ugt_smax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x7FFF_FFFE + v2 = icmp ugt v0, v1 + return v2 +} + +; function %icmp_ugt_smax_minus_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 0x7fff_fffe +; v2 = icmp ugt v0, v1 ; v1 = 0x7fff_fffe +; return v2 +; } + function %icmp_uge_umin(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0 @@ -447,6 +697,20 @@ block0(v0: i32): ; return v3 ; v3 = 1 ; } +function %icmp_uge_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 1 + v2 = icmp uge v0, v1 + return v2 +} + +; function %icmp_uge_1(i32) -> i8 fast { +; block0(v0: i32): +; v3 = iconst.i32 0 +; v5 = icmp ne v0, v3 ; v3 = 0 +; return v5 +; } + function %icmp_uge_umax(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0xFFFF_FFFF @@ -456,9 +720,23 @@ block0(v0: i32): ; function %icmp_uge_umax(i32) -> i8 fast { ; block0(v0: i32): -; v1 = iconst.i32 0xffff_ffff -; v3 = icmp eq v0, v1 ; v1 = 0xffff_ffff -; return v3 +; v4 = iconst.i32 0xffff_fffe +; v5 = icmp ugt v0, v4 ; v4 = 0xffff_fffe +; return v5 +; } + +function %icmp_uge_umax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0xFFFF_FFFE + v2 = icmp uge v0, v1 + return v2 +} + +; function %icmp_uge_umax_minus_1(i32) -> i8 fast { +; block0(v0: i32): +; v3 = iconst.i32 0xffff_fffd +; v4 = icmp ugt v0, v3 ; v3 = 0xffff_fffd +; return v4 ; } function %icmp_uge_smin(i32) -> i8 { @@ -470,9 +748,23 @@ block0(v0: i32): ; function %icmp_uge_smin(i32) -> i8 fast { ; block0(v0: i32): -; v1 = iconst.i32 0x8000_0000 -; v2 = icmp uge v0, v1 ; v1 = 0x8000_0000 -; return v2 +; v3 = iconst.i32 0x7fff_ffff +; v4 = icmp ugt v0, v3 ; v3 = 0x7fff_ffff +; return v4 +; } + +function %icmp_uge_smin_plus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x8000_0001 + v2 = icmp uge v0, v1 + return v2 +} + +; function %icmp_uge_smin_plus_1(i32) -> i8 fast { +; block0(v0: i32): +; v3 = iconst.i32 0x8000_0000 +; v4 = icmp ugt v0, v3 ; v3 = 0x8000_0000 +; return v4 ; } function %icmp_uge_smax(i32) -> i8 { @@ -484,9 +776,23 @@ block0(v0: i32): ; function %icmp_uge_smax(i32) -> i8 fast { ; block0(v0: i32): -; v1 = iconst.i32 0x7fff_ffff -; v2 = icmp uge v0, v1 ; v1 = 0x7fff_ffff -; return v2 +; v3 = iconst.i32 0x7fff_fffe +; v4 = icmp ugt v0, v3 ; v3 = 0x7fff_fffe +; return v4 +; } + +function %icmp_uge_smax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x7FFF_FFFE + v2 = icmp uge v0, v1 + return v2 +} + +; function %icmp_uge_smax_minus_1(i32) -> i8 fast { +; block0(v0: i32): +; v3 = iconst.i32 0x7fff_fffd +; v4 = icmp ugt v0, v3 ; v3 = 0x7fff_fffd +; return v4 ; } function %icmp_slt_umin(i32) -> i8 { @@ -503,6 +809,20 @@ block0(v0: i32): ; return v2 ; } +function %icmp_slt_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 1 + v2 = icmp slt v0, v1 + return v2 +} + +; function %icmp_slt_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 1 +; v9 = icmp slt v0, v1 ; v1 = 1 +; return v9 +; } + function %icmp_slt_umax(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0xFFFF_FFFF @@ -517,6 +837,20 @@ block0(v0: i32): ; return v2 ; } +function %icmp_slt_umax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0xFFFF_FFFE + v2 = icmp slt v0, v1 + return v2 +} + +; function %icmp_slt_umax_minus_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 0xffff_fffe +; v2 = icmp slt v0, v1 ; v1 = 0xffff_fffe +; return v2 +; } + function %icmp_slt_smin(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0x8000_0000 @@ -530,6 +864,20 @@ block0(v0: i32): ; return v3 ; v3 = 0 ; } +function %icmp_slt_smin_plus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x8000_0001 + v2 = icmp slt v0, v1 + return v2 +} + +; function %icmp_slt_smin_plus_1(i32) -> i8 fast { +; block0(v0: i32): +; v3 = iconst.i32 0x8000_0000 +; v4 = icmp eq v0, v3 ; v3 = 0x8000_0000 +; return v4 +; } + function %icmp_slt_smax(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0x7FFF_FFFF @@ -544,6 +892,20 @@ block0(v0: i32): ; return v3 ; } +function %icmp_slt_smax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x7FFF_FFFE + v2 = icmp slt v0, v1 + return v2 +} + +; function %icmp_slt_smax_minus_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 0x7fff_fffe +; v2 = icmp slt v0, v1 ; v1 = 0x7fff_fffe +; return v2 +; } + function %icmp_sle_umin(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0 @@ -554,8 +916,22 @@ block0(v0: i32): ; function %icmp_sle_umin(i32) -> i8 fast { ; block0(v0: i32): ; v1 = iconst.i32 0 -; v2 = icmp sle v0, v1 ; v1 = 0 -; return v2 +; v9 = icmp sle v0, v1 ; v1 = 0 +; return v9 +; } + +function %icmp_sle_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 1 + v2 = icmp sle v0, v1 + return v2 +} + +; function %icmp_sle_1(i32) -> i8 fast { +; block0(v0: i32): +; v3 = iconst.i32 2 +; v4 = icmp slt v0, v3 ; v3 = 2 +; return v4 ; } function %icmp_sle_umax(i32) -> i8 { @@ -567,8 +943,22 @@ block0(v0: i32): ; function %icmp_sle_umax(i32) -> i8 fast { ; block0(v0: i32): -; v3 = iconst.i32 0 -; v4 = icmp slt v0, v3 ; v3 = 0 +; v5 = iconst.i32 0 +; v6 = icmp slt v0, v5 ; v5 = 0 +; return v6 +; } + +function %icmp_sle_umax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0xFFFF_FFFE + v2 = icmp sle v0, v1 + return v2 +} + +; function %icmp_sle_umax_minus_1(i32) -> i8 fast { +; block0(v0: i32): +; v3 = iconst.i32 0xffff_ffff +; v4 = icmp slt v0, v3 ; v3 = 0xffff_ffff ; return v4 ; } @@ -582,8 +972,22 @@ block0(v0: i32): ; function %icmp_sle_smin(i32) -> i8 fast { ; block0(v0: i32): ; v1 = iconst.i32 0x8000_0000 -; v3 = icmp eq v0, v1 ; v1 = 0x8000_0000 -; return v3 +; v5 = icmp eq v0, v1 ; v1 = 0x8000_0000 +; return v5 +; } + +function %icmp_sle_smin_plus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x8000_0001 + v2 = icmp sle v0, v1 + return v2 +} + +; function %icmp_sle_smin_plus_1(i32) -> i8 fast { +; block0(v0: i32): +; v3 = iconst.i32 0x8000_0002 +; v4 = icmp slt v0, v3 ; v3 = 0x8000_0002 +; return v4 ; } function %icmp_sle_smax(i32) -> i8 { @@ -599,6 +1003,20 @@ block0(v0: i32): ; return v3 ; v3 = 1 ; } +function %icmp_sle_smax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x7FFF_FFFE + v2 = icmp sle v0, v1 + return v2 +} + +; function %icmp_sle_smax_minus_1(i32) -> i8 fast { +; block0(v0: i32): +; v3 = iconst.i32 0x7fff_ffff +; v5 = icmp ne v0, v3 ; v3 = 0x7fff_ffff +; return v5 +; } + function %icmp_sgt_umin(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0 @@ -613,6 +1031,20 @@ block0(v0: i32): ; return v2 ; } +function %icmp_sgt_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 1 + v2 = icmp sgt v0, v1 + return v2 +} + +; function %icmp_sgt_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 1 +; v2 = icmp sgt v0, v1 ; v1 = 1 +; return v2 +; } + function %icmp_sgt_umax(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0xFFFF_FFFF @@ -627,6 +1059,20 @@ block0(v0: i32): ; return v4 ; } +function %icmp_sgt_umax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0xFFFF_FFFE + v2 = icmp sgt v0, v1 + return v2 +} + +; function %icmp_sgt_umax_minus_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 0xffff_fffe +; v2 = icmp sgt v0, v1 ; v1 = 0xffff_fffe +; return v2 +; } + function %icmp_sgt_smin(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0x8000_0000 @@ -641,6 +1087,20 @@ block0(v0: i32): ; return v3 ; } +function %icmp_sgt_smin_plus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x8000_0001 + v2 = icmp sgt v0, v1 + return v2 +} + +; function %icmp_sgt_smin_plus_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 0x8000_0001 +; v2 = icmp sgt v0, v1 ; v1 = 0x8000_0001 +; return v2 +; } + function %icmp_sgt_smax(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0x7FFF_FFFF @@ -654,6 +1114,20 @@ block0(v0: i32): ; return v3 ; v3 = 0 ; } +function %icmp_sgt_smax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x7FFF_FFFE + v2 = icmp sgt v0, v1 + return v2 +} + +; function %icmp_sgt_smax_minus_1(i32) -> i8 fast { +; block0(v0: i32): +; v3 = iconst.i32 0x7fff_ffff +; v4 = icmp eq v0, v3 ; v3 = 0x7fff_ffff +; return v4 +; } + function %icmp_sge_umin(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0 @@ -668,6 +1142,20 @@ block0(v0: i32): ; return v2 ; } +function %icmp_sge_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 1 + v2 = icmp sge v0, v1 + return v2 +} + +; function %icmp_sge_1(i32) -> i8 fast { +; block0(v0: i32): +; v3 = iconst.i32 0 +; v4 = icmp sgt v0, v3 ; v3 = 0 +; return v4 +; } + function %icmp_sge_umax(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0xFFFF_FFFF @@ -682,6 +1170,20 @@ block0(v0: i32): ; return v2 ; } +function %icmp_sge_umax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0xFFFF_FFFE + v2 = icmp sge v0, v1 + return v2 +} + +; function %icmp_sge_umax_minus_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 0xffff_fffe +; v2 = icmp sge v0, v1 ; v1 = 0xffff_fffe +; return v2 +; } + function %icmp_sge_smin(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0x8000_0000 @@ -695,6 +1197,20 @@ block0(v0: i32): ; return v3 ; v3 = 1 ; } +function %icmp_sge_smin_plus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x8000_0001 + v2 = icmp sge v0, v1 + return v2 +} + +; function %icmp_sge_smin_plus_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 0x8000_0001 +; v2 = icmp sge v0, v1 ; v1 = 0x8000_0001 +; return v2 +; } + function %icmp_sge_smax(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0x7FFF_FFFF @@ -709,6 +1225,20 @@ block0(v0: i32): ; return v3 ; } +function %icmp_sge_smax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x7FFF_FFFE + v2 = icmp sge v0, v1 + return v2 +} + +; function %icmp_sge_smax_minus_1(i32) -> i8 fast { +; block0(v0: i32): +; v1 = iconst.i32 0x7fff_fffe +; v2 = icmp sge v0, v1 ; v1 = 0x7fff_fffe +; return v2 +; } + function %icmp_and_eq_eq(i32, i32) -> i8 { block0(v0: i32, v1: i32): v2 = icmp eq v0, v1 diff --git a/cranelift/filetests/filetests/egraph/icmp.clif b/cranelift/filetests/filetests/egraph/icmp.clif index 44f50201dbda..03f2350b2cf6 100644 --- a/cranelift/filetests/filetests/egraph/icmp.clif +++ b/cranelift/filetests/filetests/egraph/icmp.clif @@ -77,9 +77,9 @@ block0(v0: i16): ; function %slt_one(i16) -> i8 fast { ; block0(v0: i16): -; v3 = iconst.i16 0 -; v4 = icmp sle v0, v3 ; v3 = 0 -; return v4 +; v1 = iconst.i16 1 +; v9 = icmp slt v0, v1 ; v1 = 1 +; return v9 ; } function %uge_one(i32) -> i8 { @@ -92,8 +92,8 @@ block0(v0: i32): ; function %uge_one(i32) -> i8 fast { ; block0(v0: i32): ; v3 = iconst.i32 0 -; v4 = icmp ne v0, v3 ; v3 = 0 -; return v4 +; v5 = icmp ne v0, v3 ; v3 = 0 +; return v5 ; } function %ult_one(i8) -> i8 { diff --git a/cranelift/filetests/filetests/egraph/make-icmp-parameterized-tests.sh b/cranelift/filetests/filetests/egraph/make-icmp-parameterized-tests.sh index ab6e5417539c..1b495080a27b 100755 --- a/cranelift/filetests/filetests/egraph/make-icmp-parameterized-tests.sh +++ b/cranelift/filetests/filetests/egraph/make-icmp-parameterized-tests.sh @@ -2,7 +2,7 @@ set -e cd $(dirname "$0") -out=parameterized-icmp.clif +out=icmp-parameterized.clif CCS="eq ne ult ule ugt uge slt sle sgt sge" function main { @@ -42,6 +42,13 @@ block0(v0: i32): return v2 } +function %icmp_${cc}_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 1 + v2 = icmp ${cc} v0, v1 + return v2 +} + function %icmp_${cc}_umax(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0xFFFF_FFFF @@ -49,6 +56,13 @@ block0(v0: i32): return v2 } +function %icmp_${cc}_umax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0xFFFF_FFFE + v2 = icmp ${cc} v0, v1 + return v2 +} + function %icmp_${cc}_smin(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0x8000_0000 @@ -56,6 +70,13 @@ block0(v0: i32): return v2 } +function %icmp_${cc}_smin_plus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x8000_0001 + v2 = icmp ${cc} v0, v1 + return v2 +} + function %icmp_${cc}_smax(i32) -> i8 { block0(v0: i32): v1 = iconst.i32 0x7FFF_FFFF @@ -63,6 +84,13 @@ block0(v0: i32): return v2 } +function %icmp_${cc}_smax_minus_1(i32) -> i8 { +block0(v0: i32): + v1 = iconst.i32 0x7FFF_FFFE + v2 = icmp ${cc} v0, v1 + return v2 +} + EOF done diff --git a/cranelift/filetests/filetests/egraph/spaceship.clif b/cranelift/filetests/filetests/egraph/spaceship.clif index 7c1c8e2be099..de5eb9031717 100644 --- a/cranelift/filetests/filetests/egraph/spaceship.clif +++ b/cranelift/filetests/filetests/egraph/spaceship.clif @@ -425,8 +425,8 @@ block0(v0: i16, v1: i16): v5 = iconst.i8 0 v6 = icmp sle v4, v5 return v6 - ; check: v7 = icmp sle v0, v1 - ; check: return v7 + ; check: v15 = icmp sle v0, v1 + ; check: return v15 } function %sgt_via_cmp(i32, i32) -> i8 {