<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Clang generates wrong alignment on packed structs (looks like #5598 again)"
   href="https://bugs.llvm.org/show_bug.cgi?id=47824">47824</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Clang generates wrong alignment on packed structs (looks like #5598 again)
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>10.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>LLVM Codegen
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>femtium@protonmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, neeilans@live.com, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=24050" name="attach_24050" title="minimal-poc.c">attachment 24050</a> <a href="attachment.cgi?id=24050&action=edit" title="minimal-poc.c">[details]</a></span>
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.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>