Here are two functions, one after another. The first one is enclosed in $push/$pop directives and have a register variables optimization. I'd expect second one not to have such, but apparently it does.
program Project1;
{$optimization off}
{$push} {$optimization regvar}
function IntLog2Up1(A: PtrUInt): PtrUInt;
var
P: PtrUInt;
begin
P := 0;
Dec(A);
if (A and $FFFF0000) <> 0 then begin A := A shr 16; P := P or 16; end;
if (A and $FF00) <> 0 then begin A := A shr 8; P := P or 8; end;
if (A and $F0) <> 0 then begin A := A shr 4; P := P or 4; end;
if (A and $0C) <> 0 then begin A := A shr 2; P := P or 2; end;
if (A and 2) <> 0 then begin A := A shr 1; P := P or 1; end;
Result := P + 1;
end;
{$pop}
function IntLog2Up2(A: PtrUInt): PtrUInt;
var
P: PtrUInt;
begin
Result := 0;
P := 1;
while (P < A) do
begin
P := P * 2;
Inc(Result);
end;
end;
begin
WriteLn(IntLog2Up1(7), IntLog2Up2(7));
end.
Here is the beginning of the first one:
C:\Users\alpi\AppData\Local\Temp\project1.lpr:10 P := 0;
004015A3 B900000000 mov ecx,$00000000
C:\Users\alpi\AppData\Local\Temp\project1.lpr:11 Dec(A);
004015A8 83E801 sub eax,$01
C:\Users\alpi\AppData\Local\Temp\project1.lpr:12 if (A and $FFFF0000) <> 0 then begin A := A shr 16; P := P or 16; end;
004015AB 89C2 mov edx,eax
004015AD 81E20000FFFF and edx,$FFFF0000
004015B3 F7C2FFFFFFFF test edx,$FFFFFFFF
004015B9 7502 jnz +$02
004015BB EB0F jmp +$0F
...
And here is the beginning of the second:
C:\Users\alpi\AppData\Local\Temp\project1.lpr:25 Result := 0;
00401656 B800000000 mov eax,$00000000
C:\Users\alpi\AppData\Local\Temp\project1.lpr:26 P := 1;
0040165B BB01000000 mov ebx,$00000001
C:\Users\alpi\AppData\Local\Temp\project1.lpr:27 while (P < A) do
00401660 EB0F jmp +$0F
00401662 8DB600000000 lea esi,[esi+$00000000]
C:\Users\alpi\AppData\Local\Temp\project1.lpr:29 P := P * 2;
00401668 89D9 mov ecx,ebx
0040166A D1E1 shl ecx,1
0040166C 89CB mov ebx,ecx
...
Lazarus 2.2.2 (rev lazarus_2_2_2) FPC 3.2.2 i386-win32-win32/win64