1; RUN: opt -passes=loop-vectorize -force-vector-width=4 -force-vector-interleave=1 -S %s | FileCheck %s 2 3define void @test_chained_first_order_recurrences_1(i16* %ptr) { 4; CHECK-LABEL: @test_chained_first_order_recurrences_1 5; CHECK-NOT: vector.body: 6; 7entry: 8 br label %loop 9 10loop: 11 %for.1 = phi i16 [ 22, %entry ], [ %for.1.next, %loop ] 12 %for.2 = phi i16 [ 33, %entry ], [ %for.1, %loop ] 13 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 14 %iv.next = add nuw nsw i64 %iv, 1 15 %gep.ptr = getelementptr inbounds i16, i16* %ptr, i64 %iv 16 %for.1.next = load i16, i16* %gep.ptr, align 2 17 %add = add i16 %for.1, %for.2 18 store i16 %add, i16* %gep.ptr 19 %exitcond.not = icmp eq i64 %iv.next, 1000 20 br i1 %exitcond.not, label %exit, label %loop 21 22exit: 23 ret void 24} 25 26define void @test_chained_first_order_recurrences_2(i16* %ptr) { 27; CHECK-LABEL: @test_chained_first_order_recurrences_2 28; CHECK-NOT: vector.body: 29; 30entry: 31 br label %loop 32 33loop: 34 %for.2 = phi i16 [ 33, %entry ], [ %for.1, %loop ] 35 %for.1 = phi i16 [ 22, %entry ], [ %for.1.next, %loop ] 36 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 37 %iv.next = add nuw nsw i64 %iv, 1 38 %gep.ptr = getelementptr inbounds i16, i16* %ptr, i64 %iv 39 %for.1.next = load i16, i16* %gep.ptr, align 2 40 %add = add i16 %for.1, %for.2 41 store i16 %add, i16* %gep.ptr 42 %exitcond.not = icmp eq i64 %iv.next, 1000 43 br i1 %exitcond.not, label %exit, label %loop 44 45exit: 46 ret void 47} 48 49define void @test_chained_first_order_recurrences_3(i16* %ptr) { 50; CHECK-LABEL: @test_chained_first_order_recurrences_3 51; CHECK-NOT: vector.body: 52; 53entry: 54 br label %loop 55 56loop: 57 %for.1 = phi i16 [ 22, %entry ], [ %for.1.next, %loop ] 58 %for.2 = phi i16 [ 33, %entry ], [ %for.1, %loop ] 59 %for.3 = phi i16 [ 33, %entry ], [ %for.2, %loop ] 60 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 61 %iv.next = add nuw nsw i64 %iv, 1 62 %gep.ptr = getelementptr inbounds i16, i16* %ptr, i64 %iv 63 %for.1.next = load i16, i16* %gep.ptr, align 2 64 %add.1 = add i16 %for.1, %for.2 65 %add.2 = add i16 %add.1, %for.3 66 store i16 %add.2, i16* %gep.ptr 67 %exitcond.not = icmp eq i64 %iv.next, 1000 68 br i1 %exitcond.not, label %exit, label %loop 69 70exit: 71 ret void 72} 73 74 75define void @test_cyclic_phis(i16* %ptr) { 76; CHECK-LABEL: @test_cyclic_phis 77; CHECK-NOT: vector.body: 78; 79entry: 80 br label %loop 81 82loop: 83 %for.1 = phi i16 [ 22, %entry ], [ %for.2, %loop ] 84 %for.2 = phi i16 [ 33, %entry ], [ %for.1, %loop ] 85 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 86 %iv.next = add nuw nsw i64 %iv, 1 87 %gep.ptr = getelementptr inbounds i16, i16* %ptr, i64 %iv 88 %for.1.next = load i16, i16* %gep.ptr, align 2 89 %add = add i16 %for.1, %for.2 90 store i16 %add, i16* %gep.ptr 91 %exitcond.not = icmp eq i64 %iv.next, 1000 92 br i1 %exitcond.not, label %exit, label %loop 93 94exit: 95 ret void 96} 97 98define void @test_first_order_recurrences_incoming_cycle_preheader(i16* %ptr) { 99; CHECK-LABEL: @test_first_order_recurrences_incoming_cycle_preheader 100; CHECK: vector.body: 101; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %vector.body ] 102; CHECK-NEXT: [[VECTOR_RECUR:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 0>, %vector.ph ], [ [[WIDE_LOAD:%.*]], %vector.body ] 103; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 104; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i16, i16* [[PTR:%.*]], i64 [[TMP0]] 105; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i16, i16* [[TMP1]], i32 0 106; CHECK-NEXT: [[TMP3:%.*]] = bitcast i16* [[TMP2]] to <4 x i16>* 107; CHECK-NEXT: [[WIDE_LOAD]] = load <4 x i16>, <4 x i16>* [[TMP3]], align 2 108; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <4 x i16> [[VECTOR_RECUR]], <4 x i16> [[WIDE_LOAD]], <4 x i32> <i32 3, i32 4, i32 5, i32 6> 109; CHECK-NEXT: [[TMP5:%.*]] = add <4 x i16> [[TMP4]], <i16 10, i16 10, i16 10, i16 10> 110; CHECK-NEXT: [[TMP6:%.*]] = bitcast i16* [[TMP2]] to <4 x i16>* 111; CHECK-NEXT: store <4 x i16> [[TMP5]], <4 x i16>* [[TMP6]], align 2 112; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4 113; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000 114; CHECK-NEXT: br i1 [[TMP7]], label %middle.block, label %vector.body 115; 116entry: 117 br label %loop.1 118 119loop.1: 120 %p = phi i16 [ 0, %entry ], [ %p, %loop.1 ] 121 br i1 true, label %loop, label %loop.1 122 123loop: 124 %for.1 = phi i16 [ %p, %loop.1 ], [ %for.1.next, %loop ] 125 %iv = phi i64 [ 0, %loop.1 ], [ %iv.next, %loop ] 126 %iv.next = add nuw nsw i64 %iv, 1 127 %gep.ptr = getelementptr inbounds i16, i16* %ptr, i64 %iv 128 %for.1.next = load i16, i16* %gep.ptr, align 2 129 %add = add i16 %for.1, 10 130 store i16 %add, i16* %gep.ptr 131 %exitcond.not = icmp eq i64 %iv.next, 1000 132 br i1 %exitcond.not, label %exit, label %loop 133 134exit: 135 ret void 136} 137 138define void @test_chained_first_order_recurrence_sink_users_1(double* %ptr) { 139; CHECK-LABEL: @test_chained_first_order_recurrence_sink_users_1 140; CHECK-NOT: vector.body: 141; 142entry: 143 br label %loop 144 145loop: 146 %for.1 = phi double [ 10.0, %entry ], [ %for.1.next, %loop ] 147 %for.2 = phi double [ 20.0, %entry ], [ %for.1, %loop ] 148 %iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ] 149 %add.1 = fadd double 10.0, %for.2 150 %add.2 = fadd double %add.1, %for.1 151 %iv.next = add nuw nsw i64 %iv, 1 152 %gep.ptr = getelementptr inbounds double, double* %ptr, i64 %iv 153 %for.1.next = load double, double* %gep.ptr, align 8 154 store double %add.2, double* %gep.ptr 155 %exitcond.not = icmp eq i64 %iv.next, 1000 156 br i1 %exitcond.not, label %exit, label %loop 157 158exit: 159 ret void 160} 161