1; RUN: opt -S -loop-vectorize -force-vector-width=2 -force-vector-interleave=1 -enable-interleaved-mem-accesses=true < %s | FileCheck %s
2
3; When merging two stores with interleaved access vectorization, make sure we
4; propagate the alias information from all scalar stores to form the most
5; generic alias info.
6
7target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
8target triple = "arm64-apple-ios5.0.0"
9
10%struct.Vec4r = type { double, double, double, double }
11%struct.Vec2r = type { double, double }
12
13define void @foobar(%struct.Vec4r* nocapture readonly %p, i32 %i)
14{
15entry:
16  %cp = alloca [20 x %struct.Vec2r], align 8
17  %0 = bitcast [20 x %struct.Vec2r]* %cp to i8*
18  br label %for.body
19
20for.cond.cleanup:                                 ; preds = %for.body
21  %arraydecay = getelementptr inbounds [20 x %struct.Vec2r], [20 x %struct.Vec2r]* %cp, i64 0, i64 0
22  call void @g(%struct.Vec2r* nonnull %arraydecay) #4
23  ret void
24
25for.body:                                         ; preds = %for.body, %entry
26  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
27  %x = getelementptr inbounds %struct.Vec4r, %struct.Vec4r* %p, i64 %indvars.iv, i32 0
28  %1 = load double, double* %x, align 8, !tbaa !3
29  %mul = fmul double %1, 2.000000e+00
30  %x4 = getelementptr inbounds [20 x %struct.Vec2r], [20 x %struct.Vec2r]* %cp, i64 0, i64 %indvars.iv, i32 0
31
32; The new store should alias any double rather than one of the fields of Vec2r.
33; CHECK: store <4 x double> {{.*}} !tbaa ![[STORE_TBAA:[0-9]+]]
34; CHECK-DAG: ![[DOUBLE_TBAA:[0-9]+]] = !{!"double", !{{[0-9+]}}, i64 0}
35; CHECK-DAG: ![[STORE_TBAA]] = !{![[DOUBLE_TBAA]], ![[DOUBLE_TBAA]], i64 0}
36  store double %mul, double* %x4, align 8, !tbaa !8
37  %y = getelementptr inbounds %struct.Vec4r, %struct.Vec4r* %p, i64 %indvars.iv, i32 1
38  %2 = load double, double* %y, align 8, !tbaa !10
39  %mul7 = fmul double %2, 3.000000e+00
40  %y10 = getelementptr inbounds [20 x %struct.Vec2r], [20 x %struct.Vec2r]* %cp, i64 0, i64 %indvars.iv, i32 1
41  store double %mul7, double* %y10, align 8, !tbaa !11
42  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
43  %exitcond = icmp eq i64 %indvars.iv.next, 4
44  br i1 %exitcond, label %for.cond.cleanup, label %for.body
45}
46
47declare void @g(%struct.Vec2r*)
48
49!llvm.module.flags = !{!0, !1}
50!llvm.ident = !{!2}
51
52!0 = !{i32 1, !"wchar_size", i32 4}
53!1 = !{i32 7, !"PIC Level", i32 2}
54!2 = !{!"clang version 6.0.0 (trunk 319007) (llvm/trunk 319324)"}
55!3 = !{!4, !5, i64 0}
56!4 = !{!"Vec4r", !5, i64 0, !5, i64 8, !5, i64 16, !5, i64 24}
57!5 = !{!"double", !6, i64 0}
58!6 = !{!"omnipotent char", !7, i64 0}
59!7 = !{!"Simple C/C++ TBAA"}
60!8 = !{!9, !5, i64 0}
61!9 = !{!"Vec2r", !5, i64 0, !5, i64 8}
62!10 = !{!4, !5, i64 8}
63!11 = !{!9, !5, i64 8}
64