1; RUN: opt -mtriple=thumbv8.1m.main-none-none-eabi -passes=hardware-loops %s -S -o - | FileCheck %s 2 3@g = common local_unnamed_addr global ptr null, align 4 4 5; CHECK-LABEL: do_with_i32_urem 6; CHECK: entry: 7; CHECK: [[TEST:%[^ ]+]] = call { i32, i1 } @llvm.test.start.loop.iterations.i32(i32 %n) 8; CHECK: [[TEST1:%[^ ]+]] = extractvalue { i32, i1 } [[TEST]], 1 9; CHECK: [[TEST0:%[^ ]+]] = extractvalue { i32, i1 } [[TEST]], 0 10; CHECK: br i1 [[TEST1]], label %while.body.preheader, label %while.end 11 12; CHECK: while.body.preheader: 13; CHECK-NEXT: br label %while.body 14 15; CHECK: while.body: 16; CHECK: [[REM:%[^ ]+]] = phi i32 [ [[TEST0]], %while.body.preheader ], [ [[LOOP_DEC:%[^ ]+]], %while.body ] 17; CHECK: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[REM]], i32 1) 18; CHECK: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0 19; CHECK: br i1 [[CMP]], label %while.body, label %while.end.loopexit 20 21define i32 @do_with_i32_urem(i32 %n) { 22entry: 23 %cmp7 = icmp eq i32 %n, 0 24 br i1 %cmp7, label %while.end, label %while.body.preheader 25 26while.body.preheader: 27 br label %while.body 28 29while.body: 30 %i.09 = phi i32 [ %inc1, %while.body ], [ 0, %while.body.preheader ] 31 %res.08 = phi i32 [ %add, %while.body ], [ 0, %while.body.preheader ] 32 %rem = urem i32 %i.09, 5 33 %add = add i32 %rem, %res.08 34 %inc1 = add nuw i32 %i.09, 1 35 %exitcond = icmp eq i32 %inc1, %n 36 br i1 %exitcond, label %while.end.loopexit, label %while.body 37 38while.end.loopexit: 39 br label %while.end 40 41while.end: 42 %res.0.lcssa = phi i32 [ 0, %entry ], [ %add, %while.end.loopexit ] 43 ret i32 %res.0.lcssa 44} 45 46; CHECK-LABEL: do_with_i32_srem 47; CHECK: entry: 48; CHECK: [[TEST:%[^ ]+]] = call { i32, i1 } @llvm.test.start.loop.iterations.i32(i32 %n) 49; CHECK: [[TEST1:%[^ ]+]] = extractvalue { i32, i1 } [[TEST]], 1 50; CHECK: [[TEST0:%[^ ]+]] = extractvalue { i32, i1 } [[TEST]], 0 51; CHECK: br i1 [[TEST1]], label %while.body.preheader, label %while.end 52 53; CHECK: while.body.preheader: 54; CHECK-NEXT: br label %while.body 55 56; CHECK: while.body: 57; CHECK: [[REM:%[^ ]+]] = phi i32 [ [[TEST0]], %while.body.preheader ], [ [[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]], 0 60; CHECK: br i1 [[CMP]], label %while.body, label %while.end.loopexit 61 62define i32 @do_with_i32_srem(i32 %n) { 63entry: 64 %cmp7 = icmp eq i32 %n, 0 65 br i1 %cmp7, label %while.end, label %while.body.preheader 66 67while.body.preheader: 68 br label %while.body 69 70while.body: 71 %i.09 = phi i32 [ %inc1, %while.body ], [ 0, %while.body.preheader ] 72 %res.08 = phi i32 [ %add, %while.body ], [ 0, %while.body.preheader ] 73 %rem = srem i32 %i.09, 5 74 %add = sub i32 %rem, %res.08 75 %inc1 = add nuw i32 %i.09, 1 76 %exitcond = icmp eq i32 %inc1, %n 77 br i1 %exitcond, label %while.end.loopexit, label %while.body 78 79while.end.loopexit: 80 br label %while.end 81 82while.end: 83 %res.0.lcssa = phi i32 [ 0, %entry ], [ %add, %while.end.loopexit ] 84 ret i32 %res.0.lcssa 85} 86 87; CHECK-LABEL: do_with_i32_udiv 88; CHECK: entry: 89; CHECK: [[TEST:%[^ ]+]] = call { i32, i1 } @llvm.test.start.loop.iterations.i32(i32 %n) 90; CHECK: [[TEST1:%[^ ]+]] = extractvalue { i32, i1 } [[TEST]], 1 91; CHECK: [[TEST0:%[^ ]+]] = extractvalue { i32, i1 } [[TEST]], 0 92; CHECK: br i1 [[TEST1]], label %while.body.preheader, label %while.end 93 94; CHECK: while.body.preheader: 95; CHECK-NEXT: br label %while.body 96 97; CHECK: while.body: 98; CHECK: [[REM:%[^ ]+]] = phi i32 [ [[TEST0]], %while.body.preheader ], [ [[LOOP_DEC:%[^ ]+]], %while.body ] 99; CHECK: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[REM]], i32 1) 100; CHECK: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0 101; CHECK: br i1 [[CMP]], label %while.body, label %while.end.loopexit 102 103define i32 @do_with_i32_udiv(i32 %n) { 104entry: 105 %cmp7 = icmp eq i32 %n, 0 106 br i1 %cmp7, label %while.end, label %while.body.preheader 107 108while.body.preheader: 109 br label %while.body 110 111while.body: 112 %i.09 = phi i32 [ %inc1, %while.body ], [ 0, %while.body.preheader ] 113 %res.08 = phi i32 [ %add, %while.body ], [ 0, %while.body.preheader ] 114 %rem = udiv i32 %i.09, 5 115 %add = add i32 %rem, %res.08 116 %inc1 = add nuw i32 %i.09, 1 117 %exitcond = icmp eq i32 %inc1, %n 118 br i1 %exitcond, label %while.end.loopexit, label %while.body 119 120while.end.loopexit: 121 br label %while.end 122 123while.end: 124 %res.0.lcssa = phi i32 [ 0, %entry ], [ %add, %while.end.loopexit ] 125 ret i32 %res.0.lcssa 126} 127 128; CHECK-LABEL: do_with_i32_sdiv 129; CHECK: entry: 130; CHECK: [[TEST:%[^ ]+]] = call { i32, i1 } @llvm.test.start.loop.iterations.i32(i32 %n) 131; CHECK: [[TEST1:%[^ ]+]] = extractvalue { i32, i1 } [[TEST]], 1 132; CHECK: [[TEST0:%[^ ]+]] = extractvalue { i32, i1 } [[TEST]], 0 133; CHECK: br i1 [[TEST1]], label %while.body.preheader, label %while.end 134 135; CHECK: while.body.preheader: 136; CHECK-NEXT: br label %while.body 137 138; CHECK: while.body: 139; CHECK: [[REM:%[^ ]+]] = phi i32 [ [[TEST0]], %while.body.preheader ], [ [[LOOP_DEC:%[^ ]+]], %while.body ] 140; CHECK: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[REM]], i32 1) 141; CHECK: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0 142; CHECK: br i1 [[CMP]], label %while.body, label %while.end.loopexit 143 144define i32 @do_with_i32_sdiv(i32 %n) { 145entry: 146 %cmp7 = icmp eq i32 %n, 0 147 br i1 %cmp7, label %while.end, label %while.body.preheader 148 149while.body.preheader: 150 br label %while.body 151 152while.body: 153 %i.09 = phi i32 [ %inc1, %while.body ], [ 0, %while.body.preheader ] 154 %res.08 = phi i32 [ %add, %while.body ], [ 0, %while.body.preheader ] 155 %rem = sdiv i32 %i.09, 5 156 %add = sub i32 %rem, %res.08 157 %inc1 = add nuw i32 %i.09, 1 158 %exitcond = icmp eq i32 %inc1, %n 159 br i1 %exitcond, label %while.end.loopexit, label %while.body 160 161while.end.loopexit: 162 br label %while.end 163 164while.end: 165 %res.0.lcssa = phi i32 [ 0, %entry ], [ %add, %while.end.loopexit ] 166 ret i32 %res.0.lcssa 167} 168 169; CHECK-LABEL: do_with_i64_urem 170; CHECK-NOT: llvm.{{.*}}.loop.iterations 171; CHECK-NOT: llvm.loop.decrement 172define i64 @do_with_i64_urem(i32 %n) { 173entry: 174 %cmp7 = icmp eq i32 %n, 0 175 br i1 %cmp7, label %while.end, label %while.body.preheader 176 177while.body.preheader: 178 br label %while.body 179 180while.body: 181 %i.09 = phi i32 [ %inc1, %while.body ], [ 0, %while.body.preheader ] 182 %res.08 = phi i64 [ %add, %while.body ], [ 0, %while.body.preheader ] 183 %conv = zext i32 %i.09 to i64 184 %rem = urem i64 %conv, 5 185 %add = add i64 %rem, %res.08 186 %inc1 = add nuw i32 %i.09, 1 187 %exitcond = icmp eq i32 %inc1, %n 188 br i1 %exitcond, label %while.end.loopexit, label %while.body 189 190while.end.loopexit: 191 br label %while.end 192 193while.end: 194 %res.0.lcssa = phi i64 [ 0, %entry ], [ %add, %while.end.loopexit ] 195 ret i64 %res.0.lcssa 196} 197 198; CHECK-LABEL: do_with_i64_srem 199; CHECK-NOT: llvm.{{.*}}.loop.iterations 200; CHECK-NOT: llvm.loop.decrement 201define i64 @do_with_i64_srem(i32 %n) { 202entry: 203 %cmp7 = icmp eq i32 %n, 0 204 br i1 %cmp7, label %while.end, label %while.body.preheader 205 206while.body.preheader: 207 br label %while.body 208 209while.body: 210 %i.09 = phi i32 [ %inc1, %while.body ], [ 0, %while.body.preheader ] 211 %res.08 = phi i64 [ %add, %while.body ], [ 0, %while.body.preheader ] 212 %conv = zext i32 %i.09 to i64 213 %rem = srem i64 %conv, 5 214 %add = sub i64 %rem, %res.08 215 %inc1 = add nuw i32 %i.09, 1 216 %exitcond = icmp eq i32 %inc1, %n 217 br i1 %exitcond, label %while.end.loopexit, label %while.body 218 219while.end.loopexit: 220 br label %while.end 221 222while.end: 223 %res.0.lcssa = phi i64 [ 0, %entry ], [ %add, %while.end.loopexit ] 224 ret i64 %res.0.lcssa 225} 226 227; CHECK-LABEL: do_with_i64_udiv 228; CHECK-NOT: llvm.{{.*}}.loop.iterations 229; CHECK-NOT: llvm.loop.decrement 230define i64 @do_with_i64_udiv(i32 %n) { 231entry: 232 %cmp7 = icmp eq i32 %n, 0 233 br i1 %cmp7, label %while.end, label %while.body.preheader 234 235while.body.preheader: 236 br label %while.body 237 238while.body: 239 %i.09 = phi i32 [ %inc1, %while.body ], [ 0, %while.body.preheader ] 240 %res.08 = phi i64 [ %add, %while.body ], [ 0, %while.body.preheader ] 241 %conv = zext i32 %i.09 to i64 242 %rem = udiv i64 %conv, 5 243 %add = add i64 %rem, %res.08 244 %inc1 = add nuw i32 %i.09, 1 245 %exitcond = icmp eq i32 %inc1, %n 246 br i1 %exitcond, label %while.end.loopexit, label %while.body 247 248while.end.loopexit: 249 br label %while.end 250 251while.end: 252 %res.0.lcssa = phi i64 [ 0, %entry ], [ %add, %while.end.loopexit ] 253 ret i64 %res.0.lcssa 254} 255 256; CHECK-LABEL: do_with_i64_sdiv 257; CHECK-NOT: call void @llvm.{{.*}}.loop.iterations 258; CHECK-NOT: call i32 @llvm.loop.decrement 259define i64 @do_with_i64_sdiv(i32 %n) { 260entry: 261 %cmp7 = icmp eq i32 %n, 0 262 br i1 %cmp7, label %while.end, label %while.body.preheader 263 264while.body.preheader: 265 br label %while.body 266 267while.body: 268 %i.09 = phi i32 [ %inc1, %while.body ], [ 0, %while.body.preheader ] 269 %res.08 = phi i64 [ %add, %while.body ], [ 0, %while.body.preheader ] 270 %conv = zext i32 %i.09 to i64 271 %rem = sdiv i64 %conv, 5 272 %add = sub i64 %rem, %res.08 273 %inc1 = add nuw i32 %i.09, 1 274 %exitcond = icmp eq i32 %inc1, %n 275 br i1 %exitcond, label %while.end.loopexit, label %while.body 276 277while.end.loopexit: 278 br label %while.end 279 280while.end: 281 %res.0.lcssa = phi i64 [ 0, %entry ], [ %add, %while.end.loopexit ] 282 ret i64 %res.0.lcssa 283} 284