<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>