]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix `~X & X` and `~X | X` patterns
authorAndrew Pinski <apinski@marvell.com>
Wed, 2 Aug 2023 22:54:20 +0000 (15:54 -0700)
committerAndrew Pinski <apinski@marvell.com>
Thu, 3 Aug 2023 02:32:04 +0000 (19:32 -0700)
As Jakub noticed in https://gcc.gnu.org/pipermail/gcc-patches/2023-August/626039.html
what I did was not totally correct because sometimes chosing the wrong type.
So to get back to what the original code but keeping around the use of bitwise_inverted_equal_p,
we just need to check if the types of the two catupures are the same type.

Also adds a testcase for the problem Jakub found.

Committed as obvious after a bootstrap and test.

gcc/ChangeLog:

* match.pd (`~X & X`): Check that the types match.
(`~x | x`, `~x ^ x`): Likewise.

gcc/testsuite/ChangeLog:

* gcc.c-torture/execute/20230802-1.c: New test.

gcc/match.pd
gcc/testsuite/gcc.c-torture/execute/20230802-1.c [new file with mode: 0644]

index c62f205c13c72f6925ae13b6d9aca65a7f9b73b5..53e622bf28f73d6e424677db4938091b7b287001 100644 (file)
@@ -1158,7 +1158,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 /* Simplify ~X & X as zero.  */
 (simplify
  (bit_and (convert? @0) (convert? @1))
- (if (bitwise_inverted_equal_p (@0, @1))
+ (if (types_match (TREE_TYPE (@0), TREE_TYPE (@1))
+      && bitwise_inverted_equal_p (@0, @1))
   { build_zero_cst (type); }))
 
 /* PR71636: Transform x & ((1U << b) - 1) -> x & ~(~0U << b);  */
@@ -1397,7 +1398,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 (for op (bit_ior bit_xor)
  (simplify
   (op (convert? @0) (convert? @1))
-  (if (bitwise_inverted_equal_p (@0, @1))
+  (if (types_match (TREE_TYPE (@0), TREE_TYPE (@1))
+       && bitwise_inverted_equal_p (@0, @1))
    (convert { build_all_ones_cst (TREE_TYPE (@0)); }))))
 
 /* x ^ x -> 0 */
diff --git a/gcc/testsuite/gcc.c-torture/execute/20230802-1.c b/gcc/testsuite/gcc.c-torture/execute/20230802-1.c
new file mode 100644 (file)
index 0000000..8802ffa
--- /dev/null
@@ -0,0 +1,68 @@
+/*  We used to simplify these incorrectly.  */
+__attribute__((noipa))
+long long
+foo (unsigned int x)
+{
+  int y = x;
+  y = ~y;
+  return ((long long) x) & y;
+}
+
+__attribute__((noipa))
+long long
+foo_v (volatile unsigned int x)
+{
+  volatile int y = x;
+  y = ~y;
+  return ((long long) x) & y;
+}
+
+__attribute__((noipa))
+long long
+bar (unsigned int x)
+{
+  int y = x;
+  y = ~y;
+  return ((long long) x) ^ y;
+}
+
+__attribute__((noipa))
+long long
+bar_v (volatile unsigned int x)
+{
+  volatile int y = x;
+  y = ~y;
+  return ((long long) x) ^ y;
+}
+
+__attribute__((noipa))
+long long
+baz (unsigned int x)
+{
+  int y = x;
+  y = ~y;
+  return y ^ ((long long) x);
+}
+
+__attribute__((noipa))
+long long
+baz_v (volatile unsigned int x)
+{
+  volatile int y = x;
+  y = ~y;
+  return y ^ ((long long) x);
+}
+
+
+int main()
+{
+  for(int t = -1; t <= 1; t++)
+    {
+      if (foo(t) != foo_v(t))
+        __builtin_abort ();
+      if (bar(t) != bar_v(t))
+        __builtin_abort ();
+      if (baz(t) != baz_v(t))
+        __builtin_abort ();
+    }
+}