1; RUN: llc < %s -mtriple=powerpc64le-unknown-linux-gnu -verify-machineinstrs -mcpu=pwr8 | FileCheck %s --check-prefixes=CHECK,CHECK-PWR8
2
3; Verify that we do NOT generate the mtctr instruction for loop trip counts < 4
4; The latency of the mtctr is only justified if there are more than 4 comparisons that are removed as a result.
5
6@a = local_unnamed_addr global i32 0, align 4
7@b = local_unnamed_addr global i32 0, align 4
8@c = local_unnamed_addr global i32 0, align 4
9@d = local_unnamed_addr global i32 0, align 4
10@e = local_unnamed_addr global i32 0, align 4
11@f = local_unnamed_addr global i32 0, align 4
12@arr = local_unnamed_addr global [5 x i32] zeroinitializer, align 4
13
14; Function Attrs: norecurse nounwind readonly
15define signext i32 @testTripCount2(i32 signext %a) {
16
17; CHECK-LABEL: testTripCount2:
18; CHECK-NOT: mtctr
19; CHECK: blr
20
21entry:
22  br label %for.body
23
24for.cond.cleanup:                                 ; preds = %for.body
25  ret i32 %add
26
27for.body:                                         ; preds = %entry, %for.body
28  %indvars.iv = phi i64 [ 1, %entry ], [ %indvars.iv.next, %for.body ]
29  %Sum.05 = phi i32 [ 0, %entry ], [ %add, %for.body ]
30  %arrayidx = getelementptr inbounds [5 x i32], [5 x i32]* @arr, i64 0, i64 %indvars.iv
31  %0 = load i32, i32* %arrayidx, align 4
32  %add = add nsw i32 %0, %Sum.05
33  %indvars.iv.next = add nsw i64 %indvars.iv, -1
34  %tobool = icmp eq i64 %indvars.iv, 0
35  br i1 %tobool, label %for.cond.cleanup, label %for.body
36}
37
38; Function Attrs: norecurse nounwind readonly
39define signext i32 @testTripCount3(i32 signext %a) {
40
41; CHECK-LABEL: testTripCount3:
42; CHECK-NOT: mtctr
43; CHECK: blr
44
45entry:
46  br label %for.body
47
48for.cond.cleanup:                                 ; preds = %for.body
49  ret i32 %add
50
51for.body:                                         ; preds = %entry, %for.body
52  %indvars.iv = phi i64 [ 2, %entry ], [ %indvars.iv.next, %for.body ]
53  %Sum.05 = phi i32 [ 0, %entry ], [ %add, %for.body ]
54  %arrayidx = getelementptr inbounds [5 x i32], [5 x i32]* @arr, i64 0, i64 %indvars.iv
55  %0 = load i32, i32* %arrayidx, align 4
56  %add = add nsw i32 %0, %Sum.05
57  %indvars.iv.next = add nsw i64 %indvars.iv, -1
58  %tobool = icmp eq i64 %indvars.iv, 0
59  br i1 %tobool, label %for.cond.cleanup, label %for.body
60}
61
62; Function Attrs: norecurse nounwind readonly
63
64define signext i32 @testTripCount4(i32 signext %a) {
65
66; CHECK-LABEL: testTripCount4:
67; CHECK: mtctr
68; CHECK: bdnz
69
70entry:
71  br label %for.body
72
73for.cond.cleanup:                                 ; preds = %for.body
74  ret i32 %add
75
76for.body:                                         ; preds = %entry, %for.body
77  %indvars.iv = phi i64 [ 3, %entry ], [ %indvars.iv.next, %for.body ]
78  %Sum.05 = phi i32 [ 0, %entry ], [ %add, %for.body ]
79  %arrayidx = getelementptr inbounds [5 x i32], [5 x i32]* @arr, i64 0, i64 %indvars.iv
80  %0 = load i32, i32* %arrayidx, align 4
81  %add = add nsw i32 %0, %Sum.05
82  %indvars.iv.next = add nsw i64 %indvars.iv, -1
83  %tobool = icmp eq i64 %indvars.iv, 0
84  br i1 %tobool, label %for.cond.cleanup, label %for.body
85}
86
87; Function Attrs: norecurse nounwind
88define signext i32 @testTripCount2NonSmallLoop() {
89; CHECK-LABEL: testTripCount2NonSmallLoop:
90; CHECK-PWR8-NOT: mtctr
91; CHECK: blr
92
93entry:
94  %.pre = load i32, i32* @a, align 4
95  br label %for.body
96
97for.body:                                         ; preds = %entry, %if.end
98  %0 = phi i32 [ %.pre, %entry ], [ %1, %if.end ]
99  %dec4 = phi i32 [ 1, %entry ], [ %dec, %if.end ]
100  %b.03 = phi i8 [ 0, %entry ], [ %b.1, %if.end ]
101  %tobool1 = icmp eq i32 %0, 0
102  br i1 %tobool1, label %if.end, label %if.then
103
104if.then:                                          ; preds = %for.body
105  store i32 2, i32* @a, align 4
106  br label %if.end
107
108if.end:                                           ; preds = %for.body, %if.then
109  %1 = phi i32 [ 2, %if.then ], [ 0, %for.body ]
110  %b.1 = phi i8 [ 2, %if.then ], [ %b.03, %for.body ]
111  %dec = add nsw i32 %dec4, -1
112  %tobool = icmp eq i32 %dec4, 0
113  br i1 %tobool, label %for.end, label %for.body
114
115for.end:                                          ; preds = %if.end
116  %conv = zext i8 %b.1 to i32
117  ret i32 %conv
118}
119
120define signext i32 @testTripCount5() {
121; CHECK-LABEL: testTripCount5:
122; CHECK-PWR8-NOT: mtctr
123
124entry:
125  %.prea = load i32, i32* @a, align 4
126  %.preb = load i32, i32* @b, align 4
127  %.prec = load i32, i32* @c, align 4
128  %.pred = load i32, i32* @d, align 4
129  %.pree = load i32, i32* @e, align 4
130  %.pref = load i32, i32* @f, align 4
131  br label %for.body
132
133for.body:                                 ; preds = %entry, %for.body
134  %indvars.iv = phi i64 [ 2, %entry ], [ %indvars.iv.next, %for.body ]
135  %0 = phi i32 [ %.prea, %entry ], [ %6, %for.body ]
136  %1 = phi i32 [ %.preb, %entry ], [ %7, %for.body ]
137  %2 = phi i32 [ %.prec, %entry ], [ %8, %for.body ]
138  %3 = phi i32 [ %.pred, %entry ], [ %9, %for.body ]
139  %4 = phi i32 [ %.pree, %entry ], [ %10, %for.body ]
140  %5 = phi i32 [ %.pref, %entry ], [ %11, %for.body ]
141  %6 = add i32 %0, 1
142  %7 = add i32 %1, 1
143  %8 = add i32 %2, 1
144  %9 = add i32 %3, 1
145  %10 = add i32 %4, 1
146  %11 = add i32 %5, 1
147  %indvars.iv.next = add nsw i64 %indvars.iv, -1
148  %tobool = icmp eq i64 %indvars.iv, 0
149  br i1 %tobool, label %for.end, label %for.body
150
151for.end:                                 ; preds = %for.body
152  store i32 %6, i32* @a, align 4
153  store i32 %7, i32* @b, align 4
154  store i32 %8, i32* @c, align 4
155  store i32 %9, i32* @d, align 4
156  store i32 %10, i32* @e, align 4
157  store i32 %11, i32* @f, align 4
158  ret i32 0
159}
160
161