Summary: | Wrong optimizations for pointers: `if (p == q) use p` -> `if (p == q) use q` | ||
---|---|---|---|
Product: | gcc | Reporter: | Alexander Cherepanov <ch3root> |
Component: | tree-optimization | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | UNCONFIRMED --- | ||
Severity: | normal | CC: | gabravier, pageexec, sjames |
Priority: | P3 | Keywords: | wrong-code |
Version: | 10.0 | ||
Target Milestone: | --- | ||
See Also: |
https://bugs.llvm.org/show_bug.cgi?id=34548 https://bugs.llvm.org/show_bug.cgi?id=44313 |
||
Host: | Target: | ||
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | ||
Bug Depends on: | 61502, 65752, 93052 | ||
Bug Blocks: |
Description
Alexander Cherepanov
2019-12-23 12:59:35 UTC
Example with a restricted pointer (dom2): ---------------------------------------------------------------------- #include <stdio.h> __attribute__((noipa,optnone)) // imagine it in a separate TU static void *opaque(void *p) { return p; } __attribute__((noipa)) // imagine it in a separate TU static void f(int *restrict p, int *restrict q) { int *r = opaque(p); // hide provenance of p if (r == q) { *p = 1; *r = 2; printf("result: %d\n", *p); } opaque(q); } int main() { int x; f(&x, &x); } ---------------------------------------------------------------------- $ gcc -std=c11 -pedantic -Wall -Wextra -Wno-attributes test.c && ./a.out test.c: In function ‘main’: test.c:22:7: warning: passing argument 1 to ‘restrict’-qualified parameter aliases with argument 2 [-Wrestrict] 22 | f(&x, &x); | ^~ ~~ result: 2 $ gcc -std=c11 -pedantic -Wall -Wextra -Wno-attributes -O3 test.c && ./a.out test.c: In function ‘main’: test.c:22:7: warning: passing argument 1 to ‘restrict’-qualified parameter aliases with argument 2 [-Wrestrict] 22 | f(&x, &x); | ^~ ~~ result: 1 ---------------------------------------------------------------------- gcc x86-64 version: gcc (GCC) 10.0.0 20191223 (experimental) ---------------------------------------------------------------------- Strictly speaking this example is not about provenance (both pointers have the same provenance) but, for the optimizer, different restricted pointers probably play similar roles. Despite the warning, equal restricted pointers are fine per se -- see, e.g., Example 3 in C11, 6.7.3.1p10. Example with a dead malloc (not in tree-opt): ---------------------------------------------------------------------- #include <stdint.h> #include <stdlib.h> #include <stdio.h> __attribute__((noipa,optnone)) // imagine it in a separate TU static void *opaque(void *p) { return p; } int main() { int *q = malloc(sizeof(int)); uintptr_t iq = (uintptr_t)(void *)q; free(q); int *p = malloc(sizeof(int)); uintptr_t ir = (uintptr_t)(void *)opaque(p); // hide provenance of p if (ir == iq) { *p = 1; *(int *)ir = 2; printf("result: %d\n", *p); } } ---------------------------------------------------------------------- $ gcc -std=c11 -pedantic -Wall -Wextra -Wno-attributes test.c && ./a.out result: 2 $ gcc -std=c11 -pedantic -Wall -Wextra -Wno-attributes -O3 test.c && ./a.out result: 1 ---------------------------------------------------------------------- gcc x86-64 version: gcc (GCC) 10.0.0 20191223 (experimental) ---------------------------------------------------------------------- For completeness, an example with a guessed pointer, based on the testcase from bug 65752, comment 0, gcc-only (dom2): ---------------------------------------------------------------------- #include <stdint.h> #include <stdio.h> __attribute__((noipa)) // imagine it in a separate TU static uintptr_t opaque_to_int(void *p) { return (uintptr_t)p; } int main() { int x; int *p = &x; uintptr_t ip = (uintptr_t)p; uintptr_t iq = 0; while (iq < ip) iq++; uintptr_t ir = opaque_to_int(p); // hide provenance of p if (ir == iq) { *p = 1; *(int *)ir = 2; printf("result: %d\n", *p); } } ---------------------------------------------------------------------- $ gcc -std=c11 -pedantic -Wall -Wextra -O3 test.c && ./a.out result: 1 ---------------------------------------------------------------------- gcc x86-64 version: gcc (GCC) 10.0.0 20191224 (experimental) ---------------------------------------------------------------------- There's duplicates about this conditional propagation issue. It also applies to integers since we track provenance through them as well. Not sure if it's really useful to have yet another bug about this. *** Bug 103343 has been marked as a duplicate of this bug. *** |