https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117646

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
               Host|x86_64-pc-linux-gnu         |
            Summary|[15 Regression] ICE:        |[15 Regression] ICE:
                   |verify_gimple failed        |verify_gimple failed
                   |invalid types for           |invalid types for
                   |‘bit_ior_expr’              |‘bit_ior_expr’ with pointer
                   |                            |type `max` and comparison
                   |                            |to nullptr
             Target|x86_64-pc-linux-gnu         |

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Reduced testcase:
```
int f(char *a, char *b) {
  char *p = a < b ? b : a;
  return p == 0;
}
```


The fixed up pattern I think:
```
/* MAX (A, B) == 0 -> a == 0 & a == 0 iff unsigned.
   MAX (A, B) != 0 -> a != 0 | b != 0 iff unsigned.  */
(for cmp      (eq      ne     )
     outerbit (bit_and bit_ior)
 (simplify
  (cmp (max @0 @1) integer_zerop@2)
  (if (TYPE_UNSIGNED (TREE_TYPE (@0)))
   (outerbit (cmp @0 @2) (cmp @1 @2)))))
```

That is don't fold directly into `(a|b) ==/!= 0` .

Or this:
```
/* MAX (A, B) == 0 -> (A|B) == 0 iff unsigned.
   MAX (A, B) != 0 -> (A|B) != 0 iff unsigned.  */
(for cmp (eq ne)
 (simplify
  (cmp (max @0 @1) integer_zerop)
  (if (TYPE_UNSIGNED (TREE_TYPE (@0)))
   (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); }
    (cmp (bit_ior (convert:utype @0) (convert:utype @1))
         { build_zero_cst (utype); } )))))
```


Which adds the conversion for pointer. I think I will go with the second one
since we simplify over to that later on anyways.

I will finish this patch up tomorrow.

Reply via email to