-
Notifications
You must be signed in to change notification settings - Fork 15.3k
Open
Description
https://godbolt.org/z/TW9b71zPM
int b, c;
int n;
void test() {
for (int i = 0; i < 1000; i += b) {
if(c < 0){
c = n;
}
}
}In the test code, the value of c only gets a chance to change when it first enters the loop, so from there we can make the following optimizations:
If initially c<0 holds, then the loop is not executed.
Otherwise, c is a loop invariant for all subsequent iterations of the loop, which can be optimized using loopUnswitch.
Furthermore, if we optimize via loopUnswitch, we see that the entire loop is unnecessary.
Finally, we get the expected code:
test(): # @test()
cmp dword ptr [rip + c], 0
js .LBB0_1
ret
.LBB0_1: # %if.then
mov eax, dword ptr [rip + n]
mov dword ptr [rip + c], eax
retBut Clang:
test(): # @test()
mov eax, dword ptr [rip + b]
mov esi, dword ptr [rip + c]
xor ecx, ecx
mov edx, dword ptr [rip + n]
jmp .LBB0_1
.LBB0_3: # %for.inc
add ecx, eax
cmp ecx, 1000
jge .LBB0_4
.LBB0_1: # %for.body
test esi, esi
jns .LBB0_3
mov dword ptr [rip + c], edx
mov esi, edx
jmp .LBB0_3
.LBB0_4: # %for.cond.cleanup
ret