Question of visitStoreInst in SROA pass

Hi all,

I have a testcase whose result is different in O0 and O2 under llvm-4.0.0 version(trunk version also gets different result).

Test.c


#include<stdio.h>

typedef int int128 __attribute__ ((vector_size (16)));

int main () {

long long int except = 0x1234567800000000;

int err=0;

long long a = 0x1234567812345678;

int128 *b = (int128 *) &a;

(*b)[0] = 0;

if (a != except)

err=1;

if (err)

printf("not equal\n");

else

printf("equal\n");

return 0;

}

O0 printed equal and O2 printed not equal. After some debugging, I found SROA pass changed the codes’ semantics. Here are IR during SROA


%a = alloca i64, align 8

%0 = bitcast i64* %a to i8*

call void @llvm.lifetime.start(i64 8, i8* %0) #2

store i64 1311768465173141112, i64* %a, align 8, !tbaa !1

%1 = bitcast i64* %a to <4 x i32>*

%2 = load <4 x i32>, <4 x i32>* %1, align 16

%vecins = insertelement <4 x i32> %2, i32 0, i32 0

store <4 x i32> %vecins, <4 x i32>* %1, align 16

%3 = load i64, i64* %a, align 8, !tbaa !1

%cmp = icmp ne i64 %3, 1311768464867721216

br i1 %cmp, label %if.then, label %if.end

But visitStoreInst will check whether Size(4 x i32 = 128) is greater than AllocaSize(64) and if so, mark the store inst(store <4 x i32> %vecins, <4 x i32>* %1, align 16) dead and delete it. My intension is to change lower 32bits of b and store it back but the compiler thinks I will store all 128 bits. Is that a bug? Or if it’s test case problem, I think compiler can at least report some warnings in stdout(currently only reports warning in debug log).

Best,

Ruobin