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.