tree-optimization/109609 - correctly interpret arg size in fnspec

By majority vote and a hint from the API name which is
arg_max_access_size_given_by_arg_p this interprets a memory access
size specified as given as other argument such as for strncpy
in the testcase which has "1cO313" as specifying the _maximum_
size read/written rather than the exact size.  There are two
uses interpreting it that way already and one differing.  The
following adjusts the differing and clarifies the documentation.

	PR tree-optimization/109609
	* attr-fnspec.h (arg_max_access_size_given_by_arg_p):
	Clarify semantics.
	* tree-ssa-alias.cc (check_fnspec): Correctly interpret
	the size given by arg_max_access_size_given_by_arg_p as
	maximum, not exact, size.

	* gcc.dg/torture/pr109609.c: New testcase.
This commit is contained in:
Richard Biener 2023-04-25 14:56:44 +02:00
parent 1c101fcfaa
commit e8d0035301
3 changed files with 43 additions and 5 deletions

View file

@ -54,7 +54,7 @@
' ' nothing is known
't' the size of value written/read corresponds to the size of
of the pointed-to type of the argument type
'1'...'9' specifies the size of value written/read is given by the
'1'...'9' specifies the size of value written/read is bound by the
specified argument
*/
@ -169,7 +169,7 @@ public:
&& str[idx] != 'x' && str[idx] != 'X';
}
/* Return true if load of memory pointed to by argument I is specified
/* Return true if load of memory pointed to by argument I is bound
by another argument. In this case set ARG. */
bool
arg_max_access_size_given_by_arg_p (unsigned int i, unsigned int *arg)

View file

@ -0,0 +1,26 @@
/* { dg-do run } */
#define N 23
#define MAX_LEN 13
char dst[N + 1];
void __attribute__((noipa))
invert(const char *id)
{
char buf[MAX_LEN];
char *ptr = buf + sizeof(buf); // start from the end of buf
*(--ptr) = '\0'; // terminate string
while (*id && ptr > buf) {
*(--ptr) = *(id++); // copy id backwards
}
__builtin_strncpy(dst, ptr, N); // copy ptr/buf to dst
}
int main()
{
invert("abcde");
if (__builtin_strcmp(dst, "edcba"))
__builtin_abort();
return 0;
}

View file

@ -2726,9 +2726,21 @@ check_fnspec (gcall *call, ao_ref *ref, bool clobber)
t = TREE_CHAIN (t);
size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_VALUE (t)));
}
ao_ref_init_from_ptr_and_size (&dref,
gimple_call_arg (call, i),
size);
poly_int64 size_hwi;
if (size
&& poly_int_tree_p (size, &size_hwi)
&& coeffs_in_range_p (size_hwi, 0,
HOST_WIDE_INT_MAX / BITS_PER_UNIT))
{
size_hwi = size_hwi * BITS_PER_UNIT;
ao_ref_init_from_ptr_and_range (&dref,
gimple_call_arg (call, i),
true, 0, -1, size_hwi);
}
else
ao_ref_init_from_ptr_and_range (&dref,
gimple_call_arg (call, i),
false, 0, -1, -1);
if (refs_may_alias_p_1 (&dref, ref, false))
return 1;
}