1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 2; RUN: opt -S -scalable-vectorization=on -force-target-supports-scalable-vectors=true -passes=loop-vectorize -force-vector-width=2 -force-vector-interleave=1 < %s | FileCheck %s 3 4target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 5 6; Make sure we can vectorize loops which contain lifetime markers. 7 8define void @test(ptr %d) { 9; CHECK-LABEL: define void @test 10; CHECK-SAME: (ptr [[D:%.*]]) { 11; CHECK-NEXT: entry: 12; CHECK-NEXT: [[ARR:%.*]] = alloca [1024 x i32], align 16 13; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4096, ptr [[ARR]]) 14; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64() 15; CHECK-NEXT: [[TMP1:%.*]] = mul i64 [[TMP0]], 2 16; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 128, [[TMP1]] 17; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] 18; CHECK: vector.ph: 19; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.vscale.i64() 20; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[TMP2]], 2 21; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 128, [[TMP3]] 22; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 128, [[N_MOD_VF]] 23; CHECK-NEXT: [[TMP4:%.*]] = call i64 @llvm.vscale.i64() 24; CHECK-NEXT: [[TMP5:%.*]] = mul i64 [[TMP4]], 2 25; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 26; CHECK: vector.body: 27; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 28; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[INDEX]], 0 29; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4096, ptr [[ARR]]) 30; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i32, ptr [[D]], i64 [[TMP6]] 31; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i32, ptr [[TMP7]], i32 0 32; CHECK-NEXT: store <vscale x 2 x i32> splat (i32 100), ptr [[TMP8]], align 8 33; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4096, ptr [[ARR]]) 34; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP5]] 35; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] 36; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] 37; CHECK: middle.block: 38; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 128, [[N_VEC]] 39; CHECK-NEXT: br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]] 40; CHECK: scalar.ph: 41; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ] 42; CHECK-NEXT: br label [[FOR_BODY:%.*]] 43; CHECK: for.body: 44; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 45; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4096, ptr [[ARR]]) 46; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[D]], i64 [[INDVARS_IV]] 47; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX]], align 8 48; CHECK-NEXT: store i32 100, ptr [[ARRAYIDX]], align 8 49; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4096, ptr [[ARR]]) 50; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 51; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32 52; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], 128 53; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END]], !llvm.loop [[LOOP3:![0-9]+]] 54; CHECK: for.end: 55; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4096, ptr [[ARR]]) 56; CHECK-NEXT: ret void 57; 58 59entry: 60 %arr = alloca [1024 x i32], align 16 61 call void @llvm.lifetime.start.p0(i64 4096, ptr %arr) #1 62 br label %for.body 63 64for.body: 65 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 66 call void @llvm.lifetime.end.p0(i64 4096, ptr %arr) #1 67 %arrayidx = getelementptr inbounds i32, ptr %d, i64 %indvars.iv 68 %0 = load i32, ptr %arrayidx, align 8 69 store i32 100, ptr %arrayidx, align 8 70 call void @llvm.lifetime.start.p0(i64 4096, ptr %arr) #1 71 %indvars.iv.next = add i64 %indvars.iv, 1 72 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 73 %exitcond = icmp ne i32 %lftr.wideiv, 128 74 br i1 %exitcond, label %for.body, label %for.end, !llvm.loop !0 75 76for.end: 77 call void @llvm.lifetime.end.p0(i64 4096, ptr %arr) #1 78 ret void 79} 80 81define void @testloopvariant(ptr %d) { 82; CHECK-LABEL: define void @testloopvariant 83; CHECK-SAME: (ptr [[D:%.*]]) { 84; CHECK-NEXT: entry: 85; CHECK-NEXT: [[ARR:%.*]] = alloca [1024 x i32], align 16 86; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64() 87; CHECK-NEXT: [[TMP1:%.*]] = mul i64 [[TMP0]], 2 88; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 128, [[TMP1]] 89; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] 90; CHECK: vector.ph: 91; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.vscale.i64() 92; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[TMP2]], 2 93; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 128, [[TMP3]] 94; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 128, [[N_MOD_VF]] 95; CHECK-NEXT: [[TMP4:%.*]] = call i64 @llvm.vscale.i64() 96; CHECK-NEXT: [[TMP5:%.*]] = mul i64 [[TMP4]], 2 97; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 98; CHECK: vector.body: 99; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 100; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[INDEX]], 0 101; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4096, ptr [[ARR]]) 102; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i32, ptr [[D]], i64 [[TMP6]] 103; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i32, ptr [[TMP7]], i32 0 104; CHECK-NEXT: store <vscale x 2 x i32> splat (i32 100), ptr [[TMP8]], align 8 105; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4096, ptr [[ARR]]) 106; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP5]] 107; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] 108; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]] 109; CHECK: middle.block: 110; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 128, [[N_VEC]] 111; CHECK-NEXT: br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]] 112; CHECK: scalar.ph: 113; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ] 114; CHECK-NEXT: br label [[FOR_BODY:%.*]] 115; CHECK: for.body: 116; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 117; CHECK-NEXT: [[TMP10:%.*]] = getelementptr [1024 x i32], ptr [[ARR]], i32 0, i64 [[INDVARS_IV]] 118; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4096, ptr [[ARR]]) 119; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[D]], i64 [[INDVARS_IV]] 120; CHECK-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARRAYIDX]], align 8 121; CHECK-NEXT: store i32 100, ptr [[ARRAYIDX]], align 8 122; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4096, ptr [[ARR]]) 123; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 124; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32 125; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], 128 126; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END]], !llvm.loop [[LOOP5:![0-9]+]] 127; CHECK: for.end: 128; CHECK-NEXT: ret void 129; 130entry: 131 %arr = alloca [1024 x i32], align 16 132 br label %for.body 133 134for.body: 135 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 136 %0 = getelementptr [1024 x i32], ptr %arr, i32 0, i64 %indvars.iv 137 call void @llvm.lifetime.end.p0(i64 4096, ptr %arr) #1 138 %arrayidx = getelementptr inbounds i32, ptr %d, i64 %indvars.iv 139 %1 = load i32, ptr %arrayidx, align 8 140 store i32 100, ptr %arrayidx, align 8 141 call void @llvm.lifetime.start.p0(i64 4096, ptr %arr) #1 142 %indvars.iv.next = add i64 %indvars.iv, 1 143 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 144 %exitcond = icmp ne i32 %lftr.wideiv, 128 145 br i1 %exitcond, label %for.body, label %for.end, !llvm.loop !0 146 147for.end: 148 ret void 149} 150 151declare void @llvm.lifetime.start.p0(i64, ptr nocapture) #1 152 153declare void @llvm.lifetime.end.p0(i64, ptr nocapture) #1 154 155!0 = distinct !{!0, !1} 156!1 = !{!"llvm.loop.vectorize.scalable.enable", i1 true} 157