14178c153SChen Zheng; RUN: llc < %s -mtriple=powerpc64le-unknown-linux-gnu -verify-machineinstrs -mcpu=pwr8 | FileCheck %s --check-prefixes=CHECK,CHECK-PWR8
24178c153SChen Zheng; RUN: llc < %s -mtriple=powerpc64le-unknown-linux-gnu -verify-machineinstrs -mcpu=a2q | FileCheck %s --check-prefixes=CHECK,CHECK-A2Q
30724fea2SLei Huang
40724fea2SLei Huang; Verify that we do NOT generate the mtctr instruction for loop trip counts < 4
50724fea2SLei Huang; The latency of the mtctr is only justified if there are more than 4 comparisons that are removed as a result.
60724fea2SLei Huang
70724fea2SLei Huang@a = common local_unnamed_addr global i32 0, align 4
84178c153SChen Zheng@b = common local_unnamed_addr global i32 0, align 4
94178c153SChen Zheng@c = common local_unnamed_addr global i32 0, align 4
104178c153SChen Zheng@d = common local_unnamed_addr global i32 0, align 4
114178c153SChen Zheng@e = common local_unnamed_addr global i32 0, align 4
124178c153SChen Zheng@f = common local_unnamed_addr global i32 0, align 4
130724fea2SLei Huang@arr = common local_unnamed_addr global [5 x i32] zeroinitializer, align 4
140724fea2SLei Huang
150724fea2SLei Huang; Function Attrs: norecurse nounwind readonly
160724fea2SLei Huangdefine signext i32 @testTripCount2(i32 signext %a) {
170724fea2SLei Huang
180724fea2SLei Huang; CHECK-LABEL: testTripCount2:
190724fea2SLei Huang; CHECK-NOT: mtctr
200724fea2SLei Huang; CHECK: blr
210724fea2SLei Huang
220724fea2SLei Huangentry:
230724fea2SLei Huang  br label %for.body
240724fea2SLei Huang
250724fea2SLei Huangfor.cond.cleanup:                                 ; preds = %for.body
260724fea2SLei Huang  ret i32 %add
270724fea2SLei Huang
280724fea2SLei Huangfor.body:                                         ; preds = %entry, %for.body
290724fea2SLei Huang  %indvars.iv = phi i64 [ 1, %entry ], [ %indvars.iv.next, %for.body ]
300724fea2SLei Huang  %Sum.05 = phi i32 [ 0, %entry ], [ %add, %for.body ]
310724fea2SLei Huang  %arrayidx = getelementptr inbounds [5 x i32], [5 x i32]* @arr, i64 0, i64 %indvars.iv
320724fea2SLei Huang  %0 = load i32, i32* %arrayidx, align 4
330724fea2SLei Huang  %add = add nsw i32 %0, %Sum.05
340724fea2SLei Huang  %indvars.iv.next = add nsw i64 %indvars.iv, -1
350724fea2SLei Huang  %tobool = icmp eq i64 %indvars.iv, 0
360724fea2SLei Huang  br i1 %tobool, label %for.cond.cleanup, label %for.body
370724fea2SLei Huang}
380724fea2SLei Huang
390724fea2SLei Huang; Function Attrs: norecurse nounwind readonly
400724fea2SLei Huangdefine signext i32 @testTripCount3(i32 signext %a) {
410724fea2SLei Huang
420724fea2SLei Huang; CHECK-LABEL: testTripCount3:
430724fea2SLei Huang; CHECK-NOT: mtctr
440724fea2SLei Huang; CHECK: blr
450724fea2SLei Huang
460724fea2SLei Huangentry:
470724fea2SLei Huang  br label %for.body
480724fea2SLei Huang
490724fea2SLei Huangfor.cond.cleanup:                                 ; preds = %for.body
500724fea2SLei Huang  ret i32 %add
510724fea2SLei Huang
520724fea2SLei Huangfor.body:                                         ; preds = %entry, %for.body
530724fea2SLei Huang  %indvars.iv = phi i64 [ 2, %entry ], [ %indvars.iv.next, %for.body ]
540724fea2SLei Huang  %Sum.05 = phi i32 [ 0, %entry ], [ %add, %for.body ]
550724fea2SLei Huang  %arrayidx = getelementptr inbounds [5 x i32], [5 x i32]* @arr, i64 0, i64 %indvars.iv
560724fea2SLei Huang  %0 = load i32, i32* %arrayidx, align 4
570724fea2SLei Huang  %add = add nsw i32 %0, %Sum.05
580724fea2SLei Huang  %indvars.iv.next = add nsw i64 %indvars.iv, -1
590724fea2SLei Huang  %tobool = icmp eq i64 %indvars.iv, 0
600724fea2SLei Huang  br i1 %tobool, label %for.cond.cleanup, label %for.body
610724fea2SLei Huang}
620724fea2SLei Huang
630724fea2SLei Huang; Function Attrs: norecurse nounwind readonly
640724fea2SLei Huang
650724fea2SLei Huangdefine signext i32 @testTripCount4(i32 signext %a) {
660724fea2SLei Huang
670724fea2SLei Huang; CHECK-LABEL: testTripCount4:
680724fea2SLei Huang; CHECK: mtctr
690724fea2SLei Huang; CHECK: bdnz
700724fea2SLei Huang
710724fea2SLei Huangentry:
720724fea2SLei Huang  br label %for.body
730724fea2SLei Huang
740724fea2SLei Huangfor.cond.cleanup:                                 ; preds = %for.body
750724fea2SLei Huang  ret i32 %add
760724fea2SLei Huang
770724fea2SLei Huangfor.body:                                         ; preds = %entry, %for.body
780724fea2SLei Huang  %indvars.iv = phi i64 [ 3, %entry ], [ %indvars.iv.next, %for.body ]
790724fea2SLei Huang  %Sum.05 = phi i32 [ 0, %entry ], [ %add, %for.body ]
800724fea2SLei Huang  %arrayidx = getelementptr inbounds [5 x i32], [5 x i32]* @arr, i64 0, i64 %indvars.iv
810724fea2SLei Huang  %0 = load i32, i32* %arrayidx, align 4
820724fea2SLei Huang  %add = add nsw i32 %0, %Sum.05
830724fea2SLei Huang  %indvars.iv.next = add nsw i64 %indvars.iv, -1
840724fea2SLei Huang  %tobool = icmp eq i64 %indvars.iv, 0
850724fea2SLei Huang  br i1 %tobool, label %for.cond.cleanup, label %for.body
860724fea2SLei Huang}
870724fea2SLei Huang
880724fea2SLei Huang; Function Attrs: norecurse nounwind
89*dfdccbb2SChen Zheng; On core a2q, IssueWidth is 1. On core pwr8, IssueWidth is 8.
90*dfdccbb2SChen Zheng; a2q should use mtctr, but pwr8 should not use mtctr.
910724fea2SLei Huangdefine signext i32 @testTripCount2NonSmallLoop() {
920724fea2SLei Huang; CHECK-LABEL: testTripCount2NonSmallLoop:
93*dfdccbb2SChen Zheng; CHECK-A2Q: mtctr
94*dfdccbb2SChen Zheng; CHECK-PWR8-NOT: mtctr
950724fea2SLei Huang; CHECK: blr
960724fea2SLei Huang
970724fea2SLei Huangentry:
980724fea2SLei Huang  %.pre = load i32, i32* @a, align 4
990724fea2SLei Huang  br label %for.body
1000724fea2SLei Huang
1010724fea2SLei Huangfor.body:                                         ; preds = %entry, %if.end
1020724fea2SLei Huang  %0 = phi i32 [ %.pre, %entry ], [ %1, %if.end ]
1030724fea2SLei Huang  %dec4 = phi i32 [ 1, %entry ], [ %dec, %if.end ]
1040724fea2SLei Huang  %b.03 = phi i8 [ 0, %entry ], [ %b.1, %if.end ]
1050724fea2SLei Huang  %tobool1 = icmp eq i32 %0, 0
1060724fea2SLei Huang  br i1 %tobool1, label %if.end, label %if.then
1070724fea2SLei Huang
1080724fea2SLei Huangif.then:                                          ; preds = %for.body
1090724fea2SLei Huang  store i32 2, i32* @a, align 4
1100724fea2SLei Huang  br label %if.end
1110724fea2SLei Huang
1120724fea2SLei Huangif.end:                                           ; preds = %for.body, %if.then
1130724fea2SLei Huang  %1 = phi i32 [ 2, %if.then ], [ 0, %for.body ]
1140724fea2SLei Huang  %b.1 = phi i8 [ 2, %if.then ], [ %b.03, %for.body ]
1150724fea2SLei Huang  %dec = add nsw i32 %dec4, -1
1160724fea2SLei Huang  %tobool = icmp eq i32 %dec4, 0
1170724fea2SLei Huang  br i1 %tobool, label %for.end, label %for.body
1180724fea2SLei Huang
1190724fea2SLei Huangfor.end:                                          ; preds = %if.end
1200724fea2SLei Huang  %conv = zext i8 %b.1 to i32
1210724fea2SLei Huang  ret i32 %conv
1220724fea2SLei Huang}
1230724fea2SLei Huang
1244178c153SChen Zheng; On core a2q, IssueWidth is 1. On core pwr8, IssueWidth is 8.
1254178c153SChen Zheng; a2q should use mtctr, but pwr8 should not use mtctr.
1264178c153SChen Zhengdefine signext i32 @testTripCount5() {
1274178c153SChen Zheng; CHECK-LABEL: testTripCount5:
12819ce6719SChen Zheng; CHECK-PWR8-NOT: mtctr
1294178c153SChen Zheng; CHECK-A2Q: mtctr
1304178c153SChen Zheng
1314178c153SChen Zhengentry:
1324178c153SChen Zheng  %.prea = load i32, i32* @a, align 4
1334178c153SChen Zheng  %.preb = load i32, i32* @b, align 4
1344178c153SChen Zheng  %.prec = load i32, i32* @c, align 4
1354178c153SChen Zheng  %.pred = load i32, i32* @d, align 4
1364178c153SChen Zheng  %.pree = load i32, i32* @e, align 4
1374178c153SChen Zheng  %.pref = load i32, i32* @f, align 4
1384178c153SChen Zheng  br label %for.body
1394178c153SChen Zheng
1404178c153SChen Zhengfor.body:                                 ; preds = %entry, %for.body
1414178c153SChen Zheng  %indvars.iv = phi i64 [ 2, %entry ], [ %indvars.iv.next, %for.body ]
1424178c153SChen Zheng  %0 = phi i32 [ %.prea, %entry ], [ %6, %for.body ]
1434178c153SChen Zheng  %1 = phi i32 [ %.preb, %entry ], [ %7, %for.body ]
1444178c153SChen Zheng  %2 = phi i32 [ %.prec, %entry ], [ %8, %for.body ]
1454178c153SChen Zheng  %3 = phi i32 [ %.pred, %entry ], [ %9, %for.body ]
1464178c153SChen Zheng  %4 = phi i32 [ %.pree, %entry ], [ %10, %for.body ]
1474178c153SChen Zheng  %5 = phi i32 [ %.pref, %entry ], [ %11, %for.body ]
1484178c153SChen Zheng  %6 = add i32 %0, 1
1494178c153SChen Zheng  %7 = add i32 %1, 1
1504178c153SChen Zheng  %8 = add i32 %2, 1
1514178c153SChen Zheng  %9 = add i32 %3, 1
1524178c153SChen Zheng  %10 = add i32 %4, 1
1534178c153SChen Zheng  %11 = add i32 %5, 1
1544178c153SChen Zheng  %indvars.iv.next = add nsw i64 %indvars.iv, -1
1554178c153SChen Zheng  %tobool = icmp eq i64 %indvars.iv, 0
1564178c153SChen Zheng  br i1 %tobool, label %for.end, label %for.body
1574178c153SChen Zheng
1584178c153SChen Zhengfor.end:                                 ; preds = %for.body
1594178c153SChen Zheng  store i32 %6, i32* @a, align 4
1604178c153SChen Zheng  store i32 %7, i32* @b, align 4
1614178c153SChen Zheng  store i32 %8, i32* @c, align 4
1624178c153SChen Zheng  store i32 %9, i32* @d, align 4
1634178c153SChen Zheng  store i32 %10, i32* @e, align 4
1644178c153SChen Zheng  store i32 %11, i32* @f, align 4
1654178c153SChen Zheng  ret i32 0
1664178c153SChen Zheng}
1674178c153SChen Zheng
168