llvm-project/llvm/test/Transforms/LoopVectorize/nested-loops-scev-expansion.ll
Florian Hahn 98d3a25f74
[VPlan] Don't preserve LCSSA in expandSCEVs. (#165505)
This follows similar reasoning as 45ce88758d24
(https://github.com/llvm/llvm-project/pull/159556):

LV does not preserve LCSSA, it constructs it just before processing a
loop to vectorize. Runtime check expressions are invariant to that loop,
so expanding them should not break LCSSA form for the loop we are about
to vectorize.

LV creates SCEV and memory runtime checks early on and then disconnects
the blocks temporarily. The patch fixes a mis-compile, where previously
LCSSA construction during SCEV expand may replace uses in currently
unreachable SCEV/memory check blocks.

Fixes https://github.com/llvm/llvm-project/issues/162512

PR: https://github.com/llvm/llvm-project/pull/165505
2025-10-29 18:25:46 +00:00

405 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_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]], 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 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_SPLATINSERT5:%.*]] = insertelement <2 x i16> poison, i16 [[REM_TRUNC]], 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_SPLAT]]
; 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_SPLAT6]]
; CHECK-NEXT: [[TMP9:%.*]] = sub <2 x i16> [[STEP_ADD]], [[BROADCAST_SPLAT6]]
; 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: br label %[[LOOP_3:.*]]
; CHECK: [[LOOP_3]]:
; CHECK-NEXT: [[IV_3:%.*]] = phi i32 [ 32, %[[SCALAR_PH]] ], [ [[IV_3_NEXT:%.*]], %[[LOOP_3]] ]
; CHECK-NEXT: [[SUB_PHI:%.*]] = phi i16 [ [[TMP5]], %[[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()