1; RUN: opt -loop-vectorize -S < %s | FileCheck %s
2
3target triple = "aarch64-unknown-linux-gnu"
4
5define void @trip7_i64(i64* noalias nocapture noundef %dst, i64* noalias nocapture noundef readonly %src) #0 {
6; CHECK-LABEL: @trip7_i64(
7; CHECK:       vector.body:
8; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %vector.body ]
9; CHECK:         [[ACTIVE_LANE_MASK:%.*]] = phi <vscale x 2 x i1> [ {{%.*}}, %vector.ph ], [ [[ACTIVE_LANE_MASK_NEXT:%.*]], %vector.body ]
10; CHECK:         {{%.*}} = call <vscale x 2 x i64> @llvm.masked.load.nxv2i64.p0nxv2i64(<vscale x 2 x i64>* {{%.*}}, i32 8, <vscale x 2 x i1> [[ACTIVE_LANE_MASK]], <vscale x 2 x i64> poison)
11; CHECK:         {{%.*}} = call <vscale x 2 x i64> @llvm.masked.load.nxv2i64.p0nxv2i64(<vscale x 2 x i64>* {{%.*}}, i32 8, <vscale x 2 x i1> [[ACTIVE_LANE_MASK]], <vscale x 2 x i64> poison)
12; CHECK:         call void @llvm.masked.store.nxv2i64.p0nxv2i64(<vscale x 2 x i64> {{%.*}}, <vscale x 2 x i64>* {{%.*}}, i32 8, <vscale x 2 x i1> [[ACTIVE_LANE_MASK]])
13; CHECK:         [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
14; CHECK-NEXT:    [[VF:%.*]] = mul i64 [[VSCALE]], 2
15; CHECK-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], [[VF]]
16; CHECK-NEXT:    [[ACTIVE_LANE_MASK_NEXT]] = call <vscale x 2 x i1> @llvm.get.active.lane.mask.nxv2i1.i64(i64 [[INDEX_NEXT]], i64 7)
17; CHECK-NEXT:    [[ACTIVE_LANE_MASK_NOT:%.*]] = xor <vscale x 2 x i1> [[ACTIVE_LANE_MASK_NEXT]], shufflevector (<vscale x 2 x i1> insertelement (<vscale x 2 x i1> poison, i1 true, i32 0), <vscale x 2 x i1> poison, <vscale x 2 x i32> zeroinitializer)
18; CHECK-NEXT:    [[COND:%.*]] = extractelement <vscale x 2 x i1> [[ACTIVE_LANE_MASK_NOT]], i32 0
19; CHECK-NEXT:    br i1 [[COND]], label %middle.block, label %vector.body
20;
21entry:
22  br label %for.body
23
24for.body:                                         ; preds = %entry, %for.body
25  %i.06 = phi i64 [ 0, %entry ], [ %inc, %for.body ]
26  %arrayidx = getelementptr inbounds i64, i64* %src, i64 %i.06
27  %0 = load i64, i64* %arrayidx, align 8
28  %mul = shl nsw i64 %0, 1
29  %arrayidx1 = getelementptr inbounds i64, i64* %dst, i64 %i.06
30  %1 = load i64, i64* %arrayidx1, align 8
31  %add = add nsw i64 %1, %mul
32  store i64 %add, i64* %arrayidx1, align 8
33  %inc = add nuw nsw i64 %i.06, 1
34  %exitcond.not = icmp eq i64 %inc, 7
35  br i1 %exitcond.not, label %for.end, label %for.body
36
37for.end:                                          ; preds = %for.body
38  ret void
39}
40
41define void @trip5_i8(i8* noalias nocapture noundef %dst, i8* noalias nocapture noundef readonly %src) #0 {
42; CHECK-LABEL: @trip5_i8(
43; CHECK:       vector.body:
44; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %vector.body ]
45; CHECK:         [[ACTIVE_LANE_MASK:%.*]] = phi <vscale x 16 x i1> [ {{%.*}}, %vector.ph ], [ [[ACTIVE_LANE_MASK_NEXT:%.*]], %vector.body ]
46; CHECK:         {{%.*}} = call <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0nxv16i8(<vscale x 16 x i8>* {{%.*}}, i32 1, <vscale x 16 x i1> [[ACTIVE_LANE_MASK]], <vscale x 16 x i8> poison)
47; CHECK:         {{%.*}} = call <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0nxv16i8(<vscale x 16 x i8>* {{%.*}}, i32 1, <vscale x 16 x i1> [[ACTIVE_LANE_MASK]], <vscale x 16 x i8> poison)
48; CHECK:         call void @llvm.masked.store.nxv16i8.p0nxv16i8(<vscale x 16 x i8> {{%.*}}, <vscale x 16 x i8>* {{%.*}}, i32 1, <vscale x 16 x i1> [[ACTIVE_LANE_MASK]])
49; CHECK:         [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
50; CHECK-NEXT:    [[VF:%.*]] = mul i64 [[VSCALE]], 16
51; CHECK-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], [[VF]]
52; CHECK-NEXT:    [[ACTIVE_LANE_MASK_NEXT]] = call <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[INDEX_NEXT]], i64 5)
53; CHECK-NEXT:    [[ACTIVE_LANE_MASK_NOT:%.*]] = xor <vscale x 16 x i1> [[ACTIVE_LANE_MASK_NEXT]], shufflevector (<vscale x 16 x i1> insertelement (<vscale x 16 x i1> poison, i1 true, i32 0), <vscale x 16 x i1> poison, <vscale x 16 x i32> zeroinitializer)
54; CHECK-NEXT:    br i1 true, label %middle.block, label %vector.body
55;
56entry:
57  br label %for.body
58
59for.body:                                         ; preds = %entry, %for.body
60  %i.08 = phi i64 [ 0, %entry ], [ %inc, %for.body ]
61  %arrayidx = getelementptr inbounds i8, i8* %src, i64 %i.08
62  %0 = load i8, i8* %arrayidx, align 1
63  %mul = shl i8 %0, 1
64  %arrayidx1 = getelementptr inbounds i8, i8* %dst, i64 %i.08
65  %1 = load i8, i8* %arrayidx1, align 1
66  %add = add i8 %mul, %1
67  store i8 %add, i8* %arrayidx1, align 1
68  %inc = add nuw nsw i64 %i.08, 1
69  %exitcond.not = icmp eq i64 %inc, 5
70  br i1 %exitcond.not, label %for.end, label %for.body
71
72for.end:                                          ; preds = %for.body
73  ret void
74}
75
76attributes #0 = { vscale_range(1,16) "target-features"="+sve" }
77