1*2a58be42SSamuel Parker; RUN: opt -mtriple=thumbv8.1m.main-none-none-eabi -passes=hardware-loops %s -S -o - | FileCheck %s 2*2a58be42SSamuel Parker; RUN: opt -mtriple=thumbv8.1m.main-none-none-eabi -passes=hardware-loops -disable-arm-loloops=true %s -S -o - | FileCheck %s --check-prefix=DISABLED 3eecba950SDavid Green; RUN: llc -mtriple=thumbv8.1m.main-none-none-eabi %s -o - | FileCheck %s --check-prefix=CHECK-LLC 4757ac02dSSam Parker 598722691SSam Parker; DISABLED-NOT: llvm.{{.*}}.loop.iterations 6757ac02dSSam Parker; DISABLED-NOT: llvm.loop.decrement 7757ac02dSSam Parker 8d17f4f26SMatt Arsenault@g = common local_unnamed_addr global ptr null, align 4 9757ac02dSSam Parker 10757ac02dSSam Parker; CHECK-LABEL: do_copy 11b2ac9681SDavid Green; CHECK: [[START:%[^ ]+]] = call i32 @llvm.start.loop.iterations.i32(i32 %n) 12757ac02dSSam Parker; CHECK: br label %while.body 13757ac02dSSam Parker 14b2ac9681SDavid Green; CHECK: [[REM:%[^ ]+]] = phi i32 [ [[START]], %entry ], [ [[LOOP_DEC:%[^ ]+]], %while.body ] 15b0614509SSjoerd Meijer; CHECK: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[REM]], i32 1) 16757ac02dSSam Parker; CHECK: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0 17757ac02dSSam Parker; CHECK: br i1 [[CMP]], label %while.body, label %while.end 18a6fd919cSSam Parker 19a6fd919cSSam Parker; CHECK-LLC-LABEL:do_copy: 20a6fd919cSSam Parker; CHECK-LLC-NOT: mov lr, r0 21a6fd919cSSam Parker; CHECK-LLC: dls lr, r0 22a6fd919cSSam Parker; CHECK-LLC-NOT: mov lr, r0 23a6fd919cSSam Parker; CHECK-LLC: [[LOOP_HEADER:\.LBB[0-9_]+]]: 24a6fd919cSSam Parker; CHECK-LLC: le lr, [[LOOP_HEADER]] 25a6fd919cSSam Parker; CHECK-LLC-NOT: b [[LOOP_EXIT:\.LBB[0-9._]+]] 26a6fd919cSSam Parker; CHECK-LLC: @ %while.end 27d17f4f26SMatt Arsenaultdefine i32 @do_copy(i32 %n, ptr nocapture %p, ptr nocapture readonly %q) { 28757ac02dSSam Parkerentry: 29757ac02dSSam Parker br label %while.body 30757ac02dSSam Parker 31757ac02dSSam Parkerwhile.body: 32d17f4f26SMatt Arsenault %q.addr.05 = phi ptr [ %incdec.ptr, %while.body ], [ %q, %entry ] 33d17f4f26SMatt Arsenault %p.addr.04 = phi ptr [ %incdec.ptr1, %while.body ], [ %p, %entry ] 34757ac02dSSam Parker %x.addr.03 = phi i32 [ %dec, %while.body ], [ %n, %entry ] 35757ac02dSSam Parker %dec = add nsw i32 %x.addr.03, -1 36d17f4f26SMatt Arsenault %incdec.ptr = getelementptr inbounds i32, ptr %q.addr.05, i32 1 37d17f4f26SMatt Arsenault %0 = load i32, ptr %q.addr.05, align 4 38d17f4f26SMatt Arsenault %incdec.ptr1 = getelementptr inbounds i32, ptr %p.addr.04, i32 1 39d17f4f26SMatt Arsenault store i32 %0, ptr %p.addr.04, align 4 40757ac02dSSam Parker %tobool = icmp eq i32 %dec, 0 41757ac02dSSam Parker br i1 %tobool, label %while.end, label %while.body 42757ac02dSSam Parker 43757ac02dSSam Parkerwhile.end: 44757ac02dSSam Parker ret i32 0 45757ac02dSSam Parker} 46757ac02dSSam Parker 47757ac02dSSam Parker; CHECK-LABEL: do_inc1 4898722691SSam Parker; CHECK: entry: 49fad70c30SDavid Green; CHECK: [[TEST:%[^ ]+]] = call { i32, i1 } @llvm.test.start.loop.iterations.i32(i32 %n) 50fad70c30SDavid Green; CHECK: [[TEST1:%[^ ]+]] = extractvalue { i32, i1 } [[TEST]], 1 51fad70c30SDavid Green; CHECK: [[TEST0:%[^ ]+]] = extractvalue { i32, i1 } [[TEST]], 0 52fad70c30SDavid Green; CHECK: br i1 [[TEST1]], label %while.body.lr.ph, label %while.end 5398722691SSam Parker 54757ac02dSSam Parker; CHECK: while.body.lr.ph: 5598722691SSam Parker; CHECK: br label %while.body 56757ac02dSSam Parker 57fad70c30SDavid Green; CHECK: [[REM:%[^ ]+]] = phi i32 [ [[TEST0]], %while.body.lr.ph ], [ [[LOOP_DEC:%[^ ]+]], %while.body ] 58b0614509SSjoerd Meijer; CHECK: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[REM]], i32 1) 59757ac02dSSam Parker; CHECK: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0 60757ac02dSSam Parker; CHECK: br i1 [[CMP]], label %while.body, label %while.end.loopexit 61757ac02dSSam Parker 62a6fd919cSSam Parker; CHECK-LLC-LABEL:do_inc1: 6398722691SSam Parker; CHECK-LLC: wls lr, {{.*}}, [[LOOP_EXIT:.[LBB_0-3]+]] 64a6fd919cSSam Parker; CHECK-LLC-NOT: mov lr, 65a6fd919cSSam Parker; CHECK-LLC: [[LOOP_HEADER:\.LBB[0-9_]+]]: 66a6fd919cSSam Parker; CHECK-LLC: le lr, [[LOOP_HEADER]] 67a6fd919cSSam Parker; CHECK-LLC-NOT: b [[LOOP_EXIT:\.LBB[0-9_]+]] 6898722691SSam Parker; CHECK-LLC: [[LOOP_EXIT]]: 69a6fd919cSSam Parker 70757ac02dSSam Parkerdefine i32 @do_inc1(i32 %n) { 71757ac02dSSam Parkerentry: 72757ac02dSSam Parker %cmp7 = icmp eq i32 %n, 0 73757ac02dSSam Parker br i1 %cmp7, label %while.end, label %while.body.lr.ph 74757ac02dSSam Parker 75757ac02dSSam Parkerwhile.body.lr.ph: 76d17f4f26SMatt Arsenault %0 = load ptr, ptr @g, align 4 77757ac02dSSam Parker br label %while.body 78757ac02dSSam Parker 79757ac02dSSam Parkerwhile.body: 80757ac02dSSam Parker %i.09 = phi i32 [ 0, %while.body.lr.ph ], [ %inc1, %while.body ] 81757ac02dSSam Parker %res.08 = phi i32 [ 0, %while.body.lr.ph ], [ %add, %while.body ] 82d17f4f26SMatt Arsenault %arrayidx = getelementptr inbounds i32, ptr %0, i32 %i.09 83d17f4f26SMatt Arsenault %1 = load i32, ptr %arrayidx, align 4 84757ac02dSSam Parker %add = add nsw i32 %1, %res.08 85757ac02dSSam Parker %inc1 = add nuw i32 %i.09, 1 86757ac02dSSam Parker %exitcond = icmp eq i32 %inc1, %n 87757ac02dSSam Parker br i1 %exitcond, label %while.end.loopexit, label %while.body 88757ac02dSSam Parker 89757ac02dSSam Parkerwhile.end.loopexit: 90757ac02dSSam Parker br label %while.end 91757ac02dSSam Parker 92757ac02dSSam Parkerwhile.end: 93757ac02dSSam Parker %res.0.lcssa = phi i32 [ 0, %entry ], [ %add, %while.end.loopexit ] 94757ac02dSSam Parker ret i32 %res.0.lcssa 95757ac02dSSam Parker} 96757ac02dSSam Parker 97757ac02dSSam Parker; CHECK-LABEL: do_inc2 9898722691SSam Parker; CHECK: entry: 99757ac02dSSam Parker; CHECK: [[ROUND:%[^ ]+]] = add i32 %n, -1 100757ac02dSSam Parker; CHECK: [[HALVE:%[^ ]+]] = lshr i32 [[ROUND]], 1 1010cf9639aSSam Parker; CHECK: [[COUNT:%[^ ]+]] = add nuw i32 [[HALVE]], 1 102757ac02dSSam Parker 10398722691SSam Parker; CHECK: while.body.lr.ph: 104b2ac9681SDavid Green; CHECK: [[START:%[^ ]+]] = call i32 @llvm.start.loop.iterations.i32(i32 [[COUNT]]) 10598722691SSam Parker; CHECK: br label %while.body 10698722691SSam Parker; CHECK: while.body: 107b2ac9681SDavid Green; CHECK: [[REM:%[^ ]+]] = phi i32 [ [[START]], %while.body.lr.ph ], [ [[LOOP_DEC:%[^ ]+]], %while.body ] 108b0614509SSjoerd Meijer; CHECK: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[REM]], i32 1) 109757ac02dSSam Parker; CHECK: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0 110757ac02dSSam Parker; CHECK: br i1 [[CMP]], label %while.body, label %while.end.loopexit 111a6fd919cSSam Parker 112a6fd919cSSam Parker; CHECK-LLC: do_inc2: 113a6fd919cSSam Parker; CHECK-LLC-NOT: mov lr, 11448230355SDavid Green; CHECK-LLC: add.w lr, 11548230355SDavid Green; CHECK-LLC-NOT: dls lr, 116a6fd919cSSam Parker; CHECK-LLC-NOT: mov lr, 117a6fd919cSSam Parker; CHECK-LLC: [[LOOP_HEADER:\.LBB[0-9._]+]]: 118a6fd919cSSam Parker; CHECK-LLC: le lr, [[LOOP_HEADER]] 119a6fd919cSSam Parker 120757ac02dSSam Parkerdefine i32 @do_inc2(i32 %n) { 121757ac02dSSam Parkerentry: 122757ac02dSSam Parker %cmp7 = icmp sgt i32 %n, 0 123757ac02dSSam Parker br i1 %cmp7, label %while.body.lr.ph, label %while.end 124757ac02dSSam Parker 125757ac02dSSam Parkerwhile.body.lr.ph: 126d17f4f26SMatt Arsenault %0 = load ptr, ptr @g, align 4 127757ac02dSSam Parker br label %while.body 128757ac02dSSam Parker 129757ac02dSSam Parkerwhile.body: 130757ac02dSSam Parker %i.09 = phi i32 [ 0, %while.body.lr.ph ], [ %add1, %while.body ] 131757ac02dSSam Parker %res.08 = phi i32 [ 0, %while.body.lr.ph ], [ %add, %while.body ] 132d17f4f26SMatt Arsenault %arrayidx = getelementptr inbounds i32, ptr %0, i32 %i.09 133d17f4f26SMatt Arsenault %1 = load i32, ptr %arrayidx, align 4 134757ac02dSSam Parker %add = add nsw i32 %1, %res.08 135757ac02dSSam Parker %add1 = add nuw nsw i32 %i.09, 2 136757ac02dSSam Parker %cmp = icmp slt i32 %add1, %n 137757ac02dSSam Parker br i1 %cmp, label %while.body, label %while.end.loopexit 138757ac02dSSam Parker 139757ac02dSSam Parkerwhile.end.loopexit: 140757ac02dSSam Parker br label %while.end 141757ac02dSSam Parker 142757ac02dSSam Parkerwhile.end: 143757ac02dSSam Parker %res.0.lcssa = phi i32 [ 0, %entry ], [ %add, %while.end.loopexit ] 144757ac02dSSam Parker ret i32 %res.0.lcssa 145757ac02dSSam Parker} 146757ac02dSSam Parker 147757ac02dSSam Parker; CHECK-LABEL: do_dec2 148757ac02dSSam Parker 14998722691SSam Parker; CHECK: entry: 150757ac02dSSam Parker; CHECK: [[ROUND:%[^ ]+]] = add i32 %n, 1 151b46c085dSRoman Lebedev; CHECK: [[SMIN:%[^ ]+]] = call i32 @llvm.smin.i32(i32 %n, i32 2) 152757ac02dSSam Parker; CHECK: [[SUB:%[^ ]+]] = sub i32 [[ROUND]], [[SMIN]] 153757ac02dSSam Parker; CHECK: [[HALVE:%[^ ]+]] = lshr i32 [[SUB]], 1 1540cf9639aSSam Parker; CHECK: [[COUNT:%[^ ]+]] = add nuw i32 [[HALVE]], 1 15598722691SSam Parker 15698722691SSam Parker; CHECK: while.body.lr.ph: 157b2ac9681SDavid Green; CHECK: [[START:%[^ ]+]] = call i32 @llvm.start.loop.iterations.i32(i32 [[COUNT]]) 15898722691SSam Parker; CHECK: br label %while.body 159757ac02dSSam Parker 160b2ac9681SDavid Green; CHECK: [[REM:%[^ ]+]] = phi i32 [ [[START]], %while.body.lr.ph ], [ [[LOOP_DEC:%[^ ]+]], %while.body ] 161b0614509SSjoerd Meijer; CHECK: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[REM]], i32 1) 162757ac02dSSam Parker; CHECK: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0 163757ac02dSSam Parker; CHECK: br i1 [[CMP]], label %while.body, label %while.end.loopexit 164a6fd919cSSam Parker 165a6fd919cSSam Parker; CHECK-LLC: do_dec2 166a6fd919cSSam Parker; CHECK-LLC-NOT: mov lr, 16748230355SDavid Green; CHECK-LLC: add.w lr, 16848230355SDavid Green; CHECK-LLC-NOT: dls lr, 169a6fd919cSSam Parker; CHECK-LLC-NOT: mov lr, 170a6fd919cSSam Parker; CHECK-LLC: [[LOOP_HEADER:\.LBB[0-9_]+]]: 171a6fd919cSSam Parker; CHECK-LLC: le lr, [[LOOP_HEADER]] 172a6fd919cSSam Parker; CHECK-LLC-NOT: b . 173757ac02dSSam Parkerdefine i32 @do_dec2(i32 %n) { 174757ac02dSSam Parkerentry: 175757ac02dSSam Parker %cmp6 = icmp sgt i32 %n, 0 176757ac02dSSam Parker br i1 %cmp6, label %while.body.lr.ph, label %while.end 177757ac02dSSam Parker 178757ac02dSSam Parkerwhile.body.lr.ph: 179d17f4f26SMatt Arsenault %0 = load ptr, ptr @g, align 4 180757ac02dSSam Parker br label %while.body 181757ac02dSSam Parker 182757ac02dSSam Parkerwhile.body: 183757ac02dSSam Parker %i.08 = phi i32 [ %n, %while.body.lr.ph ], [ %sub, %while.body ] 184757ac02dSSam Parker %res.07 = phi i32 [ 0, %while.body.lr.ph ], [ %add, %while.body ] 185d17f4f26SMatt Arsenault %arrayidx = getelementptr inbounds i32, ptr %0, i32 %i.08 186d17f4f26SMatt Arsenault %1 = load i32, ptr %arrayidx, align 4 187757ac02dSSam Parker %add = add nsw i32 %1, %res.07 188757ac02dSSam Parker %sub = add nsw i32 %i.08, -2 189757ac02dSSam Parker %cmp = icmp sgt i32 %i.08, 2 190757ac02dSSam Parker br i1 %cmp, label %while.body, label %while.end.loopexit 191757ac02dSSam Parker 192757ac02dSSam Parkerwhile.end.loopexit: 193757ac02dSSam Parker br label %while.end 194757ac02dSSam Parker 195757ac02dSSam Parkerwhile.end: 196757ac02dSSam Parker %res.0.lcssa = phi i32 [ 0, %entry ], [ %add, %while.end.loopexit ] 197757ac02dSSam Parker ret i32 %res.0.lcssa 198757ac02dSSam Parker} 199