<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 - Wrong alignment of pointer argument when typedef enforced"
   href="https://bugs.llvm.org/show_bug.cgi?id=42154">42154</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Wrong alignment of pointer argument when typedef enforced
          </td>
        </tr>

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

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>Other
          </td>
        </tr>

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

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

        <tr>
          <th>Keywords</th>
          <td>miscompilation
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>-New Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>diogo.sampaio@arm.com
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>diogo.sampaio@arm.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org, neeilans@live.com, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Given the input cpp code:
===
#include <arm_neon.h>

struct S4 {
  long long M2;
  S4(signed int &&P5) {}
};

typedef struct S5 {
  float32x2_t M0;
  float16x4_t M1;
  int M5;
  S5(float32x2_t &&P0, float16x4_t &&P1) : M0(P0), M1(P1) {}
} S5 __attribute((aligned(4))); //<<== In a typedef, it reduces the alignment.

struct S2 :  public S4, public S5 {
public:
  S2(S4 &&P1, S5 &&P2) : S4(P1), S5(P2) {}
};

int main() {
  S2 a(S4(2049077767), S5(vdup_n_f32(0), vdup_n_f16(0)));
  return 0;
}
===
The typedef enforces S5 to be 4 bytes aligned.
S5 constructor should write to M0 and M1 using a 4 byte alignment, but clang
emits 8 bytes alignment for these writes.
===
compiling with the command:

clang --target=arm-arm-none-eabi -mcpu=cortex-a15 -S -o - -emit-llvm -O1
test.cpp

In the IR, the important bits are:
==
Allocating the S5 structure:

` %ref.tmp2 = alloca %struct.S5, align 4`
==
In the S5 constructor, function simd64_float32_tO18__simd64_float16_t:

Writing to the first element:
`
 %M0 = getelementptr inbounds %struct.S5, %struct.S5* %this, i32 0, i32 0
 store <2 x float> %0, <2 x float>* %M0, align 8   <<==== WRONG align!
`

Writing to the second element:
`
   %M1 = getelementptr inbounds %struct.S5, %struct.S5* %this, i32 0, i32 1
   store <4 x half> %1, <4 x half>* %M1, align 8 <<==== WRONG align!
`
--


This causes llc to generate the instruction:
`vst1.32 {d16}, [r1:64]!`
instead of
`vst1.32 {d16}, [r1]!`
Which enforces a 64 bit alignment, but the r1 pointer is 32 bit aligned.

Changing these aligns to 4 gives the correct result. So clang should be able to
detect that alignment = min (8, 4) here.</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>