Min/max intrinsics generate wrong code with absolute addressing on x86-64/win64.
Compile this program for x86-64/win64
with -O2
+.
{$mode objfpc}
var
value: SizeUint;
procedure Proc;
var
x: SizeUint;
begin
x := random(0);
if x >= value then value := x; // (!)
end;
begin
value := 5;
Proc;
writeln('Must be 5: ', value);
end.
Line marked with (!)
generates the following assembly, where the (!!!)
part is obviously wrong because two instructions down the same variable is addressed RIP-relatively:
; if x >= value then value := x; // (!)
mov rdx, rax ; rdx = rax = x
cmp [$00014010], rax ; value <= x (!!!)
cmovnbe rdx, [rip+$00012A1F] ; rdx = max(x, value)
mov [rip+$00012A18], rdx ; value := rdx
For me: the program as is compares x
to the arbitrary but readable memory location and gives wrong result (Must be 5: 0
), adding uses SysUtils
makes it crash instead.
Edited by Rika