Adam Nemet | a502ee7 | 2017-12-06 22:42:24 +0000 | [diff] [blame^] | 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 | |
| 7 | target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" |
| 8 | target triple = "arm64-apple-ios5.0.0" |
| 9 | |
| 10 | %struct.Vec4r = type { double, double, double, double } |
| 11 | %struct.Vec2r = type { double, double } |
| 12 | |
| 13 | define void @foobar(%struct.Vec4r* nocapture readonly %p, i32 %i) |
| 14 | { |
| 15 | entry: |
| 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 | |
| 20 | for.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 | |
| 25 | for.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 | |
| 47 | declare 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} |