[llvm-bugs] [Bug 42154] New: Wrong alignment of pointer argument when typedef enforced

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Jun 6 04:50:06 PDT 2019


https://bugs.llvm.org/show_bug.cgi?id=42154

            Bug ID: 42154
           Summary: Wrong alignment of pointer argument when typedef
                    enforced
           Product: clang
           Version: trunk
          Hardware: Other
                OS: All
            Status: NEW
          Keywords: miscompilation
          Severity: normal
          Priority: P
         Component: -New Bugs
          Assignee: diogo.sampaio at arm.com
          Reporter: diogo.sampaio at arm.com
                CC: htmldeveloper at gmail.com, llvm-bugs at lists.llvm.org,
                    neeilans at live.com, richard-llvm at metafoo.co.uk

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.

-- 
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/20190606/149c9a1a/attachment.html>


More information about the llvm-bugs mailing list