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" } } */