diff --git a/cranelift/codegen/src/opts/arithmetic.isle b/cranelift/codegen/src/opts/arithmetic.isle index 2e0703ef6c53..a8aa42fdeeec 100644 --- a/cranelift/codegen/src/opts/arithmetic.isle +++ b/cranelift/codegen/src/opts/arithmetic.isle @@ -436,4 +436,140 @@ (rule (simplify (uge ty x (umin ty x y))) (iconst_u ty 1)) (rule (simplify (uge ty x (umin ty y x))) (iconst_u ty 1)) (rule (simplify (ule ty (umin ty x y) x)) (iconst_u ty 1)) -(rule (simplify (ule ty (umin ty y x) x)) (iconst_u ty 1)) \ No newline at end of file +(rule (simplify (ule ty (umin ty y x) x)) (iconst_u ty 1)) + +;; min/max(x,x) --> x +(rule (simplify (umin ty x x)) x) +(rule (simplify (smin ty x x)) x) +(rule (simplify (umax ty x x)) x) +(rule (simplify (smax ty x x)) x) + +;; max(max(x, y), x) --> max(x, y) +(rule (simplify (smax ty (smax ty x y) x)) (smax ty x y)) +(rule (simplify (smax ty (smax ty y x) x)) (smax ty x y)) +(rule (simplify (smax ty x (smax ty x y))) (smax ty x y)) +(rule (simplify (smax ty x (smax ty y x))) (smax ty x y)) +(rule (simplify (umax ty (umax ty x y) x)) (umax ty x y)) +(rule (simplify (umax ty (umax ty y x) x)) (umax ty x y)) +(rule (simplify (umax ty x (umax ty x y))) (umax ty x y)) +(rule (simplify (umax ty x (umax ty y x))) (umax ty x y)) + +;; min(min(x, y), x) --> min(x, y) +(rule (simplify (smin ty (smin ty x y) x)) (smin ty x y)) +(rule (simplify (smin ty (smin ty y x) x)) (smin ty x y)) +(rule (simplify (smin ty x (smin ty x y))) (smin ty x y)) +(rule (simplify (smin ty x (smin ty y x))) (smin ty x y)) +(rule (simplify (umin ty (umin ty x y) x)) (umin ty x y)) +(rule (simplify (umin ty (umin ty y x) x)) (umin ty x y)) +(rule (simplify (umin ty x (umin ty x y))) (umin ty x y)) +(rule (simplify (umin ty x (umin ty y x))) (umin ty x y)) + +;; min(max(x, y), y) --> y ; max(min(x, y), y) --> y +(rule (simplify (smin ty (smax ty x y) y)) y) +(rule (simplify (smin ty (smax ty y x) y)) y) +(rule (simplify (smin ty y (smax ty x y))) y) +(rule (simplify (smin ty y (smax ty y x))) y) +(rule (simplify (umin ty (umax ty x y) y)) y) +(rule (simplify (umin ty (umax ty y x) y)) y) +(rule (simplify (umin ty y (umax ty x y))) y) +(rule (simplify (umin ty y (umax ty y x))) y) +(rule (simplify (smax ty (smin ty x y) y)) y) +(rule (simplify (smax ty (smin ty y x) y)) y) +(rule (simplify (smax ty y (smin ty x y))) y) +(rule (simplify (smax ty y (smin ty y x))) y) +(rule (simplify (umax ty (umin ty x y) y)) y) +(rule (simplify (umax ty (umin ty y x) y)) y) +(rule (simplify (umax ty y (umin ty x y))) y) +(rule (simplify (umax ty y (umin ty y x))) y) + +;; min(min(x, y), max(x, y)) --> min(x,y) +(rule (simplify (smin ty (smax ty x y) (smin ty x y))) (smin ty x y)) +(rule (simplify (smin ty (smax ty x y) (smin ty y x))) (smin ty x y)) +(rule (simplify (smin ty (smax ty x y) (umin ty x y))) (umin ty x y)) +(rule (simplify (smin ty (smax ty x y) (umin ty y x))) (umin ty x y)) + +(rule (simplify (smin ty (smin ty x y) (smax ty x y))) (smin ty x y)) +(rule (simplify (smin ty (smin ty x y) (smax ty y x))) (smin ty x y)) +(rule (simplify (smin ty (smin ty x y) (umax ty x y))) (smin ty x y)) +(rule (simplify (smin ty (smin ty x y) (umax ty y x))) (smin ty x y)) + +(rule (simplify (smin ty (umax ty x y) (smin ty x y))) (smin ty x y)) +(rule (simplify (smin ty (umax ty x y) (smin ty y x))) (smin ty x y)) +(rule (simplify (smin ty (umax ty x y) (umin ty x y))) (smin ty x y)) +(rule (simplify (smin ty (umax ty x y) (umin ty y x))) (smin ty x y)) + +(rule (simplify (smin ty (umin ty x y) (smax ty x y))) (umin ty x y)) +(rule (simplify (smin ty (umin ty x y) (smax ty y x))) (umin ty x y)) +(rule (simplify (smin ty (umin ty x y) (umax ty x y))) (smin ty x y)) +(rule (simplify (smin ty (umin ty x y) (umax ty y x))) (smin ty x y)) + +(rule (simplify (umin ty (smax ty x y) (smin ty x y))) (umin ty x y)) +(rule (simplify (umin ty (smax ty x y) (smin ty y x))) (umin ty x y)) +(rule (simplify (umin ty (smax ty x y) (umin ty x y))) (umin ty x y)) +(rule (simplify (umin ty (smax ty x y) (umin ty y x))) (umin ty x y)) + +(rule (simplify (umin ty (smin ty x y) (smax ty x y))) (umin ty x y)) +(rule (simplify (umin ty (smin ty x y) (smax ty y x))) (umin ty x y)) +(rule (simplify (umin ty (smin ty x y) (umax ty x y))) (smin ty x y)) +(rule (simplify (umin ty (smin ty x y) (umax ty y x))) (smin ty x y)) + +(rule (simplify (umin ty (umax ty x y) (smin ty x y))) (smin ty x y)) +(rule (simplify (umin ty (umax ty x y) (smin ty y x))) (smin ty x y)) +(rule (simplify (umin ty (umax ty x y) (umin ty x y))) (umin ty x y)) +(rule (simplify (umin ty (umax ty x y) (umin ty y x))) (umin ty x y)) + +(rule (simplify (umin ty (umin ty x y) (smax ty x y))) (umin ty x y)) +(rule (simplify (umin ty (umin ty x y) (smax ty y x))) (umin ty x y)) +(rule (simplify (umin ty (umin ty x y) (umax ty x y))) (umin ty x y)) +(rule (simplify (umin ty (umin ty x y) (umax ty y x))) (umin ty x y)) + +;; max(min(x, y), max(x, y)) --> max(x, y) +(rule (simplify (smax ty (smax ty x y) (smin ty x y))) (smax ty x y)) +(rule (simplify (smax ty (smax ty x y) (smin ty y x))) (smax ty x y)) +(rule (simplify (smax ty (smax ty x y) (umin ty x y))) (smax ty x y)) +(rule (simplify (smax ty (smax ty x y) (umin ty y x))) (smax ty x y)) + +(rule (simplify (smax ty (smin ty x y) (smax ty x y))) (smax ty x y)) +(rule (simplify (smax ty (smin ty x y) (smax ty y x))) (smax ty x y)) +(rule (simplify (smax ty (smin ty x y) (umax ty x y))) (umax ty x y)) +(rule (simplify (smax ty (smin ty x y) (umax ty y x))) (umax ty x y)) + +(rule (simplify (smax ty (umax ty x y) (smin ty x y))) (umax ty x y)) +(rule (simplify (smax ty (umax ty x y) (smin ty y x))) (umax ty x y)) +(rule (simplify (smax ty (umax ty x y) (umin ty x y))) (smax ty x y)) +(rule (simplify (smax ty (umax ty x y) (umin ty y x))) (smax ty x y)) + +(rule (simplify (smax ty (umin ty x y) (smax ty x y))) (smax ty x y)) +(rule (simplify (smax ty (umin ty x y) (smax ty y x))) (smax ty x y)) +(rule (simplify (smax ty (umin ty x y) (umax ty x y))) (smax ty x y)) +(rule (simplify (smax ty (umin ty x y) (umax ty y x))) (smax ty x y)) + +(rule (simplify (umax ty (smax ty x y) (smin ty x y))) (umax ty x y)) +(rule (simplify (umax ty (smax ty x y) (smin ty y x))) (umax ty x y)) +(rule (simplify (umax ty (smax ty x y) (umin ty x y))) (smax ty x y)) +(rule (simplify (umax ty (smax ty x y) (umin ty y x))) (smax ty x y)) + +(rule (simplify (umax ty (smin ty x y) (smax ty x y))) (umax ty x y)) +(rule (simplify (umax ty (smin ty x y) (smax ty y x))) (umax ty x y)) +(rule (simplify (umax ty (smin ty x y) (umax ty x y))) (umax ty x y)) +(rule (simplify (umax ty (smin ty x y) (umax ty y x))) (umax ty x y)) + +(rule (simplify (umax ty (umax ty x y) (smin ty x y))) (umax ty x y)) +(rule (simplify (umax ty (umax ty x y) (smin ty y x))) (umax ty x y)) +(rule (simplify (umax ty (umax ty x y) (umin ty x y))) (umax ty x y)) +(rule (simplify (umax ty (umax ty x y) (umin ty y x))) (umax ty x y)) + +(rule (simplify (umax ty (umin ty x y) (smax ty x y))) (smax ty x y)) +(rule (simplify (umax ty (umin ty x y) (smax ty y x))) (smax ty x y)) +(rule (simplify (umax ty (umin ty x y) (umax ty x y))) (umax ty x y)) +(rule (simplify (umax ty (umin ty x y) (umax ty y x))) (umax ty x y)) + +;; x > max(x, y) --> 0 +(rule (simplify (sgt ty x (smax ty x y))) (iconst_u ty 0)) +(rule (simplify (sgt ty x (smax ty y x))) (iconst_u ty 0)) +(rule (simplify (slt ty (smax ty x y) x)) (iconst_u ty 0)) +(rule (simplify (slt ty (smax ty y x) x)) (iconst_u ty 0)) +(rule (simplify (ugt ty x (umax ty x y))) (iconst_u ty 0)) +(rule (simplify (ugt ty x (umax ty y x))) (iconst_u ty 0)) +(rule (simplify (ult ty (umax ty x y) x)) (iconst_u ty 0)) +(rule (simplify (ult ty (umax ty y x) x)) (iconst_u ty 0)) \ No newline at end of file diff --git a/cranelift/filetests/filetests/egraph/arithmetic-precise.clif b/cranelift/filetests/filetests/egraph/arithmetic-precise.clif index 7249b7df8d2a..8ea8ec3c9cca 100644 --- a/cranelift/filetests/filetests/egraph/arithmetic-precise.clif +++ b/cranelift/filetests/filetests/egraph/arithmetic-precise.clif @@ -432,3 +432,163 @@ block0(v0: i32, v1: i32): ; return v3 ; } +;; umin(x, x) --> x +function %test_umin_same(i32) -> i32 fast { +block0(v0: i32): + v1 = umin v0, v0 + return v1 +} + +; function %test_umin_same(i32) -> i32 fast { +; block0(v0: i32): +; return v0 +; } + +;; smin(x, x) --> x +function %test_smin_same(i32) -> i32 fast { +block0(v0: i32): + v1 = smin v0, v0 + return v1 +} + +; function %test_smin_same(i32) -> i32 fast { +; block0(v0: i32): +; return v0 +; } + +;; umax(x, x) --> x +function %test_umax_same(i32) -> i32 fast { +block0(v0: i32): + v1 = umax v0, v0 + return v1 +} + +; function %test_umax_same(i32) -> i32 fast { +; block0(v0: i32): +; return v0 +; } + +;; smax(x, x) --> x +function %test_smax_same(i32) -> i32 fast { +block0(v0: i32): + v1 = smax v0, v0 + return v1 +} + +; function %test_smax_same(i32) -> i32 fast { +; block0(v0: i32): +; return v0 +; } + +;; smax(smax(x, y), x) --> smax(x, y) +function %test_smax_nested_absorb(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = smax v0, v1 + v3 = smax v2, v0 + return v3 +} + +; function %test_smax_nested_absorb(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v2 = smax v0, v1 +; return v2 +; } + +;; umax(umax(x, y), x) --> umax(x, y) +function %test_umax_nested_absorb(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = umax v0, v1 + v3 = umax v2, v0 + return v3 +} + +; function %test_umax_nested_absorb(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v2 = umax v0, v1 +; return v2 +; } + +;; smin(smin(x, y), x) --> smin(x, y) +function %test_smin_nested_absorb(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = smin v0, v1 + v3 = smin v2, v0 + return v3 +} + +; function %test_smin_nested_absorb(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v2 = smin v0, v1 +; return v2 +; } + +;; umin(umin(x, y), x) --> umin(x, y) +function %test_umin_nested_absorb(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = umin v0, v1 + v3 = umin v2, v0 + return v3 +} + +; function %test_umin_nested_absorb(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v2 = umin v0, v1 +; return v2 +; } + +;; smin(smax(x, y), y) --> y +function %test_smin_smax_absorb(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = smax v0, v1 + v3 = smin v2, v1 + return v3 +} + +; function %test_smin_smax_absorb(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; return v1 +; } + +;; umax(umin(x, y), y) --> y +function %test_umax_umin_absorb(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = umin v0, v1 + v3 = umax v2, v1 + return v3 +} + +; function %test_umax_umin_absorb(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; return v1 +; } + +;; x > smax(x, y) --> false +function %test_sgt_x_smax(i32, i32) -> i8 fast { +block0(v0: i32, v1: i32): + v2 = smax v0, v1 + v3 = icmp sgt v0, v2 + return v3 +} + +; function %test_sgt_x_smax(i32, i32) -> i8 fast { +; block0(v0: i32, v1: i32): +; v2 = smax v0, v1 +; v3 = icmp sgt v0, v2 +; return v3 +; } + +;; x >_u umax(x, y) --> false +function %test_ugt_x_umax(i32, i32) -> i8 fast { +block0(v0: i32, v1: i32): + v2 = umax v0, v1 + v3 = icmp ugt v0, v2 + return v3 +} + +; function %test_ugt_x_umax(i32, i32) -> i8 fast { +; block0(v0: i32, v1: i32): +; v2 = umax v0, v1 +; v3 = icmp ugt v0, v2 +; return v3 +; } + diff --git a/cranelift/filetests/filetests/runtests/arithmetic.clif b/cranelift/filetests/filetests/runtests/arithmetic.clif index ac85426c0480..037d8bd4f0f5 100644 --- a/cranelift/filetests/filetests/runtests/arithmetic.clif +++ b/cranelift/filetests/filetests/runtests/arithmetic.clif @@ -947,4 +947,122 @@ block0(v0: i32, v1: i32): ; run: %test_ule_umin_x(0, 0) == 1 ; run: %test_ule_umin_x(1, 2) == 1 -; run: %test_ule_umin_x(2, 1) == 1 \ No newline at end of file +; run: %test_ule_umin_x(2, 1) == 1 + +function %test_umin_same(i32) -> i32 fast { +block0(v0: i32): + v1 = umin v0, v0 + return v1 +} + +; run: %test_umin_same(0) == 0 +; run: %test_umin_same(1) == 1 + +function %test_smin_same(i32) -> i32 fast { +block0(v0: i32): + v1 = smin v0, v0 + return v1 +} + +; run: %test_smin_same(0) == 0 +; run: %test_smin_same(1) == 1 + +function %test_umax_same(i32) -> i32 fast { +block0(v0: i32): + v1 = umax v0, v0 + return v1 +} + +; run: %test_umax_same(0) == 0 +; run: %test_umax_same(1) == 1 + +function %test_smax_same(i32) -> i32 fast { +block0(v0: i32): + v1 = smax v0, v0 + return v1 +} + +; run: %test_smax_same(0) == 0 +; run: %test_smax_same(1) == 1 + +function %test_smax_nested_absorb(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = smax v0, v1 + v3 = smax v2, v0 + return v3 +} + +; run: %test_smax_nested_absorb(0, 0) == 0 +; run: %test_smax_nested_absorb(1, 2) == 2 +; run: %test_smax_nested_absorb(2, 1) == 2 + +function %test_umax_nested_absorb(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = umax v0, v1 + v3 = umax v2, v0 + return v3 +} + +; run: %test_umax_nested_absorb(0, 0) == 0 +; run: %test_umax_nested_absorb(1, 2) == 2 + +function %test_smin_nested_absorb(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = smin v0, v1 + v3 = smin v2, v0 + return v3 +} + +; run: %test_smin_nested_absorb(0, 0) == 0 +; run: %test_smin_nested_absorb(1, 2) == 1 +; run: %test_smin_nested_absorb(2, 1) == 1 + +function %test_umin_nested_absorb(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = umin v0, v1 + v3 = umin v2, v0 + return v3 +} + +; run: %test_umin_nested_absorb(0, 0) == 0 +; run: %test_umin_nested_absorb(1, 2) == 1 +; run: %test_umin_nested_absorb(2, 1) == 1 + +function %test_smin_smax_absorb(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = smax v0, v1 + v3 = smin v2, v1 + return v3 +} + +; run: %test_smin_smax_absorb(0, 0) == 0 +; run: %test_smin_smax_absorb(1, 2) == 2 + +function %test_umax_umin_absorb(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = umin v0, v1 + v3 = umax v2, v1 + return v3 +} + +; run: %test_umax_umin_absorb(0, 0) == 0 +; run: %test_umax_umin_absorb(1, 2) == 2 + +function %test_sgt_x_smax(i32, i32) -> i8 fast { +block0(v0: i32, v1: i32): + v2 = smax v0, v1 + v3 = icmp sgt v0, v2 + return v3 +} + +; run: %test_sgt_x_smax(0, 0) == 0 +; run: %test_sgt_x_smax(1, 2) == 0 +function %test_ugt_x_umax(i32, i32) -> i8 fast { +block0(v0: i32, v1: i32): + v2 = umax v0, v1 + v3 = icmp ugt v0, v2 + return v3 +} + +; run: %test_ugt_x_umax(0, 0) == 0 +; run: %test_ugt_x_umax(1, 2) == 0 \ No newline at end of file