[SLP] Add cost model for `llvm.powi.*` intrinsics
[llvm-project.git] / llvm / test / Transforms / LoopVectorize / first-order-recurrence-chains.ll
blob5806bbaae1f0d9ce666a6f62e559f23dec4d949a
1 ; RUN: opt -passes=loop-vectorize -force-vector-width=4 -force-vector-interleave=1 -S %s | FileCheck %s
3 define void @test_chained_first_order_recurrences_1(i16* %ptr) {
4 ; CHECK-LABEL: @test_chained_first_order_recurrences_1
5 ; CHECK-NOT: vector.body:
7 entry:
8   br label %loop
10 loop:
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
22 exit:
23   ret void
26 define void @test_chained_first_order_recurrences_2(i16* %ptr) {
27 ; CHECK-LABEL: @test_chained_first_order_recurrences_2
28 ; CHECK-NOT: vector.body:
30 entry:
31   br label %loop
33 loop:
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
45 exit:
46   ret void
49 define void @test_chained_first_order_recurrences_3(i16* %ptr) {
50 ; CHECK-LABEL: @test_chained_first_order_recurrences_3
51 ; CHECK-NOT: vector.body:
53 entry:
54   br label %loop
56 loop:
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
70 exit:
71   ret void
75 define void @test_cyclic_phis(i16* %ptr) {
76 ; CHECK-LABEL: @test_cyclic_phis
77 ; CHECK-NOT: vector.body:
79 entry:
80   br label %loop
82 loop:
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
94 exit:
95   ret void
98 define 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
116 entry:
117   br label %loop.1
119 loop.1:
120   %p = phi i16 [ 0, %entry ], [ %p, %loop.1 ]
121   br i1 true, label %loop, label %loop.1
123 loop:
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
134 exit:
135   ret void
138 define 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:
142 entry:
143   br label %loop
145 loop:
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
158 exit:
159   ret void