Aliasing Issue after vectorization

Hi all,

I used LLVM’s SLP vectorization pass and set the vector register width to 64. LLVM vectorizes A,B into E.

The question is regarding aliasing, where before vectorization LLVM returns that both A and B do not alias with C individually. But after vectorization LLVM returns that E which is the vectorized value of A and B does alias with D (same as C).

Can this happen and why is LLVM’s alias analysis returning they are infact aliased?

Thank You!

Before vectorization

entry:
%0 = bitcast %“class.internal::BlockVectorIterators::Iterator”* %c to i64*
%1 = load i64, i64* %0, align 8, !tbaa !2
%2 = bitcast %“class.internal::BlockVectorIterators::Iterator”* %this to i64*
store i64 %1, i64* %2, align 8, !tbaa !2
%global_index = getelementptr inbounds %“class.internal::BlockVectorIterators::Iterator”, %“class.internal::BlockVectorIterators::Iterator”* %c, i64 0, i32 1
%global_index3 = getelementptr inbounds %“class.internal::BlockVectorIterators::Iterator”, %“class.internal::BlockVectorIterators::Iterator”* %this, i64 0, i32 1
store i32 %3, i32* %global_index3, align 8, !tbaa !8
%index_within_block = getelementptr inbounds %“class.internal::BlockVectorIterators::Iterator”, %“class.internal::BlockVectorIterators::Iterator”* %c, i64 0, i32 3
%4 = load i32, i32* %index_within_block, align 8, !tbaa !9
%index_within_block4 = getelementptr inbounds %“class.internal::BlockVectorIterators::Iterator”, %“class.internal::BlockVectorIterators::Iterator”* %this, i64 0, i32 3
C: store i32 %4, i32* %index_within_block4, align 8, !tbaa !9
%current_block = getelementptr inbounds %“class.internal::BlockVectorIterators::Iterator”, %“class.internal::BlockVectorIterators::Iterator”* %c, i64 0, i32 2
B: %5 = load i32, i32* %current_block, align 4, !tbaa !10
%current_block5 = getelementptr inbounds %“class.internal::BlockVectorIterators::Iterator”, %“class.internal::BlockVectorIterators::Iterator”* %this, i64 0, i32 2
store i32 %5, i32* %current_block5, align 4, !tbaa !10
%next_break_forward = getelementptr inbounds %“class.internal::BlockVectorIterators::Iterator”, %“class.internal::BlockVectorIterators::Iterator”* %c, i64 0, i32 4
%6 = load i32, i32* %next_break_forward, align 4, !tbaa !11
%next_break_forward6 = getelementptr inbounds %“class.internal::BlockVectorIterators::Iterator”, %“class.internal::BlockVectorIterators::Iterator”* %this, i64 0, i32 4
store i32 %6, i32* %next_break_forward6, align 4, !tbaa !11
%next_break_backward = getelementptr inbounds %“class.internal::BlockVectorIterators::Iterator”, %“class.internal::BlockVectorIterators::Iterator”* %c, i64 0, i32 5
%7 = load i32, i32* %next_break_backward, align 8, !tbaa !12
%next_break_backward7 = getelementptr inbounds %“class.internal::BlockVectorIterators::Iterator”, %“class.internal::BlockVectorIterators::Iterator”* %this, i64 0, i32 5
store i32 %7, i32* %next_break_backward7, align 8, !tbaa !12
ret %“class.internal::BlockVectorIterators::Iterator”* %this

After vectorization

entry:
%0 = bitcast %“class.internal::BlockVectorIterators::Iterator”* %c to i64*
%1 = load i64, i64* %0, align 8, !tbaa !2
%2 = bitcast %“class.internal::BlockVectorIterators::Iterator”* %this to i64*
store i64 %1, i64* %2, align 8, !tbaa !2
%global_index = getelementptr inbounds %“class.internal::BlockVectorIterators::Iterator”, %“class.internal::BlockVectorIterators::Iterator”* %c, i64 0, i32 1
%global_index3 = getelementptr inbounds %“class.internal::BlockVectorIterators::Iterator”, %“class.internal::BlockVectorIterators::Iterator”* %this, i64 0, i32 1
%index_within_block = getelementptr inbounds %“class.internal::BlockVectorIterators::Iterator”, %“class.internal::BlockVectorIterators::Iterator”* %c, i64 0, i32 3
%3 = load i32, i32* %index_within_block, align 8, !tbaa !8
%index_within_block4 = getelementptr inbounds %“class.internal::BlockVectorIterators::Iterator”, %“class.internal::BlockVectorIterators::Iterator”* %this, i64 0, i32 3
D: store i32 %3, i32* %index_within_block4, align 8, !tbaa !8
%current_block = getelementptr inbounds %“class.internal::BlockVectorIterators::Iterator”, %“class.internal::BlockVectorIterators::Iterator”* %c, i64 0, i32 2
%4 = bitcast i32* %global_index to <2 x i32>*
E: %5 = load <2 x i32>, <2 x i32>* %4, align 8, !tbaa !9
%current_block5 = getelementptr inbounds %“class.internal::BlockVectorIterators::Iterator”, %“class.internal::BlockVectorIterators::Iterator”* %this, i64 0, i32 2
%6 = bitcast i32* %global_index3 to <2 x i32>*
store <2 x i32> %5, <2 x i32>* %6, align 8, !tbaa !9
%next_break_forward = getelementptr inbounds %“class.internal::BlockVectorIterators::Iterator”, %“class.internal::BlockVectorIterators::Iterator”* %c, i64 0, i32 4
%7 = load i32, i32* %next_break_forward, align 4, !tbaa !10
%next_break_forward6 = getelementptr inbounds %“class.internal::BlockVectorIterators::Iterator”, %“class.internal::BlockVectorIterators::Iterator”* %this, i64 0, i32 4
store i32 %7, i32* %next_break_forward6, align 4, !tbaa !10
%next_break_backward = getelementptr inbounds %“class.internal::BlockVectorIterators::Iterator”, %“class.internal::BlockVectorIterators::Iterator”* %c, i64 0, i32 5
%8 = load i32, i32* %next_break_backward, align 8, !tbaa !11
%next_break_backward7 = getelementptr inbounds %“class.internal::BlockVectorIterators::Iterator”, %“class.internal::BlockVectorIterators::Iterator”* %this, i64 0, i32 5
store i32 %8, i32* %next_break_backward7, align 8, !tbaa !11
ret %“class.internal::BlockVectorIterators::Iterator”* %this

Hi, Charith,

I don’t think that we can figure this out from only what you’ve presented. Could you file a bug report with the full IR for the different cases at bugs.llvm.org? We’d need to at least see how the %“class.internal::BlockVectorIterators::Iterator” type is defined and how the TBAA metadata is defined in both cases, but we might need to look at what the AA implementation is doing in more detail.

-Hal