1 ; RUN: opt -basicaa -loop-unroll-and-jam -allow-unroll-and-jam -unroll-and-jam-count=4 < %s -S | FileCheck %s 2 3 target 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 10 define void @fore_aft_less(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 11 entry: 12 %cmp = icmp sgt i32 %N, 0 13 br i1 %cmp, label %for.outer, label %cleanup 14 15 for.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 21 for.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 32 for.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 40 cleanup: 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 50 define void @fore_aft_eq(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 51 entry: 52 %cmp = icmp sgt i32 %N, 0 53 br i1 %cmp, label %for.outer, label %cleanup 54 55 for.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 61 for.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 72 for.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 80 cleanup: 81 ret void 82 } 83 84 85 ; CHECK-LABEL: fore_aft_more 86 ; CHECK: %j = phi 87 ; CHECK-NOT: %j.1 = phi 88 define void @fore_aft_more(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 89 entry: 90 %cmp = icmp sgt i32 %N, 0 91 br i1 %cmp, label %for.outer, label %cleanup 92 93 for.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 99 for.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 110 for.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 118 cleanup: 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 128 define void @fore_sub_less(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 129 entry: 130 %cmp = icmp sgt i32 %N, 0 131 br i1 %cmp, label %for.outer, label %cleanup 132 133 for.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 139 for.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 153 for.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 158 cleanup: 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 168 define void @fore_sub_eq(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 169 entry: 170 %cmp = icmp sgt i32 %N, 0 171 br i1 %cmp, label %for.outer, label %cleanup 172 173 for.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 179 for.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 193 for.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 198 cleanup: 199 ret void 200 } 201 202 203 ; CHECK-LABEL: fore_sub_more 204 ; CHECK: %j = phi 205 ; CHECK-NOT: %j.1 = phi 206 define void @fore_sub_more(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 207 entry: 208 %cmp = icmp sgt i32 %N, 0 209 br i1 %cmp, label %for.outer, label %cleanup 210 211 for.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 217 for.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 231 for.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 236 cleanup: 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 246 define void @sub_aft_less(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 247 entry: 248 %cmp = icmp sgt i32 %N, 0 249 br i1 %cmp, label %for.outer, label %cleanup 250 251 for.outer: 252 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ] 253 br label %for.inner 254 255 for.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 268 for.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 276 cleanup: 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 286 define void @sub_aft_eq(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 287 entry: 288 %cmp = icmp sgt i32 %N, 0 289 br i1 %cmp, label %for.outer, label %cleanup 290 291 for.outer: 292 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ] 293 br label %for.inner 294 295 for.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 308 for.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 316 cleanup: 317 ret void 318 } 319 320 321 ; CHECK-LABEL: sub_aft_more 322 ; CHECK: %j = phi 323 ; CHECK-NOT: %j.1 = phi 324 define void @sub_aft_more(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 325 entry: 326 %cmp = icmp sgt i32 %N, 0 327 br i1 %cmp, label %for.outer, label %cleanup 328 329 for.outer: 330 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ] 331 br label %for.inner 332 333 for.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 346 for.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 354 cleanup: 355 ret void 356 } 357 358 359 ; CHECK-LABEL: sub_sub_less 360 ; CHECK: %j = phi 361 ; CHECK-NOT: %j.1 = phi 362 define void @sub_sub_less(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 363 entry: 364 %cmp = icmp sgt i32 %N, 0 365 br i1 %cmp, label %for.outer, label %cleanup 366 367 for.outer: 368 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ] 369 br label %for.inner 370 371 for.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 387 for.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 392 cleanup: 393 ret void 394 } 395 396 397 ; CHECK-LABEL: sub_sub_eq 398 ; CHECK: %j = phi 399 ; CHECK: %j.1 = phi 400 define void @sub_sub_eq(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 401 entry: 402 %cmp = icmp sgt i32 %N, 0 403 br i1 %cmp, label %for.outer, label %cleanup 404 405 for.outer: 406 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ] 407 br label %for.inner 408 409 for.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 425 for.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 430 cleanup: 431 ret void 432 } 433 434 435 ; CHECK-LABEL: sub_sub_more 436 ; CHECK: %j = phi 437 ; CHECK-NOT: %j.1 = phi 438 define void @sub_sub_more(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) { 439 entry: 440 %cmp = icmp sgt i32 %N, 0 441 br i1 %cmp, label %for.outer, label %cleanup 442 443 for.outer: 444 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ] 445 br label %for.inner 446 447 for.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 463 for.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 468 cleanup: 469 ret void 470 } 471