https://gcc.gnu.org/g:45a3277149d95a51cf9109cab87ee39a7dce73e2

commit r15-5380-g45a3277149d95a51cf9109cab87ee39a7dce73e2
Author: Andrew Pinski <quic_apin...@quicinc.com>
Date:   Sun Nov 17 20:21:58 2024 -0800

    match: Fix the `max<a,b>==0` pattern for pointers [PR117646]
    
    For pointers I forgot that BIT_IOR_EXPR is not valid so when
    I added the pattern to convert `max<a,b> != 0` (r15-5356), GCC
    would start to ICEing saying pointer types were not valid for
    BIT_IOR_EXPR.
    This fixes the problem by casting to the unsigned type of the
    inner type. There was another way of fixing this to handling it
    as `a == 0 & b == 0` but both match and reassoication (for pointers)
    will then convert it back into the form I am creating here so
    let's just use that form instead.
    
    Bootstrapped and tested on x86_64-linux-gnu.
    
            PR tree-optimization/117646
    
    gcc/ChangeLog:
    
            * match.pd (`max<a,b>==0`): Add casts to `unsigned type`.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/torture/minmaxneeqptr-1.c: New test.
    
    Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com>

Diff:
---
 gcc/match.pd                                   |  6 ++++--
 gcc/testsuite/gcc.dg/torture/minmaxneeqptr-1.c | 21 +++++++++++++++++++++
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index 4bec24a21b29..f5181325f3b9 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4799,9 +4799,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
    MAX (A, B) != 0 -> (A|B) != 0 iff unsigned.  */
 (for cmp (eq ne)
  (simplify
-  (cmp (max @0 @1) integer_zerop@2)
+  (cmp (max @0 @1) integer_zerop)
   (if (TYPE_UNSIGNED (TREE_TYPE (@0)))
-   (cmp (bit_ior @0 @1) @2))))
+   (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); }
+    (cmp (bit_ior (convert:utype @0) (convert:utype @1))
+         { build_zero_cst (utype); } )))))
 
 /* Undo fancy ways of writing max/min or other ?: expressions, like
    a - ((a - b) & -(a < b))  and  a - (a - b) * (a < b) into (a < b) ? b : a.
diff --git a/gcc/testsuite/gcc.dg/torture/minmaxneeqptr-1.c 
b/gcc/testsuite/gcc.dg/torture/minmaxneeqptr-1.c
new file mode 100644
index 000000000000..aa45722330f4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/minmaxneeqptr-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+
+/* PR tree-optimization/117646 */
+
+int maxeq(char *a, char *b) {
+  char *p = a < b ? b : a;
+  return p == (void*)0;
+}
+int maxne(char *a, char *b) {
+  char *p = a < b ? b : a;
+  return p == (void*)0;
+}
+
+int mineq(char *a, char *b) {
+  char *p = a > b ? b : a;
+  return p == (void*)0;
+}
+int minne(char *a, char *b) {
+  char *p = a > b ? b : a;
+  return p == (void*)0;
+}

Reply via email to