Open cddouma-arm opened 8 years ago
Bugzilla Link | 28429 |
Version | trunk |
OS | All |
CC | @hfinkel,@sanjoy |
The following loop is not unrolled because the trip count is not simple constant:
void foo(int x, int *p) { x += 2; //any value bigger than 1 for (int i = x; i <= x+1; ++i) p[i] = i; }
The attached IR is generated compiling the above source with: ./bin/clang --target=aarch64-arm-none-eabi -mllvm -debug-only=loop-unroll -O3
SCEV find the trip count as: (-2 + (-1 * %x) + ((2 + %x) smax (3 + %x)))
This expression can be simplified into a constant if the arguments of smax are not wrapping. But while the original source has non-wrapping expressions, they are not marked as such by SCEV. Reason is that SCEV considers these expressions possible poison values and marks them as wrapping. This seem to be a limitation in the llvm::ScalarEvolution::isSCEVExprNeverPoison function.
Analysis so far: The actual add instructions have the nsw flags and reside in a basic block just before the loop body. The isSCEVExprNeverPoison function is called on them but assumes the instruction must be part of a loop. If the instruction is not part of any loop it is reported as a possible poison value.
A possible fix would be to assume the instruction is loop independent if it is not part of any loop. But I am not sure if the loop information is complete (does absence of loop info on a basic block means there is no loop in the code in the scalar evolution pass?). With such a fix the resulting expression would be:
(-2 + (-1 * %x) + ((2 + %x)
This is foldable, although the current folding expression constructors don’t handle this case yet.