View Issue Details

IDProjectCategoryView StatusLast Update
0038533FPCCompilerpublic2021-02-22 22:42
Reporterrunewalsh Assigned ToFlorian  
PrioritynormalSeverityminorReproducibilitysometimes
Status resolvedResolutionfixed 
Platformi386-win32 
Product Version3.3.1 
Fixed in Version3.3.1 
Summary0038533: -CpCOREAVX2 is scared of reinterpret-casting ‘result’ on x86-32
DescriptionCode in ‘Steps to reproduce’ gives wrong result on i386-win32 with -CpCOREAVX2 and -O2 or higher.
Expected: 45 23 1
Actual: 45 123 0

The code itself does the following.
Imagine a W×H grid. We can number its cells in row-major order as PackPoint2D(x, y) = y×W + x and define an inverse operation, UnpackPoint2D(pid) = {x = pid % W, y = pid / W}.

Three-dimensional counterpart is W×H×D grid.
UnpackPoint3D(pid) unpacks Z = pid / (W×H) and, for the simplicity, delegates the rest of work (unpacking X and Y) to UnpackPoint2D(pid % (W×H)).

Although it's not nice to reinterpret_cast 3D vector as 2D that way, this ought to work neverthless, right? At least this is not an excuse for “uint64 mod 100” to give 123.

With size=100×100×100, point (XX, YY, ZZ) gets packed into decimal value ZZYYXX and vice versa. Thus, Unpack(12345) should give (45, 23, 1).
Steps To Reproducetype
    FlatIndex = uint64;
    UintVec2 = array[0 .. 1] of uint32; PUintVec2 = ^UintVec2;
    UintVec3 = array[0 .. 2] of uint32; PUintVec3 = ^UintVec3;

function UnpackPoint(index: FlatIndex; const size: UintVec2): UintVec2;
var
    q: FlatIndex;
begin
    q := index div size[0];
    result[1] := q;
    result[0] := index - q * size[0];
end;

function UnpackPoint(index: FlatIndex; const size: UintVec3): UintVec3;
var
    d, q: FlatIndex;
begin
    d := FlatIndex(size[1]) * size[0];
    q := index div d;
    result[2] := q;
    PUintVec2(@result)^ := UnpackPoint(index - q * d, PUintVec2(@size)^);
end;

var
    v, sz: UintVec3;
begin
    sz[0] := 100;
    sz[1] := 100;
    sz[2] := 100;
    v := UnpackPoint(12345, sz);
    writeln('Expected: 45 23 1');
    writeln('Actual: ', v[0], ' ', v[1], ' ', v[2]);
end.
TagsNo tags attached.
Fixed in Revision48791
FPCOldBugId
FPCTarget-
Attached Files

Activities

runewalsh

2021-02-22 20:19

reporter   ~0129107

Last edited: 2021-02-22 20:51

View 8 revisions

The site of the problem is not the reinterpret-casting, sorry. Here's a simpler version:

type
    UintVec2 = record x, y: uint32; end;

function GetY(const flatIndex: uint64; const planeSize: UintVec2): uint32;
var
    planePixels, z, rest: uint64;
begin
    planePixels := uint64(planeSize.y) * planeSize.x;
    z := flatIndex div planePixels;
    rest := flatIndex - z * planePixels;
    result := rest div planeSize.x;
end;

var
    planeSize: UintVec2;
begin
    planeSize.x := 100; planeSize.y := 100;
    writeln('Must be 23: ', GetY(12345, planeSize));
end.

What misleaded me is that the bug easily vanishes.

runewalsh

2021-02-22 22:42

reporter   ~0129109

Thanks u_u

Issue History

Date Modified Username Field Change
2021-02-22 18:47 runewalsh New Issue
2021-02-22 20:19 runewalsh Note Added: 0129107
2021-02-22 20:22 runewalsh Note Edited: 0129107 View Revisions
2021-02-22 20:24 runewalsh Note Edited: 0129107 View Revisions
2021-02-22 20:44 runewalsh Note Edited: 0129107 View Revisions
2021-02-22 20:48 runewalsh Note Edited: 0129107 View Revisions
2021-02-22 20:49 runewalsh Note Edited: 0129107 View Revisions
2021-02-22 20:50 runewalsh Note Edited: 0129107 View Revisions
2021-02-22 20:51 runewalsh Note Edited: 0129107 View Revisions
2021-02-22 21:39 Florian Assigned To => Florian
2021-02-22 21:39 Florian Status new => resolved
2021-02-22 21:39 Florian Resolution open => fixed
2021-02-22 21:39 Florian Fixed in Version => 3.3.1
2021-02-22 21:39 Florian Fixed in Revision => 48791
2021-02-22 21:39 Florian FPCTarget => -
2021-02-22 22:42 runewalsh Note Added: 0129109