1 ; RUN: opt < %s -loop-reroll -S | FileCheck %s 2 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 3 target triple = "x86_64-unknown-linux-gnu" 4 5 ; int foo(int a); 6 ; void bar(int *x) { 7 ; for (int i = 0; i < 500; i += 3) { 8 ; foo(i); 9 ; foo(i+1); 10 ; foo(i+2); 11 ; } 12 ; } 13 14 ; Function Attrs: nounwind uwtable 15 define void @bar(i32* nocapture readnone %x) #0 { 16 entry: 17 br label %for.body 18 19 for.body: ; preds = %for.body, %entry 20 %i.08 = phi i32 [ 0, %entry ], [ %add3, %for.body ] 21 %call = tail call i32 @foo(i32 %i.08) #1 22 %add = add nsw i32 %i.08, 1 23 %call1 = tail call i32 @foo(i32 %add) #1 24 %add2 = add nsw i32 %i.08, 2 25 %call3 = tail call i32 @foo(i32 %add2) #1 26 %add3 = add nsw i32 %i.08, 3 27 %exitcond = icmp sge i32 %add3, 500 28 br i1 %exitcond, label %for.end, label %for.body 29 30 ; CHECK-LABEL: @bar 31 32 ; CHECK: for.body: 33 ; CHECK: %indvar = phi i32 [ %indvar.next, %for.body ], [ 0, %entry ] 34 ; CHECK: %call = tail call i32 @foo(i32 %indvar) #1 35 ; CHECK: %indvar.next = add i32 %indvar, 1 36 ; CHECK: %exitcond1 = icmp eq i32 %indvar, 500 37 ; CHECK: br i1 %exitcond1, label %for.end, label %for.body 38 39 ; CHECK: ret 40 41 for.end: ; preds = %for.body 42 ret void 43 } 44 45 declare i32 @foo(i32) 46 47 ; void hi1(int *x) { 48 ; for (int i = 0; i < 1500; i += 3) { 49 ; x[i] = foo(0); 50 ; x[i+1] = foo(0); 51 ; x[i+2] = foo(0); 52 ; } 53 ; } 54 55 ; Function Attrs: nounwind uwtable 56 define void @hi1(i32* nocapture %x) #0 { 57 entry: 58 br label %for.body 59 60 for.body: ; preds = %entry, %for.body 61 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 62 %call = tail call i32 @foo(i32 0) #1 63 %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv 64 store i32 %call, i32* %arrayidx, align 4 65 %call1 = tail call i32 @foo(i32 0) #1 66 %0 = add nsw i64 %indvars.iv, 1 67 %arrayidx3 = getelementptr inbounds i32, i32* %x, i64 %0 68 store i32 %call1, i32* %arrayidx3, align 4 69 %call4 = tail call i32 @foo(i32 0) #1 70 %1 = add nsw i64 %indvars.iv, 2 71 %arrayidx7 = getelementptr inbounds i32, i32* %x, i64 %1 72 store i32 %call4, i32* %arrayidx7, align 4 73 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 3 74 %2 = trunc i64 %indvars.iv.next to i32 75 %cmp = icmp slt i32 %2, 1500 76 br i1 %cmp, label %for.body, label %for.end 77 78 ; CHECK-LABEL: @hi1 79 80 ; CHECK: for.body: 81 ; CHECK: %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ] 82 ; CHECK: %call = tail call i32 @foo(i32 0) #1 83 ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvar 84 ; CHECK: store i32 %call, i32* %arrayidx, align 4 85 ; CHECK: %indvar.next = add i64 %indvar, 1 86 ; CHECK: %exitcond = icmp eq i64 %indvar, 1499 87 ; CHECK: br i1 %exitcond, label %for.end, label %for.body 88 89 ; CHECK: ret 90 91 for.end: ; preds = %for.body 92 ret void 93 } 94 95 ; void hi2(int *x) { 96 ; for (int i = 0; i < 500; ++i) { 97 ; x[3*i] = foo(0); 98 ; x[3*i+1] = foo(0); 99 ; x[3*i+2] = foo(0); 100 ; } 101 ; } 102 103 ; Function Attrs: nounwind uwtable 104 define void @hi2(i32* nocapture %x) #0 { 105 entry: 106 br label %for.body 107 108 for.body: ; preds = %for.body, %entry 109 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 110 %call = tail call i32 @foo(i32 0) #1 111 %0 = mul nsw i64 %indvars.iv, 3 112 %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0 113 store i32 %call, i32* %arrayidx, align 4 114 %call1 = tail call i32 @foo(i32 0) #1 115 %1 = add nsw i64 %0, 1 116 %arrayidx4 = getelementptr inbounds i32, i32* %x, i64 %1 117 store i32 %call1, i32* %arrayidx4, align 4 118 %call5 = tail call i32 @foo(i32 0) #1 119 %2 = add nsw i64 %0, 2 120 %arrayidx9 = getelementptr inbounds i32, i32* %x, i64 %2 121 store i32 %call5, i32* %arrayidx9, align 4 122 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 123 %exitcond = icmp eq i64 %indvars.iv.next, 500 124 br i1 %exitcond, label %for.end, label %for.body 125 126 ; CHECK-LABEL: @hi2 127 128 ; CHECK: for.body: 129 ; CHECK: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 130 ; CHECK: %call = tail call i32 @foo(i32 0) #1 131 ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv 132 ; CHECK: store i32 %call, i32* %arrayidx, align 4 133 ; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 134 ; CHECK: %exitcond1 = icmp eq i64 %indvars.iv, 1499 135 ; CHECK: br i1 %exitcond1, label %for.end, label %for.body 136 137 ; CHECK: ret 138 139 for.end: ; preds = %for.body 140 ret void 141 } 142 143 ; void goo(float alpha, float *a, float *b) { 144 ; for (int i = 0; i < 3200; i += 5) { 145 ; a[i] += alpha * b[i]; 146 ; a[i + 1] += alpha * b[i + 1]; 147 ; a[i + 2] += alpha * b[i + 2]; 148 ; a[i + 3] += alpha * b[i + 3]; 149 ; a[i + 4] += alpha * b[i + 4]; 150 ; } 151 ; } 152 153 ; Function Attrs: nounwind uwtable 154 define void @goo(float %alpha, float* nocapture %a, float* nocapture readonly %b) #0 { 155 entry: 156 br label %for.body 157 158 for.body: ; preds = %entry, %for.body 159 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 160 %arrayidx = getelementptr inbounds float, float* %b, i64 %indvars.iv 161 %0 = load float, float* %arrayidx, align 4 162 %mul = fmul float %0, %alpha 163 %arrayidx2 = getelementptr inbounds float, float* %a, i64 %indvars.iv 164 %1 = load float, float* %arrayidx2, align 4 165 %add = fadd float %1, %mul 166 store float %add, float* %arrayidx2, align 4 167 %2 = add nsw i64 %indvars.iv, 1 168 %arrayidx5 = getelementptr inbounds float, float* %b, i64 %2 169 %3 = load float, float* %arrayidx5, align 4 170 %mul6 = fmul float %3, %alpha 171 %arrayidx9 = getelementptr inbounds float, float* %a, i64 %2 172 %4 = load float, float* %arrayidx9, align 4 173 %add10 = fadd float %4, %mul6 174 store float %add10, float* %arrayidx9, align 4 175 %5 = add nsw i64 %indvars.iv, 2 176 %arrayidx13 = getelementptr inbounds float, float* %b, i64 %5 177 %6 = load float, float* %arrayidx13, align 4 178 %mul14 = fmul float %6, %alpha 179 %arrayidx17 = getelementptr inbounds float, float* %a, i64 %5 180 %7 = load float, float* %arrayidx17, align 4 181 %add18 = fadd float %7, %mul14 182 store float %add18, float* %arrayidx17, align 4 183 %8 = add nsw i64 %indvars.iv, 3 184 %arrayidx21 = getelementptr inbounds float, float* %b, i64 %8 185 %9 = load float, float* %arrayidx21, align 4 186 %mul22 = fmul float %9, %alpha 187 %arrayidx25 = getelementptr inbounds float, float* %a, i64 %8 188 %10 = load float, float* %arrayidx25, align 4 189 %add26 = fadd float %10, %mul22 190 store float %add26, float* %arrayidx25, align 4 191 %11 = add nsw i64 %indvars.iv, 4 192 %arrayidx29 = getelementptr inbounds float, float* %b, i64 %11 193 %12 = load float, float* %arrayidx29, align 4 194 %mul30 = fmul float %12, %alpha 195 %arrayidx33 = getelementptr inbounds float, float* %a, i64 %11 196 %13 = load float, float* %arrayidx33, align 4 197 %add34 = fadd float %13, %mul30 198 store float %add34, float* %arrayidx33, align 4 199 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 5 200 %14 = trunc i64 %indvars.iv.next to i32 201 %cmp = icmp slt i32 %14, 3200 202 br i1 %cmp, label %for.body, label %for.end 203 204 ; CHECK-LABEL: @goo 205 206 ; CHECK: for.body: 207 ; CHECK: %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ] 208 ; CHECK: %arrayidx = getelementptr inbounds float, float* %b, i64 %indvar 209 ; CHECK: %0 = load float, float* %arrayidx, align 4 210 ; CHECK: %mul = fmul float %0, %alpha 211 ; CHECK: %arrayidx2 = getelementptr inbounds float, float* %a, i64 %indvar 212 ; CHECK: %1 = load float, float* %arrayidx2, align 4 213 ; CHECK: %add = fadd float %1, %mul 214 ; CHECK: store float %add, float* %arrayidx2, align 4 215 ; CHECK: %indvar.next = add i64 %indvar, 1 216 ; CHECK: %exitcond = icmp eq i64 %indvar, 3199 217 ; CHECK: br i1 %exitcond, label %for.end, label %for.body 218 219 ; CHECK: ret 220 221 for.end: ; preds = %for.body 222 ret void 223 } 224 225 ; void hoo(float alpha, float *a, float *b, int *ip) { 226 ; for (int i = 0; i < 3200; i += 5) { 227 ; a[i] += alpha * b[ip[i]]; 228 ; a[i + 1] += alpha * b[ip[i + 1]]; 229 ; a[i + 2] += alpha * b[ip[i + 2]]; 230 ; a[i + 3] += alpha * b[ip[i + 3]]; 231 ; a[i + 4] += alpha * b[ip[i + 4]]; 232 ; } 233 ; } 234 235 ; Function Attrs: nounwind uwtable 236 define void @hoo(float %alpha, float* nocapture %a, float* nocapture readonly %b, i32* nocapture readonly %ip) #0 { 237 entry: 238 br label %for.body 239 240 for.body: ; preds = %entry, %for.body 241 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 242 %arrayidx = getelementptr inbounds i32, i32* %ip, i64 %indvars.iv 243 %0 = load i32, i32* %arrayidx, align 4 244 %idxprom1 = sext i32 %0 to i64 245 %arrayidx2 = getelementptr inbounds float, float* %b, i64 %idxprom1 246 %1 = load float, float* %arrayidx2, align 4 247 %mul = fmul float %1, %alpha 248 %arrayidx4 = getelementptr inbounds float, float* %a, i64 %indvars.iv 249 %2 = load float, float* %arrayidx4, align 4 250 %add = fadd float %2, %mul 251 store float %add, float* %arrayidx4, align 4 252 %3 = add nsw i64 %indvars.iv, 1 253 %arrayidx7 = getelementptr inbounds i32, i32* %ip, i64 %3 254 %4 = load i32, i32* %arrayidx7, align 4 255 %idxprom8 = sext i32 %4 to i64 256 %arrayidx9 = getelementptr inbounds float, float* %b, i64 %idxprom8 257 %5 = load float, float* %arrayidx9, align 4 258 %mul10 = fmul float %5, %alpha 259 %arrayidx13 = getelementptr inbounds float, float* %a, i64 %3 260 %6 = load float, float* %arrayidx13, align 4 261 %add14 = fadd float %6, %mul10 262 store float %add14, float* %arrayidx13, align 4 263 %7 = add nsw i64 %indvars.iv, 2 264 %arrayidx17 = getelementptr inbounds i32, i32* %ip, i64 %7 265 %8 = load i32, i32* %arrayidx17, align 4 266 %idxprom18 = sext i32 %8 to i64 267 %arrayidx19 = getelementptr inbounds float, float* %b, i64 %idxprom18 268 %9 = load float, float* %arrayidx19, align 4 269 %mul20 = fmul float %9, %alpha 270 %arrayidx23 = getelementptr inbounds float, float* %a, i64 %7 271 %10 = load float, float* %arrayidx23, align 4 272 %add24 = fadd float %10, %mul20 273 store float %add24, float* %arrayidx23, align 4 274 %11 = add nsw i64 %indvars.iv, 3 275 %arrayidx27 = getelementptr inbounds i32, i32* %ip, i64 %11 276 %12 = load i32, i32* %arrayidx27, align 4 277 %idxprom28 = sext i32 %12 to i64 278 %arrayidx29 = getelementptr inbounds float, float* %b, i64 %idxprom28 279 %13 = load float, float* %arrayidx29, align 4 280 %mul30 = fmul float %13, %alpha 281 %arrayidx33 = getelementptr inbounds float, float* %a, i64 %11 282 %14 = load float, float* %arrayidx33, align 4 283 %add34 = fadd float %14, %mul30 284 store float %add34, float* %arrayidx33, align 4 285 %15 = add nsw i64 %indvars.iv, 4 286 %arrayidx37 = getelementptr inbounds i32, i32* %ip, i64 %15 287 %16 = load i32, i32* %arrayidx37, align 4 288 %idxprom38 = sext i32 %16 to i64 289 %arrayidx39 = getelementptr inbounds float, float* %b, i64 %idxprom38 290 %17 = load float, float* %arrayidx39, align 4 291 %mul40 = fmul float %17, %alpha 292 %arrayidx43 = getelementptr inbounds float, float* %a, i64 %15 293 %18 = load float, float* %arrayidx43, align 4 294 %add44 = fadd float %18, %mul40 295 store float %add44, float* %arrayidx43, align 4 296 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 5 297 %19 = trunc i64 %indvars.iv.next to i32 298 %cmp = icmp slt i32 %19, 3200 299 br i1 %cmp, label %for.body, label %for.end 300 301 ; CHECK-LABEL: @hoo 302 303 ; CHECK: for.body: 304 ; CHECK: %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ] 305 ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %ip, i64 %indvar 306 ; CHECK: %0 = load i32, i32* %arrayidx, align 4 307 ; CHECK: %idxprom1 = sext i32 %0 to i64 308 ; CHECK: %arrayidx2 = getelementptr inbounds float, float* %b, i64 %idxprom1 309 ; CHECK: %1 = load float, float* %arrayidx2, align 4 310 ; CHECK: %mul = fmul float %1, %alpha 311 ; CHECK: %arrayidx4 = getelementptr inbounds float, float* %a, i64 %indvar 312 ; CHECK: %2 = load float, float* %arrayidx4, align 4 313 ; CHECK: %add = fadd float %2, %mul 314 ; CHECK: store float %add, float* %arrayidx4, align 4 315 ; CHECK: %indvar.next = add i64 %indvar, 1 316 ; CHECK: %exitcond = icmp eq i64 %indvar, 3199 317 ; CHECK: br i1 %exitcond, label %for.end, label %for.body 318 319 ; CHECK: ret 320 321 for.end: ; preds = %for.body 322 ret void 323 } 324 325 ; void multi1(int *x) { 326 ; y = foo(0) 327 ; for (int i = 0; i < 500; ++i) { 328 ; x[3*i] = y; 329 ; x[3*i+1] = y; 330 ; x[3*i+2] = y; 331 ; x[3*i+6] = y; 332 ; x[3*i+7] = y; 333 ; x[3*i+8] = y; 334 ; } 335 ; } 336 337 ; Function Attrs: nounwind uwtable 338 define void @multi1(i32* nocapture %x) #0 { 339 entry: 340 %call = tail call i32 @foo(i32 0) #1 341 br label %for.body 342 343 for.body: ; preds = %for.body, %entry 344 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 345 %0 = mul nsw i64 %indvars.iv, 3 346 %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0 347 store i32 %call, i32* %arrayidx, align 4 348 %1 = add nsw i64 %0, 1 349 %arrayidx4 = getelementptr inbounds i32, i32* %x, i64 %1 350 store i32 %call, i32* %arrayidx4, align 4 351 %2 = add nsw i64 %0, 2 352 %arrayidx9 = getelementptr inbounds i32, i32* %x, i64 %2 353 store i32 %call, i32* %arrayidx9, align 4 354 %3 = add nsw i64 %0, 6 355 %arrayidx6 = getelementptr inbounds i32, i32* %x, i64 %3 356 store i32 %call, i32* %arrayidx6, align 4 357 %4 = add nsw i64 %0, 7 358 %arrayidx7 = getelementptr inbounds i32, i32* %x, i64 %4 359 store i32 %call, i32* %arrayidx7, align 4 360 %5 = add nsw i64 %0, 8 361 %arrayidx8 = getelementptr inbounds i32, i32* %x, i64 %5 362 store i32 %call, i32* %arrayidx8, align 4 363 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 364 %exitcond = icmp eq i64 %indvars.iv.next, 500 365 br i1 %exitcond, label %for.end, label %for.body 366 367 ; CHECK-LABEL: @multi1 368 369 ; CHECK:for.body: 370 ; CHECK: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 371 ; CHECK: %0 = add i64 %indvars.iv, 6 372 ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv 373 ; CHECK: store i32 %call, i32* %arrayidx, align 4 374 ; CHECK: %arrayidx6 = getelementptr inbounds i32, i32* %x, i64 %0 375 ; CHECK: store i32 %call, i32* %arrayidx6, align 4 376 ; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 377 ; CHECK: %exitcond2 = icmp eq i64 %0, 1505 378 ; CHECK: br i1 %exitcond2, label %for.end, label %for.body 379 380 for.end: ; preds = %for.body 381 ret void 382 } 383 384 ; void multi2(int *x) { 385 ; y = foo(0) 386 ; for (int i = 0; i < 500; ++i) { 387 ; x[3*i] = y; 388 ; x[3*i+1] = y; 389 ; x[3*i+2] = y; 390 ; x[3*(i+1)] = y; 391 ; x[3*(i+1)+1] = y; 392 ; x[3*(i+1)+2] = y; 393 ; } 394 ; } 395 396 ; Function Attrs: nounwind uwtable 397 define void @multi2(i32* nocapture %x) #0 { 398 entry: 399 %call = tail call i32 @foo(i32 0) #1 400 br label %for.body 401 402 for.body: ; preds = %for.body, %entry 403 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 404 %0 = mul nsw i64 %indvars.iv, 3 405 %add = add nsw i64 %indvars.iv, 1 406 %newmul = mul nsw i64 %add, 3 407 %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0 408 store i32 %call, i32* %arrayidx, align 4 409 %1 = add nsw i64 %0, 1 410 %arrayidx4 = getelementptr inbounds i32, i32* %x, i64 %1 411 store i32 %call, i32* %arrayidx4, align 4 412 %2 = add nsw i64 %0, 2 413 %arrayidx9 = getelementptr inbounds i32, i32* %x, i64 %2 414 store i32 %call, i32* %arrayidx9, align 4 415 %arrayidx6 = getelementptr inbounds i32, i32* %x, i64 %newmul 416 store i32 %call, i32* %arrayidx6, align 4 417 %3 = add nsw i64 %newmul, 1 418 %arrayidx7 = getelementptr inbounds i32, i32* %x, i64 %3 419 store i32 %call, i32* %arrayidx7, align 4 420 %4 = add nsw i64 %newmul, 2 421 %arrayidx8 = getelementptr inbounds i32, i32* %x, i64 %4 422 store i32 %call, i32* %arrayidx8, align 4 423 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 424 %exitcond = icmp eq i64 %indvars.iv.next, 500 425 br i1 %exitcond, label %for.end, label %for.body 426 427 ; CHECK-LABEL: @multi2 428 429 ; CHECK:for.body: 430 ; CHECK: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 431 ; CHECK: %0 = add i64 %indvars.iv, 3 432 ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv 433 ; CHECK: store i32 %call, i32* %arrayidx, align 4 434 ; CHECK: %arrayidx6 = getelementptr inbounds i32, i32* %x, i64 %0 435 ; CHECK: store i32 %call, i32* %arrayidx6, align 4 436 ; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 437 ; CHECK: %exitcond2 = icmp eq i64 %indvars.iv, 1499 438 ; CHECK: br i1 %exitcond2, label %for.end, label %for.body 439 440 for.end: ; preds = %for.body 441 ret void 442 } 443 444 ; void multi3(int *x) { 445 ; y = foo(0) 446 ; for (int i = 0; i < 500; ++i) { 447 ; // Note: No zero index 448 ; x[3*i+3] = y; 449 ; x[3*i+4] = y; 450 ; x[3*i+5] = y; 451 ; } 452 ; } 453 454 ; Function Attrs: nounwind uwtable 455 define void @multi3(i32* nocapture %x) #0 { 456 entry: 457 %call = tail call i32 @foo(i32 0) #1 458 br label %for.body 459 460 for.body: ; preds = %for.body, %entry 461 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 462 %0 = mul nsw i64 %indvars.iv, 3 463 %x0 = add nsw i64 %0, 3 464 %add = add nsw i64 %indvars.iv, 1 465 %arrayidx = getelementptr inbounds i32, i32* %x, i64 %x0 466 store i32 %call, i32* %arrayidx, align 4 467 %1 = add nsw i64 %0, 4 468 %arrayidx4 = getelementptr inbounds i32, i32* %x, i64 %1 469 store i32 %call, i32* %arrayidx4, align 4 470 %2 = add nsw i64 %0, 5 471 %arrayidx9 = getelementptr inbounds i32, i32* %x, i64 %2 472 store i32 %call, i32* %arrayidx9, align 4 473 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 474 %exitcond = icmp eq i64 %indvars.iv.next, 500 475 br i1 %exitcond, label %for.end, label %for.body 476 477 ; CHECK-LABEL: @multi3 478 ; CHECK: for.body: 479 ; CHECK: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 480 ; CHECK: %0 = add i64 %indvars.iv, 3 481 ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0 482 ; CHECK: store i32 %call, i32* %arrayidx, align 4 483 ; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 484 ; CHECK: %exitcond1 = icmp eq i64 %0, 1502 485 ; CHECK: br i1 %exitcond1, label %for.end, label %for.body 486 487 for.end: ; preds = %for.body 488 ret void 489 } 490 491 ; int foo(int a); 492 ; void bar2(int *x, int y, int z) { 493 ; for (int i = 0; i < 500; i += 3) { 494 ; foo(i+y+i*z); // Slightly reordered instruction order 495 ; foo(i+1+y+(i+1)*z); 496 ; foo(i+2+y+(i+2)*z); 497 ; } 498 ; } 499 500 ; Function Attrs: nounwind uwtable 501 define void @bar2(i32* nocapture readnone %x, i32 %y, i32 %z) #0 { 502 entry: 503 br label %for.body 504 505 for.body: ; preds = %for.body, %entry 506 %i.08 = phi i32 [ 0, %entry ], [ %add3, %for.body ] 507 508 %tmp1 = add i32 %i.08, %y 509 %tmp2 = mul i32 %i.08, %z 510 %tmp3 = add i32 %tmp2, %tmp1 511 %call = tail call i32 @foo(i32 %tmp3) #1 512 513 %add = add nsw i32 %i.08, 1 514 %tmp2a = mul i32 %add, %z 515 %tmp1a = add i32 %add, %y 516 %tmp3a = add i32 %tmp2a, %tmp1a 517 %calla = tail call i32 @foo(i32 %tmp3a) #1 518 519 %add2 = add nsw i32 %i.08, 2 520 %tmp2b = mul i32 %add2, %z 521 %tmp1b = add i32 %add2, %y 522 %tmp3b = add i32 %tmp2b, %tmp1b 523 %callb = tail call i32 @foo(i32 %tmp3b) #1 524 525 %add3 = add nsw i32 %i.08, 3 526 527 %exitcond = icmp sge i32 %add3, 500 528 br i1 %exitcond, label %for.end, label %for.body 529 530 ; CHECK-LABEL: @bar2 531 532 ; CHECK: for.body: 533 ; CHECK: %indvar = phi i32 [ %indvar.next, %for.body ], [ 0, %entry ] 534 ; CHECK: %tmp1 = add i32 %indvar, %y 535 ; CHECK: %tmp2 = mul i32 %indvar, %z 536 ; CHECK: %tmp3 = add i32 %tmp2, %tmp1 537 ; CHECK: %call = tail call i32 @foo(i32 %tmp3) #1 538 ; CHECK: %indvar.next = add i32 %indvar, 1 539 ; CHECK: %exitcond1 = icmp eq i32 %indvar, 500 540 ; CHECK: br i1 %exitcond1, label %for.end, label %for.body 541 542 ; CHECK: ret 543 544 for.end: ; preds = %for.body 545 ret void 546 } 547 548 %struct.s = type { i32, i32 } 549 550 ; Function Attrs: nounwind uwtable 551 define void @gep1(%struct.s* nocapture %x) #0 { 552 entry: 553 %call = tail call i32 @foo(i32 0) #1 554 br label %for.body 555 556 for.body: ; preds = %for.body, %entry 557 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 558 %0 = mul nsw i64 %indvars.iv, 3 559 %arrayidx = getelementptr inbounds %struct.s, %struct.s* %x, i64 %0, i32 0 560 store i32 %call, i32* %arrayidx, align 4 561 %1 = add nsw i64 %0, 1 562 %arrayidx4 = getelementptr inbounds %struct.s, %struct.s* %x, i64 %1, i32 0 563 store i32 %call, i32* %arrayidx4, align 4 564 %2 = add nsw i64 %0, 2 565 %arrayidx9 = getelementptr inbounds %struct.s, %struct.s* %x, i64 %2, i32 0 566 store i32 %call, i32* %arrayidx9, align 4 567 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 568 %exitcond = icmp eq i64 %indvars.iv.next, 500 569 br i1 %exitcond, label %for.end, label %for.body 570 571 ; CHECK-LABEL: @gep1 572 ; This test is a crash test only. 573 ; CHECK: ret 574 for.end: ; preds = %for.body 575 ret void 576 } 577 578 579 attributes #0 = { nounwind uwtable } 580 attributes #1 = { nounwind } 581 582