llvm-project/llvm/test/Transforms/LoopVectorize/nested-loops-scev-expansion.ll
Florian Hahn 2511b143ac
[LV] Add additional SCEV expansion test with nested loops.
Update SCEV expansion tests to check for full generated IR and add
additional test to check for expanding SCEVs before an existing
instruction in the entry block.
2025-08-23 21:41:46 +01:00

410 lines
20 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 5
; RUN: opt -passes=loop-vectorize -force-vector-width=2 -force-vector-interleave=2 -scev-verify-ir -S %s | FileCheck %s
; Make sure SCEV is not queried while the IR is temporarily invalid.
define void @pr49538() {
; CHECK-LABEL: define void @pr49538() {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: br label %[[LOOP_0:.*]]
; CHECK: [[LOOP_0]]:
; CHECK-NEXT: [[IV_0:%.*]] = phi i16 [ -1, %[[ENTRY]] ], [ [[IV_0_NEXT:%.*]], %[[LOOP_0_LATCH:.*]] ]
; CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[IV_0]] to i32
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[TMP0]], 1
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i32 [[TMP1]], 4
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
; CHECK: [[VECTOR_PH]]:
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i32 [[TMP1]], 4
; CHECK-NEXT: [[N_VEC:%.*]] = sub i32 [[TMP1]], [[N_MOD_VF]]
; CHECK-NEXT: [[DOTCAST:%.*]] = trunc i32 [[N_VEC]] to i16
; CHECK-NEXT: [[TMP2:%.*]] = add i16 -1, [[DOTCAST]]
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
; CHECK: [[VECTOR_BODY]]:
; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 4
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
; CHECK-NEXT: br i1 [[TMP3]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
; CHECK: [[MIDDLE_BLOCK]]:
; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i32 [[TMP1]], [[N_VEC]]
; CHECK-NEXT: br i1 [[CMP_N]], label %[[LOOP_0_LATCH]], label %[[SCALAR_PH]]
; CHECK: [[SCALAR_PH]]:
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i16 [ [[TMP2]], %[[MIDDLE_BLOCK]] ], [ -1, %[[LOOP_0]] ]
; CHECK-NEXT: br label %[[LOOP_1:.*]]
; CHECK: [[LOOP_1]]:
; CHECK-NEXT: [[IV_1:%.*]] = phi i16 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_1_NEXT:%.*]], %[[LOOP_1]] ]
; CHECK-NEXT: [[IV_1_NEXT]] = add nsw i16 [[IV_1]], 1
; CHECK-NEXT: [[I6:%.*]] = icmp eq i16 [[IV_1_NEXT]], [[IV_0]]
; CHECK-NEXT: br i1 [[I6]], label %[[LOOP_0_LATCH]], label %[[LOOP_1]], !llvm.loop [[LOOP3:![0-9]+]]
; CHECK: [[LOOP_0_LATCH]]:
; CHECK-NEXT: [[I8:%.*]] = phi i16 [ 1, %[[LOOP_1]] ], [ 1, %[[MIDDLE_BLOCK]] ]
; CHECK-NEXT: [[IV_0_NEXT]] = add nsw i16 [[IV_0]], 1
; CHECK-NEXT: [[EC_0:%.*]] = icmp eq i16 [[IV_0_NEXT]], [[I8]]
; CHECK-NEXT: br i1 [[EC_0]], label %[[EXIT:.*]], label %[[LOOP_0]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
entry:
br label %loop.0
loop.0:
%iv.0 = phi i16 [ -1, %entry ], [ %iv.0.next, %loop.0.latch ]
br label %loop.1
loop.1:
%iv.1 = phi i16 [ -1, %loop.0 ], [ %iv.1.next, %loop.1 ]
%iv.1.next = add nsw i16 %iv.1, 1
%i6 = icmp eq i16 %iv.1.next, %iv.0
br i1 %i6, label %loop.0.latch, label %loop.1
loop.0.latch:
%i8 = phi i16 [ 1, %loop.1 ]
%iv.0.next = add nsw i16 %iv.0, 1
%ec.0 = icmp eq i16 %iv.0.next, %i8
br i1 %ec.0, label %exit, label %loop.0
exit:
ret void
}
define void @pr49900(i32 %x, ptr %ptr) {
; CHECK-LABEL: define void @pr49900(
; CHECK-SAME: i32 [[X:%.*]], ptr [[PTR:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: br label %[[LOOP_0:.*]]
; CHECK: [[LOOP_0]]:
; CHECK-NEXT: [[EC_0:%.*]] = icmp slt i32 [[X]], 0
; CHECK-NEXT: br i1 [[EC_0]], label %[[LOOP_0]], label %[[LOOP_1_PH:.*]]
; CHECK: [[LOOP_1_PH]]:
; CHECK-NEXT: br label %[[LOOP_1:.*]]
; CHECK: [[LOOP_1]]:
; CHECK-NEXT: [[IV_1:%.*]] = phi i32 [ 0, %[[LOOP_1_PH]] ], [ [[IV_3_NEXT_LCSSA:%.*]], %[[LOOP_1_LATCH:.*]] ]
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[IV_1]], 12
; CHECK-NEXT: [[SMAX2:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 65537)
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[SMAX2]], -12
; CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[TMP1]], [[IV_1]]
; CHECK-NEXT: [[UMIN3:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP2]], i32 1)
; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[UMIN3]], 1
; CHECK-NEXT: [[TMP4:%.*]] = sub i32 [[TMP2]], [[UMIN3]]
; CHECK-NEXT: [[TMP5:%.*]] = udiv i32 [[TMP4]], 13
; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[TMP3]], [[TMP5]]
; CHECK-NEXT: [[MIN_ITERS_CHECK5:%.*]] = icmp ult i32 [[TMP6]], 4
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK5]], label %[[SCALAR_PH4:.*]], label %[[VECTOR_PH6:.*]]
; CHECK: [[VECTOR_PH6]]:
; CHECK-NEXT: [[N_MOD_VF7:%.*]] = urem i32 [[TMP6]], 4
; CHECK-NEXT: [[N_VEC8:%.*]] = sub i32 [[TMP6]], [[N_MOD_VF7]]
; CHECK-NEXT: [[TMP7:%.*]] = mul i32 [[N_VEC8]], 13
; CHECK-NEXT: [[TMP8:%.*]] = add i32 [[IV_1]], [[TMP7]]
; CHECK-NEXT: br label %[[VECTOR_BODY9:.*]]
; CHECK: [[VECTOR_BODY9]]:
; CHECK-NEXT: [[INDEX10:%.*]] = phi i32 [ 0, %[[VECTOR_PH6]] ], [ [[INDEX_NEXT11:%.*]], %[[VECTOR_BODY9]] ]
; CHECK-NEXT: [[INDEX_NEXT11]] = add nuw i32 [[INDEX10]], 4
; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[INDEX_NEXT11]], [[N_VEC8]]
; CHECK-NEXT: br i1 [[TMP9]], label %[[MIDDLE_BLOCK12:.*]], label %[[VECTOR_BODY9]], !llvm.loop [[LOOP4:![0-9]+]]
; CHECK: [[MIDDLE_BLOCK12]]:
; CHECK-NEXT: [[CMP_N13:%.*]] = icmp eq i32 [[TMP6]], [[N_VEC8]]
; CHECK-NEXT: br i1 [[CMP_N13]], label %[[LOOP_3_PH:.*]], label %[[SCALAR_PH4]]
; CHECK: [[SCALAR_PH4]]:
; CHECK-NEXT: [[BC_RESUME_VAL14:%.*]] = phi i32 [ [[TMP8]], %[[MIDDLE_BLOCK12]] ], [ [[IV_1]], %[[LOOP_1]] ]
; CHECK-NEXT: br label %[[LOOP_2:.*]]
; CHECK: [[LOOP_2]]:
; CHECK-NEXT: [[IV_2:%.*]] = phi i32 [ [[BC_RESUME_VAL14]], %[[SCALAR_PH4]] ], [ [[IV_2_NEXT:%.*]], %[[LOOP_2]] ]
; CHECK-NEXT: [[TMP54:%.*]] = add i32 [[IV_2]], 12
; CHECK-NEXT: [[IV_2_NEXT]] = add i32 [[IV_2]], 13
; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[IV_2_NEXT]] to i64
; CHECK-NEXT: [[TMP56:%.*]] = add nuw nsw i64 [[EXT]], 1
; CHECK-NEXT: [[C6:%.*]] = icmp sle i32 [[TMP54]], 65536
; CHECK-NEXT: br i1 [[C6]], label %[[LOOP_2]], label %[[LOOP_3_PH]], !llvm.loop [[LOOP5:![0-9]+]]
; CHECK: [[LOOP_3_PH]]:
; CHECK-NEXT: [[IV_2_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_2_NEXT]], %[[LOOP_2]] ], [ [[TMP8]], %[[MIDDLE_BLOCK12]] ]
; CHECK-NEXT: [[TMP10:%.*]] = add i32 [[IV_1]], 26
; CHECK-NEXT: [[TMP11:%.*]] = add i32 [[IV_1]], 12
; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP11]], i32 65537)
; CHECK-NEXT: [[TMP12:%.*]] = add i32 [[SMAX]], -12
; CHECK-NEXT: [[TMP13:%.*]] = sub i32 [[TMP12]], [[IV_1]]
; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP13]], i32 1)
; CHECK-NEXT: [[TMP14:%.*]] = sub i32 [[TMP13]], [[UMIN]]
; CHECK-NEXT: [[TMP15:%.*]] = udiv i32 [[TMP14]], 13
; CHECK-NEXT: [[TMP16:%.*]] = add i32 [[UMIN]], [[TMP15]]
; CHECK-NEXT: [[TMP17:%.*]] = mul i32 [[TMP16]], 13
; CHECK-NEXT: [[TMP18:%.*]] = add i32 [[TMP10]], [[TMP17]]
; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[TMP18]], i32 65536)
; CHECK-NEXT: [[TMP19:%.*]] = add i32 [[UMAX]], -26
; CHECK-NEXT: [[TMP20:%.*]] = sub i32 [[TMP19]], [[IV_1]]
; CHECK-NEXT: [[TMP21:%.*]] = sub i32 [[TMP20]], [[TMP17]]
; CHECK-NEXT: [[UMIN1:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP21]], i32 1)
; CHECK-NEXT: [[TMP22:%.*]] = add i32 [[UMIN1]], 1
; CHECK-NEXT: [[TMP23:%.*]] = sub i32 [[TMP20]], [[UMIN1]]
; CHECK-NEXT: [[TMP24:%.*]] = sub i32 [[TMP23]], [[TMP17]]
; CHECK-NEXT: [[TMP25:%.*]] = udiv i32 [[TMP24]], 13
; CHECK-NEXT: [[TMP26:%.*]] = add i32 [[TMP22]], [[TMP25]]
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i32 [[TMP26]], 4
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
; CHECK: [[VECTOR_PH]]:
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i32 [[TMP26]], 4
; CHECK-NEXT: [[N_VEC:%.*]] = sub i32 [[TMP26]], [[N_MOD_VF]]
; CHECK-NEXT: [[TMP27:%.*]] = mul i32 [[N_VEC]], 13
; CHECK-NEXT: [[TMP28:%.*]] = add i32 [[IV_2_NEXT_LCSSA]], [[TMP27]]
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
; CHECK: [[VECTOR_BODY]]:
; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 4
; CHECK-NEXT: [[TMP29:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
; CHECK-NEXT: br i1 [[TMP29]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
; CHECK: [[MIDDLE_BLOCK]]:
; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i32 [[TMP26]], [[N_VEC]]
; CHECK-NEXT: br i1 [[CMP_N]], label %[[LOOP_1_LATCH]], label %[[SCALAR_PH]]
; CHECK: [[SCALAR_PH]]:
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i32 [ [[TMP28]], %[[MIDDLE_BLOCK]] ], [ [[IV_2_NEXT_LCSSA]], %[[LOOP_3_PH]] ]
; CHECK-NEXT: br label %[[LOOP_3:.*]]
; CHECK: [[LOOP_3]]:
; CHECK-NEXT: [[IV_3:%.*]] = phi i32 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_3_NEXT:%.*]], %[[LOOP_3]] ]
; CHECK-NEXT: [[IV_3_NEXT]] = add i32 [[IV_3]], 13
; CHECK-NEXT: [[C1:%.*]] = icmp ult i32 [[IV_3_NEXT]], 65536
; CHECK-NEXT: br i1 [[C1]], label %[[LOOP_3]], label %[[LOOP_1_LATCH]], !llvm.loop [[LOOP7:![0-9]+]]
; CHECK: [[LOOP_1_LATCH]]:
; CHECK-NEXT: [[IV_3_NEXT_LCSSA]] = phi i32 [ [[IV_3_NEXT]], %[[LOOP_3]] ], [ [[TMP28]], %[[MIDDLE_BLOCK]] ]
; CHECK-NEXT: [[EC:%.*]] = icmp ne i32 [[IV_1]], 9999
; CHECK-NEXT: br i1 [[EC]], label %[[LOOP_1]], label %[[EXIT:.*]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
entry:
br label %loop.0
loop.0: ; preds = %bb2, %bb
%ec.0 = icmp slt i32 %x, 0
br i1 %ec.0, label %loop.0, label %loop.1.ph
loop.1.ph: ; preds = %bb2
br label %loop.1
loop.1: ; preds = %bb33, %bb5
%iv.1 = phi i32 [ 0, %loop.1.ph ], [ %iv.3.next, %loop.1.latch ]
br label %loop.2
loop.2:
%iv.2 = phi i32 [ %iv.1, %loop.1 ], [ %iv.2.next, %loop.2 ]
%tmp54 = add i32 %iv.2, 12
%iv.2.next = add i32 %iv.2, 13
%ext = zext i32 %iv.2.next to i64
%tmp56 = add nuw nsw i64 %ext, 1
%C6 = icmp sle i32 %tmp54, 65536
br i1 %C6, label %loop.2, label %loop.3.ph
loop.3.ph:
br label %loop.3
loop.3:
%iv.3 = phi i32 [ %iv.2.next, %loop.3.ph ], [ %iv.3.next, %loop.3 ]
%iv.3.next = add i32 %iv.3 , 13
%C1 = icmp ult i32 %iv.3.next, 65536
br i1 %C1, label %loop.3, label %loop.1.latch
loop.1.latch:
%ec = icmp ne i32 %iv.1, 9999
br i1 %ec, label %loop.1, label %exit
exit:
ret void
}
define void @pr52024(ptr %dst, i16 %N) {
; CHECK-LABEL: define void @pr52024(
; CHECK-SAME: ptr [[DST:%.*]], i16 [[N:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: br label %[[LOOP_1:.*]]
; CHECK: [[LOOP_1]]:
; CHECK-NEXT: [[IV_1:%.*]] = phi i16 [ 1, %[[ENTRY]] ], [ [[IV_1_NEXT:%.*]], %[[LOOP_1_LATCH:.*]] ]
; CHECK-NEXT: [[IV_1_NEXT]] = mul i16 [[IV_1]], 3
; CHECK-NEXT: [[EXITCOND_1:%.*]] = icmp uge i16 [[IV_1_NEXT]], 99
; CHECK-NEXT: br i1 [[EXITCOND_1]], label %[[LOOP_1_LATCH]], label %[[EXIT_LOOPEXIT1:.*]]
; CHECK: [[LOOP_1_LATCH]]:
; CHECK-NEXT: [[EXITCOND_2:%.*]] = icmp eq i16 [[IV_1_NEXT]], [[N]]
; CHECK-NEXT: br i1 [[EXITCOND_2]], label %[[LOOP_2_PH:.*]], label %[[LOOP_1]]
; CHECK: [[LOOP_2_PH]]:
; CHECK-NEXT: [[IV_1_LCSSA2:%.*]] = phi i16 [ [[IV_1]], %[[LOOP_1_LATCH]] ]
; CHECK-NEXT: [[IV_1_NEXT_LCSSA:%.*]] = phi i16 [ [[IV_1_NEXT]], %[[LOOP_1_LATCH]] ]
; CHECK-NEXT: [[IV_1_NEXT_EXT:%.*]] = sext i16 [[IV_1_NEXT_LCSSA]] to i64
; CHECK-NEXT: [[TMP0:%.*]] = mul i16 [[IV_1_LCSSA2]], 3
; CHECK-NEXT: br label %[[LOOP_2_HEADER:.*]]
; CHECK: [[LOOP_2_HEADER]]:
; CHECK-NEXT: [[IV_1_REM:%.*]] = urem i64 100, [[IV_1_NEXT_EXT]]
; CHECK-NEXT: [[REM_TRUNC:%.*]] = trunc i64 [[IV_1_REM]] to i16
; CHECK-NEXT: [[TMP1:%.*]] = udiv i64 100, [[IV_1_NEXT_EXT]]
; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i16
; CHECK-NEXT: [[TMP3:%.*]] = mul i16 [[TMP0]], [[TMP2]]
; CHECK-NEXT: [[TMP4:%.*]] = add i16 [[TMP3]], -100
; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
; CHECK: [[VECTOR_PH]]:
; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <2 x i16> poison, i16 [[TMP4]], i64 0
; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <2 x i16> [[BROADCAST_SPLATINSERT]], <2 x i16> poison, <2 x i32> zeroinitializer
; CHECK-NEXT: [[TMP5:%.*]] = mul i16 24, [[TMP4]]
; CHECK-NEXT: [[TMP6:%.*]] = mul <2 x i16> splat (i16 2), [[BROADCAST_SPLAT]]
; CHECK-NEXT: [[BROADCAST_SPLATINSERT3:%.*]] = insertelement <2 x i16> poison, i16 [[REM_TRUNC]], i64 0
; CHECK-NEXT: [[BROADCAST_SPLAT4:%.*]] = shufflevector <2 x i16> [[BROADCAST_SPLATINSERT3]], <2 x i16> poison, <2 x i32> zeroinitializer
; CHECK-NEXT: [[BROADCAST_SPLATINSERT5:%.*]] = insertelement <2 x i16> poison, i16 [[TMP4]], i64 0
; CHECK-NEXT: [[BROADCAST_SPLAT6:%.*]] = shufflevector <2 x i16> [[BROADCAST_SPLATINSERT5]], <2 x i16> poison, <2 x i32> zeroinitializer
; CHECK-NEXT: [[TMP7:%.*]] = mul <2 x i16> <i16 0, i16 1>, [[BROADCAST_SPLAT6]]
; CHECK-NEXT: [[INDUCTION:%.*]] = add <2 x i16> zeroinitializer, [[TMP7]]
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
; CHECK: [[VECTOR_BODY]]:
; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i16> [ [[INDUCTION]], %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ]
; CHECK-NEXT: [[STEP_ADD:%.*]] = add <2 x i16> [[VEC_IND]], [[TMP6]]
; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i32 8, [[INDEX]]
; CHECK-NEXT: [[TMP8:%.*]] = sub <2 x i16> [[VEC_IND]], [[BROADCAST_SPLAT4]]
; CHECK-NEXT: [[TMP9:%.*]] = sub <2 x i16> [[STEP_ADD]], [[BROADCAST_SPLAT4]]
; CHECK-NEXT: [[TMP10:%.*]] = zext <2 x i16> [[TMP8]] to <2 x i32>
; CHECK-NEXT: [[TMP11:%.*]] = zext <2 x i16> [[TMP9]] to <2 x i32>
; CHECK-NEXT: [[TMP12:%.*]] = getelementptr i32, ptr [[DST]], i32 [[OFFSET_IDX]]
; CHECK-NEXT: [[TMP13:%.*]] = getelementptr i32, ptr [[TMP12]], i32 2
; CHECK-NEXT: store <2 x i32> [[TMP10]], ptr [[TMP12]], align 4
; CHECK-NEXT: store <2 x i32> [[TMP11]], ptr [[TMP13]], align 4
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 4
; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i16> [[STEP_ADD]], [[TMP6]]
; CHECK-NEXT: [[TMP14:%.*]] = icmp eq i32 [[INDEX_NEXT]], 24
; CHECK-NEXT: br i1 [[TMP14]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]
; CHECK: [[MIDDLE_BLOCK]]:
; CHECK-NEXT: br label %[[SCALAR_PH]]
; CHECK: [[SCALAR_PH]]:
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i32 [ 32, %[[MIDDLE_BLOCK]] ], [ 8, %[[LOOP_2_HEADER]] ]
; CHECK-NEXT: [[BC_RESUME_VAL7:%.*]] = phi i16 [ [[TMP5]], %[[MIDDLE_BLOCK]] ], [ 0, %[[LOOP_2_HEADER]] ]
; CHECK-NEXT: br label %[[LOOP_3:.*]]
; CHECK: [[LOOP_3]]:
; CHECK-NEXT: [[IV_3:%.*]] = phi i32 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_3_NEXT:%.*]], %[[LOOP_3]] ]
; CHECK-NEXT: [[SUB_PHI:%.*]] = phi i16 [ [[BC_RESUME_VAL7]], %[[SCALAR_PH]] ], [ [[SUB:%.*]], %[[LOOP_3]] ]
; CHECK-NEXT: [[SUB]] = sub i16 [[SUB_PHI]], [[REM_TRUNC]]
; CHECK-NEXT: [[SUB_EXT:%.*]] = zext i16 [[SUB]] to i32
; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr i32, ptr [[DST]], i32 [[IV_3]]
; CHECK-NEXT: store i32 [[SUB_EXT]], ptr [[GEP_DST]], align 4
; CHECK-NEXT: [[IV_3_NEXT]] = add nuw nsw i32 [[IV_3]], 1
; CHECK-NEXT: [[EXITCOND_3:%.*]] = icmp eq i32 [[IV_3_NEXT]], 34
; CHECK-NEXT: br i1 [[EXITCOND_3]], label %[[LOOP_2_LATCH:.*]], label %[[LOOP_3]], !llvm.loop [[LOOP9:![0-9]+]]
; CHECK: [[LOOP_2_LATCH]]:
; CHECK-NEXT: [[SUB_LCSSA:%.*]] = phi i16 [ [[SUB]], %[[LOOP_3]] ]
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp uge i16 [[SUB_LCSSA]], 200
; CHECK-NEXT: br i1 [[EXITCOND]], label %[[EXIT_LOOPEXIT:.*]], label %[[LOOP_2_HEADER]]
; CHECK: [[EXIT_LOOPEXIT]]:
; CHECK-NEXT: br label %[[EXIT:.*]]
; CHECK: [[EXIT_LOOPEXIT1]]:
; CHECK-NEXT: br label %[[EXIT]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
entry:
br label %loop.1
loop.1:
%iv.1 = phi i16 [ 1, %entry ], [ %iv.1.next, %loop.1.latch ]
%iv.1.next = mul i16 %iv.1, 3
%exitcond.1 = icmp uge i16 %iv.1.next, 99
br i1 %exitcond.1, label %loop.1.latch, label %exit
loop.1.latch:
%exitcond.2 = icmp eq i16 %iv.1.next, %N
br i1 %exitcond.2, label %loop.2.ph, label %loop.1
loop.2.ph:
%iv.1.next.lcssa = phi i16 [ %iv.1.next, %loop.1.latch ]
%iv.1.next.ext = sext i16 %iv.1.next.lcssa to i64
br label %loop.2.header
loop.2.header:
%iv.1.rem = urem i64 100, %iv.1.next.ext
%rem.trunc = trunc i64 %iv.1.rem to i16
br label %loop.3
loop.3:
%iv.3 = phi i32 [ 8, %loop.2.header ], [ %iv.3.next, %loop.3 ]
%sub.phi = phi i16 [ 0, %loop.2.header ], [ %sub, %loop.3 ]
%sub = sub i16 %sub.phi, %rem.trunc
%sub.ext = zext i16 %sub to i32
%gep.dst = getelementptr i32, ptr %dst, i32 %iv.3
store i32 %sub.ext, ptr %gep.dst
%iv.3.next= add nuw nsw i32 %iv.3, 1
%exitcond.3 = icmp eq i32 %iv.3.next, 34
br i1 %exitcond.3, label %loop.2.latch, label %loop.3
loop.2.latch:
%sub.lcssa = phi i16 [ %sub, %loop.3 ]
%exitcond = icmp uge i16 %sub.lcssa, 200
br i1 %exitcond, label %exit, label %loop.2.header
exit:
ret void
}
define void @test_expand_secv_in_entry_before_gep(ptr %dst) {
; CHECK-LABEL: define void @test_expand_secv_in_entry_before_gep(
; CHECK-SAME: ptr [[DST:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: br label %[[OUTER_HEADER:.*]]
; CHECK: [[OUTER_HEADER]]:
; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[OUTER_IV_NEXT:%.*]], %[[OUTER_LATCH:.*]] ]
; CHECK-NEXT: [[TMP0:%.*]] = mul i64 [[OUTER_IV]], -1
; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[TMP0]], 112
; CHECK-NEXT: [[GEP_M:%.*]] = getelementptr [36 x [36 x double]], ptr [[DST]], i64 0, i64 [[OUTER_IV]]
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP1]], 4
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
; CHECK: [[VECTOR_PH]]:
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP1]], 4
; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP1]], [[N_MOD_VF]]
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[OUTER_IV]], [[N_VEC]]
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
; CHECK: [[VECTOR_BODY]]:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 [[OUTER_IV]], [[INDEX]]
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds double, ptr [[GEP_M]], i64 [[OFFSET_IDX]]
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds double, ptr [[TMP3]], i32 2
; CHECK-NEXT: store <2 x double> zeroinitializer, ptr [[TMP3]], align 8
; CHECK-NEXT: store <2 x double> zeroinitializer, ptr [[TMP4]], align 8
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
; CHECK-NEXT: br i1 [[TMP5]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]]
; CHECK: [[MIDDLE_BLOCK]]:
; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP1]], [[N_VEC]]
; CHECK-NEXT: br i1 [[CMP_N]], label %[[OUTER_LATCH]], label %[[SCALAR_PH]]
; CHECK: [[SCALAR_PH]]:
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[TMP2]], %[[MIDDLE_BLOCK]] ], [ [[OUTER_IV]], %[[OUTER_HEADER]] ]
; CHECK-NEXT: br label %[[INNER:.*]]
; CHECK: [[INNER]]:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[INNER]] ]
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds double, ptr [[GEP_M]], i64 [[IV]]
; CHECK-NEXT: store double 0.000000e+00, ptr [[GEP]], align 8
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], 111
; CHECK-NEXT: br i1 [[EC]], label %[[OUTER_LATCH]], label %[[INNER]], !llvm.loop [[LOOP11:![0-9]+]]
; CHECK: [[OUTER_LATCH]]:
; CHECK-NEXT: [[OUTER_IV_NEXT]] = add i64 [[OUTER_IV]], 1
; CHECK-NEXT: [[C:%.*]] = call i1 @cond()
; CHECK-NEXT: br i1 [[C]], label %[[OUTER_HEADER]], label %[[EXIT:.*]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
entry:
br label %outer.header
outer.header:
%outer.iv = phi i64 [ 0, %entry ], [ %outer.iv.next, %outer.latch ]
%gep.m = getelementptr [36 x [36 x double]], ptr %dst, i64 0, i64 %outer.iv
br label %inner
inner:
%iv = phi i64 [ %outer.iv, %outer.header ], [ %iv.next, %inner ]
%gep = getelementptr inbounds double, ptr %gep.m, i64 %iv
store double 0.00, ptr %gep, align 8
%iv.next = add i64 %iv, 1
%ec = icmp eq i64 %iv, 111
br i1 %ec, label %outer.latch, label %inner
outer.latch:
%outer.iv.next = add i64 %outer.iv, 1
%c = call i1 @cond()
br i1 %c, label %outer.header, label %exit
exit:
ret void
}
declare void @cond()