1; RUN: opt -basic-aa -loop-unroll-and-jam -allow-unroll-and-jam -unroll-and-jam-count=4 < %s -S | FileCheck %s 2; RUN: opt -aa-pipeline=basic-aa -passes='loop-unroll-and-jam' -allow-unroll-and-jam -unroll-and-jam-count=4 < %s -S | FileCheck %s 3 4target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" 5 6; CHECK-LABEL: fore_aft_less 7; CHECK: %j = phi 8; CHECK: %j.1 = phi 9; CHECK: %j.2 = phi 10; CHECK: %j.3 = phi 11define void @fore_aft_less(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 12entry: 13 %cmp = icmp sgt i32 %N, 0 14 br i1 %cmp, label %for.outer, label %cleanup 15 16for.outer: 17 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ] 18 %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i 19 store i32 1, i32* %arrayidx, align 4 20 br label %for.inner 21 22for.inner: 23 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ] 24 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ] 25 %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j 26 %0 = load i32, i32* %arrayidx5, align 4 27 %mul = mul nsw i32 %0, %i 28 %add = add nsw i32 %mul, %sum 29 %add6 = add nuw nsw i32 %j, 1 30 %exitcond = icmp eq i32 %add6, %N 31 br i1 %exitcond, label %for.latch, label %for.inner 32 33for.latch: 34 %add7 = add nuw nsw i32 %i, 1 35 %add72 = add nuw nsw i32 %i, -1 36 %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %add72 37 store i32 %add, i32* %arrayidx8, align 4 38 %exitcond29 = icmp eq i32 %add7, %N 39 br i1 %exitcond29, label %cleanup, label %for.outer 40 41cleanup: 42 ret void 43} 44 45 46; CHECK-LABEL: fore_aft_eq 47; CHECK: %j = phi 48; CHECK: %j.1 = phi 49; CHECK: %j.2 = phi 50; CHECK: %j.3 = phi 51define void @fore_aft_eq(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 52entry: 53 %cmp = icmp sgt i32 %N, 0 54 br i1 %cmp, label %for.outer, label %cleanup 55 56for.outer: 57 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ] 58 %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i 59 store i32 1, i32* %arrayidx, align 4 60 br label %for.inner 61 62for.inner: 63 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ] 64 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ] 65 %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j 66 %0 = load i32, i32* %arrayidx5, align 4 67 %mul = mul nsw i32 %0, %i 68 %add = add nsw i32 %mul, %sum 69 %add6 = add nuw nsw i32 %j, 1 70 %exitcond = icmp eq i32 %add6, %N 71 br i1 %exitcond, label %for.latch, label %for.inner 72 73for.latch: 74 %add7 = add nuw nsw i32 %i, 1 75 %add72 = add nuw nsw i32 %i, 0 76 %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %i 77 store i32 %add, i32* %arrayidx8, align 4 78 %exitcond29 = icmp eq i32 %add7, %N 79 br i1 %exitcond29, label %cleanup, label %for.outer 80 81cleanup: 82 ret void 83} 84 85 86; CHECK-LABEL: fore_aft_more 87; CHECK: %j = phi 88; CHECK-NOT: %j.1 = phi 89define void @fore_aft_more(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 90entry: 91 %cmp = icmp sgt i32 %N, 0 92 br i1 %cmp, label %for.outer, label %cleanup 93 94for.outer: 95 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ] 96 %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i 97 store i32 1, i32* %arrayidx, align 4 98 br label %for.inner 99 100for.inner: 101 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ] 102 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ] 103 %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j 104 %0 = load i32, i32* %arrayidx5, align 4 105 %mul = mul nsw i32 %0, %i 106 %add = add nsw i32 %mul, %sum 107 %add6 = add nuw nsw i32 %j, 1 108 %exitcond = icmp eq i32 %add6, %N 109 br i1 %exitcond, label %for.latch, label %for.inner 110 111for.latch: 112 %add7 = add nuw nsw i32 %i, 1 113 %add72 = add nuw nsw i32 %i, 1 114 %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %add72 115 store i32 %add, i32* %arrayidx8, align 4 116 %exitcond29 = icmp eq i32 %add7, %N 117 br i1 %exitcond29, label %cleanup, label %for.outer 118 119cleanup: 120 ret void 121} 122 123 124; CHECK-LABEL: fore_sub_less 125; CHECK: %j = phi 126; CHECK: %j.1 = phi 127; CHECK: %j.2 = phi 128; CHECK: %j.3 = phi 129define void @fore_sub_less(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 130entry: 131 %cmp = icmp sgt i32 %N, 0 132 br i1 %cmp, label %for.outer, label %cleanup 133 134for.outer: 135 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ] 136 %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i 137 store i32 1, i32* %arrayidx, align 4 138 br label %for.inner 139 140for.inner: 141 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ] 142 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ] 143 %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j 144 %0 = load i32, i32* %arrayidx5, align 4 145 %mul = mul nsw i32 %0, %i 146 %add = add nsw i32 %mul, %sum 147 %add72 = add nuw nsw i32 %i, -1 148 %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %add72 149 store i32 %add, i32* %arrayidx8, align 4 150 %add6 = add nuw nsw i32 %j, 1 151 %exitcond = icmp eq i32 %add6, %N 152 br i1 %exitcond, label %for.latch, label %for.inner 153 154for.latch: 155 %add7 = add nuw nsw i32 %i, 1 156 %exitcond29 = icmp eq i32 %add7, %N 157 br i1 %exitcond29, label %cleanup, label %for.outer 158 159cleanup: 160 ret void 161} 162 163 164; CHECK-LABEL: fore_sub_eq 165; CHECK: %j = phi 166; CHECK: %j.1 = phi 167; CHECK: %j.2 = phi 168; CHECK: %j.3 = phi 169define void @fore_sub_eq(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 170entry: 171 %cmp = icmp sgt i32 %N, 0 172 br i1 %cmp, label %for.outer, label %cleanup 173 174for.outer: 175 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ] 176 %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i 177 store i32 1, i32* %arrayidx, align 4 178 br label %for.inner 179 180for.inner: 181 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ] 182 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ] 183 %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j 184 %0 = load i32, i32* %arrayidx5, align 4 185 %mul = mul nsw i32 %0, %i 186 %add = add nsw i32 %mul, %sum 187 %add72 = add nuw nsw i32 %i, 0 188 %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %add72 189 store i32 %add, i32* %arrayidx8, align 4 190 %add6 = add nuw nsw i32 %j, 1 191 %exitcond = icmp eq i32 %add6, %N 192 br i1 %exitcond, label %for.latch, label %for.inner 193 194for.latch: 195 %add7 = add nuw nsw i32 %i, 1 196 %exitcond29 = icmp eq i32 %add7, %N 197 br i1 %exitcond29, label %cleanup, label %for.outer 198 199cleanup: 200 ret void 201} 202 203 204; CHECK-LABEL: fore_sub_more 205; CHECK: %j = phi 206; CHECK-NOT: %j.1 = phi 207define void @fore_sub_more(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 208entry: 209 %cmp = icmp sgt i32 %N, 0 210 br i1 %cmp, label %for.outer, label %cleanup 211 212for.outer: 213 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ] 214 %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i 215 store i32 1, i32* %arrayidx, align 4 216 br label %for.inner 217 218for.inner: 219 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ] 220 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ] 221 %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j 222 %0 = load i32, i32* %arrayidx5, align 4 223 %mul = mul nsw i32 %0, %i 224 %add = add nsw i32 %mul, %sum 225 %add72 = add nuw nsw i32 %i, 1 226 %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %add72 227 store i32 %add, i32* %arrayidx8, align 4 228 %add6 = add nuw nsw i32 %j, 1 229 %exitcond = icmp eq i32 %add6, %N 230 br i1 %exitcond, label %for.latch, label %for.inner 231 232for.latch: 233 %add7 = add nuw nsw i32 %i, 1 234 %exitcond29 = icmp eq i32 %add7, %N 235 br i1 %exitcond29, label %cleanup, label %for.outer 236 237cleanup: 238 ret void 239} 240 241 242; CHECK-LABEL: sub_aft_less 243; CHECK: %j = phi 244; CHECK: %j.1 = phi 245; CHECK: %j.2 = phi 246; CHECK: %j.3 = phi 247define void @sub_aft_less(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 248entry: 249 %cmp = icmp sgt i32 %N, 0 250 br i1 %cmp, label %for.outer, label %cleanup 251 252for.outer: 253 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ] 254 br label %for.inner 255 256for.inner: 257 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ] 258 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ] 259 %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j 260 %0 = load i32, i32* %arrayidx5, align 4 261 %mul = mul nsw i32 %0, %i 262 %add = add nsw i32 %mul, %sum 263 %add6 = add nuw nsw i32 %j, 1 264 %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i 265 store i32 1, i32* %arrayidx, align 4 266 %exitcond = icmp eq i32 %add6, %N 267 br i1 %exitcond, label %for.latch, label %for.inner 268 269for.latch: 270 %add7 = add nuw nsw i32 %i, 1 271 %add72 = add nuw nsw i32 %i, -1 272 %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %add72 273 store i32 %add, i32* %arrayidx8, align 4 274 %exitcond29 = icmp eq i32 %add7, %N 275 br i1 %exitcond29, label %cleanup, label %for.outer 276 277cleanup: 278 ret void 279} 280 281 282; CHECK-LABEL: sub_aft_eq 283; CHECK: %j = phi 284; CHECK: %j.1 = phi 285; CHECK: %j.2 = phi 286; CHECK: %j.3 = phi 287define void @sub_aft_eq(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 288entry: 289 %cmp = icmp sgt i32 %N, 0 290 br i1 %cmp, label %for.outer, label %cleanup 291 292for.outer: 293 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ] 294 br label %for.inner 295 296for.inner: 297 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ] 298 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ] 299 %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j 300 %0 = load i32, i32* %arrayidx5, align 4 301 %mul = mul nsw i32 %0, %i 302 %add = add nsw i32 %mul, %sum 303 %add6 = add nuw nsw i32 %j, 1 304 %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i 305 store i32 1, i32* %arrayidx, align 4 306 %exitcond = icmp eq i32 %add6, %N 307 br i1 %exitcond, label %for.latch, label %for.inner 308 309for.latch: 310 %add7 = add nuw nsw i32 %i, 1 311 %add72 = add nuw nsw i32 %i, 0 312 %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %i 313 store i32 %add, i32* %arrayidx8, align 4 314 %exitcond29 = icmp eq i32 %add7, %N 315 br i1 %exitcond29, label %cleanup, label %for.outer 316 317cleanup: 318 ret void 319} 320 321 322; CHECK-LABEL: sub_aft_more 323; CHECK: %j = phi 324; CHECK-NOT: %j.1 = phi 325define void @sub_aft_more(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 326entry: 327 %cmp = icmp sgt i32 %N, 0 328 br i1 %cmp, label %for.outer, label %cleanup 329 330for.outer: 331 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ] 332 br label %for.inner 333 334for.inner: 335 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ] 336 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ] 337 %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j 338 %0 = load i32, i32* %arrayidx5, align 4 339 %mul = mul nsw i32 %0, %i 340 %add = add nsw i32 %mul, %sum 341 %add6 = add nuw nsw i32 %j, 1 342 %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i 343 store i32 1, i32* %arrayidx, align 4 344 %exitcond = icmp eq i32 %add6, %N 345 br i1 %exitcond, label %for.latch, label %for.inner 346 347for.latch: 348 %add7 = add nuw nsw i32 %i, 1 349 %add72 = add nuw nsw i32 %i, 1 350 %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %add72 351 store i32 %add, i32* %arrayidx8, align 4 352 %exitcond29 = icmp eq i32 %add7, %N 353 br i1 %exitcond29, label %cleanup, label %for.outer 354 355cleanup: 356 ret void 357} 358 359 360; CHECK-LABEL: sub_sub_less 361; CHECK: %j = phi 362; CHECK-NOT: %j.1 = phi 363define void @sub_sub_less(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 364entry: 365 %cmp = icmp sgt i32 %N, 0 366 br i1 %cmp, label %for.outer, label %cleanup 367 368for.outer: 369 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ] 370 br label %for.inner 371 372for.inner: 373 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ] 374 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ] 375 %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j 376 %0 = load i32, i32* %arrayidx5, align 4 377 %mul = mul nsw i32 %0, %i 378 %add = add nsw i32 %mul, %sum 379 %add6 = add nuw nsw i32 %j, 1 380 %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i 381 store i32 1, i32* %arrayidx, align 4 382 %add72 = add nuw nsw i32 %i, -1 383 %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %add72 384 store i32 %add, i32* %arrayidx8, align 4 385 %exitcond = icmp eq i32 %add6, %N 386 br i1 %exitcond, label %for.latch, label %for.inner 387 388for.latch: 389 %add7 = add nuw nsw i32 %i, 1 390 %exitcond29 = icmp eq i32 %add7, %N 391 br i1 %exitcond29, label %cleanup, label %for.outer 392 393cleanup: 394 ret void 395} 396 397 398; CHECK-LABEL: sub_sub_eq 399; CHECK: %j = phi 400; CHECK: %j.1 = phi 401; CHECK: %j.2 = phi 402; CHECK: %j.3 = phi 403define void @sub_sub_eq(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 404entry: 405 %cmp = icmp sgt i32 %N, 0 406 br i1 %cmp, label %for.outer, label %cleanup 407 408for.outer: 409 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ] 410 br label %for.inner 411 412for.inner: 413 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ] 414 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ] 415 %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j 416 %0 = load i32, i32* %arrayidx5, align 4 417 %mul = mul nsw i32 %0, %i 418 %add = add nsw i32 %mul, %sum 419 %add6 = add nuw nsw i32 %j, 1 420 %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i 421 store i32 1, i32* %arrayidx, align 4 422 %add72 = add nuw nsw i32 %i, 0 423 %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %add72 424 store i32 %add, i32* %arrayidx8, align 4 425 %exitcond = icmp eq i32 %add6, %N 426 br i1 %exitcond, label %for.latch, label %for.inner 427 428for.latch: 429 %add7 = add nuw nsw i32 %i, 1 430 %exitcond29 = icmp eq i32 %add7, %N 431 br i1 %exitcond29, label %cleanup, label %for.outer 432 433cleanup: 434 ret void 435} 436 437 438; CHECK-LABEL: sub_sub_more 439; CHECK: %j = phi 440; CHECK-NOT: %j.1 = phi 441define void @sub_sub_more(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 442entry: 443 %cmp = icmp sgt i32 %N, 0 444 br i1 %cmp, label %for.outer, label %cleanup 445 446for.outer: 447 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ] 448 br label %for.inner 449 450for.inner: 451 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ] 452 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ] 453 %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j 454 %0 = load i32, i32* %arrayidx5, align 4 455 %mul = mul nsw i32 %0, %i 456 %add = add nsw i32 %mul, %sum 457 %add6 = add nuw nsw i32 %j, 1 458 %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i 459 store i32 1, i32* %arrayidx, align 4 460 %add72 = add nuw nsw i32 %i, 1 461 %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %add72 462 store i32 %add, i32* %arrayidx8, align 4 463 %exitcond = icmp eq i32 %add6, %N 464 br i1 %exitcond, label %for.latch, label %for.inner 465 466for.latch: 467 %add7 = add nuw nsw i32 %i, 1 468 %exitcond29 = icmp eq i32 %add7, %N 469 br i1 %exitcond29, label %cleanup, label %for.outer 470 471cleanup: 472 ret void 473} 474