On Fri, Aug 28, 2020 at 1:24 PM Erick Ochoa
<erick.oc...@theobroma-systems.com> wrote:
>
> Hi,
>
> I'm testing the precision of IPA-PTA when compiling with -flto. I found
> this case when a global variable is marked as escaping even if the
> variable is a primitive type and no address is taken.
>
> This is the result of IPA-PTA which I believe is wrong.
>
> buff2 = { ESCAPED NONLOCAL }
> buff1 = { }
> buff0 = { ESCAPED NONLOCAL }
>
> The variable must be assigned a value returned from a function from a
> library (i.e. I think the execution path in IPA-PTA is through
> handle_lhs_call).
>
> I later tested with local variables and those are correctly marked as
> not escaping. This might have to do just with the fact that these are
> global variables. I understand that there's also virtual memory operands
> which define that a function might modify a global variable... but I
> would suspect that ipa-visibility should have turned these variables as
> not externally visible. But then why is buff1 not escaping? (strlen is a
> builtin and there's a different execution path...)
>
> I talked about this before but I'm adding the test case here in case
> someone more knowledgeable can comment and guide me towards a more
> concrete reason and I could try to provide a patch that also includes
> the fix itself.
>
> This was compiled and tested with GCC-10.2.0
>
>
> diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-20.c
> b/gcc/testsuite/gcc.dg/ipa/ipa-pta-20.c
> new file mode 100644
> index 00000000000..c82d5205b78
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-20.c
> @@ -0,0 +1,23 @@
> +/* { dg-do run } */
> +/* { dg-options "-flto -flto-partition=none -O2 -fipa-pta
> -fdump-ipa-pta2-details" } */
> +
> +#include <stdio.h>
> +#include <math.h>
> +#include <string.h>
> +
> +char buff0;
> +char buff1;
> +char buff2;
> +
> +int
> +main(int argc, char** argv)
> +{
> +  buff0 = argv[1][0]; // escapes?
> +  buff1 = strlen(argv[1]); // does not escape
> +  buff2 = rand(); // escapes?
> +  return &buff0 < &buff1 ? &buff2 < &buff1 : 0;
> +}
> +
> +/* { dg-final { scan-ipa-dump "buff0 = { }" "pta2" } } */
> +/* { dg-final { scan-ipa-dump "buff1 = { }" "pta2" } } */
> +/* { dg-final { scan-ipa-dump "buff2 = { }" "pta2" } } */

I think you're reading the dumps wrong.

ESCAPED = { }

nothing escapes

buff2 = { ESCAPED NONLOCAL }
buff1 = { }
buff0 = { ESCAPED NONLOCAL }

this means that buff2 and buff0 point to what escapes and other global memory.
This is because argv[1][0] points to global memory and rand () returns
a pointer to global memory (and everything that escapes is also global memory).

Note we track pointers through integers which means even a 'char' and an 'int'
are considered pointer (parts).  strlen is handled explicitely to not
convey a pointer.

The above does not mean that buff2 or buff0 escape!

Richard.

Reply via email to