1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -loop-vectorize -force-vector-width=2 -S -prefer-predicate-over-epilog %s | FileCheck %s 3 4 5; Test case for PR46525. There are two candidates to pick for 6; `udiv i64 %y, %add` when expanding SCEV expressions. Make sure we pick %div, 7; which dominates the vector loop. 8 9define void @test(i16 %x, i64 %y, i32* %ptr) { 10; CHECK-LABEL: @test( 11; CHECK-NEXT: entry: 12; CHECK-NEXT: [[CONV19:%.*]] = sext i16 [[X:%.*]] to i64 13; CHECK-NEXT: [[ADD:%.*]] = add i64 [[CONV19]], 492802768830814067 14; CHECK-NEXT: br label [[LOOP_PREHEADER:%.*]] 15; CHECK: loop.preheader: 16; CHECK-NEXT: [[DIV:%.*]] = udiv i64 [[Y:%.*]], [[ADD]] 17; CHECK-NEXT: [[INC:%.*]] = add i64 [[DIV]], 1 18; CHECK-NEXT: [[TMP0:%.*]] = add nuw nsw i64 [[DIV]], 4 19; CHECK-NEXT: [[TMP1:%.*]] = udiv i64 [[TMP0]], [[INC]] 20; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i64 [[TMP1]], 1 21; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] 22; CHECK: vector.ph: 23; CHECK-NEXT: [[N_RND_UP:%.*]] = add i64 [[TMP2]], 1 24; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[N_RND_UP]], 2 25; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[N_RND_UP]], [[N_MOD_VF]] 26; CHECK-NEXT: [[IND_END:%.*]] = mul i64 [[N_VEC]], [[INC]] 27; CHECK-NEXT: [[TRIP_COUNT_MINUS_1:%.*]] = sub i64 [[TMP2]], 1 28; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <2 x i64> undef, i64 [[TRIP_COUNT_MINUS_1]], i32 0 29; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <2 x i64> [[BROADCAST_SPLATINSERT]], <2 x i64> undef, <2 x i32> zeroinitializer 30; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 31; CHECK: vector.body: 32; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE6:%.*]] ] 33; CHECK-NEXT: [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], [[INC]] 34; CHECK-NEXT: [[BROADCAST_SPLATINSERT1:%.*]] = insertelement <2 x i64> undef, i64 [[OFFSET_IDX]], i32 0 35; CHECK-NEXT: [[BROADCAST_SPLAT2:%.*]] = shufflevector <2 x i64> [[BROADCAST_SPLATINSERT1]], <2 x i64> undef, <2 x i32> zeroinitializer 36; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> undef, i64 [[INC]], i32 0 37; CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <2 x i64> [[DOTSPLATINSERT]], <2 x i64> undef, <2 x i32> zeroinitializer 38; CHECK-NEXT: [[TMP3:%.*]] = mul <2 x i64> <i64 0, i64 1>, [[DOTSPLAT]] 39; CHECK-NEXT: [[INDUCTION:%.*]] = add <2 x i64> [[BROADCAST_SPLAT2]], [[TMP3]] 40; CHECK-NEXT: [[TMP4:%.*]] = mul i64 0, [[INC]] 41; CHECK-NEXT: [[TMP5:%.*]] = add i64 [[OFFSET_IDX]], [[TMP4]] 42; CHECK-NEXT: [[BROADCAST_SPLATINSERT3:%.*]] = insertelement <2 x i64> undef, i64 [[INDEX]], i32 0 43; CHECK-NEXT: [[BROADCAST_SPLAT4:%.*]] = shufflevector <2 x i64> [[BROADCAST_SPLATINSERT3]], <2 x i64> undef, <2 x i32> zeroinitializer 44; CHECK-NEXT: [[VEC_IV:%.*]] = add <2 x i64> [[BROADCAST_SPLAT4]], <i64 0, i64 1> 45; CHECK-NEXT: [[TMP6:%.*]] = icmp ule <2 x i64> [[VEC_IV]], [[BROADCAST_SPLAT]] 46; CHECK-NEXT: [[TMP7:%.*]] = extractelement <2 x i1> [[TMP6]], i32 0 47; CHECK-NEXT: br i1 [[TMP7]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]] 48; CHECK: pred.store.if: 49; CHECK-NEXT: store i32 0, i32* [[PTR:%.*]], align 4 50; CHECK-NEXT: br label [[PRED_STORE_CONTINUE]] 51; CHECK: pred.store.continue: 52; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i1> [[TMP6]], i32 1 53; CHECK-NEXT: br i1 [[TMP8]], label [[PRED_STORE_IF5:%.*]], label [[PRED_STORE_CONTINUE6]] 54; CHECK: pred.store.if5: 55; CHECK-NEXT: store i32 0, i32* [[PTR]], align 4 56; CHECK-NEXT: br label [[PRED_STORE_CONTINUE6]] 57; CHECK: pred.store.continue6: 58; CHECK-NEXT: [[OFFSET_IDX7:%.*]] = mul i64 [[INDEX]], [[INC]] 59; CHECK-NEXT: [[TMP9:%.*]] = trunc i64 [[OFFSET_IDX7]] to i8 60; CHECK-NEXT: [[TMP10:%.*]] = trunc i64 [[INC]] to i8 61; CHECK-NEXT: [[BROADCAST_SPLATINSERT8:%.*]] = insertelement <2 x i8> undef, i8 [[TMP9]], i32 0 62; CHECK-NEXT: [[BROADCAST_SPLAT9:%.*]] = shufflevector <2 x i8> [[BROADCAST_SPLATINSERT8]], <2 x i8> undef, <2 x i32> zeroinitializer 63; CHECK-NEXT: [[DOTSPLATINSERT10:%.*]] = insertelement <2 x i8> undef, i8 [[TMP10]], i32 0 64; CHECK-NEXT: [[DOTSPLAT11:%.*]] = shufflevector <2 x i8> [[DOTSPLATINSERT10]], <2 x i8> undef, <2 x i32> zeroinitializer 65; CHECK-NEXT: [[TMP11:%.*]] = mul <2 x i8> <i8 0, i8 1>, [[DOTSPLAT11]] 66; CHECK-NEXT: [[INDUCTION12:%.*]] = add <2 x i8> [[BROADCAST_SPLAT9]], [[TMP11]] 67; CHECK-NEXT: [[TMP12:%.*]] = mul i8 0, [[TMP10]] 68; CHECK-NEXT: [[TMP13:%.*]] = add i8 [[TMP9]], [[TMP12]] 69; CHECK-NEXT: [[TMP14:%.*]] = add i8 [[TMP13]], 1 70; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 2 71; CHECK-NEXT: [[TMP15:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] 72; CHECK-NEXT: br i1 [[TMP15]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop !0 73; 74entry: 75 %conv19 = sext i16 %x to i64 76 %add = add i64 %conv19, 492802768830814067 77 br label %loop.preheader 78 79loop.preheader: 80 %div = udiv i64 %y, %add 81 %inc = add i64 %div, 1 82 br label %loop 83 84loop: 85 %iv = phi i64 [ %iv.next, %loop ], [ 0, %loop.preheader ] 86 store i32 0, i32* %ptr, align 4 87 %v2 = trunc i64 %iv to i8 88 %v3 = add i8 %v2, 1 89 %cmp15 = icmp slt i8 %v3, 5 90 %iv.next = add i64 %iv, %inc 91 br i1 %cmp15, label %loop, label %loop.exit 92 93loop.exit: 94 %div.1 = udiv i64 %y, %add 95 %v1 = add i64 %div.1, 1 96 br label %loop.2 97 98loop.2: 99 %iv.1 = phi i64 [ %iv.next.1, %loop.2 ], [ 0, %loop.exit ] 100 %iv.next.1 = add i64 %iv.1, %v1 101 call void @use(i64 %iv.next.1) 102 %ec = icmp ult i64 %iv.next.1, 200 103 br i1 %ec, label %loop.2, label %loop.2.exit 104 105loop.2.exit: 106 %c = call i1 @cond() 107 br i1 %c, label %loop.preheader, label %exit 108 109exit: 110 ret void 111} 112 113declare void @use(i64) 114declare i1 @cond() 115