The following code: int main() { for(int i=0; i += i < 1000, i < 1000;); } optimizes on x86_64 to the following code: main: .LFB0: xorl %eax, %eax .L2: xorl %edx, %edx cmpl $999, %eax setle %dl addl %edx, %eax cmpl $999, %eax jle .L2 xorl %eax, %eax ret I would expect the loop to be removed completely.
There's a chicken-and-egg issue in optimization -- proving that i < 1000 is always true for the increment requires the number of iterations to be known and that requires this condition to be simplified. optimistic VRP should be able to figure this out together with SCEV but SCEV isn't fed with the intermediate VRP info nor does VRP query SCEV during iteration at the right point. Quite an arcane case though... clang doesn't get it either.
Hi Richard, I agree that this seems quite 'arcane' at first glance; I should explain that I found it when an empty for loop failed to optimize out in rust - the reduced test case failed to optimize in clang and also gcc, so I posted it here. My thought is that this kind of pattern might be more common than it seems at first glance, after other code has been reduced. null
Fixed for GCC 11, by the ranger patches for eVRP.