https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77580
Bug ID: 77580 Summary: Improve devirtualization Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: wdijkstr at arm dot com Target Milestone: --- A commonly used benchmark contains a hot loop which calls one of 2 virtual functions via a static variable which is set just before. A reduced example is: int f1(int x) { return x + 1; } int f2(int x) { return x + 2; } static int (*virt)(int); int f(int *p, int n, int x) { int i; if (x > 10) virt = f1; else virt = f2; for (i = 0; i < n; i++) p[i] = virt (i); } This is obviously very stupid code, however GCC could do better. virt is not address-taken, neither f1 nor f2 make a call, so virt is effectively a local variable. So the loop could be transformed to p[i] = (x > 10) ? f1 (i) : f2 (i); to enable inlining after which the if can be lifted: int f_opt(int *p, int n, int x) { int i; if (x > 10) virt = f1; else virt = f2; if (x > 10) for (i = 0; i < n; i++) p[i] = f1 (i); else for (i = 0; i < n; i++) p[i] = f2 (i); }