Regvar and Absolute produce wrong results with FPU type SSE
Summary
The functions below implement an approximation of the ln() function, one version uses pointer cast, the other "absolute". They are precise within 0.1% but when compiling with FPUType SSE and regvar ON, the "absolute" version is grossly off for all arguments below 0.5 as shown in the image.
System Information
PC Windows 10, i386-win32, FPC 3.2.2, 3.2.3 (as of 5/03/23).
This may be related to #40212 but that was for x86_64-linux.
Steps to reproduce
Compile and run, using fpc SSE2_Absolute.pas -Mobjfpc -CfSSE -Ooregvar
Example Project
{.$FPUTYPE SSE}
{.$OPTIMIZATION REGVAR}
{fastlnABS version goes wrong when using SSE and regvar}
function fastln (x: single): single; //version using pointer cast
var px: pdword;
y: single;
begin
px := @x;
y := px^ shr 23 - 125.0837635981;
px^ := (px^ AND $07FFFFF) or ($7E shl 23);
result := (y +0.455253*x -1.90418/(x+0.388403))* 0.69314718;
end;
function fastlnABS (x: single): single; //version using absolute
var d: dword absolute x;
y: single;
begin
y := d shr 23 - 125.0837635981;
d := (d AND $07FFFFF) or ($7E shl 23);
result := (y +0.455253*x -1.90418/(x+0.388403))* 0.69314718;
end;
begin
writeln ('Testing fastln (0.2).......');
write ('Version using pointer : ');
if abs (ln(0.2) - fastln(0.2)) > 1e-3 then writeln ('WRONG') else writeln ('correct');
write ('Version using absolute: ');
if abs (ln(0.2) - fastlnABS(0.2)) > 1e-3 then writeln ('WRONG') else writeln ('correct');
end.