View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0038533 | FPC | Compiler | public | 2021-02-22 18:47 | 2021-02-22 22:42 |
Reporter | runewalsh | Assigned To | Florian | ||
Priority | normal | Severity | minor | Reproducibility | sometimes |
Status | resolved | Resolution | fixed | ||
Platform | i386-win32 | ||||
Product Version | 3.3.1 | ||||
Fixed in Version | 3.3.1 | ||||
Summary | 0038533: -CpCOREAVX2 is scared of reinterpret-casting ‘result’ on x86-32 | ||||
Description | Code 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 Reproduce | type 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. | ||||
Tags | No tags attached. | ||||
Fixed in Revision | 48791 | ||||
FPCOldBugId | |||||
FPCTarget | - | ||||
Attached Files |
|
|
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. |
|
Thanks u_u |
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 |