; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 ; RUN: opt -p loop-vectorize -vectorizer-min-trip-count=8 -mcpu=skylake-avx512 -S %s | FileCheck %s target triple = "x86_64-unknown-linux-gnu" ; Test case for https://github.com/llvm/llvm-project/issues/121518. Make sure ; that we preserve LCSSA form when using %iv.1 from loop.1 in the trip count ; expression when vectorizing loop.2 define void @value_defined_in_loop1_used_for_trip_counts(i32 %start, i1 %c, ptr %dst) { ; CHECK-LABEL: define void @value_defined_in_loop1_used_for_trip_counts( ; CHECK-SAME: i32 [[START:%.*]], i1 [[C:%.*]], ptr [[DST:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: [[ENTRY:.*]]: ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[C]], i32 0, i32 7 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[SELECT]] to i64 ; CHECK-NEXT: br label %[[LOOP_1:.*]] ; CHECK: [[LOOP_1]]: ; CHECK-NEXT: [[IV_1:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[ZEXT]], %[[LOOP_1]] ] ; CHECK-NEXT: br i1 false, label %[[LOOP_1_EXIT:.*]], label %[[LOOP_1]] ; CHECK: [[LOOP_1_EXIT]]: ; CHECK-NEXT: [[IV_1_LCSSA2:%.*]] = phi i64 [ [[IV_1]], %[[LOOP_1]] ] ; CHECK-NEXT: [[IV_1_LCSSA:%.*]] = phi i64 [ [[IV_1]], %[[LOOP_1]] ] ; CHECK-NEXT: br i1 [[C]], label %[[LOOP_2_PREHEADER:.*]], label %[[LOOP_3_PREHEADER:.*]] ; CHECK: [[LOOP_3_PREHEADER]]: ; CHECK-NEXT: br label %[[VECTOR_PH:.*]] ; CHECK: [[VECTOR_PH]]: ; CHECK-NEXT: [[TRIP_COUNT_MINUS_1:%.*]] = sub i64 [[IV_1_LCSSA2]], 1 ; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <16 x i64> poison, i64 [[TRIP_COUNT_MINUS_1]], i64 0 ; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <16 x i64> [[BROADCAST_SPLATINSERT]], <16 x i64> poison, <16 x i32> zeroinitializer ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] ; CHECK: [[VECTOR_BODY]]: ; CHECK-NEXT: [[TMP0:%.*]] = icmp ule <16 x i64> , [[BROADCAST_SPLAT]] ; CHECK-NEXT: call void @llvm.masked.store.v16i8.p0(<16 x i8> zeroinitializer, ptr [[DST]], i32 1, <16 x i1> [[TMP0]]) ; CHECK-NEXT: br label %[[MIDDLE_BLOCK:.*]] ; CHECK: [[MIDDLE_BLOCK]]: ; CHECK-NEXT: br label %[[EXIT_1_LOOPEXIT1:.*]] ; CHECK: [[SCALAR_PH:.*]]: ; CHECK-NEXT: br label %[[LOOP_3:.*]] ; CHECK: [[LOOP_2_PREHEADER]]: ; CHECK-NEXT: br label %[[LOOP_2:.*]] ; CHECK: [[LOOP_2]]: ; CHECK-NEXT: [[IV_2:%.*]] = phi i64 [ [[IV_2_NEXT:%.*]], %[[LOOP_2]] ], [ 0, %[[LOOP_2_PREHEADER]] ] ; CHECK-NEXT: [[IV_3:%.*]] = phi i32 [ [[IV_3_NEXT:%.*]], %[[LOOP_2]] ], [ [[START]], %[[LOOP_2_PREHEADER]] ] ; CHECK-NEXT: [[IV_3_NEXT]] = add i32 [[IV_3]], 1 ; CHECK-NEXT: [[IV_2_NEXT]] = add i64 [[IV_2]], 1 ; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[IV_3]], 1 ; CHECK-NEXT: [[ZEXT8:%.*]] = zext i32 [[SHL]] to i64 ; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr i8, ptr [[DST]], i64 [[ZEXT8]] ; CHECK-NEXT: store i16 0, ptr [[GEP_DST]], align 2 ; CHECK-NEXT: [[EC_2:%.*]] = icmp ult i64 [[IV_2]], [[IV_1_LCSSA]] ; CHECK-NEXT: br i1 [[EC_2]], label %[[LOOP_2]], label %[[EXIT_1_LOOPEXIT:.*]] ; CHECK: [[LOOP_3]]: ; CHECK-NEXT: [[IV_4:%.*]] = phi i64 [ [[IV_4_NEXT:%.*]], %[[LOOP_3]] ], [ 0, %[[SCALAR_PH]] ] ; CHECK-NEXT: [[GEP_DST_2:%.*]] = getelementptr i8, ptr [[DST]], i64 [[IV_4]] ; CHECK-NEXT: store i8 0, ptr [[GEP_DST_2]], align 1 ; CHECK-NEXT: [[IV_4_NEXT]] = add i64 [[IV_4]], 1 ; CHECK-NEXT: [[EC_3:%.*]] = icmp ult i64 [[IV_4_NEXT]], [[IV_1_LCSSA]] ; CHECK-NEXT: br i1 [[EC_3]], label %[[LOOP_3]], label %[[EXIT_1_LOOPEXIT1]] ; CHECK: [[EXIT_1_LOOPEXIT]]: ; CHECK-NEXT: br label %[[EXIT_1:.*]] ; CHECK: [[EXIT_1_LOOPEXIT1]]: ; CHECK-NEXT: br label %[[EXIT_1]] ; CHECK: [[EXIT_1]]: ; CHECK-NEXT: ret void ; entry: %select = select i1 %c, i32 0, i32 7 %zext = zext i32 %select to i64 br label %loop.1 loop.1: %iv.1 = phi i64 [ 0, %entry ], [ %zext, %loop.1 ] br i1 false, label %loop.1.exit, label %loop.1 loop.1.exit: br i1 %c, label %loop.2, label %loop.3 loop.2: %iv.2 = phi i64 [ 0, %loop.1.exit ], [ %iv.2.next, %loop.2 ] %iv.3 = phi i32 [ %start, %loop.1.exit ], [ %iv.3.next, %loop.2 ] %iv.3.next = add i32 %iv.3, 1 %iv.2.next = add i64 %iv.2, 1 %shl = shl i32 %iv.3, 1 %zext8 = zext i32 %shl to i64 %gep.dst = getelementptr i8, ptr %dst, i64 %zext8 store i16 0, ptr %gep.dst, align 2 %ec.2 = icmp ult i64 %iv.2, %iv.1 br i1 %ec.2, label %loop.2, label %exit.1 loop.3: %iv.4 = phi i64 [ 0, %loop.1.exit ], [ %iv.4.next, %loop.3 ] %gep.dst.2 = getelementptr i8, ptr %dst, i64 %iv.4 store i8 0, ptr %gep.dst.2, align 1 %iv.4.next = add i64 %iv.4, 1 %ec.3 = icmp ult i64 %iv.4.next, %iv.1 br i1 %ec.3, label %loop.3, label %exit.1 exit.1: ret void }