1; RUN: opt < %s -S -loop-flatten -debug-only=loop-flatten 2>&1 | FileCheck %s 2; REQUIRES: asserts 3 4; Every function in this file has a reason that it can't be transformed. 5 6; CHECK-NOT: Checks all passed, doing the transformation 7 8; Outer loop does not start at zero 9define void @test_1(i32 %N, i32* nocapture %C, i32* nocapture readonly %A, i32 %scale) { 10entry: 11 %cmp25 = icmp sgt i32 %N, 0 12 br i1 %cmp25, label %for.body4.lr.ph, label %for.cond.cleanup 13 14for.body4.lr.ph: 15 %i.026 = phi i32 [ %inc10, %for.cond.cleanup3 ], [ 1, %entry ] 16 %mul = mul nsw i32 %i.026, %N 17 br label %for.body4 18 19for.body4: 20 %j.024 = phi i32 [ 0, %for.body4.lr.ph ], [ %inc, %for.body4 ] 21 %add = add nsw i32 %j.024, %mul 22 %arrayidx = getelementptr inbounds i32, i32* %A, i32 %add 23 %0 = load i32, i32* %arrayidx, align 4 24 %mul5 = mul nsw i32 %0, %scale 25 %arrayidx8 = getelementptr inbounds i32, i32* %C, i32 %add 26 store i32 %mul5, i32* %arrayidx8, align 4 27 %inc = add nuw nsw i32 %j.024, 1 28 %exitcond = icmp eq i32 %inc, %N 29 br i1 %exitcond, label %for.cond.cleanup3, label %for.body4 30 31for.cond.cleanup3: 32 %inc10 = add nuw nsw i32 %i.026, 1 33 %exitcond27 = icmp eq i32 %inc10, %N 34 br i1 %exitcond27, label %for.cond.cleanup, label %for.body4.lr.ph 35 36for.cond.cleanup: 37 ret void 38} 39 40; Inner loop does not start at zero 41define void @test_2(i32 %N, i32* nocapture %C, i32* nocapture readonly %A, i32 %scale) { 42entry: 43 %cmp25 = icmp sgt i32 %N, 0 44 br i1 %cmp25, label %for.body4.lr.ph, label %for.cond.cleanup 45 46for.body4.lr.ph: 47 %i.026 = phi i32 [ %inc10, %for.cond.cleanup3 ], [ 0, %entry ] 48 %mul = mul nsw i32 %i.026, %N 49 br label %for.body4 50 51for.body4: 52 %j.024 = phi i32 [ 1, %for.body4.lr.ph ], [ %inc, %for.body4 ] 53 %add = add nsw i32 %j.024, %mul 54 %arrayidx = getelementptr inbounds i32, i32* %A, i32 %add 55 %0 = load i32, i32* %arrayidx, align 4 56 %mul5 = mul nsw i32 %0, %scale 57 %arrayidx8 = getelementptr inbounds i32, i32* %C, i32 %add 58 store i32 %mul5, i32* %arrayidx8, align 4 59 %inc = add nuw nsw i32 %j.024, 1 60 %exitcond = icmp eq i32 %inc, %N 61 br i1 %exitcond, label %for.cond.cleanup3, label %for.body4 62 63for.cond.cleanup3: 64 %inc10 = add nuw nsw i32 %i.026, 1 65 %exitcond27 = icmp eq i32 %inc10, %N 66 br i1 %exitcond27, label %for.cond.cleanup, label %for.body4.lr.ph 67 68for.cond.cleanup: 69 ret void 70} 71 72; Outer IV used directly 73define hidden void @test_3(i16 zeroext %N, i32* nocapture %C, i32* nocapture readonly %A, i32 %scale) { 74entry: 75 %conv = zext i16 %N to i32 76 %cmp25 = icmp eq i16 %N, 0 77 br i1 %cmp25, label %for.cond.cleanup, label %for.body.lr.ph.split.us 78 79for.body.lr.ph.split.us: ; preds = %entry 80 br label %for.body.us 81 82for.body.us: ; preds = %for.cond2.for.cond.cleanup6_crit_edge.us, %for.body.lr.ph.split.us 83 %i.026.us = phi i32 [ 0, %for.body.lr.ph.split.us ], [ %inc12.us, %for.cond2.for.cond.cleanup6_crit_edge.us ] 84 %arrayidx.us = getelementptr inbounds i32, i32* %A, i32 %i.026.us 85 %mul9.us = mul nuw nsw i32 %i.026.us, %conv 86 br label %for.body7.us 87 88for.body7.us: ; preds = %for.body.us, %for.body7.us 89 %j.024.us = phi i32 [ 0, %for.body.us ], [ %inc.us, %for.body7.us ] 90 %0 = load i32, i32* %arrayidx.us, align 4 91 %mul.us = mul nsw i32 %0, %scale 92 %add.us = add nuw nsw i32 %j.024.us, %mul9.us 93 %arrayidx10.us = getelementptr inbounds i32, i32* %C, i32 %add.us 94 store i32 %mul.us, i32* %arrayidx10.us, align 4 95 %inc.us = add nuw nsw i32 %j.024.us, 1 96 %exitcond = icmp ne i32 %inc.us, %conv 97 br i1 %exitcond, label %for.body7.us, label %for.cond2.for.cond.cleanup6_crit_edge.us 98 99for.cond2.for.cond.cleanup6_crit_edge.us: ; preds = %for.body7.us 100 %inc12.us = add nuw nsw i32 %i.026.us, 1 101 %exitcond27 = icmp ne i32 %inc12.us, %conv 102 br i1 %exitcond27, label %for.body.us, label %for.cond.cleanup.loopexit 103 104for.cond.cleanup.loopexit: ; preds = %for.cond2.for.cond.cleanup6_crit_edge.us 105 br label %for.cond.cleanup 106 107for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit, %entry 108 ret void 109} 110 111; Inner IV used directly 112define hidden void @test_4(i16 zeroext %N, i32* nocapture %C, i32* nocapture readonly %A, i32 %scale) { 113entry: 114 %conv = zext i16 %N to i32 115 %cmp25 = icmp eq i16 %N, 0 116 br i1 %cmp25, label %for.cond.cleanup, label %for.body.lr.ph.split.us 117 118for.body.lr.ph.split.us: ; preds = %entry 119 br label %for.body.us 120 121for.body.us: ; preds = %for.cond2.for.cond.cleanup6_crit_edge.us, %for.body.lr.ph.split.us 122 %i.026.us = phi i32 [ 0, %for.body.lr.ph.split.us ], [ %inc12.us, %for.cond2.for.cond.cleanup6_crit_edge.us ] 123 %mul9.us = mul nuw nsw i32 %i.026.us, %conv 124 br label %for.body7.us 125 126for.body7.us: ; preds = %for.body.us, %for.body7.us 127 %j.024.us = phi i32 [ 0, %for.body.us ], [ %inc.us, %for.body7.us ] 128 %arrayidx.us = getelementptr inbounds i32, i32* %A, i32 %j.024.us 129 %0 = load i32, i32* %arrayidx.us, align 4 130 %mul.us = mul nsw i32 %0, %scale 131 %add.us = add nuw nsw i32 %j.024.us, %mul9.us 132 %arrayidx10.us = getelementptr inbounds i32, i32* %C, i32 %add.us 133 store i32 %mul.us, i32* %arrayidx10.us, align 4 134 %inc.us = add nuw nsw i32 %j.024.us, 1 135 %exitcond = icmp ne i32 %inc.us, %conv 136 br i1 %exitcond, label %for.body7.us, label %for.cond2.for.cond.cleanup6_crit_edge.us 137 138for.cond2.for.cond.cleanup6_crit_edge.us: ; preds = %for.body7.us 139 %inc12.us = add nuw nsw i32 %i.026.us, 1 140 %exitcond27 = icmp ne i32 %inc12.us, %conv 141 br i1 %exitcond27, label %for.body.us, label %for.cond.cleanup.loopexit 142 143for.cond.cleanup.loopexit: ; preds = %for.cond2.for.cond.cleanup6_crit_edge.us 144 br label %for.cond.cleanup 145 146for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit, %entry 147 ret void 148} 149 150; Inner iteration count not invariant in outer loop 151declare i32 @get_int() readonly 152define void @test_5(i16 zeroext %N, i32* nocapture %C, i32* nocapture readonly %A, i32 %scale) { 153entry: 154 %conv = zext i16 %N to i32 155 %cmp27 = icmp eq i16 %N, 0 156 br i1 %cmp27, label %for.cond.cleanup, label %for.body.lr.ph 157 158for.body.lr.ph: ; preds = %entry 159 br label %for.body 160 161for.cond.cleanup.loopexit: ; preds = %for.cond.cleanup5 162 br label %for.cond.cleanup 163 164for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit, %entry 165 ret void 166 167for.body: ; preds = %for.body.lr.ph, %for.cond.cleanup5 168 %i.028 = phi i32 [ 0, %for.body.lr.ph ], [ %inc12, %for.cond.cleanup5 ] 169 %call = tail call i32 @get_int() 170 %cmp325 = icmp sgt i32 %call, 0 171 br i1 %cmp325, label %for.body6.lr.ph, label %for.cond.cleanup5 172 173for.body6.lr.ph: ; preds = %for.body 174 %mul = mul nsw i32 %call, %i.028 175 br label %for.body6 176 177for.cond.cleanup5.loopexit: ; preds = %for.body6 178 br label %for.cond.cleanup5 179 180for.cond.cleanup5: ; preds = %for.cond.cleanup5.loopexit, %for.body 181 %inc12 = add nuw nsw i32 %i.028, 1 182 %exitcond29 = icmp ne i32 %inc12, %conv 183 br i1 %exitcond29, label %for.body, label %for.cond.cleanup.loopexit 184 185for.body6: ; preds = %for.body6.lr.ph, %for.body6 186 %j.026 = phi i32 [ 0, %for.body6.lr.ph ], [ %inc, %for.body6 ] 187 %add = add nsw i32 %j.026, %mul 188 %arrayidx = getelementptr inbounds i32, i32* %A, i32 %add 189 %0 = load i32, i32* %arrayidx, align 4 190 %mul7 = mul nsw i32 %0, %scale 191 %arrayidx10 = getelementptr inbounds i32, i32* %C, i32 %add 192 store i32 %mul7, i32* %arrayidx10, align 4 193 %inc = add nuw nsw i32 %j.026, 1 194 %exitcond = icmp ne i32 %inc, %call 195 br i1 %exitcond, label %for.body6, label %for.cond.cleanup5.loopexit 196} 197 198; Inner loop has an early exit 199define hidden void @test_6(i16 zeroext %N, i32* nocapture %C, i32* nocapture readonly %A, i32 %scale) { 200entry: 201 %conv = zext i16 %N to i32 202 %cmp39 = icmp eq i16 %N, 0 203 br i1 %cmp39, label %for.cond.cleanup, label %for.body.us.preheader 204 205for.body.us.preheader: ; preds = %entry 206 br label %for.body.us 207 208for.body.us: ; preds = %for.body.us.preheader, %cleanup.us 209 %i.040.us = phi i32 [ %inc19.us, %cleanup.us ], [ 0, %for.body.us.preheader ] 210 %mul.us = mul nuw nsw i32 %i.040.us, %conv 211 br label %for.body7.us 212 213for.body7.us: ; preds = %for.body.us, %if.end.us 214 %j.038.us = phi i32 [ 0, %for.body.us ], [ %inc.us, %if.end.us ] 215 %add.us = add nuw nsw i32 %j.038.us, %mul.us 216 %arrayidx.us = getelementptr inbounds i32, i32* %A, i32 %add.us 217 %0 = load i32, i32* %arrayidx.us, align 4 218 %tobool.us = icmp eq i32 %0, 0 219 br i1 %tobool.us, label %if.end.us, label %cleanup.us 220 221cleanup.us: ; preds = %if.end.us, %for.body7.us 222 %inc19.us = add nuw nsw i32 %i.040.us, 1 223 %exitcond = icmp eq i32 %inc19.us, %conv 224 br i1 %exitcond, label %for.cond.cleanup, label %for.body.us 225 226if.end.us: ; preds = %for.body7.us 227 %arrayidx17.us = getelementptr inbounds i32, i32* %C, i32 %add.us 228 store i32 0, i32* %arrayidx17.us, align 4 229 %inc.us = add nuw nsw i32 %j.038.us, 1 230 %cmp4.us = icmp ult i32 %inc.us, %conv 231 br i1 %cmp4.us, label %for.body7.us, label %cleanup.us 232 233for.cond.cleanup: ; preds = %cleanup.us, %entry 234 ret void 235} 236 237define hidden void @test_7(i16 zeroext %N, i32* nocapture %C, i32* nocapture readonly %A, i32 %scale) { 238entry: 239 %conv = zext i16 %N to i32 240 %cmp30 = icmp eq i16 %N, 0 241 br i1 %cmp30, label %cleanup, label %for.body.us.preheader 242 243for.body.us.preheader: ; preds = %entry 244 br label %for.body.us 245 246for.body.us: ; preds = %for.body.us.preheader, %for.cond2.for.cond.cleanup6_crit_edge.us 247 %i.031.us = phi i32 [ %inc15.us, %for.cond2.for.cond.cleanup6_crit_edge.us ], [ 0, %for.body.us.preheader ] 248 %call.us = tail call i32 @get_int() #2 249 %tobool.us = icmp eq i32 %call.us, 0 250 br i1 %tobool.us, label %for.body7.lr.ph.us, label %cleanup 251 252for.body7.us: ; preds = %for.body7.us, %for.body7.lr.ph.us 253 %j.029.us = phi i32 [ 0, %for.body7.lr.ph.us ], [ %inc.us, %for.body7.us ] 254 %add.us = add nuw nsw i32 %j.029.us, %mul.us 255 %arrayidx.us = getelementptr inbounds i32, i32* %A, i32 %add.us 256 %0 = load i32, i32* %arrayidx.us, align 4 257 %mul9.us = mul nsw i32 %0, %scale 258 %arrayidx13.us = getelementptr inbounds i32, i32* %C, i32 %add.us 259 store i32 %mul9.us, i32* %arrayidx13.us, align 4 260 %inc.us = add nuw nsw i32 %j.029.us, 1 261 %exitcond = icmp eq i32 %inc.us, %conv 262 br i1 %exitcond, label %for.cond2.for.cond.cleanup6_crit_edge.us, label %for.body7.us 263 264for.body7.lr.ph.us: ; preds = %for.body.us 265 %mul.us = mul nuw nsw i32 %i.031.us, %conv 266 br label %for.body7.us 267 268for.cond2.for.cond.cleanup6_crit_edge.us: ; preds = %for.body7.us 269 %inc15.us = add nuw nsw i32 %i.031.us, 1 270 %cmp.us = icmp ult i32 %inc15.us, %conv 271 br i1 %cmp.us, label %for.body.us, label %cleanup 272 273cleanup: ; preds = %for.cond2.for.cond.cleanup6_crit_edge.us, %for.body.us, %entry 274 ret void 275} 276 277; Step is not 1 278define i32 @test_8(i32 %val, i16* nocapture %A) { 279entry: 280 br label %for.body 281 282for.body: ; preds = %entry, %for.inc6 283 %i.018 = phi i32 [ 0, %entry ], [ %inc7, %for.inc6 ] 284 %mul = mul nuw nsw i32 %i.018, 20 285 br label %for.body3 286 287for.body3: ; preds = %for.body, %for.body3 288 %j.017 = phi i32 [ 0, %for.body ], [ %inc, %for.body3 ] 289 %add = add nuw nsw i32 %j.017, %mul 290 %arrayidx = getelementptr inbounds i16, i16* %A, i32 %add 291 %0 = load i16, i16* %arrayidx, align 2 292 %conv16 = zext i16 %0 to i32 293 %add4 = add i32 %conv16, %val 294 %conv5 = trunc i32 %add4 to i16 295 store i16 %conv5, i16* %arrayidx, align 2 296 %inc = add nuw nsw i32 %j.017, 1 297 %exitcond = icmp ne i32 %inc, 20 298 br i1 %exitcond, label %for.body3, label %for.inc6 299 300for.inc6: ; preds = %for.body3 301 %inc7 = add nuw nsw i32 %i.018, 2 302 %exitcond19 = icmp ne i32 %inc7, 10 303 br i1 %exitcond19, label %for.body, label %for.end8 304 305for.end8: ; preds = %for.inc6 306 ret i32 10 307} 308 309 310; Step is not 1 311define i32 @test_9(i32 %val, i16* nocapture %A) { 312entry: 313 br label %for.body 314 315for.body: ; preds = %entry, %for.inc6 316 %i.018 = phi i32 [ 0, %entry ], [ %inc7, %for.inc6 ] 317 %mul = mul nuw nsw i32 %i.018, 20 318 br label %for.body3 319 320for.body3: ; preds = %for.body, %for.body3 321 %j.017 = phi i32 [ 0, %for.body ], [ %inc, %for.body3 ] 322 %add = add nuw nsw i32 %j.017, %mul 323 %arrayidx = getelementptr inbounds i16, i16* %A, i32 %add 324 %0 = load i16, i16* %arrayidx, align 2 325 %conv16 = zext i16 %0 to i32 326 %add4 = add i32 %conv16, %val 327 %conv5 = trunc i32 %add4 to i16 328 store i16 %conv5, i16* %arrayidx, align 2 329 %inc = add nuw nsw i32 %j.017, 2 330 %exitcond = icmp ne i32 %inc, 20 331 br i1 %exitcond, label %for.body3, label %for.inc6 332 333for.inc6: ; preds = %for.body3 334 %inc7 = add nuw nsw i32 %i.018, 1 335 %exitcond19 = icmp ne i32 %inc7, 10 336 br i1 %exitcond19, label %for.body, label %for.end8 337 338for.end8: ; preds = %for.inc6 339 ret i32 10 340} 341 342 343; Outer loop conditional phi 344define i32 @e() { 345entry: 346 br label %for.body 347 348for.body: ; preds = %entry, %for.end16 349 %f.033 = phi i32 [ 0, %entry ], [ %inc18, %for.end16 ] 350 %g.032 = phi i32 [ undef, %entry ], [ %g.3.lcssa, %for.end16 ] 351 %.pr = add i32 10, 10 352 %tobool29 = icmp eq i32 %.pr, 0 353 br i1 %tobool29, label %for.end, label %for.body2.lr.ph 354 355for.body2.lr.ph: ; preds = %for.body 356 br label %for.cond1.for.end_crit_edge 357 358for.cond1.for.end_crit_edge: ; preds = %for.body2.lr.ph 359 br label %for.end 360 361for.end: ; preds = %for.cond1.for.end_crit_edge, %for.body 362 %g.1.lcssa = phi i32 [ 0, %for.cond1.for.end_crit_edge ], [ %g.032, %for.body ] 363 br label %for.body5 364 365for.body5: ; preds = %for.end, %lor.end 366 %i.031 = phi i32 [ 0, %for.end ], [ %inc15, %lor.end ] 367 %g.230 = phi i32 [ %g.1.lcssa, %for.end ], [ %g.3, %lor.end ] 368 %0 = add i32 10, 10 369 %1 = add i32 10, 10 370 %tobool9 = icmp eq i32 %1, 0 371 br i1 %tobool9, label %lor.rhs, label %lor.end 372 373lor.rhs: ; preds = %for.body5 374 %2 = add i32 10, 10 375 %call11 = add i32 10, 10 376 %tobool12 = icmp ne i32 %call11, 0 377 br label %lor.end 378 379lor.end: ; preds = %for.body5, %lor.rhs 380 %g.3 = phi i32 [ %g.230, %for.body5 ], [ %call11, %lor.rhs ] 381 %3 = phi i1 [ true, %for.body5 ], [ %tobool12, %lor.rhs ] 382 %lor.ext = zext i1 %3 to i32 383 %inc15 = add nuw nsw i32 %i.031, 1 384 %exitcond = icmp ne i32 %inc15, 9 385 br i1 %exitcond, label %for.body5, label %for.end16 386 387for.end16: ; preds = %lor.end 388 %g.3.lcssa = phi i32 [ %g.3, %lor.end ] 389 %inc18 = add nuw nsw i32 %f.033, 1 390 %exitcond34 = icmp ne i32 %inc18, 7 391 br i1 %exitcond34, label %for.body, label %for.end19 392 393for.end19: ; preds = %for.end16 394 ret i32 undef 395} 396 397; A 3d loop corresponding to: 398; 399; for (int i = 0; i < N; ++i) 400; for (int j = 0; j < N; ++j) 401; for (int k = 0; k < N; ++k) 402; f(&A[i + N * (j + N * k)]); 403; 404define void @d3_1(i32* %A, i32 %N) { 405entry: 406 %cmp35 = icmp sgt i32 %N, 0 407 br i1 %cmp35, label %for.cond1.preheader.lr.ph, label %for.cond.cleanup 408 409for.cond1.preheader.lr.ph: 410 br label %for.cond1.preheader.us 411 412for.cond1.preheader.us: 413 %i.036.us = phi i32 [ 0, %for.cond1.preheader.lr.ph ], [ %inc15.us, %for.cond1.for.cond.cleanup3_crit_edge.us ] 414 br i1 true, label %for.cond5.preheader.us.us.preheader, label %for.cond5.preheader.us52.preheader 415 416for.cond5.preheader.us52.preheader: 417 br label %for.cond5.preheader.us52 418 419for.cond5.preheader.us.us.preheader: 420 br label %for.cond5.preheader.us.us 421 422for.cond5.preheader.us52: 423 br i1 false, label %for.cond5.preheader.us52, label %for.cond1.for.cond.cleanup3_crit_edge.us.loopexit58 424 425for.cond1.for.cond.cleanup3_crit_edge.us.loopexit: 426 br label %for.cond1.for.cond.cleanup3_crit_edge.us 427 428for.cond1.for.cond.cleanup3_crit_edge.us.loopexit58: 429 br label %for.cond1.for.cond.cleanup3_crit_edge.us 430 431for.cond1.for.cond.cleanup3_crit_edge.us: 432 %inc15.us = add nuw nsw i32 %i.036.us, 1 433 %cmp.us = icmp slt i32 %inc15.us, %N 434 br i1 %cmp.us, label %for.cond1.preheader.us, label %for.cond.cleanup.loopexit 435 436for.cond5.preheader.us.us: 437 %j.033.us.us = phi i32 [ %inc12.us.us, %for.cond5.for.cond.cleanup7_crit_edge.us.us ], [ 0, %for.cond5.preheader.us.us.preheader ] 438 br label %for.body8.us.us 439 440for.cond5.for.cond.cleanup7_crit_edge.us.us: 441 %inc12.us.us = add nuw nsw i32 %j.033.us.us, 1 442 %cmp2.us.us = icmp slt i32 %inc12.us.us, %N 443 br i1 %cmp2.us.us, label %for.cond5.preheader.us.us, label %for.cond1.for.cond.cleanup3_crit_edge.us.loopexit 444 445for.body8.us.us: 446 %k.031.us.us = phi i32 [ 0, %for.cond5.preheader.us.us ], [ %inc.us.us, %for.body8.us.us ] 447 %mul.us.us = mul nsw i32 %k.031.us.us, %N 448 %add.us.us = add nsw i32 %mul.us.us, %j.033.us.us 449 %mul9.us.us = mul nsw i32 %add.us.us, %N 450 %add10.us.us = add nsw i32 %mul9.us.us, %i.036.us 451 %idxprom.us.us = sext i32 %add10.us.us to i64 452 %arrayidx.us.us = getelementptr inbounds i32, i32* %A, i64 %idxprom.us.us 453 tail call void @f(i32* %arrayidx.us.us) #2 454 %inc.us.us = add nuw nsw i32 %k.031.us.us, 1 455 %cmp6.us.us = icmp slt i32 %inc.us.us, %N 456 br i1 %cmp6.us.us, label %for.body8.us.us, label %for.cond5.for.cond.cleanup7_crit_edge.us.us 457 458for.cond.cleanup.loopexit: 459 br label %for.cond.cleanup 460 461for.cond.cleanup: 462 ret void 463} 464 465; A 3d loop corresponding to: 466; 467; for (int k = 0; k < N; ++k) 468; for (int i = 0; i < N; ++i) 469; for (int j = 0; j < M; ++j) 470; f(&A[i*M+j]); 471; 472; This could be supported, but isn't at the moment. 473; 474define void @d3_2(i32* %A, i32 %N, i32 %M) { 475entry: 476 %cmp30 = icmp sgt i32 %N, 0 477 br i1 %cmp30, label %for.cond1.preheader.lr.ph, label %for.cond.cleanup 478 479for.cond1.preheader.lr.ph: 480 %cmp625 = icmp sgt i32 %M, 0 481 br label %for.cond1.preheader.us 482 483for.cond1.preheader.us: 484 %k.031.us = phi i32 [ 0, %for.cond1.preheader.lr.ph ], [ %inc13.us, %for.cond1.for.cond.cleanup3_crit_edge.us ] 485 br i1 %cmp625, label %for.cond5.preheader.us.us.preheader, label %for.cond5.preheader.us43.preheader 486 487for.cond5.preheader.us43.preheader: 488 br label %for.cond1.for.cond.cleanup3_crit_edge.us.loopexit50 489 490for.cond5.preheader.us.us.preheader: 491 br label %for.cond5.preheader.us.us 492 493for.cond1.for.cond.cleanup3_crit_edge.us.loopexit: 494 br label %for.cond1.for.cond.cleanup3_crit_edge.us 495 496for.cond1.for.cond.cleanup3_crit_edge.us.loopexit50: 497 br label %for.cond1.for.cond.cleanup3_crit_edge.us 498 499for.cond1.for.cond.cleanup3_crit_edge.us: 500 %inc13.us = add nuw nsw i32 %k.031.us, 1 501 %exitcond52 = icmp ne i32 %inc13.us, %N 502 br i1 %exitcond52, label %for.cond1.preheader.us, label %for.cond.cleanup.loopexit 503 504for.cond5.preheader.us.us: 505 %i.028.us.us = phi i32 [ %inc10.us.us, %for.cond5.for.cond.cleanup7_crit_edge.us.us ], [ 0, %for.cond5.preheader.us.us.preheader ] 506 %mul.us.us = mul nsw i32 %i.028.us.us, %M 507 br label %for.body8.us.us 508 509for.cond5.for.cond.cleanup7_crit_edge.us.us: 510 %inc10.us.us = add nuw nsw i32 %i.028.us.us, 1 511 %exitcond51 = icmp ne i32 %inc10.us.us, %N 512 br i1 %exitcond51, label %for.cond5.preheader.us.us, label %for.cond1.for.cond.cleanup3_crit_edge.us.loopexit 513 514for.body8.us.us: 515 %j.026.us.us = phi i32 [ 0, %for.cond5.preheader.us.us ], [ %inc.us.us, %for.body8.us.us ] 516 %add.us.us = add nsw i32 %j.026.us.us, %mul.us.us 517 %idxprom.us.us = sext i32 %add.us.us to i64 518 %arrayidx.us.us = getelementptr inbounds i32, i32* %A, i64 %idxprom.us.us 519 tail call void @f(i32* %arrayidx.us.us) #2 520 %inc.us.us = add nuw nsw i32 %j.026.us.us, 1 521 %exitcond = icmp ne i32 %inc.us.us, %M 522 br i1 %exitcond, label %for.body8.us.us, label %for.cond5.for.cond.cleanup7_crit_edge.us.us 523 524for.cond.cleanup.loopexit: 525 br label %for.cond.cleanup 526 527for.cond.cleanup: 528 ret void 529} 530 531; A 3d loop corresponding to: 532; 533; for (int i = 0; i < N; ++i) 534; for (int j = 0; j < M; ++j) { 535; A[i*M+j] = 0; 536; for (int k = 0; k < N; ++k) 537; g(); 538; } 539; 540define void @d3_3(i32* nocapture %A, i32 %N, i32 %M) { 541entry: 542 %cmp29 = icmp sgt i32 %N, 0 543 br i1 %cmp29, label %for.cond1.preheader.lr.ph, label %for.cond.cleanup 544 545for.cond1.preheader.lr.ph: 546 %cmp227 = icmp sgt i32 %M, 0 547 br i1 %cmp227, label %for.cond1.preheader.us.preheader, label %for.cond1.preheader.preheader 548 549for.cond1.preheader.preheader: 550 br label %for.cond.cleanup.loopexit49 551 552for.cond1.preheader.us.preheader: 553 br label %for.cond1.preheader.us 554 555for.cond1.preheader.us: 556 %i.030.us = phi i32 [ %inc13.us, %for.cond1.for.cond.cleanup3_crit_edge.us ], [ 0, %for.cond1.preheader.us.preheader ] 557 %mul.us = mul nsw i32 %i.030.us, %M 558 br i1 true, label %for.body4.us.us.preheader, label %for.body4.us32.preheader 559 560for.body4.us32.preheader: 561 br label %for.cond1.for.cond.cleanup3_crit_edge.us.loopexit48 562 563for.body4.us.us.preheader: 564 br label %for.body4.us.us 565 566for.cond1.for.cond.cleanup3_crit_edge.us.loopexit: 567 br label %for.cond1.for.cond.cleanup3_crit_edge.us 568 569for.cond1.for.cond.cleanup3_crit_edge.us.loopexit48: 570 br label %for.cond1.for.cond.cleanup3_crit_edge.us 571 572for.cond1.for.cond.cleanup3_crit_edge.us: 573 %inc13.us = add nuw nsw i32 %i.030.us, 1 574 %exitcond51 = icmp ne i32 %inc13.us, %N 575 br i1 %exitcond51, label %for.cond1.preheader.us, label %for.cond.cleanup.loopexit 576 577for.body4.us.us: 578 %j.028.us.us = phi i32 [ %inc10.us.us, %for.cond5.for.cond.cleanup7_crit_edge.us.us ], [ 0, %for.body4.us.us.preheader ] 579 %add.us.us = add nsw i32 %j.028.us.us, %mul.us 580 %idxprom.us.us = sext i32 %add.us.us to i64 581 %arrayidx.us.us = getelementptr inbounds i32, i32* %A, i64 %idxprom.us.us 582 store i32 0, i32* %arrayidx.us.us, align 4 583 br label %for.body8.us.us 584 585for.cond5.for.cond.cleanup7_crit_edge.us.us: 586 %inc10.us.us = add nuw nsw i32 %j.028.us.us, 1 587 %exitcond50 = icmp ne i32 %inc10.us.us, %M 588 br i1 %exitcond50, label %for.body4.us.us, label %for.cond1.for.cond.cleanup3_crit_edge.us.loopexit 589 590for.body8.us.us: 591 %k.026.us.us = phi i32 [ 0, %for.body4.us.us ], [ %inc.us.us, %for.body8.us.us ] 592 tail call void bitcast (void (...)* @g to void ()*)() #2 593 %inc.us.us = add nuw nsw i32 %k.026.us.us, 1 594 %exitcond = icmp ne i32 %inc.us.us, %N 595 br i1 %exitcond, label %for.body8.us.us, label %for.cond5.for.cond.cleanup7_crit_edge.us.us 596 597for.cond.cleanup.loopexit: 598 br label %for.cond.cleanup 599 600for.cond.cleanup.loopexit49: 601 br label %for.cond.cleanup 602 603for.cond.cleanup: 604 ret void 605} 606 607declare dso_local void @f(i32*) 608declare dso_local void @g(...) 609