From: Daniel Barboza <[email protected]>
Also adding the variant "(A>>C) == (B>>C) -> (A^B) < (1<<C)"
Bootstrapped and regression tested on x86.
PR tree-optimization/110010
gcc/ChangeLog:
* match.pd (`(A>>C) NE|EQ (B>>C) -> (A^B) GE|LT (1<<C)`): New
pattern.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/pr110010.c: New test.
---
gcc/match.pd | 15 +++++++++++++++
gcc/testsuite/gcc.dg/tree-ssa/pr110010.c | 14 ++++++++++++++
2 files changed, 29 insertions(+)
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr110010.c
diff --git a/gcc/match.pd b/gcc/match.pd
index 7f16fd4e081..d98971e7220 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2615,6 +2615,21 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& tree_to_shwi (@1) < TYPE_PRECISION (TREE_TYPE (@0)))
(eq @0 @2)))
+/* PR110010: (A >> C) != (B >> C) -> (A ^ B) >= (1 << C)
+ and likewise (A >> C) == (B >> C) -> (A ^ B) < (1 << C).
+
+ Note that maybe_canonicalize_comparison_1 related patterns
+ might change ">= (1 << C)" to "> (1 << C - 1)" and
+ "< (1 << C)" to "<= (1 << C - 1)". */
+(for cmp (ne eq)
+ icmp (ge lt)
+ (simplify
+ (cmp (rshift @0 INTEGER_CST@2) (rshift @1 INTEGER_CST@2))
+ (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
+ && INTEGRAL_TYPE_P (TREE_TYPE (@1))
+ && TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (TREE_TYPE (@1)))
+ (icmp (bit_xor @0 @1) (lshift { build_one_cst (TREE_TYPE (@0)); } @2)))))
+
/* Convert ~ (-A) to A - 1. */
(simplify
(bit_not (convert? (negate @0)))
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr110010.c
b/gcc/testsuite/gcc.dg/tree-ssa/pr110010.c
new file mode 100644
index 00000000000..bda6f1191b1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr110010.c
@@ -0,0 +1,14 @@
+/* { dg-additional-options -O1 } */
+/* { dg-additional-options -fdump-tree-gimple } */
+#define N 5
+
+unsigned f(unsigned a, unsigned b)
+{
+ return (a>>N) != (b>>N);
+}
+
+unsigned f2(unsigned a, unsigned b)
+{
+ return (a>>N) == (b>>N);
+}
+/* { dg-final { scan-tree-dump-times " >> " 0 gimple } } */
--
2.43.0