[llvm-bugs] [Bug 47824] New: Clang generates wrong alignment on packed structs (looks like #5598 again)
via llvm-bugs
llvm-bugs at lists.llvm.org
Tue Oct 13 07:52:16 PDT 2020
https://bugs.llvm.org/show_bug.cgi?id=47824
Bug ID: 47824
Summary: Clang generates wrong alignment on packed structs
(looks like #5598 again)
Product: clang
Version: 10.0
Hardware: PC
OS: All
Status: NEW
Severity: enhancement
Priority: P
Component: LLVM Codegen
Assignee: unassignedclangbugs at nondot.org
Reporter: femtium at protonmail.com
CC: llvm-bugs at lists.llvm.org, neeilans at live.com,
richard-llvm at metafoo.co.uk
Created attachment 24050
--> https://bugs.llvm.org/attachment.cgi?id=24050&action=edit
minimal-poc.c
Consider this simple test case, test1.c:
```c
struct a { int x; };
struct b { int x; };
void test(struct a *a, struct b *b)
{
a->x = b->x;
}
```
And this other test case, test2.c:
```c
struct __attribute__((packed)) a { int x; };
struct b { int x; };
void test(struct a *a, struct b *b)
{
a->x = b->x;
}
```
Both of the test() functions write sizeof(int) to offset 0 of a struct. One
would expect them to behave identically. Indeed, on x86, they generate the
exact same code. (with -O1 or -Os: "mov, mov, ret")
However, they do not generate the same IR. Here's a diff of the .ll output:
```diff
%x1 = getelementptr inbounds %struct.a, %struct.a* %2, i32 0, i32 0
- store i32 %1, i32* %x1, align 4
+ store i32 %1, i32* %x1, align 1
ret void
}
```
This does not change the generated code on X86, since that architecture
supports unaligned memory access. However, on e.g. RISCV:
```asm
test1:
lw a1, 0(a1)
sw a1, 0(a0)
ret
```
vs
```asm
test2:
lw a1, 0(a1)
sb a1, 0(a0)
srli a2, a1, 24
sb a2, 3(a0)
srli a2, a1, 16
sb a2, 2(a0)
srli a1, a1, 8
sb a1, 1(a0)
ret
```
If I manually hack the following code into the target:
```c++
+bool FooTargetLowering::allowsMisalignedMemoryAccesses(EVT VT, unsigned
AddrSpace,
+ unsigned Align,
+ MachineMemOperand::Flags Flags,
+ bool *Fast) const {
+ return true;
+}
```
Then the code generation is once again identical between the two cases.
Obviously, this is only valid if the target supports unaligned access.
Here are my thoughts about the situation:
1) At a glance, this look like #5598 has resurfaced.
2) #5598 mentions a test for x86_64. If there is indeed a regression test,
x86_64 is a bad choice, since the problem is very unlikely (guaranteed?) not to
show up on this arch
3) I think the generated IR itself is *wrong*. I can understand that an
unaligned field store would be "align 1", but surely there's no need to do this
for naturally-aligned fields?
I don't know the deeper cause of this, but I hope this simple test case can
help shed some light on what is going on.
Attached file `minimal-poc.c`, identical to `test2.c` mentioned inline in this
report.
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20201013/70add291/attachment.html>
More information about the llvm-bugs
mailing list