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