https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87054
Bug ID: 87054
Summary: misaligned asm output is turned into dereferenced
pointer-to-aligned
Product: gcc
Version: 9.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: aoliva at gcc dot gnu.org
Depends on: 80334
Target Milestone: ---
This bug came up while attempting to trigger the bug 80334, that was suspected
to be latent in earlier versions. I managed to trigger the latent problem with
a variant of the testcase below, but attempting to further minimize it, I found
a way to trigger it even in GCC 8 and trunk:
#ifndef T
# define T long
#endif
#ifndef R
# define R "r"
#endif
typedef T A; // #define T to long or __int128
struct B { char d; A c; } __attribute__((packed));
B b[50]; // many elements to avoid loop unrolling
int main () {
for (int i = 0; i < sizeof(b) / sizeof(*b); i++) {
asm ("" : "+" R (b[i].unpacked)); // #define R to "r" on ppc or "x" on
x86_64
}
}
The gimplifier introduces a pointer to the misaligned field for the asm output,
discarding the information about the misalignment, and that pointer is
dereferenced as if the object was aligned. There is a (broken) patch in that
bug that works around the problem, but that fails to build libstdc++-v3
(unbound template names).
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80334#c12
FTR, the testcase that exercises the bug in older compilers, before the fix was
backported, has a "manual reload" of the asm operand, compared with the above:
auto r = b[i].unpacked; // aligned access to unaligned address
asm ("" : "+" R (r)); // #define R to "r" on ppc or "x" on x86_64
b[i].unpacked = r; // pretend the loop has externally-visible effects
Referenced Bugs:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80334
[Bug 80334] [5 Regression] Segfault when taking address of copy of unaligned
struct