Failed to Unroll a Seemingly Simple Loop

Hi,

I found LLVM cannot unroll the loop in the example below, while gcc can. Before I dig more about this issue, is this behavior as designed?

bool bar(int i);

void foo(int *a, int x, int y) {
for (int i = 0; i < 4; ++i) {
if (bar(i)) {
break;
}
a[i] = i;
}
}

Btw, if s/break/continue, LLVM is able to unroll it.

Thanks,
Jingyue

I found LLVM cannot unroll the loop in the example below, while gcc can.
Before I dig more about this issue, is this behavior as designed?

It doesn't unroll the loop because the trip count is not known at
compile time (it could exit early because of the break), and by
default loops with runtime loop counts are not unrolled. However,
even specifying -unroll-runtime still doesn't get the loop to unroll.
Looking deeper it looks like runtime loop unrolling is only performed
if the loop has a single exit. See:
Transforms/Util/LoopUnroll.cpp:211 and
Transforms/Util/LoopUnrollRuntime.cpp:231.

It'd be nice if an optimization missed remark was emitted. Certainly
a remark should be emitted in the case where you give a unroll pragma
to specifically unroll the loop. Can you file a PR about this remark
issue and assign it to me?

thanks,
Mark

Nice find, Mark! Thanks a lot.

I filed http://llvm.org/bugs/show_bug.cgi?id=20100 to track the remark issue.

Jingyue

The FIXME at ScalarEvolution.cpp:4084 explains LoopUnroll’s behavior on my example. I’ll try to fix it.

Jingyue