275 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 52; RUN: opt -passes=loop-vectorize -S %s | FileCheck %s3 4target triple = "aarch64-linux-gnu"5 6; Original loop has trip count 17, but contains interleave groups with gaps, so7; the last iteration must execute in the scalar loop. Thus the vector loop can8; only execute up to 16 iterations.9define i64 @vector_loop_with_remaining_iterations(ptr %src, ptr noalias %dst, i32 %x) #0 {10; CHECK-LABEL: define i64 @vector_loop_with_remaining_iterations(11; CHECK-SAME: ptr [[SRC:%.*]], ptr noalias [[DST:%.*]], i32 [[X:%.*]]) #[[ATTR0:[0-9]+]] {12; CHECK-NEXT: [[ENTRY:.*:]]13; CHECK-NEXT: br label %[[VECTOR_PH:.*]]14; CHECK: [[VECTOR_PH]]:15; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <16 x i32> poison, i32 [[X]], i64 016; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <16 x i32> [[BROADCAST_SPLATINSERT]], <16 x i32> poison, <16 x i32> zeroinitializer17; CHECK-NEXT: [[TMP3:%.*]] = call <16 x i32> @llvm.abs.v16i32(<16 x i32> [[BROADCAST_SPLAT]], i1 false)18; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]19; CHECK: [[VECTOR_BODY]]:20; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]21; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <16 x i64> [ zeroinitializer, %[[VECTOR_PH]] ], [ [[TMP11:%.*]], %[[VECTOR_BODY]] ]22; CHECK-NEXT: [[TMP4:%.*]] = getelementptr { [4 x i8] }, ptr [[SRC]], i64 [[INDEX]], i32 0, i64 323; CHECK-NEXT: [[WIDE_VEC:%.*]] = load <64 x i8>, ptr [[TMP4]], align 124; CHECK-NEXT: [[STRIDED_VEC:%.*]] = shufflevector <64 x i8> [[WIDE_VEC]], <64 x i8> poison, <16 x i32> <i32 0, i32 4, i32 8, i32 12, i32 16, i32 20, i32 24, i32 28, i32 32, i32 36, i32 40, i32 44, i32 48, i32 52, i32 56, i32 60>25; CHECK-NEXT: [[TMP5:%.*]] = zext <16 x i8> [[STRIDED_VEC]] to <16 x i32>26; CHECK-NEXT: [[TMP6:%.*]] = call <16 x i32> @llvm.umin.v16i32(<16 x i32> [[TMP3]], <16 x i32> [[TMP5]])27; CHECK-NEXT: [[TMP7:%.*]] = call <16 x i32> @llvm.umin.v16i32(<16 x i32> [[TMP3]], <16 x i32> [[TMP6]])28; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 [[INDEX]]29; CHECK-NEXT: store <16 x i8> zeroinitializer, ptr [[TMP8]], align 130; CHECK-NEXT: [[TMP10:%.*]] = zext <16 x i32> [[TMP7]] to <16 x i64>31; CHECK-NEXT: [[TMP11]] = or <16 x i64> [[VEC_PHI]], [[TMP10]]32; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 1633; CHECK-NEXT: [[TMP12:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1634; CHECK-NEXT: br i1 [[TMP12]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]35; CHECK: [[MIDDLE_BLOCK]]:36; CHECK-NEXT: [[TMP13:%.*]] = call i64 @llvm.vector.reduce.or.v16i64(<16 x i64> [[TMP11]])37; CHECK-NEXT: br label %[[SCALAR_PH:.*]]38; CHECK: [[SCALAR_PH]]:39; CHECK-NEXT: br label %[[LOOP:.*]]40; CHECK: [[LOOP]]:41; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 16, %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]42; CHECK-NEXT: [[RED:%.*]] = phi i64 [ [[TMP13]], %[[SCALAR_PH]] ], [ [[RED_NEXT:%.*]], %[[LOOP]] ]43; CHECK-NEXT: [[GEP_SRC_I_I:%.*]] = getelementptr { [4 x i8] }, ptr [[SRC]], i64 [[IV]], i32 0, i64 344; CHECK-NEXT: [[L:%.*]] = load i8, ptr [[GEP_SRC_I_I]], align 145; CHECK-NEXT: [[L_EXT:%.*]] = zext i8 [[L]] to i3246; CHECK-NEXT: [[ABS_0:%.*]] = call i32 @llvm.abs.i32(i32 [[X]], i1 false)47; CHECK-NEXT: [[MIN_0:%.*]] = call i32 @llvm.umin.i32(i32 [[ABS_0]], i32 [[L_EXT]])48; CHECK-NEXT: [[ABS_1:%.*]] = call i32 @llvm.abs.i32(i32 [[X]], i1 false)49; CHECK-NEXT: [[MIN_1:%.*]] = call i32 @llvm.umin.i32(i32 [[ABS_1]], i32 [[MIN_0]])50; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 [[IV]]51; CHECK-NEXT: store i8 0, ptr [[GEP_DST]], align 152; CHECK-NEXT: [[MIN_EXT:%.*]] = zext i32 [[MIN_1]] to i6453; CHECK-NEXT: [[RED_NEXT]] = or i64 [[RED]], [[MIN_EXT]]54; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 155; CHECK-NEXT: [[EXITCOND_NOT_I_I:%.*]] = icmp eq i64 [[IV_NEXT]], 1756; CHECK-NEXT: br i1 [[EXITCOND_NOT_I_I]], label %[[EXIT:.*]], label %[[LOOP]], !llvm.loop [[LOOP3:![0-9]+]]57; CHECK: [[EXIT]]:58; CHECK-NEXT: [[RED_NEXT_LCSSA:%.*]] = phi i64 [ [[RED_NEXT]], %[[LOOP]] ]59; CHECK-NEXT: ret i64 [[RED_NEXT_LCSSA]]60;61entry:62 br label %loop63 64loop:65 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]66 %red = phi i64 [ 0, %entry ], [ %red.next, %loop ]67 %gep.src.i.i = getelementptr { [4 x i8] }, ptr %src, i64 %iv, i32 0, i64 368 %l = load i8, ptr %gep.src.i.i, align 169 %l.ext = zext i8 %l to i3270 %abs.0 = call i32 @llvm.abs.i32(i32 %x, i1 false)71 %min.0 = call i32 @llvm.umin.i32(i32 %abs.0, i32 %l.ext)72 %abs.1 = call i32 @llvm.abs.i32(i32 %x, i1 false)73 %min.1 = call i32 @llvm.umin.i32(i32 %abs.1, i32 %min.0)74 %gep.dst = getelementptr inbounds i8, ptr %dst, i64 %iv75 store i8 0, ptr %gep.dst, align 176 %min.ext = zext i32 %min.1 to i6477 %red.next = or i64 %red, %min.ext78 %iv.next = add i64 %iv, 179 %exitcond.not.i.i = icmp eq i64 %iv.next, 1780 br i1 %exitcond.not.i.i, label %exit, label %loop81 82exit:83 ret i64 %red.next84}85 86; Original loop has trip count 17, but contains interleave groups with gaps, so87; the last iteration must execute in the scalar loop. Thus the vector loop can88; only execute up to 16 iterations.89define i64 @main_vector_loop_fixed_with_no_remaining_iterations(ptr %src, ptr noalias %dst, i32 %x) #0 {90; CHECK-LABEL: define i64 @main_vector_loop_fixed_with_no_remaining_iterations(91; CHECK-SAME: ptr [[SRC:%.*]], ptr noalias [[DST:%.*]], i32 [[X:%.*]]) #[[ATTR0]] {92; CHECK-NEXT: [[ENTRY:.*:]]93; CHECK-NEXT: br label %[[VECTOR_PH:.*]]94; CHECK: [[VECTOR_PH]]:95; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <16 x i32> poison, i32 [[X]], i64 096; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <16 x i32> [[BROADCAST_SPLATINSERT]], <16 x i32> poison, <16 x i32> zeroinitializer97; CHECK-NEXT: [[TMP3:%.*]] = call <16 x i32> @llvm.abs.v16i32(<16 x i32> [[BROADCAST_SPLAT]], i1 false)98; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]99; CHECK: [[VECTOR_BODY]]:100; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]101; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <16 x i64> [ zeroinitializer, %[[VECTOR_PH]] ], [ [[TMP11:%.*]], %[[VECTOR_BODY]] ]102; CHECK-NEXT: [[TMP4:%.*]] = getelementptr { [4 x i8] }, ptr [[SRC]], i64 [[INDEX]], i32 0, i64 3103; CHECK-NEXT: [[WIDE_VEC:%.*]] = load <64 x i8>, ptr [[TMP4]], align 1104; CHECK-NEXT: [[STRIDED_VEC:%.*]] = shufflevector <64 x i8> [[WIDE_VEC]], <64 x i8> poison, <16 x i32> <i32 0, i32 4, i32 8, i32 12, i32 16, i32 20, i32 24, i32 28, i32 32, i32 36, i32 40, i32 44, i32 48, i32 52, i32 56, i32 60>105; CHECK-NEXT: [[TMP5:%.*]] = zext <16 x i8> [[STRIDED_VEC]] to <16 x i32>106; CHECK-NEXT: [[TMP6:%.*]] = call <16 x i32> @llvm.umin.v16i32(<16 x i32> [[TMP3]], <16 x i32> [[TMP5]])107; CHECK-NEXT: [[TMP7:%.*]] = call <16 x i32> @llvm.umin.v16i32(<16 x i32> [[TMP3]], <16 x i32> [[TMP6]])108; CHECK-NEXT: [[TMP26:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 [[INDEX]]109; CHECK-NEXT: store <16 x i8> zeroinitializer, ptr [[TMP26]], align 1110; CHECK-NEXT: [[TMP10:%.*]] = zext <16 x i32> [[TMP7]] to <16 x i64>111; CHECK-NEXT: [[TMP11]] = or <16 x i64> [[VEC_PHI]], [[TMP10]]112; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 16113; CHECK-NEXT: [[TMP12:%.*]] = icmp eq i64 [[INDEX_NEXT]], 16114; CHECK-NEXT: br i1 [[TMP12]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]115; CHECK: [[MIDDLE_BLOCK]]:116; CHECK-NEXT: [[TMP13:%.*]] = call i64 @llvm.vector.reduce.or.v16i64(<16 x i64> [[TMP11]])117; CHECK-NEXT: br label %[[SCALAR_PH:.*]]118; CHECK: [[SCALAR_PH]]:119; CHECK-NEXT: br label %[[LOOP:.*]]120; CHECK: [[LOOP]]:121; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 16, %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]122; CHECK-NEXT: [[RED:%.*]] = phi i64 [ [[TMP13]], %[[SCALAR_PH]] ], [ [[RED_NEXT:%.*]], %[[LOOP]] ]123; CHECK-NEXT: [[GEP_SRC_I_I:%.*]] = getelementptr { [4 x i8] }, ptr [[SRC]], i64 [[IV]], i32 0, i64 3124; CHECK-NEXT: [[L:%.*]] = load i8, ptr [[GEP_SRC_I_I]], align 1125; CHECK-NEXT: [[L_EXT:%.*]] = zext i8 [[L]] to i32126; CHECK-NEXT: [[ABS_0:%.*]] = call i32 @llvm.abs.i32(i32 [[X]], i1 false)127; CHECK-NEXT: [[MIN_0:%.*]] = call i32 @llvm.umin.i32(i32 [[ABS_0]], i32 [[L_EXT]])128; CHECK-NEXT: [[ABS_1:%.*]] = call i32 @llvm.abs.i32(i32 [[X]], i1 false)129; CHECK-NEXT: [[MIN_1:%.*]] = call i32 @llvm.umin.i32(i32 [[ABS_1]], i32 [[MIN_0]])130; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 [[IV]]131; CHECK-NEXT: store i8 0, ptr [[GEP_DST]], align 1132; CHECK-NEXT: [[MIN_EXT:%.*]] = zext i32 [[MIN_1]] to i64133; CHECK-NEXT: [[RED_NEXT]] = or i64 [[RED]], [[MIN_EXT]]134; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1135; CHECK-NEXT: [[EXITCOND_NOT_I_I:%.*]] = icmp eq i64 [[IV_NEXT]], 17136; CHECK-NEXT: br i1 [[EXITCOND_NOT_I_I]], label %[[EXIT:.*]], label %[[LOOP]], !llvm.loop [[LOOP5:![0-9]+]]137; CHECK: [[EXIT]]:138; CHECK-NEXT: [[RED_NEXT_LCSSA:%.*]] = phi i64 [ [[RED_NEXT]], %[[LOOP]] ]139; CHECK-NEXT: ret i64 [[RED_NEXT_LCSSA]]140;141entry:142 br label %loop143 144loop:145 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]146 %red = phi i64 [ 0, %entry ], [ %red.next, %loop ]147 %gep.src.i.i = getelementptr { [4 x i8] }, ptr %src, i64 %iv, i32 0, i64 3148 %l = load i8, ptr %gep.src.i.i, align 1149 %l.ext = zext i8 %l to i32150 %abs.0 = call i32 @llvm.abs.i32(i32 %x, i1 false)151 %min.0 = call i32 @llvm.umin.i32(i32 %abs.0, i32 %l.ext)152 %abs.1 = call i32 @llvm.abs.i32(i32 %x, i1 false)153 %min.1 = call i32 @llvm.umin.i32(i32 %abs.1, i32 %min.0)154 %gep.dst = getelementptr inbounds i8, ptr %dst, i64 %iv155 store i8 0, ptr %gep.dst, align 1156 %min.ext = zext i32 %min.1 to i64157 %red.next = or i64 %red, %min.ext158 %iv.next = add i64 %iv, 1159 %exitcond.not.i.i = icmp eq i64 %iv.next, 17160 br i1 %exitcond.not.i.i, label %exit, label %loop161 162exit:163 ret i64 %red.next164}165 166; Test case for https://github.com/llvm/llvm-project/issues/149726.167define void @main_vector_loop_fixed_single_vector_iteration_with_runtime_checks(ptr noalias %A, ptr noalias %B, ptr noalias %C, ptr noalias %D, ptr noalias %E, ptr noalias %F, ptr noalias %G, ptr noalias %H, ptr noalias %I, ptr noalias %J, ptr noalias %K, ptr %L) #1 {168; CHECK-LABEL: define void @main_vector_loop_fixed_single_vector_iteration_with_runtime_checks(169; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]], ptr noalias [[D:%.*]], ptr noalias [[E:%.*]], ptr noalias [[F:%.*]], ptr noalias [[G:%.*]], ptr noalias [[H:%.*]], ptr noalias [[I:%.*]], ptr noalias [[J:%.*]], ptr noalias [[K:%.*]], ptr [[L:%.*]]) #[[ATTR1:[0-9]+]] {170; CHECK-NEXT: [[ENTRY:.*:]]171; CHECK-NEXT: br label %[[VECTOR_PH:.*]]172; CHECK: [[VECTOR_PH]]:173; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]174; CHECK: [[VECTOR_BODY]]:175; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]176; CHECK-NEXT: [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], 2177; CHECK-NEXT: [[IV:%.*]] = add i64 [[OFFSET_IDX]], 0178; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 2179; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[OFFSET_IDX]], 4180; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[OFFSET_IDX]], 6181; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr i64, ptr [[J]], i64 [[IV]]182; CHECK-NEXT: [[WIDE_VEC:%.*]] = load <8 x i64>, ptr [[GEP_J]], align 8183; CHECK-NEXT: [[STRIDED_VEC:%.*]] = shufflevector <8 x i64> [[WIDE_VEC]], <8 x i64> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>184; CHECK-NEXT: [[TMP5:%.*]] = trunc <4 x i64> [[STRIDED_VEC]] to <4 x i16>185; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i16> [[TMP5]], i32 0186; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i16> [[TMP5]], i32 1187; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x i16> [[TMP5]], i32 2188; CHECK-NEXT: [[TMP13:%.*]] = extractelement <4 x i16> [[TMP5]], i32 3189; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i16, ptr [[K]], i64 [[IV]]190; CHECK-NEXT: [[TMP7:%.*]] = getelementptr i16, ptr [[K]], i64 [[TMP1]]191; CHECK-NEXT: [[TMP8:%.*]] = getelementptr i16, ptr [[K]], i64 [[TMP2]]192; CHECK-NEXT: [[TMP9:%.*]] = getelementptr i16, ptr [[K]], i64 [[TMP3]]193; CHECK-NEXT: store i16 [[TMP10]], ptr [[TMP6]], align 2194; CHECK-NEXT: store i16 [[TMP11]], ptr [[TMP7]], align 2195; CHECK-NEXT: store i16 [[TMP12]], ptr [[TMP8]], align 2196; CHECK-NEXT: store i16 [[TMP13]], ptr [[TMP9]], align 2197; CHECK-NEXT: store i64 0, ptr [[A]], align 8198; CHECK-NEXT: store i64 0, ptr [[B]], align 8199; CHECK-NEXT: store i64 0, ptr [[C]], align 8200; CHECK-NEXT: store i64 0, ptr [[D]], align 8201; CHECK-NEXT: store i64 0, ptr [[E]], align 8202; CHECK-NEXT: store i64 0, ptr [[F]], align 8203; CHECK-NEXT: store i64 0, ptr [[G]], align 8204; CHECK-NEXT: store i64 0, ptr [[H]], align 8205; CHECK-NEXT: store i64 0, ptr [[I]], align 8206; CHECK-NEXT: store i64 0, ptr [[L]], align 8207; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4208; CHECK-NEXT: [[TMP14:%.*]] = icmp eq i64 [[INDEX_NEXT]], 4209; CHECK-NEXT: br i1 [[TMP14]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]210; CHECK: [[MIDDLE_BLOCK]]:211; CHECK-NEXT: br label %[[SCALAR_PH:.*]]212; CHECK: [[SCALAR_PH]]:213; CHECK-NEXT: br label %[[LOOP:.*]]214; CHECK: [[LOOP]]:215; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ 8, %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]216; CHECK-NEXT: [[GEP_J1:%.*]] = getelementptr i64, ptr [[J]], i64 [[IV1]]217; CHECK-NEXT: [[L_J:%.*]] = load i64, ptr [[GEP_J1]], align 8218; CHECK-NEXT: [[L_TRUNC:%.*]] = trunc i64 [[L_J]] to i16219; CHECK-NEXT: [[GEP_K:%.*]] = getelementptr i16, ptr [[K]], i64 [[IV1]]220; CHECK-NEXT: store i16 [[L_TRUNC]], ptr [[GEP_K]], align 2221; CHECK-NEXT: store i64 0, ptr [[A]], align 8222; CHECK-NEXT: store i64 0, ptr [[B]], align 8223; CHECK-NEXT: store i64 0, ptr [[C]], align 8224; CHECK-NEXT: store i64 0, ptr [[D]], align 8225; CHECK-NEXT: store i64 0, ptr [[E]], align 8226; CHECK-NEXT: store i64 0, ptr [[F]], align 8227; CHECK-NEXT: store i64 0, ptr [[G]], align 8228; CHECK-NEXT: store i64 0, ptr [[H]], align 8229; CHECK-NEXT: store i64 0, ptr [[I]], align 8230; CHECK-NEXT: store i64 0, ptr [[L]], align 8231; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV1]], 2232; CHECK-NEXT: [[EC:%.*]] = icmp ult i64 [[IV1]], 14233; CHECK-NEXT: br i1 [[EC]], label %[[LOOP]], label %[[EXIT:.*]], !llvm.loop [[LOOP8:![0-9]+]]234; CHECK: [[EXIT]]:235; CHECK-NEXT: ret void236;237entry:238 br label %loop239 240loop:241 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]242 %gep.J = getelementptr i64, ptr %J, i64 %iv243 %l.J = load i64, ptr %gep.J, align 8244 %l.trunc = trunc i64 %l.J to i16245 %gep.K = getelementptr i16, ptr %K, i64 %iv246 store i16 %l.trunc, ptr %gep.K, align 2247 store i64 0, ptr %A, align 8248 store i64 0, ptr %B, align 8249 store i64 0, ptr %C, align 8250 store i64 0, ptr %D, align 8251 store i64 0, ptr %E, align 8252 store i64 0, ptr %F, align 8253 store i64 0, ptr %G, align 8254 store i64 0, ptr %H, align 8255 store i64 0, ptr %I, align 8256 store i64 0, ptr %L, align 8257 %iv.next = add i64 %iv, 2258 %ec = icmp ult i64 %iv, 14259 br i1 %ec, label %loop, label %exit, !llvm.loop !0260 261exit:262 ret void263}264 265declare i32 @llvm.umin.i32(i32, i32)266 267declare i32 @llvm.abs.i32(i32, i1 immarg)268 269attributes #0 = { "target-cpu"="neoverse-512tvb" }270attributes #1 = { "target-cpu"="grace" }271 272!0 = distinct !{!0, !1, !2}273!1 = !{!"llvm.loop.mustprogress"}274!2 = !{!"llvm.loop.vectorize.enable", i1 true}275