https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92765
--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Now, determine_min_objsize has been introduced for the strcmp_eq optimization and maybe doing something conservative for the strcmp -> ~[0, 0] or [0, 0] optimization there like get_base_address on the ADDR_EXPR argument would not be appropriate for that use case, if the original use case is "is there a guarantee at least that many bytes will be actually accessible". So maybe the bug is actually in the caller, that assumes that if determine_min_objsize returns something small and we need to strcmp that with some larger string that it can't be equal. That is wrong though. Say if determine_min_objsize successfully uses compute_builtin_object_size with kind 2, on _3 = PHI <_1, _2> where _1 = __builtin_malloc (2); and _2 = __builtin_malloc (16); Here, __builtin_object_size (_3, 2) is 2 and __builtin_object_size (_3, 0) is 16. If there is __builtin_strcmp (_3, "abcd"), we can't assume it is not equal simply because determine_min_objsize returned 2 for _3, we would need to use (non-existent) determine_max_objsize for that. Perhaps to determine if it should warn determine_min_objsize is acceptable, though it likely should use both determine_min_objsize and determine_max_objsize and differentiate between is vs. may be in the warning (perhaps have two levels of the warning). But for code generation, determine_min_objsize is wrong. __attribute__((noipa)) int bar (char *x, int y) { asm volatile ("" : : "g" (x), "g" (y) : "memory"); if (y == 0) __builtin_strcpy (x, "abcd"); return y; } __attribute__((noipa)) char * foo (int x) { char *p; if (x) p = __builtin_malloc (2); else p = __builtin_calloc (16, 1); if (bar (p, x)) return p; if (__builtin_strcmp (p, "abcd") != 0) __builtin_abort (); return p; } int main () { __builtin_free (foo (0)); __builtin_free (foo (1)); return 0; }