]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix wrong code with pure functions
authorJan Hubicka <jh@suse.cz>
Fri, 12 Nov 2021 22:55:50 +0000 (23:55 +0100)
committerJan Hubicka <jh@suse.cz>
Fri, 12 Nov 2021 22:55:50 +0000 (23:55 +0100)
I introduced bug into find_func_aliases_for_call in handling pure functions.
Instead of reading global memory pure functions are believed to write global
memory.  This results in misoptimization of the testcase at -O1.

The change to pta-callused.c updates the template for new behaviour of the
constraint generation. We copy nonlocal memory to calluse which is correct but
also not strictly necessary because later we take care to add nonlocal_p flag
manually.

gcc/ChangeLog:

PR tree-optimization/103209
* tree-ssa-structalias.c (find_func_aliases_for_call): Fix
use of handle_rhs_call

gcc/testsuite/ChangeLog:

PR tree-optimization/103209
* gcc.dg/tree-ssa/pta-callused.c: Update template.
* gcc.c-torture/execute/pr103209.c: New test.

gcc/testsuite/gcc.c-torture/execute/pr103209.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c
gcc/tree-ssa-structalias.c

diff --git a/gcc/testsuite/gcc.c-torture/execute/pr103209.c b/gcc/testsuite/gcc.c-torture/execute/pr103209.c
new file mode 100644 (file)
index 0000000..4816893
--- /dev/null
@@ -0,0 +1,36 @@
+#include <stdio.h>
+#include <stdint.h>
+
+int32_t a[6];
+int64_t b;
+int32_t *c;
+int32_t **d = &c;
+int64_t *e = &b;
+int32_t **const *f = &d;
+int32_t **const **g = &f;
+int32_t *h();
+static int16_t j();
+static uint32_t k(int8_t, const int32_t *, int64_t);
+static uint32_t l() {
+  int32_t *m = &a[3];
+  int32_t n = 0;
+  int8_t o = 0;
+  int32_t *p[] = {&n, &n, &n, &n};
+  uint32_t q[6][1][2] = {};
+  for (o = 0; o <= 1; o = 6)
+    if (h(j(k(3, 0, q[2][0][0]), &n), n) == p[3])
+      *m = *e;
+  return 0;
+}
+int32_t *h(uint32_t, int32_t) { return ***g; }
+int16_t j(uint32_t, int32_t *r) { **f = r; return 0;}
+uint32_t k(int8_t, const int32_t *, int64_t) { *e = 3; return 0;}
+int main() {
+  int i = 0;
+  l();
+  for (i = 0; i < 6; i++){
+    if (i == 3 && a[i] != 3)
+       __builtin_abort ();
+  }
+  return 0;
+}
index aa639b45dc21bd27602831d4108dfb2c1f48b891..b9a57d8d13513c17abfd5c28a4a872589d53d814 100644 (file)
@@ -22,5 +22,5 @@ int bar (int b)
   return *foo (&q);
 }
 
-/* { dg-final { scan-tree-dump "CALLUSED\\(\[0-9\]+\\) = { NONLOCAL f.* i q }" "alias" } } */
+/* { dg-final { scan-tree-dump "CALLUSED\\(\[0-9\]+\\) = { ESCAPED NONLOCAL f.* i q }" "alias" } } */
 
index 153ddf57a61ce5f72daf9e557b9d33fa96dffb65..34fd47fdf47b25652afc583ed68ad708bdfe0034 100644 (file)
@@ -4996,7 +4996,7 @@ find_func_aliases_for_call (struct function *fn, gcall *t)
         reachable from their arguments, but they are not an escape
         point for reachable memory of their arguments.  */
       else if (flags & (ECF_PURE|ECF_LOOPING_CONST_OR_PURE))
-       handle_rhs_call (t, &rhsc, implicit_pure_eaf_flags, true, false);
+       handle_rhs_call (t, &rhsc, implicit_pure_eaf_flags, false, true);
       /* If the call is to a replaceable operator delete and results
         from a delete expression as opposed to a direct call to
         such operator, then the effects for PTA (in particular