Skip to content
GitLab
    • Why GitLab
    • Pricing
    • Contact Sales
    • Explore
  • Why GitLab
  • Pricing
  • Contact Sales
  • Explore
  • Sign in
  • Get free trial
  • FPC
  • FPCFPC
  • FPC SourceFPC Source
  • Issues
  • #40239

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.

Comparison_ln_fastln

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.

SSE2_Absolute.pas

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking