1 ; RUN: llc < %s -mtriple=powerpc64le-unknown-linux-gnu -verify-machineinstrs -mcpu=pwr8 | FileCheck %s --check-prefixes=CHECK,CHECK-PWR8
2 ; RUN: llc < %s -mtriple=powerpc64le-unknown-linux-gnu -verify-machineinstrs -mcpu=a2q | FileCheck %s --check-prefixes=CHECK,CHECK-A2Q
4 ; Verify that we do NOT generate the mtctr instruction for loop trip counts < 4
5 ; The latency of the mtctr is only justified if there are more than 4 comparisons that are removed as a result.
7 @a = common local_unnamed_addr global i32 0, align 4
8 @b = common local_unnamed_addr global i32 0, align 4
9 @c = common local_unnamed_addr global i32 0, align 4
10 @d = common local_unnamed_addr global i32 0, align 4
11 @e = common local_unnamed_addr global i32 0, align 4
12 @f = common local_unnamed_addr global i32 0, align 4
13 @arr = common local_unnamed_addr global [5 x i32] zeroinitializer, align 4
15 ; Function Attrs: norecurse nounwind readonly
16 define signext i32 @testTripCount2(i32 signext %a) {
18 ; CHECK-LABEL: testTripCount2:
25 for.cond.cleanup: ; preds = %for.body
28 for.body: ; preds = %entry, %for.body
29 %indvars.iv = phi i64 [ 1, %entry ], [ %indvars.iv.next, %for.body ]
30 %Sum.05 = phi i32 [ 0, %entry ], [ %add, %for.body ]
31 %arrayidx = getelementptr inbounds [5 x i32], [5 x i32]* @arr, i64 0, i64 %indvars.iv
32 %0 = load i32, i32* %arrayidx, align 4
33 %add = add nsw i32 %0, %Sum.05
34 %indvars.iv.next = add nsw i64 %indvars.iv, -1
35 %tobool = icmp eq i64 %indvars.iv, 0
36 br i1 %tobool, label %for.cond.cleanup, label %for.body
39 ; Function Attrs: norecurse nounwind readonly
40 define signext i32 @testTripCount3(i32 signext %a) {
42 ; CHECK-LABEL: testTripCount3:
49 for.cond.cleanup: ; preds = %for.body
52 for.body: ; preds = %entry, %for.body
53 %indvars.iv = phi i64 [ 2, %entry ], [ %indvars.iv.next, %for.body ]
54 %Sum.05 = phi i32 [ 0, %entry ], [ %add, %for.body ]
55 %arrayidx = getelementptr inbounds [5 x i32], [5 x i32]* @arr, i64 0, i64 %indvars.iv
56 %0 = load i32, i32* %arrayidx, align 4
57 %add = add nsw i32 %0, %Sum.05
58 %indvars.iv.next = add nsw i64 %indvars.iv, -1
59 %tobool = icmp eq i64 %indvars.iv, 0
60 br i1 %tobool, label %for.cond.cleanup, label %for.body
63 ; Function Attrs: norecurse nounwind readonly
65 define signext i32 @testTripCount4(i32 signext %a) {
67 ; CHECK-LABEL: testTripCount4:
74 for.cond.cleanup: ; preds = %for.body
77 for.body: ; preds = %entry, %for.body
78 %indvars.iv = phi i64 [ 3, %entry ], [ %indvars.iv.next, %for.body ]
79 %Sum.05 = phi i32 [ 0, %entry ], [ %add, %for.body ]
80 %arrayidx = getelementptr inbounds [5 x i32], [5 x i32]* @arr, i64 0, i64 %indvars.iv
81 %0 = load i32, i32* %arrayidx, align 4
82 %add = add nsw i32 %0, %Sum.05
83 %indvars.iv.next = add nsw i64 %indvars.iv, -1
84 %tobool = icmp eq i64 %indvars.iv, 0
85 br i1 %tobool, label %for.cond.cleanup, label %for.body
88 ; Function Attrs: norecurse nounwind
89 ; On core a2q, IssueWidth is 1. On core pwr8, IssueWidth is 8.
90 ; a2q should use mtctr, but pwr8 should not use mtctr.
91 define signext i32 @testTripCount2NonSmallLoop() {
92 ; CHECK-LABEL: testTripCount2NonSmallLoop:
94 ; CHECK-PWR8-NOT: mtctr
98 %.pre = load i32, i32* @a, align 4
101 for.body: ; preds = %entry, %if.end
102 %0 = phi i32 [ %.pre, %entry ], [ %1, %if.end ]
103 %dec4 = phi i32 [ 1, %entry ], [ %dec, %if.end ]
104 %b.03 = phi i8 [ 0, %entry ], [ %b.1, %if.end ]
105 %tobool1 = icmp eq i32 %0, 0
106 br i1 %tobool1, label %if.end, label %if.then
108 if.then: ; preds = %for.body
109 store i32 2, i32* @a, align 4
112 if.end: ; preds = %for.body, %if.then
113 %1 = phi i32 [ 2, %if.then ], [ 0, %for.body ]
114 %b.1 = phi i8 [ 2, %if.then ], [ %b.03, %for.body ]
115 %dec = add nsw i32 %dec4, -1
116 %tobool = icmp eq i32 %dec4, 0
117 br i1 %tobool, label %for.end, label %for.body
119 for.end: ; preds = %if.end
120 %conv = zext i8 %b.1 to i32
124 ; On core a2q, IssueWidth is 1. On core pwr8, IssueWidth is 8.
125 ; a2q should use mtctr, but pwr8 should not use mtctr.
126 define signext i32 @testTripCount5() {
127 ; CHECK-LABEL: testTripCount5:
128 ; CHECK-PWR8-NOT: mtctr
132 %.prea = load i32, i32* @a, align 4
133 %.preb = load i32, i32* @b, align 4
134 %.prec = load i32, i32* @c, align 4
135 %.pred = load i32, i32* @d, align 4
136 %.pree = load i32, i32* @e, align 4
137 %.pref = load i32, i32* @f, align 4
140 for.body: ; preds = %entry, %for.body
141 %indvars.iv = phi i64 [ 2, %entry ], [ %indvars.iv.next, %for.body ]
142 %0 = phi i32 [ %.prea, %entry ], [ %6, %for.body ]
143 %1 = phi i32 [ %.preb, %entry ], [ %7, %for.body ]
144 %2 = phi i32 [ %.prec, %entry ], [ %8, %for.body ]
145 %3 = phi i32 [ %.pred, %entry ], [ %9, %for.body ]
146 %4 = phi i32 [ %.pree, %entry ], [ %10, %for.body ]
147 %5 = phi i32 [ %.pref, %entry ], [ %11, %for.body ]
154 %indvars.iv.next = add nsw i64 %indvars.iv, -1
155 %tobool = icmp eq i64 %indvars.iv, 0
156 br i1 %tobool, label %for.end, label %for.body
158 for.end: ; preds = %for.body
159 store i32 %6, i32* @a, align 4
160 store i32 %7, i32* @b, align 4
161 store i32 %8, i32* @c, align 4
162 store i32 %9, i32* @d, align 4
163 store i32 %10, i32* @e, align 4
164 store i32 %11, i32* @f, align 4