[Bug tree-optimization/92765] [10 Regression] Wrong code caused by folding of -Wstring-compare since r276773
jakub at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Tue Dec 3 11:36:00 GMT 2019
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;
}
More information about the Gcc-bugs
mailing list