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.