1; RUN: opt < %s -tbaa -basic-aa -loop-vectorize -force-vector-interleave=1 -force-vector-width=4 -dce -instcombine -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s 2; RUN: opt < %s -basic-aa -loop-vectorize -force-vector-interleave=1 -force-vector-width=4 -dce -instcombine -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s --check-prefix=CHECK-NOTBAA 3target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 4 5; TBAA partitions the accesses in this loop, so it can be vectorized without 6; runtime checks. 7define i32 @test1(i32* nocapture %a, float* nocapture readonly %b) { 8; CHECK-LABEL: @test1 9; CHECK: entry: 10; CHECK-NEXT: br label %vector.body 11; CHECK: vector.body: 12 13; CHECK: load <4 x float>, <4 x float>* %{{.*}}, align 4, !tbaa 14; CHECK: store <4 x i32> %{{.*}}, <4 x i32>* %{{.*}}, align 4, !tbaa 15 16; CHECK: ret i32 0 17 18; CHECK-NOTBAA-LABEL: @test1 19; CHECK-NOTBAA: entry: 20; CHECK-NOTBAA: icmp ugt i32* 21; CHECK-NOTBAA: icmp ugt float* 22; CHECK-NOTBAA-NOT: icmp 23; CHECK-NOTBAA: br i1 {{.+}}, label %for.body, label %vector.body 24 25; CHECK-NOTBAA: load <4 x float>, <4 x float>* %{{.*}}, align 4, !tbaa 26; CHECK-NOTBAA: store <4 x i32> %{{.*}}, <4 x i32>* %{{.*}}, align 4, !tbaa 27 28; CHECK-NOTBAA: ret i32 0 29 30entry: 31 br label %for.body 32 33for.body: ; preds = %for.body, %entry 34 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 35 %arrayidx = getelementptr inbounds float, float* %b, i64 %indvars.iv 36 %0 = load float, float* %arrayidx, align 4, !tbaa !0 37 %conv = fptosi float %0 to i32 38 %arrayidx2 = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 39 store i32 %conv, i32* %arrayidx2, align 4, !tbaa !4 40 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 41 %exitcond = icmp eq i64 %indvars.iv.next, 1600 42 br i1 %exitcond, label %for.end, label %for.body 43 44for.end: ; preds = %for.body 45 ret i32 0 46} 47 48; This test is like the first, except here there is still one runtime check 49; required. Without TBAA, however, two checks are required. 50define i32 @test2(i32* nocapture readonly %a, float* nocapture readonly %b, float* nocapture %c) { 51; CHECK-LABEL: @test2 52; CHECK: entry: 53; CHECK: icmp ugt float* 54; CHECK: icmp ugt float* 55; CHECK-NOT: icmp uge i32* 56; CHECK: br i1 {{.+}}, label %for.body, label %vector.body 57 58; CHECK: load <4 x float>, <4 x float>* %{{.*}}, align 4, !tbaa 59; CHECK: store <4 x float> %{{.*}}, <4 x float>* %{{.*}}, align 4, !tbaa 60 61; CHECK: ret i32 0 62 63; CHECK-NOTBAA-LABEL: @test2 64; CHECK-NOTBAA: entry: 65; CHECK-NOTBAA: icmp ugt float* 66; CHECK-NOTBAA: icmp ugt float* 67; CHECK-NOTBAA-DAG: icmp ugt float* 68; CHECK-NOTBAA-DAG: icmp ugt i32* 69; CHECK-NOTBAA-NOT: icmp 70; CHECK-NOTBAA: br i1 {{.+}}, label %for.body, label %vector.body 71 72; CHECK-NOTBAA: load <4 x float>, <4 x float>* %{{.*}}, align 4, !tbaa 73; CHECK-NOTBAA: store <4 x float> %{{.*}}, <4 x float>* %{{.*}}, align 4, !tbaa 74 75; CHECK-NOTBAA: ret i32 0 76 77entry: 78 br label %for.body 79 80for.body: ; preds = %for.body, %entry 81 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 82 %arrayidx = getelementptr inbounds float, float* %b, i64 %indvars.iv 83 %0 = load float, float* %arrayidx, align 4, !tbaa !0 84 %arrayidx2 = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 85 %1 = load i32, i32* %arrayidx2, align 4, !tbaa !4 86 %conv = sitofp i32 %1 to float 87 %mul = fmul float %0, %conv 88 %arrayidx4 = getelementptr inbounds float, float* %c, i64 %indvars.iv 89 store float %mul, float* %arrayidx4, align 4, !tbaa !0 90 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 91 %exitcond = icmp eq i64 %indvars.iv.next, 1600 92 br i1 %exitcond, label %for.end, label %for.body 93 94for.end: ; preds = %for.body 95 ret i32 0 96} 97 98!0 = !{!1, !1, i64 0} 99!1 = !{!"float", !2, i64 0} 100!2 = !{!"omnipotent char", !3, i64 0} 101!3 = !{!"Simple C/C++ TBAA"} 102!4 = !{!5, !5, i64 0} 103!5 = !{!"int", !2, i64 0} 104