Is this an over alignment bug for ARM?

Hi,

I'm debugging an Android code which caused data violation fault and it seems Clang is generating a store with over alignment.

Given test.cpp:
class F {
   public:
     F(void);
   private:
     F(const F& f);
     const F& operator= (const F& f);
     char *mFileName;
     void *mBasePtr;
     unsigned int mBaseLen;
     long long mOffset;
     void *mDataPtr;
     unsigned int mDataLen;
};

F::F(void)
   :mFileName(0), mBasePtr(0), mBaseLen(0), mDataPtr(0), mDataLen(0) { }

clang++ -S -march=armv7-a -mfloat-abi=softfp -mfpu=neon -std=gnu++11 -target arm-linux-androideabi -mthumb -Os test.cpp -S -o test.s

THe asm of the constructor is:
     vmov.i32 d16, #0x0
     mov r1, r0
     vst1.32 {d16}, [r1:64]! =========> the store assumes *this ptr has 8-byte alignment, which seems wrong
     movs r2, #0
     str r2, [r1]
     strd r2, r2, [r0, #24]
     bx lr

It's because Clang generates a store with alignment of 8:
   %mFileName = getelementptr inbounds %"class.android::FileMap", %"class.android::FileMap"* %this, i32 0, i32 0
   store i8* null, i8** %mFileName, align 8

And I trace it back to Clang patch r246985 "Compute and preserve alignment more faithfully in IR-generation."

It seems a bug to me.

Thanks,
Weiming

Hi Weiming,

I'm debugging an Android code which caused data violation fault and it seems Clang is generating a store with over alignment.

I think that's valid. The "long long" member means that the entire
class must be 8-byte aligned (under AAPCS), in particular the this
pointer itself. And then there are 4 bytes of padding between mBaseLen
and mOffset to ensure mOffset actually is aligned.

Or am I misreading something?

Cheers.

Tim.

Hi Tim,

Thanks for the answer.
So "new" or malloc should guarantee that it returns a at-least 8-byte aligned "this" pointer, is that correct?

Thank,s
Weiming

Probably. They need to return something compatible with max_align_t,
which I strongly suspect is 8-byte aligned on Android.

There is a concept of "extended alignment" in the C and C++ standards,
where the user may have to realign the results of malloc manually, or
presumably implement custom new operators. This mostly only applies to
things like AVX-512 vectors though.

Cheers.

Tim.

I see. I will keep digging why malloc is retuning a 4-byte aligned address.

Thanks a lot for the info!

Weiming

It's certainly very odd if it's the Android system's malloc, these
requirements have been around for ages. I'd be interested to hear what
you find out (either way).

Tim.