Fix `~X & X` and `~X | X` patterns

Message ID 20230803023110.2271301-1-apinski@marvell.com
State Unresolved
Headers
Series Fix `~X & X` and `~X | X` patterns |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Andrew Pinski Aug. 3, 2023, 2:31 a.m. UTC
  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                                  |  6 +-
 .../gcc.c-torture/execute/20230802-1.c        | 68 +++++++++++++++++++
 2 files changed, 72 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/execute/20230802-1.c
  

Patch

diff --git a/gcc/match.pd b/gcc/match.pd
index c62f205c13c..53e622bf28f 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -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
index 00000000000..8802ffa8238
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20230802-1.c
@@ -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 ();
+    }
+}