199 lines · plain
1; RUN: opt -mtriple=thumbv8.1m.main-none-none-eabi -passes=hardware-loops %s -S -o - | FileCheck %s2; RUN: opt -mtriple=thumbv8.1m.main-none-none-eabi -passes=hardware-loops -disable-arm-loloops=true %s -S -o - | FileCheck %s --check-prefix=DISABLED3; RUN: llc -mtriple=thumbv8.1m.main-none-none-eabi %s -o - | FileCheck %s --check-prefix=CHECK-LLC4 5; DISABLED-NOT: llvm.{{.*}}.loop.iterations6; DISABLED-NOT: llvm.loop.decrement7 8@g = common local_unnamed_addr global ptr null, align 49 10; CHECK-LABEL: do_copy11; CHECK: [[START:%[^ ]+]] = call i32 @llvm.start.loop.iterations.i32(i32 %n)12; CHECK: br label %while.body13 14; CHECK: [[REM:%[^ ]+]] = phi i32 [ [[START]], %entry ], [ [[LOOP_DEC:%[^ ]+]], %while.body ]15; CHECK: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[REM]], i32 1)16; CHECK: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 017; CHECK: br i1 [[CMP]], label %while.body, label %while.end18 19; CHECK-LLC-LABEL:do_copy:20; CHECK-LLC-NOT: mov lr, r021; CHECK-LLC: dls lr, r022; CHECK-LLC-NOT: mov lr, r023; CHECK-LLC: [[LOOP_HEADER:\.LBB[0-9_]+]]:24; CHECK-LLC: le lr, [[LOOP_HEADER]]25; CHECK-LLC-NOT: b [[LOOP_EXIT:\.LBB[0-9._]+]]26; CHECK-LLC: @ %while.end27define i32 @do_copy(i32 %n, ptr nocapture %p, ptr nocapture readonly %q) {28entry:29 br label %while.body30 31while.body:32 %q.addr.05 = phi ptr [ %incdec.ptr, %while.body ], [ %q, %entry ]33 %p.addr.04 = phi ptr [ %incdec.ptr1, %while.body ], [ %p, %entry ]34 %x.addr.03 = phi i32 [ %dec, %while.body ], [ %n, %entry ]35 %dec = add nsw i32 %x.addr.03, -136 %incdec.ptr = getelementptr inbounds i32, ptr %q.addr.05, i32 137 %0 = load i32, ptr %q.addr.05, align 438 %incdec.ptr1 = getelementptr inbounds i32, ptr %p.addr.04, i32 139 store i32 %0, ptr %p.addr.04, align 440 %tobool = icmp eq i32 %dec, 041 br i1 %tobool, label %while.end, label %while.body42 43while.end:44 ret i32 045}46 47; CHECK-LABEL: do_inc148; CHECK: entry:49; CHECK: [[TEST:%[^ ]+]] = call { i32, i1 } @llvm.test.start.loop.iterations.i32(i32 %n)50; CHECK: [[TEST1:%[^ ]+]] = extractvalue { i32, i1 } [[TEST]], 151; CHECK: [[TEST0:%[^ ]+]] = extractvalue { i32, i1 } [[TEST]], 052; CHECK: br i1 [[TEST1]], label %while.body.lr.ph, label %while.end53 54; CHECK: while.body.lr.ph:55; CHECK: br label %while.body56 57; CHECK: [[REM:%[^ ]+]] = phi i32 [ [[TEST0]], %while.body.lr.ph ], [ [[LOOP_DEC:%[^ ]+]], %while.body ]58; CHECK: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[REM]], i32 1)59; CHECK: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 060; CHECK: br i1 [[CMP]], label %while.body, label %while.end.loopexit61 62; CHECK-LLC-LABEL:do_inc1:63; CHECK-LLC: wls lr, {{.*}}, [[LOOP_EXIT:.[LBB_0-3]+]]64; CHECK-LLC-NOT: mov lr,65; CHECK-LLC: [[LOOP_HEADER:\.LBB[0-9_]+]]:66; CHECK-LLC: le lr, [[LOOP_HEADER]]67; CHECK-LLC-NOT: b [[LOOP_EXIT:\.LBB[0-9_]+]]68; CHECK-LLC: [[LOOP_EXIT]]:69 70define i32 @do_inc1(i32 %n) {71entry:72 %cmp7 = icmp eq i32 %n, 073 br i1 %cmp7, label %while.end, label %while.body.lr.ph74 75while.body.lr.ph:76 %0 = load ptr, ptr @g, align 477 br label %while.body78 79while.body:80 %i.09 = phi i32 [ 0, %while.body.lr.ph ], [ %inc1, %while.body ]81 %res.08 = phi i32 [ 0, %while.body.lr.ph ], [ %add, %while.body ]82 %arrayidx = getelementptr inbounds i32, ptr %0, i32 %i.0983 %1 = load i32, ptr %arrayidx, align 484 %add = add nsw i32 %1, %res.0885 %inc1 = add nuw i32 %i.09, 186 %exitcond = icmp eq i32 %inc1, %n87 br i1 %exitcond, label %while.end.loopexit, label %while.body88 89while.end.loopexit:90 br label %while.end91 92while.end:93 %res.0.lcssa = phi i32 [ 0, %entry ], [ %add, %while.end.loopexit ]94 ret i32 %res.0.lcssa95}96 97; CHECK-LABEL: do_inc298; CHECK: entry:99; CHECK: [[ROUND:%[^ ]+]] = add i32 %n, -1100; CHECK: [[HALVE:%[^ ]+]] = lshr i32 [[ROUND]], 1101; CHECK: [[COUNT:%[^ ]+]] = add nuw i32 [[HALVE]], 1102 103; CHECK: while.body.lr.ph:104; CHECK: [[START:%[^ ]+]] = call i32 @llvm.start.loop.iterations.i32(i32 [[COUNT]])105; CHECK: br label %while.body106; CHECK: while.body:107; CHECK: [[REM:%[^ ]+]] = phi i32 [ [[START]], %while.body.lr.ph ], [ [[LOOP_DEC:%[^ ]+]], %while.body ]108; CHECK: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[REM]], i32 1)109; CHECK: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0110; CHECK: br i1 [[CMP]], label %while.body, label %while.end.loopexit111 112; CHECK-LLC: do_inc2:113; CHECK-LLC-NOT: mov lr,114; CHECK-LLC: add.w lr,115; CHECK-LLC-NOT: dls lr,116; CHECK-LLC-NOT: mov lr,117; CHECK-LLC: [[LOOP_HEADER:\.LBB[0-9._]+]]:118; CHECK-LLC: le lr, [[LOOP_HEADER]]119 120define i32 @do_inc2(i32 %n) {121entry:122 %cmp7 = icmp sgt i32 %n, 0123 br i1 %cmp7, label %while.body.lr.ph, label %while.end124 125while.body.lr.ph:126 %0 = load ptr, ptr @g, align 4127 br label %while.body128 129while.body:130 %i.09 = phi i32 [ 0, %while.body.lr.ph ], [ %add1, %while.body ]131 %res.08 = phi i32 [ 0, %while.body.lr.ph ], [ %add, %while.body ]132 %arrayidx = getelementptr inbounds i32, ptr %0, i32 %i.09133 %1 = load i32, ptr %arrayidx, align 4134 %add = add nsw i32 %1, %res.08135 %add1 = add nuw nsw i32 %i.09, 2136 %cmp = icmp slt i32 %add1, %n137 br i1 %cmp, label %while.body, label %while.end.loopexit138 139while.end.loopexit:140 br label %while.end141 142while.end:143 %res.0.lcssa = phi i32 [ 0, %entry ], [ %add, %while.end.loopexit ]144 ret i32 %res.0.lcssa145}146 147; CHECK-LABEL: do_dec2148 149; CHECK: entry:150; CHECK: [[ROUND:%[^ ]+]] = add i32 %n, 1151; CHECK: [[SMIN:%[^ ]+]] = call i32 @llvm.smin.i32(i32 %n, i32 2)152; CHECK: [[SUB:%[^ ]+]] = sub i32 [[ROUND]], [[SMIN]]153; CHECK: [[HALVE:%[^ ]+]] = lshr i32 [[SUB]], 1154; CHECK: [[COUNT:%[^ ]+]] = add nuw i32 [[HALVE]], 1155 156; CHECK: while.body.lr.ph:157; CHECK: [[START:%[^ ]+]] = call i32 @llvm.start.loop.iterations.i32(i32 [[COUNT]])158; CHECK: br label %while.body159 160; CHECK: [[REM:%[^ ]+]] = phi i32 [ [[START]], %while.body.lr.ph ], [ [[LOOP_DEC:%[^ ]+]], %while.body ]161; CHECK: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[REM]], i32 1)162; CHECK: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0163; CHECK: br i1 [[CMP]], label %while.body, label %while.end.loopexit164 165; CHECK-LLC: do_dec2166; CHECK-LLC-NOT: mov lr,167; CHECK-LLC: add.w lr,168; CHECK-LLC-NOT: dls lr,169; CHECK-LLC-NOT: mov lr,170; CHECK-LLC: [[LOOP_HEADER:\.LBB[0-9_]+]]:171; CHECK-LLC: le lr, [[LOOP_HEADER]]172; CHECK-LLC-NOT: b .173define i32 @do_dec2(i32 %n) {174entry:175 %cmp6 = icmp sgt i32 %n, 0176 br i1 %cmp6, label %while.body.lr.ph, label %while.end177 178while.body.lr.ph:179 %0 = load ptr, ptr @g, align 4180 br label %while.body181 182while.body:183 %i.08 = phi i32 [ %n, %while.body.lr.ph ], [ %sub, %while.body ]184 %res.07 = phi i32 [ 0, %while.body.lr.ph ], [ %add, %while.body ]185 %arrayidx = getelementptr inbounds i32, ptr %0, i32 %i.08186 %1 = load i32, ptr %arrayidx, align 4187 %add = add nsw i32 %1, %res.07188 %sub = add nsw i32 %i.08, -2189 %cmp = icmp sgt i32 %i.08, 2190 br i1 %cmp, label %while.body, label %while.end.loopexit191 192while.end.loopexit:193 br label %while.end194 195while.end:196 %res.0.lcssa = phi i32 [ 0, %entry ], [ %add, %while.end.loopexit ]197 ret i32 %res.0.lcssa198}199