aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2024-05-23 11:26:14 +0200
committerRichard Biener <rguenther@suse.de>2024-05-23 14:38:48 +0200
commit61f5b3c59ed20438d7d9918d7a83d29a21097d4e (patch)
tree67d1c58ba74a518dbfee1ca19c6fa7bd60f2a237 /gcc
parent4efa7ec85a85c6024d0907a0e735ad5df7fca952 (diff)
downloadgcc-61f5b3c59ed20438d7d9918d7a83d29a21097d4e.zip
gcc-61f5b3c59ed20438d7d9918d7a83d29a21097d4e.tar.gz
gcc-61f5b3c59ed20438d7d9918d7a83d29a21097d4e.tar.bz2
tree-optimization/115138 - ptr-vs-ptr and FUNCTION_DECLs
I failed to realize we do not represent FUNCTION_DECLs or LABEL_DECLs in vars explicitly and thus have to compare pt.vars_contains_nonlocal. PR tree-optimization/115138 * tree-ssa-alias.cc (ptrs_compare_unequal): Make sure pt.vars_contains_nonlocal differs since we do not represent FUNCTION_DECLs or LABEL_DECLs in vars explicitly. * gcc.dg/torture/pr115138.c: New testcase.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr115138.c28
-rw-r--r--gcc/tree-ssa-alias.cc6
2 files changed, 34 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr115138.c b/gcc/testsuite/gcc.dg/torture/pr115138.c
new file mode 100644
index 0000000..6becaec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr115138.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+
+int foo (int) {}
+int bar (int) {}
+
+typedef int (*pred)(int);
+
+int x, y;
+pred A () { if (x) return foo; else return bar; }
+pred B () { if (y) return foo; else return bar; }
+int __attribute__((noipa)) baz()
+{
+ pred a = A();
+ pred b = B();
+ if (a != b)
+ return 42;
+ return 0;
+}
+
+int main()
+{
+ if (baz () != 0)
+ __builtin_abort ();
+ y = 1;
+ if (baz () != 42)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/tree-ssa-alias.cc b/gcc/tree-ssa-alias.cc
index d64d6d0..1a91d63 100644
--- a/gcc/tree-ssa-alias.cc
+++ b/gcc/tree-ssa-alias.cc
@@ -501,6 +501,12 @@ ptrs_compare_unequal (tree ptr1, tree ptr2)
|| pi2->pt.vars_contains_interposable)
return false;
if ((!pi1->pt.null || !pi2->pt.null)
+ /* ??? We do not represent FUNCTION_DECL and LABEL_DECL
+ in pt.vars but only set pt.vars_contains_nonlocal. This
+ makes compares involving those and other nonlocals
+ imprecise. */
+ && (!pi1->pt.vars_contains_nonlocal
+ || !pi2->pt.vars_contains_nonlocal)
&& (!pt_solution_includes_const_pool (&pi1->pt)
|| !pt_solution_includes_const_pool (&pi2->pt)))
return !pt_solutions_intersect (&pi1->pt, &pi2->pt);