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.
--- /dev/null
+/* { 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;
+}
|| 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);